Skip to content

Commit 54f7311

Browse files
committed
Suggest a let binding to extend temporary lifetimes with NLL
1 parent ea6fe08 commit 54f7311

14 files changed

+47
-10
lines changed

Diff for: src/librustc_mir/borrow_check/error_reporting.rs

+22-10
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ use super::borrow_set::BorrowData;
2424
use super::{Context, MirBorrowckCtxt};
2525
use super::{InitializationRequiringAction, PrefixSet};
2626

27+
use borrow_check::nll::explain_borrow::BorrowContainsPointReason;
2728
use dataflow::drop_flag_effects;
2829
use dataflow::move_paths::indexes::MoveOutIndex;
2930
use dataflow::move_paths::MovePathIndex;
@@ -409,6 +410,8 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
409410
self.access_place_error_reported
410411
.insert((root_place.clone(), borrow_span));
411412

413+
let borrow_reason = self.find_why_borrow_contains_point(context, borrow);
414+
412415
let mut err = match &self.describe_place(&borrow.borrowed_place) {
413416
Some(_) if self.is_place_thread_local(root_place) => {
414417
self.report_thread_local_value_does_not_live_long_enough(drop_span, borrow_span)
@@ -418,17 +421,17 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
418421
name,
419422
&scope_tree,
420423
&borrow,
424+
borrow_reason,
421425
drop_span,
422426
borrow_span,
423-
proper_span,
424427
kind.map(|k| (k, place_span.0)),
425428
),
426429
None => self.report_temporary_value_does_not_live_long_enough(
427430
context,
428431
&scope_tree,
429432
&borrow,
433+
borrow_reason,
430434
drop_span,
431-
borrow_span,
432435
proper_span,
433436
),
434437
};
@@ -444,16 +447,16 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
444447
name: &String,
445448
scope_tree: &Lrc<ScopeTree>,
446449
borrow: &BorrowData<'tcx>,
450+
reason: BorrowContainsPointReason<'tcx>,
447451
drop_span: Span,
448452
borrow_span: Span,
449-
_proper_span: Span,
450453
kind_place: Option<(WriteKind, &Place<'tcx>)>,
451454
) -> DiagnosticBuilder<'cx> {
452455
debug!(
453456
"report_local_value_does_not_live_long_enough(\
454-
{:?}, {:?}, {:?}, {:?}, {:?}, {:?}\
457+
{:?}, {:?}, {:?}, {:?}, {:?}, {:?}, {:?}\
455458
)",
456-
context, name, scope_tree, borrow, drop_span, borrow_span
459+
context, name, scope_tree, borrow, reason, drop_span, borrow_span
457460
);
458461

459462
let mut err = self.tcx.path_does_not_live_long_enough(
@@ -468,7 +471,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
468471
format!("`{}` dropped here while still borrowed", name),
469472
);
470473

471-
self.explain_why_borrow_contains_point(context, borrow, kind_place, &mut err);
474+
self.report_why_borrow_contains_point(&mut err, reason, kind_place);
472475
err
473476
}
474477

@@ -501,15 +504,15 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
501504
context: Context,
502505
scope_tree: &Lrc<ScopeTree>,
503506
borrow: &BorrowData<'tcx>,
507+
reason: BorrowContainsPointReason<'tcx>,
504508
drop_span: Span,
505-
_borrow_span: Span,
506509
proper_span: Span,
507510
) -> DiagnosticBuilder<'cx> {
508511
debug!(
509512
"report_temporary_value_does_not_live_long_enough(\
510-
{:?}, {:?}, {:?}, {:?}, {:?}\
513+
{:?}, {:?}, {:?}, {:?}, {:?}, {:?}\
511514
)",
512-
context, scope_tree, borrow, drop_span, proper_span
515+
context, scope_tree, borrow, reason, drop_span, proper_span
513516
);
514517

515518
let tcx = self.tcx;
@@ -518,7 +521,16 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
518521
err.span_label(proper_span, "temporary value does not live long enough");
519522
err.span_label(drop_span, "temporary value only lives until here");
520523

521-
self.explain_why_borrow_contains_point(context, borrow, None, &mut err);
524+
// Only give this note and suggestion if they could be relevant
525+
match reason {
526+
BorrowContainsPointReason::Liveness {..}
527+
| BorrowContainsPointReason::DropLiveness {..} => {
528+
err.note("consider using a `let` binding to create a longer lived value");
529+
}
530+
BorrowContainsPointReason::OutlivesFreeRegion {..} => (),
531+
}
532+
533+
self.report_why_borrow_contains_point(&mut err, reason, None);
522534
err
523535
}
524536

Diff for: src/test/ui/borrowck/borrowck-borrowed-uniq-rvalue-2.nll.stderr

+1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ LL | let x = defer(&vec!["Goodbye", "world!"]);
88
LL | x.x[0];
99
| ------ borrow later used here
1010
|
11+
= note: consider using a `let` binding to create a longer lived value
1112
= note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
1213

1314
error: aborting due to previous error

Diff for: src/test/ui/borrowck/borrowck-borrowed-uniq-rvalue.nll.stderr

