- 
                Notifications
    You must be signed in to change notification settings 
- Fork 13.9k
Closed
Labels
A-closuresArea: Closures (`|…| { … }`)Area: Closures (`|…| { … }`)A-diagnosticsArea: Messages for errors, warnings, and lintsArea: Messages for errors, warnings, and lintsC-enhancementCategory: An issue proposing an enhancement or a PR with one.Category: An issue proposing an enhancement or a PR with one.WG-diagnosticsWorking group: DiagnosticsWorking group: Diagnostics
Description
When a higher-ranked closure is misused, as in:
fn give_any<F: for<'r> FnOnce(&'r ())>(f: F) {
    f(&());
}
fn main() {
    let x = None;
    give_any(|y| x = Some(y));
}The compiler gives an obscure error message:
error[E0495]: cannot infer an appropriate lifetime due to conflicting requirements
 --> src/main.rs:7:27
  |
7 |     give_any(|y| x = Some(y));
  |                           ^
  |
note: first, the lifetime cannot outlive the anonymous lifetime #2 defined on the body at 7:14...
 --> src/main.rs:7:14
  |
7 |     give_any(|y| x = Some(y));
  |              ^^^^^^^^^^^^^^^
note: ...so that expression is assignable (expected &(), found &())
 --> src/main.rs:7:27
  |
7 |     give_any(|y| x = Some(y));
  |                           ^
note: but, the lifetime must be valid for the expression at 7:14...
 --> src/main.rs:7:14
  |
7 |     give_any(|y| x = Some(y));
  |              ^^^^^^^^^^^^^^^
note: ...so type `[closure@src/main.rs:7:14: 7:29 x:&mut std::option::Option<&()>]` of expression is valid during the expression
 --> src/main.rs:7:14
  |
7 |     give_any(|y| x = Some(y));
  |              ^^^^^^^^^^^^^^^
error: aborting due to previous error
The problem isn't that complicated: give_any was declared as taking F: for<'r> FnOnce(&'r ()), so it can pass a y can be of type &'α () for any lifetime 'α, which might not live long enough to be assigned to x.
However, the error message talks about an "anonymous lifetime #2 defined on the body", which is not something someone can understand without knowing the compiler. It should at least mention the problem argument.
estebank
Metadata
Metadata
Assignees
Labels
A-closuresArea: Closures (`|…| { … }`)Area: Closures (`|…| { … }`)A-diagnosticsArea: Messages for errors, warnings, and lintsArea: Messages for errors, warnings, and lintsC-enhancementCategory: An issue proposing an enhancement or a PR with one.Category: An issue proposing an enhancement or a PR with one.WG-diagnosticsWorking group: DiagnosticsWorking group: Diagnostics