diff options
| author | Brian Anderson <andersrb@gmail.com> | 2015-05-11 11:22:01 -0700 |
|---|---|---|
| committer | Brian Anderson <andersrb@gmail.com> | 2015-05-11 11:22:01 -0700 |
| commit | fd815b7a57b0214362d53b5e4e0dc282c5c26dfd (patch) | |
| tree | d3710cc7dcdb877fcc9c6622cab032c0c0920d8b /src | |
| parent | 781c2aa6200f45fe2ce6c4cb74779792c17add63 (diff) | |
| parent | f245929834543ca9a00278827a82d29ae3b2770f (diff) | |
| download | rust-fd815b7a57b0214362d53b5e4e0dc282c5c26dfd.tar.gz rust-fd815b7a57b0214362d53b5e4e0dc282c5c26dfd.zip | |
Merge pull request #25299 from alexcrichton/beta-backport
Backport mem::forget to beta
Diffstat (limited to 'src')
| -rw-r--r-- | src/libcollections/slice.rs | 11 | ||||
| -rw-r--r-- | src/libcollections/str.rs | 11 | ||||
| -rw-r--r-- | src/libcollections/string.rs | 8 | ||||
| -rw-r--r-- | src/libcollections/vec.rs | 4 | ||||
| -rw-r--r-- | src/libcore/intrinsics.rs | 4 | ||||
| -rw-r--r-- | src/libcore/mem.rs | 51 | ||||
| -rw-r--r-- | src/libcore/str/mod.rs | 9 | ||||
| -rw-r--r-- | src/libstd/sys/unix/fd.rs | 2 | ||||
| -rw-r--r-- | src/libstd/sys/windows/handle.rs | 2 |
9 files changed, 76 insertions, 26 deletions
diff --git a/src/libcollections/slice.rs b/src/libcollections/slice.rs index 6622d8a9c40..8a566445e38 100644 --- a/src/libcollections/slice.rs +++ b/src/libcollections/slice.rs @@ -80,7 +80,6 @@ #![stable(feature = "rust1", since = "1.0.0")] use alloc::boxed::Box; -use core::convert::AsRef; use core::clone::Clone; use core::cmp::Ordering::{self, Greater, Less}; use core::cmp::{self, Ord, PartialEq}; @@ -1028,23 +1027,23 @@ pub trait SliceConcatExt<T: ?Sized, U> { fn connect(&self, sep: &T) -> U; } -impl<T: Clone, V: AsRef<[T]>> SliceConcatExt<T, Vec<T>> for [V] { +impl<T: Clone, V: Borrow<[T]>> SliceConcatExt<T, Vec<T>> for [V] { fn concat(&self) -> Vec<T> { - let size = self.iter().fold(0, |acc, v| acc + v.as_ref().len()); + let size = self.iter().fold(0, |acc, v| acc + v.borrow().len()); let mut result = Vec::with_capacity(size); for v in self { - result.push_all(v.as_ref()) + result.push_all(v.borrow()) } result } fn connect(&self, sep: &T) -> Vec<T> { - let size = self.iter().fold(0, |acc, v| acc + v.as_ref().len()); + let size = self.iter().fold(0, |acc, v| acc + v.borrow().len()); let mut result = Vec::with_capacity(size + self.len()); let mut first = true; for v in self { if first { first = false } else { result.push(sep.clone()) } - result.push_all(v.as_ref()) + result.push_all(v.borrow()) } result } diff --git a/src/libcollections/str.rs b/src/libcollections/str.rs index 7a28b56b7c1..6edc62785e8 100644 --- a/src/libcollections/str.rs +++ b/src/libcollections/str.rs @@ -61,7 +61,6 @@ use core::str::pattern::Pattern; use core::str::pattern::{Searcher, ReverseSearcher, DoubleEndedSearcher}; use unicode::str::{UnicodeStr, Utf16Encoder}; -use core::convert::AsRef; use vec_deque::VecDeque; use borrow::{Borrow, ToOwned}; use string::String; @@ -85,18 +84,18 @@ pub use core::str::pattern; Section: Creating a string */ -impl<S: AsRef<str>> SliceConcatExt<str, String> for [S] { +impl<S: Borrow<str>> SliceConcatExt<str, String> for [S] { fn concat(&self) -> String { if self.is_empty() { return String::new(); } // `len` calculation may overflow but push_str will check boundaries - let len = self.iter().map(|s| s.as_ref().len()).sum(); + let len = self.iter().map(|s| s.borrow().len()).sum(); let mut result = String::with_capacity(len); for s in self { - result.push_str(s.as_ref()) + result.push_str(s.borrow()) } result @@ -115,7 +114,7 @@ impl<S: AsRef<str>> SliceConcatExt<str, String> for [S] { // this is wrong without the guarantee that `self` is non-empty // `len` calculation may overflow but push_str but will check boundaries let len = sep.len() * (self.len() - 1) - + self.iter().map(|s| s.as_ref().len()).sum::<usize>(); + + self.iter().map(|s| s.borrow().len()).sum::<usize>(); let mut result = String::with_capacity(len); let mut first = true; @@ -125,7 +124,7 @@ impl<S: AsRef<str>> SliceConcatExt<str, String> for [S] { } else { result.push_str(sep); } - result.push_str(s.as_ref()); + result.push_str(s.borrow()); } result } diff --git a/src/libcollections/string.rs b/src/libcollections/string.rs index 41ad7c2d783..66fa4573bd7 100644 --- a/src/libcollections/string.rs +++ b/src/libcollections/string.rs @@ -1006,6 +1006,14 @@ impl AsRef<str> for String { } #[stable(feature = "rust1", since = "1.0.0")] +impl AsRef<[u8]> for String { + #[inline] + fn as_ref(&self) -> &[u8] { + self.as_bytes() + } +} + +#[stable(feature = "rust1", since = "1.0.0")] impl<'a> From<&'a str> for String { #[inline] fn from(s: &'a str) -> String { diff --git a/src/libcollections/vec.rs b/src/libcollections/vec.rs index 6195056579d..d5112c9fdff 100644 --- a/src/libcollections/vec.rs +++ b/src/libcollections/vec.rs @@ -637,7 +637,7 @@ impl<T> Vec<T> { // zero-size types consume no memory, so we can't rely on the // address space running out self.len = self.len.checked_add(1).expect("length overflow"); - unsafe { mem::forget(value); } + mem::forget(value); return } @@ -959,7 +959,7 @@ impl<T> Vec<T> { num_u: 0, marker: PhantomData, }; - unsafe { mem::forget(vec); } + mem::forget(vec); while pv.num_t != 0 { unsafe { diff --git a/src/libcore/intrinsics.rs b/src/libcore/intrinsics.rs index 8ed89adec5b..077d6367ff3 100644 --- a/src/libcore/intrinsics.rs +++ b/src/libcore/intrinsics.rs @@ -217,10 +217,6 @@ extern "rust-intrinsic" { pub fn uninit<T>() -> T; /// Moves a value out of scope without running drop glue. - /// - /// `forget` is unsafe because the caller is responsible for - /// ensuring the argument is deallocated already. - #[stable(feature = "rust1", since = "1.0.0")] pub fn forget<T>(_: T) -> (); /// Unsafely transforms a value of one type into a value of another type. diff --git a/src/libcore/mem.rs b/src/libcore/mem.rs index c4128e79765..a149af3a440 100644 --- a/src/libcore/mem.rs +++ b/src/libcore/mem.rs @@ -22,15 +22,54 @@ use ptr; #[stable(feature = "rust1", since = "1.0.0")] pub use intrinsics::transmute; -/// Moves a thing into the void. +/// Leaks a value into the void, consuming ownership and never running its +/// destructor. /// -/// The forget function will take ownership of the provided value but neglect -/// to run any required cleanup or memory management operations on it. +/// This function will take ownership of its argument, but is distinct from the +/// `mem::drop` function in that it **does not run the destructor**, leaking the +/// value and any resources that it owns. /// -/// This function is the unsafe version of the `drop` function because it does -/// not run any destructors. +/// # Safety +/// +/// This function is not marked as `unsafe` as Rust does not guarantee that the +/// `Drop` implementation for a value will always run. Note, however, that +/// leaking resources such as memory or I/O objects is likely not desired, so +/// this function is only recommended for specialized use cases. +/// +/// The safety of this function implies that when writing `unsafe` code +/// yourself care must be taken when leveraging a destructor that is required to +/// run to preserve memory safety. There are known situations where the +/// destructor may not run (such as if ownership of the object with the +/// destructor is returned) which must be taken into account. +/// +/// # Other forms of Leakage +/// +/// It's important to point out that this function is not the only method by +/// which a value can be leaked in safe Rust code. Other known sources of +/// leakage are: +/// +/// * `Rc` and `Arc` cycles +/// * `mpsc::{Sender, Receiver}` cycles (they use `Arc` internally) +/// * Panicking destructors are likely to leak local resources +/// +/// # Example +/// +/// ```rust,no_run +/// use std::mem; +/// use std::fs::File; +/// +/// // Leak some heap memory by never deallocating it +/// let heap_memory = Box::new(3); +/// mem::forget(heap_memory); +/// +/// // Leak an I/O object, never closing the file +/// let file = File::open("foo.txt").unwrap(); +/// mem::forget(file); +/// ``` #[stable(feature = "rust1", since = "1.0.0")] -pub use intrinsics::forget; +pub fn forget<T>(t: T) { + unsafe { intrinsics::forget(t) } +} /// Returns the size of a type in bytes. /// diff --git a/src/libcore/str/mod.rs b/src/libcore/str/mod.rs index 31431f44962..bdd9f5a7ba7 100644 --- a/src/libcore/str/mod.rs +++ b/src/libcore/str/mod.rs @@ -23,6 +23,7 @@ use self::pattern::{Searcher, ReverseSearcher, DoubleEndedSearcher}; use char::CharExt; use clone::Clone; use cmp::{self, Eq}; +use convert::AsRef; use default::Default; use fmt; use iter::ExactSizeIterator; @@ -1843,6 +1844,14 @@ impl StrExt for str { fn parse<T: FromStr>(&self) -> Result<T, T::Err> { FromStr::from_str(self) } } +#[stable(feature = "rust1", since = "1.0.0")] +impl AsRef<[u8]> for str { + #[inline] + fn as_ref(&self) -> &[u8] { + self.as_bytes() + } +} + /// Pluck a code point out of a UTF-8-like byte slice and return the /// index of the next code point. #[inline] diff --git a/src/libstd/sys/unix/fd.rs b/src/libstd/sys/unix/fd.rs index e5bdb554359..026380027d2 100644 --- a/src/libstd/sys/unix/fd.rs +++ b/src/libstd/sys/unix/fd.rs @@ -31,7 +31,7 @@ impl FileDesc { /// Extracts the actual filedescriptor without closing it. pub fn into_raw(self) -> c_int { let fd = self.fd; - unsafe { mem::forget(self) }; + mem::forget(self); fd } diff --git a/src/libstd/sys/windows/handle.rs b/src/libstd/sys/windows/handle.rs index 9481e180ce5..c835d503388 100644 --- a/src/libstd/sys/windows/handle.rs +++ b/src/libstd/sys/windows/handle.rs @@ -32,7 +32,7 @@ impl Handle { pub fn into_raw(self) -> HANDLE { let ret = self.0; - unsafe { mem::forget(self) } + mem::forget(self); return ret; } |
