Skip to content

Commit 7db49b9

Browse files
committed
Deduplicated borrow checking errors.
1 parent d0f8e29 commit 7db49b9

File tree

1 file changed

+29
-10
lines changed

1 file changed

+29
-10
lines changed

src/librustc_mir/borrow_check.rs

+29-10
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ use rustc::mir::{Mir, Mutability, Operand, Projection, ProjectionElem, Rvalue};
2020
use rustc::mir::{Statement, StatementKind, Terminator, TerminatorKind};
2121
use transform::nll;
2222

23+
use rustc_data_structures::fx::FxHashSet;
2324
use rustc_data_structures::indexed_set::{self, IdxSetBuf};
2425
use rustc_data_structures::indexed_vec::{Idx};
2526

@@ -136,6 +137,7 @@ fn do_mir_borrowck<'a, 'gcx, 'tcx>(infcx: &InferCtxt<'a, 'gcx, 'tcx>,
136137
node_id: id,
137138
move_data: &mdpe.move_data,
138139
param_env: param_env,
140+
storage_drop_or_dead_error_reported: FxHashSet(),
139141
};
140142

141143
let mut state = InProgress::new(flow_borrows,
@@ -153,6 +155,10 @@ pub struct MirBorrowckCtxt<'cx, 'gcx: 'tcx, 'tcx: 'cx> {
153155
node_id: ast::NodeId,
154156
move_data: &'cx MoveData<'tcx>,
155157
param_env: ParamEnv<'gcx>,
158+
/// This field keeps track of when storage drop or dead errors are reported
159+
/// in order to stop duplicate error reporting and identify the conditions required
160+
/// for a "temporary value dropped here while still borrowed" error. See #45360.
161+
storage_drop_or_dead_error_reported: FxHashSet<Local>,
156162
}
157163

158164
// (forced to be `pub` due to its use as an associated type below.)
@@ -281,10 +287,12 @@ impl<'cx, 'gcx, 'tcx> DataflowResultsConsumer<'cx, 'tcx> for MirBorrowckCtxt<'cx
281287
}
282288

283289
StatementKind::StorageDead(local) => {
284-
self.access_lvalue(ContextKind::StorageDead.new(location),
285-
(&Lvalue::Local(local), span),
286-
(Shallow(None), Write(WriteKind::StorageDead)),
287-
flow_state);
290+
if self.storage_drop_or_dead_error_reported.insert(local) {
291+
self.access_lvalue(ContextKind::StorageDead.new(location),
292+
(&Lvalue::Local(local), span),
293+
(Shallow(None), Write(WriteKind::StorageDead)),
294+
flow_state);
295+
}
288296
}
289297
}
290298
}
@@ -604,12 +612,23 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
604612
let erased_ty = gcx.lift(&self.tcx.erase_regions(&ty)).unwrap();
605613
let moves_by_default = erased_ty.moves_by_default(gcx, self.param_env, DUMMY_SP);
606614

607-
if moves_by_default {
608-
// move of lvalue: check if this is move of already borrowed path
609-
self.access_lvalue(context, lvalue_span, (Deep, Write(WriteKind::Move)), flow_state);
610-
} else {
611-
// copy of lvalue: check if this is "copy of frozen path" (FIXME: see check_loans.rs)
612-
self.access_lvalue(context, lvalue_span, (Deep, Read(ReadKind::Copy)), flow_state);
615+
// Check if error has already been reported to stop duplicate reporting.
616+
let has_storage_drop_or_dead_error_reported = match *lvalue {
617+
Lvalue::Local(local) => self.storage_drop_or_dead_error_reported.insert(local),
618+
_ => false,
619+
};
620+
621+
if !has_storage_drop_or_dead_error_reported {
622+
if moves_by_default {
623+
// move of lvalue: check if this is move of already borrowed path
624+
self.access_lvalue(context, lvalue_span, (Deep, Write(WriteKind::Move)),
625+
flow_state);
626+
} else {
627+
// copy of lvalue: check if this is "copy of frozen path"
628+
// (FIXME: see check_loans.rs)
629+
self.access_lvalue(context, lvalue_span, (Deep, Read(ReadKind::Copy)),
630+
flow_state);
631+
}
613632
}
614633

615634
// Finally, check if path was already moved.

0 commit comments

Comments
 (0)