diff --git a/compiler/rustc_hir_analysis/src/check/intrinsic.rs b/compiler/rustc_hir_analysis/src/check/intrinsic.rs index 54bb3ac411304..09610a2f3ec6d 100644 --- a/compiler/rustc_hir_analysis/src/check/intrinsic.rs +++ b/compiler/rustc_hir_analysis/src/check/intrinsic.rs @@ -265,6 +265,7 @@ pub(crate) fn check_intrinsic_type( vec![Ty::new_imm_ptr(tcx, param(0)), tcx.types.isize], Ty::new_imm_ptr(tcx, param(0)), ), + sym::slice_get_unchecked => (3, 0, vec![param(1), tcx.types.usize], param(0)), sym::ptr_mask => ( 1, 0, diff --git a/compiler/rustc_mir_transform/src/lower_intrinsics.rs b/compiler/rustc_mir_transform/src/lower_intrinsics.rs index 9c21bcfc0d26a..52f4c39c09bb1 100644 --- a/compiler/rustc_mir_transform/src/lower_intrinsics.rs +++ b/compiler/rustc_mir_transform/src/lower_intrinsics.rs @@ -262,6 +262,52 @@ impl<'tcx> crate::MirPass<'tcx> for LowerIntrinsics { }); terminator.kind = TerminatorKind::Goto { target }; } + sym::slice_get_unchecked => { + let target = target.unwrap(); + let Ok([ptrish, index]) = take_array(args) else { + span_bug!( + terminator.source_info.span, + "Wrong number of arguments for {intrinsic:?}", + ); + }; + + let place = ptrish.node.place().unwrap(); + assert!(!place.is_indirect()); + let updated_place = place.project_deeper( + &[ + ProjectionElem::Deref, + ProjectionElem::Index( + index.node.place().unwrap().as_local().unwrap(), + ), + ], + tcx, + ); + + let ret_ty = generic_args.type_at(0); + let rvalue = match *ret_ty.kind() { + ty::RawPtr(_, Mutability::Not) => { + Rvalue::RawPtr(RawPtrKind::Const, updated_place) + } + ty::RawPtr(_, Mutability::Mut) => { + Rvalue::RawPtr(RawPtrKind::Mut, updated_place) + } + ty::Ref(region, _, Mutability::Not) => { + Rvalue::Ref(region, BorrowKind::Shared, updated_place) + } + ty::Ref(region, _, Mutability::Mut) => Rvalue::Ref( + region, + BorrowKind::Mut { kind: MutBorrowKind::Default }, + updated_place, + ), + _ => bug!("Unknown return type {ret_ty:?}"), + }; + + block.statements.push(Statement { + source_info: terminator.source_info, + kind: StatementKind::Assign(Box::new((*destination, rvalue))), + }); + terminator.kind = TerminatorKind::Goto { target }; + } sym::transmute | sym::transmute_unchecked => { let dst_ty = destination.ty(local_decls, tcx).ty; let Ok([arg]) = take_array(args) else { diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index ae94169b01dc2..970faf2997c5b 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -2000,6 +2000,7 @@ symbols! { slice, slice_from_raw_parts, slice_from_raw_parts_mut, + slice_get_unchecked, slice_into_vec, slice_iter, slice_len_fn, diff --git a/library/core/src/intrinsics/bounds.rs b/library/core/src/intrinsics/bounds.rs new file mode 100644 index 0000000000000..046e191212cc0 --- /dev/null +++ b/library/core/src/intrinsics/bounds.rs @@ -0,0 +1,39 @@ +//! Various traits used to restrict intrinsics to not-completely-wrong types. + +/// Types with a built-in dereference operator in runtime MIR, +/// aka references and raw pointers. +/// +/// # Safety +/// Must actually *be* such a type. +pub unsafe trait BuiltinDeref: Sized { + type Pointee: ?Sized; +} + +unsafe impl BuiltinDeref for &mut T { + type Pointee = T; +} +unsafe impl BuiltinDeref for &T { + type Pointee = T; +} +unsafe impl BuiltinDeref for *mut T { + type Pointee = T; +} +unsafe impl BuiltinDeref for *const T { + type Pointee = T; +} + +pub trait ChangePointee: BuiltinDeref { + type Output; +} +impl<'a, T: ?Sized + 'a, U: ?Sized + 'a> ChangePointee for &'a mut T { + type Output = &'a mut U; +} +impl<'a, T: ?Sized + 'a, U: ?Sized + 'a> ChangePointee for &'a T { + type Output = &'a U; +} +impl ChangePointee for *mut T { + type Output = *mut U; +} +impl ChangePointee for *const T { + type Output = *const U; +} diff --git a/library/core/src/intrinsics/mod.rs b/library/core/src/intrinsics/mod.rs index f89baef76f093..10c5ab10390a4 100644 --- a/library/core/src/intrinsics/mod.rs +++ b/library/core/src/intrinsics/mod.rs @@ -53,6 +53,7 @@ use crate::marker::{ConstParamTy, DiscriminantKind, Tuple}; use crate::ptr; +mod bounds; pub mod fallback; pub mod mir; pub mod simd; @@ -1730,7 +1731,7 @@ pub const fn needs_drop() -> bool; #[rustc_intrinsic_const_stable_indirect] #[rustc_nounwind] #[rustc_intrinsic] -pub const unsafe fn offset(dst: Ptr, offset: Delta) -> Ptr; +pub const unsafe fn offset(dst: Ptr, offset: Delta) -> Ptr; /// Calculates the offset from a pointer, potentially wrapping. /// @@ -1751,6 +1752,33 @@ pub const unsafe fn offset(dst: Ptr, offset: Delta) -> Ptr; #[rustc_intrinsic] pub const unsafe fn arith_offset(dst: *const T, offset: isize) -> *const T; +/// Projects to the `index`-th element of `slice_ptr`, as the same kind of pointer +/// as the slice was provided -- so `&mut [T] → &mut T`, `&[T] → &T`, +/// `*mut [T] → *mut T`, or `*const [T] → *const T` -- without a bounds check. +/// +/// This is exposed via `::get(_unchecked)(_mut)`, +/// and isn't intended to be used elsewhere. +/// +/// Expands in MIR to `{&, &mut, &raw const, &raw mut} (*slice_ptr)[index]`, +/// depending on the types involved, so no backend support is needed. +/// +/// # Safety +/// +/// - `index < PtrMetadata(slice_ptr)`, so the indexing is in-bounds for the slice +/// - the resulting offsetting is in-bounds of the allocated object, which is +/// always the case for references, but needs to be upheld manually for pointers +#[cfg(not(bootstrap))] +#[rustc_nounwind] +#[rustc_intrinsic] +pub const unsafe fn slice_get_unchecked< + ItemPtr: bounds::ChangePointee<[T], Pointee = T, Output = SlicePtr>, + SlicePtr, + T, +>( + slice_ptr: SlicePtr, + index: usize, +) -> ItemPtr; + /// Masks out bits of the pointer according to a mask. /// /// Note that, unlike most intrinsics, this is safe to call; @@ -3575,18 +3603,9 @@ pub const fn type_id() -> u128; #[unstable(feature = "core_intrinsics", issue = "none")] #[rustc_intrinsic_const_stable_indirect] #[rustc_intrinsic] -pub const fn aggregate_raw_ptr, D, M>(data: D, meta: M) -> P; - -#[unstable(feature = "core_intrinsics", issue = "none")] -pub trait AggregateRawPtr { - type Metadata: Copy; -} -impl AggregateRawPtr<*const T> for *const P { - type Metadata =

::Metadata; -} -impl AggregateRawPtr<*mut T> for *mut P { - type Metadata =

::Metadata; -} +pub const fn aggregate_raw_ptr(data: D, meta: M) -> P +where +

::Pointee: ptr::Pointee; /// Lowers in MIR to `Rvalue::UnaryOp` with `UnOp::PtrMetadata`. /// diff --git a/library/core/src/slice/index.rs b/library/core/src/slice/index.rs index b18d316c73a6f..69160a911b212 100644 --- a/library/core/src/slice/index.rs +++ b/library/core/src/slice/index.rs @@ -1,5 +1,7 @@ //! Indexing implementations for `[T]`. +#[cfg(not(bootstrap))] +use crate::intrinsics::slice_get_unchecked; use crate::panic::const_panic; use crate::ub_checks::assert_unsafe_precondition; use crate::{ops, range}; @@ -83,6 +85,7 @@ const fn slice_end_index_overflow_fail() -> ! { // Both the safe and unsafe public methods share these helpers, // which use intrinsics directly to get *no* extra checks. +#[cfg(bootstrap)] #[inline(always)] const unsafe fn get_noubcheck(ptr: *const [T], index: usize) -> *const T { let ptr = ptr as *const T; @@ -90,6 +93,7 @@ const unsafe fn get_noubcheck(ptr: *const [T], index: usize) -> *const T { unsafe { crate::intrinsics::offset(ptr, index) } } +#[cfg(bootstrap)] #[inline(always)] const unsafe fn get_mut_noubcheck(ptr: *mut [T], index: usize) -> *mut T { let ptr = ptr as *mut T; @@ -103,8 +107,9 @@ const unsafe fn get_offset_len_noubcheck( offset: usize, len: usize, ) -> *const [T] { + let ptr = ptr as *const T; // SAFETY: The caller already checked these preconditions - let ptr = unsafe { get_noubcheck(ptr, offset) }; + let ptr = unsafe { crate::intrinsics::offset(ptr, offset) }; crate::intrinsics::aggregate_raw_ptr(ptr, len) } @@ -114,8 +119,9 @@ const unsafe fn get_offset_len_mut_noubcheck( offset: usize, len: usize, ) -> *mut [T] { + let ptr = ptr as *mut T; // SAFETY: The caller already checked these preconditions - let ptr = unsafe { get_mut_noubcheck(ptr, offset) }; + let ptr = unsafe { crate::intrinsics::offset(ptr, offset) }; crate::intrinsics::aggregate_raw_ptr(ptr, len) } @@ -224,15 +230,35 @@ unsafe impl SliceIndex<[T]> for usize { #[inline] fn get(self, slice: &[T]) -> Option<&T> { - // SAFETY: `self` is checked to be in bounds. - if self < slice.len() { unsafe { Some(&*get_noubcheck(slice, self)) } } else { None } + if self < slice.len() { + #[cfg(bootstrap)] + // SAFETY: `self` is checked to be in bounds. + unsafe { + Some(&*get_noubcheck(slice, self)) + } + #[cfg(not(bootstrap))] + // SAFETY: `self` is checked to be in bounds. + unsafe { + Some(slice_get_unchecked(slice, self)) + } + } else { + None + } } #[inline] fn get_mut(self, slice: &mut [T]) -> Option<&mut T> { if self < slice.len() { + #[cfg(bootstrap)] + // SAFETY: `self` is checked to be in bounds. + unsafe { + Some(&mut *get_mut_noubcheck(slice, self)) + } + #[cfg(not(bootstrap))] // SAFETY: `self` is checked to be in bounds. - unsafe { Some(&mut *get_mut_noubcheck(slice, self)) } + unsafe { + Some(slice_get_unchecked(slice, self)) + } } else { None } @@ -254,7 +280,14 @@ unsafe impl SliceIndex<[T]> for usize { // Use intrinsics::assume instead of hint::assert_unchecked so that we don't check the // precondition of this function twice. crate::intrinsics::assume(self < slice.len()); - get_noubcheck(slice, self) + #[cfg(bootstrap)] + { + get_noubcheck(slice, self) + } + #[cfg(not(bootstrap))] + { + slice_get_unchecked(slice, self) + } } } @@ -267,7 +300,16 @@ unsafe impl SliceIndex<[T]> for usize { (this: usize = self, len: usize = slice.len()) => this < len ); // SAFETY: see comments for `get_unchecked` above. - unsafe { get_mut_noubcheck(slice, self) } + unsafe { + #[cfg(bootstrap)] + { + get_mut_noubcheck(slice, self) + } + #[cfg(not(bootstrap))] + { + slice_get_unchecked(slice, self) + } + } } #[inline] diff --git a/tests/mir-opt/lower_intrinsics.rs b/tests/mir-opt/lower_intrinsics.rs index 4e000b05a4b47..1e4f20241947e 100644 --- a/tests/mir-opt/lower_intrinsics.rs +++ b/tests/mir-opt/lower_intrinsics.rs @@ -263,3 +263,24 @@ pub fn get_metadata(a: *const i32, b: *const [u8], c: *const dyn std::fmt::Debug let _usize = ptr_metadata(b); let _vtable = ptr_metadata(c); } + +// EMIT_MIR lower_intrinsics.slice_get.LowerIntrinsics.diff +pub unsafe fn slice_get<'a, 'b>( + r: &'a [i8], + rm: &'b mut [i16], + p: *const [i32], + pm: *mut [i64], + i: usize, +) -> (&'a i8, &'b mut i16, *const i32, *mut i64) { + use std::intrinsics::slice_get_unchecked; + // CHECK: = &(*_{{[0-9]+}})[_{{[0-9]+}}] + // CHECK: = &mut (*_{{[0-9]+}})[_{{[0-9]+}}] + // CHECK: = &raw const (*_{{[0-9]+}})[_{{[0-9]+}}] + // CHECK: = &raw mut (*_{{[0-9]+}})[_{{[0-9]+}}] + ( + slice_get_unchecked(r, i), + slice_get_unchecked(rm, i), + slice_get_unchecked(p, i), + slice_get_unchecked(pm, i), + ) +} diff --git a/tests/mir-opt/lower_intrinsics.slice_get.LowerIntrinsics.panic-abort.diff b/tests/mir-opt/lower_intrinsics.slice_get.LowerIntrinsics.panic-abort.diff new file mode 100644 index 0000000000000..d18bdc431683f --- /dev/null +++ b/tests/mir-opt/lower_intrinsics.slice_get.LowerIntrinsics.panic-abort.diff @@ -0,0 +1,85 @@ +- // MIR for `slice_get` before LowerIntrinsics ++ // MIR for `slice_get` after LowerIntrinsics + + fn slice_get(_1: &[i8], _2: &mut [i16], _3: *const [i32], _4: *mut [i64], _5: usize) -> (&i8, &mut i16, *const i32, *mut i64) { + debug r => _1; + debug rm => _2; + debug p => _3; + debug pm => _4; + debug i => _5; + let mut _0: (&i8, &mut i16, *const i32, *mut i64); + let mut _6: &i8; + let mut _7: &[i8]; + let mut _8: usize; + let mut _9: &mut i16; + let mut _10: &mut [i16]; + let mut _11: usize; + let mut _12: *const i32; + let mut _13: *const [i32]; + let mut _14: usize; + let mut _15: *mut i64; + let mut _16: *mut [i64]; + let mut _17: usize; + + bb0: { + StorageLive(_6); + StorageLive(_7); + _7 = copy _1; + StorageLive(_8); + _8 = copy _5; +- _6 = slice_get_unchecked::<&i8, &[i8], i8>(move _7, move _8) -> [return: bb1, unwind unreachable]; ++ _6 = &(*_7)[_8]; ++ goto -> bb1; + } + + bb1: { + StorageDead(_8); + StorageDead(_7); + StorageLive(_9); + StorageLive(_10); + _10 = move _2; + StorageLive(_11); + _11 = copy _5; +- _9 = slice_get_unchecked::<&mut i16, &mut [i16], i16>(move _10, move _11) -> [return: bb2, unwind unreachable]; ++ _9 = &mut (*_10)[_11]; ++ goto -> bb2; + } + + bb2: { + StorageDead(_11); + StorageDead(_10); + StorageLive(_12); + StorageLive(_13); + _13 = copy _3; + StorageLive(_14); + _14 = copy _5; +- _12 = slice_get_unchecked::<*const i32, *const [i32], i32>(move _13, move _14) -> [return: bb3, unwind unreachable]; ++ _12 = &raw const (*_13)[_14]; ++ goto -> bb3; + } + + bb3: { + StorageDead(_14); + StorageDead(_13); + StorageLive(_15); + StorageLive(_16); + _16 = copy _4; + StorageLive(_17); + _17 = copy _5; +- _15 = slice_get_unchecked::<*mut i64, *mut [i64], i64>(move _16, move _17) -> [return: bb4, unwind unreachable]; ++ _15 = &raw mut (*_16)[_17]; ++ goto -> bb4; + } + + bb4: { + StorageDead(_17); + StorageDead(_16); + _0 = (move _6, move _9, move _12, move _15); + StorageDead(_15); + StorageDead(_12); + StorageDead(_9); + StorageDead(_6); + return; + } + } + diff --git a/tests/mir-opt/lower_intrinsics.slice_get.LowerIntrinsics.panic-unwind.diff b/tests/mir-opt/lower_intrinsics.slice_get.LowerIntrinsics.panic-unwind.diff new file mode 100644 index 0000000000000..d18bdc431683f --- /dev/null +++ b/tests/mir-opt/lower_intrinsics.slice_get.LowerIntrinsics.panic-unwind.diff @@ -0,0 +1,85 @@ +- // MIR for `slice_get` before LowerIntrinsics ++ // MIR for `slice_get` after LowerIntrinsics + + fn slice_get(_1: &[i8], _2: &mut [i16], _3: *const [i32], _4: *mut [i64], _5: usize) -> (&i8, &mut i16, *const i32, *mut i64) { + debug r => _1; + debug rm => _2; + debug p => _3; + debug pm => _4; + debug i => _5; + let mut _0: (&i8, &mut i16, *const i32, *mut i64); + let mut _6: &i8; + let mut _7: &[i8]; + let mut _8: usize; + let mut _9: &mut i16; + let mut _10: &mut [i16]; + let mut _11: usize; + let mut _12: *const i32; + let mut _13: *const [i32]; + let mut _14: usize; + let mut _15: *mut i64; + let mut _16: *mut [i64]; + let mut _17: usize; + + bb0: { + StorageLive(_6); + StorageLive(_7); + _7 = copy _1; + StorageLive(_8); + _8 = copy _5; +- _6 = slice_get_unchecked::<&i8, &[i8], i8>(move _7, move _8) -> [return: bb1, unwind unreachable]; ++ _6 = &(*_7)[_8]; ++ goto -> bb1; + } + + bb1: { + StorageDead(_8); + StorageDead(_7); + StorageLive(_9); + StorageLive(_10); + _10 = move _2; + StorageLive(_11); + _11 = copy _5; +- _9 = slice_get_unchecked::<&mut i16, &mut [i16], i16>(move _10, move _11) -> [return: bb2, unwind unreachable]; ++ _9 = &mut (*_10)[_11]; ++ goto -> bb2; + } + + bb2: { + StorageDead(_11); + StorageDead(_10); + StorageLive(_12); + StorageLive(_13); + _13 = copy _3; + StorageLive(_14); + _14 = copy _5; +- _12 = slice_get_unchecked::<*const i32, *const [i32], i32>(move _13, move _14) -> [return: bb3, unwind unreachable]; ++ _12 = &raw const (*_13)[_14]; ++ goto -> bb3; + } + + bb3: { + StorageDead(_14); + StorageDead(_13); + StorageLive(_15); + StorageLive(_16); + _16 = copy _4; + StorageLive(_17); + _17 = copy _5; +- _15 = slice_get_unchecked::<*mut i64, *mut [i64], i64>(move _16, move _17) -> [return: bb4, unwind unreachable]; ++ _15 = &raw mut (*_16)[_17]; ++ goto -> bb4; + } + + bb4: { + StorageDead(_17); + StorageDead(_16); + _0 = (move _6, move _9, move _12, move _15); + StorageDead(_15); + StorageDead(_12); + StorageDead(_9); + StorageDead(_6); + return; + } + } + diff --git a/tests/mir-opt/pre-codegen/slice_index.slice_get_mut_usize.PreCodegen.after.panic-abort.mir b/tests/mir-opt/pre-codegen/slice_index.slice_get_mut_usize.PreCodegen.after.panic-abort.mir index ec67193bc7948..d1b1e3d7dd73d 100644 --- a/tests/mir-opt/pre-codegen/slice_index.slice_get_mut_usize.PreCodegen.after.panic-abort.mir +++ b/tests/mir-opt/pre-codegen/slice_index.slice_get_mut_usize.PreCodegen.after.panic-abort.mir @@ -8,19 +8,11 @@ fn slice_get_mut_usize(_1: &mut [u32], _2: usize) -> Option<&mut u32> { scope 2 (inlined >::get_mut) { let mut _3: usize; let mut _4: bool; - let mut _5: *mut [u32]; - let mut _7: *mut u32; - let mut _8: &mut u32; - scope 3 (inlined core::slice::index::get_mut_noubcheck::) { - let _6: *mut u32; - scope 4 { - } - } + let mut _5: &mut u32; } } bb0: { - StorageLive(_8); StorageLive(_4); StorageLive(_3); _3 = PtrMetadata(copy _1); @@ -36,23 +28,15 @@ fn slice_get_mut_usize(_1: &mut [u32], _2: usize) -> Option<&mut u32> { bb2: { StorageDead(_3); - StorageLive(_7); StorageLive(_5); - _5 = &raw mut (*_1); - StorageLive(_6); - _6 = copy _5 as *mut u32 (PtrToPtr); - _7 = Offset(copy _6, copy _2); - StorageDead(_6); + _5 = &mut (*_1)[_2]; + _0 = Option::<&mut u32>::Some(move _5); StorageDead(_5); - _8 = &mut (*_7); - _0 = Option::<&mut u32>::Some(copy _8); - StorageDead(_7); goto -> bb3; } bb3: { StorageDead(_4); - StorageDead(_8); return; } } diff --git a/tests/mir-opt/pre-codegen/slice_index.slice_get_mut_usize.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/pre-codegen/slice_index.slice_get_mut_usize.PreCodegen.after.panic-unwind.mir index ec67193bc7948..d1b1e3d7dd73d 100644 --- a/tests/mir-opt/pre-codegen/slice_index.slice_get_mut_usize.PreCodegen.after.panic-unwind.mir +++ b/tests/mir-opt/pre-codegen/slice_index.slice_get_mut_usize.PreCodegen.after.panic-unwind.mir @@ -8,19 +8,11 @@ fn slice_get_mut_usize(_1: &mut [u32], _2: usize) -> Option<&mut u32> { scope 2 (inlined >::get_mut) { let mut _3: usize; let mut _4: bool; - let mut _5: *mut [u32]; - let mut _7: *mut u32; - let mut _8: &mut u32; - scope 3 (inlined core::slice::index::get_mut_noubcheck::) { - let _6: *mut u32; - scope 4 { - } - } + let mut _5: &mut u32; } } bb0: { - StorageLive(_8); StorageLive(_4); StorageLive(_3); _3 = PtrMetadata(copy _1); @@ -36,23 +28,15 @@ fn slice_get_mut_usize(_1: &mut [u32], _2: usize) -> Option<&mut u32> { bb2: { StorageDead(_3); - StorageLive(_7); StorageLive(_5); - _5 = &raw mut (*_1); - StorageLive(_6); - _6 = copy _5 as *mut u32 (PtrToPtr); - _7 = Offset(copy _6, copy _2); - StorageDead(_6); + _5 = &mut (*_1)[_2]; + _0 = Option::<&mut u32>::Some(move _5); StorageDead(_5); - _8 = &mut (*_7); - _0 = Option::<&mut u32>::Some(copy _8); - StorageDead(_7); goto -> bb3; } bb3: { StorageDead(_4); - StorageDead(_8); return; } } diff --git a/tests/mir-opt/pre-codegen/slice_index.slice_get_unchecked_mut_range.PreCodegen.after.panic-abort.mir b/tests/mir-opt/pre-codegen/slice_index.slice_get_unchecked_mut_range.PreCodegen.after.panic-abort.mir index 597f02e837ab6..6fb1637a6e02f 100644 --- a/tests/mir-opt/pre-codegen/slice_index.slice_get_unchecked_mut_range.PreCodegen.after.panic-abort.mir +++ b/tests/mir-opt/pre-codegen/slice_index.slice_get_unchecked_mut_range.PreCodegen.after.panic-abort.mir @@ -15,12 +15,10 @@ fn slice_get_unchecked_mut_range(_1: &mut [u32], _2: std::ops::Range) -> let _8: usize; scope 3 { scope 6 (inlined core::slice::index::get_offset_len_mut_noubcheck::) { - let _10: *mut u32; + let _9: *mut u32; scope 7 { - } - scope 8 (inlined core::slice::index::get_mut_noubcheck::) { - let _9: *mut u32; - scope 9 { + let _10: *mut u32; + scope 8 { } } } @@ -47,13 +45,13 @@ fn slice_get_unchecked_mut_range(_1: &mut [u32], _2: std::ops::Range) -> bb1: { StorageDead(_6); _8 = SubUnchecked(copy _4, copy _3); - StorageLive(_10); StorageLive(_9); + StorageLive(_10); _9 = copy _5 as *mut u32 (PtrToPtr); _10 = Offset(copy _9, copy _3); - StorageDead(_9); _11 = *mut [u32] from (copy _10, copy _8); StorageDead(_10); + StorageDead(_9); StorageDead(_8); StorageDead(_5); _0 = &mut (*_11); diff --git a/tests/mir-opt/pre-codegen/slice_index.slice_get_unchecked_mut_range.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/pre-codegen/slice_index.slice_get_unchecked_mut_range.PreCodegen.after.panic-unwind.mir index 597f02e837ab6..6fb1637a6e02f 100644 --- a/tests/mir-opt/pre-codegen/slice_index.slice_get_unchecked_mut_range.PreCodegen.after.panic-unwind.mir +++ b/tests/mir-opt/pre-codegen/slice_index.slice_get_unchecked_mut_range.PreCodegen.after.panic-unwind.mir @@ -15,12 +15,10 @@ fn slice_get_unchecked_mut_range(_1: &mut [u32], _2: std::ops::Range) -> let _8: usize; scope 3 { scope 6 (inlined core::slice::index::get_offset_len_mut_noubcheck::) { - let _10: *mut u32; + let _9: *mut u32; scope 7 { - } - scope 8 (inlined core::slice::index::get_mut_noubcheck::) { - let _9: *mut u32; - scope 9 { + let _10: *mut u32; + scope 8 { } } } @@ -47,13 +45,13 @@ fn slice_get_unchecked_mut_range(_1: &mut [u32], _2: std::ops::Range) -> bb1: { StorageDead(_6); _8 = SubUnchecked(copy _4, copy _3); - StorageLive(_10); StorageLive(_9); + StorageLive(_10); _9 = copy _5 as *mut u32 (PtrToPtr); _10 = Offset(copy _9, copy _3); - StorageDead(_9); _11 = *mut [u32] from (copy _10, copy _8); StorageDead(_10); + StorageDead(_9); StorageDead(_8); StorageDead(_5); _0 = &mut (*_11); diff --git a/tests/mir-opt/pre-codegen/slice_index.slice_ptr_get_unchecked_range.PreCodegen.after.panic-abort.mir b/tests/mir-opt/pre-codegen/slice_index.slice_ptr_get_unchecked_range.PreCodegen.after.panic-abort.mir index e34723898e4ac..ad1ca5dff43a9 100644 --- a/tests/mir-opt/pre-codegen/slice_index.slice_ptr_get_unchecked_range.PreCodegen.after.panic-abort.mir +++ b/tests/mir-opt/pre-codegen/slice_index.slice_ptr_get_unchecked_range.PreCodegen.after.panic-abort.mir @@ -13,12 +13,10 @@ fn slice_ptr_get_unchecked_range(_1: *const [u32], _2: std::ops::Range) - let _7: usize; scope 3 { scope 6 (inlined core::slice::index::get_offset_len_noubcheck::) { - let _9: *const u32; + let _8: *const u32; scope 7 { - } - scope 8 (inlined core::slice::index::get_noubcheck::) { - let _8: *const u32; - scope 9 { + let _9: *const u32; + scope 8 { } } } @@ -42,13 +40,13 @@ fn slice_ptr_get_unchecked_range(_1: *const [u32], _2: std::ops::Range) - bb1: { StorageDead(_5); _7 = SubUnchecked(copy _4, copy _3); - StorageLive(_9); StorageLive(_8); + StorageLive(_9); _8 = copy _1 as *const u32 (PtrToPtr); _9 = Offset(copy _8, copy _3); - StorageDead(_8); _0 = *const [u32] from (copy _9, copy _7); StorageDead(_9); + StorageDead(_8); StorageDead(_7); return; } diff --git a/tests/mir-opt/pre-codegen/slice_index.slice_ptr_get_unchecked_range.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/pre-codegen/slice_index.slice_ptr_get_unchecked_range.PreCodegen.after.panic-unwind.mir index e34723898e4ac..ad1ca5dff43a9 100644 --- a/tests/mir-opt/pre-codegen/slice_index.slice_ptr_get_unchecked_range.PreCodegen.after.panic-unwind.mir +++ b/tests/mir-opt/pre-codegen/slice_index.slice_ptr_get_unchecked_range.PreCodegen.after.panic-unwind.mir @@ -13,12 +13,10 @@ fn slice_ptr_get_unchecked_range(_1: *const [u32], _2: std::ops::Range) - let _7: usize; scope 3 { scope 6 (inlined core::slice::index::get_offset_len_noubcheck::) { - let _9: *const u32; + let _8: *const u32; scope 7 { - } - scope 8 (inlined core::slice::index::get_noubcheck::) { - let _8: *const u32; - scope 9 { + let _9: *const u32; + scope 8 { } } } @@ -42,13 +40,13 @@ fn slice_ptr_get_unchecked_range(_1: *const [u32], _2: std::ops::Range) - bb1: { StorageDead(_5); _7 = SubUnchecked(copy _4, copy _3); - StorageLive(_9); StorageLive(_8); + StorageLive(_9); _8 = copy _1 as *const u32 (PtrToPtr); _9 = Offset(copy _8, copy _3); - StorageDead(_8); _0 = *const [u32] from (copy _9, copy _7); StorageDead(_9); + StorageDead(_8); StorageDead(_7); return; }