Suggest a let binding to extend temporary lifetimes with NLL
This commit is contained in:
parent
ea6fe08751
commit
54f7311587
@ -24,6 +24,7 @@ use super::borrow_set::BorrowData;
|
||||
use super::{Context, MirBorrowckCtxt};
|
||||
use super::{InitializationRequiringAction, PrefixSet};
|
||||
|
||||
use borrow_check::nll::explain_borrow::BorrowContainsPointReason;
|
||||
use dataflow::drop_flag_effects;
|
||||
use dataflow::move_paths::indexes::MoveOutIndex;
|
||||
use dataflow::move_paths::MovePathIndex;
|
||||
@ -409,6 +410,8 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
|
||||
self.access_place_error_reported
|
||||
.insert((root_place.clone(), borrow_span));
|
||||
|
||||
let borrow_reason = self.find_why_borrow_contains_point(context, borrow);
|
||||
|
||||
let mut err = match &self.describe_place(&borrow.borrowed_place) {
|
||||
Some(_) if self.is_place_thread_local(root_place) => {
|
||||
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> {
|
||||
name,
|
||||
&scope_tree,
|
||||
&borrow,
|
||||
borrow_reason,
|
||||
drop_span,
|
||||
borrow_span,
|
||||
proper_span,
|
||||
kind.map(|k| (k, place_span.0)),
|
||||
),
|
||||
None => self.report_temporary_value_does_not_live_long_enough(
|
||||
context,
|
||||
&scope_tree,
|
||||
&borrow,
|
||||
borrow_reason,
|
||||
drop_span,
|
||||
borrow_span,
|
||||
proper_span,
|
||||
),
|
||||
};
|
||||
@ -444,16 +447,16 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
|
||||
name: &String,
|
||||
scope_tree: &Lrc<ScopeTree>,
|
||||
borrow: &BorrowData<'tcx>,
|
||||
reason: BorrowContainsPointReason<'tcx>,
|
||||
drop_span: Span,
|
||||
borrow_span: Span,
|
||||
_proper_span: Span,
|
||||
kind_place: Option<(WriteKind, &Place<'tcx>)>,
|
||||
) -> DiagnosticBuilder<'cx> {
|
||||
debug!(
|
||||
"report_local_value_does_not_live_long_enough(\
|
||||
{:?}, {:?}, {:?}, {:?}, {:?}, {:?}\
|
||||
{:?}, {:?}, {:?}, {:?}, {:?}, {:?}, {:?}\
|
||||
)",
|
||||
context, name, scope_tree, borrow, drop_span, borrow_span
|
||||
context, name, scope_tree, borrow, reason, drop_span, borrow_span
|
||||
);
|
||||
|
||||
let mut err = self.tcx.path_does_not_live_long_enough(
|
||||
@ -468,7 +471,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
|
||||
format!("`{}` dropped here while still borrowed", name),
|
||||
);
|
||||
|
||||
self.explain_why_borrow_contains_point(context, borrow, kind_place, &mut err);
|
||||
self.report_why_borrow_contains_point(&mut err, reason, kind_place);
|
||||
err
|
||||
}
|
||||
|
||||
@ -501,15 +504,15 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
|
||||
context: Context,
|
||||
scope_tree: &Lrc<ScopeTree>,
|
||||
borrow: &BorrowData<'tcx>,
|
||||
reason: BorrowContainsPointReason<'tcx>,
|
||||
drop_span: Span,
|
||||
_borrow_span: Span,
|
||||
proper_span: Span,
|
||||
) -> DiagnosticBuilder<'cx> {
|
||||
debug!(
|
||||
"report_temporary_value_does_not_live_long_enough(\
|
||||
{:?}, {:?}, {:?}, {:?}, {:?}\
|
||||
{:?}, {:?}, {:?}, {:?}, {:?}, {:?}\
|
||||
)",
|
||||
context, scope_tree, borrow, drop_span, proper_span
|
||||
context, scope_tree, borrow, reason, drop_span, proper_span
|
||||
);
|
||||
|
||||
let tcx = self.tcx;
|
||||
@ -518,7 +521,16 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
|
||||
err.span_label(proper_span, "temporary value does not live long enough");
|
||||
err.span_label(drop_span, "temporary value only lives until here");
|
||||
|
||||
self.explain_why_borrow_contains_point(context, borrow, None, &mut err);
|
||||
// Only give this note and suggestion if they could be relevant
|
||||
match reason {
|
||||
BorrowContainsPointReason::Liveness {..}
|
||||
| BorrowContainsPointReason::DropLiveness {..} => {
|
||||
err.note("consider using a `let` binding to create a longer lived value");
|
||||
}
|
||||
BorrowContainsPointReason::OutlivesFreeRegion {..} => (),
|
||||
}
|
||||
|
||||
self.report_why_borrow_contains_point(&mut err, reason, None);
|
||||
err
|
||||
}
|
||||
|
||||
|
@ -8,6 +8,7 @@ LL | let x = defer(&vec!["Goodbye", "world!"]);
|
||||
LL | x.x[0];
|
||||
| ------ borrow later used here
|
||||
|
|
||||
= note: consider using a `let` binding to create a longer lived value
|
||||
= note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
|
||||
|
||||
error: aborting due to previous error
|
||||
|
@ -8,6 +8,8 @@ LL | buggy_map.insert(42, &*Box::new(1)); //~ ERROR borrowed value does not
|
||||
...
|
||||
LL | buggy_map.insert(43, &*tmp);
|
||||
| --------- borrow later used here
|
||||
|
|
||||
= note: consider using a `let` binding to create a longer lived value
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
@ -8,6 +8,8 @@ LL | let val: &_ = x.borrow().0;
|
||||
...
|
||||
LL | println!("{}", val);
|
||||
| --- borrow later used here
|
||||
|
|
||||
= note: consider using a `let` binding to create a longer lived value
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
@ -8,6 +8,8 @@ LL | let val: &_ = x.borrow().0;
|
||||
...
|
||||
LL | println!("{}", val);
|
||||
| --- borrow later used here
|
||||
|
|
||||
= note: consider using a `let` binding to create a longer lived value
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
@ -28,6 +28,7 @@ fn main() {
|
||||
//[mir]~^^^^^ ERROR borrowed value does not live long enough [E0597]
|
||||
//[mir]~| NOTE temporary value does not live long enough
|
||||
//[mir]~| NOTE temporary value only lives until here
|
||||
//[mir]~| NOTE consider using a `let` binding to create a longer lived value
|
||||
println!("{}", val);
|
||||
//[mir]~^ borrow later used here
|
||||
}
|
||||
|
@ -9,6 +9,7 @@ LL | //~^ ERROR borrowed value does not live long enough
|
||||
LL | x.use_mut();
|
||||
| - borrow later used here
|
||||
|
|
||||
= note: consider using a `let` binding to create a longer lived value
|
||||
= note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
|
||||
|
||||
error: aborting due to previous error
|
||||
|
@ -8,6 +8,8 @@ LL | });
|
||||
| - temporary value only lives until here
|
||||
LL | println!("{:?}", x);
|
||||
| - borrow later used here
|
||||
|
|
||||
= note: consider using a `let` binding to create a longer lived value
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
@ -8,6 +8,7 @@ LL | x = &id(3); //~ ERROR borrowed value does not live long enough
|
||||
LL | assert_eq!(*x, 3);
|
||||
| ------------------ borrow later used here
|
||||
|
|
||||
= note: consider using a `let` binding to create a longer lived value
|
||||
= note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
|
||||
|
||||
error: aborting due to previous error
|
||||
|
@ -8,6 +8,8 @@ LL | v3.push(&id('x')); // statement 6
|
||||
...
|
||||
LL | (v1, v2, v3, /* v4 is above. */ v5).use_ref();
|
||||
| -- borrow later used here
|
||||
|
|
||||
= note: consider using a `let` binding to create a longer lived value
|
||||
|
||||
error[E0597]: borrowed value does not live long enough
|
||||
--> $DIR/borrowck-let-suggestion-suffixes.rs:38:18
|
||||
@ -19,6 +21,8 @@ LL | v4.push(&id('y'));
|
||||
...
|
||||
LL | v4.use_ref();
|
||||
| -- borrow later used here
|
||||
|
|
||||
= note: consider using a `let` binding to create a longer lived value
|
||||
|
||||
error[E0597]: borrowed value does not live long enough
|
||||
--> $DIR/borrowck-let-suggestion-suffixes.rs:49:14
|
||||
@ -30,6 +34,8 @@ LL | v5.push(&id('z'));
|
||||
...
|
||||
LL | (v1, v2, v3, /* v4 is above. */ v5).use_ref();
|
||||
| -- borrow later used here
|
||||
|
|
||||
= note: consider using a `let` binding to create a longer lived value
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
|
||||
|
@ -8,6 +8,8 @@ LL | }
|
||||
| - temporary value only lives until here
|
||||
LL | println!("{}", *msg);
|
||||
| ---- borrow later used here
|
||||
|
|
||||
= note: consider using a `let` binding to create a longer lived value
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
@ -8,6 +8,8 @@ LL | ];
|
||||
...
|
||||
LL | for &&x in &v {
|
||||
| -- borrow later used here
|
||||
|
|
||||
= note: consider using a `let` binding to create a longer lived value
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
@ -8,6 +8,8 @@ LL | }
|
||||
| - temporary value only lives until here
|
||||
LL | }
|
||||
| - borrow later used here, when `blah` is dropped
|
||||
|
|
||||
= note: consider using a `let` binding to create a longer lived value
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
@ -9,6 +9,7 @@ LL | }
|
||||
LL | y.use_ref();
|
||||
| - borrow later used here
|
||||
|
|
||||
= note: consider using a `let` binding to create a longer lived value
|
||||
= note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
|
||||
|
||||
error: aborting due to previous error
|
||||
|
Loading…
x
Reference in New Issue
Block a user