diff --git a/library/core/src/intrinsics/mod.rs b/library/core/src/intrinsics/mod.rs index e5604d277f57a..205729e4a4e77 100644 --- a/library/core/src/intrinsics/mod.rs +++ b/library/core/src/intrinsics/mod.rs @@ -3410,6 +3410,7 @@ pub const fn contract_checks() -> bool { // doesn't honor `#[allow_internal_unstable]`, so for the const feature gate we use the user-facing // `contracts` feature rather than the perma-unstable `contracts_internals` #[rustc_const_unstable(feature = "contracts", issue = "128044")] +#[miri::intrinsic_fallback_is_spec] #[lang = "contract_check_requires"] #[rustc_intrinsic] pub const fn contract_check_requires bool + Copy>(cond: C) { @@ -3438,6 +3439,7 @@ pub const fn contract_check_requires bool + Copy>(cond: C) { // `contracts` feature rather than the perma-unstable `contracts_internals`. // Const-checking doesn't honor allow_internal_unstable logic used by contract expansion. #[rustc_const_unstable(feature = "contracts", issue = "128044")] +#[miri::intrinsic_fallback_is_spec] #[lang = "contract_check_ensures"] #[rustc_intrinsic] pub const fn contract_check_ensures bool + Copy, Ret>(cond: C, ret: Ret) -> Ret { @@ -3459,6 +3461,7 @@ pub const fn contract_check_ensures bool + Copy, Ret>(cond: C, re /// This is the old version of contract_check_ensures kept here for bootstrap only. #[cfg(bootstrap)] #[unstable(feature = "contracts_internals", issue = "128044" /* compiler-team#759 */)] +#[miri::intrinsic_fallback_is_spec] #[rustc_intrinsic] pub fn contract_check_ensures<'a, Ret, C: Fn(&'a Ret) -> bool>(ret: &'a Ret, cond: C) { if contract_checks() && !cond(ret) { diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs index 9625475e617ea..825ca74e84c0f 100644 --- a/library/core/src/lib.rs +++ b/library/core/src/lib.rs @@ -95,6 +95,7 @@ // // Library features: // tidy-alphabetical-start +#![cfg_attr(not(bootstrap), feature(contracts))] #![feature(array_ptr_get)] #![feature(asm_experimental_arch)] #![feature(bigint_helper_methods)] diff --git a/library/core/src/mem/mod.rs b/library/core/src/mem/mod.rs index 27387754633d1..1b235ef02eaf4 100644 --- a/library/core/src/mem/mod.rs +++ b/library/core/src/mem/mod.rs @@ -476,6 +476,8 @@ pub const fn align_of() -> usize { #[stable(feature = "rust1", since = "1.0.0")] #[rustc_const_stable(feature = "const_align_of_val", since = "1.85.0")] #[allow(deprecated)] +#[rustc_allow_const_fn_unstable(contracts)] +#[cfg_attr(not(bootstrap), core::contracts::ensures(|result: &usize| result.is_power_of_two()))] pub const fn align_of_val(val: &T) -> usize { // SAFETY: val is a reference, so it's a valid raw pointer unsafe { intrinsics::min_align_of_val(val) } diff --git a/library/core/src/ptr/alignment.rs b/library/core/src/ptr/alignment.rs index 19311e39b454e..e6e5c8de41fe3 100644 --- a/library/core/src/ptr/alignment.rs +++ b/library/core/src/ptr/alignment.rs @@ -43,6 +43,9 @@ impl Alignment { #[unstable(feature = "ptr_alignment_type", issue = "102070")] #[inline] #[must_use] + #[rustc_allow_const_fn_unstable(contracts)] + #[cfg_attr(not(bootstrap), core::contracts::ensures( + |result: &Alignment| result.as_usize().is_power_of_two()))] pub const fn of() -> Self { // This can't actually panic since type alignment is always a power of two. const { Alignment::new(align_of::()).unwrap() } @@ -54,6 +57,11 @@ impl Alignment { /// Note that `0` is not a power of two, nor a valid alignment. #[unstable(feature = "ptr_alignment_type", issue = "102070")] #[inline] + #[rustc_allow_const_fn_unstable(contracts)] + #[cfg_attr(not(bootstrap), core::contracts::ensures( + move + |result: &Option| align.is_power_of_two() == result.is_some() && + (result.is_none() || result.unwrap().as_usize() == align)))] pub const fn new(align: usize) -> Option { if align.is_power_of_two() { // SAFETY: Just checked it only has one bit set @@ -73,6 +81,12 @@ impl Alignment { /// It must *not* be zero. #[unstable(feature = "ptr_alignment_type", issue = "102070")] #[inline] + #[cfg_attr(not(bootstrap), rustc_const_unstable(feature = "contracts", issue = "128044"))] + #[cfg_attr(not(bootstrap), core::contracts::requires(align.is_power_of_two()))] + #[cfg_attr(not(bootstrap), core::contracts::ensures( + move + |result: &Alignment| result.as_usize() == align && + result.as_usize().is_power_of_two()))] pub const unsafe fn new_unchecked(align: usize) -> Self { assert_unsafe_precondition!( check_language_ub, @@ -88,6 +102,9 @@ impl Alignment { /// Returns the alignment as a [`usize`]. #[unstable(feature = "ptr_alignment_type", issue = "102070")] #[inline] + #[rustc_allow_const_fn_unstable(contracts)] + #[cfg_attr(not(bootstrap), core::contracts::ensures( + |result: &usize| result.is_power_of_two()))] pub const fn as_usize(self) -> usize { self.0 as usize } @@ -95,6 +112,11 @@ impl Alignment { /// Returns the alignment as a [NonZero]<[usize]>. #[unstable(feature = "ptr_alignment_type", issue = "102070")] #[inline] + #[rustc_allow_const_fn_unstable(contracts)] + #[cfg_attr(not(bootstrap), core::contracts::ensures( + move + |result: &NonZero| result.get().is_power_of_two() && + result.get() == self.as_usize()))] pub const fn as_nonzero(self) -> NonZero { // This transmutes directly to avoid the UbCheck in `NonZero::new_unchecked` // since there's no way for the user to trip that check anyway -- the @@ -120,6 +142,12 @@ impl Alignment { /// ``` #[unstable(feature = "ptr_alignment_type", issue = "102070")] #[inline] + #[cfg_attr(not(bootstrap), rustc_const_unstable(feature = "contracts", issue = "128044"))] + #[cfg_attr(not(bootstrap), core::contracts::requires(self.as_usize().is_power_of_two()))] + #[cfg_attr(not(bootstrap), core::contracts::ensures( + move + |result: &u32| *result < usize::BITS && + (1usize << *result) == self.as_usize()))] pub const fn log2(self) -> u32 { self.as_nonzero().trailing_zeros() } @@ -149,6 +177,12 @@ impl Alignment { /// ``` #[unstable(feature = "ptr_alignment_type", issue = "102070")] #[inline] + #[cfg_attr(not(bootstrap), rustc_const_unstable(feature = "contracts", issue = "128044"))] + #[cfg_attr(not(bootstrap), core::contracts::ensures( + move + |result: &usize| *result > 0 && + *result == !(self.as_usize() -1) && + self.as_usize() & *result == self.as_usize()))] pub const fn mask(self) -> usize { // SAFETY: The alignment is always nonzero, and therefore decrementing won't overflow. !(unsafe { self.as_usize().unchecked_sub(1) }) diff --git a/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.DataflowConstProp.32bit.panic-abort.diff b/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.DataflowConstProp.32bit.panic-abort.diff index 2c89670dcf7d7..e22e91ce09cf4 100644 --- a/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.DataflowConstProp.32bit.panic-abort.diff +++ b/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.DataflowConstProp.32bit.panic-abort.diff @@ -16,23 +16,34 @@ scope 4 (inlined Unique::<[bool; 0]>::dangling) { let mut _5: std::ptr::NonNull<[bool; 0]>; scope 5 (inlined NonNull::<[bool; 0]>::dangling) { - let mut _6: std::num::NonZero; + let _6: std::ptr::Alignment; + let mut _7: std::num::NonZero; scope 6 { - scope 8 (inlined std::ptr::Alignment::as_nonzero) { + scope 10 (inlined std::ptr::Alignment::as_nonzero) { + let mut _8: {closure@std::ptr::Alignment::as_nonzero::{closure#0}}; + let mut _9: std::num::NonZero; + scope 11 { + } + scope 12 (inlined core::contracts::build_check_ensures::, {closure@std::ptr::Alignment::as_nonzero::{closure#0}}>) { + } } - scope 9 (inlined NonNull::<[bool; 0]>::without_provenance) { - let _7: *const [bool; 0]; - scope 10 { + scope 13 (inlined NonNull::<[bool; 0]>::without_provenance) { + let _10: *const [bool; 0]; + scope 14 { } - scope 11 (inlined NonZero::::get) { + scope 15 (inlined NonZero::::get) { } - scope 12 (inlined std::ptr::without_provenance::<[bool; 0]>) { - scope 13 (inlined without_provenance_mut::<[bool; 0]>) { + scope 16 (inlined std::ptr::without_provenance::<[bool; 0]>) { + scope 17 (inlined without_provenance_mut::<[bool; 0]>) { } } } } scope 7 (inlined std::ptr::Alignment::of::<[bool; 0]>) { + scope 8 { + } + scope 9 (inlined core::contracts::build_check_ensures::::{closure#0}}>) { + } } } } @@ -45,33 +56,42 @@ StorageLive(_4); StorageLive(_5); StorageLive(_6); - _6 = const NonZero::(core::num::niche_types::NonZeroUsizeInner(1_usize)); + _6 = contract_check_ensures::<{closure@std::ptr::Alignment::of<[bool; 0]>::{closure#0}}, std::ptr::Alignment>(const ZeroSized: {closure@std::ptr::Alignment::of<[bool; 0]>::{closure#0}}, const std::ptr::Alignment::of::<[bool; 0]>::{constant#0}) -> [return: bb2, unwind unreachable]; + } + + bb1: { + StorageDead(_1); + return; + } + + bb2: { StorageLive(_7); - _7 = const {0x1 as *const [bool; 0]}; - _5 = const NonNull::<[bool; 0]> {{ pointer: {0x1 as *const [bool; 0]} }}; + StorageLive(_8); + _8 = {closure@$SRC_DIR/core/src/ptr/alignment.rs:LL:COL} { 0: copy _6 }; + StorageLive(_9); + _9 = copy _6 as std::num::NonZero (Transmute); + _7 = contract_check_ensures::<{closure@std::ptr::Alignment::as_nonzero::{closure#0}}, NonZero>(move _8, move _9) -> [return: bb3, unwind unreachable]; + } + + bb3: { + StorageDead(_9); + StorageDead(_8); + StorageLive(_10); + _10 = copy _7 as *const [bool; 0] (Transmute); + _5 = NonNull::<[bool; 0]> { pointer: copy _10 }; + StorageDead(_10); StorageDead(_7); StorageDead(_6); - _4 = const Unique::<[bool; 0]> {{ pointer: NonNull::<[bool; 0]> {{ pointer: {0x1 as *const [bool; 0]} }}, _marker: PhantomData::<[bool; 0]> }}; + _4 = Unique::<[bool; 0]> { pointer: move _5, _marker: const PhantomData::<[bool; 0]> }; StorageDead(_5); - _3 = const Unique::<[bool]> {{ pointer: NonNull::<[bool]> {{ pointer: Indirect { alloc_id: ALLOC0, offset: Size(0 bytes) }: *const [bool] }}, _marker: PhantomData::<[bool]> }}; + _3 = move _4 as std::ptr::Unique<[bool]> (PointerCoercion(Unsize, Implicit)); StorageDead(_4); - _2 = const Box::<[bool]>(Unique::<[bool]> {{ pointer: NonNull::<[bool]> {{ pointer: Indirect { alloc_id: ALLOC1, offset: Size(0 bytes) }: *const [bool] }}, _marker: PhantomData::<[bool]> }}, std::alloc::Global); + _2 = Box::<[bool]>(copy _3, const std::alloc::Global); StorageDead(_3); - _1 = const A {{ foo: Box::<[bool]>(Unique::<[bool]> {{ pointer: NonNull::<[bool]> {{ pointer: Indirect { alloc_id: ALLOC2, offset: Size(0 bytes) }: *const [bool] }}, _marker: PhantomData::<[bool]> }}, std::alloc::Global) }}; + _1 = A { foo: move _2 }; StorageDead(_2); _0 = const (); drop(_1) -> [return: bb1, unwind unreachable]; } - - bb1: { - StorageDead(_1); - return; - } } - ALLOC2 (size: 8, align: 4) { .. } - - ALLOC1 (size: 8, align: 4) { .. } - - ALLOC0 (size: 8, align: 4) { .. } - diff --git a/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.DataflowConstProp.32bit.panic-unwind.diff b/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.DataflowConstProp.32bit.panic-unwind.diff index 8fecfe224cc69..d98a016c85f41 100644 --- a/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.DataflowConstProp.32bit.panic-unwind.diff +++ b/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.DataflowConstProp.32bit.panic-unwind.diff @@ -16,23 +16,34 @@ scope 4 (inlined Unique::<[bool; 0]>::dangling) { let mut _5: std::ptr::NonNull<[bool; 0]>; scope 5 (inlined NonNull::<[bool; 0]>::dangling) { - let mut _6: std::num::NonZero; + let _6: std::ptr::Alignment; + let mut _7: std::num::NonZero; scope 6 { - scope 8 (inlined std::ptr::Alignment::as_nonzero) { + scope 10 (inlined std::ptr::Alignment::as_nonzero) { + let mut _8: {closure@std::ptr::Alignment::as_nonzero::{closure#0}}; + let mut _9: std::num::NonZero; + scope 11 { + } + scope 12 (inlined core::contracts::build_check_ensures::, {closure@std::ptr::Alignment::as_nonzero::{closure#0}}>) { + } } - scope 9 (inlined NonNull::<[bool; 0]>::without_provenance) { - let _7: *const [bool; 0]; - scope 10 { + scope 13 (inlined NonNull::<[bool; 0]>::without_provenance) { + let _10: *const [bool; 0]; + scope 14 { } - scope 11 (inlined NonZero::::get) { + scope 15 (inlined NonZero::::get) { } - scope 12 (inlined std::ptr::without_provenance::<[bool; 0]>) { - scope 13 (inlined without_provenance_mut::<[bool; 0]>) { + scope 16 (inlined std::ptr::without_provenance::<[bool; 0]>) { + scope 17 (inlined without_provenance_mut::<[bool; 0]>) { } } } } scope 7 (inlined std::ptr::Alignment::of::<[bool; 0]>) { + scope 8 { + } + scope 9 (inlined core::contracts::build_check_ensures::::{closure#0}}>) { + } } } } @@ -45,22 +56,7 @@ StorageLive(_4); StorageLive(_5); StorageLive(_6); - _6 = const NonZero::(core::num::niche_types::NonZeroUsizeInner(1_usize)); - StorageLive(_7); - _7 = const {0x1 as *const [bool; 0]}; - _5 = const NonNull::<[bool; 0]> {{ pointer: {0x1 as *const [bool; 0]} }}; - StorageDead(_7); - StorageDead(_6); - _4 = const Unique::<[bool; 0]> {{ pointer: NonNull::<[bool; 0]> {{ pointer: {0x1 as *const [bool; 0]} }}, _marker: PhantomData::<[bool; 0]> }}; - StorageDead(_5); - _3 = const Unique::<[bool]> {{ pointer: NonNull::<[bool]> {{ pointer: Indirect { alloc_id: ALLOC0, offset: Size(0 bytes) }: *const [bool] }}, _marker: PhantomData::<[bool]> }}; - StorageDead(_4); - _2 = const Box::<[bool]>(Unique::<[bool]> {{ pointer: NonNull::<[bool]> {{ pointer: Indirect { alloc_id: ALLOC1, offset: Size(0 bytes) }: *const [bool] }}, _marker: PhantomData::<[bool]> }}, std::alloc::Global); - StorageDead(_3); - _1 = const A {{ foo: Box::<[bool]>(Unique::<[bool]> {{ pointer: NonNull::<[bool]> {{ pointer: Indirect { alloc_id: ALLOC2, offset: Size(0 bytes) }: *const [bool] }}, _marker: PhantomData::<[bool]> }}, std::alloc::Global) }}; - StorageDead(_2); - _0 = const (); - drop(_1) -> [return: bb1, unwind: bb2]; + _6 = contract_check_ensures::<{closure@std::ptr::Alignment::of<[bool; 0]>::{closure#0}}, std::ptr::Alignment>(const ZeroSized: {closure@std::ptr::Alignment::of<[bool; 0]>::{closure#0}}, const std::ptr::Alignment::of::<[bool; 0]>::{constant#0}) -> [return: bb3, unwind continue]; } bb1: { @@ -71,11 +67,35 @@ bb2 (cleanup): { resume; } - } - ALLOC2 (size: 8, align: 4) { .. } - - ALLOC1 (size: 8, align: 4) { .. } + bb3: { + StorageLive(_7); + StorageLive(_8); + _8 = {closure@$SRC_DIR/core/src/ptr/alignment.rs:LL:COL} { 0: copy _6 }; + StorageLive(_9); + _9 = copy _6 as std::num::NonZero (Transmute); + _7 = contract_check_ensures::<{closure@std::ptr::Alignment::as_nonzero::{closure#0}}, NonZero>(move _8, move _9) -> [return: bb4, unwind continue]; + } - ALLOC0 (size: 8, align: 4) { .. } + bb4: { + StorageDead(_9); + StorageDead(_8); + StorageLive(_10); + _10 = copy _7 as *const [bool; 0] (Transmute); + _5 = NonNull::<[bool; 0]> { pointer: copy _10 }; + StorageDead(_10); + StorageDead(_7); + StorageDead(_6); + _4 = Unique::<[bool; 0]> { pointer: move _5, _marker: const PhantomData::<[bool; 0]> }; + StorageDead(_5); + _3 = move _4 as std::ptr::Unique<[bool]> (PointerCoercion(Unsize, Implicit)); + StorageDead(_4); + _2 = Box::<[bool]>(copy _3, const std::alloc::Global); + StorageDead(_3); + _1 = A { foo: move _2 }; + StorageDead(_2); + _0 = const (); + drop(_1) -> [return: bb1, unwind: bb2]; + } + } diff --git a/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.DataflowConstProp.64bit.panic-abort.diff b/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.DataflowConstProp.64bit.panic-abort.diff index 976ea252c2f89..e22e91ce09cf4 100644 --- a/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.DataflowConstProp.64bit.panic-abort.diff +++ b/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.DataflowConstProp.64bit.panic-abort.diff @@ -16,23 +16,34 @@ scope 4 (inlined Unique::<[bool; 0]>::dangling) { let mut _5: std::ptr::NonNull<[bool; 0]>; scope 5 (inlined NonNull::<[bool; 0]>::dangling) { - let mut _6: std::num::NonZero; + let _6: std::ptr::Alignment; + let mut _7: std::num::NonZero; scope 6 { - scope 8 (inlined std::ptr::Alignment::as_nonzero) { + scope 10 (inlined std::ptr::Alignment::as_nonzero) { + let mut _8: {closure@std::ptr::Alignment::as_nonzero::{closure#0}}; + let mut _9: std::num::NonZero; + scope 11 { + } + scope 12 (inlined core::contracts::build_check_ensures::, {closure@std::ptr::Alignment::as_nonzero::{closure#0}}>) { + } } - scope 9 (inlined NonNull::<[bool; 0]>::without_provenance) { - let _7: *const [bool; 0]; - scope 10 { + scope 13 (inlined NonNull::<[bool; 0]>::without_provenance) { + let _10: *const [bool; 0]; + scope 14 { } - scope 11 (inlined NonZero::::get) { + scope 15 (inlined NonZero::::get) { } - scope 12 (inlined std::ptr::without_provenance::<[bool; 0]>) { - scope 13 (inlined without_provenance_mut::<[bool; 0]>) { + scope 16 (inlined std::ptr::without_provenance::<[bool; 0]>) { + scope 17 (inlined without_provenance_mut::<[bool; 0]>) { } } } } scope 7 (inlined std::ptr::Alignment::of::<[bool; 0]>) { + scope 8 { + } + scope 9 (inlined core::contracts::build_check_ensures::::{closure#0}}>) { + } } } } @@ -45,33 +56,42 @@ StorageLive(_4); StorageLive(_5); StorageLive(_6); - _6 = const NonZero::(core::num::niche_types::NonZeroUsizeInner(1_usize)); + _6 = contract_check_ensures::<{closure@std::ptr::Alignment::of<[bool; 0]>::{closure#0}}, std::ptr::Alignment>(const ZeroSized: {closure@std::ptr::Alignment::of<[bool; 0]>::{closure#0}}, const std::ptr::Alignment::of::<[bool; 0]>::{constant#0}) -> [return: bb2, unwind unreachable]; + } + + bb1: { + StorageDead(_1); + return; + } + + bb2: { StorageLive(_7); - _7 = const {0x1 as *const [bool; 0]}; - _5 = const NonNull::<[bool; 0]> {{ pointer: {0x1 as *const [bool; 0]} }}; + StorageLive(_8); + _8 = {closure@$SRC_DIR/core/src/ptr/alignment.rs:LL:COL} { 0: copy _6 }; + StorageLive(_9); + _9 = copy _6 as std::num::NonZero (Transmute); + _7 = contract_check_ensures::<{closure@std::ptr::Alignment::as_nonzero::{closure#0}}, NonZero>(move _8, move _9) -> [return: bb3, unwind unreachable]; + } + + bb3: { + StorageDead(_9); + StorageDead(_8); + StorageLive(_10); + _10 = copy _7 as *const [bool; 0] (Transmute); + _5 = NonNull::<[bool; 0]> { pointer: copy _10 }; + StorageDead(_10); StorageDead(_7); StorageDead(_6); - _4 = const Unique::<[bool; 0]> {{ pointer: NonNull::<[bool; 0]> {{ pointer: {0x1 as *const [bool; 0]} }}, _marker: PhantomData::<[bool; 0]> }}; + _4 = Unique::<[bool; 0]> { pointer: move _5, _marker: const PhantomData::<[bool; 0]> }; StorageDead(_5); - _3 = const Unique::<[bool]> {{ pointer: NonNull::<[bool]> {{ pointer: Indirect { alloc_id: ALLOC0, offset: Size(0 bytes) }: *const [bool] }}, _marker: PhantomData::<[bool]> }}; + _3 = move _4 as std::ptr::Unique<[bool]> (PointerCoercion(Unsize, Implicit)); StorageDead(_4); - _2 = const Box::<[bool]>(Unique::<[bool]> {{ pointer: NonNull::<[bool]> {{ pointer: Indirect { alloc_id: ALLOC1, offset: Size(0 bytes) }: *const [bool] }}, _marker: PhantomData::<[bool]> }}, std::alloc::Global); + _2 = Box::<[bool]>(copy _3, const std::alloc::Global); StorageDead(_3); - _1 = const A {{ foo: Box::<[bool]>(Unique::<[bool]> {{ pointer: NonNull::<[bool]> {{ pointer: Indirect { alloc_id: ALLOC2, offset: Size(0 bytes) }: *const [bool] }}, _marker: PhantomData::<[bool]> }}, std::alloc::Global) }}; + _1 = A { foo: move _2 }; StorageDead(_2); _0 = const (); drop(_1) -> [return: bb1, unwind unreachable]; } - - bb1: { - StorageDead(_1); - return; - } } - ALLOC2 (size: 16, align: 8) { .. } - - ALLOC1 (size: 16, align: 8) { .. } - - ALLOC0 (size: 16, align: 8) { .. } - diff --git a/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.32bit.panic-abort.diff b/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.32bit.panic-abort.diff index 1f9cf6d6aca83..df8d93565d5a6 100644 --- a/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.32bit.panic-abort.diff +++ b/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.32bit.panic-abort.diff @@ -16,23 +16,34 @@ scope 4 (inlined Unique::<[bool; 0]>::dangling) { let mut _5: std::ptr::NonNull<[bool; 0]>; scope 5 (inlined NonNull::<[bool; 0]>::dangling) { - let mut _6: std::num::NonZero; + let _6: std::ptr::Alignment; + let mut _7: std::num::NonZero; scope 6 { - scope 8 (inlined std::ptr::Alignment::as_nonzero) { + scope 10 (inlined std::ptr::Alignment::as_nonzero) { + let mut _8: {closure@std::ptr::Alignment::as_nonzero::{closure#0}}; + let mut _9: std::num::NonZero; + scope 11 { + } + scope 12 (inlined core::contracts::build_check_ensures::, {closure@std::ptr::Alignment::as_nonzero::{closure#0}}>) { + } } - scope 9 (inlined NonNull::<[bool; 0]>::without_provenance) { - let _7: *const [bool; 0]; - scope 10 { + scope 13 (inlined NonNull::<[bool; 0]>::without_provenance) { + let _10: *const [bool; 0]; + scope 14 { } - scope 11 (inlined NonZero::::get) { + scope 15 (inlined NonZero::::get) { } - scope 12 (inlined std::ptr::without_provenance::<[bool; 0]>) { - scope 13 (inlined without_provenance_mut::<[bool; 0]>) { + scope 16 (inlined std::ptr::without_provenance::<[bool; 0]>) { + scope 17 (inlined without_provenance_mut::<[bool; 0]>) { } } } } scope 7 (inlined std::ptr::Alignment::of::<[bool; 0]>) { + scope 8 { + } + scope 9 (inlined core::contracts::build_check_ensures::::{closure#0}}>) { + } } } } @@ -45,40 +56,42 @@ StorageLive(_4); StorageLive(_5); StorageLive(_6); -- _6 = const std::ptr::Alignment::of::<[bool; 0]>::{constant#0} as std::num::NonZero (Transmute); -+ _6 = const NonZero::(core::num::niche_types::NonZeroUsizeInner(1_usize)); + _6 = contract_check_ensures::<{closure@std::ptr::Alignment::of<[bool; 0]>::{closure#0}}, std::ptr::Alignment>(const ZeroSized: {closure@std::ptr::Alignment::of<[bool; 0]>::{closure#0}}, const std::ptr::Alignment::of::<[bool; 0]>::{constant#0}) -> [return: bb2, unwind unreachable]; + } + + bb1: { + StorageDead(_1); + return; + } + + bb2: { StorageLive(_7); -- _7 = copy _6 as *const [bool; 0] (Transmute); -- _5 = NonNull::<[bool; 0]> { pointer: copy _7 }; -+ _7 = const {0x1 as *const [bool; 0]}; -+ _5 = const NonNull::<[bool; 0]> {{ pointer: {0x1 as *const [bool; 0]} }}; + StorageLive(_8); + _8 = {closure@$SRC_DIR/core/src/ptr/alignment.rs:LL:COL} { 0: copy _6 }; + StorageLive(_9); + _9 = copy _6 as std::num::NonZero (Transmute); + _7 = contract_check_ensures::<{closure@std::ptr::Alignment::as_nonzero::{closure#0}}, NonZero>(move _8, move _9) -> [return: bb3, unwind unreachable]; + } + + bb3: { + StorageDead(_9); + StorageDead(_8); + StorageLive(_10); + _10 = copy _7 as *const [bool; 0] (Transmute); + _5 = NonNull::<[bool; 0]> { pointer: copy _10 }; + StorageDead(_10); StorageDead(_7); StorageDead(_6); -- _4 = Unique::<[bool; 0]> { pointer: move _5, _marker: const PhantomData::<[bool; 0]> }; -+ _4 = const Unique::<[bool; 0]> {{ pointer: NonNull::<[bool; 0]> {{ pointer: {0x1 as *const [bool; 0]} }}, _marker: PhantomData::<[bool; 0]> }}; + _4 = Unique::<[bool; 0]> { pointer: move _5, _marker: const PhantomData::<[bool; 0]> }; StorageDead(_5); -- _3 = move _4 as std::ptr::Unique<[bool]> (PointerCoercion(Unsize, Implicit)); -+ _3 = const Unique::<[bool]> {{ pointer: NonNull::<[bool]> {{ pointer: Indirect { alloc_id: ALLOC0, offset: Size(0 bytes) }: *const [bool] }}, _marker: PhantomData::<[bool]> }}; + _3 = move _4 as std::ptr::Unique<[bool]> (PointerCoercion(Unsize, Implicit)); StorageDead(_4); -- _2 = Box::<[bool]>(copy _3, const std::alloc::Global); -+ _2 = const Box::<[bool]>(Unique::<[bool]> {{ pointer: NonNull::<[bool]> {{ pointer: Indirect { alloc_id: ALLOC1, offset: Size(0 bytes) }: *const [bool] }}, _marker: PhantomData::<[bool]> }}, std::alloc::Global); + _2 = Box::<[bool]>(copy _3, const std::alloc::Global); StorageDead(_3); -- _1 = A { foo: move _2 }; -+ _1 = const A {{ foo: Box::<[bool]>(Unique::<[bool]> {{ pointer: NonNull::<[bool]> {{ pointer: Indirect { alloc_id: ALLOC2, offset: Size(0 bytes) }: *const [bool] }}, _marker: PhantomData::<[bool]> }}, std::alloc::Global) }}; + _1 = A { foo: move _2 }; StorageDead(_2); _0 = const (); drop(_1) -> [return: bb1, unwind unreachable]; } - - bb1: { - StorageDead(_1); - return; - } } -+ -+ ALLOC2 (size: 8, align: 4) { .. } -+ -+ ALLOC1 (size: 8, align: 4) { .. } -+ -+ ALLOC0 (size: 8, align: 4) { .. } diff --git a/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.32bit.panic-unwind.diff b/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.32bit.panic-unwind.diff index a8760285fac11..0abce626aeb75 100644 --- a/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.32bit.panic-unwind.diff +++ b/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.32bit.panic-unwind.diff @@ -16,23 +16,34 @@ scope 4 (inlined Unique::<[bool; 0]>::dangling) { let mut _5: std::ptr::NonNull<[bool; 0]>; scope 5 (inlined NonNull::<[bool; 0]>::dangling) { - let mut _6: std::num::NonZero; + let _6: std::ptr::Alignment; + let mut _7: std::num::NonZero; scope 6 { - scope 8 (inlined std::ptr::Alignment::as_nonzero) { + scope 10 (inlined std::ptr::Alignment::as_nonzero) { + let mut _8: {closure@std::ptr::Alignment::as_nonzero::{closure#0}}; + let mut _9: std::num::NonZero; + scope 11 { + } + scope 12 (inlined core::contracts::build_check_ensures::, {closure@std::ptr::Alignment::as_nonzero::{closure#0}}>) { + } } - scope 9 (inlined NonNull::<[bool; 0]>::without_provenance) { - let _7: *const [bool; 0]; - scope 10 { + scope 13 (inlined NonNull::<[bool; 0]>::without_provenance) { + let _10: *const [bool; 0]; + scope 14 { } - scope 11 (inlined NonZero::::get) { + scope 15 (inlined NonZero::::get) { } - scope 12 (inlined std::ptr::without_provenance::<[bool; 0]>) { - scope 13 (inlined without_provenance_mut::<[bool; 0]>) { + scope 16 (inlined std::ptr::without_provenance::<[bool; 0]>) { + scope 17 (inlined without_provenance_mut::<[bool; 0]>) { } } } } scope 7 (inlined std::ptr::Alignment::of::<[bool; 0]>) { + scope 8 { + } + scope 9 (inlined core::contracts::build_check_ensures::::{closure#0}}>) { + } } } } @@ -45,29 +56,7 @@ StorageLive(_4); StorageLive(_5); StorageLive(_6); -- _6 = const std::ptr::Alignment::of::<[bool; 0]>::{constant#0} as std::num::NonZero (Transmute); -+ _6 = const NonZero::(core::num::niche_types::NonZeroUsizeInner(1_usize)); - StorageLive(_7); -- _7 = copy _6 as *const [bool; 0] (Transmute); -- _5 = NonNull::<[bool; 0]> { pointer: copy _7 }; -+ _7 = const {0x1 as *const [bool; 0]}; -+ _5 = const NonNull::<[bool; 0]> {{ pointer: {0x1 as *const [bool; 0]} }}; - StorageDead(_7); - StorageDead(_6); -- _4 = Unique::<[bool; 0]> { pointer: move _5, _marker: const PhantomData::<[bool; 0]> }; -+ _4 = const Unique::<[bool; 0]> {{ pointer: NonNull::<[bool; 0]> {{ pointer: {0x1 as *const [bool; 0]} }}, _marker: PhantomData::<[bool; 0]> }}; - StorageDead(_5); -- _3 = move _4 as std::ptr::Unique<[bool]> (PointerCoercion(Unsize, Implicit)); -+ _3 = const Unique::<[bool]> {{ pointer: NonNull::<[bool]> {{ pointer: Indirect { alloc_id: ALLOC0, offset: Size(0 bytes) }: *const [bool] }}, _marker: PhantomData::<[bool]> }}; - StorageDead(_4); -- _2 = Box::<[bool]>(copy _3, const std::alloc::Global); -+ _2 = const Box::<[bool]>(Unique::<[bool]> {{ pointer: NonNull::<[bool]> {{ pointer: Indirect { alloc_id: ALLOC1, offset: Size(0 bytes) }: *const [bool] }}, _marker: PhantomData::<[bool]> }}, std::alloc::Global); - StorageDead(_3); -- _1 = A { foo: move _2 }; -+ _1 = const A {{ foo: Box::<[bool]>(Unique::<[bool]> {{ pointer: NonNull::<[bool]> {{ pointer: Indirect { alloc_id: ALLOC2, offset: Size(0 bytes) }: *const [bool] }}, _marker: PhantomData::<[bool]> }}, std::alloc::Global) }}; - StorageDead(_2); - _0 = const (); - drop(_1) -> [return: bb1, unwind: bb2]; + _6 = contract_check_ensures::<{closure@std::ptr::Alignment::of<[bool; 0]>::{closure#0}}, std::ptr::Alignment>(const ZeroSized: {closure@std::ptr::Alignment::of<[bool; 0]>::{closure#0}}, const std::ptr::Alignment::of::<[bool; 0]>::{constant#0}) -> [return: bb3, unwind continue]; } bb1: { @@ -78,11 +67,35 @@ bb2 (cleanup): { resume; } + + bb3: { + StorageLive(_7); + StorageLive(_8); + _8 = {closure@$SRC_DIR/core/src/ptr/alignment.rs:LL:COL} { 0: copy _6 }; + StorageLive(_9); + _9 = copy _6 as std::num::NonZero (Transmute); + _7 = contract_check_ensures::<{closure@std::ptr::Alignment::as_nonzero::{closure#0}}, NonZero>(move _8, move _9) -> [return: bb4, unwind continue]; + } + + bb4: { + StorageDead(_9); + StorageDead(_8); + StorageLive(_10); + _10 = copy _7 as *const [bool; 0] (Transmute); + _5 = NonNull::<[bool; 0]> { pointer: copy _10 }; + StorageDead(_10); + StorageDead(_7); + StorageDead(_6); + _4 = Unique::<[bool; 0]> { pointer: move _5, _marker: const PhantomData::<[bool; 0]> }; + StorageDead(_5); + _3 = move _4 as std::ptr::Unique<[bool]> (PointerCoercion(Unsize, Implicit)); + StorageDead(_4); + _2 = Box::<[bool]>(copy _3, const std::alloc::Global); + StorageDead(_3); + _1 = A { foo: move _2 }; + StorageDead(_2); + _0 = const (); + drop(_1) -> [return: bb1, unwind: bb2]; + } } -+ -+ ALLOC2 (size: 8, align: 4) { .. } -+ -+ ALLOC1 (size: 8, align: 4) { .. } -+ -+ ALLOC0 (size: 8, align: 4) { .. } diff --git a/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.64bit.panic-abort.diff b/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.64bit.panic-abort.diff index c398ae70a1a3e..df8d93565d5a6 100644 --- a/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.64bit.panic-abort.diff +++ b/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.64bit.panic-abort.diff @@ -16,23 +16,34 @@ scope 4 (inlined Unique::<[bool; 0]>::dangling) { let mut _5: std::ptr::NonNull<[bool; 0]>; scope 5 (inlined NonNull::<[bool; 0]>::dangling) { - let mut _6: std::num::NonZero; + let _6: std::ptr::Alignment; + let mut _7: std::num::NonZero; scope 6 { - scope 8 (inlined std::ptr::Alignment::as_nonzero) { + scope 10 (inlined std::ptr::Alignment::as_nonzero) { + let mut _8: {closure@std::ptr::Alignment::as_nonzero::{closure#0}}; + let mut _9: std::num::NonZero; + scope 11 { + } + scope 12 (inlined core::contracts::build_check_ensures::, {closure@std::ptr::Alignment::as_nonzero::{closure#0}}>) { + } } - scope 9 (inlined NonNull::<[bool; 0]>::without_provenance) { - let _7: *const [bool; 0]; - scope 10 { + scope 13 (inlined NonNull::<[bool; 0]>::without_provenance) { + let _10: *const [bool; 0]; + scope 14 { } - scope 11 (inlined NonZero::::get) { + scope 15 (inlined NonZero::::get) { } - scope 12 (inlined std::ptr::without_provenance::<[bool; 0]>) { - scope 13 (inlined without_provenance_mut::<[bool; 0]>) { + scope 16 (inlined std::ptr::without_provenance::<[bool; 0]>) { + scope 17 (inlined without_provenance_mut::<[bool; 0]>) { } } } } scope 7 (inlined std::ptr::Alignment::of::<[bool; 0]>) { + scope 8 { + } + scope 9 (inlined core::contracts::build_check_ensures::::{closure#0}}>) { + } } } } @@ -45,40 +56,42 @@ StorageLive(_4); StorageLive(_5); StorageLive(_6); -- _6 = const std::ptr::Alignment::of::<[bool; 0]>::{constant#0} as std::num::NonZero (Transmute); -+ _6 = const NonZero::(core::num::niche_types::NonZeroUsizeInner(1_usize)); + _6 = contract_check_ensures::<{closure@std::ptr::Alignment::of<[bool; 0]>::{closure#0}}, std::ptr::Alignment>(const ZeroSized: {closure@std::ptr::Alignment::of<[bool; 0]>::{closure#0}}, const std::ptr::Alignment::of::<[bool; 0]>::{constant#0}) -> [return: bb2, unwind unreachable]; + } + + bb1: { + StorageDead(_1); + return; + } + + bb2: { StorageLive(_7); -- _7 = copy _6 as *const [bool; 0] (Transmute); -- _5 = NonNull::<[bool; 0]> { pointer: copy _7 }; -+ _7 = const {0x1 as *const [bool; 0]}; -+ _5 = const NonNull::<[bool; 0]> {{ pointer: {0x1 as *const [bool; 0]} }}; + StorageLive(_8); + _8 = {closure@$SRC_DIR/core/src/ptr/alignment.rs:LL:COL} { 0: copy _6 }; + StorageLive(_9); + _9 = copy _6 as std::num::NonZero (Transmute); + _7 = contract_check_ensures::<{closure@std::ptr::Alignment::as_nonzero::{closure#0}}, NonZero>(move _8, move _9) -> [return: bb3, unwind unreachable]; + } + + bb3: { + StorageDead(_9); + StorageDead(_8); + StorageLive(_10); + _10 = copy _7 as *const [bool; 0] (Transmute); + _5 = NonNull::<[bool; 0]> { pointer: copy _10 }; + StorageDead(_10); StorageDead(_7); StorageDead(_6); -- _4 = Unique::<[bool; 0]> { pointer: move _5, _marker: const PhantomData::<[bool; 0]> }; -+ _4 = const Unique::<[bool; 0]> {{ pointer: NonNull::<[bool; 0]> {{ pointer: {0x1 as *const [bool; 0]} }}, _marker: PhantomData::<[bool; 0]> }}; + _4 = Unique::<[bool; 0]> { pointer: move _5, _marker: const PhantomData::<[bool; 0]> }; StorageDead(_5); -- _3 = move _4 as std::ptr::Unique<[bool]> (PointerCoercion(Unsize, Implicit)); -+ _3 = const Unique::<[bool]> {{ pointer: NonNull::<[bool]> {{ pointer: Indirect { alloc_id: ALLOC0, offset: Size(0 bytes) }: *const [bool] }}, _marker: PhantomData::<[bool]> }}; + _3 = move _4 as std::ptr::Unique<[bool]> (PointerCoercion(Unsize, Implicit)); StorageDead(_4); -- _2 = Box::<[bool]>(copy _3, const std::alloc::Global); -+ _2 = const Box::<[bool]>(Unique::<[bool]> {{ pointer: NonNull::<[bool]> {{ pointer: Indirect { alloc_id: ALLOC1, offset: Size(0 bytes) }: *const [bool] }}, _marker: PhantomData::<[bool]> }}, std::alloc::Global); + _2 = Box::<[bool]>(copy _3, const std::alloc::Global); StorageDead(_3); -- _1 = A { foo: move _2 }; -+ _1 = const A {{ foo: Box::<[bool]>(Unique::<[bool]> {{ pointer: NonNull::<[bool]> {{ pointer: Indirect { alloc_id: ALLOC2, offset: Size(0 bytes) }: *const [bool] }}, _marker: PhantomData::<[bool]> }}, std::alloc::Global) }}; + _1 = A { foo: move _2 }; StorageDead(_2); _0 = const (); drop(_1) -> [return: bb1, unwind unreachable]; } - - bb1: { - StorageDead(_1); - return; - } } -+ -+ ALLOC2 (size: 16, align: 8) { .. } -+ -+ ALLOC1 (size: 16, align: 8) { .. } -+ -+ ALLOC0 (size: 16, align: 8) { .. } diff --git a/tests/mir-opt/dataflow-const-prop/default_boxed_slice.rs b/tests/mir-opt/dataflow-const-prop/default_boxed_slice.rs index 087bd7a18572c..ca9f38453b5b1 100644 --- a/tests/mir-opt/dataflow-const-prop/default_boxed_slice.rs +++ b/tests/mir-opt/dataflow-const-prop/default_boxed_slice.rs @@ -20,6 +20,6 @@ fn main() { // CHECK: debug a => [[a:_.*]]; // We may check other inlined functions as well... - // CHECK: {{_.*}} = const Box::<[bool]>( + // CHECK: {{_.*}} = {{(const )?}}Box::<[bool]>( let a: A = A { foo: Box::default() }; }