Merge pull request #25299 from alexcrichton/beta-backport

Backport mem::forget to beta
This commit is contained in:
Brian Anderson
2015-05-11 11:22:01 -07:00
9 changed files with 76 additions and 26 deletions
+5 -6
View File
@@ -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
}
+5 -6
View File
@@ -61,7 +61,6 @@
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 @@
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 @@ fn connect(&self, sep: &str) -> String {
// 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 @@ fn connect(&self, sep: &str) -> String {
} else {
result.push_str(sep);
}
result.push_str(s.as_ref());
result.push_str(s.borrow());
}
result
}
+8
View File
@@ -1005,6 +1005,14 @@ fn as_ref(&self) -> &str {
}
}
#[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]
+2 -2
View File
@@ -637,7 +637,7 @@ fn resize<T>(vec: &mut 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 @@ pub fn map_in_place<U, F>(self, mut f: F) -> Vec<U> where F: FnMut(T) -> U {
num_u: 0,
marker: PhantomData,
};
unsafe { mem::forget(vec); }
mem::forget(vec);
while pv.num_t != 0 {
unsafe {
-4
View File
@@ -217,10 +217,6 @@
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.
+45 -6
View File
@@ -22,15 +22,54 @@
#[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.
///
+9
View File
@@ -23,6 +23,7 @@
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 @@ fn is_empty(&self) -> bool { self.len() == 0 }
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]
+1 -1
View File
@@ -31,7 +31,7 @@ pub fn raw(&self) -> c_int { self.fd }
/// 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
}
+1 -1
View File
@@ -32,7 +32,7 @@ pub fn raw(&self) -> HANDLE { self.0 }
pub fn into_raw(self) -> HANDLE {
let ret = self.0;
unsafe { mem::forget(self) }
mem::forget(self);
return ret;
}