slice.get(i) should use a slice projection in MIR, like slice[i] does
This commit is contained in:
parent
aa5832b142
commit
4668124cc7
15 changed files with 385 additions and 86 deletions
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
39
library/core/src/intrinsics/bounds.rs
Normal file
39
library/core/src/intrinsics/bounds.rs
Normal file
|
|
@ -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<T: ?Sized> BuiltinDeref for &mut T {
|
||||
type Pointee = T;
|
||||
}
|
||||
unsafe impl<T: ?Sized> BuiltinDeref for &T {
|
||||
type Pointee = T;
|
||||
}
|
||||
unsafe impl<T: ?Sized> BuiltinDeref for *mut T {
|
||||
type Pointee = T;
|
||||
}
|
||||
unsafe impl<T: ?Sized> BuiltinDeref for *const T {
|
||||
type Pointee = T;
|
||||
}
|
||||
|
||||
pub trait ChangePointee<U: ?Sized>: BuiltinDeref {
|
||||
type Output;
|
||||
}
|
||||
impl<'a, T: ?Sized + 'a, U: ?Sized + 'a> ChangePointee<U> for &'a mut T {
|
||||
type Output = &'a mut U;
|
||||
}
|
||||
impl<'a, T: ?Sized + 'a, U: ?Sized + 'a> ChangePointee<U> for &'a T {
|
||||
type Output = &'a U;
|
||||
}
|
||||
impl<T: ?Sized, U: ?Sized> ChangePointee<U> for *mut T {
|
||||
type Output = *mut U;
|
||||
}
|
||||
impl<T: ?Sized, U: ?Sized> ChangePointee<U> for *const T {
|
||||
type Output = *const U;
|
||||
}
|
||||
|
|
@ -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<T: ?Sized>() -> bool;
|
|||
#[rustc_intrinsic_const_stable_indirect]
|
||||
#[rustc_nounwind]
|
||||
#[rustc_intrinsic]
|
||||
pub const unsafe fn offset<Ptr, Delta>(dst: Ptr, offset: Delta) -> Ptr;
|
||||
pub const unsafe fn offset<Ptr: bounds::BuiltinDeref, Delta>(dst: Ptr, offset: Delta) -> Ptr;
|
||||
|
||||
/// Calculates the offset from a pointer, potentially wrapping.
|
||||
///
|
||||
|
|
@ -1751,6 +1752,33 @@ pub const unsafe fn offset<Ptr, Delta>(dst: Ptr, offset: Delta) -> Ptr;
|
|||
#[rustc_intrinsic]
|
||||
pub const unsafe fn arith_offset<T>(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 `<usize as SliceIndex>::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<T: ?Sized + 'static>() -> u128;
|
|||
#[unstable(feature = "core_intrinsics", issue = "none")]
|
||||
#[rustc_intrinsic_const_stable_indirect]
|
||||
#[rustc_intrinsic]
|
||||
pub const fn aggregate_raw_ptr<P: AggregateRawPtr<D, Metadata = M>, D, M>(data: D, meta: M) -> P;
|
||||
|
||||
#[unstable(feature = "core_intrinsics", issue = "none")]
|
||||
pub trait AggregateRawPtr<D> {
|
||||
type Metadata: Copy;
|
||||
}
|
||||
impl<P: ?Sized, T: ptr::Thin> AggregateRawPtr<*const T> for *const P {
|
||||
type Metadata = <P as ptr::Pointee>::Metadata;
|
||||
}
|
||||
impl<P: ?Sized, T: ptr::Thin> AggregateRawPtr<*mut T> for *mut P {
|
||||
type Metadata = <P as ptr::Pointee>::Metadata;
|
||||
}
|
||||
pub const fn aggregate_raw_ptr<P: bounds::BuiltinDeref, D, M>(data: D, meta: M) -> P
|
||||
where
|
||||
<P as bounds::BuiltinDeref>::Pointee: ptr::Pointee<Metadata = M>;
|
||||
|
||||
/// Lowers in MIR to `Rvalue::UnaryOp` with `UnOp::PtrMetadata`.
|
||||
///
|
||||
|
|
|
|||
|
|
@ -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<T>(ptr: *const [T], index: usize) -> *const T {
|
||||
let ptr = ptr as *const T;
|
||||
|
|
@ -90,6 +93,7 @@ const unsafe fn get_noubcheck<T>(ptr: *const [T], index: usize) -> *const T {
|
|||
unsafe { crate::intrinsics::offset(ptr, index) }
|
||||
}
|
||||
|
||||
#[cfg(bootstrap)]
|
||||
#[inline(always)]
|
||||
const unsafe fn get_mut_noubcheck<T>(ptr: *mut [T], index: usize) -> *mut T {
|
||||
let ptr = ptr as *mut T;
|
||||
|
|
@ -103,8 +107,9 @@ const unsafe fn get_offset_len_noubcheck<T>(
|
|||
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<T>(
|
|||
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<T> 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)) }
|
||||
unsafe {
|
||||
Some(&mut *get_mut_noubcheck(slice, self))
|
||||
}
|
||||
#[cfg(not(bootstrap))]
|
||||
// SAFETY: `self` is checked to be in bounds.
|
||||
unsafe {
|
||||
Some(slice_get_unchecked(slice, self))
|
||||
}
|
||||
} else {
|
||||
None
|
||||
}
|
||||
|
|
@ -254,7 +280,14 @@ unsafe impl<T> 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<T> 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]
|
||||
|
|
|
|||
|
|
@ -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),
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -8,19 +8,11 @@ fn slice_get_mut_usize(_1: &mut [u32], _2: usize) -> Option<&mut u32> {
|
|||
scope 2 (inlined <usize as SliceIndex<[u32]>>::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::<u32>) {
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,19 +8,11 @@ fn slice_get_mut_usize(_1: &mut [u32], _2: usize) -> Option<&mut u32> {
|
|||
scope 2 (inlined <usize as SliceIndex<[u32]>>::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::<u32>) {
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,12 +15,10 @@ fn slice_get_unchecked_mut_range(_1: &mut [u32], _2: std::ops::Range<usize>) ->
|
|||
let _8: usize;
|
||||
scope 3 {
|
||||
scope 6 (inlined core::slice::index::get_offset_len_mut_noubcheck::<u32>) {
|
||||
let _10: *mut u32;
|
||||
let _9: *mut u32;
|
||||
scope 7 {
|
||||
}
|
||||
scope 8 (inlined core::slice::index::get_mut_noubcheck::<u32>) {
|
||||
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<usize>) ->
|
|||
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);
|
||||
|
|
|
|||
|
|
@ -15,12 +15,10 @@ fn slice_get_unchecked_mut_range(_1: &mut [u32], _2: std::ops::Range<usize>) ->
|
|||
let _8: usize;
|
||||
scope 3 {
|
||||
scope 6 (inlined core::slice::index::get_offset_len_mut_noubcheck::<u32>) {
|
||||
let _10: *mut u32;
|
||||
let _9: *mut u32;
|
||||
scope 7 {
|
||||
}
|
||||
scope 8 (inlined core::slice::index::get_mut_noubcheck::<u32>) {
|
||||
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<usize>) ->
|
|||
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);
|
||||
|
|
|
|||
|
|
@ -13,12 +13,10 @@ fn slice_ptr_get_unchecked_range(_1: *const [u32], _2: std::ops::Range<usize>) -
|
|||
let _7: usize;
|
||||
scope 3 {
|
||||
scope 6 (inlined core::slice::index::get_offset_len_noubcheck::<u32>) {
|
||||
let _9: *const u32;
|
||||
let _8: *const u32;
|
||||
scope 7 {
|
||||
}
|
||||
scope 8 (inlined core::slice::index::get_noubcheck::<u32>) {
|
||||
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<usize>) -
|
|||
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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,12 +13,10 @@ fn slice_ptr_get_unchecked_range(_1: *const [u32], _2: std::ops::Range<usize>) -
|
|||
let _7: usize;
|
||||
scope 3 {
|
||||
scope 6 (inlined core::slice::index::get_offset_len_noubcheck::<u32>) {
|
||||
let _9: *const u32;
|
||||
let _8: *const u32;
|
||||
scope 7 {
|
||||
}
|
||||
scope 8 (inlined core::slice::index::get_noubcheck::<u32>) {
|
||||
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<usize>) -
|
|||
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;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue