Skip to content

Commit c8cca6e

Browse files
committed
Suggest that values are dropped in the opposite order they are defined
1 parent eeb1f37 commit c8cca6e

22 files changed

+102
-13
lines changed

src/librustc/mir/mod.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -302,6 +302,19 @@ impl<'tcx> Mir<'tcx> {
302302
}
303303
}
304304

305+
/// Check if `sub` is a sub scope of `sup`
306+
pub fn is_sub_scope(&self, mut sub: SourceScope, sup: SourceScope) -> bool {
307+
loop {
308+
if sub == sup {
309+
return true;
310+
}
311+
match self.source_scopes[sub].parent_scope {
312+
None => return false,
313+
Some(p) => sub = p,
314+
}
315+
}
316+
}
317+
305318
/// Return the return type, it always return first element from `local_decls` array
306319
pub fn return_ty(&self) -> Ty<'tcx> {
307320
self.local_decls[RETURN_PLACE].ty

src/librustc_mir/borrow_check/error_reporting.rs

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11+
use borrow_check::WriteKind;
1112
use syntax_pos::Span;
1213
use rustc::middle::region::ScopeTree;
1314
use rustc::mir::{BorrowKind, Field, Local, LocalKind, Location, Operand};
@@ -162,7 +163,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
162163
format!("borrow of {} occurs here", borrow_msg),
163164
);
164165
err.span_label(span, format!("move out of {} occurs here", value_msg));
165-
self.explain_why_borrow_contains_point(context, borrow, &mut err);
166+
self.explain_why_borrow_contains_point(context, borrow, None, &mut err);
166167
err.emit();
167168
}
168169

@@ -182,7 +183,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
182183
Origin::Mir,
183184
);
184185

185-
self.explain_why_borrow_contains_point(context, borrow, &mut err);
186+
self.explain_why_borrow_contains_point(context, borrow, None, &mut err);
186187

187188
err.emit();
188189
}
@@ -380,7 +381,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
380381
);
381382
}
382383

383-
self.explain_why_borrow_contains_point(context, issued_borrow, &mut err);
384+
self.explain_why_borrow_contains_point(context, issued_borrow, None, &mut err);
384385

385386
err.emit();
386387
}
@@ -389,8 +390,10 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
389390
&mut self,
390391
context: Context,
391392
borrow: &BorrowData<'tcx>,
392-
drop_span: Span,
393+
place_span: (&Place<'tcx>, Span),
394+
kind: Option<WriteKind>,
393395
) {
396+
let drop_span = place_span.1;
394397
let scope_tree = self.tcx.region_scope_tree(self.mir_def_id);
395398
let root_place = self.prefixes(&borrow.borrowed_place, PrefixSet::All)
396399
.last()
@@ -450,6 +453,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
450453
drop_span,
451454
borrow_span,
452455
proper_span,
456+
kind.map(|k| (k, place_span.0)),
453457
);
454458
}
455459
(RegionKind::ReEarlyBound(_), None)
@@ -495,7 +499,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
495499
drop_span,
496500
format!("`{}` dropped here while still borrowed", name),
497501
);
498-
self.explain_why_borrow_contains_point(context, borrow, &mut err);
502+
self.explain_why_borrow_contains_point(context, borrow, None, &mut err);
499503
err.emit();
500504
}
501505

@@ -517,7 +521,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
517521
"temporary value dropped here while still borrowed",
518522
);
519523
err.note("consider using a `let` binding to increase its lifetime");
520-
self.explain_why_borrow_contains_point(context, borrow, &mut err);
524+
self.explain_why_borrow_contains_point(context, borrow, None, &mut err);
521525
err.emit();
522526
}
523527

@@ -530,6 +534,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
530534
drop_span: Span,
531535
borrow_span: Span,
532536
_proper_span: Span,
537+
kind_place: Option<(WriteKind, &Place<'tcx>)>,
533538
) {
534539
debug!(
535540
"report_unscoped_local_value_does_not_live_long_enough(\
@@ -544,7 +549,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
544549
err.span_label(borrow_span, "borrowed value does not live long enough");
545550
err.span_label(drop_span, "borrowed value only lives until here");
546551

547-
self.explain_why_borrow_contains_point(context, borrow, &mut err);
552+
self.explain_why_borrow_contains_point(context, borrow, kind_place, &mut err);
548553
err.emit();
549554
}
550555

@@ -570,7 +575,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
570575
err.span_label(proper_span, "temporary value does not live long enough");
571576
err.span_label(drop_span, "temporary value only lives until here");
572577

573-
self.explain_why_borrow_contains_point(context, borrow, &mut err);
578+
self.explain_why_borrow_contains_point(context, borrow, None, &mut err);
574579
err.emit();
575580
}
576581

@@ -588,7 +593,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
588593
Origin::Mir,
589594
);
590595

591-
self.explain_why_borrow_contains_point(context, loan, &mut err);
596+
self.explain_why_borrow_contains_point(context, loan, None, &mut err);
592597

593598
err.emit();
594599
}

src/librustc_mir/borrow_check/mod.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1050,7 +1050,8 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
10501050
this.report_borrowed_value_does_not_live_long_enough(
10511051
context,
10521052
borrow,
1053-
place_span.1,
1053+
place_span,
1054+
Some(kind),
10541055
);
10551056
}
10561057
WriteKind::Mutate => {
@@ -1328,7 +1329,8 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
13281329
self.report_borrowed_value_does_not_live_long_enough(
13291330
context,
13301331
borrow,
1331-
span,
1332+
(place, span),
1333+
None,
13321334
)
13331335
}
13341336
}

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

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,10 @@
99
// except according to those terms.
1010

1111
use borrow_check::nll::region_infer::{Cause, RegionInferenceContext};
12-
use borrow_check::{Context, MirBorrowckCtxt};
12+
use borrow_check::{Context, MirBorrowckCtxt, WriteKind};
1313
use borrow_check::borrow_set::BorrowData;
1414
use rustc::mir::visit::{MirVisitable, PlaceContext, Visitor};
15-
use rustc::mir::{Local, Location, Mir};
15+
use rustc::mir::{Local, Location, Mir, Place};
1616
use rustc_data_structures::fx::FxHashSet;
1717
use rustc_errors::DiagnosticBuilder;
1818
use util::liveness::{self, DefUse, LivenessMode};
@@ -22,11 +22,21 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
2222
/// point from `context`. This is key for the "3-point errors"
2323
/// [described in the NLL RFC][d].
2424
///
25+
/// # Parameters
26+
///
27+
/// - `borrow`: the borrow in question
28+
/// - `context`: where the borrow occurs
29+
/// - `kind_place`: if Some, this describes the statement that triggered the error.
30+
/// - first half is the kind of write, if any, being performed
31+
/// - second half is the place being accessed
32+
/// - `err`: where the error annotations are going to be added
33+
///
2534
/// [d]: https://rust-lang.github.io/rfcs/2094-nll.html#leveraging-intuition-framing-errors-in-terms-of-points
2635
pub(in borrow_check) fn explain_why_borrow_contains_point(
2736
&mut self,
2837
context: Context,
2938
borrow: &BorrowData<'tcx>,
39+
kind_place: Option<(WriteKind, &Place<'tcx>)>,
3040
err: &mut DiagnosticBuilder<'_>,
3141
) {
3242
let regioncx = &&self.nonlexical_regioncx;
@@ -64,6 +74,17 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
6474
local_name
6575
),
6676
);
77+
78+
if let Some((WriteKind::StorageDeadOrDrop, place)) = kind_place {
79+
if let Place::Local(borrowed_local) = place {
80+
let dropped_local_scope = mir.local_decls[local].visibility_scope;
81+
let borrowed_local_scope = mir.local_decls[*borrowed_local].visibility_scope;
82+
83+
if mir.is_sub_scope(borrowed_local_scope, dropped_local_scope) {
84+
err.note("values in a scope are dropped in the opposite order they are defined");
85+
}
86+
}
87+
}
6788
}
6889
None => {
6990
err.span_label(

src/test/ui/dropck/dropck-eyepatch-extern-crate.nll.stderr

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ LL | }
99
| |
1010
| borrowed value only lives until here
1111
| borrow later used here, when `dt` is dropped
12+
|
13+
= note: values in a scope are dropped in the opposite order they are defined
1214

1315
error: aborting due to previous error
1416

src/test/ui/dropck/dropck-eyepatch-reorder.nll.stderr

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ LL | }
99
| |
1010
| borrowed value only lives until here
1111
| borrow later used here, when `dt` is dropped
12+
|
13+
= note: values in a scope are dropped in the opposite order they are defined
1214

