Skip to content

Commit fd815b7

Browse files
committed
Merge pull request #25299 from alexcrichton/beta-backport
Backport mem::forget to beta
2 parents 781c2aa + f245929 commit fd815b7

File tree

9 files changed

+76
-26
lines changed

9 files changed

+76
-26
lines changed

src/libcollections/slice.rs

+5-6
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,6 @@
8080
#![stable(feature = "rust1", since = "1.0.0")]
8181

8282
use alloc::boxed::Box;
83-
use core::convert::AsRef;
8483
use core::clone::Clone;
8584
use core::cmp::Ordering::{self, Greater, Less};
8685
use core::cmp::{self, Ord, PartialEq};
@@ -1028,23 +1027,23 @@ pub trait SliceConcatExt<T: ?Sized, U> {
10281027
fn connect(&self, sep: &T) -> U;
10291028
}
10301029

1031-
impl<T: Clone, V: AsRef<[T]>> SliceConcatExt<T, Vec<T>> for [V] {
1030+
impl<T: Clone, V: Borrow<[T]>> SliceConcatExt<T, Vec<T>> for [V] {
10321031
fn concat(&self) -> Vec<T> {
1033-
let size = self.iter().fold(0, |acc, v| acc + v.as_ref().len());
1032+
let size = self.iter().fold(0, |acc, v| acc + v.borrow().len());
10341033
let mut result = Vec::with_capacity(size);
10351034
for v in self {
1036-
result.push_all(v.as_ref())
1035+
result.push_all(v.borrow())
10371036
}
10381037
result
10391038
}
10401039

10411040
fn connect(&self, sep: &T) -> Vec<T> {
1042-
let size = self.iter().fold(0, |acc, v| acc + v.as_ref().len());
1041+
let size = self.iter().fold(0, |acc, v| acc + v.borrow().len());
10431042
let mut result = Vec::with_capacity(size + self.len());
10441043
let mut first = true;
10451044
for v in self {
10461045
if first { first = false } else { result.push(sep.clone()) }
1047-
result.push_all(v.as_ref())
1046+
result.push_all(v.borrow())
10481047
}
10491048
result
10501049
}

src/libcollections/str.rs

+5-6
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,6 @@ use core::str::pattern::Pattern;
6161
use core::str::pattern::{Searcher, ReverseSearcher, DoubleEndedSearcher};
6262
use unicode::str::{UnicodeStr, Utf16Encoder};
6363

64-
use core::convert::AsRef;
6564
use vec_deque::VecDeque;
6665
use borrow::{Borrow, ToOwned};
6766
use string::String;
@@ -85,18 +84,18 @@ pub use core::str::pattern;
8584
Section: Creating a string
8685
*/
8786

88-
impl<S: AsRef<str>> SliceConcatExt<str, String> for [S] {
87+
impl<S: Borrow<str>> SliceConcatExt<str, String> for [S] {
8988
fn concat(&self) -> String {
9089
if self.is_empty() {
9190
return String::new();
9291
}
9392

9493
// `len` calculation may overflow but push_str will check boundaries
95-
let len = self.iter().map(|s| s.as_ref().len()).sum();
94+
let len = self.iter().map(|s| s.borrow().len()).sum();
9695
let mut result = String::with_capacity(len);
9796

9897
for s in self {
99-
result.push_str(s.as_ref())
98+
result.push_str(s.borrow())
10099
}
101100

102101
result
@@ -115,7 +114,7 @@ impl<S: AsRef<str>> SliceConcatExt<str, String> for [S] {
115114
// this is wrong without the guarantee that `self` is non-empty
116115
// `len` calculation may overflow but push_str but will check boundaries
117116
let len = sep.len() * (self.len() - 1)
118-
+ self.iter().map(|s| s.as_ref().len()).sum::<usize>();
117+
+ self.iter().map(|s| s.borrow().len()).sum::<usize>();
119118
let mut result = String::with_capacity(len);
120119
let mut first = true;
121120

@@ -125,7 +124,7 @@ impl<S: AsRef<str>> SliceConcatExt<str, String> for [S] {
125124
} else {
126125
result.push_str(sep);
127126
}
128-
result.push_str(s.as_ref());
127+
result.push_str(s.borrow());
129128
}
130129
result
131130
}

src/libcollections/string.rs

+8
Original file line numberDiff line numberDiff line change
@@ -1005,6 +1005,14 @@ impl AsRef<str> for String {
10051005
}
10061006
}
10071007

1008+
#[stable(feature = "rust1", since = "1.0.0")]
1009+
impl AsRef<[u8]> for String {
1010+
#[inline]
1011+
fn as_ref(&self) -> &[u8] {
1012+
self.as_bytes()
1013+
}
1014+
}
1015+
10081016
#[stable(feature = "rust1", since = "1.0.0")]
10091017
impl<'a> From<&'a str> for String {
10101018
#[inline]

src/libcollections/vec.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -637,7 +637,7 @@ impl<T> Vec<T> {
637637
// zero-size types consume no memory, so we can't rely on the
638638
// address space running out
639639
self.len = self.len.checked_add(1).expect("length overflow");
640-
unsafe { mem::forget(value); }
640+
mem::forget(value);
641641
return
642642
}
643643

@@ -959,7 +959,7 @@ impl<T> Vec<T> {
959959
num_u: 0,
960960
marker: PhantomData,
961961
};
962-
unsafe { mem::forget(vec); }
962+
mem::forget(vec);
963963

964964
while pv.num_t != 0 {
965965
unsafe {

src/libcore/intrinsics.rs

-4
Original file line numberDiff line numberDiff line change
@@ -217,10 +217,6 @@ extern "rust-intrinsic" {
217217
pub fn uninit<T>() -> T;
218218

219219
/// Moves a value out of scope without running drop glue.
220-
///
221-
/// `forget` is unsafe because the caller is responsible for
222-
/// ensuring the argument is deallocated already.
223-
#[stable(feature = "rust1", since = "1.0.0")]
224220
pub fn forget<T>(_: T) -> ();
225221

226222
/// Unsafely transforms a value of one type into a value of another type.

src/libcore/mem.rs

+45-6
Original file line numberDiff line numberDiff line change
@@ -22,15 +22,54 @@ use ptr;
2222
#[stable(feature = "rust1", since = "1.0.0")]
2323
pub use intrinsics::transmute;
2424

25-
/// Moves a thing into the void.
25+
/// Leaks a value into the void, consuming ownership and never running its
26+
/// destructor.
2627
///
27-
/// The forget function will take ownership of the provided value but neglect
28-
/// to run any required cleanup or memory management operations on it.
28+
/// This function will take ownership of its argument, but is distinct from the
29+
/// `mem::drop` function in that it **does not run the destructor**, leaking the
30+
/// value and any resources that it owns.
2931
///
30-
/// This function is the unsafe version of the `drop` function because it does
31-
/// not run any destructors.
32+
/// # Safety
33+
///
34+
/// This function is not marked as `unsafe` as Rust does not guarantee that the
35+
/// `Drop` implementation for a value will always run. Note, however, that
36+
/// leaking resources such as memory or I/O objects is likely not desired, so
37+
/// this function is only recommended for specialized use cases.
38+
///
39+
/// The safety of this function implies that when writing `unsafe` code
40+
/// yourself care must be taken when leveraging a destructor that is required to
41+
/// run to preserve memory safety. There are known situations where the
42+
/// destructor may not run (such as if ownership of the object with the
43+
/// destructor is returned) which must be taken into account.
44+
///
45+
/// # Other forms of Leakage
46+
///
47+
/// It's important to point out that this function is not the only method by
48+
/// which a value can be leaked in safe Rust code. Other known sources of
49+
/// leakage are:
50+
///
51+
/// * `Rc` and `Arc` cycles
52+
/// * `mpsc::{Sender, Receiver}` cycles (they use `Arc` internally)
53+
/// * Panicking destructors are likely to leak local resources
54+
///
55+
/// # Example
56+
///
57+
/// ```rust,no_run
58+
/// use std::mem;
59+
/// use std::fs::File;
60+
///
61+
/// // Leak some heap memory by never deallocating it
62+
/// let heap_memory = Box::new(3);
63+
/// mem::forget(heap_memory);
64+
///
65+
/// // Leak an I/O object, never closing the file
66+
/// let file = File::open("foo.txt").unwrap();
67+
/// mem::forget(file);
68+
/// ```
3269
#[stable(feature = "rust1", since = "1.0.0")]
33-
pub use intrinsics::forget;
70+
pub fn forget<T>(t: T) {
71+
unsafe { intrinsics::forget(t) }
72+
}
3473

3574
/// Returns the size of a type in bytes.
3675
///

src/libcore/str/mod.rs

+9
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ use self::pattern::{Searcher, ReverseSearcher, DoubleEndedSearcher};
2323
use char::CharExt;
2424
use clone::Clone;
2525
use cmp::{self, Eq};
26+
use convert::AsRef;
2627
use default::Default;
2728
use fmt;
2829
use iter::ExactSizeIterator;
@@ -1843,6 +1844,14 @@ impl StrExt for str {
18431844
fn parse<T: FromStr>(&self) -> Result<T, T::Err> { FromStr::from_str(self) }
18441845
}
18451846

1847+
#[stable(feature = "rust1", since = "1.0.0")]
1848+
impl AsRef<[u8]> for str {
1849+
#[inline]
1850+
fn as_ref(&self) -> &[u8] {
1851+
self.as_bytes()
1852+
}
1853+
}
1854+
18461855
/// Pluck a code point out of a UTF-8-like byte slice and return the
18471856
/// index of the next code point.
18481857
#[inline]

src/libstd/sys/unix/fd.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ impl FileDesc {
3131
/// Extracts the actual filedescriptor without closing it.
3232
pub fn into_raw(self) -> c_int {
3333
let fd = self.fd;
34-
unsafe { mem::forget(self) };
34+
mem::forget(self);
3535
fd
3636
}
3737

src/libstd/sys/windows/handle.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ impl Handle {
3232

3333
pub fn into_raw(self) -> HANDLE {
3434
let ret = self.0;
35-
unsafe { mem::forget(self) }
35+
mem::forget(self);
3636
return ret;
3737
}
3838

0 commit comments

Comments
 (0)