Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

create a specific error for temporary values that are borrowed too long #54131

Closed
nikomatsakis opened this issue Sep 11, 2018 · 2 comments
Closed
Assignees
Labels
A-NLL Area: Non-lexical lifetimes (NLL) NLL-diagnostics Working towards the "diagnostic parity" goal T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@nikomatsakis
Copy link
Contributor

nikomatsakis commented Sep 11, 2018

Carrying over a comment from #54088:

I feel like the temporary rules are a common source of confusion. I think we should consider using a distinct error code for them, so that --explain can have some extra text to introduce the rules. Maybe good for a follow-up to this PR though.

As a specific example, consider this test:

let x = gimme({
let v = 22;
&(v,)
//~^ ERROR borrowed value does not live long enough [E0597]
});

we give this error:

error[E0597]: borrowed value does not live long enough
--> $DIR/borrowed-temporary-error.rs:20:10
|
LL | &(v,)
| ^^^^ temporary value does not live long enough
LL | //~^ ERROR borrowed value does not live long enough [E0597]
LL | });
| - temporary value only lives until here
LL | println!("{:?}", x);
| - borrow later used here

but I think we should say something more like this:

error[E9999]: temporary value borrowed for too long
  --> $DIR/borrowed-temporary-error.rs:20:10
   |
LL |         &(v,)
   |          ^^^^ creates a temporary which is freed while still in use
LL |         //~^ ERROR borrowed value does not live long enough [E0597]
LL |     });
   |       - temporary value is freed at the end of this statement
LL |     println!("{:?}", x);
   |                      - but the borrow is later used here

Moreover, the extended error for E9999 ought to explain the temporary rules.

@nikomatsakis nikomatsakis added T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. A-NLL Area: Non-lexical lifetimes (NLL) NLL-diagnostics Working towards the "diagnostic parity" goal labels Sep 11, 2018
@nikomatsakis nikomatsakis added this to the Edition 2018 RC 2 milestone Sep 11, 2018
@nikomatsakis
Copy link
Contributor Author

nikomatsakis commented Sep 11, 2018

Here are some notes on what we might say in the extended error:

When you write &expr and expr is not a "path" rooted in some variable (e.g., &foo.bar) but rather something that creates a new value (e.g., &foo()), a temporary will be created:

let x = foo();
let y = &x;

If this temporary expression is assigned directly into a let, or into a tuple or struct that is assigned into a let, it lives until the end of the block:

Example:

{ 
    let x = &foo(); // <-- temporary is created here
    ...
} // <-- and then freed here

Otherwise, the temporary is freed at the end of the statement. This most commonly occurs with function call arguments:

let p = bar(&foo()); // <-- temporary is freed after this statement

If p here borrows from the temporary, then you are going to get an error, because the temporary gets freed while still in use. You can add a temporary to extend the lifetime:

let tmp_ref = &foo(); // freed at end of block
let p = bar(tmp_ref); 
...

@mikhail-m1
Copy link
Contributor

I can take it if no one already started

mikhail-m1 added a commit to mikhail-m1/rust that referenced this issue Sep 23, 2018
mikhail-m1 added a commit to mikhail-m1/rust that referenced this issue Sep 25, 2018
bors added a commit that referenced this issue Sep 26, 2018
add "temporary value borrowed for too long" error

Issue #54131

r? @nikomatsakis
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-NLL Area: Non-lexical lifetimes (NLL) NLL-diagnostics Working towards the "diagnostic parity" goal T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

No branches or pull requests

2 participants