+2
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ LL | buggy_map.insert(42, &*Box::new(1)); //~ ERROR borrowed value does not
88
...
99
LL | buggy_map.insert(43, &*tmp);
1010
| --------- borrow later used here
11+
|
12+
= note: consider using a `let` binding to create a longer lived value
1113

1214
error: aborting due to previous error
1315

Diff for: src/test/ui/issues/issue-36082.ast.nll.stderr

+2
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ LL | let val: &_ = x.borrow().0;
88
...
99
LL | println!("{}", val);
1010
| --- borrow later used here
11+
|
12+
= note: consider using a `let` binding to create a longer lived value
1113

1214
error: aborting due to previous error
1315

Diff for: src/test/ui/issues/issue-36082.mir.stderr

+2
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ LL | let val: &_ = x.borrow().0;
88
...
99
LL | println!("{}", val);
1010
| --- borrow later used here
11+
|
12+
= note: consider using a `let` binding to create a longer lived value
1113

1214
error: aborting due to previous error
1315

Diff for: src/test/ui/issues/issue-36082.rs

+1
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ fn main() {
2828
//[mir]~^^^^^ ERROR borrowed value does not live long enough [E0597]
2929
//[mir]~| NOTE temporary value does not live long enough
3030
//[mir]~| NOTE temporary value only lives until here
31+
//[mir]~| NOTE consider using a `let` binding to create a longer lived value
3132
println!("{}", val);
3233
//[mir]~^ borrow later used here
3334
}

Diff for: src/test/ui/lifetimes/borrowck-let-suggestion.nll.stderr

+1
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ LL | //~^ ERROR borrowed value does not live long enough
99
LL | x.use_mut();
1010
| - borrow later used here
1111
|
12+
= note: consider using a `let` binding to create a longer lived value
1213
= note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
1314

1415
error: aborting due to previous error

Diff for: src/test/ui/nll/borrowed-temporary-error.stderr

+2
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ LL | });
88
| - temporary value only lives until here
99
LL | println!("{:?}", x);
1010
| - borrow later used here
11+
|
12+
= note: consider using a `let` binding to create a longer lived value
1113

1214
error: aborting due to previous error
1315

Diff for: src/test/ui/regions/regions-var-type-out-of-scope.nll.stderr

+1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ LL | x = &id(3); //~ ERROR borrowed value does not live long enough
88
LL | assert_eq!(*x, 3);
99
| ------------------ borrow later used here
1010
|
11+
= note: consider using a `let` binding to create a longer lived value
1112
= note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
1213

1314
error: aborting due to previous error

Diff for: src/test/ui/span/borrowck-let-suggestion-suffixes.nll.stderr

+6
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ LL | v3.push(&id('x')); // statement 6
88
...
99
LL | (v1, v2, v3, /* v4 is above. */ v5).use_ref();
1010
| -- borrow later used here
11+
|
12+
= note: consider using a `let` binding to create a longer lived value
1113

1214
error[E0597]: borrowed value does not live long enough
1315
--> $DIR/borrowck-let-suggestion-suffixes.rs:38:18
@@ -19,6 +21,8 @@ LL | v4.push(&id('y'));
1921
...
2022
LL | v4.use_ref();
2123
| -- borrow later used here
24+
|
25+
= note: consider using a `let` binding to create a longer lived value
2226

2327
error[E0597]: borrowed value does not live long enough
2428
--> $DIR/borrowck-let-suggestion-suffixes.rs:49:14
@@ -30,6 +34,8 @@ LL | v5.push(&id('z'));
3034
...
3135
LL | (v1, v2, v3, /* v4 is above. */ v5).use_ref();
3236
| -- borrow later used here
37+
|
38+
= note: consider using a `let` binding to create a longer lived value
3339

3440
error: aborting due to 3 previous errors
3541

Diff for: src/test/ui/span/borrowck-ref-into-rvalue.nll.stderr

+2
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ LL | }
88
| - temporary value only lives until here
99
LL | println!("{}", *msg);
1010
| ---- borrow later used here
11+
|
12+
= note: consider using a `let` binding to create a longer lived value
1113

1214
error: aborting due to previous error
1315

Diff for: src/test/ui/span/issue-15480.nll.stderr

+2
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ LL | ];
88
...
99
LL | for &&x in &v {
1010
| -- borrow later used here
11+
|
12+
= note: consider using a `let` binding to create a longer lived value
1113

1214
error: aborting due to previous error
1315

Diff for: src/test/ui/span/regions-close-over-borrowed-ref-in-obj.nll.stderr

+2
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ LL | }
88
| - temporary value only lives until here
99
LL | }
1010
| - borrow later used here, when `blah` is dropped
11+
|
12+
= note: consider using a `let` binding to create a longer lived value
1113

1214
error: aborting due to previous error
1315

Diff for: src/test/ui/span/slice-borrow.nll.stderr

+1
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ LL | }
99
LL | y.use_ref();
1010
| - borrow later used here
1111
|
12+
= note: consider using a `let` binding to create a longer lived value
1213
= note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
1314

1415
error: aborting due to previous error

0 commit comments

Comments
 (0)