diff --git a/library/core/src/mem/manually_drop.rs b/library/core/src/mem/manually_drop.rs index 7d49da8509577..74f917bcf1cc5 100644 --- a/library/core/src/mem/manually_drop.rs +++ b/library/core/src/mem/manually_drop.rs @@ -1,4 +1,7 @@ -use crate::marker::Destruct; +use crate::cmp::Ordering; +use crate::hash::{Hash, Hasher}; +use crate::marker::{Destruct, StructuralPartialEq}; +use crate::mem::MaybeDangling; use crate::ops::{Deref, DerefMut, DerefPure}; use crate::ptr; @@ -152,11 +155,11 @@ use crate::ptr; /// [`MaybeUninit`]: crate::mem::MaybeUninit #[stable(feature = "manually_drop", since = "1.20.0")] #[lang = "manually_drop"] -#[derive(Copy, Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)] +#[derive(Copy, Clone, Debug, Default)] #[repr(transparent)] #[rustc_pub_transparent] pub struct ManuallyDrop { - value: T, + value: MaybeDangling, } impl ManuallyDrop { @@ -179,7 +182,7 @@ impl ManuallyDrop { #[rustc_const_stable(feature = "const_manually_drop", since = "1.32.0")] #[inline(always)] pub const fn new(value: T) -> ManuallyDrop { - ManuallyDrop { value } + ManuallyDrop { value: MaybeDangling::new(value) } } /// Extracts the value from the `ManuallyDrop` container. @@ -197,7 +200,7 @@ impl ManuallyDrop { #[rustc_const_stable(feature = "const_manually_drop", since = "1.32.0")] #[inline(always)] pub const fn into_inner(slot: ManuallyDrop) -> T { - slot.value + slot.value.into_inner() } /// Takes the value from the `ManuallyDrop` container out. @@ -222,7 +225,7 @@ impl ManuallyDrop { pub const unsafe fn take(slot: &mut ManuallyDrop) -> T { // SAFETY: we are reading from a reference, which is guaranteed // to be valid for reads. - unsafe { ptr::read(&slot.value) } + unsafe { ptr::read(slot.value.as_ref()) } } } @@ -259,7 +262,7 @@ impl ManuallyDrop { // SAFETY: we are dropping the value pointed to by a mutable reference // which is guaranteed to be valid for writes. // It is up to the caller to make sure that `slot` isn't dropped again. - unsafe { ptr::drop_in_place(&mut slot.value) } + unsafe { ptr::drop_in_place(slot.value.as_mut()) } } } @@ -269,7 +272,7 @@ impl const Deref for ManuallyDrop { type Target = T; #[inline(always)] fn deref(&self) -> &T { - &self.value + self.value.as_ref() } } @@ -278,9 +281,43 @@ impl const Deref for ManuallyDrop { impl const DerefMut for ManuallyDrop { #[inline(always)] fn deref_mut(&mut self) -> &mut T { - &mut self.value + self.value.as_mut() } } #[unstable(feature = "deref_pure_trait", issue = "87121")] unsafe impl DerefPure for ManuallyDrop {} + +#[stable(feature = "manually_drop", since = "1.20.0")] +impl Eq for ManuallyDrop {} + +#[stable(feature = "manually_drop", since = "1.20.0")] +impl PartialEq for ManuallyDrop { + fn eq(&self, other: &Self) -> bool { + self.value.as_ref().eq(other.value.as_ref()) + } +} + +#[stable(feature = "manually_drop", since = "1.20.0")] +impl StructuralPartialEq for ManuallyDrop {} + +#[stable(feature = "manually_drop", since = "1.20.0")] +impl Ord for ManuallyDrop { + fn cmp(&self, other: &Self) -> Ordering { + self.value.as_ref().cmp(other.value.as_ref()) + } +} + +#[stable(feature = "manually_drop", since = "1.20.0")] +impl PartialOrd for ManuallyDrop { + fn partial_cmp(&self, other: &Self) -> Option { + self.value.as_ref().partial_cmp(other.value.as_ref()) + } +} + +#[stable(feature = "manually_drop", since = "1.20.0")] +impl Hash for ManuallyDrop { + fn hash(&self, state: &mut H) { + self.value.as_ref().hash(state); + } +} diff --git a/library/core/src/mem/maybe_dangling.rs b/library/core/src/mem/maybe_dangling.rs new file mode 100644 index 0000000000000..4724003a6d1d8 --- /dev/null +++ b/library/core/src/mem/maybe_dangling.rs @@ -0,0 +1,102 @@ +#![unstable(feature = "maybe_dangling", issue = "118166")] + +use crate::{mem, ptr}; + +/// Allows wrapped [references] and [boxes] to dangle. +/// +/// That is, if a reference (or a `Box`) is wrapped in `MaybeDangling` (including when in a +/// (nested) field of a compound type wrapped in `MaybeDangling`), it does not have to follow +/// pointer aliasing rules or be dereferenceable. +/// +/// This can be useful when the value can become dangling while the function holding it is still +/// executing (particularly in concurrent code). As a somewhat absurd example, consider this code: +/// +/// ```rust,no_run +/// #![feature(box_as_ptr)] +/// # use std::alloc::{dealloc, Layout}; +/// # use std::mem; +/// +/// let mut boxed = Box::new(0_u32); +/// let ptr = Box::as_mut_ptr(&mut boxed); +/// +/// // Safety: the pointer comes from a box and thus was allocated before; `box` is not used afterwards +/// unsafe { dealloc(ptr.cast(), Layout::new::()) }; +/// +/// mem::forget(boxed); // <-- this is UB! +/// ``` +/// +/// Even though the `Box`e's destructor is not run (and thus we don't have a double free bug), this +/// code is still UB. This is because when moving `boxed` into `forget`, its validity invariants +/// are asserted, causing UB since the `Box` is dangling. +/// +/// To fix this we could use `MaybeDangling`: +/// +/// ```rust +/// #![feature(maybe_dangling, box_as_ptr)] +/// # use std::alloc::{dealloc, Layout}; +/// # use std::mem::{self, MaybeDangling}; +/// +/// let mut boxed = MaybeDangling::new(Box::new(0_u32)); +/// let ptr = Box::as_mut_ptr(boxed.as_mut()); +/// +/// // Safety: the pointer comes from a box and thus was allocated before; `box` is not used afterwards +/// unsafe { dealloc(ptr.cast(), Layout::new::()) }; +/// +/// mem::forget(boxed); // <-- this is OK! +/// ``` +/// +/// Note that the bit pattern must still be valid for the wrapped type. That is, [references] +/// (and [boxes]) still must be aligned and non-null. +/// +/// Additionally note that safe code can still assume that the inner value in a `MaybeDangling` is +/// **not** dangling -- functions like [`as_ref`] and [`into_inner`] are safe. It is not sound to +/// return a dangling reference in a `MaybeDangling` to safe code. However, it *is* sound +/// to hold such values internally inside your code -- and there's no way to do that without +/// this type. +/// +/// [references]: prim@reference +/// [boxes]: ../../std/boxed/struct.Box.html +/// [`into_inner`]: MaybeDangling::into_inner +/// [`as_ref`]: MaybeDangling::as_ref +#[repr(transparent)] +#[rustc_pub_transparent] +#[derive(Debug, Copy, Clone, Default)] +pub struct MaybeDangling(P); + +impl MaybeDangling

