-
Notifications
You must be signed in to change notification settings - Fork 12.7k
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
Note when opaque future from async fn
is involved in a type mismatch is unclear
#80658
Comments
Looks like #66463 touched areas of code that are relevant to this issue (not to say that it caused the issue, only that it provides a potential pointer to the parts of the code related to generating this error message) |
@nellshamrell Are you still planning to work on this? If not no worries, feel free to release your assignment. |
…tebank Reword labels on E0308 involving async fn return type Fix for rust-lang#80658. When someone writes code like this: ```rust fn foo() -> u8 { async fn async_fn() -> () {} async_fn() } ``` And they try to compile it, they will see an error that looks like this: ```bash error[E0308]: mismatched types --> test.rs:4:5 | 1 | fn foo() -> u8 { | -- expected `u8` because of return type 2 | async fn async_fn() -> () {} | -- checked the `Output` of this `async fn`, found opaque type 3 | 4 | async_fn() | ^^^^^^^^^^ expected `u8`, found opaque type | = note: while checking the return type of this `async fn` = note: expected type `u8` found opaque type `impl Future` ```
…tebank Reword labels on E0308 involving async fn return type Fix for rust-lang#80658. When someone writes code like this: ```rust fn foo() -> u8 { async fn async_fn() -> () {} async_fn() } ``` And they try to compile it, they will see an error that looks like this: ```bash error[E0308]: mismatched types --> test.rs:4:5 | 1 | fn foo() -> u8 { | -- expected `u8` because of return type 2 | async fn async_fn() -> () {} | -- checked the `Output` of this `async fn`, found opaque type 3 | 4 | async_fn() | ^^^^^^^^^^ expected `u8`, found opaque type | = note: while checking the return type of this `async fn` = note: expected type `u8` found opaque type `impl Future` ```
…tebank Reword labels on E0308 involving async fn return type Fix for rust-lang#80658. When someone writes code like this: ```rust fn foo() -> u8 { async fn async_fn() -> () {} async_fn() } ``` And they try to compile it, they will see an error that looks like this: ```bash error[E0308]: mismatched types --> test.rs:4:5 | 1 | fn foo() -> u8 { | -- expected `u8` because of return type 2 | async fn async_fn() -> () {} | -- checked the `Output` of this `async fn`, found opaque type 3 | 4 | async_fn() | ^^^^^^^^^^ expected `u8`, found opaque type | = note: while checking the return type of this `async fn` = note: expected type `u8` found opaque type `impl Future` ```
Can't this issue be closed (#82165) or is there still more work to be done? |
The note seems clearer now:
But it would be good to get confirmation that this is fixed before closing. |
"checked the (Oops, did I confuse the issue by giving |
This is going to be a very common scenario. I'd prefer to see a more radically improved error message. What I posted on #84166 was something like
|
@rustbot assign @nellshamrell |
So I was looking at this in order to write mentoring instructions. I note that the example in the OP contains a kind of type error (the async function is returning If we rewrite to this example: fn foo() -> u8 {
async fn async_fn() -> u8 { 22 }
async_fn()
} we presently get this error:
|
I would like to give this error;
which isn't that far apart. |
I believe the current "help" is generated by this function: rust/compiler/rustc_infer/src/infer/error_reporting/mod.rs Lines 1731 to 1755 in e5615dc
although there are some other places that generate similar messages (e.g., here). |
This in turn is invoked from rust/compiler/rustc_infer/src/infer/error_reporting/mod.rs Lines 1424 to 1431 in e5615dc
|
This could be a bit difficult because the setup is currently very oriented at adding helps and notes to an existing error ( rust/compiler/rustc_infer/src/infer/error_reporting/mod.rs Lines 1941 to 1946 in e5615dc
although |
You'll have to dig a bit through the code to see just how hard it is to decide when the I think if I were going to do this I might keep the logic in |
Not sure @nellshamrell if that helps at all =) |
FINALLY have some time to devote to this. Thank you so much for the pointers, @nikomatsakis, that helps a lot! |
Repro stepsAdding some repro steps for my own reference (and for anyone else!) $ cargo new troubleshooting_example
$ cd troubleshooting_example Head into fn foo() -> u8 {
async fn async_fn() -> u8 { 22 }
async_fn()
} Actual behavior$ cargo build
error[E0308]: mismatched types
--> src/lib.rs:4:5
|
1 | fn foo() -> u8 {
| -- expected `u8` because of return type
2 | async fn async_fn() -> u8 { 22 }
| -- the `Output` of this `async fn`'s found opaque type
3 |
4 | async_fn()
| ^^^^^^^^^^ expected `u8`, found opaque type
|
= note: expected type `u8`
found opaque type `impl std::future::Future`
error: aborting due to previous error
For more information about this error, try `rustc --explain E0308`.
error: could not compile `troubleshooting_example`.
To learn more, run the command again with --verbose. Desired behavior$ cargo build
error[E0308]: missing await on future
--> src/main.rs:8:12
|
1 | fn foo() -> u8 {
| -- expected `u8` because of return type
2 | async fn async_fn() -> u8 { 22 }
| ----- calling an async function returns a future
3 |
4 | async_fn()
| ^^^^^^^^^^ expected `u8`, found future
|
help: consider `await`ing on the `Future`
|
4 | async_fn().await
| ^^^^^^
error: aborting due to previous error |
NotesRelevant files/functionscompiler/rustc_infer/src/infer/error_reporting/mod.rsadd_labels_for_types This function adds some wording async errors (this is where I focused in #82165) fn add_labels_for_types(
&self,
err: &mut DiagnosticBuilder<'_>,
target: &str,
types: &FxHashMap<TyCategory, FxHashSet<Span>>,
) {
for (key, values) in types.iter() {
let count = values.len();
let kind = key.descr();
let mut returned_async_output_error = false;
for sp in values {
err.span_label(
*sp,
format!(
"{}{}{} {}{}",
if sp.is_desugaring(DesugaringKind::Async)
&& !returned_async_output_error
{
"checked the `Output` of this `async fn`, "
} else if count == 1 {
"the "
} else {
""
},
if count > 1 { "one of the " } else { "" },
target,
kind,
pluralize!(count),
),
);
if sp.is_desugaring(DesugaringKind::Async)
&& returned_async_output_error == false
{
err.note("while checking the return type of the `async fn`");
returned_async_output_error = true;
}
}
}
}
} suggest_await_on_expect_found This appears to generate the help text in the relevant async error from the example, particularly this section: (_, Some(ty)) if ty::TyS::same_type(exp_found.expected, ty) => {
let span = match cause.code {
// scrutinee's span
ObligationCauseCode::Pattern { span: Some(span), .. } => span,
_ => exp_span,
};
diag.span_suggestion_verbose(
span.shrink_to_hi(),
"consider `await`ing on the `Future`",
".await".to_string(),
Applicability::MaybeIncorrect,
);
} note_type_err This function calls if let Some(exp_found) = exp_found {
self.suggest_as_ref_where_appropriate(span, &exp_found, diag);
self.suggest_accessing_field_where_appropriate(cause, &exp_found, diag);
self.suggest_await_on_expect_found(cause, span, &exp_found, diag);
} |
@nellshamrell sounds good-- let me know if I can help |
I've completed a partial fix for this at this time. When running the above example, I now get this output: nell@DESKTOP-VBH9MU6:~/rust/troubleshooting_example$ rustc +rust-stage-1 src/lib.rs --edition 2018
error[E0308]: mismatched types
--> src/lib.rs:4:5
|
1 | fn foo() -> u8 {
| -- expected `u8` because of return type
2 | async fn async_fn() -> u8 { 22 }
| -- calling an async function returns a future
3 |
4 | async_fn()
| ^^^^^^^^^^ expected `u8`, found opaque type
|
= note: while checking the return type of the `async fn`
= note: expected type `u8`
found opaque type `impl Future`
help: consider `await`ing on the `Future`
|
4 | async_fn().await
| ^^^^^^
error: aborting due to 2 previous errors
Some errors have detailed explanations: E0308, E0601.
For more information about an error, try `rustc --explain E0308`. Seeing if I can further improve it. |
I'm trying to figure out where in the code "^^^^^^^^^^ expected |
@nellshamrell there is some generic machinery to manage type mismatches, I guess it's there somewhere |
I've opened a PR with at least a partial fix for this issue: #86705 |
Is this still an issue? The current output for the test case (playground) is:
which looks pretty close to the desired output listed above. |
@rustbot claim I will take a look as discussed in one of the async team meeting |
Considering the following code ```rust fn foo() -> u8 { async fn async_fn() -> u8 { 22 } async_fn() } fn main() {} ``` the error generated before this commit from the compiler is ``` ➜ rust git:(macros/async_fn_suggestion) ✗ rustc test.rs --edition 2021 error[E0308]: mismatched types --> test.rs:4:5 | 1 | fn foo() -> u8 { | -- expected `u8` because of return type ... 4 | async_fn() | ^^^^^^^^^^ expected `u8`, found opaque type | = note: expected type `u8` found opaque type `impl Future<Output = u8>` help: consider `await`ing on the `Future` | 4 | async_fn().await | ++++++ error: aborting due to previous error ``` In this case the error is nor perfect, and can confuse the user that do not know that the opaque type is the future. So this commit will propose (and conclude the work start in rust-lang#80658) to change the string `opaque type` to `future` when applicable and also remove the Expected vs Received note by adding a more specific one regarding the async function that return a future type. So the new error emitted by the compiler is ``` error[E0308]: mismatched types --> test.rs:4:5 | 1 | fn foo() -> u8 { | -- expected `u8` because of return type ... 4 | async_fn() | ^^^^^^^^^^ expected `u8`, found future | note: calling an async function returns a future --> test.rs:4:5 | 4 | async_fn() | ^^^^^^^^^^ help: consider `await`ing on the `Future` | 4 | async_fn().await | ++++++ error: aborting due to previous error ``` Signed-off-by: Vincenzo Palazzo <[email protected]>
emits
The note "the
Output
of thisasync fn
's found opaque type" is kind of hard to understand. If the return type ofasync_fn
isn't explicitly given, it doesn't even point at a type:Perhaps the note should instead look like this:
@rustbot label A-async-await A-diagnostics D-confusing T-compiler
The text was updated successfully, but these errors were encountered: