Skip to content

Commit 55fc6bd

Browse files
committed
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.)
1 parent 9a7bf4a commit 55fc6bd

19 files changed

+58
-30
lines changed

compiler/rustc_middle/src/mir/syntax.rs

+11-2
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,9 @@ pub enum AnalysisPhase {
127127
/// * [`StatementKind::AscribeUserType`]
128128
/// * [`StatementKind::Coverage`] with [`CoverageKind::BlockMarker`] or [`CoverageKind::SpanMarker`]
129129
/// * [`Rvalue::Ref`] with `BorrowKind::Fake`
130+
/// * [`CastKind::PointerCoercion`] with any of the following:
131+
/// * [`PointerCoercion::ArrayToPointer`]
132+
/// * [`PointerCoercion::MutToConstPointer`]
130133
///
131134
/// Furthermore, `Deref` projections must be the first projection within any place (if they
132135
/// appear at all)
@@ -1281,8 +1284,7 @@ pub enum Rvalue<'tcx> {
12811284
///
12821285
/// This allows for casts from/to a variety of types.
12831286
///
1284-
/// **FIXME**: Document exactly which `CastKind`s allow which types of casts. Figure out why
1285-
/// `ArrayToPointer` and `MutToConstPointer` are special.
1287+
/// **FIXME**: Document exactly which `CastKind`s allow which types of casts.
12861288
Cast(CastKind, Operand<'tcx>, Ty<'tcx>),
12871289

12881290
/// * `Offset` has the same semantics as [`offset`](pointer::offset), except that the second
@@ -1362,6 +1364,13 @@ pub enum CastKind {
13621364
PointerWithExposedProvenance,
13631365
/// Pointer related casts that are done by coercions. Note that reference-to-raw-ptr casts are
13641366
/// translated into `&raw mut/const *r`, i.e., they are not actually casts.
1367+
///
1368+
/// The following are allowed in [`AnalysisPhase::Initial`] as they're needed for borrowck,
1369+
/// but after that are forbidden (including in all phases of runtime MIR):
1370+
/// * [`PointerCoercion::ArrayToPointer`]
1371+
/// * [`PointerCoercion::MutToConstPointer`]
1372+
///
1373+
/// Both are runtime nops, so should be [`CastKind::PtrToPtr`] instead in runtime MIR.
13651374
PointerCoercion(PointerCoercion),
13661375
/// Cast into a dyn* object.
13671376
DynStar,

compiler/rustc_mir_transform/src/cleanup_post_borrowck.rs

+18-1
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,8 @@
1818
1919
use crate::MirPass;
2020
use rustc_middle::mir::coverage::CoverageKind;
21-
use rustc_middle::mir::{Body, BorrowKind, Rvalue, StatementKind, TerminatorKind};
21+
use rustc_middle::mir::{Body, BorrowKind, CastKind, Rvalue, StatementKind, TerminatorKind};
22+
use rustc_middle::ty::adjustment::PointerCoercion;
2223
use rustc_middle::ty::TyCtxt;
2324

2425
pub struct CleanupPostBorrowck;
@@ -36,6 +37,22 @@ impl<'tcx> MirPass<'tcx> for CleanupPostBorrowck {
3637
CoverageKind::BlockMarker { .. } | CoverageKind::SpanMarker { .. },
3738
)
3839
| StatementKind::FakeRead(..) => statement.make_nop(),
40+
StatementKind::Assign(box (
41+
_,
42+
Rvalue::Cast(
43+
ref mut cast_kind @ CastKind::PointerCoercion(
44+
PointerCoercion::ArrayToPointer
45+
| PointerCoercion::MutToConstPointer,
46+
),
47+
..,
48+
),
49+
)) => {
50+
// BorrowCk needed to track whether these cases were coercions or casts,
51+
// to know whether to check lifetimes in their pointees,
52+
// but from now on that distinction doesn't matter,
53+
// so just make them ordinary pointer casts instead.
54+
*cast_kind = CastKind::PtrToPtr;
55+
}
3956
_ => (),
4057
}
4158
}

compiler/rustc_mir_transform/src/gvn.rs