{ + /// Wraps a value in a `MaybeDangling`, allowing it to dangle. + pub const fn new(x: P) -> Self + where + P: Sized, + { + MaybeDangling(x) + } + + /// Returns a reference to the inner value. + /// + /// Note that this is UB if the inner value is currently dangling. + pub const fn as_ref(&self) -> &P { + &self.0 + } + + /// Returns a mutable reference to the inner value. + /// + /// Note that this is UB if the inner value is currently dangling. + pub const fn as_mut(&mut self) -> &mut P { + &mut self.0 + } + + /// Extracts the value from the `MaybeDangling` container. + /// + /// Note that this is UB if the inner value is currently dangling. + pub const fn into_inner(self) -> P + where + P: Sized, + { + // FIXME: replace this with `self.0` when const checker can figure out that `self` isn't actually dropped + // SAFETY: this is equivalent to `self.0` + let x = unsafe { ptr::read(&self.0) }; + mem::forget(self); + x + } +} diff --git a/library/core/src/mem/mod.rs b/library/core/src/mem/mod.rs index ad5fda0cfe4db..4f7edce1e977f 100644 --- a/library/core/src/mem/mod.rs +++ b/library/core/src/mem/mod.rs @@ -19,6 +19,10 @@ mod maybe_uninit; #[stable(feature = "maybe_uninit", since = "1.36.0")] pub use maybe_uninit::MaybeUninit; +mod maybe_dangling; +#[unstable(feature = "maybe_dangling", issue = "118166")] +pub use maybe_dangling::MaybeDangling; + mod transmutability; #[unstable(feature = "transmutability", issue = "99571")] pub use transmutability::{Assume, TransmuteFrom}; diff --git a/src/etc/gdb_providers.py b/src/etc/gdb_providers.py index 676842f66240d..b0b6682f5279e 100644 --- a/src/etc/gdb_providers.py +++ b/src/etc/gdb_providers.py @@ -298,7 +298,7 @@ def cast_to_internal(node): for i in xrange(0, length + 1): if height > 0: - child_ptr = edges[i]["value"]["value"] + child_ptr = edges[i]["value"]["value"][ZERO_FIELD] for child in children_of_node(child_ptr, height - 1): yield child if i < length: @@ -306,12 +306,12 @@ def cast_to_internal(node): key_type_size = keys.type.sizeof val_type_size = vals.type.sizeof key = ( - keys[i]["value"]["value"] + keys[i]["value"]["value"][ZERO_FIELD] if key_type_size > 0 else gdb.parse_and_eval("()") ) val = ( - vals[i]["value"]["value"] + vals[i]["value"]["value"][ZERO_FIELD] if val_type_size > 0 else gdb.parse_and_eval("()") ) diff --git a/src/tools/miri/tests/pass/stacked_borrows/stack-printing.stdout b/src/tools/miri/tests/pass/stacked_borrows/stack-printing.stdout index 296339e738455..de7da309271da 100644 --- a/src/tools/miri/tests/pass/stacked_borrows/stack-printing.stdout +++ b/src/tools/miri/tests/pass/stacked_borrows/stack-printing.stdout @@ -1,6 +1,6 @@ 0..1: [ SharedReadWrite ] 0..1: [ SharedReadWrite ] 0..1: [ SharedReadWrite ] -0..1: [ SharedReadWrite Unique Unique Unique Unique Unique Unique Unique ] -0..1: [ SharedReadWrite Disabled Disabled Disabled Disabled Disabled Disabled Disabled SharedReadOnly ] +0..1: [ SharedReadWrite Unique Unique Unique Unique Unique Unique Unique Unique Unique Unique Unique ] +0..1: [ SharedReadWrite Disabled Disabled Disabled Disabled Disabled Disabled Disabled Disabled Disabled Disabled Disabled SharedReadOnly ] 0..1: [ unknown-bottom(..) ] diff --git a/tests/mir-opt/pre-codegen/loops.vec_move.PreCodegen.after.mir b/tests/mir-opt/pre-codegen/loops.vec_move.PreCodegen.after.mir index 4260ec3eaedf1..6ab4b77123069 100644 --- a/tests/mir-opt/pre-codegen/loops.vec_move.PreCodegen.after.mir +++ b/tests/mir-opt/pre-codegen/loops.vec_move.PreCodegen.after.mir @@ -3,304 +3,322 @@ fn vec_move(_1: Vec) -> () { debug v => _1; let mut _0: (); - let mut _21: std::vec::IntoIter; let mut _22: std::vec::IntoIter; - let mut _23: &mut std::vec::IntoIter; - let mut _24: std::option::Option; - let mut _25: isize; - let _27: (); + let mut _23: std::vec::IntoIter; + let mut _24: &mut std::vec::IntoIter; + let mut _25: std::option::Option; + let mut _26: isize; + let _28: (); scope 1 { - debug iter => _22; - let _26: impl Sized; + debug iter => _23; + let _27: impl Sized; scope 2 { - debug x => _26; + debug x => _27; } } scope 3 (inlined as IntoIterator>::into_iter) { debug self => _1; - let _2: std::mem::ManuallyDrop>; - let mut _3: *const std::alloc::Global; - let mut _8: usize; - let mut _10: *mut impl Sized; - let mut _11: *const impl Sized; - let mut _12: usize; - let _28: &std::vec::Vec; - let mut _29: &std::mem::ManuallyDrop>; - let mut _30: &alloc::raw_vec::RawVec; - let mut _31: &std::mem::ManuallyDrop>; - let _32: &std::vec::Vec; - let mut _33: &std::mem::ManuallyDrop>; - let _34: &std::vec::Vec; - let mut _35: &std::mem::ManuallyDrop>; - let mut _36: &alloc::raw_vec::RawVec; - let mut _37: &std::mem::ManuallyDrop>; + let _3: std::mem::ManuallyDrop>; + let mut _4: *const std::alloc::Global; + let mut _9: usize; + let mut _11: *mut impl Sized; + let mut _12: *const impl Sized; + let mut _13: usize; + let _29: &std::vec::Vec; + let mut _30: &std::mem::ManuallyDrop>; + let mut _31: &alloc::raw_vec::RawVec; + let mut _32: &std::mem::ManuallyDrop>; + let _33: &std::vec::Vec; + let mut _34: &std::mem::ManuallyDrop>; + let _35: &std::vec::Vec; + let mut _36: &std::mem::ManuallyDrop>; + let mut _37: &alloc::raw_vec::RawVec; + let mut _38: &std::mem::ManuallyDrop>; scope 4 { - debug me => _2; + debug me => _3; scope 5 { - debug alloc => const ManuallyDrop:: {{ value: std::alloc::Global }}; - let _6: std::ptr::NonNull; + debug alloc => const ManuallyDrop:: {{ value: MaybeDangling::(std::alloc::Global) }}; + let _7: std::ptr::NonNull; scope 6 { - debug buf => _6; - let _7: *mut impl Sized; + debug buf => _7; + let _8: *mut impl Sized; scope 7 { - debug begin => _7; + debug begin => _8; scope 8 { - debug end => _11; - let _19: usize; + debug end => _12; + let _20: usize; scope 9 { - debug cap => _19; + debug cap => _20; } - scope 39 (inlined > as Deref>::deref) { - debug self => _37; + scope 45 (inlined > as Deref>::deref) { + debug self => _38; + scope 46 (inlined MaybeDangling::>::as_ref) { + } } - scope 40 (inlined alloc::raw_vec::RawVec::::capacity) { - debug self => _36; - let mut _38: &alloc::raw_vec::RawVecInner; - scope 41 (inlined std::mem::size_of::) { + scope 47 (inlined alloc::raw_vec::RawVec::::capacity) { + debug self => _37; + let mut _39: &alloc::raw_vec::RawVecInner; + scope 48 (inlined std::mem::size_of::) { } - scope 42 (inlined alloc::raw_vec::RawVecInner::capacity) { - debug self => _38; + scope 49 (inlined alloc::raw_vec::RawVecInner::capacity) { + debug self => _39; debug elem_size => const ::SIZE; - let mut _20: core::num::niche_types::UsizeNoHighBit; - scope 43 (inlined core::num::niche_types::UsizeNoHighBit::as_inner) { - debug self => _20; + let mut _21: core::num::niche_types::UsizeNoHighBit; + scope 50 (inlined core::num::niche_types::UsizeNoHighBit::as_inner) { + debug self => _21; } } } } - scope 25 (inlined > as Deref>::deref) { - debug self => _33; + scope 29 (inlined > as Deref>::deref) { + debug self => _34; + scope 30 (inlined MaybeDangling::>::as_ref) { + } } - scope 26 (inlined Vec::::len) { - debug self => _32; - let mut _13: bool; - scope 27 { + scope 31 (inlined Vec::::len) { + debug self => _33; + let mut _14: bool; + scope 32 { } } - scope 28 (inlined std::ptr::mut_ptr::::wrapping_byte_add) { - debug self => _7; - debug count => _12; - let mut _14: *mut u8; - let mut _18: *mut u8; - scope 29 (inlined std::ptr::mut_ptr::::cast::) { - debug self => _7; + scope 33 (inlined std::ptr::mut_ptr::::wrapping_byte_add) { + debug self => _8; + debug count => _13; + let mut _15: *mut u8; + let mut _19: *mut u8; + scope 34 (inlined std::ptr::mut_ptr::::cast::) { + debug self => _8; } - scope 30 (inlined std::ptr::mut_ptr::::wrapping_add) { - debug self => _14; - debug count => _12; - let mut _15: isize; - scope 31 (inlined std::ptr::mut_ptr::::wrapping_offset) { - debug self => _14; - debug count => _15; - let mut _16: *const u8; + scope 35 (inlined std::ptr::mut_ptr::::wrapping_add) { + debug self => _15; + debug count => _13; + let mut _16: isize; + scope 36 (inlined std::ptr::mut_ptr::::wrapping_offset) { + debug self => _15; + debug count => _16; let mut _17: *const u8; + let mut _18: *const u8; } } - scope 32 (inlined std::ptr::mut_ptr::::with_metadata_of::) { - debug self => _18; - debug meta => _5; - scope 33 (inlined std::ptr::metadata::) { - debug ptr => _5; + scope 37 (inlined std::ptr::mut_ptr::::with_metadata_of::) { + debug self => _19; + debug meta => _6; + scope 38 (inlined std::ptr::metadata::) { + debug ptr => _6; } - scope 34 (inlined std::ptr::from_raw_parts_mut::) { + scope 39 (inlined std::ptr::from_raw_parts_mut::) { } } } - scope 35 (inlined > as Deref>::deref) { - debug self => _35; + scope 40 (inlined > as Deref>::deref) { + debug self => _36; + scope 41 (inlined MaybeDangling::>::as_ref) { + } } - scope 36 (inlined Vec::::len) { - debug self => _34; - let mut _9: bool; - scope 37 { + scope 42 (inlined Vec::::len) { + debug self => _35; + let mut _10: bool; + scope 43 { } } - scope 38 (inlined #[track_caller] std::ptr::mut_ptr::::add) { - debug self => _7; - debug count => _8; + scope 44 (inlined #[track_caller] std::ptr::mut_ptr::::add) { + debug self => _8; + debug count => _9; } } - scope 24 (inlined NonNull::::as_ptr) { - debug self => _6; + scope 28 (inlined NonNull::::as_ptr) { + debug self => _7; } } - scope 17 (inlined > as Deref>::deref) { - debug self => _31; + scope 20 (inlined > as Deref>::deref) { + debug self => _32; + scope 21 (inlined MaybeDangling::>::as_ref) { + } } - scope 18 (inlined alloc::raw_vec::RawVec::::non_null) { - debug self => _30; - scope 19 (inlined alloc::raw_vec::RawVecInner::non_null::) { - let mut _4: std::ptr::NonNull; - scope 20 (inlined Unique::::cast::) { - scope 21 (inlined NonNull::::cast::) { - let mut _5: *const impl Sized; - scope 22 (inlined NonNull::::as_ptr) { + scope 22 (inlined alloc::raw_vec::RawVec::::non_null) { + debug self => _31; + scope 23 (inlined alloc::raw_vec::RawVecInner::non_null::) { + let mut _5: std::ptr::NonNull; + scope 24 (inlined Unique::::cast::) { + scope 25 (inlined NonNull::::cast::) { + let mut _6: *const impl Sized; + scope 26 (inlined NonNull::::as_ptr) { } } } - scope 23 (inlined Unique::::as_non_null_ptr) { + scope 27 (inlined Unique::::as_non_null_ptr) { } } } } - scope 11 (inlined > as Deref>::deref) { - debug self => _29; + scope 12 (inlined > as Deref>::deref) { + debug self => _30; + scope 13 (inlined MaybeDangling::>::as_ref) { + } } - scope 12 (inlined Vec::::allocator) { - debug self => _28; - scope 13 (inlined alloc::raw_vec::RawVec::::allocator) { - scope 14 (inlined alloc::raw_vec::RawVecInner::allocator) { + scope 14 (inlined Vec::::allocator) { + debug self => _29; + scope 15 (inlined alloc::raw_vec::RawVec::::allocator) { + scope 16 (inlined alloc::raw_vec::RawVecInner::allocator) { } } } - scope 15 (inlined #[track_caller] std::ptr::read::) { - debug src => _3; + scope 17 (inlined #[track_caller] std::ptr::read::) { + debug src => _4; } - scope 16 (inlined ManuallyDrop::::new) { + scope 18 (inlined ManuallyDrop::::new) { debug value => const std::alloc::Global; + scope 19 (inlined MaybeDangling::::new) { + } } } scope 10 (inlined ManuallyDrop::>::new) { debug value => _1; + let mut _2: std::mem::MaybeDangling>; + scope 11 (inlined MaybeDangling::>::new) { + } } } bb0: { - StorageLive(_21); - StorageLive(_6); + StorageLive(_22); StorageLive(_7); - StorageLive(_11); - StorageLive(_19); + StorageLive(_8); + StorageLive(_12); + StorageLive(_20); + StorageLive(_6); StorageLive(_5); - StorageLive(_4); - StorageLive(_17); - StorageLive(_2); - _2 = ManuallyDrop::> { value: copy _1 }; + StorageLive(_18); StorageLive(_3); - // DBG: _29 = &_2; - // DBG: _28 = &(_2.0: std::vec::Vec); - _3 = &raw const ((((_2.0: std::vec::Vec).0: alloc::raw_vec::RawVec).0: alloc::raw_vec::RawVecInner).2: std::alloc::Global); - StorageDead(_3); - // DBG: _31 = &_2; - // DBG: _30 = &((_2.0: std::vec::Vec).0: alloc::raw_vec::RawVec); - _4 = copy (((((_2.0: std::vec::Vec).0: alloc::raw_vec::RawVec).0: alloc::raw_vec::RawVecInner).0: std::ptr::Unique).0: std::ptr::NonNull); - _5 = copy _4 as *const impl Sized (Transmute); - _6 = NonNull:: { pointer: copy _5 }; - _7 = copy _4 as *mut impl Sized (Transmute); + StorageLive(_2); + _2 = MaybeDangling::>(copy _1); + _3 = ManuallyDrop::> { value: move _2 }; + StorageDead(_2); + StorageLive(_4); + // DBG: _30 = &_3; + // DBG: _29 = &((_3.0: std::mem::MaybeDangling>).0: std::vec::Vec); + _4 = &raw const (((((_3.0: std::mem::MaybeDangling>).0: std::vec::Vec).0: alloc::raw_vec::RawVec).0: alloc::raw_vec::RawVecInner).2: std::alloc::Global); + StorageDead(_4); + // DBG: _32 = &_3; + // DBG: _31 = &(((_3.0: std::mem::MaybeDangling>).0: std::vec::Vec).0: alloc::raw_vec::RawVec); + _5 = copy ((((((_3.0: std::mem::MaybeDangling>).0: std::vec::Vec).0: alloc::raw_vec::RawVec).0: alloc::raw_vec::RawVecInner).0: std::ptr::Unique).0: std::ptr::NonNull); + _6 = copy _5 as *const impl Sized (Transmute); + _7 = NonNull:: { pointer: copy _6 }; + _8 = copy _5 as *mut impl Sized (Transmute); switchInt(const ::IS_ZST) -> [0: bb1, otherwise: bb2]; } bb1: { - StorageLive(_10); - StorageLive(_8); - // DBG: _35 = &_2; - // DBG: _34 = &(_2.0: std::vec::Vec); - _8 = copy ((_2.0: std::vec::Vec).1: usize); + StorageLive(_11); StorageLive(_9); - _9 = Le(copy _8, const ::MAX_SLICE_LEN); - assume(move _9); - StorageDead(_9); - _10 = Offset(copy _7, copy _8); - _11 = copy _10 as *const impl Sized (PtrToPtr); - StorageDead(_8); + // DBG: _36 = &_3; + // DBG: _35 = &((_3.0: std::mem::MaybeDangling>).0: std::vec::Vec); + _9 = copy (((_3.0: std::mem::MaybeDangling>).0: std::vec::Vec).1: usize); + StorageLive(_10); + _10 = Le(copy _9, const ::MAX_SLICE_LEN); + assume(move _10); StorageDead(_10); + _11 = Offset(copy _8, copy _9); + _12 = copy _11 as *const impl Sized (PtrToPtr); + StorageDead(_9); + StorageDead(_11); goto -> bb4; } bb2: { - StorageLive(_12); - // DBG: _33 = &_2; - // DBG: _32 = &(_2.0: std::vec::Vec); - _12 = copy ((_2.0: std::vec::Vec).1: usize); StorageLive(_13); - _13 = Le(copy _12, const ::MAX_SLICE_LEN); - assume(move _13); - StorageDead(_13); - StorageLive(_18); + // DBG: _34 = &_3; + // DBG: _33 = &((_3.0: std::mem::MaybeDangling>).0: std::vec::Vec); + _13 = copy (((_3.0: std::mem::MaybeDangling>).0: std::vec::Vec).1: usize); StorageLive(_14); - _14 = copy _4 as *mut u8 (Transmute); + _14 = Le(copy _13, const ::MAX_SLICE_LEN); + assume(move _14); + StorageDead(_14); + StorageLive(_19); StorageLive(_15); - _15 = copy _12 as isize (IntToInt); + _15 = copy _5 as *mut u8 (Transmute); StorageLive(_16); - _16 = copy _4 as *const u8 (Transmute); - _17 = arith_offset::(move _16, move _15) -> [return: bb3, unwind unreachable]; + _16 = copy _13 as isize (IntToInt); + StorageLive(_17); + _17 = copy _5 as *const u8 (Transmute); + _18 = arith_offset::(move _17, move _16) -> [return: bb3, unwind unreachable]; } bb3: { + StorageDead(_17); + _19 = copy _18 as *mut u8 (PtrToPtr); StorageDead(_16); - _18 = copy _17 as *mut u8 (PtrToPtr); StorageDead(_15); - StorageDead(_14); - StorageDead(_18); - StorageDead(_12); - _11 = copy _17 as *const impl Sized (PtrToPtr); + StorageDead(_19); + StorageDead(_13); + _12 = copy _18 as *const impl Sized (PtrToPtr); goto -> bb4; } bb4: { - // DBG: _37 = &_2; - // DBG: _36 = &((_2.0: std::vec::Vec).0: alloc::raw_vec::RawVec); - // DBG: _38 = &(((_2.0: std::vec::Vec).0: alloc::raw_vec::RawVec).0: alloc::raw_vec::RawVecInner); + // DBG: _38 = &_3; + // DBG: _37 = &(((_3.0: std::mem::MaybeDangling>).0: std::vec::Vec).0: alloc::raw_vec::RawVec); + // DBG: _39 = &((((_3.0: std::mem::MaybeDangling>).0: std::vec::Vec).0: alloc::raw_vec::RawVec).0: alloc::raw_vec::RawVecInner); switchInt(const ::SIZE) -> [0: bb5, otherwise: bb6]; } bb5: { - _19 = const usize::MAX; + _20 = const usize::MAX; goto -> bb7; } bb6: { - StorageLive(_20); - _20 = copy ((((_2.0: std::vec::Vec).0: alloc::raw_vec::RawVec).0: alloc::raw_vec::RawVecInner).1: core::num::niche_types::UsizeNoHighBit); - _19 = copy _20 as usize (Transmute); - StorageDead(_20); + StorageLive(_21); + _21 = copy (((((_3.0: std::mem::MaybeDangling>).0: std::vec::Vec).0: alloc::raw_vec::RawVec).0: alloc::raw_vec::RawVecInner).1: core::num::niche_types::UsizeNoHighBit); + _20 = copy _21 as usize (Transmute); + StorageDead(_21); goto -> bb7; } bb7: { - _21 = std::vec::IntoIter:: { buf: copy _6, phantom: const ZeroSized: PhantomData, cap: move _19, alloc: const ManuallyDrop:: {{ value: std::alloc::Global }}, ptr: copy _6, end: copy _11 }; - StorageDead(_2); - StorageDead(_17); - StorageDead(_4); + _22 = std::vec::IntoIter:: { buf: copy _7, phantom: const ZeroSized: PhantomData, cap: move _20, alloc: const ManuallyDrop:: {{ value: MaybeDangling::(std::alloc::Global) }}, ptr: copy _7, end: copy _12 }; + StorageDead(_3); + StorageDead(_18); StorageDead(_5); - StorageDead(_19); - StorageDead(_11); - StorageDead(_7); StorageDead(_6); - StorageLive(_22); - _22 = move _21; + StorageDead(_20); + StorageDead(_12); + StorageDead(_8); + StorageDead(_7); + StorageLive(_23); + _23 = move _22; goto -> bb8; } bb8: { - StorageLive(_24); - _23 = &mut _22; - _24 = as Iterator>::next(move _23) -> [return: bb9, unwind: bb15]; + StorageLive(_25); + _24 = &mut _23; + _25 = as Iterator>::next(move _24) -> [return: bb9, unwind: bb15]; } bb9: { - _25 = discriminant(_24); - switchInt(move _25) -> [0: bb10, 1: bb12, otherwise: bb14]; + _26 = discriminant(_25); + switchInt(move _26) -> [0: bb10, 1: bb12, otherwise: bb14]; } bb10: { - StorageDead(_24); - drop(_22) -> [return: bb11, unwind continue]; + StorageDead(_25); + drop(_23) -> [return: bb11, unwind continue]; } bb11: { + StorageDead(_23); StorageDead(_22); - StorageDead(_21); return; } bb12: { - _26 = move ((_24 as Some).0: impl Sized); - _27 = opaque::(move _26) -> [return: bb13, unwind: bb15]; + _27 = move ((_25 as Some).0: impl Sized); + _28 = opaque::(move _27) -> [return: bb13, unwind: bb15]; } bb13: { - StorageDead(_24); + StorageDead(_25); goto -> bb8; } @@ -309,7 +327,7 @@ fn vec_move(_1: Vec) -> () { } bb15 (cleanup): { - drop(_22) -> [return: bb16, unwind terminate(cleanup)]; + drop(_23) -> [return: bb16, unwind terminate(cleanup)]; } bb16 (cleanup): { diff --git a/tests/ui/async-await/future-sizes/async-awaiting-fut.stdout b/tests/ui/async-await/future-sizes/async-awaiting-fut.stdout index b30c15bcbe6ed..13f03ffa65b5d 100644 --- a/tests/ui/async-await/future-sizes/async-awaiting-fut.stdout +++ b/tests/ui/async-await/future-sizes/async-awaiting-fut.stdout @@ -7,6 +7,8 @@ print-type-size variant `Returned`: 0 bytes print-type-size variant `Panicked`: 0 bytes print-type-size type: `std::mem::ManuallyDrop<{async fn body of calls_fut<{async fn body of big_fut()}>()}>`: 3077 bytes, alignment: 1 bytes print-type-size field `.value`: 3077 bytes +print-type-size type: `std::mem::MaybeDangling<{async fn body of calls_fut<{async fn body of big_fut()}>()}>`: 3077 bytes, alignment: 1 bytes +print-type-size field `.0`: 3077 bytes print-type-size type: `std::mem::MaybeUninit<{async fn body of calls_fut<{async fn body of big_fut()}>()}>`: 3077 bytes, alignment: 1 bytes print-type-size variant `MaybeUninit`: 3077 bytes print-type-size field `.uninit`: 0 bytes @@ -36,6 +38,8 @@ print-type-size variant `Panicked`: 1025 bytes print-type-size upvar `.fut`: 1025 bytes print-type-size type: `std::mem::ManuallyDrop<{async fn body of big_fut()}>`: 1025 bytes, alignment: 1 bytes print-type-size field `.value`: 1025 bytes +print-type-size type: `std::mem::MaybeDangling<{async fn body of big_fut()}>`: 1025 bytes, alignment: 1 bytes +print-type-size field `.0`: 1025 bytes print-type-size type: `std::mem::MaybeUninit<{async fn body of big_fut()}>`: 1025 bytes, alignment: 1 bytes print-type-size variant `MaybeUninit`: 1025 bytes print-type-size field `.uninit`: 0 bytes @@ -85,6 +89,10 @@ print-type-size type: `std::mem::ManuallyDrop`: 1 bytes, alignment: 1 byte print-type-size field `.value`: 1 bytes print-type-size type: `std::mem::ManuallyDrop<{async fn body of wait()}>`: 1 bytes, alignment: 1 bytes print-type-size field `.value`: 1 bytes +print-type-size type: `std::mem::MaybeDangling`: 1 bytes, alignment: 1 bytes +print-type-size field `.0`: 1 bytes +print-type-size type: `std::mem::MaybeDangling<{async fn body of wait()}>`: 1 bytes, alignment: 1 bytes +print-type-size field `.0`: 1 bytes print-type-size type: `std::mem::MaybeUninit`: 1 bytes, alignment: 1 bytes print-type-size variant `MaybeUninit`: 1 bytes print-type-size field `.uninit`: 0 bytes diff --git a/tests/ui/async-await/future-sizes/large-arg.stdout b/tests/ui/async-await/future-sizes/large-arg.stdout index e00420d1493f4..d51afa33595cb 100644 --- a/tests/ui/async-await/future-sizes/large-arg.stdout +++ b/tests/ui/async-await/future-sizes/large-arg.stdout @@ -7,6 +7,8 @@ print-type-size variant `Returned`: 0 bytes print-type-size variant `Panicked`: 0 bytes print-type-size type: `std::mem::ManuallyDrop<{async fn body of a<[u8; 1024]>()}>`: 3075 bytes, alignment: 1 bytes print-type-size field `.value`: 3075 bytes +print-type-size type: `std::mem::MaybeDangling<{async fn body of a<[u8; 1024]>()}>`: 3075 bytes, alignment: 1 bytes +print-type-size field `.0`: 3075 bytes print-type-size type: `std::mem::MaybeUninit<{async fn body of a<[u8; 1024]>()}>`: 3075 bytes, alignment: 1 bytes print-type-size variant `MaybeUninit`: 3075 bytes print-type-size field `.uninit`: 0 bytes @@ -24,6 +26,8 @@ print-type-size variant `Panicked`: 1024 bytes print-type-size upvar `.t`: 1024 bytes print-type-size type: `std::mem::ManuallyDrop<{async fn body of b<[u8; 1024]>()}>`: 2050 bytes, alignment: 1 bytes print-type-size field `.value`: 2050 bytes +print-type-size type: `std::mem::MaybeDangling<{async fn body of b<[u8; 1024]>()}>`: 2050 bytes, alignment: 1 bytes +print-type-size field `.0`: 2050 bytes print-type-size type: `std::mem::MaybeUninit<{async fn body of b<[u8; 1024]>()}>`: 2050 bytes, alignment: 1 bytes print-type-size variant `MaybeUninit`: 2050 bytes print-type-size field `.uninit`: 0 bytes @@ -41,6 +45,8 @@ print-type-size variant `Panicked`: 1024 bytes print-type-size upvar `.t`: 1024 bytes print-type-size type: `std::mem::ManuallyDrop<{async fn body of c<[u8; 1024]>()}>`: 1025 bytes, alignment: 1 bytes print-type-size field `.value`: 1025 bytes +print-type-size type: `std::mem::MaybeDangling<{async fn body of c<[u8; 1024]>()}>`: 1025 bytes, alignment: 1 bytes +print-type-size field `.0`: 1025 bytes print-type-size type: `std::mem::MaybeUninit<{async fn body of c<[u8; 1024]>()}>`: 1025 bytes, alignment: 1 bytes print-type-size variant `MaybeUninit`: 1025 bytes print-type-size field `.uninit`: 0 bytes diff --git a/tests/ui/print_type_sizes/async.stdout b/tests/ui/print_type_sizes/async.stdout index d3d6b6471c6ef..d2adff80e3c9c 100644 --- a/tests/ui/print_type_sizes/async.stdout +++ b/tests/ui/print_type_sizes/async.stdout @@ -12,6 +12,8 @@ print-type-size variant `Panicked`: 8192 bytes print-type-size upvar `.arg`: 8192 bytes print-type-size type: `std::mem::ManuallyDrop<[u8; 8192]>`: 8192 bytes, alignment: 1 bytes print-type-size field `.value`: 8192 bytes +print-type-size type: `std::mem::MaybeDangling<[u8; 8192]>`: 8192 bytes, alignment: 1 bytes +print-type-size field `.0`: 8192 bytes print-type-size type: `std::mem::MaybeUninit<[u8; 8192]>`: 8192 bytes, alignment: 1 bytes print-type-size variant `MaybeUninit`: 8192 bytes print-type-size field `.uninit`: 0 bytes @@ -47,6 +49,8 @@ print-type-size type: `std::ptr::NonNull`: 8 bytes, print-type-size field `.pointer`: 8 bytes print-type-size type: `std::mem::ManuallyDrop<{async fn body of wait()}>`: 1 bytes, alignment: 1 bytes print-type-size field `.value`: 1 bytes +print-type-size type: `std::mem::MaybeDangling<{async fn body of wait()}>`: 1 bytes, alignment: 1 bytes +print-type-size field `.0`: 1 bytes print-type-size type: `std::mem::MaybeUninit<{async fn body of wait()}>`: 1 bytes, alignment: 1 bytes print-type-size variant `MaybeUninit`: 1 bytes print-type-size field `.uninit`: 0 bytes diff --git a/tests/ui/print_type_sizes/coroutine_discr_placement.stdout b/tests/ui/print_type_sizes/coroutine_discr_placement.stdout index 4ce1ce46f6e82..b51beb514ba80 100644 --- a/tests/ui/print_type_sizes/coroutine_discr_placement.stdout +++ b/tests/ui/print_type_sizes/coroutine_discr_placement.stdout @@ -11,6 +11,8 @@ print-type-size variant `Returned`: 0 bytes print-type-size variant `Panicked`: 0 bytes print-type-size type: `std::mem::ManuallyDrop`: 4 bytes, alignment: 4 bytes print-type-size field `.value`: 4 bytes +print-type-size type: `std::mem::MaybeDangling`: 4 bytes, alignment: 4 bytes +print-type-size field `.0`: 4 bytes print-type-size type: `std::mem::MaybeUninit`: 4 bytes, alignment: 4 bytes print-type-size variant `MaybeUninit`: 4 bytes print-type-size field `.uninit`: 0 bytes diff --git a/tests/ui/thir-print/offset_of.stdout b/tests/ui/thir-print/offset_of.stdout index 846817f475288..ab924091ba7a0 100644 --- a/tests/ui/thir-print/offset_of.stdout +++ b/tests/ui/thir-print/offset_of.stdout @@ -68,7 +68,7 @@ body: ) else_block: None lint_level: Explicit(HirId(DefId(offset_of::concrete).10)) - span: $DIR/offset_of.rs:37:5: 1433:57 (#0) + span: $DIR/offset_of.rs:37:5: 1437:57 (#0) } } Stmt { @@ -117,7 +117,7 @@ body: ) else_block: None lint_level: Explicit(HirId(DefId(offset_of::concrete).20)) - span: $DIR/offset_of.rs:38:5: 1433:57 (#0) + span: $DIR/offset_of.rs:38:5: 1437:57 (#0) } } Stmt { @@ -166,7 +166,7 @@ body: ) else_block: None lint_level: Explicit(HirId(DefId(offset_of::concrete).30)) - span: $DIR/offset_of.rs:39:5: 1433:57 (#0) + span: $DIR/offset_of.rs:39:5: 1437:57 (#0) } } Stmt { @@ -215,7 +215,7 @@ body: ) else_block: None lint_level: Explicit(HirId(DefId(offset_of::concrete).40)) - span: $DIR/offset_of.rs:40:5: 1433:57 (#0) + span: $DIR/offset_of.rs:40:5: 1437:57 (#0) } } Stmt { @@ -264,7 +264,7 @@ body: ) else_block: None lint_level: Explicit(HirId(DefId(offset_of::concrete).50)) - span: $DIR/offset_of.rs:41:5: 1433:57 (#0) + span: $DIR/offset_of.rs:41:5: 1437:57 (#0) } } ] @@ -864,7 +864,7 @@ body: ) else_block: None lint_level: Explicit(HirId(DefId(offset_of::generic).12)) - span: $DIR/offset_of.rs:45:5: 1433:57 (#0) + span: $DIR/offset_of.rs:45:5: 1437:57 (#0) } } Stmt { @@ -913,7 +913,7 @@ body: ) else_block: None lint_level: Explicit(HirId(DefId(offset_of::generic).24)) - span: $DIR/offset_of.rs:46:5: 1433:57 (#0) + span: $DIR/offset_of.rs:46:5: 1437:57 (#0) } } Stmt { @@ -962,7 +962,7 @@ body: ) else_block: None lint_level: Explicit(HirId(DefId(offset_of::generic).36)) - span: $DIR/offset_of.rs:47:5: 1433:57 (#0) + span: $DIR/offset_of.rs:47:5: 1437:57 (#0) } } Stmt { @@ -1011,7 +1011,7 @@ body: ) else_block: None lint_level: Explicit(HirId(DefId(offset_of::generic).48)) - span: $DIR/offset_of.rs:48:5: 1433:57 (#0) + span: $DIR/offset_of.rs:48:5: 1437:57 (#0) } } ]