- 
                Notifications
    You must be signed in to change notification settings 
- Fork 13.9k
Open
Labels
A-diagnosticsArea: Messages for errors, warnings, and lintsArea: Messages for errors, warnings, and lintsA-lifetimesArea: Lifetimes / regionsArea: Lifetimes / regionsC-enhancementCategory: An issue proposing an enhancement or a PR with one.Category: An issue proposing an enhancement or a PR with one.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.Relevant to the compiler team, which will review and decide on the PR/issue.
Description
#![feature(nll)]
fn mutate_while_borrowed(x: &mut i32) -> &i32 {
    let y = &*x;
    *x += 1;
    y
}
struct S;
impl S {
    fn wrong_elided_lifetime(&self, x: &i32) -> &i32 {
        x
    }
}Gives these errors
error[E0506]: cannot assign to `*x` because it is borrowed
 --> src/lib.rs:5:5
  |
3 | fn mutate_while_borrowed(x: &mut i32) -> &i32 {
  |                             - let's call the lifetime of this reference `'1`
4 |     let y = &*x;
  |             --- borrow of `*x` occurs here
5 |     *x += 1;
  |     ^^^^^^^ assignment to borrowed `*x` occurs here
6 |     y
  |     - returning this value requires that `*x` is borrowed for `'1`
error: lifetime may not live long enough
  --> src/lib.rs:12:9
   |
11 |     fn wrong_elided_lifetime(&self, x: &i32) -> &i32 {
   |                              -         - let's call the lifetime of this reference `'1`
   |                              |
   |                              let's call the lifetime of this reference `'2`
12 |         x
   |         ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
error: aborting due to 2 previous errors
It's not made clear why the returns are expected to have lifetime '1. It would be helpful to have annotations like
3 | fn mutate_while_borrowed(x: &mut i32) -> &i32 {
  |                             -            - this elided lifetime is inferred to be `'1`
  |                             |
  |                             let's call the lifetime of this reference `'1`
Maybe link to the book section as well? For the second function, maybe adding a named lifetime (f<'a>(&self, &'a i32) -> &'a i32) could be automatically suggested, but that does change the semantics of the function to callers.
Without #![feature(nll)], the second function produces a different error, which could also use these enhancements:
error[E0623]: lifetime mismatch
  --> src/lib.rs:10:9
   |
9  |     fn wrong_elided_lifetime(&self, x: &i32) -> &i32 {
   |                                        ----     ----
   |                                        |
   |                                        this parameter and the return type are declared with different lifetimes...
10 |         x
   |         ^ ...but data from `x` is returned here
@rustbot modify labels: +C-enhancement +A-diagnostics +A-lifetimes
@rustbot claim
Metadata
Metadata
Assignees
Labels
A-diagnosticsArea: Messages for errors, warnings, and lintsArea: Messages for errors, warnings, and lintsA-lifetimesArea: Lifetimes / regionsArea: Lifetimes / regionsC-enhancementCategory: An issue proposing an enhancement or a PR with one.Category: An issue proposing an enhancement or a PR with one.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.Relevant to the compiler team, which will review and decide on the PR/issue.