diff options
| author | bors <bors@rust-lang.org> | 2019-11-24 02:17:29 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2019-11-24 02:17:29 +0000 |
| commit | e41ced3f8d8e2f3f377ef931458e612d5f3d1f3f (patch) | |
| tree | 7d1fb15021ff6320393277ab0aeb5ce5ac5a566c /src/libcore | |
| parent | ad808d95c4839caedc2be76d0ed059dc920ab4b6 (diff) | |
| parent | d22bf91320cf3ba08326ca644e39de35592ce394 (diff) | |
| download | rust-e41ced3f8d8e2f3f377ef931458e612d5f3d1f3f.tar.gz rust-e41ced3f8d8e2f3f377ef931458e612d5f3d1f3f.zip | |
Auto merge of #66686 - Centril:rollup-07slyoo, r=Centril
Rollup of 5 pull requests Successful merges: - #64856 (Scope format! temporaries) - #66411 (mem::forget docs: mention ManuallyDrop) - #66594 (Fix cycle when debug-printing opaque types) - #66641 (parser: recover on nested ADTs as enum variants) - #66659 (make `./x.py bench` again) Failed merges: r? @ghost
Diffstat (limited to 'src/libcore')
| -rw-r--r-- | src/libcore/benches/num/mod.rs | 4 | ||||
| -rw-r--r-- | src/libcore/mem/mod.rs | 36 |
2 files changed, 35 insertions, 5 deletions
diff --git a/src/libcore/benches/num/mod.rs b/src/libcore/benches/num/mod.rs index f5c49ea5bf0..2dcdf2b6fe9 100644 --- a/src/libcore/benches/num/mod.rs +++ b/src/libcore/benches/num/mod.rs @@ -35,7 +35,7 @@ macro_rules! from_str_bench { .iter() .cycle() .take(5_000) - .filter_map(|s| <($t)>::from_str(s).ok()) + .filter_map(|s| <$t>::from_str(s).ok()) .max() }) } @@ -51,7 +51,7 @@ macro_rules! from_str_radix_bench { .iter() .cycle() .take(5_000) - .filter_map(|s| <($t)>::from_str_radix(s, $radix).ok()) + .filter_map(|s| <$t>::from_str_radix(s, $radix).ok()) .max() }) } diff --git a/src/libcore/mem/mod.rs b/src/libcore/mem/mod.rs index fff010385c3..bba441464ff 100644 --- a/src/libcore/mem/mod.rs +++ b/src/libcore/mem/mod.rs @@ -45,8 +45,9 @@ pub use crate::intrinsics::transmute; /// `mem::forget` from safe code does not fundamentally change Rust's safety /// guarantees. /// -/// That said, leaking resources such as memory or I/O objects is usually undesirable, -/// so `forget` is only recommended for specialized use cases like those shown below. +/// That said, leaking resources such as memory or I/O objects is usually undesirable. +/// The need comes up in some specialized use cases for FFI or unsafe code, but even +/// then, [`ManuallyDrop`] is typically preferred. /// /// Because forgetting a value is allowed, any `unsafe` code you write must /// allow for this possibility. You cannot return a value and expect that the @@ -68,7 +69,35 @@ pub use crate::intrinsics::transmute; /// ``` /// /// The practical use cases for `forget` are rather specialized and mainly come -/// up in unsafe or FFI code. +/// up in unsafe or FFI code. However, [`ManuallyDrop`] is usually preferred +/// for such cases, e.g.: +/// +/// ``` +/// use std::mem::ManuallyDrop; +/// +/// let v = vec![65, 122]; +/// // Before we disassemble `v` into its raw parts, make sure it +/// // does not get dropped! +/// let mut v = ManuallyDrop::new(v); +/// // Now disassemble `v`. These operations cannot panic, so there cannot be a leak. +/// let ptr = v.as_mut_ptr(); +/// let cap = v.capacity(); +/// // Finally, build a `String`. +/// let s = unsafe { String::from_raw_parts(ptr, 2, cap) }; +/// assert_eq!(s, "Az"); +/// // `s` is implicitly dropped and its memory deallocated. +/// ``` +/// +/// Using `ManuallyDrop` here has two advantages: +/// +/// * We do not "touch" `v` after disassembling it. For some types, operations +/// such as passing ownership (to a funcion like `mem::forget`) requires them to actually +/// be fully owned right now; that is a promise we do not want to make here as we are +/// in the process of transferring ownership to the new `String` we are building. +/// * In case of an unexpected panic, `ManuallyDrop` is not dropped, but if the panic +/// occurs before `mem::forget` was called we might end up dropping invalid data, +/// or double-dropping. In other words, `ManuallyDrop` errs on the side of leaking +/// instead of erring on the side of dropping. /// /// [drop]: fn.drop.html /// [uninit]: fn.uninitialized.html @@ -78,6 +107,7 @@ pub use crate::intrinsics::transmute; /// [leak]: ../../std/boxed/struct.Box.html#method.leak /// [into_raw]: ../../std/boxed/struct.Box.html#method.into_raw /// [ub]: ../../reference/behavior-considered-undefined.html +/// [`ManuallyDrop`]: struct.ManuallyDrop.html #[inline] #[stable(feature = "rust1", since = "1.0.0")] pub fn forget<T>(t: T) { |
