Skip to content

Commit 3be6803

Browse files
committed
Auto merge of #145513 - beepster4096:erasedereftemps, r=saethlin,cjgillot
Validate CopyForDeref and DerefTemps better and remove them from runtime MIR (split from my WIP #145344) This PR: - Removes `Rvalue::CopyForDeref` and `LocalInfo::DerefTemp` from runtime MIR - Using a new mir pass `EraseDerefTemps` - `CopyForDeref(x)` is turned into `Use(Copy(x))` - `DerefTemp` is turned into `Boring` - Not sure if this part is actually necessary, it made more sense in #145344 with `DerefTemp` storing actual data that I wanted to keep from having to be kept in sync with the rest of the body in runtime MIR - Checks in validation that `CopyForDeref` and `DerefTemp` are only used together - Removes special handling for `CopyForDeref` from many places - Removes `CopyForDeref` from `custom_mir` reverting #111587 - In runtime MIR simple copies can be used instead - In post cleanup analysis MIR it was already wrong to use due to the lack of support for creating `DerefTemp` locals - Possibly this should be its own PR? - Adds an argument to `deref_finder` to avoid creating new `DerefTemp`s and `CopyForDeref` in runtime MIR. - Ideally we would just avoid making intermediate derefs instead of fixing it at the end of a pass / during shim building - Removes some usages of `deref_finder` that I found out don't actually do anything r? oli-obk
2 parents be0ade2 + 033474b commit 3be6803

File tree

55 files changed

+418
-407
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

55 files changed

+418
-407
lines changed

compiler/rustc_borrowck/src/lib.rs

Lines changed: 2 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1538,24 +1538,6 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, '_, 'tcx> {
15381538
self.consume_operand(location, (operand, span), state)
15391539
}
15401540

1541-
&Rvalue::CopyForDeref(place) => {
1542-
self.access_place(
1543-
location,
1544-
(place, span),
1545-
(Deep, Read(ReadKind::Copy)),
1546-
LocalMutationIsAllowed::No,
1547-
state,
1548-
);
1549-
1550-
// Finally, check if path was already moved.
1551-
self.check_if_path_or_subpath_is_moved(
1552-
location,
1553-
InitializationRequiringAction::Use,
1554-
(place.as_ref(), span),
1555-
state,
1556-
);
1557-
}
1558-
15591541
&Rvalue::Discriminant(place) => {
15601542
let af = match *rvalue {
15611543
Rvalue::Discriminant(..) => None,
@@ -1617,6 +1599,8 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, '_, 'tcx> {
16171599
Rvalue::WrapUnsafeBinder(op, _) => {
16181600
self.consume_operand(location, (op, span), state);
16191601
}
1602+
1603+
Rvalue::CopyForDeref(_) => bug!("`CopyForDeref` in borrowck"),
16201604
}
16211605
}
16221606

compiler/rustc_borrowck/src/polonius/legacy/loan_invalidations.rs

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -300,11 +300,6 @@ impl<'a, 'tcx> LoanInvalidationsGenerator<'a, 'tcx> {
300300
| Rvalue::Cast(_ /*cast_kind*/, operand, _ /*ty*/)
301301
| Rvalue::ShallowInitBox(operand, _ /*ty*/) => self.consume_operand(location, operand),
302302

303-
&Rvalue::CopyForDeref(place) => {
304-
let op = &Operand::Copy(place);
305-
self.consume_operand(location, op);
306-
}
307-
308303
&Rvalue::Discriminant(place) => {
309304
self.access_place(
310305
location,
@@ -330,6 +325,8 @@ impl<'a, 'tcx> LoanInvalidationsGenerator<'a, 'tcx> {
330325
Rvalue::WrapUnsafeBinder(op, _) => {
331326
self.consume_operand(location, op);
332327
}
328+
329+
Rvalue::CopyForDeref(_) => bug!("`CopyForDeref` in borrowck"),
333330
}
334331
}
335332

compiler/rustc_codegen_cranelift/src/base.rs

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -600,11 +600,6 @@ fn codegen_stmt<'tcx>(fx: &mut FunctionCx<'_, '_, 'tcx>, cur_block: Block, stmt:
600600
let val = codegen_operand(fx, operand);
601601
lval.write_cvalue(fx, val);
602602
}
603-
Rvalue::CopyForDeref(place) => {
604-
let cplace = codegen_place(fx, place);
605-
let val = cplace.to_cvalue(fx);
606-
lval.write_cvalue(fx, val)
607-
}
608603
Rvalue::Ref(_, _, place) | Rvalue::RawPtr(_, place) => {
609604
let place = codegen_place(fx, place);
610605
let ref_ = place.place_ref(fx, lval.layout());
@@ -928,6 +923,7 @@ fn codegen_stmt<'tcx>(fx: &mut FunctionCx<'_, '_, 'tcx>, cur_block: Block, stmt:
928923
let operand = codegen_operand(fx, operand);
929924
lval.write_cvalue_transmute(fx, operand);
930925
}
926+
Rvalue::CopyForDeref(_) => bug!("`CopyForDeref` in codegen"),
931927
}
932928
}
933929
StatementKind::StorageLive(_)

compiler/rustc_codegen_ssa/src/mir/rvalue.rs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -504,9 +504,6 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
504504
self.codegen_place_to_pointer(bx, place, mk_ref)
505505
}
506506