+3-7
Original file line numberDiff line numberDiff line change
@@ -572,11 +572,7 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
572572
let ret = self.ecx.ptr_to_ptr(&src, to).ok()?;
573573
ret.into()
574574
}
575-
CastKind::PointerCoercion(
576-
ty::adjustment::PointerCoercion::MutToConstPointer
577-
| ty::adjustment::PointerCoercion::ArrayToPointer
578-
| ty::adjustment::PointerCoercion::UnsafeFnPointer,
579-
) => {
575+
CastKind::PointerCoercion(ty::adjustment::PointerCoercion::UnsafeFnPointer) => {
580576
let src = self.evaluated[value].as_ref()?;
581577
let src = self.ecx.read_immediate(src).ok()?;
582578
let to = self.ecx.layout_of(to).ok()?;
@@ -1165,10 +1161,10 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
11651161
}
11661162
}
11671163

1168-
if let PtrToPtr | PointerCoercion(MutToConstPointer) = kind
1164+
if let PtrToPtr = kind
11691165
&& let Value::Cast { kind: inner_kind, value: inner_value, from: inner_from, to: _ } =
11701166
*self.get(value)
1171-
&& let PtrToPtr | PointerCoercion(MutToConstPointer) = inner_kind
1167+
&& let PtrToPtr = inner_kind
11721168
{
11731169
from = inner_from;
11741170
value = inner_value;

compiler/rustc_mir_transform/src/lib.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -49,11 +49,11 @@ mod abort_unwinding_calls;
4949
mod add_call_guards;
5050
mod add_moves_for_packed_drops;
5151
mod add_retag;
52+
mod add_subtyping_projections;
53+
mod check_alignment;
5254
mod check_const_item_mutation;
5355
mod check_packed_ref;
54-
mod remove_place_mention;
5556
// This pass is public to allow external drivers to perform MIR cleanup
56-
mod add_subtyping_projections;
5757
pub mod cleanup_post_borrowck;
5858
mod copy_prop;
5959
mod coroutine;
@@ -92,6 +92,7 @@ mod prettify;
9292
mod promote_consts;
9393
mod ref_prop;
9494
mod remove_noop_landing_pads;
95+
mod remove_place_mention;
9596
mod remove_storage_markers;
9697
mod remove_uninit_drops;
9798
mod remove_unneeded_drops;
@@ -101,7 +102,6 @@ mod reveal_all;
101102
mod shim;
102103
mod ssa;
103104
// This pass is public to allow external drivers to perform MIR cleanup
104-
mod check_alignment;
105105
pub mod simplify;
106106
mod simplify_branches;
107107
mod simplify_comparison_integral;

compiler/rustc_mir_transform/src/validate.rs

+7-1
Original file line numberDiff line numberDiff line change
@@ -1187,6 +1187,9 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
11871187
"CastKind::{kind:?} output must be a raw const pointer, not {:?}",
11881188
ty::RawPtr(_, Mutability::Not)
11891189
);
1190+
if self.mir_phase >= MirPhase::Analysis(AnalysisPhase::PostCleanup) {
1191+
self.fail(location, format!("After borrowck, MIR disallows {kind:?}"));
1192+
}
11901193
}
11911194
CastKind::PointerCoercion(PointerCoercion::ArrayToPointer) => {
11921195
// FIXME: Check pointee types
@@ -1200,6 +1203,9 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
12001203
"CastKind::{kind:?} output must be a raw pointer, not {:?}",
12011204
ty::RawPtr(..)
12021205
);
1206+
if self.mir_phase >= MirPhase::Analysis(AnalysisPhase::PostCleanup) {
1207+
self.fail(location, format!("After borrowck, MIR disallows {kind:?}"));
1208+
}
12031209
}
12041210
CastKind::PointerCoercion(PointerCoercion::Unsize) => {
12051211
// This is used for all `CoerceUnsized` types,
@@ -1211,7 +1217,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
12111217
if !input_valid || !target_valid {
12121218
self.fail(
12131219
location,
1214-
format!("Wrong cast kind {kind:?} for the type {op_ty}",),
1220+
format!("Wrong cast kind {kind:?} for the type {op_ty}"),
12151221
);
12161222
}
12171223
}

tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.32bit.panic-abort.diff

+1-1
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@
8080

8181
bb4: {
8282
StorageDead(_8);
83-
- _11 = _6 as *const [bool; 0] (PointerCoercion(MutToConstPointer));
83+
- _11 = _6 as *const [bool; 0] (PtrToPtr);
8484
- _5 = NonNull::<[bool; 0]> { pointer: _11 };
8585
+ _11 = const {0x1 as *const [bool; 0]};
8686
+ _5 = const NonNull::<[bool; 0]> {{ pointer: {0x1 as *const [bool; 0]} }};

tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.32bit.panic-unwind.diff

+1-1
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@
8484

8585
bb5: {
8686
StorageDead(_8);
87-
- _11 = _6 as *const [bool; 0] (PointerCoercion(MutToConstPointer));
87+
- _11 = _6 as *const [bool; 0] (PtrToPtr);
8888
- _5 = NonNull::<[bool; 0]> { pointer: _11 };
8989
+ _11 = const {0x1 as *const [bool; 0]};
9090
+ _5 = const NonNull::<[bool; 0]> {{ pointer: {0x1 as *const [bool; 0]} }};

tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.64bit.panic-abort.diff

+1-1
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@
8080

8181
bb4: {
8282
StorageDead(_8);
83-
- _11 = _6 as *const [bool; 0] (PointerCoercion(MutToConstPointer));
83+
- _11 = _6 as *const [bool; 0] (PtrToPtr);
8484
- _5 = NonNull::<[bool; 0]> { pointer: _11 };
8585
+ _11 = const {0x1 as *const [bool; 0]};
8686
+ _5 = const NonNull::<[bool; 0]> {{ pointer: {0x1 as *const [bool; 0]} }};

tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.64bit.panic-unwind.diff

+1-1
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@
8484

8585
bb5: {
8686
StorageDead(_8);
87-
- _11 = _6 as *const [bool; 0] (PointerCoercion(MutToConstPointer));
87+
- _11 = _6 as *const [bool; 0] (PtrToPtr);
8888
- _5 = NonNull::<[bool; 0]> { pointer: _11 };
8989
+ _11 = const {0x1 as *const [bool; 0]};
9090
+ _5 = const NonNull::<[bool; 0]> {{ pointer: {0x1 as *const [bool; 0]} }};

tests/mir-opt/instsimplify/casts.roundtrip.InstSimplify.diff

+1-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
StorageLive(_4);
1515
_4 = _1;
1616
_3 = move _4 as *mut u8 (PtrToPtr);
17-
_2 = move _3 as *const u8 (PointerCoercion(MutToConstPointer));
17+
_2 = move _3 as *const u8 (PtrToPtr);
1818
StorageDead(_4);
1919
StorageDead(_3);
2020
- _0 = move _2 as *const u8 (PtrToPtr);

tests/mir-opt/instsimplify/casts.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ pub fn roundtrip(x: *const u8) -> *const u8 {
2121
// CHECK-LABEL: fn roundtrip(
2222
// CHECK: _4 = _1;
2323
// CHECK: _3 = move _4 as *mut u8 (PtrToPtr);
24-
// CHECK: _2 = move _3 as *const u8 (PointerCoercion(MutToConstPointer));
24+
// CHECK: _2 = move _3 as *const u8 (PtrToPtr);
2525
x as *mut u8 as *const u8
2626
}
2727

tests/mir-opt/pre-codegen/slice_iter.enumerated_loop.PreCodegen.after.panic-abort.mir

+1-1
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () {
7979
_7 = _4 as *mut T (PtrToPtr);
8080
_8 = Offset(_7, _3);
8181
StorageDead(_7);
82-
_9 = move _8 as *const T (PointerCoercion(MutToConstPointer));
82+
_9 = move _8 as *const T (PtrToPtr);
8383
StorageDead(_8);
8484
goto -> bb3;
8585
}

tests/mir-opt/pre-codegen/slice_iter.enumerated_loop.PreCodegen.after.panic-unwind.mir

+1-1
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () {
7979
_7 = _4 as *mut T (PtrToPtr);
8080
_8 = Offset(_7, _3);
8181
StorageDead(_7);
82-
_9 = move _8 as *const T (PointerCoercion(MutToConstPointer));
82+
_9 = move _8 as *const T (PtrToPtr);
8383
StorageDead(_8);
8484
goto -> bb3;
8585
}

tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.panic-abort.mir

+1-1
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ fn forward_loop(_1: &[T], _2: impl Fn(&T)) -> () {
7171
_7 = _4 as *mut T (PtrToPtr);
7272
_8 = Offset(_7, _3);
7373
StorageDead(_7);
74-
_9 = move _8 as *const T (PointerCoercion(MutToConstPointer));
74+
_9 = move _8 as *const T (PtrToPtr);
7575
StorageDead(_8);
7676
goto -> bb3;
7777
}

tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.panic-unwind.mir

+1-1
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ fn forward_loop(_1: &[T], _2: impl Fn(&T)) -> () {
7171
_7 = _4 as *mut T (PtrToPtr);
7272
_8 = Offset(_7, _3);
7373
StorageDead(_7);
74-
_9 = move _8 as *const T (PointerCoercion(MutToConstPointer));
74+
_9 = move _8 as *const T (PtrToPtr);
7575
StorageDead(_8);
7676
goto -> bb3;
7777
}

tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.panic-abort.mir

+1-1
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ fn reverse_loop(_1: &[T], _2: impl Fn(&T)) -> () {
7979
_7 = _4 as *mut T (PtrToPtr);
8080
_8 = Offset(_7, _3);
8181
StorageDead(_7);
82-
_9 = move _8 as *const T (PointerCoercion(MutToConstPointer));
82+
_9 = move _8 as *const T (PtrToPtr);
8383
StorageDead(_8);
8484
goto -> bb3;
8585
}

tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.panic-unwind.mir

+1-1
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ fn reverse_loop(_1: &[T], _2: impl Fn(&T)) -> () {
7979
_7 = _4 as *mut T (PtrToPtr);
8080
_8 = Offset(_7, _3);
8181
StorageDead(_7);
82-
_9 = move _8 as *const T (PointerCoercion(MutToConstPointer));
82+
_9 = move _8 as *const T (PtrToPtr);
8383
StorageDead(_8);
8484
goto -> bb3;
8585
}

tests/mir-opt/retag.array_casts.SimplifyCfg-pre-optimizations.after.panic-abort.mir

+2-2
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ fn array_casts() -> () {
6464
StorageLive(_4);
6565
_4 = &mut _1;
6666
_3 = &raw mut (*_4);
67-
_2 = move _3 as *mut usize (PointerCoercion(ArrayToPointer));
67+
_2 = move _3 as *mut usize (PtrToPtr);
6868
StorageDead(_3);
6969
StorageDead(_4);
7070
StorageLive(_5);
@@ -87,7 +87,7 @@ fn array_casts() -> () {
8787
StorageLive(_11);
8888
_11 = &_8;
8989
_10 = &raw const (*_11);
90-
_9 = move _10 as *const usize (PointerCoercion(ArrayToPointer));
90+
_9 = move _10 as *const usize (PtrToPtr);
9191
StorageDead(_10);
9292
StorageDead(_11);
9393
StorageLive(_12);

tests/mir-opt/retag.array_casts.SimplifyCfg-pre-optimizations.after.panic-unwind.mir

+2-2
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ fn array_casts() -> () {
6464
StorageLive(_4);
6565
_4 = &mut _1;
6666
_3 = &raw mut (*_4);
67-
_2 = move _3 as *mut usize (PointerCoercion(ArrayToPointer));
67+
_2 = move _3 as *mut usize (PtrToPtr);
6868
StorageDead(_3);
6969
StorageDead(_4);
7070
StorageLive(_5);
@@ -87,7 +87,7 @@ fn array_casts() -> () {
8787
StorageLive(_11);
8888
_11 = &_8;
8989
_10 = &raw const (*_11);
90-
_9 = move _10 as *const usize (PointerCoercion(ArrayToPointer));
90+
_9 = move _10 as *const usize (PtrToPtr);
9191
StorageDead(_10);
9292
StorageDead(_11);
9393
StorageLive(_12);

0 commit comments

Comments
 (0)