-
Notifications
You must be signed in to change notification settings - Fork 12.8k
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
Incorrect lifetime error with a generic FnMut after annotating the type in a closure. #22557
Comments
Note that declaring fn bar<'a, 'b, F: FnMut(&'a mut Nothing) -> &'b mut Nothing>(_: F) {} |
The code in the comment seems... bad. This is possibly related to #22077. |
A variant that uses struct Nothing;
fn foo<'a, 'b, F: Fn(&'a Nothing) -> T, T: 'b>(_: F) { }
fn bar<'a, 'b, F: Fn(&'a Nothing) -> &'b Nothing>(_: F) { }
fn main() {
bar(|x| x); // OK
bar(|x: &Nothing| x); // OK
foo(|x| x); // OK
foo(|x: &Nothing| x); // Error
} |
punting to next week's triage. |
an interesting corner case. we could try to fix this (and such a fix should be backwards compatible), but its not a terribly high priority. P-low, I-enhancement |
This is actually the expected behavior, I believe, though writing this comment is making me want to dig a bit deeper to make sure. What is happening is that when an explicit annotation is provided, That said, if my hypothesis is correct, then there are two routes to fix this:
Similarly the example from #22557 (comment) is I think harmless -- basically the caller is providing a fn where 'a and 'b will be bound the same lifetime, and that's ok, but the callee doesn't get to assume that it does. |
OK, so, I looked a bit at this. The reason the results are a bit surprising is that the code is a bit hokey right now but not (I believe) unsound (though it wouldn't surprise me if there was a gotcha in some particular case). One thing it does do is separate out the expected argument and return types. So in these cases part of what results for the inconsistent errors is that we infer the return type based on the expectation. For An example of code that probably ought to compile but doesn't because of this phenomena is: fn main() {
let f = |x: &i32| x;
let i = &3;
let j = f(i);
} In this case, there is no expected return type, so you wind up with a fresh variable, just as in |
This (or something similar) appears to happen with higher-ranked bounds too: fn foo<F>(_: F) where F: for<'a> Fn(&'a str) -> &'a str
{}
fn main() {
foo(|s| s); // ok
foo(|s: &str| s); // not ok
}
|
Expected behavior or not? |
All cases except for @nikomatsakis' no longer cause any error. Should we keep this issue open or reopen a more targeted one for that case? |
Its even questionable whether @nikomatsakis 's example should compile. (To be fair, they did qualify that example with "probably should compile.") Lets close this and open up a separate issue dedicated to that example, especially since I think that example is related to #22340 |
Closing and leaving the remaining example in its own issuein #58052. |
The code:
Playpen
Compiling this on playpen results in this compile error:
I think that this code is supposed to compile, and the error message isn't very helpful either. What exactly is
(expected
&mut Nothing, found
&mut Nothing)
?The text was updated successfully, but these errors were encountered: