Rollup merge of #36171 - jonathandturner:temporary_value, r=nikomatsakis

Update lifetime errors to specifically note temporaries

This PR updates the error message we give in the case of a temporary value not living long enough.

Before:

<img width="497" alt="screen shot 2016-08-31 at 10 02 47 am" src="https://cloud.githubusercontent.com/assets/547158/18138551/27a06794-6f62-11e6-9ee2-bdf8bed75ca7.png">

Now:

<img width="488" alt="screen shot 2016-08-31 at 10 03 01 am" src="https://cloud.githubusercontent.com/assets/547158/18138557/2e5cf322-6f62-11e6-9047-4a78abf3d78c.png">

Specifically, it makes the following changes:

* Detects if a temporary is being used.  If so, it changes the labels to mention that a temporary value specifically is in question
* Simplifies wording of the existing labels to focus on lifetimes rather than values being valid
* Changes the help to a note, since the help+span wasn't as helpful (and sometimes more confusing) than just a note.

r? @nikomatsakis
This commit is contained in:
Jonathan Turner 2016-09-02 15:28:51 -07:00 committed by GitHub
commit 59c0ff6314
6 changed files with 44 additions and 29 deletions

View File

@ -1028,6 +1028,12 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> {
}
err_out_of_scope(super_scope, sub_scope, cause) => {
let (value_kind, value_msg) = match err.cmt.cat {
mc::Categorization::Rvalue(_) =>
("temporary value", "temporary value created here"),
_ =>
("borrowed value", "does not live long enough")
};
match cause {
euv::ClosureCapture(s) => {
// The primary span starts out as the closure creation point.
@ -1038,13 +1044,13 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> {
Some(primary) => {
db.span = MultiSpan::from_span(s);
db.span_label(primary, &format!("capture occurs here"));
db.span_label(s, &format!("does not live long enough"));
db.span_label(s, &value_msg);
}
None => ()
}
}
_ => {
db.span_label(error_span, &format!("does not live long enough"));
db.span_label(error_span, &value_msg);
}
}
@ -1053,14 +1059,15 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> {
match (sub_span, super_span) {
(Some(s1), Some(s2)) if s1 == s2 => {
db.span_label(s1, &"borrowed value dropped before borrower");
db.span_label(s1, &format!("{} dropped before borrower", value_kind));
db.note("values in a scope are dropped in the opposite order \
they are created");
}
_ => {
match sub_span {
Some(s) => {
db.span_label(s, &"borrowed value must be valid until here");
db.span_label(s, &format!("{} needs to live until here",
value_kind));
}
None => {
self.tcx.note_and_explain_region(
@ -1072,7 +1079,7 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> {
}
match super_span {
Some(s) => {
db.span_label(s, &"borrowed value only valid until here");
db.span_label(s, &format!("{} only lives until here", value_kind));
}
None => {
self.tcx.note_and_explain_region(
@ -1085,9 +1092,8 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> {
}
}
if let Some(span) = statement_scope_span(self.tcx, super_scope) {
db.span_help(span,
"consider using a `let` binding to increase its lifetime");
if let Some(_) = statement_scope_span(self.tcx, super_scope) {
db.note("consider using a `let` binding to increase its lifetime");
}
}

View File

@ -25,9 +25,9 @@ fn f() {
v3.push(&'x'); // statement 6
//~^ ERROR borrowed value does not live long enough
//~| NOTE does not live long enough
//~| NOTE borrowed value only valid until here
//~| HELP consider using a `let` binding to increase its lifetime
//~| NOTE temporary value created here
//~| NOTE temporary value only lives until here
//~| NOTE consider using a `let` binding to increase its lifetime
{
@ -35,26 +35,26 @@ fn f() {
v4.push(&'y');
//~^ ERROR borrowed value does not live long enough
//~| NOTE does not live long enough
//~| NOTE borrowed value only valid until here
//~| HELP consider using a `let` binding to increase its lifetime
//~| NOTE temporary value created here
//~| NOTE temporary value only lives until here
//~| NOTE consider using a `let` binding to increase its lifetime
} // (statement 7)
//~^ NOTE borrowed value must be valid until here
//~^ NOTE temporary value needs to live until here
let mut v5 = Vec::new(); // statement 8
v5.push(&'z');
//~^ ERROR borrowed value does not live long enough
//~| NOTE does not live long enough
//~| NOTE borrowed value only valid until here
//~| HELP consider using a `let` binding to increase its lifetime
//~| NOTE temporary value created here
//~| NOTE temporary value only lives until here
//~| NOTE consider using a `let` binding to increase its lifetime
v1.push(&old[0]);
}
//~^ NOTE borrowed value dropped before borrower
//~| NOTE borrowed value must be valid until here
//~| NOTE borrowed value must be valid until here
//~| NOTE temporary value needs to live until here
//~| NOTE temporary value needs to live until here
fn main() {
f();

View File

@ -24,8 +24,8 @@ fn broken() {
x += 1; //~ ERROR cannot assign
//~^ NOTE assignment to borrowed `x` occurs here
}
//~^ NOTE borrowed value only valid until here
//~^ NOTE borrowed value only lives until here
}
//~^ NOTE borrowed value must be valid until here
//~^ NOTE borrowed value needs to live until here
fn main() { }

View File

@ -10,12 +10,7 @@
fn f() {
let x = [1].iter();
//~^ ERROR borrowed value does not live long enough
//~| NOTE does not live long enough
//~| NOTE borrowed value only valid until here
//~| HELP consider using a `let` binding to increase its lifetime
}
//~^ borrowed value must be valid until here
fn main() {
f();

View File

@ -0,0 +1,14 @@
error: borrowed value does not live long enough
--> $DIR/borrowck-let-suggestion.rs:12:13
|
12 | let x = [1].iter();
| ^^^ - temporary value only lives until here
| |
| temporary value created here
13 | }
| - temporary value needs to live until here
|
= note: consider using a `let` binding to increase its lifetime
error: aborting due to previous error

View File

@ -5,10 +5,10 @@ error: `x` does not live long enough
| ^
| |
| does not live long enough
| borrowed value only valid until here
| borrowed value only lives until here
...
23 | }
| - borrowed value must be valid until here
| - borrowed value needs to live until here
error: aborting due to previous error