-
Notifications
You must be signed in to change notification settings - Fork 13.2k
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
Higher-ranked closure error messages should avoid "anonymous lifetime #2 defined on the body" #45983
Comments
I'd like to work on this if noone is already interested. |
So this specific case:
probably we should say something like
It should be pretty easy to use the routines that @gaurikholkar added to identify which parameter the bound region comes from, at least much of the time (i.e., Not perfect. Thoughts on how to improve? I want to say "cannot escape the closure" but that sounds like jargon. Maybe "data is only borrowed during the closure body"? |
I wonder if it is worth it to also point at the closure as well:
|
@estebank do we have some way to just highlight the |
@nikomatsakis I believe there was a recent change that either added or merely used that, so it is possible. |
@estebank if so, I'd be in favor. Otherwise, we're just setting ourselves up for the "overlapping spans" problem. |
@estebank @nikomatsakis I was pretty much away from keyboard for the last couple days. Finally I'm getting into the issue |
I believe #45927 might be the PR that I'd seen pointing at the closure's arg block. |
The current output is still sub-par, but it is slightly clearer on what is going on:
I now think that the output should point at the closure, the outside binding being affected and its declaration:
|
Custom error when moving arg outside of its closure When given the following code: ```rust fn give_any<F: for<'r> FnOnce(&'r ())>(f: F) { f(&()); } fn main() { let mut x = None; give_any(|y| x = Some(y)); } ``` provide a custom error: ``` error: borrowed data cannot be moved outside of its closure --> file.rs:7:27 | 6 | let mut x = None; | ----- borrowed data cannot be moved into here... 7 | give_any(|y| x = Some(y)); | --- ^ cannot be moved outside of its closure | | | ...because it cannot outlive this closure ``` instead of the generic lifetime error: ``` error[E0495]: cannot infer an appropriate lifetime due to conflicting requirements --> file.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... --> file.rs:7:14 | 7 | give_any(|y| x = Some(y)); | ^^^^^^^^^^^^^^^ note: ...so that expression is assignable (expected &(), found &()) --> file.rs:7:27 | 7 | give_any(|y| x = Some(y)); | ^ note: but, the lifetime must be valid for the block suffix following statement 0 at 6:5... --> file.rs:6:5 | 6 | / let mut x = None; 7 | | give_any(|y| x = Some(y)); 8 | | } | |_^ note: ...so that variable is valid at time of its declaration --> file.rs:6:9 | 6 | let mut x = None; | ^^^^^ ``` Fix #45983.
When a higher-ranked closure is misused, as in:
The compiler gives an obscure error message:
The problem isn't that complicated:
give_any
was declared as takingF: for<'r> FnOnce(&'r ())
, so it can pass ay
can be of type&'α ()
for any lifetime'α
, which might not live long enough to be assigned tox
.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.
cc @cengizio @estebank
The text was updated successfully, but these errors were encountered: