Update NonZero and NonNull to not field-project (per MCP807)

This commit is contained in:
Scott McMurray 2024-11-21 09:15:22 -08:00
parent 2d0ea7956c
commit 7afce4f06a
16 changed files with 587 additions and 514 deletions

View File

@ -37,6 +37,8 @@ pub unsafe trait ZeroablePrimitive: Sized + Copy + private::Sealed {
macro_rules! impl_zeroable_primitive {
($($NonZeroInner:ident ( $primitive:ty )),+ $(,)?) => {
mod private {
use super::*;
#[unstable(
feature = "nonzero_internals",
reason = "implementation detail which may disappear or be replaced at any time",
@ -45,7 +47,11 @@ macro_rules! impl_zeroable_primitive {
pub trait Sealed {}
$(
#[derive(Debug, Clone, Copy, PartialEq)]
// This inner type is never shown directly, so intentionally does not have Debug
#[expect(missing_debug_implementations)]
// Since this struct is non-generic and derives Copy,
// the derived Clone is `*self` and thus doesn't field-project.
#[derive(Clone, Copy)]
#[repr(transparent)]
#[rustc_layout_scalar_valid_range_start(1)]
#[rustc_nonnull_optimization_guaranteed]
@ -55,6 +61,16 @@ macro_rules! impl_zeroable_primitive {
issue = "none"
)]
pub struct $NonZeroInner($primitive);
// This is required to allow matching a constant. We don't get it from a derive
// because the derived `PartialEq` would do a field projection, which is banned
// by <https://github.com/rust-lang/compiler-team/issues/807>.
#[unstable(
feature = "nonzero_internals",
reason = "implementation detail which may disappear or be replaced at any time",
issue = "none"
)]
impl StructuralPartialEq for $NonZeroInner {}
)+
}
@ -172,7 +188,7 @@ where
{
#[inline]
fn clone(&self) -> Self {
Self(self.0)
*self
}
}
@ -440,15 +456,21 @@ where
#[rustc_const_stable(feature = "const_nonzero_get", since = "1.34.0")]
#[inline]
pub const fn get(self) -> T {
// FIXME: This can be changed to simply `self.0` once LLVM supports `!range` metadata
// for function arguments: https://github.com/llvm/llvm-project/issues/76628
//
// Rustc can set range metadata only if it loads `self` from
// memory somewhere. If the value of `self` was from by-value argument
// of some not-inlined function, LLVM don't have range metadata
// to understand that the value cannot be zero.
//
// For now, using the transmute `assume`s the range at runtime.
// Using the transmute `assume`s the range at runtime.
//
// Even once LLVM supports `!range` metadata for function arguments
// (see <https://github.com/llvm/llvm-project/issues/76628>), this can't
// be `.0` because MCP#807 bans field-projecting into `scalar_valid_range`
// types, and it arguably wouldn't want to be anyway because if this is
// MIR-inlined, there's no opportunity to put that argument metadata anywhere.
//
// The good answer here will eventually be pattern types, which will hopefully
// allow it to go back to `.0`, maybe with a cast of some sort.
//
// SAFETY: `ZeroablePrimitive` guarantees that the size and bit validity
// of `.0` is such that this transmute is sound.

View File

@ -7,7 +7,7 @@ use crate::pin::PinCoerceUnsized;
use crate::ptr::Unique;
use crate::slice::{self, SliceIndex};
use crate::ub_checks::assert_unsafe_precondition;
use crate::{fmt, hash, intrinsics, ptr};
use crate::{fmt, hash, intrinsics, mem, ptr};
/// `*mut T` but non-zero and [covariant].
///
@ -69,6 +69,8 @@ use crate::{fmt, hash, intrinsics, ptr};
#[rustc_nonnull_optimization_guaranteed]
#[rustc_diagnostic_item = "NonNull"]
pub struct NonNull<T: ?Sized> {
// Remember to use `.as_ptr()` instead of `.pointer`, as field projecting to
// this is banned by <https://github.com/rust-lang/compiler-team/issues/807>.
pointer: *const T,
}
@ -282,7 +284,7 @@ impl<T: ?Sized> NonNull<T> {
pub fn addr(self) -> NonZero<usize> {
// SAFETY: The pointer is guaranteed by the type to be non-null,
// meaning that the address will be non-zero.
unsafe { NonZero::new_unchecked(self.pointer.addr()) }
unsafe { NonZero::new_unchecked(self.as_ptr().addr()) }
}
/// Creates a new pointer with the given address and the [provenance][crate::ptr#provenance] of
@ -296,7 +298,7 @@ impl<T: ?Sized> NonNull<T> {
#[stable(feature = "strict_provenance", since = "CURRENT_RUSTC_VERSION")]
pub fn with_addr(self, addr: NonZero<usize>) -> Self {
// SAFETY: The result of `ptr::from::with_addr` is non-null because `addr` is guaranteed to be non-zero.
unsafe { NonNull::new_unchecked(self.pointer.with_addr(addr.get()) as *mut _) }
unsafe { NonNull::new_unchecked(self.as_ptr().with_addr(addr.get()) as *mut _) }
}
/// Creates a new pointer by mapping `self`'s address to a new one, preserving the
@ -335,7 +337,12 @@ impl<T: ?Sized> NonNull<T> {
#[must_use]
#[inline(always)]
pub const fn as_ptr(self) -> *mut T {
self.pointer as *mut T
// This is a transmute for the same reasons as `NonZero::get`.
// SAFETY: `NonNull` is `transparent` over a `*const T`, and `*const T`
// and `*mut T` have the same layout, so transitively we can transmute
// our `NonNull` to a `*mut T` directly.
unsafe { mem::transmute::<Self, *mut T>(self) }
}
/// Returns a shared reference to the value. If the value may be uninitialized, [`as_uninit_ref`]
@ -484,7 +491,7 @@ impl<T: ?Sized> NonNull<T> {
// Additionally safety contract of `offset` guarantees that the resulting pointer is
// pointing to an allocation, there can't be an allocation at null, thus it's safe to
// construct `NonNull`.
unsafe { NonNull { pointer: intrinsics::offset(self.pointer, count) } }
unsafe { NonNull { pointer: intrinsics::offset(self.as_ptr(), count) } }
}
/// Calculates the offset from a pointer in bytes.
@ -508,7 +515,7 @@ impl<T: ?Sized> NonNull<T> {
// Additionally safety contract of `offset` guarantees that the resulting pointer is
// pointing to an allocation, there can't be an allocation at null, thus it's safe to
// construct `NonNull`.
unsafe { NonNull { pointer: self.pointer.byte_offset(count) } }
unsafe { NonNull { pointer: self.as_ptr().byte_offset(count) } }
}
/// Adds an offset to a pointer (convenience for `.offset(count as isize)`).
@ -560,7 +567,7 @@ impl<T: ?Sized> NonNull<T> {
// Additionally safety contract of `offset` guarantees that the resulting pointer is
// pointing to an allocation, there can't be an allocation at null, thus it's safe to
// construct `NonNull`.
unsafe { NonNull { pointer: intrinsics::offset(self.pointer, count) } }
unsafe { NonNull { pointer: intrinsics::offset(self.as_ptr(), count) } }
}
/// Calculates the offset from a pointer in bytes (convenience for `.byte_offset(count as isize)`).
@ -584,7 +591,7 @@ impl<T: ?Sized> NonNull<T> {
// Additionally safety contract of `add` guarantees that the resulting pointer is pointing
// to an allocation, there can't be an allocation at null, thus it's safe to construct
// `NonNull`.
unsafe { NonNull { pointer: self.pointer.byte_add(count) } }
unsafe { NonNull { pointer: self.as_ptr().byte_add(count) } }
}
/// Subtracts an offset from a pointer (convenience for
@ -667,7 +674,7 @@ impl<T: ?Sized> NonNull<T> {
// Additionally safety contract of `sub` guarantees that the resulting pointer is pointing
// to an allocation, there can't be an allocation at null, thus it's safe to construct
// `NonNull`.
unsafe { NonNull { pointer: self.pointer.byte_sub(count) } }
unsafe { NonNull { pointer: self.as_ptr().byte_sub(count) } }
}
/// Calculates the distance between two pointers within the same allocation. The returned value is in
@ -764,7 +771,7 @@ impl<T: ?Sized> NonNull<T> {
T: Sized,
{
// SAFETY: the caller must uphold the safety contract for `offset_from`.
unsafe { self.pointer.offset_from(origin.pointer) }
unsafe { self.as_ptr().offset_from(origin.as_ptr()) }
}
/// Calculates the distance between two pointers within the same allocation. The returned value is in
@ -782,7 +789,7 @@ impl<T: ?Sized> NonNull<T> {
#[rustc_const_stable(feature = "non_null_convenience", since = "1.80.0")]
pub const unsafe fn byte_offset_from<U: ?Sized>(self, origin: NonNull<U>) -> isize {
// SAFETY: the caller must uphold the safety contract for `byte_offset_from`.
unsafe { self.pointer.byte_offset_from(origin.pointer) }
unsafe { self.as_ptr().byte_offset_from(origin.as_ptr()) }
}
// N.B. `wrapping_offset``, `wrapping_add`, etc are not implemented because they can wrap to null
@ -857,7 +864,7 @@ impl<T: ?Sized> NonNull<T> {
T: Sized,
{
// SAFETY: the caller must uphold the safety contract for `sub_ptr`.
unsafe { self.pointer.sub_ptr(subtracted.pointer) }
unsafe { self.as_ptr().sub_ptr(subtracted.as_ptr()) }
}
/// Calculates the distance between two pointers within the same allocation, *where it's known that
@ -876,7 +883,7 @@ impl<T: ?Sized> NonNull<T> {
#[rustc_const_unstable(feature = "const_ptr_sub_ptr", issue = "95892")]
pub const unsafe fn byte_sub_ptr<U: ?Sized>(self, origin: NonNull<U>) -> usize {
// SAFETY: the caller must uphold the safety contract for `byte_sub_ptr`.
unsafe { self.pointer.byte_sub_ptr(origin.pointer) }
unsafe { self.as_ptr().byte_sub_ptr(origin.as_ptr()) }
}
/// Reads the value from `self` without moving it. This leaves the
@ -894,7 +901,7 @@ impl<T: ?Sized> NonNull<T> {
T: Sized,
{
// SAFETY: the caller must uphold the safety contract for `read`.
unsafe { ptr::read(self.pointer) }
unsafe { ptr::read(self.as_ptr()) }
}
/// Performs a volatile read of the value from `self` without moving it. This
@ -915,7 +922,7 @@ impl<T: ?Sized> NonNull<T> {
T: Sized,
{
// SAFETY: the caller must uphold the safety contract for `read_volatile`.
unsafe { ptr::read_volatile(self.pointer) }
unsafe { ptr::read_volatile(self.as_ptr()) }
}
/// Reads the value from `self` without moving it. This leaves the
@ -935,7 +942,7 @@ impl<T: ?Sized> NonNull<T> {
T: Sized,
{
// SAFETY: the caller must uphold the safety contract for `read_unaligned`.
unsafe { ptr::read_unaligned(self.pointer) }
unsafe { ptr::read_unaligned(self.as_ptr()) }
}
/// Copies `count * size_of<T>` bytes from `self` to `dest`. The source
@ -955,7 +962,7 @@ impl<T: ?Sized> NonNull<T> {
T: Sized,
{
// SAFETY: the caller must uphold the safety contract for `copy`.
unsafe { ptr::copy(self.pointer, dest.as_ptr(), count) }
unsafe { ptr::copy(self.as_ptr(), dest.as_ptr(), count) }
}
/// Copies `count * size_of<T>` bytes from `self` to `dest`. The source
@ -975,7 +982,7 @@ impl<T: ?Sized> NonNull<T> {
T: Sized,
{
// SAFETY: the caller must uphold the safety contract for `copy_nonoverlapping`.
unsafe { ptr::copy_nonoverlapping(self.pointer, dest.as_ptr(), count) }
unsafe { ptr::copy_nonoverlapping(self.as_ptr(), dest.as_ptr(), count) }
}
/// Copies `count * size_of<T>` bytes from `src` to `self`. The source
@ -995,7 +1002,7 @@ impl<T: ?Sized> NonNull<T> {
T: Sized,
{
// SAFETY: the caller must uphold the safety contract for `copy`.
unsafe { ptr::copy(src.pointer, self.as_ptr(), count) }
unsafe { ptr::copy(src.as_ptr(), self.as_ptr(), count) }
}
/// Copies `count * size_of<T>` bytes from `src` to `self`. The source
@ -1015,7 +1022,7 @@ impl<T: ?Sized> NonNull<T> {
T: Sized,
{
// SAFETY: the caller must uphold the safety contract for `copy_nonoverlapping`.
unsafe { ptr::copy_nonoverlapping(src.pointer, self.as_ptr(), count) }
unsafe { ptr::copy_nonoverlapping(src.as_ptr(), self.as_ptr(), count) }
}
/// Executes the destructor (if any) of the pointed-to value.
@ -1202,7 +1209,7 @@ impl<T: ?Sized> NonNull<T> {
{
// SAFETY: `align` has been checked to be a power of 2 above.
unsafe { ptr::align_offset(self.pointer, align) }
unsafe { ptr::align_offset(self.as_ptr(), align) }
}
}
@ -1230,7 +1237,7 @@ impl<T: ?Sized> NonNull<T> {
where
T: Sized,
{
self.pointer.is_aligned()
self.as_ptr().is_aligned()
}
/// Returns whether the pointer is aligned to `align`.
@ -1267,7 +1274,7 @@ impl<T: ?Sized> NonNull<T> {
#[must_use]
#[unstable(feature = "pointer_is_aligned_to", issue = "96284")]
pub fn is_aligned_to(self, align: usize) -> bool {
self.pointer.is_aligned_to(align)
self.as_ptr().is_aligned_to(align)
}
}

View File

@ -31,7 +31,6 @@
}
}
scope 9 (inlined NonNull::<[u8]>::as_ptr) {
let mut _17: *const [u8];
}
}
scope 3 (inlined #[track_caller] Option::<Layout>::unwrap) {
@ -102,16 +101,9 @@
StorageDead(_16);
StorageDead(_12);
StorageDead(_6);
- StorageLive(_17);
+ nop;
_17 = copy (_5.0: *const [u8]);
- _4 = move _17 as *mut [u8] (PtrToPtr);
- StorageDead(_17);
+ _4 = copy _17 as *mut [u8] (PtrToPtr);
+ nop;
_4 = copy _5 as *mut [u8] (Transmute);
StorageDead(_5);
- _3 = move _4 as *mut u8 (PtrToPtr);
+ _3 = copy _17 as *mut u8 (PtrToPtr);
_3 = move _4 as *mut u8 (PtrToPtr);
StorageDead(_4);
StorageDead(_3);
- StorageDead(_1);

View File

@ -20,7 +20,6 @@
scope 5 (inlined <std::alloc::Global as Allocator>::allocate) {
}
scope 6 (inlined NonNull::<[u8]>::as_ptr) {
let mut _12: *const [u8];
}
}
scope 3 (inlined #[track_caller] Option::<Layout>::unwrap) {
@ -45,16 +44,9 @@
bb1: {
StorageDead(_6);
- StorageLive(_12);
+ nop;
_12 = copy (_5.0: *const [u8]);
- _4 = move _12 as *mut [u8] (PtrToPtr);
- StorageDead(_12);
+ _4 = copy _12 as *mut [u8] (PtrToPtr);
+ nop;
_4 = copy _5 as *mut [u8] (Transmute);
StorageDead(_5);
- _3 = move _4 as *mut u8 (PtrToPtr);
+ _3 = copy _12 as *mut u8 (PtrToPtr);
_3 = move _4 as *mut u8 (PtrToPtr);
StorageDead(_4);
StorageDead(_3);
- StorageDead(_1);

View File

@ -31,7 +31,6 @@
}
}
scope 9 (inlined NonNull::<[u8]>::as_ptr) {
let mut _17: *const [u8];
}
}
scope 3 (inlined #[track_caller] Option::<Layout>::unwrap) {
@ -102,16 +101,9 @@
StorageDead(_16);
StorageDead(_12);
StorageDead(_6);
- StorageLive(_17);
+ nop;
_17 = copy (_5.0: *const [u8]);
- _4 = move _17 as *mut [u8] (PtrToPtr);
- StorageDead(_17);
+ _4 = copy _17 as *mut [u8] (PtrToPtr);
+ nop;
_4 = copy _5 as *mut [u8] (Transmute);
StorageDead(_5);
- _3 = move _4 as *mut u8 (PtrToPtr);
+ _3 = copy _17 as *mut u8 (PtrToPtr);
_3 = move _4 as *mut u8 (PtrToPtr);
StorageDead(_4);
StorageDead(_3);
- StorageDead(_1);

View File

@ -20,7 +20,6 @@
scope 5 (inlined <std::alloc::Global as Allocator>::allocate) {
}
scope 6 (inlined NonNull::<[u8]>::as_ptr) {
let mut _12: *const [u8];
}
}
scope 3 (inlined #[track_caller] Option::<Layout>::unwrap) {
@ -45,16 +44,9 @@
bb1: {
StorageDead(_6);
- StorageLive(_12);
+ nop;
_12 = copy (_5.0: *const [u8]);
- _4 = move _12 as *mut [u8] (PtrToPtr);
- StorageDead(_12);
+ _4 = copy _12 as *mut [u8] (PtrToPtr);
+ nop;
_4 = copy _5 as *mut [u8] (Transmute);
StorageDead(_5);
- _3 = move _4 as *mut u8 (PtrToPtr);
+ _3 = copy _12 as *mut u8 (PtrToPtr);
_3 = move _4 as *mut u8 (PtrToPtr);
StorageDead(_4);
StorageDead(_3);
- StorageDead(_1);

View File

@ -4,28 +4,28 @@ 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 _12: std::iter::Enumerate<std::slice::Iter<'_, T>>;
let mut _13: std::iter::Enumerate<std::slice::Iter<'_, T>>;
let mut _21: std::option::Option<(usize, &T)>;
let mut _24: &impl Fn(usize, &T);
let mut _25: (usize, &T);
let _26: ();
let mut _13: std::slice::Iter<'_, T>;
let mut _14: std::iter::Enumerate<std::slice::Iter<'_, T>>;
let mut _15: std::iter::Enumerate<std::slice::Iter<'_, T>>;
let mut _23: std::option::Option<(usize, &T)>;
let mut _26: &impl Fn(usize, &T);
let mut _27: (usize, &T);
let _28: ();
scope 1 {
debug iter => _13;
let _22: usize;
let _23: &T;
debug iter => _15;
let _24: usize;
let _25: &T;
scope 2 {
debug i => _22;
debug x => _23;
debug i => _24;
debug x => _25;
}
scope 18 (inlined <Enumerate<std::slice::Iter<'_, T>> as Iterator>::next) {
let mut _14: &mut std::slice::Iter<'_, T>;
let mut _15: std::option::Option<&T>;
let mut _19: (usize, bool);
let mut _20: (usize, &T);
let mut _16: &mut std::slice::Iter<'_, T>;
let mut _17: std::option::Option<&T>;
let mut _21: (usize, bool);
let mut _22: (usize, &T);
scope 19 {
let _18: usize;
let _20: usize;
scope 24 {
}
}
@ -40,8 +40,8 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () {
}
}
scope 25 (inlined <Option<&T> as Try>::branch) {
let mut _16: isize;
let _17: &T;
let mut _18: isize;
let _19: &T;
scope 26 {
}
}
@ -50,13 +50,14 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () {
scope 3 (inlined core::slice::<impl [T]>::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 _5: std::ptr::NonNull<[T]>;
let mut _9: *mut T;
let mut _10: *mut T;
let mut _12: *const T;
scope 5 {
let _6: std::ptr::NonNull<T>;
let _8: std::ptr::NonNull<T>;
scope 6 {
let _9: *const T;
let _11: *const T;
scope 7 {
}
scope 12 (inlined without_provenance::<T>) {
@ -72,7 +73,8 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () {
}
}
scope 10 (inlined NonNull::<[T]>::cast::<T>) {
let mut _5: *const T;
let mut _6: *mut [T];
let mut _7: *const T;
scope 11 (inlined NonNull::<[T]>::as_ptr) {
}
}
@ -87,76 +89,82 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () {
}
bb0: {
StorageLive(_11);
StorageLive(_13);
StorageLive(_3);
StorageLive(_6);
StorageLive(_4);
StorageLive(_5);
StorageLive(_8);
_3 = PtrMetadata(copy _1);
StorageLive(_5);
StorageLive(_4);
_4 = &raw const (*_1);
_5 = copy _4 as *const T (PtrToPtr);
_6 = NonNull::<T> { pointer: copy _5 };
StorageLive(_9);
_5 = NonNull::<[T]> { pointer: move _4 };
StorageDead(_4);
StorageLive(_6);
StorageLive(_7);
_6 = copy _5 as *mut [T] (Transmute);
_7 = copy _6 as *const T (PtrToPtr);
_8 = NonNull::<T> { pointer: move _7 };
StorageDead(_7);
StorageDead(_6);
StorageDead(_5);
StorageLive(_11);
switchInt(const <T as std::mem::SizedTypeProperties>::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);
StorageLive(_10);
StorageLive(_9);
_9 = copy _8 as *mut T (Transmute);
_10 = Offset(copy _9, copy _3);
StorageDead(_9);
_11 = move _10 as *const T (PtrToPtr);
StorageDead(_10);
goto -> bb3;
}
bb2: {
_9 = copy _3 as *const T (Transmute);
_11 = copy _3 as *const T (Transmute);
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);
StorageDead(_9);
StorageDead(_5);
StorageDead(_4);
StorageDead(_6);
StorageDead(_3);
_12 = Enumerate::<std::slice::Iter<'_, T>> { iter: copy _11, count: const 0_usize };
StorageLive(_12);
_12 = copy _11;
_13 = std::slice::Iter::<'_, T> { ptr: copy _8, end_or_len: move _12, _marker: const ZeroSized: PhantomData<&T> };
StorageDead(_12);
StorageDead(_11);
StorageLive(_13);
_13 = copy _12;
StorageDead(_8);
StorageDead(_3);
_14 = Enumerate::<std::slice::Iter<'_, T>> { iter: copy _13, count: const 0_usize };
StorageDead(_13);
StorageLive(_15);
_15 = copy _14;
goto -> bb4;
}
bb4: {
StorageLive(_23);
StorageLive(_20);
StorageLive(_21);
StorageLive(_18);
StorageLive(_19);
StorageLive(_15);
StorageLive(_14);
_14 = &mut (_13.0: std::slice::Iter<'_, T>);
_15 = <std::slice::Iter<'_, T> as Iterator>::next(move _14) -> [return: bb5, unwind unreachable];
StorageLive(_17);
StorageLive(_16);
_16 = &mut (_15.0: std::slice::Iter<'_, T>);
_17 = <std::slice::Iter<'_, T> as Iterator>::next(move _16) -> [return: bb5, unwind unreachable];
}
bb5: {
StorageDead(_14);
StorageLive(_16);
_16 = discriminant(_15);
switchInt(move _16) -> [0: bb6, 1: bb8, otherwise: bb11];
StorageDead(_16);
StorageLive(_18);
_18 = discriminant(_17);
switchInt(move _18) -> [0: bb6, 1: bb8, otherwise: bb11];
}
bb6: {
StorageDead(_16);
StorageDead(_15);
StorageDead(_19);
StorageDead(_18);
StorageDead(_17);
StorageDead(_21);
StorageDead(_13);
StorageDead(_20);
StorageDead(_23);
StorageDead(_15);
drop(_2) -> [return: bb7, unwind unreachable];
}
@ -165,35 +173,35 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () {
}
bb8: {
_17 = move ((_15 as Some).0: &T);
StorageDead(_16);
StorageDead(_15);
_18 = copy (_13.1: usize);
_19 = AddWithOverflow(copy (_13.1: usize), const 1_usize);
assert(!move (_19.1: bool), "attempt to compute `{} + {}`, which would overflow", copy (_13.1: usize), const 1_usize) -> [success: bb9, unwind unreachable];
_19 = move ((_17 as Some).0: &T);
StorageDead(_18);
StorageDead(_17);
_20 = copy (_15.1: usize);
_21 = AddWithOverflow(copy (_15.1: usize), const 1_usize);
assert(!move (_21.1: bool), "attempt to compute `{} + {}`, which would overflow", copy (_15.1: usize), const 1_usize) -> [success: bb9, unwind unreachable];
}
bb9: {
(_13.1: usize) = move (_19.0: usize);
StorageLive(_20);
_20 = (copy _18, copy _17);
_21 = Option::<(usize, &T)>::Some(move _20);
(_15.1: usize) = move (_21.0: usize);
StorageLive(_22);
_22 = (copy _20, copy _19);
_23 = Option::<(usize, &T)>::Some(move _22);
StorageDead(_22);
StorageDead(_21);
StorageDead(_20);
StorageDead(_19);
StorageDead(_18);
_22 = copy (((_21 as Some).0: (usize, &T)).0: usize);
_23 = copy (((_21 as Some).0: (usize, &T)).1: &T);
StorageLive(_24);
_24 = &_2;
StorageLive(_25);
_25 = (copy _22, copy _23);
_26 = <impl Fn(usize, &T) as Fn<(usize, &T)>>::call(move _24, move _25) -> [return: bb10, unwind unreachable];
_24 = copy (((_23 as Some).0: (usize, &T)).0: usize);
_25 = copy (((_23 as Some).0: (usize, &T)).1: &T);
StorageLive(_26);
_26 = &_2;
StorageLive(_27);
_27 = (copy _24, copy _25);
_28 = <impl Fn(usize, &T) as Fn<(usize, &T)>>::call(move _26, move _27) -> [return: bb10, unwind unreachable];
}
bb10: {
StorageDead(_25);
StorageDead(_24);
StorageDead(_21);
StorageDead(_27);
StorageDead(_26);
StorageDead(_23);
goto -> bb4;
}

View File

@ -4,34 +4,35 @@ 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 _12: std::iter::Enumerate<std::slice::Iter<'_, T>>;
let mut _13: std::iter::Enumerate<std::slice::Iter<'_, T>>;
let mut _14: &mut std::iter::Enumerate<std::slice::Iter<'_, T>>;
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: std::slice::Iter<'_, T>;
let mut _14: std::iter::Enumerate<std::slice::Iter<'_, T>>;
let mut _15: std::iter::Enumerate<std::slice::Iter<'_, T>>;
let mut _16: &mut std::iter::Enumerate<std::slice::Iter<'_, T>>;
let mut _17: std::option::Option<(usize, &T)>;
let mut _18: isize;
let mut _21: &impl Fn(usize, &T);
let mut _22: (usize, &T);
let _23: ();
scope 1 {
debug iter => _13;
let _17: usize;
let _18: &T;
debug iter => _15;
let _19: usize;
let _20: &T;
scope 2 {
debug i => _17;
debug x => _18;
debug i => _19;
debug x => _20;
}
}
scope 3 (inlined core::slice::<impl [T]>::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 _5: std::ptr::NonNull<[T]>;
let mut _9: *mut T;
let mut _10: *mut T;
let mut _12: *const T;
scope 5 {
let _6: std::ptr::NonNull<T>;
let _8: std::ptr::NonNull<T>;
scope 6 {
let _9: *const T;
let _11: *const T;
scope 7 {
}
scope 12 (inlined without_provenance::<T>) {
@ -47,7 +48,8 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () {
}
}
scope 10 (inlined NonNull::<[T]>::cast::<T>) {
let mut _5: *const T;
let mut _6: *mut [T];
let mut _7: *const T;
scope 11 (inlined NonNull::<[T]>::as_ptr) {
}
}
@ -62,66 +64,72 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () {
}
bb0: {
StorageLive(_11);
StorageLive(_13);
StorageLive(_3);
StorageLive(_6);
StorageLive(_4);
StorageLive(_5);
StorageLive(_8);
_3 = PtrMetadata(copy _1);
StorageLive(_5);
StorageLive(_4);
_4 = &raw const (*_1);
_5 = copy _4 as *const T (PtrToPtr);
_6 = NonNull::<T> { pointer: copy _5 };
StorageLive(_9);
_5 = NonNull::<[T]> { pointer: move _4 };
StorageDead(_4);
StorageLive(_6);
StorageLive(_7);
_6 = copy _5 as *mut [T] (Transmute);
_7 = copy _6 as *const T (PtrToPtr);
_8 = NonNull::<T> { pointer: move _7 };
StorageDead(_7);
StorageDead(_6);
StorageDead(_5);
StorageLive(_11);
switchInt(const <T as std::mem::SizedTypeProperties>::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);
StorageLive(_10);
StorageLive(_9);
_9 = copy _8 as *mut T (Transmute);
_10 = Offset(copy _9, copy _3);
StorageDead(_9);
_11 = move _10 as *const T (PtrToPtr);
StorageDead(_10);
goto -> bb3;
}
bb2: {
_9 = copy _3 as *const T (Transmute);
_11 = copy _3 as *const T (Transmute);
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);
StorageDead(_9);
StorageDead(_5);
StorageDead(_4);
StorageDead(_6);
StorageDead(_3);
_12 = Enumerate::<std::slice::Iter<'_, T>> { iter: copy _11, count: const 0_usize };
StorageLive(_12);
_12 = copy _11;
_13 = std::slice::Iter::<'_, T> { ptr: copy _8, end_or_len: move _12, _marker: const ZeroSized: PhantomData<&T> };
StorageDead(_12);
StorageDead(_11);
StorageLive(_13);
_13 = copy _12;
StorageDead(_8);
StorageDead(_3);
_14 = Enumerate::<std::slice::Iter<'_, T>> { iter: copy _13, count: const 0_usize };
StorageDead(_13);
StorageLive(_15);
_15 = copy _14;
goto -> bb4;
}
bb4: {
StorageLive(_15);
_14 = &mut _13;
_15 = <Enumerate<std::slice::Iter<'_, T>> as Iterator>::next(move _14) -> [return: bb5, unwind: bb11];
StorageLive(_17);
_16 = &mut _15;
_17 = <Enumerate<std::slice::Iter<'_, T>> as Iterator>::next(move _16) -> [return: bb5, unwind: bb11];
}
bb5: {
_16 = discriminant(_15);
switchInt(move _16) -> [0: bb6, 1: bb8, otherwise: bb10];
_18 = discriminant(_17);
switchInt(move _18) -> [0: bb6, 1: bb8, otherwise: bb10];
}
bb6: {
StorageDead(_17);
StorageDead(_15);
StorageDead(_13);
drop(_2) -> [return: bb7, unwind continue];
}
@ -130,19 +138,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);
StorageLive(_19);
_19 = &_2;
StorageLive(_20);
_20 = (copy _17, copy _18);
_21 = <impl Fn(usize, &T) as Fn<(usize, &T)>>::call(move _19, move _20) -> [return: bb9, unwind: bb11];
_19 = copy (((_17 as Some).0: (usize, &T)).0: usize);
_20 = copy (((_17 as Some).0: (usize, &T)).1: &T);
StorageLive(_21);
_21 = &_2;
StorageLive(_22);
_22 = (copy _19, copy _20);
_23 = <impl Fn(usize, &T) as Fn<(usize, &T)>>::call(move _21, move _22) -> [return: bb9, unwind: bb11];
}
bb9: {
StorageDead(_20);
StorageDead(_19);
StorageDead(_15);
StorageDead(_22);
StorageDead(_21);
StorageDead(_17);
goto -> bb4;
}

View File

@ -4,31 +4,32 @@ fn forward_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 _12: std::slice::Iter<'_, T>;
let mut _13: &mut std::slice::Iter<'_, T>;
let mut _14: std::option::Option<&T>;
let mut _15: isize;
let mut _17: &impl Fn(&T);
let mut _18: (&T,);
let _19: ();
let mut _13: std::slice::Iter<'_, T>;
let mut _14: std::slice::Iter<'_, T>;
let mut _15: &mut std::slice::Iter<'_, T>;
let mut _16: std::option::Option<&T>;
let mut _17: isize;
let mut _19: &impl Fn(&T);
let mut _20: (&T,);
let _21: ();
scope 1 {
debug iter => _12;
let _16: &T;
debug iter => _14;
let _18: &T;
scope 2 {
debug x => _16;
debug x => _18;
}
}
scope 3 (inlined core::slice::<impl [T]>::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 _5: std::ptr::NonNull<[T]>;
let mut _9: *mut T;
let mut _10: *mut T;
let mut _12: *const T;
scope 5 {
let _6: std::ptr::NonNull<T>;
let _8: std::ptr::NonNull<T>;
scope 6 {
let _9: *const T;
let _11: *const T;
scope 7 {
}
scope 12 (inlined without_provenance::<T>) {
@ -44,7 +45,8 @@ fn forward_loop(_1: &[T], _2: impl Fn(&T)) -> () {
}
}
scope 10 (inlined NonNull::<[T]>::cast::<T>) {
let mut _5: *const T;
let mut _6: *mut [T];
let mut _7: *const T;
scope 11 (inlined NonNull::<[T]>::as_ptr) {
}
}
@ -56,62 +58,68 @@ fn forward_loop(_1: &[T], _2: impl Fn(&T)) -> () {
bb0: {
StorageLive(_3);
StorageLive(_6);
StorageLive(_4);
StorageLive(_5);
StorageLive(_8);
_3 = PtrMetadata(copy _1);
StorageLive(_5);
StorageLive(_4);
_4 = &raw const (*_1);
_5 = copy _4 as *const T (PtrToPtr);
_6 = NonNull::<T> { pointer: copy _5 };
StorageLive(_9);
_5 = NonNull::<[T]> { pointer: move _4 };
StorageDead(_4);
StorageLive(_6);
StorageLive(_7);
_6 = copy _5 as *mut [T] (Transmute);
_7 = copy _6 as *const T (PtrToPtr);
_8 = NonNull::<T> { pointer: move _7 };
StorageDead(_7);
StorageDead(_6);
StorageDead(_5);
StorageLive(_11);
switchInt(const <T as std::mem::SizedTypeProperties>::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);
StorageLive(_10);
StorageLive(_9);
_9 = copy _8 as *mut T (Transmute);
_10 = Offset(copy _9, copy _3);
StorageDead(_9);
_11 = move _10 as *const T (PtrToPtr);
StorageDead(_10);
goto -> bb3;
}
bb2: {
_9 = copy _3 as *const T (Transmute);
_11 = copy _3 as *const T (Transmute);
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);
StorageDead(_9);
StorageDead(_5);
StorageDead(_4);
StorageDead(_6);
StorageDead(_3);
StorageLive(_12);
_12 = copy _11;
_13 = std::slice::Iter::<'_, T> { ptr: copy _8, end_or_len: move _12, _marker: const ZeroSized: PhantomData<&T> };
StorageDead(_12);
StorageDead(_11);
StorageDead(_8);
StorageDead(_3);
StorageLive(_14);
_14 = copy _13;
goto -> bb4;
}
bb4: {
StorageLive(_14);
_13 = &mut _12;
_14 = <std::slice::Iter<'_, T> as Iterator>::next(move _13) -> [return: bb5, unwind unreachable];
StorageLive(_16);
_15 = &mut _14;
_16 = <std::slice::Iter<'_, T> as Iterator>::next(move _15) -> [return: bb5, unwind unreachable];
}
bb5: {
_15 = discriminant(_14);
switchInt(move _15) -> [0: bb6, 1: bb8, otherwise: bb10];
_17 = discriminant(_16);
switchInt(move _17) -> [0: bb6, 1: bb8, otherwise: bb10];
}
bb6: {
StorageDead(_16);
StorageDead(_14);
StorageDead(_12);
drop(_2) -> [return: bb7, unwind unreachable];
}
@ -120,18 +128,18 @@ fn forward_loop(_1: &[T], _2: impl Fn(&T)) -> () {
}
bb8: {
_16 = copy ((_14 as Some).0: &T);
StorageLive(_17);
_17 = &_2;
StorageLive(_18);
_18 = (copy _16,);
_19 = <impl Fn(&T) as Fn<(&T,)>>::call(move _17, move _18) -> [return: bb9, unwind unreachable];
_18 = copy ((_16 as Some).0: &T);
StorageLive(_19);
_19 = &_2;
StorageLive(_20);
_20 = (copy _18,);
_21 = <impl Fn(&T) as Fn<(&T,)>>::call(move _19, move _20) -> [return: bb9, unwind unreachable];
}
bb9: {
StorageDead(_18);
StorageDead(_17);
StorageDead(_14);
StorageDead(_20);
StorageDead(_19);
StorageDead(_16);
goto -> bb4;
}

View File

@ -4,31 +4,32 @@ fn forward_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 _12: std::slice::Iter<'_, T>;
let mut _13: &mut std::slice::Iter<'_, T>;
let mut _14: std::option::Option<&T>;
let mut _15: isize;
let mut _17: &impl Fn(&T);
let mut _18: (&T,);
let _19: ();
let mut _13: std::slice::Iter<'_, T>;
let mut _14: std::slice::Iter<'_, T>;
let mut _15: &mut std::slice::Iter<'_, T>;
let mut _16: std::option::Option<&T>;
let mut _17: isize;
let mut _19: &impl Fn(&T);
let mut _20: (&T,);
let _21: ();
scope 1 {
debug iter => _12;
let _16: &T;
debug iter => _14;
let _18: &T;
scope 2 {
debug x => _16;
debug x => _18;
}
}
scope 3 (inlined core::slice::<impl [T]>::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 _5: std::ptr::NonNull<[T]>;
let mut _9: *mut T;
let mut _10: *mut T;
let mut _12: *const T;
scope 5 {
let _6: std::ptr::NonNull<T>;
let _8: std::ptr::NonNull<T>;
scope 6 {
let _9: *const T;
let _11: *const T;
scope 7 {
}
scope 12 (inlined without_provenance::<T>) {
@ -44,7 +45,8 @@ fn forward_loop(_1: &[T], _2: impl Fn(&T)) -> () {
}
}
scope 10 (inlined NonNull::<[T]>::cast::<T>) {
let mut _5: *const T;
let mut _6: *mut [T];
let mut _7: *const T;
scope 11 (inlined NonNull::<[T]>::as_ptr) {
}
}
@ -56,62 +58,68 @@ fn forward_loop(_1: &[T], _2: impl Fn(&T)) -> () {
bb0: {
StorageLive(_3);
StorageLive(_6);
StorageLive(_4);
StorageLive(_5);
StorageLive(_8);
_3 = PtrMetadata(copy _1);
StorageLive(_5);
StorageLive(_4);
_4 = &raw const (*_1);
_5 = copy _4 as *const T (PtrToPtr);
_6 = NonNull::<T> { pointer: copy _5 };
StorageLive(_9);
_5 = NonNull::<[T]> { pointer: move _4 };
StorageDead(_4);
StorageLive(_6);
StorageLive(_7);
_6 = copy _5 as *mut [T] (Transmute);
_7 = copy _6 as *const T (PtrToPtr);
_8 = NonNull::<T> { pointer: move _7 };
StorageDead(_7);
StorageDead(_6);
StorageDead(_5);
StorageLive(_11);
switchInt(const <T as std::mem::SizedTypeProperties>::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);
StorageLive(_10);
StorageLive(_9);
_9 = copy _8 as *mut T (Transmute);
_10 = Offset(copy _9, copy _3);
StorageDead(_9);
_11 = move _10 as *const T (PtrToPtr);
StorageDead(_10);
goto -> bb3;
}
bb2: {
_9 = copy _3 as *const T (Transmute);
_11 = copy _3 as *const T (Transmute);
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);
StorageDead(_9);
StorageDead(_5);
StorageDead(_4);
StorageDead(_6);
StorageDead(_3);
StorageLive(_12);
_12 = copy _11;
_13 = std::slice::Iter::<'_, T> { ptr: copy _8, end_or_len: move _12, _marker: const ZeroSized: PhantomData<&T> };
StorageDead(_12);
StorageDead(_11);
StorageDead(_8);
StorageDead(_3);
StorageLive(_14);
_14 = copy _13;
goto -> bb4;
}
bb4: {
StorageLive(_14);
_13 = &mut _12;
_14 = <std::slice::Iter<'_, T> as Iterator>::next(move _13) -> [return: bb5, unwind: bb11];
StorageLive(_16);
_15 = &mut _14;
_16 = <std::slice::Iter<'_, T> as Iterator>::next(move _15) -> [return: bb5, unwind: bb11];
}
bb5: {
_15 = discriminant(_14);
switchInt(move _15) -> [0: bb6, 1: bb8, otherwise: bb10];
_17 = discriminant(_16);
switchInt(move _17) -> [0: bb6, 1: bb8, otherwise: bb10];
}
bb6: {
StorageDead(_16);
StorageDead(_14);
StorageDead(_12);
drop(_2) -> [return: bb7, unwind continue];
}
@ -120,18 +128,18 @@ fn forward_loop(_1: &[T], _2: impl Fn(&T)) -> () {
}
bb8: {
_16 = copy ((_14 as Some).0: &T);
StorageLive(_17);
_17 = &_2;
StorageLive(_18);
_18 = (copy _16,);
_19 = <impl Fn(&T) as Fn<(&T,)>>::call(move _17, move _18) -> [return: bb9, unwind: bb11];
_18 = copy ((_16 as Some).0: &T);
StorageLive(_19);
_19 = &_2;
StorageLive(_20);
_20 = (copy _18,);
_21 = <impl Fn(&T) as Fn<(&T,)>>::call(move _19, move _20) -> [return: bb9, unwind: bb11];
}
bb9: {
StorageDead(_18);
StorageDead(_17);
StorageDead(_14);
StorageDead(_20);
StorageDead(_19);
StorageDead(_16);
goto -> bb4;
}

View File

@ -4,34 +4,35 @@ 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 _12: std::iter::Rev<std::slice::Iter<'_, T>>;
let mut _13: std::iter::Rev<std::slice::Iter<'_, T>>;
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 _13: std::slice::Iter<'_, T>;
let mut _14: std::iter::Rev<std::slice::Iter<'_, T>>;
let mut _15: std::iter::Rev<std::slice::Iter<'_, T>>;
let mut _17: std::option::Option<&T>;
let mut _18: isize;
let mut _20: &impl Fn(&T);
let mut _21: (&T,);
let _22: ();
scope 1 {
debug iter => _13;
let _17: &T;
debug iter => _15;
let _19: &T;
scope 2 {
debug x => _17;
debug x => _19;
}
scope 18 (inlined <Rev<std::slice::Iter<'_, T>> as Iterator>::next) {
let mut _14: &mut std::slice::Iter<'_, T>;
let mut _16: &mut std::slice::Iter<'_, T>;
}
}
scope 3 (inlined core::slice::<impl [T]>::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 _5: std::ptr::NonNull<[T]>;
let mut _9: *mut T;
let mut _10: *mut T;
let mut _12: *const T;
scope 5 {
let _6: std::ptr::NonNull<T>;
let _8: std::ptr::NonNull<T>;
scope 6 {
let _9: *const T;
let _11: *const T;
scope 7 {
}
scope 12 (inlined without_provenance::<T>) {
@ -47,7 +48,8 @@ fn reverse_loop(_1: &[T], _2: impl Fn(&T)) -> () {
}
}
scope 10 (inlined NonNull::<[T]>::cast::<T>) {
let mut _5: *const T;
let mut _6: *mut [T];
let mut _7: *const T;
scope 11 (inlined NonNull::<[T]>::as_ptr) {
}
}
@ -62,68 +64,74 @@ fn reverse_loop(_1: &[T], _2: impl Fn(&T)) -> () {
}
bb0: {
StorageLive(_11);
StorageLive(_13);
StorageLive(_3);
StorageLive(_6);
StorageLive(_4);
StorageLive(_5);
StorageLive(_8);
_3 = PtrMetadata(copy _1);
StorageLive(_5);
StorageLive(_4);
_4 = &raw const (*_1);
_5 = copy _4 as *const T (PtrToPtr);
_6 = NonNull::<T> { pointer: copy _5 };
StorageLive(_9);
_5 = NonNull::<[T]> { pointer: move _4 };
StorageDead(_4);
StorageLive(_6);
StorageLive(_7);
_6 = copy _5 as *mut [T] (Transmute);
_7 = copy _6 as *const T (PtrToPtr);
_8 = NonNull::<T> { pointer: move _7 };
StorageDead(_7);
StorageDead(_6);
StorageDead(_5);
StorageLive(_11);
switchInt(const <T as std::mem::SizedTypeProperties>::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);
StorageLive(_10);
StorageLive(_9);
_9 = copy _8 as *mut T (Transmute);
_10 = Offset(copy _9, copy _3);
StorageDead(_9);
_11 = move _10 as *const T (PtrToPtr);
StorageDead(_10);
goto -> bb3;
}
bb2: {
_9 = copy _3 as *const T (Transmute);
_11 = copy _3 as *const T (Transmute);
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);
StorageDead(_9);
StorageDead(_5);
StorageDead(_4);
StorageDead(_6);
StorageDead(_3);
_12 = Rev::<std::slice::Iter<'_, T>> { iter: copy _11 };
StorageLive(_12);
_12 = copy _11;
_13 = std::slice::Iter::<'_, T> { ptr: copy _8, end_or_len: move _12, _marker: const ZeroSized: PhantomData<&T> };
StorageDead(_12);
StorageDead(_11);
StorageLive(_13);
_13 = copy _12;
StorageDead(_8);
StorageDead(_3);
_14 = Rev::<std::slice::Iter<'_, T>> { iter: copy _13 };
StorageDead(_13);
StorageLive(_15);
_15 = copy _14;
goto -> bb4;
}
bb4: {
StorageLive(_15);
StorageLive(_14);
_14 = &mut (_13.0: std::slice::Iter<'_, T>);
_15 = <std::slice::Iter<'_, T> as DoubleEndedIterator>::next_back(move _14) -> [return: bb5, unwind unreachable];
StorageLive(_17);
StorageLive(_16);
_16 = &mut (_15.0: std::slice::Iter<'_, T>);
_17 = <std::slice::Iter<'_, T> as DoubleEndedIterator>::next_back(move _16) -> [return: bb5, unwind unreachable];
}
bb5: {
StorageDead(_14);
_16 = discriminant(_15);
switchInt(move _16) -> [0: bb6, 1: bb8, otherwise: bb10];
StorageDead(_16);
_18 = discriminant(_17);
switchInt(move _18) -> [0: bb6, 1: bb8, otherwise: bb10];
}
bb6: {
StorageDead(_17);
StorageDead(_15);
StorageDead(_13);
drop(_2) -> [return: bb7, unwind unreachable];
}
@ -132,18 +140,18 @@ fn reverse_loop(_1: &[T], _2: impl Fn(&T)) -> () {
}
bb8: {
_17 = copy ((_15 as Some).0: &T);
StorageLive(_18);
_18 = &_2;
StorageLive(_19);
_19 = (copy _17,);
_20 = <impl Fn(&T) as Fn<(&T,)>>::call(move _18, move _19) -> [return: bb9, unwind unreachable];
_19 = copy ((_17 as Some).0: &T);
StorageLive(_20);
_20 = &_2;
StorageLive(_21);
_21 = (copy _19,);
_22 = <impl Fn(&T) as Fn<(&T,)>>::call(move _20, move _21) -> [return: bb9, unwind unreachable];
}
bb9: {
StorageDead(_19);
StorageDead(_18);
StorageDead(_15);
StorageDead(_21);
StorageDead(_20);
StorageDead(_17);
goto -> bb4;
}

View File

@ -4,34 +4,35 @@ 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 _12: std::iter::Rev<std::slice::Iter<'_, T>>;
let mut _13: std::iter::Rev<std::slice::Iter<'_, T>>;
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 _13: std::slice::Iter<'_, T>;
let mut _14: std::iter::Rev<std::slice::Iter<'_, T>>;
let mut _15: std::iter::Rev<std::slice::Iter<'_, T>>;
let mut _17: std::option::Option<&T>;
let mut _18: isize;
let mut _20: &impl Fn(&T);
let mut _21: (&T,);
let _22: ();
scope 1 {
debug iter => _13;
let _17: &T;
debug iter => _15;
let _19: &T;
scope 2 {
debug x => _17;
debug x => _19;
}
scope 18 (inlined <Rev<std::slice::Iter<'_, T>> as Iterator>::next) {
let mut _14: &mut std::slice::Iter<'_, T>;
let mut _16: &mut std::slice::Iter<'_, T>;
}
}
scope 3 (inlined core::slice::<impl [T]>::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 _5: std::ptr::NonNull<[T]>;
let mut _9: *mut T;
let mut _10: *mut T;
let mut _12: *const T;
scope 5 {
let _6: std::ptr::NonNull<T>;
let _8: std::ptr::NonNull<T>;
scope 6 {
let _9: *const T;
let _11: *const T;
scope 7 {
}
scope 12 (inlined without_provenance::<T>) {
@ -47,7 +48,8 @@ fn reverse_loop(_1: &[T], _2: impl Fn(&T)) -> () {
}
}
scope 10 (inlined NonNull::<[T]>::cast::<T>) {
let mut _5: *const T;
let mut _6: *mut [T];
let mut _7: *const T;
scope 11 (inlined NonNull::<[T]>::as_ptr) {
}
}
@ -62,68 +64,74 @@ fn reverse_loop(_1: &[T], _2: impl Fn(&T)) -> () {
}
bb0: {
StorageLive(_11);
StorageLive(_13);
StorageLive(_3);
StorageLive(_6);
StorageLive(_4);
StorageLive(_5);
StorageLive(_8);
_3 = PtrMetadata(copy _1);
StorageLive(_5);
StorageLive(_4);
_4 = &raw const (*_1);
_5 = copy _4 as *const T (PtrToPtr);
_6 = NonNull::<T> { pointer: copy _5 };
StorageLive(_9);
_5 = NonNull::<[T]> { pointer: move _4 };
StorageDead(_4);
StorageLive(_6);
StorageLive(_7);
_6 = copy _5 as *mut [T] (Transmute);
_7 = copy _6 as *const T (PtrToPtr);
_8 = NonNull::<T> { pointer: move _7 };
StorageDead(_7);
StorageDead(_6);
StorageDead(_5);
StorageLive(_11);
switchInt(const <T as std::mem::SizedTypeProperties>::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);
StorageLive(_10);
StorageLive(_9);
_9 = copy _8 as *mut T (Transmute);
_10 = Offset(copy _9, copy _3);
StorageDead(_9);
_11 = move _10 as *const T (PtrToPtr);
StorageDead(_10);
goto -> bb3;
}
bb2: {
_9 = copy _3 as *const T (Transmute);
_11 = copy _3 as *const T (Transmute);
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);
StorageDead(_9);
StorageDead(_5);
StorageDead(_4);
StorageDead(_6);
StorageDead(_3);
_12 = Rev::<std::slice::Iter<'_, T>> { iter: copy _11 };
StorageLive(_12);
_12 = copy _11;
_13 = std::slice::Iter::<'_, T> { ptr: copy _8, end_or_len: move _12, _marker: const ZeroSized: PhantomData<&T> };
StorageDead(_12);
StorageDead(_11);
StorageLive(_13);
_13 = copy _12;
StorageDead(_8);
StorageDead(_3);
_14 = Rev::<std::slice::Iter<'_, T>> { iter: copy _13 };
StorageDead(_13);
StorageLive(_15);
_15 = copy _14;
goto -> bb4;
}
bb4: {
StorageLive(_15);
StorageLive(_14);
_14 = &mut (_13.0: std::slice::Iter<'_, T>);
_15 = <std::slice::Iter<'_, T> as DoubleEndedIterator>::next_back(move _14) -> [return: bb5, unwind: bb11];
StorageLive(_17);
StorageLive(_16);
_16 = &mut (_15.0: std::slice::Iter<'_, T>);
_17 = <std::slice::Iter<'_, T> as DoubleEndedIterator>::next_back(move _16) -> [return: bb5, unwind: bb11];
}
bb5: {
StorageDead(_14);
_16 = discriminant(_15);
switchInt(move _16) -> [0: bb6, 1: bb8, otherwise: bb10];
StorageDead(_16);
_18 = discriminant(_17);
switchInt(move _18) -> [0: bb6, 1: bb8, otherwise: bb10];
}
bb6: {
StorageDead(_17);
StorageDead(_15);
StorageDead(_13);
drop(_2) -> [return: bb7, unwind continue];
}
@ -132,18 +140,18 @@ fn reverse_loop(_1: &[T], _2: impl Fn(&T)) -> () {
}
bb8: {
_17 = copy ((_15 as Some).0: &T);
StorageLive(_18);
_18 = &_2;
StorageLive(_19);
_19 = (copy _17,);
_20 = <impl Fn(&T) as Fn<(&T,)>>::call(move _18, move _19) -> [return: bb9, unwind: bb11];
_19 = copy ((_17 as Some).0: &T);
StorageLive(_20);
_20 = &_2;
StorageLive(_21);
_21 = (copy _19,);
_22 = <impl Fn(&T) as Fn<(&T,)>>::call(move _20, move _21) -> [return: bb9, unwind: bb11];
}
bb9: {
StorageDead(_19);
StorageDead(_18);
StorageDead(_15);
StorageDead(_21);
StorageDead(_20);
StorageDead(_17);
goto -> bb4;
}

View File

@ -15,11 +15,11 @@ fn slice_iter_generic_is_empty(_1: &std::slice::Iter<'_, T>) -> bool {
scope 4 {
scope 8 (inlined <NonNull<T> as PartialEq>::eq) {
let mut _5: std::ptr::NonNull<T>;
let mut _6: *mut T;
let mut _7: *mut T;
scope 9 (inlined NonNull::<T>::as_ptr) {
let mut _6: *const T;
}
scope 10 (inlined NonNull::<T>::as_ptr) {
let mut _7: *const T;
}
}
}
@ -48,13 +48,13 @@ fn slice_iter_generic_is_empty(_1: &std::slice::Iter<'_, T>) -> bool {
_4 = copy (*_3);
StorageDead(_3);
StorageLive(_6);
StorageLive(_7);
StorageLive(_5);
_5 = copy ((*_1).0: std::ptr::NonNull<T>);
_6 = copy (_5.0: *const T);
_6 = copy _5 as *mut T (Transmute);
StorageDead(_5);
_7 = copy (_4.0: *const T);
_0 = Eq(copy _6, copy _7);
StorageLive(_7);
_7 = copy _4 as *mut T (Transmute);
_0 = Eq(move _6, move _7);
StorageDead(_7);
StorageDead(_6);
goto -> bb3;

View File

@ -15,11 +15,11 @@ fn slice_iter_generic_is_empty(_1: &std::slice::Iter<'_, T>) -> bool {
scope 4 {
scope 8 (inlined <NonNull<T> as PartialEq>::eq) {
let mut _5: std::ptr::NonNull<T>;
let mut _6: *mut T;
let mut _7: *mut T;
scope 9 (inlined NonNull::<T>::as_ptr) {
let mut _6: *const T;
}
scope 10 (inlined NonNull::<T>::as_ptr) {
let mut _7: *const T;
}
}
}
@ -48,13 +48,13 @@ fn slice_iter_generic_is_empty(_1: &std::slice::Iter<'_, T>) -> bool {
_4 = copy (*_3);
StorageDead(_3);
StorageLive(_6);
StorageLive(_7);
StorageLive(_5);
_5 = copy ((*_1).0: std::ptr::NonNull<T>);
_6 = copy (_5.0: *const T);
_6 = copy _5 as *mut T (Transmute);
StorageDead(_5);
_7 = copy (_4.0: *const T);
_0 = Eq(copy _6, copy _7);
StorageLive(_7);
_7 = copy _4 as *mut T (Transmute);
_0 = Eq(move _6, move _7);
StorageDead(_7);
StorageDead(_6);
goto -> bb3;

View File

@ -7,16 +7,18 @@ fn vec_deref_to_slice(_1: &Vec<u8>) -> &[u8] {
debug self => _1;
scope 2 (inlined Vec::<u8>::as_slice) {
debug self => _1;
let mut _7: usize;
let mut _9: *const u8;
let mut _10: usize;
scope 3 (inlined Vec::<u8>::as_ptr) {
debug self => _1;
let mut _2: &alloc::raw_vec::RawVec<u8>;
let mut _8: *mut u8;
scope 4 (inlined alloc::raw_vec::RawVec::<u8>::ptr) {
debug self => _2;
let mut _3: &alloc::raw_vec::RawVecInner;
scope 5 (inlined alloc::raw_vec::RawVecInner::ptr::<u8>) {
debug self => _3;
let mut _6: std::ptr::NonNull<u8>;
let mut _7: std::ptr::NonNull<u8>;
scope 6 (inlined alloc::raw_vec::RawVecInner::non_null::<u8>) {
debug self => _3;
let mut _4: std::ptr::NonNull<u8>;
@ -25,27 +27,28 @@ fn vec_deref_to_slice(_1: &Vec<u8>) -> &[u8] {
debug ((self: Unique<u8>).1: std::marker::PhantomData<u8>) => const PhantomData::<u8>;
scope 8 (inlined NonNull::<u8>::cast::<u8>) {
debug self => _4;
let mut _5: *mut u8;
let mut _6: *const u8;
scope 9 (inlined NonNull::<u8>::as_ptr) {
debug self => _4;
let mut _5: *const u8;
}
}
}
scope 10 (inlined Unique::<u8>::as_non_null_ptr) {
debug ((self: Unique<u8>).0: std::ptr::NonNull<u8>) => _6;
debug ((self: Unique<u8>).0: std::ptr::NonNull<u8>) => _7;
debug ((self: Unique<u8>).1: std::marker::PhantomData<u8>) => const PhantomData::<u8>;
}
}
scope 11 (inlined NonNull::<u8>::as_ptr) {
debug self => _6;
debug self => _7;
}
}
}
}
scope 12 (inlined std::slice::from_raw_parts::<'_, u8>) {
debug data => _5;
debug len => _7;
let _8: *const [u8];
debug data => _9;
debug len => _10;
let _11: *const [u8];
scope 13 (inlined core::ub_checks::check_language_ub) {
scope 14 (inlined core::ub_checks::check_language_ub::runtime) {
}
@ -55,11 +58,11 @@ fn vec_deref_to_slice(_1: &Vec<u8>) -> &[u8] {
scope 16 (inlined align_of::<u8>) {
}
scope 17 (inlined slice_from_raw_parts::<u8>) {
debug data => _5;
debug len => _7;
debug data => _9;
debug len => _10;
scope 18 (inlined std::ptr::from_raw_parts::<[u8], u8>) {
debug data_pointer => _5;
debug metadata => _7;
debug data_pointer => _9;
debug metadata => _10;
}
}
}
@ -67,26 +70,37 @@ fn vec_deref_to_slice(_1: &Vec<u8>) -> &[u8] {
}
bb0: {
StorageLive(_8);
StorageLive(_9);
StorageLive(_2);
_2 = &((*_1).0: alloc::raw_vec::RawVec<u8>);
StorageLive(_3);
_3 = &(((*_1).0: alloc::raw_vec::RawVec<u8>).0: alloc::raw_vec::RawVecInner);
StorageLive(_6);
StorageLive(_7);
StorageLive(_4);
_4 = copy (((((*_1).0: alloc::raw_vec::RawVec<u8>).0: alloc::raw_vec::RawVecInner).0: std::ptr::Unique<u8>).0: std::ptr::NonNull<u8>);
_5 = copy (_4.0: *const u8);
_6 = NonNull::<u8> { pointer: copy _5 };
StorageDead(_4);
StorageLive(_5);
StorageLive(_6);
_5 = copy _4 as *mut u8 (Transmute);
_6 = copy _5 as *const u8 (PtrToPtr);
_7 = NonNull::<u8> { pointer: move _6 };
StorageDead(_6);
StorageDead(_3);
StorageDead(_2);
StorageLive(_7);
_7 = copy ((*_1).1: usize);
StorageLive(_8);
_8 = *const [u8] from (copy _5, copy _7);
_0 = &(*_8);
StorageDead(_8);
StorageDead(_5);
StorageDead(_4);
_8 = copy _7 as *mut u8 (Transmute);
StorageDead(_7);
StorageDead(_3);
_9 = copy _8 as *const u8 (PtrToPtr);
StorageDead(_2);
StorageLive(_10);
_10 = copy ((*_1).1: usize);
StorageLive(_11);
_11 = *const [u8] from (copy _9, copy _10);
_0 = &(*_11);
StorageDead(_11);
StorageDead(_10);
StorageDead(_9);
StorageDead(_8);
return;
}
}

View File

@ -7,16 +7,18 @@ fn vec_deref_to_slice(_1: &Vec<u8>) -> &[u8] {
debug self => _1;
scope 2 (inlined Vec::<u8>::as_slice) {
debug self => _1;
let mut _7: usize;
let mut _9: *const u8;
let mut _10: usize;
scope 3 (inlined Vec::<u8>::as_ptr) {
debug self => _1;
let mut _2: &alloc::raw_vec::RawVec<u8>;
let mut _8: *mut u8;
scope 4 (inlined alloc::raw_vec::RawVec::<u8>::ptr) {
debug self => _2;
let mut _3: &alloc::raw_vec::RawVecInner;
scope 5 (inlined alloc::raw_vec::RawVecInner::ptr::<u8>) {
debug self => _3;
let mut _6: std::ptr::NonNull<u8>;
let mut _7: std::ptr::NonNull<u8>;
scope 6 (inlined alloc::raw_vec::RawVecInner::non_null::<u8>) {
debug self => _3;
let mut _4: std::ptr::NonNull<u8>;
@ -25,27 +27,28 @@ fn vec_deref_to_slice(_1: &Vec<u8>) -> &[u8] {
debug ((self: Unique<u8>).1: std::marker::PhantomData<u8>) => const PhantomData::<u8>;
scope 8 (inlined NonNull::<u8>::cast::<u8>) {
debug self => _4;
let mut _5: *mut u8;
let mut _6: *const u8;
scope 9 (inlined NonNull::<u8>::as_ptr) {
debug self => _4;
let mut _5: *const u8;
}
}
}
scope 10 (inlined Unique::<u8>::as_non_null_ptr) {
debug ((self: Unique<u8>).0: std::ptr::NonNull<u8>) => _6;
debug ((self: Unique<u8>).0: std::ptr::NonNull<u8>) => _7;
debug ((self: Unique<u8>).1: std::marker::PhantomData<u8>) => const PhantomData::<u8>;
}
}
scope 11 (inlined NonNull::<u8>::as_ptr) {
debug self => _6;
debug self => _7;
}
}
}
}
scope 12 (inlined std::slice::from_raw_parts::<'_, u8>) {
debug data => _5;
debug len => _7;
let _8: *const [u8];
debug data => _9;
debug len => _10;
let _11: *const [u8];
scope 13 (inlined core::ub_checks::check_language_ub) {
scope 14 (inlined core::ub_checks::check_language_ub::runtime) {
}
@ -55,11 +58,11 @@ fn vec_deref_to_slice(_1: &Vec<u8>) -> &[u8] {
scope 16 (inlined align_of::<u8>) {
}
scope 17 (inlined slice_from_raw_parts::<u8>) {
debug data => _5;
debug len => _7;
debug data => _9;
debug len => _10;
scope 18 (inlined std::ptr::from_raw_parts::<[u8], u8>) {
debug data_pointer => _5;
debug metadata => _7;
debug data_pointer => _9;
debug metadata => _10;
}
}
}
@ -67,26 +70,37 @@ fn vec_deref_to_slice(_1: &Vec<u8>) -> &[u8] {
}
bb0: {
StorageLive(_8);
StorageLive(_9);
StorageLive(_2);
_2 = &((*_1).0: alloc::raw_vec::RawVec<u8>);
StorageLive(_3);
_3 = &(((*_1).0: alloc::raw_vec::RawVec<u8>).0: alloc::raw_vec::RawVecInner);
StorageLive(_6);
StorageLive(_7);
StorageLive(_4);
_4 = copy (((((*_1).0: alloc::raw_vec::RawVec<u8>).0: alloc::raw_vec::RawVecInner).0: std::ptr::Unique<u8>).0: std::ptr::NonNull<u8>);
_5 = copy (_4.0: *const u8);
_6 = NonNull::<u8> { pointer: copy _5 };
StorageDead(_4);
StorageLive(_5);
StorageLive(_6);
_5 = copy _4 as *mut u8 (Transmute);
_6 = copy _5 as *const u8 (PtrToPtr);
_7 = NonNull::<u8> { pointer: move _6 };
StorageDead(_6);
StorageDead(_3);
StorageDead(_2);
StorageLive(_7);
_7 = copy ((*_1).1: usize);
StorageLive(_8);
_8 = *const [u8] from (copy _5, copy _7);
_0 = &(*_8);
StorageDead(_8);
StorageDead(_5);
StorageDead(_4);
_8 = copy _7 as *mut u8 (Transmute);
StorageDead(_7);
StorageDead(_3);
_9 = copy _8 as *const u8 (PtrToPtr);
StorageDead(_2);
StorageLive(_10);
_10 = copy ((*_1).1: usize);
StorageLive(_11);
_11 = *const [u8] from (copy _9, copy _10);
_0 = &(*_11);
StorageDead(_11);
StorageDead(_10);
StorageDead(_9);
StorageDead(_8);
return;
}
}