diff --git a/library/core/src/slice/iter.rs b/library/core/src/slice/iter.rs index 33132dcc7148d..5835f0a6e937f 100644 --- a/library/core/src/slice/iter.rs +++ b/library/core/src/slice/iter.rs @@ -11,8 +11,8 @@ use crate::iter::{ use crate::marker::PhantomData; use crate::mem::{self, SizedTypeProperties}; use crate::num::NonZero; -use crate::ptr::{NonNull, without_provenance, without_provenance_mut}; -use crate::{cmp, fmt}; +use crate::ptr::{self, NonNull}; +use crate::{cmp, fmt, intrinsics}; #[stable(feature = "boxed_slice_into_iter", since = "1.80.0")] impl !Iterator for [T] {} @@ -72,10 +72,14 @@ pub struct Iter<'a, T: 'a> { /// /// This address will be used for all ZST elements, never changed. ptr: NonNull, - /// For non-ZSTs, the non-null pointer to the past-the-end element. + /// For non-ZSTs, the address of the past-the-end element. This is + /// intentionally *not* a pointer, so that it doesn't carry provenance. + /// If you're turning this into a pointer, you need to use the provenance from + /// `ptr` instead. (If this carried provenance, the compiler wouldn't know + /// that reads from the start and the end are actually the same provenance.) /// - /// For ZSTs, this is `ptr::without_provenance_mut(len)`. - end_or_len: *const T, + /// For ZSTs, this is the length. + end_addr_or_len: usize, _marker: PhantomData<&'a T>, } @@ -98,10 +102,9 @@ impl<'a, T> Iter<'a, T> { let ptr: NonNull = NonNull::from_ref(slice).cast(); // SAFETY: Similar to `IterMut::new`. unsafe { - let end_or_len = - if T::IS_ZST { without_provenance(len) } else { ptr.as_ptr().add(len) }; + let end_addr_or_len = if T::IS_ZST { len } else { addr_usize(ptr.add(len)) }; - Self { ptr, end_or_len, _marker: PhantomData } + Self { ptr, end_addr_or_len, _marker: PhantomData } } } @@ -153,7 +156,7 @@ iterator! {struct Iter -> *const T, &'a T, const, {/* no mut */}, as_ref, { impl Clone for Iter<'_, T> { #[inline] fn clone(&self) -> Self { - Iter { ptr: self.ptr, end_or_len: self.end_or_len, _marker: self._marker } + Iter { ptr: self.ptr, end_addr_or_len: self.end_addr_or_len, _marker: self._marker } } } @@ -197,10 +200,14 @@ pub struct IterMut<'a, T: 'a> { /// /// This address will be used for all ZST elements, never changed. ptr: NonNull, - /// For non-ZSTs, the non-null pointer to the past-the-end element. + /// For non-ZSTs, the address of the past-the-end element. This is + /// intentionally *not* a pointer, so that it doesn't carry provenance. + /// If you're turning this into a pointer, you need to use the provenance from + /// `ptr` instead. (If this carried provenance, the compiler wouldn't know + /// that reads from the start and the end are actually the same provenance.) /// - /// For ZSTs, this is `ptr::without_provenance_mut(len)`. - end_or_len: *mut T, + /// For ZSTs, this is the length. + end_addr_or_len: usize, _marker: PhantomData<&'a mut T>, } @@ -238,10 +245,9 @@ impl<'a, T> IterMut<'a, T> { // See the `next_unchecked!` and `is_empty!` macros as well as the // `post_inc_start` method for more information. unsafe { - let end_or_len = - if T::IS_ZST { without_provenance_mut(len) } else { ptr.as_ptr().add(len) }; + let end_addr_or_len = if T::IS_ZST { len } else { addr_usize(ptr.add(len)) }; - Self { ptr, end_or_len, _marker: PhantomData } + Self { ptr, end_addr_or_len, _marker: PhantomData } } } @@ -3478,3 +3484,12 @@ impl<'a, T: 'a + fmt::Debug, P> fmt::Debug for ChunkByMut<'a, T, P> { f.debug_struct("ChunkByMut").field("slice", &self.slice).finish() } } + +/// Same as `p.addr().get()`, but faster to compile by avoiding a bunch of +/// intermediate steps and unneeded UB checks, which also inlines better. +#[inline] +const fn addr_usize(p: NonNull) -> usize { + // SAFETY: `NonNull` for a sized type has the same layout as `usize`, + // and we intentionally don't want to expose here. + unsafe { intrinsics::transmute(p) } +} diff --git a/library/core/src/slice/iter/macros.rs b/library/core/src/slice/iter/macros.rs index 7c1ed3fe8a246..19589da8652bc 100644 --- a/library/core/src/slice/iter/macros.rs +++ b/library/core/src/slice/iter/macros.rs @@ -1,36 +1,64 @@ //! Macros used by iterators of slice. -/// Convenience & performance macro for consuming the `end_or_len` field, by +/// Convenience macro for updating the `end_addr_or_len` field for non-ZSTs. +macro_rules! set_end { + ($this:ident . end = $new_end:expr) => {{ + $this.end_addr_or_len = addr_usize($new_end); + }}; +} + +/// Convenience & performance macro for consuming the `end_addr_or_len` field, by /// giving a `(&mut) usize` or `(&mut) NonNull` depending whether `T` is /// or is not a ZST respectively. /// -/// Internally, this reads the `end` through a pointer-to-`NonNull` so that -/// it'll get the appropriate non-null metadata in the backend without needing -/// to call `assume` manually. +/// When giving a `NonNull` for the end, it creates it by offsetting from the +/// `ptr` so that the backend knows that both pointers have the same provenance. macro_rules! if_zst { (mut $this:ident, $len:ident => $zst_body:expr, $end:ident => $other_body:expr,) => {{ #![allow(unused_unsafe)] // we're sometimes used within an unsafe block + let ptr = $this.ptr; if T::IS_ZST { - // SAFETY: for ZSTs, the pointer is storing a provenance-free length, - // so consuming and updating it as a `usize` is fine. - let $len = unsafe { &mut *(&raw mut $this.end_or_len).cast::() }; + let $len = &mut $this.end_addr_or_len; $zst_body } else { - // SAFETY: for non-ZSTs, the type invariant ensures it cannot be null - let $end = unsafe { &mut *(&raw mut $this.end_or_len).cast::>() }; + let $len; + #[allow(unused_unsafe)] // we're sometimes used within an unsafe block + // SAFETY: By type invariant `end >= ptr`, and thus the subtraction + // cannot overflow, and the iter represents a single allocated + // object so the `add` will also be in-range. + let $end = unsafe { + // Need to load as `NonNull` to get `!nonnull` metadata + // (Transmuting gets an assume instead) + let end: NonNull = *ptr::addr_of!($this.end_addr_or_len).cast(); + // Not using `with_addr` because we have ordering information that + // we can take advantage of here that `with_addr` cannot. + $len = intrinsics::ptr_offset_from_unsigned(end.as_ptr(), ptr.as_ptr()); + ptr.add($len) + }; $other_body } }}; ($this:ident, $len:ident => $zst_body:expr, $end:ident => $other_body:expr,) => {{ - #![allow(unused_unsafe)] // we're sometimes used within an unsafe block - if T::IS_ZST { - let $len = $this.end_or_len.addr(); + let $len = $this.end_addr_or_len; $zst_body } else { - // SAFETY: for non-ZSTs, the type invariant ensures it cannot be null - let $end = unsafe { mem::transmute::<*const T, NonNull>($this.end_or_len) }; + let $len; + #[allow(unused_unsafe)] // we're sometimes used within an unsafe block + // SAFETY: By type invariant `end >= ptr`, and thus the subtraction + // cannot overflow, and the iter represents a single allocated + // object so the `add` will also be in-range. + let $end = unsafe { + let ptr = $this.ptr; + // Need to load as `NonNull` to get `!nonnull` metadata + // (Transmuting gets an assume instead) + let end: NonNull = *ptr::addr_of!($this.end_addr_or_len).cast(); + // Not using `with_addr` because we have ordering information that + // we can take advantage of here that `with_addr` cannot. + $len = intrinsics::ptr_offset_from_unsigned(end.as_ptr(), ptr.as_ptr()); + ptr.add($len) + }; $other_body } }}; @@ -50,12 +78,7 @@ macro_rules! len { ($self: ident) => {{ if_zst!($self, len => len, - end => { - // To get rid of some bounds checks (see `position`), we use ptr_sub instead of - // offset_from (Tested by `codegen/slice-position-bounds-check`.) - // SAFETY: by the type invariant pointers are aligned and `start <= end` - unsafe { end.offset_from_unsigned($self.ptr) } - }, + _end => len, ) }}; } @@ -128,8 +151,9 @@ macro_rules! iterator { // which is guaranteed to not overflow an `isize`. Also, the resulting pointer // is in bounds of `slice`, which fulfills the other requirements for `offset`. end => unsafe { - *end = end.sub(offset); - *end + let new_end = end.sub(offset); + set_end!(self.end = new_end); + new_end }, ) } @@ -158,12 +182,11 @@ macro_rules! iterator { // one of the most mono'd things in the library. let ptr = self.ptr; - let end_or_len = self.end_or_len; // SAFETY: See inner comments. (For some reason having multiple // block breaks inlining this -- if you can fix that please do!) unsafe { if T::IS_ZST { - let len = end_or_len.addr(); + let len = self.end_addr_or_len; if len == 0 { return None; } @@ -171,12 +194,12 @@ macro_rules! iterator { // cannot wrap. (Ideally this would be `checked_sub`, which // does the same thing internally, but as of 2025-02 that // doesn't optimize quite as small in MIR.) - self.end_or_len = without_provenance_mut(len.unchecked_sub(1)); + self.end_addr_or_len = intrinsics::unchecked_sub(len, 1); } else { - // SAFETY: by type invariant, the `end_or_len` field is always + // SAFETY: by type invariant, the `end_addr_or_len` field is always // non-null for a non-ZST pointee. (This transmute ensures we // get `!nonnull` metadata on the load of the field.) - if ptr == crate::intrinsics::transmute::<$ptr, NonNull>(end_or_len) { + if ptr == *(&raw const self.end_addr_or_len).cast::>() { return None; } // SAFETY: since it's not empty, per the check above, moving @@ -207,7 +230,7 @@ macro_rules! iterator { // This iterator is now empty. if_zst!(mut self, len => *len = 0, - end => self.ptr = *end, + end => self.ptr = end, ); return None; } @@ -432,7 +455,7 @@ macro_rules! iterator { // This iterator is now empty. if_zst!(mut self, len => *len = 0, - end => *end = self.ptr, + _end => set_end!(self.end = self.ptr), ); return None; } diff --git a/tests/codegen/issues/issue-37945.rs b/tests/codegen/issues/issue-37945.rs index 23d0eab8ae466..9e4f4b6415188 100644 --- a/tests/codegen/issues/issue-37945.rs +++ b/tests/codegen/issues/issue-37945.rs @@ -3,32 +3,33 @@ // Check that LLVM understands that `Iter` pointer is not null. Issue #37945. +// There used to be a comparison against `null`, so we check that it's not there +// and that the appropriate parameter metadata is. + #![crate_type = "lib"] use std::slice::Iter; #[no_mangle] pub fn is_empty_1(xs: Iter) -> bool { - // CHECK-LABEL: @is_empty_1( - // CHECK-NEXT: start: - // CHECK-NEXT: [[A:%.*]] = icmp ne ptr {{%xs.0|%xs.1}}, null - // CHECK-NEXT: tail call void @llvm.assume(i1 [[A]]) - // The order between %xs.0 and %xs.1 on the next line doesn't matter - // and different LLVM versions produce different order. - // CHECK-NEXT: [[B:%.*]] = icmp eq ptr {{%xs.0, %xs.1|%xs.1, %xs.0}} - // CHECK-NEXT: ret i1 [[B:%.*]] + // CHECK-LABEL: @is_empty_1 + // CHECK-SAME: (ptr noundef nonnull{{.*}}%xs.0, {{i32|i64}}{{.+}}%xs.1) + + // CHECK-NOT: null + // CHECK-NOT: i32 0 + // CHECK-NOT: i64 0 + { xs }.next().is_none() } #[no_mangle] pub fn is_empty_2(xs: Iter) -> bool { // CHECK-LABEL: @is_empty_2 - // CHECK-NEXT: start: - // CHECK-NEXT: [[C:%.*]] = icmp ne ptr {{%xs.0|%xs.1}}, null - // CHECK-NEXT: tail call void @llvm.assume(i1 [[C]]) - // The order between %xs.0 and %xs.1 on the next line doesn't matter - // and different LLVM versions produce different order. - // CHECK-NEXT: [[D:%.*]] = icmp eq ptr {{%xs.0, %xs.1|%xs.1, %xs.0}} - // CHECK-NEXT: ret i1 [[D:%.*]] + // CHECK-SAME: (ptr noundef nonnull{{.*}}%xs.0, {{i32|i64}}{{.+}}%xs.1) + + // CHECK-NOT: null + // CHECK-NOT: i32 0 + // CHECK-NOT: i64 0 + xs.map(|&x| x).next().is_none() } diff --git a/tests/codegen/slice-iter-len-eq-zero.rs b/tests/codegen/slice-iter-len-eq-zero.rs index 6998d98e498c9..965a6606112ac 100644 --- a/tests/codegen/slice-iter-len-eq-zero.rs +++ b/tests/codegen/slice-iter-len-eq-zero.rs @@ -1,4 +1,5 @@ //@ compile-flags: -Copt-level=3 +//@ only-64bit //@ needs-deterministic-layouts (opposite scalar pair orders breaks it) #![crate_type = "lib"] @@ -7,8 +8,11 @@ type Demo = [u8; 3]; // CHECK-LABEL: @slice_iter_len_eq_zero #[no_mangle] pub fn slice_iter_len_eq_zero(y: std::slice::Iter<'_, Demo>) -> bool { - // CHECK-NOT: sub - // CHECK: %[[RET:.+]] = icmp eq ptr {{%y.0, %y.1|%y.1, %y.0}} + // CHECK: start: + // CHECK: %[[NOT_ZERO:.+]] = icmp ne i64 %1, 0 + // CHECK: call void @llvm.assume(i1 %[[NOT_ZERO]]) + // CHECK: %[[PTR_ADDR:.+]] = ptrtoint ptr %0 to i64 + // CHECK: %[[RET:.+]] = icmp eq i64 %1, %[[PTR_ADDR]] // CHECK: ret i1 %[[RET]] y.len() == 0 } @@ -21,7 +25,7 @@ pub fn slice_iter_len_eq_zero_ref(y: &mut std::slice::Iter<'_, Demo>) -> bool { // CHECK-SAME: !nonnull // CHECK: %[[B:.+]] = load ptr // CHECK-SAME: !nonnull - // CHECK: %[[RET:.+]] = icmp eq ptr %[[A]], %[[B]] + // CHECK: %[[RET:.+]] = icmp eq ptr %[[B]], %[[A]] // CHECK: ret i1 %[[RET]] y.len() == 0 } @@ -31,7 +35,7 @@ struct MyZST; // CHECK-LABEL: @slice_zst_iter_len_eq_zero #[no_mangle] pub fn slice_zst_iter_len_eq_zero(y: std::slice::Iter<'_, MyZST>) -> bool { - // CHECK: %[[RET:.+]] = icmp eq ptr %y.1, null + // CHECK: %[[RET:.+]] = icmp eq i64 %y.1, 0 // CHECK: ret i1 %[[RET]] y.len() == 0 } @@ -39,9 +43,9 @@ pub fn slice_zst_iter_len_eq_zero(y: std::slice::Iter<'_, MyZST>) -> bool { // CHECK-LABEL: @slice_zst_iter_len_eq_zero_ref #[no_mangle] pub fn slice_zst_iter_len_eq_zero_ref(y: &mut std::slice::Iter<'_, MyZST>) -> bool { - // CHECK: %[[LEN:.+]] = load ptr - // CHECK-NOT: !nonnull - // CHECK: %[[RET:.+]] = icmp eq ptr %[[LEN]], null + // CHECK: %[[LEN:.+]] = load i64 + // CHECK-NOT: !range + // CHECK: %[[RET:.+]] = icmp eq i64 %[[LEN]], 0 // CHECK: ret i1 %[[RET]] y.len() == 0 } diff --git a/tests/codegen/slice-iter-nonnull.rs b/tests/codegen/slice-iter-nonnull.rs index 87907e7ad0a30..5d93245319d07 100644 --- a/tests/codegen/slice-iter-nonnull.rs +++ b/tests/codegen/slice-iter-nonnull.rs @@ -23,7 +23,9 @@ pub fn slice_iter_next<'a>(it: &mut std::slice::Iter<'a, u32>) -> Option<&'a u32 // CHECK-SAME: !noundef // CHECK: icmp eq ptr %[[START]], %[[END]] - // CHECK: store ptr{{.+}}, ptr %it, + // CHECK-NOT: store + // CHECK: store ptr {{.+}}, ptr %it, + // CHECK-NOT: store it.next() } @@ -31,16 +33,18 @@ pub fn slice_iter_next<'a>(it: &mut std::slice::Iter<'a, u32>) -> Option<&'a u32 // CHECK-LABEL: @slice_iter_next_back( #[no_mangle] pub fn slice_iter_next_back<'a>(it: &mut std::slice::Iter<'a, u32>) -> Option<&'a u32> { - // CHECK: %[[ENDP:.+]] = getelementptr inbounds{{( nuw)?}} i8, ptr %it, {{i32 4|i64 8}} - // CHECK: %[[END:.+]] = load ptr, ptr %[[ENDP]] + // CHECK: %[[START:.+]] = load ptr, ptr %it, // CHECK-SAME: !nonnull // CHECK-SAME: !noundef - // CHECK: %[[START:.+]] = load ptr, ptr %it, + // CHECK: %[[ENDP:.+]] = getelementptr inbounds{{( nuw)?}} i8, ptr %it, {{i32 4|i64 8}} + // CHECK: %[[END:.+]] = load ptr, ptr %[[ENDP]] // CHECK-SAME: !nonnull // CHECK-SAME: !noundef // CHECK: icmp eq ptr %[[START]], %[[END]] - // CHECK: store ptr{{.+}}, ptr %[[ENDP]], + // CHECK-NOT: store + // CHECK: store {{i32|i64}} {{.+}}, ptr %[[ENDP]], + // CHECK-NOT: store it.next_back() } @@ -51,30 +55,32 @@ pub fn slice_iter_next_back<'a>(it: &mut std::slice::Iter<'a, u32>) -> Option<&' // attribute is there, and confirms adding the assume back doesn't do anything. // CHECK-LABEL: @slice_iter_new -// CHECK-SAME: (ptr noalias noundef nonnull {{.+}} %slice.0, {{.+}} noundef %slice.1) +// CHECK-SAME: (ptr noalias noundef nonnull {{.+}} %slice.0, [[USIZE:i32|i64]] noundef %slice.1) #[no_mangle] pub fn slice_iter_new(slice: &[u32]) -> std::slice::Iter<'_, u32> { // CHECK-NOT: slice - // CHECK: %[[END:.+]] = getelementptr inbounds{{( nuw)?}} i32{{.+}} %slice.0{{.+}} %slice.1 + // CHECK: %[[END_PTR:.+]] = getelementptr inbounds{{( nuw)?}} i32, ptr %slice.0, [[USIZE]] %slice.1 + // CHECK-NEXT: %[[END_ADDR:.+]] = ptrtoint ptr %[[END_PTR]] to [[USIZE]] // CHECK-NOT: slice // CHECK: insertvalue {{.+}} ptr %slice.0, 0 // CHECK-NOT: slice - // CHECK: insertvalue {{.+}} ptr %[[END]], 1 + // CHECK: insertvalue {{.+}} [[USIZE]] %[[END_ADDR]], 1 // CHECK-NOT: slice // CHECK: } slice.iter() } // CHECK-LABEL: @slice_iter_mut_new -// CHECK-SAME: (ptr noalias noundef nonnull {{.+}} %slice.0, {{.+}} noundef %slice.1) +// CHECK-SAME: (ptr noalias noundef nonnull {{.+}} %slice.0, [[USIZE:i32|i64]] noundef %slice.1) #[no_mangle] pub fn slice_iter_mut_new(slice: &mut [u32]) -> std::slice::IterMut<'_, u32> { // CHECK-NOT: slice - // CHECK: %[[END:.+]] = getelementptr inbounds{{( nuw)?}} i32{{.+}} %slice.0{{.+}} %slice.1 + // CHECK: %[[END_PTR:.+]] = getelementptr inbounds{{( nuw)?}} i32, ptr %slice.0, [[USIZE]] %slice.1 + // CHECK-NEXT: %[[END_ADDR:.+]] = ptrtoint ptr %[[END_PTR]] to [[USIZE]] // CHECK-NOT: slice // CHECK: insertvalue {{.+}} ptr %slice.0, 0 // CHECK-NOT: slice - // CHECK: insertvalue {{.+}} ptr %[[END]], 1 + // CHECK: insertvalue {{.+}} [[USIZE]] %[[END_ADDR]], 1 // CHECK-NOT: slice // CHECK: } slice.iter_mut() @@ -83,11 +89,11 @@ pub fn slice_iter_mut_new(slice: &mut [u32]) -> std::slice::IterMut<'_, u32> { // CHECK-LABEL: @slice_iter_is_empty #[no_mangle] pub fn slice_iter_is_empty(it: &std::slice::Iter<'_, u32>) -> bool { - // CHECK: %[[ENDP:.+]] = getelementptr inbounds{{( nuw)?}} i8, ptr %it, {{i32 4|i64 8}} - // CHECK: %[[END:.+]] = load ptr, ptr %[[ENDP]] + // CHECK: %[[START:.+]] = load ptr, ptr %it, // CHECK-SAME: !nonnull // CHECK-SAME: !noundef - // CHECK: %[[START:.+]] = load ptr, ptr %it, + // CHECK: %[[ENDP:.+]] = getelementptr inbounds{{( nuw)?}} i8, ptr %it, {{i32 4|i64 8}} + // CHECK: %[[END:.+]] = load ptr, ptr %[[ENDP]] // CHECK-SAME: !nonnull // CHECK-SAME: !noundef @@ -99,17 +105,18 @@ pub fn slice_iter_is_empty(it: &std::slice::Iter<'_, u32>) -> bool { // CHECK-LABEL: @slice_iter_len #[no_mangle] pub fn slice_iter_len(it: &std::slice::Iter<'_, u32>) -> usize { - // CHECK: %[[ENDP:.+]] = getelementptr inbounds{{( nuw)?}} i8, ptr %it, {{i32 4|i64 8}} - // CHECK: %[[END:.+]] = load ptr, ptr %[[ENDP]] + // CHECK: %[[START:.+]] = load ptr, ptr %it, // CHECK-SAME: !nonnull // CHECK-SAME: !noundef - // CHECK: %[[START:.+]] = load ptr, ptr %it, + // CHECK: %[[ENDP:.+]] = getelementptr inbounds{{( nuw)?}} i8, ptr %it, {{i32 4|i64 8}} + // CHECK: %[[END:.+]] = load ptr, ptr %[[ENDP]] // CHECK-SAME: !nonnull // CHECK-SAME: !noundef - // CHECK: ptrtoint - // CHECK: ptrtoint - // CHECK: sub nuw - // CHECK: lshr exact + // CHECK: %[[END_ADDR:.+]] = ptrtoint ptr %[[END]] + // CHECK: %[[START_ADDR:.+]] = ptrtoint ptr %[[START]] + // CHECK: %[[BYTES:.+]] = sub nuw [[USIZE]] %[[END_ADDR]], %[[START_ADDR]] + // CHECK: %[[ELEMS:.+]] = lshr exact [[USIZE]] %[[BYTES]], 2 + // CHECK: ret [[USIZE]] %[[ELEMS]] it.len() } diff --git a/tests/mir-opt/pre-codegen/slice_iter.enumerated_loop.PreCodegen.after.panic-abort.mir b/tests/mir-opt/pre-codegen/slice_iter.enumerated_loop.PreCodegen.after.panic-abort.mir index d389e4069d05a..ae7c0ecca1788 100644 --- a/tests/mir-opt/pre-codegen/slice_iter.enumerated_loop.PreCodegen.after.panic-abort.mir +++ b/tests/mir-opt/pre-codegen/slice_iter.enumerated_loop.PreCodegen.after.panic-abort.mir @@ -4,95 +4,45 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () { debug slice => _1; debug f => _2; let mut _0: (); - let mut _11: std::ptr::NonNull; - let mut _12: *const T; - let mut _13: usize; - let mut _32: std::option::Option<(usize, &T)>; - let mut _35: &impl Fn(usize, &T); - let mut _36: (usize, &T); - let _37: (); + let mut _10: std::slice::Iter<'_, T>; + let mut _11: std::iter::Enumerate>; + let mut _12: std::iter::Enumerate>; + let mut _20: std::option::Option<(usize, &T)>; + let mut _23: &impl Fn(usize, &T); + let mut _24: (usize, &T); + let _25: (); scope 1 { - debug (((iter: Enumerate>).0: std::slice::Iter<'_, T>).0: std::ptr::NonNull) => _11; - debug (((iter: Enumerate>).0: std::slice::Iter<'_, T>).1: *const T) => _12; - debug (((iter: Enumerate>).0: std::slice::Iter<'_, T>).2: std::marker::PhantomData<&T>) => const ZeroSized: PhantomData<&T>; - debug ((iter: Enumerate>).1: usize) => _13; - let _33: usize; - let _34: &T; + debug iter => _12; + let _21: usize; + let _22: &T; scope 2 { - debug i => _33; - debug x => _34; + debug i => _21; + debug x => _22; } - scope 18 (inlined > as Iterator>::next) { - let mut _27: std::option::Option<&T>; - let mut _30: (usize, bool); - let mut _31: (usize, &T); - scope 19 { - let _29: usize; - scope 24 { + scope 17 (inlined > as Iterator>::next) { + let mut _13: &mut std::slice::Iter<'_, T>; + let mut _14: std::option::Option<&T>; + let mut _18: (usize, bool); + let mut _19: (usize, &T); + scope 18 { + let _17: usize; + scope 23 { } } - scope 20 { - scope 21 { - scope 27 (inlined as FromResidual>>::from_residual) { + scope 19 { + scope 20 { + scope 26 (inlined as FromResidual>>::from_residual) { } } } - scope 22 { - scope 23 { - } - } - scope 25 (inlined as Try>::branch) { - let _28: &T; - scope 26 { + scope 21 { + scope 22 { } } - scope 28 (inlined as Iterator>::next) { - let _14: std::ptr::NonNull; - let _16: std::ptr::NonNull; - let mut _19: bool; - let mut _22: std::ptr::NonNull; - let mut _24: usize; - let _26: &T; - scope 29 { - let _15: *const T; - scope 30 { - let _23: usize; - scope 31 { - scope 34 (inlined #[track_caller] core::num::::unchecked_sub) { - scope 35 (inlined core::ub_checks::check_language_ub) { - scope 36 (inlined core::ub_checks::check_language_ub::runtime) { - } - } - } - scope 37 (inlined without_provenance_mut::) { - } - } - scope 32 (inlined std::ptr::const_ptr::::addr) { - scope 33 (inlined std::ptr::const_ptr::::cast::<()>) { - } - } - scope 38 (inlined as PartialEq>::eq) { - let mut _17: *mut T; - let mut _18: *mut T; - scope 39 (inlined NonNull::::as_ptr) { - } - scope 40 (inlined NonNull::::as_ptr) { - } - } - scope 41 (inlined NonNull::::add) { - let mut _20: *const T; - let mut _21: *const T; - scope 42 (inlined NonNull::::as_ptr) { - } - } - scope 43 (inlined NonNull::::as_ref::<'_>) { - let _25: *const T; - scope 44 (inlined NonNull::::as_ptr) { - } - scope 45 (inlined std::ptr::mut_ptr::::cast_const) { - } - } - } + scope 24 (inlined as Try>::branch) { + let mut _15: isize; + let _16: &T; + scope 25 { } } } @@ -100,22 +50,19 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () { scope 3 (inlined core::slice::::iter) { scope 4 (inlined std::slice::Iter::<'_, T>::new) { let _3: usize; - let mut _7: *mut T; - let mut _8: *mut T; - let mut _10: *const T; + let mut _9: usize; scope 5 { let _6: std::ptr::NonNull; scope 6 { - let _9: *const T; + let _8: usize; scope 7 { } - scope 11 (inlined std::ptr::without_provenance::) { - scope 12 (inlined without_provenance_mut::) { + scope 11 (inlined NonNull::::add) { + let mut _7: *const T; + scope 12 (inlined NonNull::::as_ptr) { } } - scope 13 (inlined NonNull::::as_ptr) { - } - scope 14 (inlined #[track_caller] std::ptr::mut_ptr::::add) { + scope 13 (inlined core::slice::iter::addr_usize::) { } } scope 8 (inlined NonNull::<[T]>::from_ref) { @@ -129,187 +76,122 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () { } } } - scope 15 (inlined as Iterator>::enumerate) { - scope 16 (inlined Enumerate::>::new) { + scope 14 (inlined as Iterator>::enumerate) { + scope 15 (inlined Enumerate::>::new) { } } - scope 17 (inlined > as IntoIterator>::into_iter) { + scope 16 (inlined > as IntoIterator>::into_iter) { } bb0: { + StorageLive(_10); StorageLive(_3); + StorageLive(_6); StorageLive(_4); + StorageLive(_5); + StorageLive(_7); _3 = PtrMetadata(copy _1); _4 = &raw const (*_1); - StorageLive(_5); _5 = copy _4 as *const T (PtrToPtr); - _6 = NonNull:: { pointer: move _5 }; - StorageDead(_5); - StorageLive(_9); + _6 = NonNull:: { pointer: copy _5 }; + StorageLive(_8); switchInt(const ::IS_ZST) -> [0: bb1, otherwise: bb2]; } bb1: { - StorageLive(_8); - StorageLive(_7); - _7 = copy _4 as *mut T (PtrToPtr); - _8 = Offset(copy _7, copy _3); - StorageDead(_7); - _9 = move _8 as *const T (PtrToPtr); - StorageDead(_8); + _7 = Offset(copy _5, copy _3); + _8 = copy _7 as usize (Transmute); goto -> bb3; } bb2: { - _9 = copy _3 as *const T (Transmute); + _8 = copy _3; goto -> bb3; } bb3: { - _10 = copy _9; + StorageLive(_9); + _9 = copy _8; + _10 = std::slice::Iter::<'_, T> { ptr: copy _6, end_addr_or_len: move _9, _marker: const ZeroSized: PhantomData<&T> }; StorageDead(_9); + StorageDead(_8); + StorageDead(_7); + StorageDead(_5); StorageDead(_4); + StorageDead(_6); StorageDead(_3); - StorageLive(_11); + _11 = Enumerate::> { iter: copy _10, count: const 0_usize }; + StorageDead(_10); StorageLive(_12); - StorageLive(_13); - _11 = copy _6; - _12 = copy _10; - _13 = const 0_usize; + _12 = copy _11; goto -> bb4; } bb4: { - StorageLive(_32); - StorageLive(_29); - StorageLive(_30); - StorageLive(_27); + StorageLive(_20); + StorageLive(_17); + StorageLive(_18); StorageLive(_14); - StorageLive(_15); - StorageLive(_23); - StorageLive(_24); - StorageLive(_16); - StorageLive(_26); - _14 = copy _11; - _15 = copy _12; - switchInt(const ::IS_ZST) -> [0: bb5, otherwise: bb8]; + StorageLive(_13); + _13 = &mut (_12.0: std::slice::Iter<'_, T>); + _14 = as Iterator>::next(move _13) -> [return: bb5, unwind unreachable]; } bb5: { - StorageLive(_19); - _16 = copy _15 as std::ptr::NonNull (Transmute); - StorageLive(_17); - _17 = copy _14 as *mut T (Transmute); - StorageLive(_18); - _18 = copy _16 as *mut T (Transmute); - _19 = Eq(move _17, move _18); - StorageDead(_18); - StorageDead(_17); - switchInt(move _19) -> [0: bb6, otherwise: bb7]; + StorageDead(_13); + StorageLive(_15); + _15 = discriminant(_14); + switchInt(move _15) -> [0: bb6, 1: bb8, otherwise: bb11]; } bb6: { - StorageDead(_19); - StorageLive(_22); - StorageLive(_21); - StorageLive(_20); - _20 = copy _14 as *const T (Transmute); - _21 = Offset(move _20, const 1_usize); + StorageDead(_15); + StorageDead(_14); + StorageDead(_18); + StorageDead(_17); StorageDead(_20); - _22 = NonNull:: { pointer: move _21 }; - StorageDead(_21); - _11 = move _22; - StorageDead(_22); - goto -> bb13; + StorageDead(_12); + drop(_2) -> [return: bb7, unwind unreachable]; } bb7: { - StorageDead(_19); - StorageDead(_26); - StorageDead(_16); - StorageDead(_24); - StorageDead(_23); - StorageDead(_15); - StorageDead(_14); - goto -> bb10; + return; } bb8: { - _23 = copy _15 as usize (Transmute); - switchInt(copy _23) -> [0: bb9, otherwise: bb12]; - } - - bb9: { - StorageDead(_26); - StorageDead(_16); - StorageDead(_24); - StorageDead(_23); + _16 = move ((_14 as Some).0: &T); StorageDead(_15); StorageDead(_14); - goto -> bb10; - } - - bb10: { - StorageDead(_27); - StorageDead(_30); - StorageDead(_29); - StorageDead(_32); - StorageDead(_11); - StorageDead(_12); - StorageDead(_13); - drop(_2) -> [return: bb11, unwind unreachable]; - } - - bb11: { - return; + _17 = copy (_12.1: usize); + _18 = AddWithOverflow(copy (_12.1: usize), const 1_usize); + assert(!move (_18.1: bool), "attempt to compute `{} + {}`, which would overflow", copy (_12.1: usize), const 1_usize) -> [success: bb9, unwind unreachable]; } - bb12: { - _24 = SubUnchecked(copy _23, const 1_usize); - _12 = copy _24 as *const T (Transmute); - goto -> bb13; + bb9: { + (_12.1: usize) = move (_18.0: usize); + StorageLive(_19); + _19 = (copy _17, copy _16); + _20 = Option::<(usize, &T)>::Some(move _19); + StorageDead(_19); + StorageDead(_18); + StorageDead(_17); + _21 = copy (((_20 as Some).0: (usize, &T)).0: usize); + _22 = copy (((_20 as Some).0: (usize, &T)).1: &T); + StorageLive(_23); + _23 = &_2; + StorageLive(_24); + _24 = (copy _21, copy _22); + _25 = >::call(move _23, move _24) -> [return: bb10, unwind unreachable]; } - bb13: { - StorageLive(_25); - _25 = copy _14 as *const T (Transmute); - _26 = &(*_25); - StorageDead(_25); - _27 = Option::<&T>::Some(copy _26); - StorageDead(_26); - StorageDead(_16); + bb10: { StorageDead(_24); StorageDead(_23); - StorageDead(_15); - StorageDead(_14); - _28 = move ((_27 as Some).0: &T); - StorageDead(_27); - _29 = copy _13; - _30 = AddWithOverflow(copy _13, const 1_usize); - assert(!move (_30.1: bool), "attempt to compute `{} + {}`, which would overflow", copy _13, const 1_usize) -> [success: bb14, unwind unreachable]; - } - - bb14: { - _13 = move (_30.0: usize); - StorageLive(_31); - _31 = (copy _29, copy _28); - _32 = Option::<(usize, &T)>::Some(move _31); - StorageDead(_31); - StorageDead(_30); - StorageDead(_29); - _33 = copy (((_32 as Some).0: (usize, &T)).0: usize); - _34 = copy (((_32 as Some).0: (usize, &T)).1: &T); - StorageLive(_35); - _35 = &_2; - StorageLive(_36); - _36 = (copy _33, copy _34); - _37 = >::call(move _35, move _36) -> [return: bb15, unwind unreachable]; + StorageDead(_20); + goto -> bb4; } - bb15: { - StorageDead(_36); - StorageDead(_35); - StorageDead(_32); - goto -> bb4; + bb11: { + unreachable; } } diff --git a/tests/mir-opt/pre-codegen/slice_iter.enumerated_loop.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/pre-codegen/slice_iter.enumerated_loop.PreCodegen.after.panic-unwind.mir index 3b58f1d61f4bb..bcea0f4b02e04 100644 --- a/tests/mir-opt/pre-codegen/slice_iter.enumerated_loop.PreCodegen.after.panic-unwind.mir +++ b/tests/mir-opt/pre-codegen/slice_iter.enumerated_loop.PreCodegen.after.panic-unwind.mir @@ -4,43 +4,40 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () { debug slice => _1; debug f => _2; let mut _0: (); - let mut _11: std::slice::Iter<'_, T>; + let mut _10: std::slice::Iter<'_, T>; + let mut _11: std::iter::Enumerate>; let mut _12: std::iter::Enumerate>; - let mut _13: std::iter::Enumerate>; - let mut _14: &mut std::iter::Enumerate>; - let mut _15: std::option::Option<(usize, &T)>; - let mut _16: isize; - let mut _19: &impl Fn(usize, &T); - let mut _20: (usize, &T); - let _21: (); + let mut _13: &mut std::iter::Enumerate>; + let mut _14: std::option::Option<(usize, &T)>; + let mut _15: isize; + let mut _18: &impl Fn(usize, &T); + let mut _19: (usize, &T); + let _20: (); scope 1 { - debug iter => _13; - let _17: usize; - let _18: &T; + debug iter => _12; + let _16: usize; + let _17: &T; scope 2 { - debug i => _17; - debug x => _18; + debug i => _16; + debug x => _17; } } scope 3 (inlined core::slice::::iter) { scope 4 (inlined std::slice::Iter::<'_, T>::new) { let _3: usize; - let mut _7: *mut T; - let mut _8: *mut T; - let mut _10: *const T; + let mut _9: usize; scope 5 { let _6: std::ptr::NonNull; scope 6 { - let _9: *const T; + let _8: usize; scope 7 { } - scope 11 (inlined std::ptr::without_provenance::) { - scope 12 (inlined without_provenance_mut::) { + scope 11 (inlined NonNull::::add) { + let mut _7: *const T; + scope 12 (inlined NonNull::::as_ptr) { } } - scope 13 (inlined NonNull::::as_ptr) { - } - scope 14 (inlined #[track_caller] std::ptr::mut_ptr::::add) { + scope 13 (inlined core::slice::iter::addr_usize::) { } } scope 8 (inlined NonNull::<[T]>::from_ref) { @@ -54,74 +51,71 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () { } } } - scope 15 (inlined as Iterator>::enumerate) { - scope 16 (inlined Enumerate::>::new) { + scope 14 (inlined as Iterator>::enumerate) { + scope 15 (inlined Enumerate::>::new) { } } - scope 17 (inlined > as IntoIterator>::into_iter) { + scope 16 (inlined > as IntoIterator>::into_iter) { } bb0: { - StorageLive(_11); + StorageLive(_10); StorageLive(_3); StorageLive(_6); StorageLive(_4); + StorageLive(_5); + StorageLive(_7); _3 = PtrMetadata(copy _1); _4 = &raw const (*_1); - StorageLive(_5); _5 = copy _4 as *const T (PtrToPtr); - _6 = NonNull:: { pointer: move _5 }; - StorageDead(_5); - StorageLive(_9); + _6 = NonNull:: { pointer: copy _5 }; + StorageLive(_8); switchInt(const ::IS_ZST) -> [0: bb1, otherwise: bb2]; } bb1: { - StorageLive(_8); - StorageLive(_7); - _7 = copy _4 as *mut T (PtrToPtr); - _8 = Offset(copy _7, copy _3); - StorageDead(_7); - _9 = move _8 as *const T (PtrToPtr); - StorageDead(_8); + _7 = Offset(copy _5, copy _3); + _8 = copy _7 as usize (Transmute); goto -> bb3; } bb2: { - _9 = copy _3 as *const T (Transmute); + _8 = copy _3; goto -> bb3; } bb3: { - StorageLive(_10); - _10 = copy _9; - _11 = std::slice::Iter::<'_, T> { ptr: copy _6, end_or_len: move _10, _marker: const ZeroSized: PhantomData<&T> }; - StorageDead(_10); + StorageLive(_9); + _9 = copy _8; + _10 = std::slice::Iter::<'_, T> { ptr: copy _6, end_addr_or_len: move _9, _marker: const ZeroSized: PhantomData<&T> }; StorageDead(_9); + StorageDead(_8); + StorageDead(_7); + StorageDead(_5); StorageDead(_4); StorageDead(_6); StorageDead(_3); - _12 = Enumerate::> { iter: copy _11, count: const 0_usize }; - StorageDead(_11); - StorageLive(_13); - _13 = copy _12; + _11 = Enumerate::> { iter: copy _10, count: const 0_usize }; + StorageDead(_10); + StorageLive(_12); + _12 = copy _11; goto -> bb4; } bb4: { - StorageLive(_15); - _14 = &mut _13; - _15 = > as Iterator>::next(move _14) -> [return: bb5, unwind: bb11]; + StorageLive(_14); + _13 = &mut _12; + _14 = > as Iterator>::next(move _13) -> [return: bb5, unwind: bb11]; } bb5: { - _16 = discriminant(_15); - switchInt(move _16) -> [0: bb6, 1: bb8, otherwise: bb10]; + _15 = discriminant(_14); + switchInt(move _15) -> [0: bb6, 1: bb8, otherwise: bb10]; } bb6: { - StorageDead(_15); - StorageDead(_13); + StorageDead(_14); + StorageDead(_12); drop(_2) -> [return: bb7, unwind continue]; } @@ -130,19 +124,19 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () { } bb8: { - _17 = copy (((_15 as Some).0: (usize, &T)).0: usize); - _18 = copy (((_15 as Some).0: (usize, &T)).1: &T); + _16 = copy (((_14 as Some).0: (usize, &T)).0: usize); + _17 = copy (((_14 as Some).0: (usize, &T)).1: &T); + StorageLive(_18); + _18 = &_2; StorageLive(_19); - _19 = &_2; - StorageLive(_20); - _20 = (copy _17, copy _18); - _21 = >::call(move _19, move _20) -> [return: bb9, unwind: bb11]; + _19 = (copy _16, copy _17); + _20 = >::call(move _18, move _19) -> [return: bb9, unwind: bb11]; } bb9: { - StorageDead(_20); StorageDead(_19); - StorageDead(_15); + StorageDead(_18); + StorageDead(_14); goto -> bb4; } diff --git a/tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.panic-abort.mir b/tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.panic-abort.mir index 216e05ec5b79c..09d23d7c867e0 100644 --- a/tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.panic-abort.mir +++ b/tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.panic-abort.mir @@ -4,89 +4,37 @@ fn forward_loop(_1: &[T], _2: impl Fn(&T)) -> () { debug slice => _1; debug f => _2; let mut _0: (); - let mut _11: std::ptr::NonNull; - let mut _12: *const T; - let mut _26: std::option::Option<&T>; - let mut _28: &impl Fn(&T); - let mut _29: (&T,); - let _30: (); + let mut _10: std::slice::Iter<'_, T>; + let mut _11: std::slice::Iter<'_, T>; + let mut _12: &mut std::slice::Iter<'_, T>; + let mut _13: std::option::Option<&T>; + let mut _14: isize; + let mut _16: &impl Fn(&T); + let mut _17: (&T,); + let _18: (); scope 1 { - debug ((iter: std::slice::Iter<'_, T>).0: std::ptr::NonNull) => _11; - debug ((iter: std::slice::Iter<'_, T>).1: *const T) => _12; - debug ((iter: std::slice::Iter<'_, T>).2: std::marker::PhantomData<&T>) => const ZeroSized: PhantomData<&T>; - let _27: &T; + debug iter => _11; + let _15: &T; scope 2 { - debug x => _27; - } - scope 16 (inlined as Iterator>::next) { - let _13: std::ptr::NonNull; - let _15: std::ptr::NonNull; - let mut _18: bool; - let mut _21: std::ptr::NonNull; - let mut _23: usize; - let _25: &T; - scope 17 { - let _14: *const T; - scope 18 { - let _22: usize; - scope 19 { - scope 22 (inlined #[track_caller] core::num::::unchecked_sub) { - scope 23 (inlined core::ub_checks::check_language_ub) { - scope 24 (inlined core::ub_checks::check_language_ub::runtime) { - } - } - } - scope 25 (inlined without_provenance_mut::) { - } - } - scope 20 (inlined std::ptr::const_ptr::::addr) { - scope 21 (inlined std::ptr::const_ptr::::cast::<()>) { - } - } - scope 26 (inlined as PartialEq>::eq) { - let mut _16: *mut T; - let mut _17: *mut T; - scope 27 (inlined NonNull::::as_ptr) { - } - scope 28 (inlined NonNull::::as_ptr) { - } - } - scope 29 (inlined NonNull::::add) { - let mut _19: *const T; - let mut _20: *const T; - scope 30 (inlined NonNull::::as_ptr) { - } - } - scope 31 (inlined NonNull::::as_ref::<'_>) { - let _24: *const T; - scope 32 (inlined NonNull::::as_ptr) { - } - scope 33 (inlined std::ptr::mut_ptr::::cast_const) { - } - } - } - } + debug x => _15; } } scope 3 (inlined core::slice::::iter) { scope 4 (inlined std::slice::Iter::<'_, T>::new) { let _3: usize; - let mut _7: *mut T; - let mut _8: *mut T; - let mut _10: *const T; + let mut _9: usize; scope 5 { let _6: std::ptr::NonNull; scope 6 { - let _9: *const T; + let _8: usize; scope 7 { } - scope 11 (inlined std::ptr::without_provenance::) { - scope 12 (inlined without_provenance_mut::) { + scope 11 (inlined NonNull::::add) { + let mut _7: *const T; + scope 12 (inlined NonNull::::as_ptr) { } } - scope 13 (inlined NonNull::::as_ptr) { - } - scope 14 (inlined #[track_caller] std::ptr::mut_ptr::::add) { + scope 13 (inlined core::slice::iter::addr_usize::) { } } scope 8 (inlined NonNull::<[T]>::from_ref) { @@ -100,158 +48,88 @@ fn forward_loop(_1: &[T], _2: impl Fn(&T)) -> () { } } } - scope 15 (inlined as IntoIterator>::into_iter) { + scope 14 (inlined as IntoIterator>::into_iter) { } bb0: { StorageLive(_3); + StorageLive(_6); StorageLive(_4); + StorageLive(_5); + StorageLive(_7); _3 = PtrMetadata(copy _1); _4 = &raw const (*_1); - StorageLive(_5); _5 = copy _4 as *const T (PtrToPtr); - _6 = NonNull:: { pointer: move _5 }; - StorageDead(_5); - StorageLive(_9); + _6 = NonNull:: { pointer: copy _5 }; + StorageLive(_8); switchInt(const ::IS_ZST) -> [0: bb1, otherwise: bb2]; } bb1: { - StorageLive(_8); - StorageLive(_7); - _7 = copy _4 as *mut T (PtrToPtr); - _8 = Offset(copy _7, copy _3); - StorageDead(_7); - _9 = move _8 as *const T (PtrToPtr); - StorageDead(_8); + _7 = Offset(copy _5, copy _3); + _8 = copy _7 as usize (Transmute); goto -> bb3; } bb2: { - _9 = copy _3 as *const T (Transmute); + _8 = copy _3; goto -> bb3; } bb3: { - _10 = copy _9; + StorageLive(_9); + _9 = copy _8; + _10 = std::slice::Iter::<'_, T> { ptr: copy _6, end_addr_or_len: move _9, _marker: const ZeroSized: PhantomData<&T> }; StorageDead(_9); + StorageDead(_8); + StorageDead(_7); + StorageDead(_5); StorageDead(_4); + StorageDead(_6); StorageDead(_3); StorageLive(_11); - StorageLive(_12); - _11 = copy _6; - _12 = copy _10; + _11 = copy _10; goto -> bb4; } bb4: { - StorageLive(_26); StorageLive(_13); - StorageLive(_14); - StorageLive(_22); - StorageLive(_23); - StorageLive(_15); - StorageLive(_25); - _13 = copy _11; - _14 = copy _12; - switchInt(const ::IS_ZST) -> [0: bb5, otherwise: bb8]; + _12 = &mut _11; + _13 = as Iterator>::next(move _12) -> [return: bb5, unwind unreachable]; } bb5: { - StorageLive(_18); - _15 = copy _14 as std::ptr::NonNull (Transmute); - StorageLive(_16); - _16 = copy _13 as *mut T (Transmute); - StorageLive(_17); - _17 = copy _15 as *mut T (Transmute); - _18 = Eq(move _16, move _17); - StorageDead(_17); - StorageDead(_16); - switchInt(move _18) -> [0: bb6, otherwise: bb7]; + _14 = discriminant(_13); + switchInt(move _14) -> [0: bb6, 1: bb8, otherwise: bb10]; } bb6: { - StorageDead(_18); - StorageLive(_21); - StorageLive(_20); - StorageLive(_19); - _19 = copy _13 as *const T (Transmute); - _20 = Offset(move _19, const 1_usize); - StorageDead(_19); - _21 = NonNull:: { pointer: move _20 }; - StorageDead(_20); - _11 = move _21; - StorageDead(_21); - goto -> bb13; + StorageDead(_13); + StorageDead(_11); + drop(_2) -> [return: bb7, unwind unreachable]; } bb7: { - StorageDead(_18); - StorageDead(_25); - StorageDead(_15); - StorageDead(_23); - StorageDead(_22); - StorageDead(_14); - StorageDead(_13); - goto -> bb10; + return; } bb8: { - _22 = copy _14 as usize (Transmute); - switchInt(copy _22) -> [0: bb9, otherwise: bb12]; + _15 = copy ((_13 as Some).0: &T); + StorageLive(_16); + _16 = &_2; + StorageLive(_17); + _17 = (copy _15,); + _18 = >::call(move _16, move _17) -> [return: bb9, unwind unreachable]; } bb9: { - StorageDead(_25); - StorageDead(_15); - StorageDead(_23); - StorageDead(_22); - StorageDead(_14); + StorageDead(_17); + StorageDead(_16); StorageDead(_13); - goto -> bb10; + goto -> bb4; } bb10: { - StorageDead(_26); - StorageDead(_11); - StorageDead(_12); - drop(_2) -> [return: bb11, unwind unreachable]; - } - - bb11: { - return; - } - - bb12: { - _23 = SubUnchecked(copy _22, const 1_usize); - _12 = copy _23 as *const T (Transmute); - goto -> bb13; - } - - bb13: { - StorageLive(_24); - _24 = copy _13 as *const T (Transmute); - _25 = &(*_24); - StorageDead(_24); - _26 = Option::<&T>::Some(copy _25); - StorageDead(_25); - StorageDead(_15); - StorageDead(_23); - StorageDead(_22); - StorageDead(_14); - StorageDead(_13); - _27 = copy ((_26 as Some).0: &T); - StorageLive(_28); - _28 = &_2; - StorageLive(_29); - _29 = (copy _27,); - _30 = >::call(move _28, move _29) -> [return: bb14, unwind unreachable]; - } - - bb14: { - StorageDead(_29); - StorageDead(_28); - StorageDead(_26); - goto -> bb4; + unreachable; } } diff --git a/tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.panic-unwind.mir index 001023919804a..028b844354e79 100644 --- a/tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.panic-unwind.mir +++ b/tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.panic-unwind.mir @@ -4,89 +4,37 @@ fn forward_loop(_1: &[T], _2: impl Fn(&T)) -> () { debug slice => _1; debug f => _2; let mut _0: (); - let mut _11: std::ptr::NonNull; - let mut _12: *const T; - let mut _26: std::option::Option<&T>; - let mut _28: &impl Fn(&T); - let mut _29: (&T,); - let _30: (); + let mut _10: std::slice::Iter<'_, T>; + let mut _11: std::slice::Iter<'_, T>; + let mut _12: &mut std::slice::Iter<'_, T>; + let mut _13: std::option::Option<&T>; + let mut _14: isize; + let mut _16: &impl Fn(&T); + let mut _17: (&T,); + let _18: (); scope 1 { - debug ((iter: std::slice::Iter<'_, T>).0: std::ptr::NonNull) => _11; - debug ((iter: std::slice::Iter<'_, T>).1: *const T) => _12; - debug ((iter: std::slice::Iter<'_, T>).2: std::marker::PhantomData<&T>) => const ZeroSized: PhantomData<&T>; - let _27: &T; + debug iter => _11; + let _15: &T; scope 2 { - debug x => _27; - } - scope 16 (inlined as Iterator>::next) { - let _13: std::ptr::NonNull; - let _15: std::ptr::NonNull; - let mut _18: bool; - let mut _21: std::ptr::NonNull; - let mut _23: usize; - let _25: &T; - scope 17 { - let _14: *const T; - scope 18 { - let _22: usize; - scope 19 { - scope 22 (inlined #[track_caller] core::num::::unchecked_sub) { - scope 23 (inlined core::ub_checks::check_language_ub) { - scope 24 (inlined core::ub_checks::check_language_ub::runtime) { - } - } - } - scope 25 (inlined without_provenance_mut::) { - } - } - scope 20 (inlined std::ptr::const_ptr::::addr) { - scope 21 (inlined std::ptr::const_ptr::::cast::<()>) { - } - } - scope 26 (inlined as PartialEq>::eq) { - let mut _16: *mut T; - let mut _17: *mut T; - scope 27 (inlined NonNull::::as_ptr) { - } - scope 28 (inlined NonNull::::as_ptr) { - } - } - scope 29 (inlined NonNull::::add) { - let mut _19: *const T; - let mut _20: *const T; - scope 30 (inlined NonNull::::as_ptr) { - } - } - scope 31 (inlined NonNull::::as_ref::<'_>) { - let _24: *const T; - scope 32 (inlined NonNull::::as_ptr) { - } - scope 33 (inlined std::ptr::mut_ptr::::cast_const) { - } - } - } - } + debug x => _15; } } scope 3 (inlined core::slice::::iter) { scope 4 (inlined std::slice::Iter::<'_, T>::new) { let _3: usize; - let mut _7: *mut T; - let mut _8: *mut T; - let mut _10: *const T; + let mut _9: usize; scope 5 { let _6: std::ptr::NonNull; scope 6 { - let _9: *const T; + let _8: usize; scope 7 { } - scope 11 (inlined std::ptr::without_provenance::) { - scope 12 (inlined without_provenance_mut::) { + scope 11 (inlined NonNull::::add) { + let mut _7: *const T; + scope 12 (inlined NonNull::::as_ptr) { } } - scope 13 (inlined NonNull::::as_ptr) { - } - scope 14 (inlined #[track_caller] std::ptr::mut_ptr::::add) { + scope 13 (inlined core::slice::iter::addr_usize::) { } } scope 8 (inlined NonNull::<[T]>::from_ref) { @@ -100,166 +48,96 @@ fn forward_loop(_1: &[T], _2: impl Fn(&T)) -> () { } } } - scope 15 (inlined as IntoIterator>::into_iter) { + scope 14 (inlined as IntoIterator>::into_iter) { } bb0: { StorageLive(_3); + StorageLive(_6); StorageLive(_4); + StorageLive(_5); + StorageLive(_7); _3 = PtrMetadata(copy _1); _4 = &raw const (*_1); - StorageLive(_5); _5 = copy _4 as *const T (PtrToPtr); - _6 = NonNull:: { pointer: move _5 }; - StorageDead(_5); - StorageLive(_9); + _6 = NonNull:: { pointer: copy _5 }; + StorageLive(_8); switchInt(const ::IS_ZST) -> [0: bb1, otherwise: bb2]; } bb1: { - StorageLive(_8); - StorageLive(_7); - _7 = copy _4 as *mut T (PtrToPtr); - _8 = Offset(copy _7, copy _3); - StorageDead(_7); - _9 = move _8 as *const T (PtrToPtr); - StorageDead(_8); + _7 = Offset(copy _5, copy _3); + _8 = copy _7 as usize (Transmute); goto -> bb3; } bb2: { - _9 = copy _3 as *const T (Transmute); + _8 = copy _3; goto -> bb3; } bb3: { - _10 = copy _9; + StorageLive(_9); + _9 = copy _8; + _10 = std::slice::Iter::<'_, T> { ptr: copy _6, end_addr_or_len: move _9, _marker: const ZeroSized: PhantomData<&T> }; StorageDead(_9); + StorageDead(_8); + StorageDead(_7); + StorageDead(_5); StorageDead(_4); + StorageDead(_6); StorageDead(_3); StorageLive(_11); - StorageLive(_12); - _11 = copy _6; - _12 = copy _10; + _11 = copy _10; goto -> bb4; } bb4: { - StorageLive(_26); StorageLive(_13); - StorageLive(_14); - StorageLive(_22); - StorageLive(_23); - StorageLive(_15); - StorageLive(_25); - _13 = copy _11; - _14 = copy _12; - switchInt(const ::IS_ZST) -> [0: bb5, otherwise: bb8]; + _12 = &mut _11; + _13 = as Iterator>::next(move _12) -> [return: bb5, unwind: bb11]; } bb5: { - StorageLive(_18); - _15 = copy _14 as std::ptr::NonNull (Transmute); - StorageLive(_16); - _16 = copy _13 as *mut T (Transmute); - StorageLive(_17); - _17 = copy _15 as *mut T (Transmute); - _18 = Eq(move _16, move _17); - StorageDead(_17); - StorageDead(_16); - switchInt(move _18) -> [0: bb6, otherwise: bb7]; + _14 = discriminant(_13); + switchInt(move _14) -> [0: bb6, 1: bb8, otherwise: bb10]; } bb6: { - StorageDead(_18); - StorageLive(_21); - StorageLive(_20); - StorageLive(_19); - _19 = copy _13 as *const T (Transmute); - _20 = Offset(move _19, const 1_usize); - StorageDead(_19); - _21 = NonNull:: { pointer: move _20 }; - StorageDead(_20); - _11 = move _21; - StorageDead(_21); - goto -> bb13; + StorageDead(_13); + StorageDead(_11); + drop(_2) -> [return: bb7, unwind continue]; } bb7: { - StorageDead(_18); - StorageDead(_25); - StorageDead(_15); - StorageDead(_23); - StorageDead(_22); - StorageDead(_14); - StorageDead(_13); - goto -> bb10; + return; } bb8: { - _22 = copy _14 as usize (Transmute); - switchInt(copy _22) -> [0: bb9, otherwise: bb12]; + _15 = copy ((_13 as Some).0: &T); + StorageLive(_16); + _16 = &_2; + StorageLive(_17); + _17 = (copy _15,); + _18 = >::call(move _16, move _17) -> [return: bb9, unwind: bb11]; } bb9: { - StorageDead(_25); - StorageDead(_15); - StorageDead(_23); - StorageDead(_22); - StorageDead(_14); + StorageDead(_17); + StorageDead(_16); StorageDead(_13); - goto -> bb10; + goto -> bb4; } bb10: { - StorageDead(_26); - StorageDead(_11); - StorageDead(_12); - drop(_2) -> [return: bb11, unwind continue]; - } - - bb11: { - return; - } - - bb12: { - _23 = SubUnchecked(copy _22, const 1_usize); - _12 = copy _23 as *const T (Transmute); - goto -> bb13; - } - - bb13: { - StorageLive(_24); - _24 = copy _13 as *const T (Transmute); - _25 = &(*_24); - StorageDead(_24); - _26 = Option::<&T>::Some(copy _25); - StorageDead(_25); - StorageDead(_15); - StorageDead(_23); - StorageDead(_22); - StorageDead(_14); - StorageDead(_13); - _27 = copy ((_26 as Some).0: &T); - StorageLive(_28); - _28 = &_2; - StorageLive(_29); - _29 = (copy _27,); - _30 = >::call(move _28, move _29) -> [return: bb14, unwind: bb15]; - } - - bb14: { - StorageDead(_29); - StorageDead(_28); - StorageDead(_26); - goto -> bb4; + unreachable; } - bb15 (cleanup): { - drop(_2) -> [return: bb16, unwind terminate(cleanup)]; + bb11 (cleanup): { + drop(_2) -> [return: bb12, unwind terminate(cleanup)]; } - bb16 (cleanup): { + bb12 (cleanup): { resume; } } diff --git a/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.panic-abort.mir b/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.panic-abort.mir index b09e36223441a..5bd5467c8eaa8 100644 --- a/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.panic-abort.mir +++ b/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.panic-abort.mir @@ -4,43 +4,40 @@ fn reverse_loop(_1: &[T], _2: impl Fn(&T)) -> () { debug slice => _1; debug f => _2; let mut _0: (); - let mut _11: std::slice::Iter<'_, T>; + let mut _10: std::slice::Iter<'_, T>; + let mut _11: std::iter::Rev>; let mut _12: std::iter::Rev>; - let mut _13: std::iter::Rev>; - let mut _15: std::option::Option<&T>; - let mut _16: isize; - let mut _18: &impl Fn(&T); - let mut _19: (&T,); - let _20: (); + let mut _14: std::option::Option<&T>; + let mut _15: isize; + let mut _17: &impl Fn(&T); + let mut _18: (&T,); + let _19: (); scope 1 { - debug iter => _13; - let _17: &T; + debug iter => _12; + let _16: &T; scope 2 { - debug x => _17; + debug x => _16; } - scope 18 (inlined > as Iterator>::next) { - let mut _14: &mut std::slice::Iter<'_, T>; + scope 17 (inlined > as Iterator>::next) { + let mut _13: &mut std::slice::Iter<'_, T>; } } scope 3 (inlined core::slice::::iter) { scope 4 (inlined std::slice::Iter::<'_, T>::new) { let _3: usize; - let mut _7: *mut T; - let mut _8: *mut T; - let mut _10: *const T; + let mut _9: usize; scope 5 { let _6: std::ptr::NonNull; scope 6 { - let _9: *const T; + let _8: usize; scope 7 { } - scope 11 (inlined std::ptr::without_provenance::) { - scope 12 (inlined without_provenance_mut::) { + scope 11 (inlined NonNull::::add) { + let mut _7: *const T; + scope 12 (inlined NonNull::::as_ptr) { } } - scope 13 (inlined NonNull::::as_ptr) { - } - scope 14 (inlined #[track_caller] std::ptr::mut_ptr::::add) { + scope 13 (inlined core::slice::iter::addr_usize::) { } } scope 8 (inlined NonNull::<[T]>::from_ref) { @@ -54,76 +51,73 @@ fn reverse_loop(_1: &[T], _2: impl Fn(&T)) -> () { } } } - scope 15 (inlined as Iterator>::rev) { - scope 16 (inlined Rev::>::new) { + scope 14 (inlined as Iterator>::rev) { + scope 15 (inlined Rev::>::new) { } } - scope 17 (inlined > as IntoIterator>::into_iter) { + scope 16 (inlined > as IntoIterator>::into_iter) { } bb0: { - StorageLive(_11); + StorageLive(_10); StorageLive(_3); StorageLive(_6); StorageLive(_4); + StorageLive(_5); + StorageLive(_7); _3 = PtrMetadata(copy _1); _4 = &raw const (*_1); - StorageLive(_5); _5 = copy _4 as *const T (PtrToPtr); - _6 = NonNull:: { pointer: move _5 }; - StorageDead(_5); - StorageLive(_9); + _6 = NonNull:: { pointer: copy _5 }; + StorageLive(_8); switchInt(const ::IS_ZST) -> [0: bb1, otherwise: bb2]; } bb1: { - StorageLive(_8); - StorageLive(_7); - _7 = copy _4 as *mut T (PtrToPtr); - _8 = Offset(copy _7, copy _3); - StorageDead(_7); - _9 = move _8 as *const T (PtrToPtr); - StorageDead(_8); + _7 = Offset(copy _5, copy _3); + _8 = copy _7 as usize (Transmute); goto -> bb3; } bb2: { - _9 = copy _3 as *const T (Transmute); + _8 = copy _3; goto -> bb3; } bb3: { - StorageLive(_10); - _10 = copy _9; - _11 = std::slice::Iter::<'_, T> { ptr: copy _6, end_or_len: move _10, _marker: const ZeroSized: PhantomData<&T> }; - StorageDead(_10); + StorageLive(_9); + _9 = copy _8; + _10 = std::slice::Iter::<'_, T> { ptr: copy _6, end_addr_or_len: move _9, _marker: const ZeroSized: PhantomData<&T> }; StorageDead(_9); + StorageDead(_8); + StorageDead(_7); + StorageDead(_5); StorageDead(_4); StorageDead(_6); StorageDead(_3); - _12 = Rev::> { iter: copy _11 }; - StorageDead(_11); - StorageLive(_13); - _13 = copy _12; + _11 = Rev::> { iter: copy _10 }; + StorageDead(_10); + StorageLive(_12); + _12 = copy _11; goto -> bb4; } bb4: { - StorageLive(_15); StorageLive(_14); - _14 = &mut (_13.0: std::slice::Iter<'_, T>); - _15 = as DoubleEndedIterator>::next_back(move _14) -> [return: bb5, unwind unreachable]; + StorageLive(_13); + _13 = &mut (_12.0: std::slice::Iter<'_, T>); + _14 = as DoubleEndedIterator>::next_back(move _13) -> [return: bb5, unwind unreachable]; } bb5: { - StorageDead(_14); - _16 = discriminant(_15); - switchInt(move _16) -> [0: bb6, 1: bb8, otherwise: bb10]; + StorageDead(_13); + _15 = discriminant(_14); + switchInt(move _15) -> [0: bb6, 1: bb8, otherwise: bb10]; } bb6: { - StorageDead(_15); - StorageDead(_13); + StorageDead(_14); + StorageDead(_12); drop(_2) -> [return: bb7, unwind unreachable]; } @@ -132,18 +126,18 @@ fn reverse_loop(_1: &[T], _2: impl Fn(&T)) -> () { } bb8: { - _17 = copy ((_15 as Some).0: &T); + _16 = copy ((_14 as Some).0: &T); + StorageLive(_17); + _17 = &_2; StorageLive(_18); - _18 = &_2; - StorageLive(_19); - _19 = (copy _17,); - _20 = >::call(move _18, move _19) -> [return: bb9, unwind unreachable]; + _18 = (copy _16,); + _19 = >::call(move _17, move _18) -> [return: bb9, unwind unreachable]; } bb9: { - StorageDead(_19); StorageDead(_18); - StorageDead(_15); + StorageDead(_17); + StorageDead(_14); goto -> bb4; } diff --git a/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.panic-unwind.mir index 12b54b57b8448..9d5f9430e30d5 100644 --- a/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.panic-unwind.mir +++ b/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.panic-unwind.mir @@ -4,43 +4,40 @@ fn reverse_loop(_1: &[T], _2: impl Fn(&T)) -> () { debug slice => _1; debug f => _2; let mut _0: (); - let mut _11: std::slice::Iter<'_, T>; + let mut _10: std::slice::Iter<'_, T>; + let mut _11: std::iter::Rev>; let mut _12: std::iter::Rev>; - let mut _13: std::iter::Rev>; - let mut _15: std::option::Option<&T>; - let mut _16: isize; - let mut _18: &impl Fn(&T); - let mut _19: (&T,); - let _20: (); + let mut _14: std::option::Option<&T>; + let mut _15: isize; + let mut _17: &impl Fn(&T); + let mut _18: (&T,); + let _19: (); scope 1 { - debug iter => _13; - let _17: &T; + debug iter => _12; + let _16: &T; scope 2 { - debug x => _17; + debug x => _16; } - scope 18 (inlined > as Iterator>::next) { - let mut _14: &mut std::slice::Iter<'_, T>; + scope 17 (inlined > as Iterator>::next) { + let mut _13: &mut std::slice::Iter<'_, T>; } } scope 3 (inlined core::slice::::iter) { scope 4 (inlined std::slice::Iter::<'_, T>::new) { let _3: usize; - let mut _7: *mut T; - let mut _8: *mut T; - let mut _10: *const T; + let mut _9: usize; scope 5 { let _6: std::ptr::NonNull; scope 6 { - let _9: *const T; + let _8: usize; scope 7 { } - scope 11 (inlined std::ptr::without_provenance::) { - scope 12 (inlined without_provenance_mut::) { + scope 11 (inlined NonNull::::add) { + let mut _7: *const T; + scope 12 (inlined NonNull::::as_ptr) { } } - scope 13 (inlined NonNull::::as_ptr) { - } - scope 14 (inlined #[track_caller] std::ptr::mut_ptr::::add) { + scope 13 (inlined core::slice::iter::addr_usize::) { } } scope 8 (inlined NonNull::<[T]>::from_ref) { @@ -54,76 +51,73 @@ fn reverse_loop(_1: &[T], _2: impl Fn(&T)) -> () { } } } - scope 15 (inlined as Iterator>::rev) { - scope 16 (inlined Rev::>::new) { + scope 14 (inlined as Iterator>::rev) { + scope 15 (inlined Rev::>::new) { } } - scope 17 (inlined > as IntoIterator>::into_iter) { + scope 16 (inlined > as IntoIterator>::into_iter) { } bb0: { - StorageLive(_11); + StorageLive(_10); StorageLive(_3); StorageLive(_6); StorageLive(_4); + StorageLive(_5); + StorageLive(_7); _3 = PtrMetadata(copy _1); _4 = &raw const (*_1); - StorageLive(_5); _5 = copy _4 as *const T (PtrToPtr); - _6 = NonNull:: { pointer: move _5 }; - StorageDead(_5); - StorageLive(_9); + _6 = NonNull:: { pointer: copy _5 }; + StorageLive(_8); switchInt(const ::IS_ZST) -> [0: bb1, otherwise: bb2]; } bb1: { - StorageLive(_8); - StorageLive(_7); - _7 = copy _4 as *mut T (PtrToPtr); - _8 = Offset(copy _7, copy _3); - StorageDead(_7); - _9 = move _8 as *const T (PtrToPtr); - StorageDead(_8); + _7 = Offset(copy _5, copy _3); + _8 = copy _7 as usize (Transmute); goto -> bb3; } bb2: { - _9 = copy _3 as *const T (Transmute); + _8 = copy _3; goto -> bb3; } bb3: { - StorageLive(_10); - _10 = copy _9; - _11 = std::slice::Iter::<'_, T> { ptr: copy _6, end_or_len: move _10, _marker: const ZeroSized: PhantomData<&T> }; - StorageDead(_10); + StorageLive(_9); + _9 = copy _8; + _10 = std::slice::Iter::<'_, T> { ptr: copy _6, end_addr_or_len: move _9, _marker: const ZeroSized: PhantomData<&T> }; StorageDead(_9); + StorageDead(_8); + StorageDead(_7); + StorageDead(_5); StorageDead(_4); StorageDead(_6); StorageDead(_3); - _12 = Rev::> { iter: copy _11 }; - StorageDead(_11); - StorageLive(_13); - _13 = copy _12; + _11 = Rev::> { iter: copy _10 }; + StorageDead(_10); + StorageLive(_12); + _12 = copy _11; goto -> bb4; } bb4: { - StorageLive(_15); StorageLive(_14); - _14 = &mut (_13.0: std::slice::Iter<'_, T>); - _15 = as DoubleEndedIterator>::next_back(move _14) -> [return: bb5, unwind: bb11]; + StorageLive(_13); + _13 = &mut (_12.0: std::slice::Iter<'_, T>); + _14 = as DoubleEndedIterator>::next_back(move _13) -> [return: bb5, unwind: bb11]; } bb5: { - StorageDead(_14); - _16 = discriminant(_15); - switchInt(move _16) -> [0: bb6, 1: bb8, otherwise: bb10]; + StorageDead(_13); + _15 = discriminant(_14); + switchInt(move _15) -> [0: bb6, 1: bb8, otherwise: bb10]; } bb6: { - StorageDead(_15); - StorageDead(_13); + StorageDead(_14); + StorageDead(_12); drop(_2) -> [return: bb7, unwind continue]; } @@ -132,18 +126,18 @@ fn reverse_loop(_1: &[T], _2: impl Fn(&T)) -> () { } bb8: { - _17 = copy ((_15 as Some).0: &T); + _16 = copy ((_14 as Some).0: &T); + StorageLive(_17); + _17 = &_2; StorageLive(_18); - _18 = &_2; - StorageLive(_19); - _19 = (copy _17,); - _20 = >::call(move _18, move _19) -> [return: bb9, unwind: bb11]; + _18 = (copy _16,); + _19 = >::call(move _17, move _18) -> [return: bb9, unwind: bb11]; } bb9: { - StorageDead(_19); StorageDead(_18); - StorageDead(_15); + StorageDead(_17); + StorageDead(_14); goto -> bb4; } diff --git a/tests/mir-opt/pre-codegen/slice_iter.slice_iter_generic_is_empty.PreCodegen.after.panic-abort.mir b/tests/mir-opt/pre-codegen/slice_iter.slice_iter_generic_is_empty.PreCodegen.after.panic-abort.mir index 38d00cfbabdda..c2a0a4edaf03d 100644 --- a/tests/mir-opt/pre-codegen/slice_iter.slice_iter_generic_is_empty.PreCodegen.after.panic-abort.mir +++ b/tests/mir-opt/pre-codegen/slice_iter.slice_iter_generic_is_empty.PreCodegen.after.panic-abort.mir @@ -4,67 +4,102 @@ fn slice_iter_generic_is_empty(_1: &std::slice::Iter<'_, T>) -> bool { debug it => _1; let mut _0: bool; scope 1 (inlined as ExactSizeIterator>::is_empty) { - let mut _2: *const T; + let mut _3: *const usize; + let mut _4: *const std::ptr::NonNull; + let mut _6: *const T; let mut _7: *const T; + let mut _8: usize; + let _13: usize; scope 2 { - let _3: std::ptr::NonNull; - let _8: usize; - scope 3 { - } + } + scope 3 { scope 4 { - scope 7 (inlined as PartialEq>::eq) { - let mut _4: std::ptr::NonNull; - let mut _5: *mut T; - let mut _6: *mut T; - scope 8 (inlined NonNull::::as_ptr) { + scope 13 (inlined as PartialEq>::eq) { + let mut _10: std::ptr::NonNull; + let mut _11: *mut T; + let mut _12: *mut T; + scope 14 (inlined NonNull::::as_ptr) { } - scope 9 (inlined NonNull::::as_ptr) { + scope 15 (inlined NonNull::::as_ptr) { } } } - scope 5 (inlined std::ptr::const_ptr::::addr) { - scope 6 (inlined std::ptr::const_ptr::::cast::<()>) { + scope 5 { + let _2: std::ptr::NonNull; + scope 6 { + let _5: std::ptr::NonNull; + scope 7 { + scope 9 (inlined NonNull::::as_ptr) { + } + scope 10 (inlined NonNull::::as_ptr) { + } + scope 11 (inlined NonNull::::add) { + let mut _9: *const T; + scope 12 (inlined NonNull::::as_ptr) { + } + } + } + scope 8 (inlined std::ptr::const_ptr::::cast::>) { + } } } } } bb0: { + StorageLive(_13); + StorageLive(_2); + StorageLive(_5); StorageLive(_8); StorageLive(_7); - StorageLive(_3); - switchInt(const ::IS_ZST) -> [0: bb1, otherwise: bb2]; + StorageLive(_9); + switchInt(const ::IS_ZST) -> [0: bb1, otherwise: bb3]; } bb1: { - StorageLive(_2); - _2 = copy ((*_1).1: *const T); - _3 = move _2 as std::ptr::NonNull (Transmute); - StorageDead(_2); - StorageLive(_5); + _2 = copy ((*_1).0: std::ptr::NonNull); StorageLive(_4); - _4 = copy ((*_1).0: std::ptr::NonNull); - _5 = copy _4 as *mut T (Transmute); + StorageLive(_3); + _3 = &raw const ((*_1).1: usize); + _4 = copy _3 as *const std::ptr::NonNull (PtrToPtr); + StorageDead(_3); + _5 = copy (*_4); StorageDead(_4); StorageLive(_6); - _6 = copy _3 as *mut T (Transmute); - _0 = Eq(move _5, move _6); - StorageDead(_6); - StorageDead(_5); - goto -> bb3; + _6 = copy _5 as *const T (Transmute); + _7 = copy _2 as *const T (Transmute); + _8 = ptr_offset_from_unsigned::(move _6, copy _7) -> [return: bb2, unwind unreachable]; } bb2: { - _7 = copy ((*_1).1: *const T); - _8 = copy _7 as usize (Transmute); - _0 = Eq(copy _8, const 0_usize); - goto -> bb3; + StorageDead(_6); + _9 = Offset(copy _7, copy _8); + StorageLive(_11); + StorageLive(_10); + _10 = copy ((*_1).0: std::ptr::NonNull); + _11 = copy _10 as *mut T (Transmute); + StorageDead(_10); + StorageLive(_12); + _12 = copy _9 as *mut T (PtrToPtr); + _0 = Eq(move _11, move _12); + StorageDead(_12); + StorageDead(_11); + goto -> bb4; } bb3: { - StorageDead(_3); + _13 = copy ((*_1).1: usize); + _0 = Eq(copy _13, const 0_usize); + goto -> bb4; + } + + bb4: { + StorageDead(_9); StorageDead(_7); StorageDead(_8); + StorageDead(_5); + StorageDead(_2); + StorageDead(_13); return; } } diff --git a/tests/mir-opt/pre-codegen/slice_iter.slice_iter_generic_is_empty.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/pre-codegen/slice_iter.slice_iter_generic_is_empty.PreCodegen.after.panic-unwind.mir index 38d00cfbabdda..c2a0a4edaf03d 100644 --- a/tests/mir-opt/pre-codegen/slice_iter.slice_iter_generic_is_empty.PreCodegen.after.panic-unwind.mir +++ b/tests/mir-opt/pre-codegen/slice_iter.slice_iter_generic_is_empty.PreCodegen.after.panic-unwind.mir @@ -4,67 +4,102 @@ fn slice_iter_generic_is_empty(_1: &std::slice::Iter<'_, T>) -> bool { debug it => _1; let mut _0: bool; scope 1 (inlined as ExactSizeIterator>::is_empty) { - let mut _2: *const T; + let mut _3: *const usize; + let mut _4: *const std::ptr::NonNull; + let mut _6: *const T; let mut _7: *const T; + let mut _8: usize; + let _13: usize; scope 2 { - let _3: std::ptr::NonNull; - let _8: usize; - scope 3 { - } + } + scope 3 { scope 4 { - scope 7 (inlined as PartialEq>::eq) { - let mut _4: std::ptr::NonNull; - let mut _5: *mut T; - let mut _6: *mut T; - scope 8 (inlined NonNull::::as_ptr) { + scope 13 (inlined as PartialEq>::eq) { + let mut _10: std::ptr::NonNull; + let mut _11: *mut T; + let mut _12: *mut T; + scope 14 (inlined NonNull::::as_ptr) { } - scope 9 (inlined NonNull::::as_ptr) { + scope 15 (inlined NonNull::::as_ptr) { } } } - scope 5 (inlined std::ptr::const_ptr::::addr) { - scope 6 (inlined std::ptr::const_ptr::::cast::<()>) { + scope 5 { + let _2: std::ptr::NonNull; + scope 6 { + let _5: std::ptr::NonNull; + scope 7 { + scope 9 (inlined NonNull::::as_ptr) { + } + scope 10 (inlined NonNull::::as_ptr) { + } + scope 11 (inlined NonNull::::add) { + let mut _9: *const T; + scope 12 (inlined NonNull::::as_ptr) { + } + } + } + scope 8 (inlined std::ptr::const_ptr::::cast::>) { + } } } } } bb0: { + StorageLive(_13); + StorageLive(_2); + StorageLive(_5); StorageLive(_8); StorageLive(_7); - StorageLive(_3); - switchInt(const ::IS_ZST) -> [0: bb1, otherwise: bb2]; + StorageLive(_9); + switchInt(const ::IS_ZST) -> [0: bb1, otherwise: bb3]; } bb1: { - StorageLive(_2); - _2 = copy ((*_1).1: *const T); - _3 = move _2 as std::ptr::NonNull (Transmute); - StorageDead(_2); - StorageLive(_5); + _2 = copy ((*_1).0: std::ptr::NonNull); StorageLive(_4); - _4 = copy ((*_1).0: std::ptr::NonNull); - _5 = copy _4 as *mut T (Transmute); + StorageLive(_3); + _3 = &raw const ((*_1).1: usize); + _4 = copy _3 as *const std::ptr::NonNull (PtrToPtr); + StorageDead(_3); + _5 = copy (*_4); StorageDead(_4); StorageLive(_6); - _6 = copy _3 as *mut T (Transmute); - _0 = Eq(move _5, move _6); - StorageDead(_6); - StorageDead(_5); - goto -> bb3; + _6 = copy _5 as *const T (Transmute); + _7 = copy _2 as *const T (Transmute); + _8 = ptr_offset_from_unsigned::(move _6, copy _7) -> [return: bb2, unwind unreachable]; } bb2: { - _7 = copy ((*_1).1: *const T); - _8 = copy _7 as usize (Transmute); - _0 = Eq(copy _8, const 0_usize); - goto -> bb3; + StorageDead(_6); + _9 = Offset(copy _7, copy _8); + StorageLive(_11); + StorageLive(_10); + _10 = copy ((*_1).0: std::ptr::NonNull); + _11 = copy _10 as *mut T (Transmute); + StorageDead(_10); + StorageLive(_12); + _12 = copy _9 as *mut T (PtrToPtr); + _0 = Eq(move _11, move _12); + StorageDead(_12); + StorageDead(_11); + goto -> bb4; } bb3: { - StorageDead(_3); + _13 = copy ((*_1).1: usize); + _0 = Eq(copy _13, const 0_usize); + goto -> bb4; + } + + bb4: { + StorageDead(_9); StorageDead(_7); StorageDead(_8); + StorageDead(_5); + StorageDead(_2); + StorageDead(_13); return; } } diff --git a/tests/mir-opt/pre-codegen/slice_iter.slice_iter_next.PreCodegen.after.panic-abort.mir b/tests/mir-opt/pre-codegen/slice_iter.slice_iter_next.PreCodegen.after.panic-abort.mir index c0ed0aea1e260..8edac638ccdd6 100644 --- a/tests/mir-opt/pre-codegen/slice_iter.slice_iter_next.PreCodegen.after.panic-abort.mir +++ b/tests/mir-opt/pre-codegen/slice_iter.slice_iter_next.PreCodegen.after.panic-abort.mir @@ -3,134 +3,12 @@ fn slice_iter_next(_1: &mut std::slice::Iter<'_, T>) -> Option<&T> { debug it => _1; let mut _0: std::option::Option<&T>; - scope 1 (inlined as Iterator>::next) { - let _2: std::ptr::NonNull; - let _4: std::ptr::NonNull; - let mut _7: bool; - let mut _10: std::ptr::NonNull; - let mut _12: usize; - let _14: &T; - scope 2 { - let _3: *const T; - scope 3 { - let _11: usize; - scope 4 { - scope 7 (inlined #[track_caller] core::num::::unchecked_sub) { - scope 8 (inlined core::ub_checks::check_language_ub) { - scope 9 (inlined core::ub_checks::check_language_ub::runtime) { - } - } - } - scope 10 (inlined without_provenance_mut::) { - } - } - scope 5 (inlined std::ptr::const_ptr::::addr) { - scope 6 (inlined std::ptr::const_ptr::::cast::<()>) { - } - } - scope 11 (inlined as PartialEq>::eq) { - let mut _5: *mut T; - let mut _6: *mut T; - scope 12 (inlined NonNull::::as_ptr) { - } - scope 13 (inlined NonNull::::as_ptr) { - } - } - scope 14 (inlined NonNull::::add) { - let mut _8: *const T; - let mut _9: *const T; - scope 15 (inlined NonNull::::as_ptr) { - } - } - scope 16 (inlined NonNull::::as_ref::<'_>) { - let _13: *const T; - scope 17 (inlined NonNull::::as_ptr) { - } - scope 18 (inlined std::ptr::mut_ptr::::cast_const) { - } - } - } - } - } bb0: { - StorageLive(_2); - StorageLive(_3); - StorageLive(_11); - StorageLive(_12); - StorageLive(_4); - StorageLive(_14); - _2 = copy ((*_1).0: std::ptr::NonNull); - _3 = copy ((*_1).1: *const T); - switchInt(const ::IS_ZST) -> [0: bb1, otherwise: bb4]; + _0 = as Iterator>::next(move _1) -> [return: bb1, unwind unreachable]; } bb1: { - StorageLive(_7); - _4 = copy _3 as std::ptr::NonNull (Transmute); - StorageLive(_5); - _5 = copy _2 as *mut T (Transmute); - StorageLive(_6); - _6 = copy _4 as *mut T (Transmute); - _7 = Eq(move _5, move _6); - StorageDead(_6); - StorageDead(_5); - switchInt(move _7) -> [0: bb2, otherwise: bb3]; - } - - bb2: { - StorageDead(_7); - StorageLive(_10); - StorageLive(_9); - StorageLive(_8); - _8 = copy _2 as *const T (Transmute); - _9 = Offset(move _8, const 1_usize); - StorageDead(_8); - _10 = NonNull:: { pointer: move _9 }; - StorageDead(_9); - ((*_1).0: std::ptr::NonNull) = move _10; - StorageDead(_10); - goto -> bb7; - } - - bb3: { - _0 = const {transmute(0x0000000000000000): Option<&T>}; - StorageDead(_7); - goto -> bb8; - } - - bb4: { - _11 = copy _3 as usize (Transmute); - switchInt(copy _11) -> [0: bb5, otherwise: bb6]; - } - - bb5: { - _0 = const {transmute(0x0000000000000000): Option<&T>}; - goto -> bb8; - } - - bb6: { - _12 = SubUnchecked(copy _11, const 1_usize); - ((*_1).1: *const T) = copy _12 as *const T (Transmute); - goto -> bb7; - } - - bb7: { - StorageLive(_13); - _13 = copy _2 as *const T (Transmute); - _14 = &(*_13); - StorageDead(_13); - _0 = Option::<&T>::Some(copy _14); - goto -> bb8; - } - - bb8: { - StorageDead(_14); - StorageDead(_4); - StorageDead(_12); - StorageDead(_11); - StorageDead(_3); - StorageDead(_2); return; } } diff --git a/tests/mir-opt/pre-codegen/slice_iter.slice_iter_next.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/pre-codegen/slice_iter.slice_iter_next.PreCodegen.after.panic-unwind.mir index c0ed0aea1e260..fdde07173437b 100644 --- a/tests/mir-opt/pre-codegen/slice_iter.slice_iter_next.PreCodegen.after.panic-unwind.mir +++ b/tests/mir-opt/pre-codegen/slice_iter.slice_iter_next.PreCodegen.after.panic-unwind.mir @@ -3,134 +3,12 @@ fn slice_iter_next(_1: &mut std::slice::Iter<'_, T>) -> Option<&T> { debug it => _1; let mut _0: std::option::Option<&T>; - scope 1 (inlined as Iterator>::next) { - let _2: std::ptr::NonNull; - let _4: std::ptr::NonNull; - let mut _7: bool; - let mut _10: std::ptr::NonNull; - let mut _12: usize; - let _14: &T; - scope 2 { - let _3: *const T; - scope 3 { - let _11: usize; - scope 4 { - scope 7 (inlined #[track_caller] core::num::::unchecked_sub) { - scope 8 (inlined core::ub_checks::check_language_ub) { - scope 9 (inlined core::ub_checks::check_language_ub::runtime) { - } - } - } - scope 10 (inlined without_provenance_mut::) { - } - } - scope 5 (inlined std::ptr::const_ptr::::addr) { - scope 6 (inlined std::ptr::const_ptr::::cast::<()>) { - } - } - scope 11 (inlined as PartialEq>::eq) { - let mut _5: *mut T; - let mut _6: *mut T; - scope 12 (inlined NonNull::::as_ptr) { - } - scope 13 (inlined NonNull::::as_ptr) { - } - } - scope 14 (inlined NonNull::::add) { - let mut _8: *const T; - let mut _9: *const T; - scope 15 (inlined NonNull::::as_ptr) { - } - } - scope 16 (inlined NonNull::::as_ref::<'_>) { - let _13: *const T; - scope 17 (inlined NonNull::::as_ptr) { - } - scope 18 (inlined std::ptr::mut_ptr::::cast_const) { - } - } - } - } - } bb0: { - StorageLive(_2); - StorageLive(_3); - StorageLive(_11); - StorageLive(_12); - StorageLive(_4); - StorageLive(_14); - _2 = copy ((*_1).0: std::ptr::NonNull); - _3 = copy ((*_1).1: *const T); - switchInt(const ::IS_ZST) -> [0: bb1, otherwise: bb4]; + _0 = as Iterator>::next(move _1) -> [return: bb1, unwind continue]; } bb1: { - StorageLive(_7); - _4 = copy _3 as std::ptr::NonNull (Transmute); - StorageLive(_5); - _5 = copy _2 as *mut T (Transmute); - StorageLive(_6); - _6 = copy _4 as *mut T (Transmute); - _7 = Eq(move _5, move _6); - StorageDead(_6); - StorageDead(_5); - switchInt(move _7) -> [0: bb2, otherwise: bb3]; - } - - bb2: { - StorageDead(_7); - StorageLive(_10); - StorageLive(_9); - StorageLive(_8); - _8 = copy _2 as *const T (Transmute); - _9 = Offset(move _8, const 1_usize); - StorageDead(_8); - _10 = NonNull:: { pointer: move _9 }; - StorageDead(_9); - ((*_1).0: std::ptr::NonNull) = move _10; - StorageDead(_10); - goto -> bb7; - } - - bb3: { - _0 = const {transmute(0x0000000000000000): Option<&T>}; - StorageDead(_7); - goto -> bb8; - } - - bb4: { - _11 = copy _3 as usize (Transmute); - switchInt(copy _11) -> [0: bb5, otherwise: bb6]; - } - - bb5: { - _0 = const {transmute(0x0000000000000000): Option<&T>}; - goto -> bb8; - } - - bb6: { - _12 = SubUnchecked(copy _11, const 1_usize); - ((*_1).1: *const T) = copy _12 as *const T (Transmute); - goto -> bb7; - } - - bb7: { - StorageLive(_13); - _13 = copy _2 as *const T (Transmute); - _14 = &(*_13); - StorageDead(_13); - _0 = Option::<&T>::Some(copy _14); - goto -> bb8; - } - - bb8: { - StorageDead(_14); - StorageDead(_4); - StorageDead(_12); - StorageDead(_11); - StorageDead(_3); - StorageDead(_2); return; } }