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

Confusing error message when closures return references based on their arguments #135325

Open
uellenberg opened this issue Jan 10, 2025 · 0 comments
Labels
A-diagnostics Area: Messages for errors, warnings, and lints T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@uellenberg
Copy link
Contributor

uellenberg commented Jan 10, 2025

Code

struct Val {
    inner: u32
}

fn main() {
    let get_str = |val: &Val| &val.inner;
    
    println!("{}", get_str(&Val { inner: 1 }));
}

Current output

error: lifetime may not live long enough
 --> src/main.rs:6:31
  |
6 |     let get_str = |val: &Val| &val.inner;
  |                         -   - ^^^^^^^^^^ returning this value requires that `'1` must outlive `'2`
  |                         |   |
  |                         |   return type of closure is &'2 u32
  |                         let's call the lifetime of this reference `'1`

Desired output

Rationale and extra context

I'm not sure what this specific limitation would be called, but I ran into it recently and thought that the error could give some advice on how to solve it. I'm not sure what the best way to do that is, so I haven't filled out the desired output section.

I was a bit surprised to learn that

struct Val {
    inner: u32
}

fn main() {
    let get_str = |val: &Val| -> &u32 { &val.inner };
    
    println!("{}", get_str(&Val { inner: 1 }));
}

still has the same error (namely, &Val and &u32 are assigned two separate lifetimes), whereas

struct Val {
    inner: u32
}

fn main() {
    let get_str: fn(&Val) -> &u32 = |val: &Val| &val.inner;
    
    println!("{}", get_str(&Val { inner: 1 }));
}

fixes the issue. I'm guessing there's some subtle differences in the way a type is created for a closure (even when the return type explicitly written out) versus specifying the type manually, but I'm honestly not sure. If there's some documentation regarding this, it might be a good idea to mention that in the error message.

Other cases

Rust Version

rustc 1.84.0 (9fc6b4312 2025-01-07)
binary: rustc
commit-hash: 9fc6b43126469e3858e2fe86cafb4f0fd5068869
commit-date: 2025-01-07
host: x86_64-unknown-linux-gnu
release: 1.84.0
LLVM version: 19.1.5

Anything else?

No response

@uellenberg uellenberg added A-diagnostics Area: Messages for errors, warnings, and lints T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Jan 10, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-diagnostics Area: Messages for errors, warnings, and lints 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

1 participant