1315
error: aborting due to previous error
1416

src/test/ui/dropck/dropck-eyepatch.nll.stderr

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ LL | }
99
| |
1010
| borrowed value only lives until here
1111
| borrow later used here, when `dt` is dropped
12+
|
13+
= note: values in a scope are dropped in the opposite order they are defined
1214

1315
error: aborting due to previous error
1416

src/test/ui/error-codes/E0597.nll.stderr

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ LL | }
99
| |
1010
| borrowed value only lives until here
1111
| borrow later used here, when `x` is dropped
12+
|
13+
= note: values in a scope are dropped in the opposite order they are defined
1214

1315
error: aborting due to previous error
1416

src/test/ui/generator/dropck.nll.stderr

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ LL | }
99
| |
1010
| borrowed value only lives until here
1111
| borrow later used here, when `gen` is dropped
12+
|
13+
= note: values in a scope are dropped in the opposite order they are defined
1214

1315
error[E0597]: `ref_` does not live long enough
1416
--> $DIR/dropck.rs:22:11
@@ -26,6 +28,8 @@ LL | }
2628
| |
2729
| borrowed value only lives until here
2830
| borrow later used here, when `gen` is dropped
31+
|
32+
= note: values in a scope are dropped in the opposite order they are defined
2933

3034
error: aborting due to 2 previous errors
3135

src/test/ui/span/dropck-object-cycle.nll.stderr

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ LL | }
99
| |
1010
| borrowed value only lives until here
1111
| borrow later used here, when `m` is dropped
12+
|
13+
= note: values in a scope are dropped in the opposite order they are defined
1214

1315
error: aborting due to previous error
1416

src/test/ui/span/dropck_direct_cycle_with_drop.nll.stderr

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ LL | }
99
| |
1010
| borrowed value only lives until here
1111
| borrow later used here, when `d1` is dropped
12+
|
13+
= note: values in a scope are dropped in the opposite order they are defined
1214

1315
error[E0597]: `d2` does not live long enough
1416
--> $DIR/dropck_direct_cycle_with_drop.rs:46:19
@@ -21,6 +23,8 @@ LL | }
2123
| |
2224
| borrowed value only lives until here
2325
| borrow later used here, when `d1` is dropped
26+
|
27+
= note: values in a scope are dropped in the opposite order they are defined
2428

2529
error: aborting due to 2 previous errors
2630

src/test/ui/span/dropck_misc_variants.nll.stderr

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ LL | }
88
| |
99
| borrowed value only lives until here
1010
| borrow later used here, when `_w` is dropped
11+
|
12+
= note: values in a scope are dropped in the opposite order they are defined
1113

1214
error[E0597]: `v` does not live long enough
1315
--> $DIR/dropck_misc_variants.rs:41:27
@@ -20,6 +22,8 @@ LL | }
2022
| |
2123
| borrowed value only lives until here
2224
| borrow later used here, when `_w` is dropped
25+
|
26+
= note: values in a scope are dropped in the opposite order they are defined
2327

