mirror of
https://github.com/rust-lang/rust.git
synced 2026-05-07 09:13:07 +03:00
Merge pull request #25299 from alexcrichton/beta-backport
Backport mem::forget to beta
This commit is contained in:
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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]
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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
@@ -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.
|
||||
///
|
||||
|
||||
@@ -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]
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user