Skip to content

Commit 10af6a2

Browse files
committed
Refactor explain_borrow to return explanation.
Previously, explain_borrow would emit an error with the explanation of the a borrow. Now, it returns a enum with what the explanation for the borrow is and any relevant spans or information such that the calling code can choose to emit the same note/suggestion as before by calling the emit method on the new enum.
1 parent 317ae05 commit 10af6a2

File tree

3 files changed

+140
-162
lines changed

3 files changed

+140
-162
lines changed

src/librustc_mir/borrow_check/error_reporting.rs

Lines changed: 44 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,14 @@
1010

1111
use borrow_check::{WriteKind, StorageDeadOrDrop};
1212
use borrow_check::prefixes::IsPrefixOf;
13+
use borrow_check::nll::explain_borrow::BorrowExplanation;
1314
use rustc::middle::region::ScopeTree;
14-
use rustc::mir::VarBindingForm;
15-
use rustc::mir::{BindingForm, BorrowKind, ClearCrossCrate, Field, Local};
16-
use rustc::mir::{FakeReadCause, LocalDecl, LocalKind, Location, Operand, Place};
17-
use rustc::mir::{ProjectionElem, Rvalue, Statement, StatementKind};
15+
use rustc::mir::{
16+
BindingForm, BorrowKind, ClearCrossCrate, Field, FakeReadCause, Local,
17+
LocalDecl, LocalKind, Location, Operand, Place,
18+
ProjectionElem, Rvalue, Statement, StatementKind,
19+
VarBindingForm,
20+
};
1821
use rustc::ty;
1922
use rustc_data_structures::fx::FxHashSet;
2023
use rustc_data_structures::sync::Lrc;
@@ -25,7 +28,6 @@ use super::borrow_set::BorrowData;
2528
use super::{Context, MirBorrowckCtxt};
2629
use super::{InitializationRequiringAction, PrefixSet};
2730

28-
use borrow_check::nll::explain_borrow::BorrowContainsPointReason;
2931
use dataflow::drop_flag_effects;
3032
use dataflow::move_paths::indexes::MoveOutIndex;
3133
use dataflow::move_paths::MovePathIndex;
@@ -226,7 +228,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
226228

227229
move_spans.var_span_label(&mut err, "move occurs due to use in closure");
228230

229-
self.explain_why_borrow_contains_point(context, borrow, None, &mut err);
231+
self.explain_why_borrow_contains_point(context, borrow, None).emit(self.tcx, &mut err);
230232
err.buffer(&mut self.errors_buffer);
231233
}
232234

@@ -263,7 +265,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
263265
format!("borrow occurs due to use of `{}` in closure", desc_place)
264266
});
265267

266-
self.explain_why_borrow_contains_point(context, borrow, None, &mut err);
268+
self.explain_why_borrow_contains_point(context, borrow, None).emit(self.tcx, &mut err);
267269
err.buffer(&mut self.errors_buffer);
268270
}
269271

@@ -390,7 +392,8 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
390392
);
391393
}
392394

393-
self.explain_why_borrow_contains_point(context, issued_borrow, None, &mut err);
395+
self.explain_why_borrow_contains_point(context, issued_borrow, None)
396+
.emit(self.tcx, &mut err);
394397

395398
err.buffer(&mut self.errors_buffer);
396399
}
@@ -445,17 +448,13 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
445448
self.access_place_error_reported
446449
.insert((root_place.clone(), borrow_span));
447450

448-
let borrow_reason = self.find_why_borrow_contains_point(context, borrow);
449-
450-
if let Some(WriteKind::StorageDeadOrDrop(StorageDeadOrDrop::Destructor)) = kind
451-
{
451+
if let Some(WriteKind::StorageDeadOrDrop(StorageDeadOrDrop::Destructor)) = kind {
452452
// If a borrow of path `B` conflicts with drop of `D` (and
453453
// we're not in the uninteresting case where `B` is a
454454
// prefix of `D`), then report this as a more interesting
455455
// destructor conflict.
456456
if !borrow.borrowed_place.is_prefix_of(place_span.0) {
457-
self.report_borrow_conflicts_with_destructor(
458-
context, borrow, borrow_reason, place_span, kind);
457+
self.report_borrow_conflicts_with_destructor(context, borrow, place_span, kind);
459458
return;
460459
}
461460
}
@@ -469,7 +468,6 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
469468
name,
470469
&scope_tree,
471470
&borrow,
472-
borrow_reason,
473471
drop_span,
474472
borrow_span,
475473
kind.map(|k| (k, place_span.0)),
@@ -478,7 +476,6 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
478476
context,
479477
&scope_tree,
480478
&borrow,
481-
borrow_reason,
482479
drop_span,
483480
proper_span,
484481
),
@@ -495,16 +492,15 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
495492
name: &String,
496493
scope_tree: &Lrc<ScopeTree>,
497494
borrow: &BorrowData<'tcx>,
498-
reason: BorrowContainsPointReason<'tcx>,
499495
drop_span: Span,
500496
borrow_span: Span,
501497
kind_place: Option<(WriteKind, &Place<'tcx>)>,
502498
) -> DiagnosticBuilder<'cx> {
503499
debug!(
504500
"report_local_value_does_not_live_long_enough(\
505-
{:?}, {:?}, {:?}, {:?}, {:?}, {:?}, {:?}\
501+
{:?}, {:?}, {:?}, {:?}, {:?}, {:?}\
506502
)",
507-
context, name, scope_tree, borrow, reason, drop_span, borrow_span
503+
context, name, scope_tree, borrow, drop_span, borrow_span
508504
);
509505

510506
let mut err = self.tcx.path_does_not_live_long_enough(
@@ -519,34 +515,32 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
519515
format!("`{}` dropped here while still borrowed", name),
520516
);
521517

