Ban ArrayToPointer
and MutToConstPointer
from runtime MIR
Apparently MIR borrowck cares about at least one of these for checking variance. In runtime MIR, though, there's no need for them as `PtrToPtr` does the same thing. (Banning them simplifies passes like GVN that no longer need to handle multiple cast possibilities.)
This commit is contained in:
parent
894f7a4ba6
commit
4630d1b23b
@ -127,6 +127,9 @@ pub enum AnalysisPhase {
|
|||||||
/// * [`StatementKind::AscribeUserType`]
|
/// * [`StatementKind::AscribeUserType`]
|
||||||
/// * [`StatementKind::Coverage`] with [`CoverageKind::BlockMarker`] or [`CoverageKind::SpanMarker`]
|
/// * [`StatementKind::Coverage`] with [`CoverageKind::BlockMarker`] or [`CoverageKind::SpanMarker`]
|
||||||
/// * [`Rvalue::Ref`] with `BorrowKind::Fake`
|
/// * [`Rvalue::Ref`] with `BorrowKind::Fake`
|
||||||
|
/// * [`CastKind::PointerCoercion`] with any of the following:
|
||||||
|
/// * [`PointerCoercion::ArrayToPointer`]
|
||||||
|
/// * [`PointerCoercion::MutToConstPointer`]
|
||||||
///
|
///
|
||||||
/// Furthermore, `Deref` projections must be the first projection within any place (if they
|
/// Furthermore, `Deref` projections must be the first projection within any place (if they
|
||||||
/// appear at all)
|
/// appear at all)
|
||||||
@ -1284,8 +1287,7 @@ pub enum Rvalue<'tcx> {
|
|||||||
///
|
///
|
||||||
/// This allows for casts from/to a variety of types.
|
/// This allows for casts from/to a variety of types.
|
||||||
///
|
///
|
||||||
/// **FIXME**: Document exactly which `CastKind`s allow which types of casts. Figure out why
|
/// **FIXME**: Document exactly which `CastKind`s allow which types of casts.
|
||||||
/// `ArrayToPointer` and `MutToConstPointer` are special.
|
|
||||||
Cast(CastKind, Operand<'tcx>, Ty<'tcx>),
|
Cast(CastKind, Operand<'tcx>, Ty<'tcx>),
|
||||||
|
|
||||||
/// * `Offset` has the same semantics as [`offset`](pointer::offset), except that the second
|
/// * `Offset` has the same semantics as [`offset`](pointer::offset), except that the second
|
||||||
@ -1365,6 +1367,13 @@ pub enum CastKind {
|
|||||||
PointerWithExposedProvenance,
|
PointerWithExposedProvenance,
|
||||||
/// Pointer related casts that are done by coercions. Note that reference-to-raw-ptr casts are
|
/// Pointer related casts that are done by coercions. Note that reference-to-raw-ptr casts are
|
||||||
/// translated into `&raw mut/const *r`, i.e., they are not actually casts.
|
/// translated into `&raw mut/const *r`, i.e., they are not actually casts.
|
||||||
|
///
|
||||||
|
/// The following are allowed in [`AnalysisPhase::Initial`] as they're needed for borrowck,
|
||||||
|
/// but after that are forbidden (including in all phases of runtime MIR):
|
||||||
|
/// * [`PointerCoercion::ArrayToPointer`]
|
||||||
|
/// * [`PointerCoercion::MutToConstPointer`]
|
||||||
|
///
|
||||||
|
/// Both are runtime nops, so should be [`CastKind::PtrToPtr`] instead in runtime MIR.
|
||||||
PointerCoercion(PointerCoercion),
|
PointerCoercion(PointerCoercion),
|
||||||
/// Cast into a dyn* object.
|
/// Cast into a dyn* object.
|
||||||
DynStar,
|
DynStar,
|
||||||
|
@ -18,7 +18,8 @@
|
|||||||
|
|
||||||
use crate::MirPass;
|
use crate::MirPass;
|
||||||
use rustc_middle::mir::coverage::CoverageKind;
|
use rustc_middle::mir::coverage::CoverageKind;
|
||||||
use rustc_middle::mir::{Body, BorrowKind, Rvalue, StatementKind, TerminatorKind};
|
use rustc_middle::mir::{Body, BorrowKind, CastKind, Rvalue, StatementKind, TerminatorKind};
|
||||||
|
use rustc_middle::ty::adjustment::PointerCoercion;
|
||||||
use rustc_middle::ty::TyCtxt;
|
use rustc_middle::ty::TyCtxt;
|
||||||
|
|
||||||
pub struct CleanupPostBorrowck;
|
pub struct CleanupPostBorrowck;
|
||||||
@ -36,6 +37,22 @@ fn run_pass(&self, _tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
|
|||||||
CoverageKind::BlockMarker { .. } | CoverageKind::SpanMarker { .. },
|
CoverageKind::BlockMarker { .. } | CoverageKind::SpanMarker { .. },
|
||||||
)
|
)
|
||||||
| StatementKind::FakeRead(..) => statement.make_nop(),
|
| StatementKind::FakeRead(..) => statement.make_nop(),
|
||||||
|
StatementKind::Assign(box (
|
||||||
|
_,
|
||||||
|
Rvalue::Cast(
|
||||||
|
ref mut cast_kind @ CastKind::PointerCoercion(
|
||||||
|
PointerCoercion::ArrayToPointer
|
||||||
|
| PointerCoercion::MutToConstPointer,
|
||||||
|
),
|
||||||
|
..,
|
||||||
|
),
|
||||||
|
)) => {
|
||||||
|
// BorrowCk needed to track whether these cases were coercions or casts,
|
||||||
|
// to know whether to check lifetimes in their pointees,
|
||||||
|
// but from now on that distinction doesn't matter,
|
||||||
|
// so just make them ordinary pointer casts instead.
|
||||||
|
*cast_kind = CastKind::PtrToPtr;
|
||||||
|
}
|
||||||
_ => (),
|
_ => (),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -571,11 +571,7 @@ fn eval_to_const(&mut self, value: VnIndex) -> Option<OpTy<'tcx>> {
|
|||||||
let ret = self.ecx.ptr_to_ptr(&src, to).ok()?;
|
let ret = self.ecx.ptr_to_ptr(&src, to).ok()?;
|
||||||
ret.into()
|
ret.into()
|
||||||
}
|
}
|
||||||
CastKind::PointerCoercion(
|
CastKind::PointerCoercion(ty::adjustment::PointerCoercion::UnsafeFnPointer) => {
|
||||||
ty::adjustment::PointerCoercion::MutToConstPointer
|
|
||||||
| ty::adjustment::PointerCoercion::ArrayToPointer
|
|
||||||
| ty::adjustment::PointerCoercion::UnsafeFnPointer,
|
|
||||||
) => {
|
|
||||||
let src = self.evaluated[value].as_ref()?;
|
let src = self.evaluated[value].as_ref()?;
|
||||||
let src = self.ecx.read_immediate(src).ok()?;
|
let src = self.ecx.read_immediate(src).ok()?;
|
||||||
let to = self.ecx.layout_of(to).ok()?;
|
let to = self.ecx.layout_of(to).ok()?;
|
||||||
@ -1164,10 +1160,10 @@ fn simplify_cast(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if let PtrToPtr | PointerCoercion(MutToConstPointer) = kind
|
if let PtrToPtr = kind
|
||||||
&& let Value::Cast { kind: inner_kind, value: inner_value, from: inner_from, to: _ } =
|
&& let Value::Cast { kind: inner_kind, value: inner_value, from: inner_from, to: _ } =
|
||||||
*self.get(value)
|
*self.get(value)
|
||||||
&& let PtrToPtr | PointerCoercion(MutToConstPointer) = inner_kind
|
&& let PtrToPtr = inner_kind
|
||||||
{
|
{
|
||||||
from = inner_from;
|
from = inner_from;
|
||||||
value = inner_value;
|
value = inner_value;
|
||||||
|
@ -51,11 +51,11 @@
|
|||||||
mod add_call_guards;
|
mod add_call_guards;
|
||||||
mod add_moves_for_packed_drops;
|
mod add_moves_for_packed_drops;
|
||||||
mod add_retag;
|
mod add_retag;
|
||||||
|
mod add_subtyping_projections;
|
||||||
|
mod check_alignment;
|
||||||
mod check_const_item_mutation;
|
mod check_const_item_mutation;
|
||||||
mod check_packed_ref;
|
mod check_packed_ref;
|
||||||
mod remove_place_mention;
|
|
||||||
// This pass is public to allow external drivers to perform MIR cleanup
|
// This pass is public to allow external drivers to perform MIR cleanup
|
||||||
mod add_subtyping_projections;
|
|
||||||
pub mod cleanup_post_borrowck;
|
pub mod cleanup_post_borrowck;
|
||||||
mod copy_prop;
|
mod copy_prop;
|
||||||
mod coroutine;
|
mod coroutine;
|
||||||
@ -94,6 +94,7 @@
|
|||||||
mod promote_consts;
|
mod promote_consts;
|
||||||
mod ref_prop;
|
mod ref_prop;
|
||||||
mod remove_noop_landing_pads;
|
mod remove_noop_landing_pads;
|
||||||
|
mod remove_place_mention;
|
||||||
mod remove_storage_markers;
|
mod remove_storage_markers;
|
||||||
mod remove_uninit_drops;
|
mod remove_uninit_drops;
|
||||||
mod remove_unneeded_drops;
|
mod remove_unneeded_drops;
|
||||||
@ -103,7 +104,6 @@
|
|||||||
mod shim;
|
mod shim;
|
||||||
mod ssa;
|
mod ssa;
|
||||||
// This pass is public to allow external drivers to perform MIR cleanup
|
// This pass is public to allow external drivers to perform MIR cleanup
|
||||||
mod check_alignment;
|
|
||||||
pub mod simplify;
|
pub mod simplify;
|
||||||
mod simplify_branches;
|
mod simplify_branches;
|
||||||
mod simplify_comparison_integral;
|
mod simplify_comparison_integral;
|
||||||
|
@ -1188,6 +1188,9 @@ macro_rules! check_kinds {
|
|||||||
"CastKind::{kind:?} output must be a raw const pointer, not {:?}",
|
"CastKind::{kind:?} output must be a raw const pointer, not {:?}",
|
||||||
ty::RawPtr(_, Mutability::Not)
|
ty::RawPtr(_, Mutability::Not)
|
||||||
);
|
);
|
||||||
|
if self.mir_phase >= MirPhase::Analysis(AnalysisPhase::PostCleanup) {
|
||||||
|
self.fail(location, format!("After borrowck, MIR disallows {kind:?}"));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
CastKind::PointerCoercion(PointerCoercion::ArrayToPointer) => {
|
CastKind::PointerCoercion(PointerCoercion::ArrayToPointer) => {
|
||||||
// FIXME: Check pointee types
|
// FIXME: Check pointee types
|
||||||
@ -1201,6 +1204,9 @@ macro_rules! check_kinds {
|
|||||||
"CastKind::{kind:?} output must be a raw pointer, not {:?}",
|
"CastKind::{kind:?} output must be a raw pointer, not {:?}",
|
||||||
ty::RawPtr(..)
|
ty::RawPtr(..)
|
||||||
);
|
);
|
||||||
|
if self.mir_phase >= MirPhase::Analysis(AnalysisPhase::PostCleanup) {
|
||||||
|
self.fail(location, format!("After borrowck, MIR disallows {kind:?}"));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
CastKind::PointerCoercion(PointerCoercion::Unsize) => {
|
CastKind::PointerCoercion(PointerCoercion::Unsize) => {
|
||||||
// This is used for all `CoerceUnsized` types,
|
// This is used for all `CoerceUnsized` types,
|
||||||
@ -1212,7 +1218,7 @@ macro_rules! check_kinds {
|
|||||||
if !input_valid || !target_valid {
|
if !input_valid || !target_valid {
|
||||||
self.fail(
|
self.fail(
|
||||||
location,
|
location,
|
||||||
format!("Wrong cast kind {kind:?} for the type {op_ty}",),
|
format!("Wrong cast kind {kind:?} for the type {op_ty}"),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -80,7 +80,7 @@
|
|||||||
|
|
||||||
bb4: {
|
bb4: {
|
||||||
StorageDead(_8);
|
StorageDead(_8);
|
||||||
- _11 = _6 as *const [bool; 0] (PointerCoercion(MutToConstPointer));
|
- _11 = _6 as *const [bool; 0] (PtrToPtr);
|
||||||
- _5 = NonNull::<[bool; 0]> { pointer: _11 };
|
- _5 = NonNull::<[bool; 0]> { pointer: _11 };
|
||||||
+ _11 = const {0x1 as *const [bool; 0]};
|
+ _11 = const {0x1 as *const [bool; 0]};
|
||||||
+ _5 = const NonNull::<[bool; 0]> {{ pointer: {0x1 as *const [bool; 0]} }};
|
+ _5 = const NonNull::<[bool; 0]> {{ pointer: {0x1 as *const [bool; 0]} }};
|
||||||
|
@ -84,7 +84,7 @@
|
|||||||
|
|
||||||
bb5: {
|
bb5: {
|
||||||
StorageDead(_8);
|
StorageDead(_8);
|
||||||
- _11 = _6 as *const [bool; 0] (PointerCoercion(MutToConstPointer));
|
- _11 = _6 as *const [bool; 0] (PtrToPtr);
|
||||||
- _5 = NonNull::<[bool; 0]> { pointer: _11 };
|
- _5 = NonNull::<[bool; 0]> { pointer: _11 };
|
||||||
+ _11 = const {0x1 as *const [bool; 0]};
|
+ _11 = const {0x1 as *const [bool; 0]};
|
||||||
+ _5 = const NonNull::<[bool; 0]> {{ pointer: {0x1 as *const [bool; 0]} }};
|
+ _5 = const NonNull::<[bool; 0]> {{ pointer: {0x1 as *const [bool; 0]} }};
|
||||||
|
@ -80,7 +80,7 @@
|
|||||||
|
|
||||||
bb4: {
|
bb4: {
|
||||||
StorageDead(_8);
|
StorageDead(_8);
|
||||||
- _11 = _6 as *const [bool; 0] (PointerCoercion(MutToConstPointer));
|
- _11 = _6 as *const [bool; 0] (PtrToPtr);
|
||||||
- _5 = NonNull::<[bool; 0]> { pointer: _11 };
|
- _5 = NonNull::<[bool; 0]> { pointer: _11 };
|
||||||
+ _11 = const {0x1 as *const [bool; 0]};
|
+ _11 = const {0x1 as *const [bool; 0]};
|
||||||
+ _5 = const NonNull::<[bool; 0]> {{ pointer: {0x1 as *const [bool; 0]} }};
|
+ _5 = const NonNull::<[bool; 0]> {{ pointer: {0x1 as *const [bool; 0]} }};
|
||||||
|
@ -84,7 +84,7 @@
|
|||||||
|
|
||||||
bb5: {
|
bb5: {
|
||||||
StorageDead(_8);
|
StorageDead(_8);
|
||||||
- _11 = _6 as *const [bool; 0] (PointerCoercion(MutToConstPointer));
|
- _11 = _6 as *const [bool; 0] (PtrToPtr);
|
||||||
- _5 = NonNull::<[bool; 0]> { pointer: _11 };
|
- _5 = NonNull::<[bool; 0]> { pointer: _11 };
|
||||||
+ _11 = const {0x1 as *const [bool; 0]};
|
+ _11 = const {0x1 as *const [bool; 0]};
|
||||||
+ _5 = const NonNull::<[bool; 0]> {{ pointer: {0x1 as *const [bool; 0]} }};
|
+ _5 = const NonNull::<[bool; 0]> {{ pointer: {0x1 as *const [bool; 0]} }};
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
StorageLive(_4);
|
StorageLive(_4);
|
||||||
_4 = _1;
|
_4 = _1;
|
||||||
_3 = move _4 as *mut u8 (PtrToPtr);
|
_3 = move _4 as *mut u8 (PtrToPtr);
|
||||||
_2 = move _3 as *const u8 (PointerCoercion(MutToConstPointer));
|
_2 = move _3 as *const u8 (PtrToPtr);
|
||||||
StorageDead(_4);
|
StorageDead(_4);
|
||||||
StorageDead(_3);
|
StorageDead(_3);
|
||||||
- _0 = move _2 as *const u8 (PtrToPtr);
|
- _0 = move _2 as *const u8 (PtrToPtr);
|
||||||
|
@ -21,7 +21,7 @@ pub fn roundtrip(x: *const u8) -> *const u8 {
|
|||||||
// CHECK-LABEL: fn roundtrip(
|
// CHECK-LABEL: fn roundtrip(
|
||||||
// CHECK: _4 = _1;
|
// CHECK: _4 = _1;
|
||||||
// CHECK: _3 = move _4 as *mut u8 (PtrToPtr);
|
// CHECK: _3 = move _4 as *mut u8 (PtrToPtr);
|
||||||
// CHECK: _2 = move _3 as *const u8 (PointerCoercion(MutToConstPointer));
|
// CHECK: _2 = move _3 as *const u8 (PtrToPtr);
|
||||||
x as *mut u8 as *const u8
|
x as *mut u8 as *const u8
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -41,7 +41,7 @@ fn slice_get_unchecked_mut_range(_1: &mut [u32], _2: std::ops::Range<usize>) ->
|
|||||||
StorageLive(_9);
|
StorageLive(_9);
|
||||||
StorageLive(_7);
|
StorageLive(_7);
|
||||||
StorageLive(_6);
|
StorageLive(_6);
|
||||||
_6 = _5 as *const [u32] (PointerCoercion(MutToConstPointer));
|
_6 = _5 as *const [u32] (PtrToPtr);
|
||||||
_7 = PtrMetadata(_6);
|
_7 = PtrMetadata(_6);
|
||||||
StorageDead(_6);
|
StorageDead(_6);
|
||||||
_8 = <std::ops::Range<usize> as SliceIndex<[T]>>::get_unchecked_mut::precondition_check(_3, _4, move _7) -> [return: bb1, unwind unreachable];
|
_8 = <std::ops::Range<usize> as SliceIndex<[T]>>::get_unchecked_mut::precondition_check(_3, _4, move _7) -> [return: bb1, unwind unreachable];
|
||||||
|
@ -41,7 +41,7 @@ fn slice_get_unchecked_mut_range(_1: &mut [u32], _2: std::ops::Range<usize>) ->
|
|||||||
StorageLive(_9);
|
StorageLive(_9);
|
||||||
StorageLive(_7);
|
StorageLive(_7);
|
||||||
StorageLive(_6);
|
StorageLive(_6);
|
||||||
_6 = _5 as *const [u32] (PointerCoercion(MutToConstPointer));
|
_6 = _5 as *const [u32] (PtrToPtr);
|
||||||
_7 = PtrMetadata(_6);
|
_7 = PtrMetadata(_6);
|
||||||
StorageDead(_6);
|
StorageDead(_6);
|
||||||
_8 = <std::ops::Range<usize> as SliceIndex<[T]>>::get_unchecked_mut::precondition_check(_3, _4, move _7) -> [return: bb1, unwind unreachable];
|
_8 = <std::ops::Range<usize> as SliceIndex<[T]>>::get_unchecked_mut::precondition_check(_3, _4, move _7) -> [return: bb1, unwind unreachable];
|
||||||
|
@ -79,7 +79,7 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () {
|
|||||||
_7 = _4 as *mut T (PtrToPtr);
|
_7 = _4 as *mut T (PtrToPtr);
|
||||||
_8 = Offset(_7, _3);
|
_8 = Offset(_7, _3);
|
||||||
StorageDead(_7);
|
StorageDead(_7);
|
||||||
_9 = move _8 as *const T (PointerCoercion(MutToConstPointer));
|
_9 = move _8 as *const T (PtrToPtr);
|
||||||
StorageDead(_8);
|
StorageDead(_8);
|
||||||
goto -> bb3;
|
goto -> bb3;
|
||||||
}
|
}
|
||||||
|
@ -79,7 +79,7 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () {
|
|||||||
_7 = _4 as *mut T (PtrToPtr);
|
_7 = _4 as *mut T (PtrToPtr);
|
||||||
_8 = Offset(_7, _3);
|
_8 = Offset(_7, _3);
|
||||||
StorageDead(_7);
|
StorageDead(_7);
|
||||||
_9 = move _8 as *const T (PointerCoercion(MutToConstPointer));
|
_9 = move _8 as *const T (PtrToPtr);
|
||||||
StorageDead(_8);
|
StorageDead(_8);
|
||||||
goto -> bb3;
|
goto -> bb3;
|
||||||
}
|
}
|
||||||
|
@ -71,7 +71,7 @@ fn forward_loop(_1: &[T], _2: impl Fn(&T)) -> () {
|
|||||||
_7 = _4 as *mut T (PtrToPtr);
|
_7 = _4 as *mut T (PtrToPtr);
|
||||||
_8 = Offset(_7, _3);
|
_8 = Offset(_7, _3);
|
||||||
StorageDead(_7);
|
StorageDead(_7);
|
||||||
_9 = move _8 as *const T (PointerCoercion(MutToConstPointer));
|
_9 = move _8 as *const T (PtrToPtr);
|
||||||
StorageDead(_8);
|
StorageDead(_8);
|
||||||
goto -> bb3;
|
goto -> bb3;
|
||||||
}
|
}
|
||||||
|
@ -71,7 +71,7 @@ fn forward_loop(_1: &[T], _2: impl Fn(&T)) -> () {
|
|||||||
_7 = _4 as *mut T (PtrToPtr);
|
_7 = _4 as *mut T (PtrToPtr);
|
||||||
_8 = Offset(_7, _3);
|
_8 = Offset(_7, _3);
|
||||||
StorageDead(_7);
|
StorageDead(_7);
|
||||||
_9 = move _8 as *const T (PointerCoercion(MutToConstPointer));
|
_9 = move _8 as *const T (PtrToPtr);
|
||||||
StorageDead(_8);
|
StorageDead(_8);
|
||||||
goto -> bb3;
|
goto -> bb3;
|
||||||
}
|
}
|
||||||
|
@ -79,7 +79,7 @@ fn reverse_loop(_1: &[T], _2: impl Fn(&T)) -> () {
|
|||||||
_7 = _4 as *mut T (PtrToPtr);
|
_7 = _4 as *mut T (PtrToPtr);
|
||||||
_8 = Offset(_7, _3);
|
_8 = Offset(_7, _3);
|
||||||
StorageDead(_7);
|
StorageDead(_7);
|
||||||
_9 = move _8 as *const T (PointerCoercion(MutToConstPointer));
|
_9 = move _8 as *const T (PtrToPtr);
|
||||||
StorageDead(_8);
|
StorageDead(_8);
|
||||||
goto -> bb3;
|
goto -> bb3;
|
||||||
}
|
}
|
||||||
|
@ -79,7 +79,7 @@ fn reverse_loop(_1: &[T], _2: impl Fn(&T)) -> () {
|
|||||||
_7 = _4 as *mut T (PtrToPtr);
|
_7 = _4 as *mut T (PtrToPtr);
|
||||||
_8 = Offset(_7, _3);
|
_8 = Offset(_7, _3);
|
||||||
StorageDead(_7);
|
StorageDead(_7);
|
||||||
_9 = move _8 as *const T (PointerCoercion(MutToConstPointer));
|
_9 = move _8 as *const T (PtrToPtr);
|
||||||
StorageDead(_8);
|
StorageDead(_8);
|
||||||
goto -> bb3;
|
goto -> bb3;
|
||||||
}
|
}
|
||||||
|
@ -64,7 +64,7 @@ fn array_casts() -> () {
|
|||||||
StorageLive(_4);
|
StorageLive(_4);
|
||||||
_4 = &mut _1;
|
_4 = &mut _1;
|
||||||
_3 = &raw mut (*_4);
|
_3 = &raw mut (*_4);
|
||||||
_2 = move _3 as *mut usize (PointerCoercion(ArrayToPointer));
|
_2 = move _3 as *mut usize (PtrToPtr);
|
||||||
StorageDead(_3);
|
StorageDead(_3);
|
||||||
StorageDead(_4);
|
StorageDead(_4);
|
||||||
StorageLive(_5);
|
StorageLive(_5);
|
||||||
@ -87,7 +87,7 @@ fn array_casts() -> () {
|
|||||||
StorageLive(_11);
|
StorageLive(_11);
|
||||||
_11 = &_8;
|
_11 = &_8;
|
||||||
_10 = &raw const (*_11);
|
_10 = &raw const (*_11);
|
||||||
_9 = move _10 as *const usize (PointerCoercion(ArrayToPointer));
|
_9 = move _10 as *const usize (PtrToPtr);
|
||||||
StorageDead(_10);
|
StorageDead(_10);
|
||||||
StorageDead(_11);
|
StorageDead(_11);
|
||||||
StorageLive(_12);
|
StorageLive(_12);
|
||||||
|
@ -64,7 +64,7 @@ fn array_casts() -> () {
|
|||||||
StorageLive(_4);
|
StorageLive(_4);
|
||||||
_4 = &mut _1;
|
_4 = &mut _1;
|
||||||
_3 = &raw mut (*_4);
|
_3 = &raw mut (*_4);
|
||||||
_2 = move _3 as *mut usize (PointerCoercion(ArrayToPointer));
|
_2 = move _3 as *mut usize (PtrToPtr);
|
||||||
StorageDead(_3);
|
StorageDead(_3);
|
||||||
StorageDead(_4);
|
StorageDead(_4);
|
||||||
StorageLive(_5);
|
StorageLive(_5);
|
||||||
@ -87,7 +87,7 @@ fn array_casts() -> () {
|
|||||||
StorageLive(_11);
|
StorageLive(_11);
|
||||||
_11 = &_8;
|
_11 = &_8;
|
||||||
_10 = &raw const (*_11);
|
_10 = &raw const (*_11);
|
||||||
_9 = move _10 as *const usize (PointerCoercion(ArrayToPointer));
|
_9 = move _10 as *const usize (PtrToPtr);
|
||||||
StorageDead(_10);
|
StorageDead(_10);
|
||||||
StorageDead(_11);
|
StorageDead(_11);
|
||||||
StorageLive(_12);
|
StorageLive(_12);
|
||||||
|
Loading…
Reference in New Issue
Block a user