Auto merge of #126308 - scottmcm:ban-some-coercions, r=saethlin · rust-lang/rust@3d5d7a2 (original) (raw)

24 files changed

lines changed

Original file line number Diff line number Diff line change
@@ -677,21 +677,22 @@ fn codegen_stmt<'tcx>(
677 677 CastKind::PointerCoercion(PointerCoercion::UnsafeFnPointer),
678 678 ref operand,
679 679 to_ty,
680 -)
681 - | Rvalue::Cast(
682 -CastKind::PointerCoercion(PointerCoercion::MutToConstPointer),
683 -ref operand,
684 - to_ty,
685 -)
686 - | Rvalue::Cast(
687 -CastKind::PointerCoercion(PointerCoercion::ArrayToPointer),
688 -ref operand,
689 - to_ty,
690 680 ) => {
691 681 let to_layout = fx.layout_of(fx.monomorphize(to_ty));
692 682 let operand = codegen_operand(fx, operand);
693 683 lval.write_cvalue(fx, operand.cast_pointer_to(to_layout));
694 684 }
685 +Rvalue::Cast(
686 +CastKind::PointerCoercion(
687 +PointerCoercion::MutToConstPointer | PointerCoercion::ArrayToPointer,
688 +),
689 + ..,
690 +) => {
691 +bug!(
692 +"{:?} is for borrowck, and should never appear in codegen",
693 + to_place_and_rval.1
694 +);
695 +}
695 696 Rvalue::Cast(
696 697 CastKind::IntToInt
697 698 | CastKind::FloatToFloat
Original file line number Diff line number Diff line change
@@ -456,8 +456,12 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
456 456 base::unsize_ptr(bx, lldata, operand.layout.ty, cast.ty, llextra);
457 457 OperandValue::Pair(lldata, llextra)
458 458 }
459 - mir::CastKind::PointerCoercion(PointerCoercion::MutToConstPointer)
460 - | mir::CastKind::PtrToPtr
459 + mir::CastKind::PointerCoercion(
460 +PointerCoercion::MutToConstPointer | PointerCoercion::ArrayToPointer,
461 +) => {
462 +bug!("{kind:?} is for borrowck, and should never appear in codegen");
463 +}
464 + mir::CastKind::PtrToPtr
461 465 if bx.cx().is_backend_scalar_pair(operand.layout) =>
462 466 {
463 467 if let OperandValue::Pair(data_ptr, meta) = operand.val {
@@ -477,9 +481,6 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
477 481 base::cast_to_dyn_star(bx, lldata, operand.layout, cast.ty, llextra);
478 482 OperandValue::Pair(lldata, llextra)
479 483 }
480 - mir::CastKind::PointerCoercion(
481 -PointerCoercion::MutToConstPointer | PointerCoercion::ArrayToPointer,
482 -)
483 484 | mir::CastKind::IntToInt
484 485 | mir::CastKind::FloatToInt
485 486 | mir::CastKind::FloatToFloat
Original file line number Diff line number Diff line change
@@ -70,9 +70,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
70 70 CastKind::PointerCoercion(
71 71 PointerCoercion::MutToConstPointer | PointerCoercion::ArrayToPointer,
72 72 ) => {
73 -// These are NOPs, but can be wide pointers.
74 -let v = self.read_immediate(src)?;
75 -self.write_immediate(*v, dest)?;
73 +bug!("{cast_kind:?} casts are for borrowck only, not runtime MIR");
76 74 }
77 75
78 76 CastKind::PointerCoercion(PointerCoercion::ReifyFnPointer) => {
Original file line number Diff line number Diff line change
@@ -127,6 +127,9 @@ pub enum AnalysisPhase {
127 127 /// * [`StatementKind::AscribeUserType`]
128 128 /// * [`StatementKind::Coverage`] with [`CoverageKind::BlockMarker`] or [`CoverageKind::SpanMarker`]
129 129 /// * [`Rvalue::Ref`] with `BorrowKind::Fake`
130 + /// * [`CastKind::PointerCoercion`] with any of the following:
131 + /// * [`PointerCoercion::ArrayToPointer`]
132 + /// * [`PointerCoercion::MutToConstPointer`]
130 133 ///
131 134 /// Furthermore, `Deref` projections must be the first projection within any place (if they
132 135 /// appear at all)
@@ -1284,8 +1287,7 @@ pub enum Rvalue<'tcx> {
1284 1287 ///
1285 1288 /// This allows for casts from/to a variety of types.
1286 1289 ///
1287 - /// **FIXME**: Document exactly which `CastKind`s allow which types of casts. Figure out why
1288 - /// `ArrayToPointer` and `MutToConstPointer` are special.
1290 + /// **FIXME**: Document exactly which `CastKind`s allow which types of casts.
1289 1291 Cast(CastKind, Operand<'tcx>, Ty<'tcx>),
1290 1292
1291 1293 /// * `Offset` has the same semantics as [`offset`](pointer::offset), except that the second
@@ -1365,6 +1367,13 @@ pub enum CastKind {
1365 1367 PointerWithExposedProvenance,
1366 1368 /// Pointer related casts that are done by coercions. Note that reference-to-raw-ptr casts are
1367 1369 /// translated into `&raw mut/const *r`, i.e., they are not actually casts.
1370 + ///
1371 + /// The following are allowed in [`AnalysisPhase::Initial`] as they're needed for borrowck,
1372 + /// but after that are forbidden (including in all phases of runtime MIR):
1373 + /// * [`PointerCoercion::ArrayToPointer`]
1374 + /// * [`PointerCoercion::MutToConstPointer`]
1375 + ///
1376 + /// Both are runtime nops, so should be [`CastKind::PtrToPtr`] instead in runtime MIR.
1368 1377 PointerCoercion(PointerCoercion),
1369 1378 /// Cast into a dyn* object.
1370 1379 DynStar,
Original file line number Diff line number Diff line change
@@ -18,7 +18,8 @@
18 18
19 19 use crate::MirPass;
20 20 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;
22 23 use rustc_middle::ty::TyCtxt;
23 24
24 25 pub struct CleanupPostBorrowck;
@@ -36,6 +37,22 @@ impl<'tcx> MirPass<'tcx> for CleanupPostBorrowck {
36 37 CoverageKind::BlockMarker { .. } | CoverageKind::SpanMarker { .. },
37 38 )
38 39 | 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 +}
39 56 _ => (),
40 57 }
41 58 }
Original file line number Diff line number Diff line change
@@ -571,11 +571,7 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
571 571 let ret = self.ecx.ptr_to_ptr(&src, to).ok()?;
572 572 ret.into()
573 573 }
574 -CastKind::PointerCoercion(
575 - ty::adjustment::PointerCoercion::MutToConstPointer
576 - | ty::adjustment::PointerCoercion::ArrayToPointer
577 - | ty::adjustment::PointerCoercion::UnsafeFnPointer,
578 -) => {
574 +CastKind::PointerCoercion(ty::adjustment::PointerCoercion::UnsafeFnPointer) => {
579 575 let src = self.evaluated[value].as_ref()?;
580 576 let src = self.ecx.read_immediate(src).ok()?;
581 577 let to = self.ecx.layout_of(to).ok()?;
@@ -1164,10 +1160,10 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
1164 1160 }
1165 1161 }
1166 1162
1167 -if let PtrToPtr | PointerCoercion(MutToConstPointer) = kind
1163 +if let PtrToPtr = kind
1168 1164 && let Value::Cast { kind: inner_kind, value: inner_value, from: inner_from, to: _ } =
1169 1165 *self.get(value)
1170 - && let PtrToPtr | PointerCoercion(MutToConstPointer) = inner_kind
1166 + && let PtrToPtr = inner_kind
1171 1167 {
1172 1168 from = inner_from;
1173 1169 value = inner_value;
Original file line number Diff line number Diff line change
@@ -51,11 +51,11 @@ mod abort_unwinding_calls;
51 51 mod add_call_guards;
52 52 mod add_moves_for_packed_drops;
53 53 mod add_retag;
54 +mod add_subtyping_projections;
55 +mod check_alignment;
54 56 mod check_const_item_mutation;
55 57 mod check_packed_ref;
56 -mod remove_place_mention;
57 58 // This pass is public to allow external drivers to perform MIR cleanup
58 -mod add_subtyping_projections;
59 59 pub mod cleanup_post_borrowck;
60 60 mod copy_prop;
61 61 mod coroutine;
@@ -94,6 +94,7 @@ mod prettify;
94 94 mod promote_consts;
95 95 mod ref_prop;
96 96 mod remove_noop_landing_pads;
97 +mod remove_place_mention;
97 98 mod remove_storage_markers;
98 99 mod remove_uninit_drops;
99 100 mod remove_unneeded_drops;
@@ -103,7 +104,6 @@ mod reveal_all;
103 104 mod shim;
104 105 mod ssa;
105 106 // This pass is public to allow external drivers to perform MIR cleanup
106 -mod check_alignment;
107 107 pub mod simplify;
108 108 mod simplify_branches;
109 109 mod simplify_comparison_integral;
Original file line number Diff line number Diff line change
@@ -1188,6 +1188,9 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
1188 1188 "CastKind::{kind:?} output must be a raw const pointer, not {:?}",
1189 1189 ty::RawPtr(_, Mutability::Not)
1190 1190 );
1191 +if self.mir_phase >= MirPhase::Analysis(AnalysisPhase::PostCleanup) {
1192 +self.fail(location, format!("After borrowck, MIR disallows {kind:?}"));
1193 +}
1191 1194 }
1192 1195 CastKind::PointerCoercion(PointerCoercion::ArrayToPointer) => {
1193 1196 // FIXME: Check pointee types
@@ -1201,6 +1204,9 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
1201 1204 "CastKind::{kind:?} output must be a raw pointer, not {:?}",
1202 1205 ty::RawPtr(..)
1203 1206 );
1207 +if self.mir_phase >= MirPhase::Analysis(AnalysisPhase::PostCleanup) {
1208 +self.fail(location, format!("After borrowck, MIR disallows {kind:?}"));
1209 +}
1204 1210 }
1205 1211 CastKind::PointerCoercion(PointerCoercion::Unsize) => {
1206 1212 // This is used for all `CoerceUnsized` types,
@@ -1212,7 +1218,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
1212 1218 if !input_valid |
1213 1219 self.fail(
1214 1220 location,
1215 -format!("Wrong cast kind {kind:?} for the type {op_ty}",),
1221 +format!("Wrong cast kind {kind:?} for the type {op_ty}"),
1216 1222 );
1217 1223 }
1218 1224 }
Original file line number Diff line number Diff line change
@@ -80,7 +80,7 @@
80 80
81 81 bb4: {
82 82 StorageDead(_8);
83 -- _11 = _6 as *const [bool; 0] (PointerCoercion(MutToConstPointer));
83 +- _11 = _6 as *const [bool; 0] (PtrToPtr);
84 84 - _5 = NonNull::<[bool; 0]> { pointer: _11 };
85 85 + _11 = const {0x1 as *const [bool; 0]};
86 86 + _5 = const NonNull::<[bool; 0]> {{ pointer: {0x1 as *const [bool; 0]} }};
Original file line number Diff line number Diff line change
@@ -84,7 +84,7 @@
84 84
85 85 bb5: {
86 86 StorageDead(_8);
87 -- _11 = _6 as *const [bool; 0] (PointerCoercion(MutToConstPointer));
87 +- _11 = _6 as *const [bool; 0] (PtrToPtr);
88 88 - _5 = NonNull::<[bool; 0]> { pointer: _11 };
89 89 + _11 = const {0x1 as *const [bool; 0]};
90 90 + _5 = const NonNull::<[bool; 0]> {{ pointer: {0x1 as *const [bool; 0]} }};
Original file line number Diff line number Diff line change
@@ -80,7 +80,7 @@
80 80
81 81 bb4: {
82 82 StorageDead(_8);
83 -- _11 = _6 as *const [bool; 0] (PointerCoercion(MutToConstPointer));
83 +- _11 = _6 as *const [bool; 0] (PtrToPtr);
84 84 - _5 = NonNull::<[bool; 0]> { pointer: _11 };
85 85 + _11 = const {0x1 as *const [bool; 0]};
86 86 + _5 = const NonNull::<[bool; 0]> {{ pointer: {0x1 as *const [bool; 0]} }};
Original file line number Diff line number Diff line change
@@ -84,7 +84,7 @@
84 84
85 85 bb5: {
86 86 StorageDead(_8);
87 -- _11 = _6 as *const [bool; 0] (PointerCoercion(MutToConstPointer));
87 +- _11 = _6 as *const [bool; 0] (PtrToPtr);
88 88 - _5 = NonNull::<[bool; 0]> { pointer: _11 };
89 89 + _11 = const {0x1 as *const [bool; 0]};
90 90 + _5 = const NonNull::<[bool; 0]> {{ pointer: {0x1 as *const [bool; 0]} }};
Original file line number Diff line number Diff line change
@@ -14,7 +14,7 @@
14 14 StorageLive(_4);
15 15 _4 = _1;
16 16 _3 = move _4 as *mut u8 (PtrToPtr);
17 - _2 = move _3 as *const u8 (PointerCoercion(MutToConstPointer));
17 + _2 = move _3 as *const u8 (PtrToPtr);
18 18 StorageDead(_4);
19 19 StorageDead(_3);
20 20 - _0 = move _2 as *const u8 (PtrToPtr);
Original file line number Diff line number Diff line change
@@ -21,7 +21,7 @@ pub fn roundtrip(x: *const u8) -> *const u8 {
21 21 // CHECK-LABEL: fn roundtrip(
22 22 // CHECK: _4 = _1;
23 23 // 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);
25 25 x as *mut u8 as *const u8
26 26 }
27 27
Original file line number Diff line number Diff line change
@@ -41,7 +41,7 @@ fn slice_get_unchecked_mut_range(_1: &mut [u32], _2: std::ops::Range) ->
41 41 StorageLive(_9);
42 42 StorageLive(_7);
43 43 StorageLive(_6);
44 -_6 = _5 as *const [u32] (PointerCoercion(MutToConstPointer));
44 +_6 = _5 as *const [u32] (PtrToPtr);
45 45 _7 = PtrMetadata(_6);
46 46 StorageDead(_6);
47 47 _8 = <std::ops::Range as SliceIndex<[T]>>::get_unchecked_mut::precondition_check(_3, _4, move _7) -> [return: bb1, unwind unreachable];
Original file line number Diff line number Diff line change
@@ -41,7 +41,7 @@ fn slice_get_unchecked_mut_range(_1: &mut [u32], _2: std::ops::Range) ->
41 41 StorageLive(_9);
42 42 StorageLive(_7);
43 43 StorageLive(_6);
44 -_6 = _5 as *const [u32] (PointerCoercion(MutToConstPointer));
44 +_6 = _5 as *const [u32] (PtrToPtr);
45 45 _7 = PtrMetadata(_6);
46 46 StorageDead(_6);
47 47 _8 = <std::ops::Range as SliceIndex<[T]>>::get_unchecked_mut::precondition_check(_3, _4, move _7) -> [return: bb1, unwind unreachable];
Original file line number Diff line number Diff line change
@@ -79,7 +79,7 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () {
79 79 _7 = _4 as *mut T (PtrToPtr);
80 80 _8 = Offset(_7, _3);
81 81 StorageDead(_7);
82 -_9 = move _8 as *const T (PointerCoercion(MutToConstPointer));
82 +_9 = move _8 as *const T (PtrToPtr);
83 83 StorageDead(_8);
84 84 goto -> bb3;
85 85 }
Original file line number Diff line number Diff line change
@@ -79,7 +79,7 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () {
79 79 _7 = _4 as *mut T (PtrToPtr);
80 80 _8 = Offset(_7, _3);
81 81 StorageDead(_7);
82 -_9 = move _8 as *const T (PointerCoercion(MutToConstPointer));
82 +_9 = move _8 as *const T (PtrToPtr);
83 83 StorageDead(_8);
84 84 goto -> bb3;
85 85 }
Original file line number Diff line number Diff line change
@@ -71,7 +71,7 @@ fn forward_loop(_1: &[T], _2: impl Fn(&T)) -> () {
71 71 _7 = _4 as *mut T (PtrToPtr);
72 72 _8 = Offset(_7, _3);
73 73 StorageDead(_7);
74 -_9 = move _8 as *const T (PointerCoercion(MutToConstPointer));
74 +_9 = move _8 as *const T (PtrToPtr);
75 75 StorageDead(_8);
76 76 goto -> bb3;
77 77 }
Original file line number Diff line number Diff line change
@@ -71,7 +71,7 @@ fn forward_loop(_1: &[T], _2: impl Fn(&T)) -> () {
71 71 _7 = _4 as *mut T (PtrToPtr);
72 72 _8 = Offset(_7, _3);
73 73 StorageDead(_7);
74 -_9 = move _8 as *const T (PointerCoercion(MutToConstPointer));
74 +_9 = move _8 as *const T (PtrToPtr);
75 75 StorageDead(_8);
76 76 goto -> bb3;
77 77 }
Original file line number Diff line number Diff line change
@@ -79,7 +79,7 @@ fn reverse_loop(_1: &[T], _2: impl Fn(&T)) -> () {
79 79 _7 = _4 as *mut T (PtrToPtr);
80 80 _8 = Offset(_7, _3);
81 81 StorageDead(_7);
82 -_9 = move _8 as *const T (PointerCoercion(MutToConstPointer));
82 +_9 = move _8 as *const T (PtrToPtr);
83 83 StorageDead(_8);
84 84 goto -> bb3;
85 85 }
Original file line number Diff line number Diff line change
@@ -79,7 +79,7 @@ fn reverse_loop(_1: &[T], _2: impl Fn(&T)) -> () {
79 79 _7 = _4 as *mut T (PtrToPtr);
80 80 _8 = Offset(_7, _3);
81 81 StorageDead(_7);
82 -_9 = move _8 as *const T (PointerCoercion(MutToConstPointer));
82 +_9 = move _8 as *const T (PtrToPtr);
83 83 StorageDead(_8);
84 84 goto -> bb3;
85 85 }
Original file line number Diff line number Diff line change
@@ -64,7 +64,7 @@ fn array_casts() -> () {
64 64 StorageLive(_4);
65 65 _4 = &mut _1;
66 66 _3 = &raw mut (*_4);
67 -_2 = move _3 as *mut usize (PointerCoercion(ArrayToPointer));
67 +_2 = move _3 as *mut usize (PtrToPtr);
68 68 StorageDead(_3);
69 69 StorageDead(_4);
70 70 StorageLive(_5);
@@ -87,7 +87,7 @@ fn array_casts() -> () {
87 87 StorageLive(_11);
88 88 _11 = &_8;
89 89 _10 = &raw const (*_11);
90 -_9 = move _10 as *const usize (PointerCoercion(ArrayToPointer));
90 +_9 = move _10 as *const usize (PtrToPtr);
91 91 StorageDead(_10);
92 92 StorageDead(_11);
93 93 StorageLive(_12);
Original file line number Diff line number Diff line change
@@ -64,7 +64,7 @@ fn array_casts() -> () {
64 64 StorageLive(_4);
65 65 _4 = &mut _1;
66 66 _3 = &raw mut (*_4);
67 -_2 = move _3 as *mut usize (PointerCoercion(ArrayToPointer));
67 +_2 = move _3 as *mut usize (PtrToPtr);
68 68 StorageDead(_3);
69 69 StorageDead(_4);
70 70 StorageLive(_5);
@@ -87,7 +87,7 @@ fn array_casts() -> () {
87 87 StorageLive(_11);
88 88 _11 = &_8;
89 89 _10 = &raw const (*_11);
90 -_9 = move _10 as *const usize (PointerCoercion(ArrayToPointer));
90 +_9 = move _10 as *const usize (PtrToPtr);
91 91 StorageDead(_10);
92 92 StorageDead(_11);
93 93 StorageLive(_12);