2428
error: aborting due to 2 previous errors
2529

src/test/ui/span/issue-24805-dropck-child-has-items-via-parent.nll.stderr

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ LL | }
99
| |
1010
| borrowed value only lives until here
1111
| borrow later used here, when `_d` is dropped
12+
|
13+
= note: values in a scope are dropped in the opposite order they are defined
1214

1315
error: aborting due to previous error
1416

src/test/ui/span/issue-24805-dropck-trait-has-items.nll.stderr

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ LL | }
88
| |
99
| borrowed value only lives until here
1010
| borrow later used here, when `_d` is dropped
11+
|
12+
= note: values in a scope are dropped in the opposite order they are defined
1113

1214
error[E0597]: `d1` does not live long enough
1315
--> $DIR/issue-24805-dropck-trait-has-items.rs:53:33
@@ -19,6 +21,8 @@ LL | }
1921
| |
2022
| borrowed value only lives until here
2123
| borrow later used here, when `_d` is dropped
24+
|
25+
= note: values in a scope are dropped in the opposite order they are defined
2226

2327
error[E0597]: `d1` does not live long enough
2428
--> $DIR/issue-24805-dropck-trait-has-items.rs:59:20
@@ -30,6 +34,8 @@ LL | }
3034
| |
3135
| borrowed value only lives until here
3236
| borrow later used here, when `_d` is dropped
37+
|
38+
= note: values in a scope are dropped in the opposite order they are defined
3339

3440
error: aborting due to 3 previous errors
3541

src/test/ui/span/issue-24895-copy-clone-dropck.nll.stderr

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ LL | }
88
| |
99
| borrowed value only lives until here
1010
| borrow later used here, when `d2` is dropped
11+
|
12+
= note: values in a scope are dropped in the opposite order they are defined
1113

1214
error: aborting due to previous error
1315

src/test/ui/span/issue-26656.nll.stderr

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ LL | }
88
| |
99
| borrowed value only lives until here
1010
| borrow later used here, when `zook` is dropped
11+
|
12+
= note: values in a scope are dropped in the opposite order they are defined
1113

1214
error: aborting due to previous error
1315

src/test/ui/span/issue28498-reject-ex1.nll.stderr

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ LL | }
99
| |
1010
| borrowed value only lives until here
1111
| borrow later used here, when `foo` is dropped
12+
|
13+
= note: values in a scope are dropped in the opposite order they are defined
1214

1315
error: aborting due to previous error
1416

src/test/ui/span/issue28498-reject-lifetime-param.nll.stderr

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ LL | }
99
| |
1010
| borrowed value only lives until here
1111
| borrow later used here, when `foo1` is dropped
12+
|
13+
= note: values in a scope are dropped in the opposite order they are defined
1214

1315
error: aborting due to previous error
1416

src/test/ui/span/issue28498-reject-passed-to-fn.nll.stderr

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ LL | }
99
| |
1010
| borrowed value only lives until here
1111
| borrow later used here, when `foo1` is dropped
12+
|
13+
= note: values in a scope are dropped in the opposite order they are defined
1214

1315
error: aborting due to previous error
1416

src/test/ui/span/issue28498-reject-trait-bound.nll.stderr

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ LL | }
99
| |
1010
| borrowed value only lives until here
1111
| borrow later used here, when `foo1` is dropped
12+
|
13+
= note: values in a scope are dropped in the opposite order they are defined
1214

1315
error: aborting due to previous error
1416

src/test/ui/span/send-is-not-static-std-sync.nll.stderr

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,8 @@ LL | }
6363
...
6464
LL | }
6565
| - borrow later used here, when `tx` is dropped
66+
|
67+
= note: values in a scope are dropped in the opposite order they are defined
6668

6769
error: aborting due to 6 previous errors
6870

0 commit comments

Comments
 (0)