-
Notifications
You must be signed in to change notification settings - Fork 12.9k
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
Mismatched types diagnostic for async fn return type trusts random returns over function signature #54326
Comments
The code that lowers Edit: was not an easy fix-- what I had in mind would require duplicating the return type in the HIR, which is hard / not possible. |
This shouldn't be solved during desugaring, IMO - we already handle closures nicely, e.g.: fn foo() -> impl Fn() -> i32 {
|| {
if false {
return Ok(6);
}
5
}
} The above example gets the nicer error - but if you put the closure in a variable before returning, you get the suboptimal pair of errors. For generators, even the below example gets the worse errors: #![feature(generators, generator_trait)]
use std::ops::Generator;
fn foo() -> impl Generator<Return = i32> {
|| {
if false {
return Ok(6);
}
yield ();
5
}
} The logic for closures follows below (I think we should generalize it a bit and use it for generators): rust/src/librustc_typeck/check/closure.rs Lines 181 to 359 in 20dc0c5
|
We decided that this bug is not blocking stabilization; confusing though it may be, it's not a severe enough "diagnostic fail" to block stabilization. |
Nonetheless, I've tagged this with E-needs-mentor because it seems eminently fixable, even if not a blocker. |
Current status of this after #60592 is in this Zulip topic. |
I've hit this today and was confused for a while. Here's a playground. |
This is not limited to closures/generators/async await but seems to occur generally with trait Tr {
type A;
}
impl<A> Tr for A {
type A = A;
}
fn f() -> impl Tr<A=u8> {
()
}
Additionally, the second note is wrong ( This does not happen when changing the code to use a boxed trait instead (expected and found are in the right order). |
We actually solved the initial example given (playground): async fn foo() -> i32 {
if false {
return Ok(6);
}
5
}
fn main() { } gives
I think the case that @jonas-schievink is describing is pretty different. I moved it to #68561 and I'm closing this issue. |
With
the errors are:
It seems the compiler prefers to trust the
return Ok(6)
line over the function signature, so it ends up marking the function signature and the one return that matches that signature as errors.In comparison, the diagnostic for regular non-async fns trusts the function signature and flags the
return Ok(6)
as the error.This latter diagnostic is much better since the user presumably wrote the function signature intentionally.
I hit this while refactoring a large async fn, and it took some time to figure out why the compiler kept insisting that the function should return a
Result
when I had no intention for it to do that - a stray early-return in the middle of the function that was returning anOk()
.The text was updated successfully, but these errors were encountered: