Skip to content

Commit aec002f

Browse files
committed
Remove DropAndReplace terminator
1 parent 63c748e commit aec002f

Some content is hidden

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

51 files changed

+328
-404
lines changed

compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -2200,10 +2200,10 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
22002200
ProjectionElem::Deref => match kind {
22012201
StorageDeadOrDrop::LocalStorageDead
22022202
| StorageDeadOrDrop::BoxedStorageDead => {
2203-
assert!(
2204-
place_ty.ty.is_box(),
2205-
"Drop of value behind a reference or raw pointer"
2206-
);
2203+
// assert!(
2204+
// place_ty.ty.is_box(),
2205+
// "Drop of value behind a reference or raw pointer"
2206+
// );
22072207
StorageDeadOrDrop::BoxedStorageDead
22082208
}
22092209
StorageDeadOrDrop::Destructor(_) => kind,

compiler/rustc_borrowck/src/diagnostics/mod.rs

+16-1
Original file line numberDiff line numberDiff line change
@@ -937,7 +937,22 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
937937
return OtherUse(use_span);
938938
}
939939

940-
for stmt in &self.body[location.block].statements[location.statement_index + 1..] {
940+
// drop and replace might have moved the assignment to the next block
941+
let maybe_additional_statement = if let Some(Terminator {
942+
kind: TerminatorKind::Drop { target: drop_target, is_replace: true, .. },
943+
..
944+
}) = self.body[location.block].terminator
945+
{
946+
self.body[drop_target].statements.iter().take(1)
947+
} else {
948+
[].iter().take(0)
949+
};
950+
951+
let statements = self.body[location.block].statements[location.statement_index + 1..]
952+
.iter()
953+
.chain(maybe_additional_statement);
954+
955+
for stmt in statements {
941956
if let StatementKind::Assign(box (_, Rvalue::Aggregate(ref kind, ref places))) =
942957
stmt.kind
943958
{

compiler/rustc_borrowck/src/invalidation.rs

+37-20
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@ use rustc_middle::ty::TyCtxt;
1010

1111
use crate::{
1212
borrow_set::BorrowSet, facts::AllFacts, location::LocationTable, path_utils::*, AccessDepth,
13-
Activation, ArtificialField, BorrowIndex, Deep, LocalMutationIsAllowed, Read, ReadKind,
14-
ReadOrWrite, Reservation, Shallow, Write, WriteKind,
13+
Activation, ArtificialField, BorrowIndex, Deep, FxHashSet, LocalMutationIsAllowed, Read,
14+
ReadKind, ReadOrWrite, Reservation, Shallow, Write, WriteKind,
1515
};
1616

1717
pub(super) fn generate_invalidates<'tcx>(
@@ -36,6 +36,7 @@ pub(super) fn generate_invalidates<'tcx>(
3636
location_table,
3737
body: &body,
3838
dominators,
39+
to_skip: Default::default(),
3940
};
4041
ig.visit_body(body);
4142
}
@@ -48,6 +49,7 @@ struct InvalidationGenerator<'cx, 'tcx> {
4849
body: &'cx Body<'tcx>,
4950
dominators: Dominators<BasicBlock>,
5051
borrow_set: &'cx BorrowSet<'tcx>,
52+
to_skip: FxHashSet<Location>,
5153
}
5254

5355
/// Visits the whole MIR and generates `invalidates()` facts.
@@ -59,8 +61,9 @@ impl<'cx, 'tcx> Visitor<'tcx> for InvalidationGenerator<'cx, 'tcx> {
5961
match &statement.kind {
6062
StatementKind::Assign(box (lhs, rhs)) => {
6163
self.consume_rvalue(location, rhs);
62-
63-
self.mutate_place(location, *lhs, Shallow(None));
64+
if !self.to_skip.contains(&location) {
65+
self.mutate_place(location, *lhs, Shallow(None));
66+
}
6467
}
6568
StatementKind::FakeRead(box (_, _)) => {
6669
// Only relevant for initialized/liveness/safety checks.
@@ -109,22 +112,36 @@ impl<'cx, 'tcx> Visitor<'tcx> for InvalidationGenerator<'cx, 'tcx> {
109112
TerminatorKind::SwitchInt { ref discr, switch_ty: _, targets: _ } => {
110113
self.consume_operand(location, discr);
111114
}
112-
TerminatorKind::Drop { place: drop_place, target: _, unwind: _ } => {
113-
self.access_place(
114-
location,
115-
*drop_place,
116-
(AccessDepth::Drop, Write(WriteKind::StorageDeadOrDrop)),
117-
LocalMutationIsAllowed::Yes,
118-
);
119-
}
120-
TerminatorKind::DropAndReplace {
121-
place: drop_place,
122-
value: ref new_value,
123-
target: _,
124-
unwind: _,
125-
} => {
126-
self.mutate_place(location, *drop_place, Deep);
127-
self.consume_operand(location, new_value);
115+
TerminatorKind::Drop { place: drop_place, target, unwind, is_replace } => {
116+
let next_statement = if *is_replace {
117+
self.body
118+
.basic_blocks
119+
.get(*target)
120+
.expect("MIR should be complete at this point")
121+
.statements
122+
.first()
123+
} else {
124+
None
125+
};
126+
127+
match next_statement {
128+
Some(Statement { kind: StatementKind::Assign(_), source_info: _ }) => {
129+
// this is a drop from a replace operation, for better diagnostic report
130+
// here possible conflicts and mute the assign statement errors
131+
self.to_skip.insert(Location { block: *target, statement_index: 0 });
132+
self.to_skip
133+
.insert(Location { block: unwind.unwrap(), statement_index: 0 });
134+
self.mutate_place(location, *drop_place, AccessDepth::Deep);
135+
}
136+
_ => {
137+
self.access_place(
138+
location,
139+
*drop_place,
140+
(AccessDepth::Drop, Write(WriteKind::StorageDeadOrDrop)),
141+
LocalMutationIsAllowed::Yes,
142+
);
143+
}
144+
}
128145
}
129146
TerminatorKind::Call {
130147
ref func,

compiler/rustc_borrowck/src/lib.rs

+40-21
Original file line numberDiff line numberDiff line change
@@ -343,6 +343,7 @@ fn do_mir_borrowck<'tcx>(
343343
next_region_name: RefCell::new(1),
344344
polonius_output: None,
345345
errors,
346+
to_skip: Default::default(),
346347
};
347348
promoted_mbcx.report_move_errors(move_errors);
348349
errors = promoted_mbcx.errors;
@@ -374,6 +375,7 @@ fn do_mir_borrowck<'tcx>(
374375
next_region_name: RefCell::new(1),
375376
polonius_output,
376377
errors,
378+
to_skip: Default::default(),
377379
};
378380

379381
// Compute and report region errors, if any.
@@ -556,6 +558,8 @@ struct MirBorrowckCtxt<'cx, 'tcx> {
556558
polonius_output: Option<Rc<PoloniusOutput>>,
557559

558560
errors: error::BorrowckErrors<'tcx>,
561+
562+
to_skip: FxHashSet<Location>,
559563
}
560564

561565
// Check that:
@@ -580,8 +584,9 @@ impl<'cx, 'tcx> rustc_mir_dataflow::ResultsVisitor<'cx, 'tcx> for MirBorrowckCtx
580584
match &stmt.kind {
581585
StatementKind::Assign(box (lhs, ref rhs)) => {
582586
self.consume_rvalue(location, (rhs, span), flow_state);
583-
584-
self.mutate_place(location, (*lhs, span), Shallow(None), flow_state);
587+
if !self.to_skip.contains(&location) {
588+
self.mutate_place(location, (*lhs, span), Shallow(None), flow_state);
589+
}
585590
}
586591
StatementKind::FakeRead(box (_, ref place)) => {
587592
// Read for match doesn't access any memory and is used to
@@ -647,29 +652,43 @@ impl<'cx, 'tcx> rustc_mir_dataflow::ResultsVisitor<'cx, 'tcx> for MirBorrowckCtx
647652
TerminatorKind::SwitchInt { ref discr, switch_ty: _, targets: _ } => {
648653
self.consume_operand(loc, (discr, span), flow_state);
649654
}
650-
TerminatorKind::Drop { place, target: _, unwind: _ } => {
655+
TerminatorKind::Drop { place, target, unwind, is_replace } => {
651656
debug!(
652657
"visit_terminator_drop \
653658
loc: {:?} term: {:?} place: {:?} span: {:?}",
654659
loc, term, place, span
655660
);
656661

657-
self.access_place(
658-
loc,
659-
(place, span),
660-
(AccessDepth::Drop, Write(WriteKind::StorageDeadOrDrop)),
661-
LocalMutationIsAllowed::Yes,
662-
flow_state,
663-
);
664-
}
665-
TerminatorKind::DropAndReplace {
666-
place: drop_place,
667-
value: ref new_value,
668-
target: _,
669-
unwind: _,
670-
} => {
671-
self.mutate_place(loc, (drop_place, span), Deep, flow_state);
672-
self.consume_operand(loc, (new_value, span), flow_state);
662+
let next_statement = if is_replace {
663+
self.body()
664+
.basic_blocks
665+
.get(target)
666+
.expect("MIR should be complete at this point")
667+
.statements
668+
.first()
669+
} else {
670+
None
671+
};
672+
673+
match next_statement {
674+
Some(Statement { kind: StatementKind::Assign(_), source_info: _ }) => {
675+
// this is a drop from a replace operation, for better diagnostic report
676+
// here possible conflicts and mute the assign statement errors
677+
self.to_skip.insert(Location { block: target, statement_index: 0 });
678+
self.to_skip
679+
.insert(Location { block: unwind.unwrap(), statement_index: 0 });
680+
self.mutate_place(loc, (place, span), AccessDepth::Deep, flow_state);
681+
}
682+
_ => {
683+
self.access_place(
684+
loc,
685+
(place, span),
686+
(AccessDepth::Drop, Write(WriteKind::StorageDeadOrDrop)),
687+
LocalMutationIsAllowed::Yes,
688+
flow_state,
689+
);
690+
}
691+
}
673692
}
674693
TerminatorKind::Call {
675694
ref func,
@@ -785,7 +804,6 @@ impl<'cx, 'tcx> rustc_mir_dataflow::ResultsVisitor<'cx, 'tcx> for MirBorrowckCtx
785804
| TerminatorKind::Assert { .. }
786805
| TerminatorKind::Call { .. }
787806
| TerminatorKind::Drop { .. }
788-
| TerminatorKind::DropAndReplace { .. }
789807
| TerminatorKind::FalseEdge { real_target: _, imaginary_target: _ }
790808
| TerminatorKind::FalseUnwind { real_target: _, unwind: _ }
791809
| TerminatorKind::Goto { .. }
@@ -1627,7 +1645,8 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
16271645
(prefix, place_span.0, place_span.1),
16281646
mpi,
16291647
);
1630-
} // Only query longest prefix with a MovePath, not further
1648+
}
1649+
// Only query longest prefix with a MovePath, not further
16311650
// ancestors; dataflow recurs on children when parents
16321651
// move (to support partial (re)inits).
16331652
//

compiler/rustc_borrowck/src/type_check/mod.rs

-20
Original file line numberDiff line numberDiff line change
@@ -1348,25 +1348,6 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
13481348
| TerminatorKind::InlineAsm { .. } => {
13491349
// no checks needed for these
13501350
}
1351-
1352-
TerminatorKind::DropAndReplace { ref place, ref value, target: _, unwind: _ } => {
1353-
let place_ty = place.ty(body, tcx).ty;
1354-
let rv_ty = value.ty(body, tcx);
1355-
1356-
let locations = term_location.to_locations();
1357-
if let Err(terr) =
1358-
self.sub_types(rv_ty, place_ty, locations, ConstraintCategory::Assignment)
1359-
{
1360-
span_mirbug!(
1361-
self,
1362-
term,
1363-
"bad DropAndReplace ({:?} = {:?}): {:?}",
1364-
place_ty,
1365-
rv_ty,
1366-
terr
1367-
);
1368-
}
1369-
}
13701351
TerminatorKind::SwitchInt { ref discr, switch_ty, .. } => {
13711352
self.check_operand(discr, term_location);
13721353

@@ -1665,7 +1646,6 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
16651646
}
16661647
TerminatorKind::Unreachable => {}
16671648
TerminatorKind::Drop { target, unwind, .. }
1668-
| TerminatorKind::DropAndReplace { target, unwind, .. }
16691649
| TerminatorKind::Assert { target, cleanup: unwind, .. } => {
16701650
self.assert_iscleanup(body, block_data, target, is_cleanup);
16711651
if let Some(unwind) = unwind {

compiler/rustc_borrowck/src/used_muts.rs

+4-3
Original file line numberDiff line numberDiff line change
@@ -71,9 +71,10 @@ impl<'visit, 'cx, 'tcx> Visitor<'tcx> for GatherUsedMutsVisitor<'visit, 'cx, 'tc
7171
TerminatorKind::Call { destination, .. } => {
7272
self.remove_never_initialized_mut_locals(*destination);
7373
}
74-
TerminatorKind::DropAndReplace { place, .. } => {
75-
self.remove_never_initialized_mut_locals(*place);
76-
}
74+
// FIXME: ??
75+
// TerminatorKind::DropAndReplace { place, .. } => {
76+
// self.remove_never_initialized_mut_locals(*place);
77+
// }
7778
_ => {}
7879
}
7980

compiler/rustc_codegen_cranelift/src/base.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -474,11 +474,10 @@ fn codegen_fn_body(fx: &mut FunctionCx<'_, '_, '_>, start_block: Block) {
474474
TerminatorKind::Yield { .. }
475475
| TerminatorKind::FalseEdge { .. }
476476
| TerminatorKind::FalseUnwind { .. }
477-
| TerminatorKind::DropAndReplace { .. }
478477
| TerminatorKind::GeneratorDrop => {
479478
bug!("shouldn't exist at codegen {:?}", bb_data.terminator());
480479
}
481-
TerminatorKind::Drop { place, target, unwind: _ } => {
480+
TerminatorKind::Drop { place, target, unwind: _, is_replace: _ } => {
482481
let drop_place = codegen_place(fx, *place);
483482
crate::abi::codegen_drop(fx, source_info, drop_place);
484483

compiler/rustc_codegen_cranelift/src/constant.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -541,8 +541,7 @@ pub(crate) fn mir_operand_get_const_val<'tcx>(
541541
| TerminatorKind::Unreachable
542542
| TerminatorKind::Drop { .. }
543543
| TerminatorKind::Assert { .. } => {}
544-
TerminatorKind::DropAndReplace { .. }
545-
| TerminatorKind::Yield { .. }
544+
TerminatorKind::Yield { .. }
546545
| TerminatorKind::GeneratorDrop
547546
| TerminatorKind::FalseEdge { .. }
548547
| TerminatorKind::FalseUnwind { .. } => unreachable!(),

compiler/rustc_codegen_ssa/src/mir/analyze.rs

-1
Original file line numberDiff line numberDiff line change
@@ -281,7 +281,6 @@ pub fn cleanup_kinds(mir: &mir::Body<'_>) -> IndexVec<mir::BasicBlock, CleanupKi
281281
TerminatorKind::Call { cleanup: unwind, .. }
282282
| TerminatorKind::InlineAsm { cleanup: unwind, .. }
283283
| TerminatorKind::Assert { cleanup: unwind, .. }
284-
| TerminatorKind::DropAndReplace { unwind, .. }
285284
| TerminatorKind::Drop { unwind, .. } => {
286285
if let Some(unwind) = unwind {
287286
debug!(

compiler/rustc_codegen_ssa/src/mir/block.rs

+1-5
Original file line numberDiff line numberDiff line change
@@ -1207,7 +1207,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
12071207
bx.unreachable();
12081208
}
12091209

1210-
mir::TerminatorKind::Drop { place, target, unwind } => {
1210+
mir::TerminatorKind::Drop { place, target, unwind, is_replace: _ } => {
12111211
self.codegen_drop_terminator(helper, bx, place, target, unwind);
12121212
}
12131213

@@ -1217,10 +1217,6 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
12171217
);
12181218
}
12191219

1220-
mir::TerminatorKind::DropAndReplace { .. } => {
1221-
bug!("undesugared DropAndReplace in codegen: {:?}", terminator);
1222-
}
1223-
12241220
mir::TerminatorKind::Call {
12251221
ref func,
12261222
ref args,

compiler/rustc_const_eval/src/interpret/terminator.rs

+2-6
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
119119
}
120120
}
121121

122-
Drop { place, target, unwind } => {
122+
Drop { place, target, unwind, is_replace: _ } => {
123123
let place = self.eval_place(place)?;
124124
let ty = place.layout.ty;
125125
trace!("TerminatorKind::drop: {:?}, type {}", place, ty);
@@ -156,11 +156,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
156156
Unreachable => throw_ub!(Unreachable),
157157

158158
// These should never occur for MIR we actually run.
159-
DropAndReplace { .. }
160-
| FalseEdge { .. }
161-
| FalseUnwind { .. }
162-
| Yield { .. }
163-
| GeneratorDrop => span_bug!(
159+
FalseEdge { .. } | FalseUnwind { .. } | Yield { .. } | GeneratorDrop => span_bug!(
164160
terminator.source_info.span,
165161
"{:#?} should have been eliminated by MIR pass",
166162
terminator.kind

compiler/rustc_const_eval/src/transform/check_consts/check.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -965,8 +965,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
965965

966966
// Forbid all `Drop` terminators unless the place being dropped is a local with no
967967
// projections that cannot be `NeedsNonConstDrop`.
968-
TerminatorKind::Drop { place: dropped_place, .. }
969-
| TerminatorKind::DropAndReplace { place: dropped_place, .. } => {
968+
TerminatorKind::Drop { place: dropped_place, .. } => {
970969
// If we are checking live drops after drop-elaboration, don't emit duplicate
971970
// errors here.
972971
if super::post_drop_elaboration::checking_enabled(self.ccx) {

compiler/rustc_const_eval/src/transform/check_consts/post_drop_elaboration.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -80,8 +80,7 @@ impl<'tcx> Visitor<'tcx> for CheckLiveDrops<'_, 'tcx> {
8080
trace!("visit_terminator: terminator={:?} location={:?}", terminator, location);
8181

8282
match &terminator.kind {
83-
mir::TerminatorKind::Drop { place: dropped_place, .. }
84-
| mir::TerminatorKind::DropAndReplace { place: dropped_place, .. } => {
83+
mir::TerminatorKind::Drop { place: dropped_place, .. } => {
8584
let dropped_ty = dropped_place.ty(self.body, self.tcx).ty;
8685
if !NeedsNonConstDrop::in_any_value_of_ty(self.ccx, dropped_ty) {
8786
// Instead of throwing a bug, we just return here. This is because we have to

0 commit comments

Comments
 (0)