507-
mir::Rvalue::CopyForDeref(place) => {
508-
self.codegen_operand(bx, &mir::Operand::Copy(place))
509-
}
510507
mir::Rvalue::RawPtr(kind, place) => {
511508
let mk_ptr = move |tcx: TyCtxt<'tcx>, ty: Ty<'tcx>| {
512509
Ty::new_ptr(tcx, ty, kind.to_mutbl_lossy())
@@ -742,6 +739,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
742739
let layout = bx.cx().layout_of(binder_ty);
743740
OperandRef { val: operand.val, layout }
744741
}
742+
mir::Rvalue::CopyForDeref(_) => bug!("`CopyForDeref` in codegen"),
745743
}
746744
}
747745

compiler/rustc_const_eval/src/check_consts/qualifs.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -234,7 +234,7 @@ where
234234

235235
Rvalue::Discriminant(place) => in_place::<Q, _>(cx, in_local, place.as_ref()),
236236

237-
Rvalue::CopyForDeref(place) => in_place::<Q, _>(cx, in_local, place.as_ref()),
237+
Rvalue::CopyForDeref(_) => bug!("`CopyForDeref` in runtime MIR"),
238238

239239
Rvalue::Use(operand)
240240
| Rvalue::Repeat(operand, _)

compiler/rustc_const_eval/src/interpret/step.rs

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -183,10 +183,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
183183
self.copy_op(&op, &dest)?;
184184
}
185185

186-
CopyForDeref(place) => {
187-
let op = self.eval_place_to_op(place, Some(dest.layout))?;
188-
self.copy_op(&op, &dest)?;
189-
}
186+
CopyForDeref(_) => bug!("`CopyForDeref` in runtime MIR"),
190187