522-
self.report_why_borrow_contains_point(&mut err, reason, kind_place);
518+
self.explain_why_borrow_contains_point(context, borrow, kind_place)
519+
.emit(self.tcx, &mut err);
520+
523521
err
524522
}
525523

526524
pub(super) fn report_borrow_conflicts_with_destructor(
527525
&mut self,
528526
context: Context,
529527
borrow: &BorrowData<'tcx>,
530-
borrow_reason: BorrowContainsPointReason<'tcx>,
531-
place_span: (&Place<'tcx>, Span),
528+
(place, drop_span): (&Place<'tcx>, Span),
532529
kind: Option<WriteKind>,
533530
) {
534531
debug!(
535532
"report_borrow_conflicts_with_destructor(\
536-
{:?}, {:?}, {:?}, {:?} {:?}\
533+
{:?}, {:?}, ({:?}, {:?}), {:?}\
537534
)",
538-
context, borrow, borrow_reason, place_span, kind,
535+
context, borrow, place, drop_span, kind,
539536
);
540537

541538
let borrow_spans = self.retrieve_borrow_spans(borrow);
542539
let borrow_span = borrow_spans.var_or_use();
543540

544541
let mut err = self.tcx.cannot_borrow_across_destructor(borrow_span, Origin::Mir);
545542

546-
let drop_span = place_span.1;
547-
548543
let (what_was_dropped, dropped_ty) = {
549-
let place = place_span.0;
550544
let desc = match self.describe_place(place) {
551545
Some(name) => format!("`{}`", name.as_str()),
552546
None => format!("temporary value"),
@@ -571,17 +565,19 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
571565
};
572566
err.span_label(drop_span, label);
573567

574-
// Only give this note and suggestion if they could be relevant
575-
match borrow_reason {
576-
BorrowContainsPointReason::Liveness {..}
577-
| BorrowContainsPointReason::DropLiveness {..} => {
568+
// Only give this note and suggestion if they could be relevant.
569+
let explanation = self.explain_why_borrow_contains_point(
570+
context, borrow, kind.map(|k| (k, place)),
571+
);
572+
match explanation {
573+
BorrowExplanation::UsedLater {..} |
574+
BorrowExplanation::UsedLaterWhenDropped {..} => {
578575
err.note("consider using a `let` binding to create a longer lived value");
579-
}
580-
BorrowContainsPointReason::OutlivesFreeRegion {..} => (),
576+
},
577+
_ => {},
581578
}
582579

583-
self.report_why_borrow_contains_point(
584-
&mut err, borrow_reason, kind.map(|k| (k, place_span.0)));
580+
explanation.emit(self.tcx, &mut err);
585581

586582
err.buffer(&mut self.errors_buffer);
587583
}
@@ -607,6 +603,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
607603
"thread-local variables cannot be borrowed beyond the end of the function",
608604
);
609605
err.span_label(drop_span, "end of enclosing function is here");
606+
610607
err
611608
}
612609

@@ -615,15 +612,14 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
615612
context: Context,
616613
scope_tree: &Lrc<ScopeTree>,
617614
borrow: &BorrowData<'tcx>,
618-
reason: BorrowContainsPointReason<'tcx>,
619615
drop_span: Span,
620616
proper_span: Span,
621617
) -> DiagnosticBuilder<'cx> {
622618
debug!(
623619
"report_temporary_value_does_not_live_long_enough(\
624-
{:?}, {:?}, {:?}, {:?}, {:?}, {:?}\
620+
{:?}, {:?}, {:?}, {:?}, {:?}\
625621
)",
626-
context, scope_tree, borrow, reason, drop_span, proper_span
622+
context, scope_tree, borrow, drop_span, proper_span
627623
);
628624

629625
let tcx = self.tcx;
@@ -632,16 +628,18 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
632628
err.span_label(proper_span, "temporary value does not live long enough");
633629
err.span_label(drop_span, "temporary value only lives until here");
634630

635-
// Only give this note and suggestion if they could be relevant
636-
match reason {
637-
BorrowContainsPointReason::Liveness {..}
638-
| BorrowContainsPointReason::DropLiveness {..} => {
631+
let explanation = self.explain_why_borrow_contains_point(context, borrow, None);
632+
match explanation {
633+
BorrowExplanation::UsedLater(..) |
634+
BorrowExplanation::UsedLaterInLoop(..) |
635+
BorrowExplanation::UsedLaterWhenDropped(..) => {
636+
// Only give this note and suggestion if it could be relevant.
639637
err.note("consider using a `let` binding to create a longer lived value");
640-
}
641-
BorrowContainsPointReason::OutlivesFreeRegion {..} => (),
638+
},
639+
_ => {},
642640
}
641+
explanation.emit(self.tcx, &mut err);
643642

644-
self.report_why_borrow_contains_point(&mut err, reason, None);
645643
err
646644
}
647645

@@ -749,7 +747,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
749747

750748
loan_spans.var_span_label(&mut err, "borrow occurs due to use in closure");
751749

752-
self.explain_why_borrow_contains_point(context, loan, None, &mut err);
750+
self.explain_why_borrow_contains_point(context, loan, None).emit(self.tcx, &mut err);
753751

754752
err.buffer(&mut self.errors_buffer);
755753
}

src/librustc_mir/borrow_check/nll/explain_borrow/find_use.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -121,9 +121,7 @@ struct DefUseVisitor<'cx, 'gcx: 'tcx, 'tcx: 'cx> {
121121

122122
enum DefUseResult {
123123
Def,
124-
125124
UseLive { local: Local },
126-
127125
UseDrop { local: Local },
128126
}
129127

0 commit comments

Comments
 (0)