191188
BinaryOp(bin_op, box (ref left, ref right)) => {
192189
let layout = util::binop_left_homogeneous(bin_op).then_some(dest.layout);

compiler/rustc_middle/src/mir/mod.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1065,7 +1065,11 @@ pub enum LocalInfo<'tcx> {
10651065
/// A temporary created during evaluating `if` predicate, possibly for pattern matching for `let`s,
10661066
/// and subject to Edition 2024 temporary lifetime rules
10671067
IfThenRescopeTemp { if_then: HirId },
1068-
/// A temporary created during the pass `Derefer` to avoid it's retagging
1068+
/// A temporary created during the pass `Derefer` treated as a transparent alias
1069+
/// for the place its copied from by analysis passes such as `AddRetag` and `ElaborateDrops`.
1070+
///
1071+
/// It may only be written to by a `CopyForDeref` and otherwise only accessed through a deref.
1072+
/// In runtime MIR, it is replaced with a normal `Boring` local.
10691073
DerefTemp,
10701074
/// A temporary created for borrow checking.
10711075
FakeBorrow,

compiler/rustc_middle/src/mir/syntax.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,9 @@ pub enum RuntimePhase {
130130
/// * [`TerminatorKind::Yield`]
131131
/// * [`TerminatorKind::CoroutineDrop`]
132132
/// * [`Rvalue::Aggregate`] for any `AggregateKind` except `Array`
133+
/// * [`Rvalue::CopyForDeref`]
133134
/// * [`PlaceElem::OpaqueCast`]
135+
/// * [`LocalInfo::DerefTemp`](super::LocalInfo::DerefTemp)
134136
///
135137
/// And the following variants are allowed:
136138
/// * [`StatementKind::Retag`]
@@ -1454,11 +1456,13 @@ pub enum Rvalue<'tcx> {
14541456
/// A CopyForDeref is equivalent to a read from a place at the
14551457
/// codegen level, but is treated specially by drop elaboration. When such a read happens, it
14561458
/// is guaranteed (via nature of the mir_opt `Derefer` in rustc_mir_transform/src/deref_separator)
1457-
/// that the only use of the returned value is a deref operation, immediately
1458-
/// followed by one or more projections. Drop elaboration treats this rvalue as if the
1459+
/// that the returned value is written into a `DerefTemp` local and that its only use is a deref operation,
1460+
/// immediately followed by one or more projections. Drop elaboration treats this rvalue as if the
14591461
/// read never happened and just projects further. This allows simplifying various MIR
14601462
/// optimizations and codegen backends that previously had to handle deref operations anywhere
14611463
/// in a place.
1464+
///
1465+
/// Disallowed in runtime MIR and is replaced by normal copies.
14621466
CopyForDeref(Place<'tcx>),
14631467

14641468
/// Wraps a value in an unsafe binder.

compiler/rustc_mir_build/src/builder/custom/parse/instruction.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -250,7 +250,6 @@ impl<'a, 'tcx> ParseCtxt<'a, 'tcx> {
250250
Ok(Rvalue::BinaryOp(BinOp::Offset, Box::new((ptr, offset))))
251251
},
252252
@call(mir_ptr_metadata, args) => Ok(Rvalue::UnaryOp(UnOp::PtrMetadata, self.parse_operand(args[0])?)),
253-
@call(mir_copy_for_deref, args) => Ok(Rvalue::CopyForDeref(self.parse_place(args[0])?)),
254253
ExprKind::Borrow { borrow_kind, arg } => Ok(
255254
Rvalue::Ref(self.tcx.lifetimes.re_erased, *borrow_kind, self.parse_place(*arg)?)
256255
),

compiler/rustc_mir_transform/src/copy_prop.rs

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -74,9 +74,7 @@ fn fully_moved_locals(ssa: &SsaLocals, body: &Body<'_>) -> DenseBitSet<Local> {
7474
let mut fully_moved = DenseBitSet::new_filled(body.local_decls.len());
7575

7676
for (_, rvalue, _) in ssa.assignments(body) {
77-
let (Rvalue::Use(Operand::Copy(place) | Operand::Move(place))
78-
| Rvalue::CopyForDeref(place)) = rvalue
79-
else {
77+
let Rvalue::Use(Operand::Copy(place) | Operand::Move(place)) = rvalue else {
8078
continue;
8179
};
8280

@@ -85,7 +83,7 @@ fn fully_moved_locals(ssa: &SsaLocals, body: &Body<'_>) -> DenseBitSet<Local> {
8583
continue;
8684
}
8785

88-
if let Rvalue::Use(Operand::Copy(_)) | Rvalue::CopyForDeref(_) = rvalue {
86+
if let Rvalue::Use(Operand::Copy(_)) = rvalue {
8987
fully_moved.remove(rhs);
9088
}
9189
}
@@ -146,8 +144,7 @@ impl<'tcx> MutVisitor<'tcx> for Replacer<'_, 'tcx> {
146144

147145
// Do not leave tautological assignments around.
148146
if let StatementKind::Assign(box (lhs, ref rhs)) = stmt.kind
149-
&& let Rvalue::Use(Operand::Copy(rhs) | Operand::Move(rhs)) | Rvalue::CopyForDeref(rhs) =
150-
*rhs
147+
&& let Rvalue::Use(Operand::Copy(rhs) | Operand::Move(rhs)) = *rhs
151148
&& lhs == rhs
152149
{
153150
stmt.make_nop(true);

0 commit comments

Comments
 (0)