Rollup merge of #107902 - vincenzopalazzo:macros/async_fn_suggestion, r=compiler-errors

fix: improve the suggestion on future not awaited

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 https://github.com/rust-lang/rust/issues/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
```

Fixes https://github.com/rust-lang/rust/issues/80658

It remains to rework the case described in the following issue https://github.com/rust-lang/rust/issues/107899 but I think this deserves its own PR after we discuss a little bit how to handle these kinds of cases.

r? `@eholk`

`@rustbot` label +I-async-nominated

Signed-off-by: Vincenzo Palazzo <vincenzopalazzodev@gmail.com>
This commit is contained in:
Matthias Krüger 2023-02-13 23:25:11 +01:00 committed by GitHub
commit 73b022b8e1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
22 changed files with 132 additions and 116 deletions

View File

@ -1783,14 +1783,24 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
} }
})) }))
{ {
diag.note_expected_found_extra( if let Some(ExpectedFound { found: found_ty, .. }) = exp_found {
&expected_label, // `Future` is a special opaque type that the compiler
expected, // will try to hide in some case such as `async fn`, so
&found_label, // to make an error more use friendly we will
found, // avoid to suggest a mismatch type with a
&sort_string(values.expected, exp_p), // type that the user usually are not usign
&sort_string(values.found, found_p), // directly such as `impl Future<Output = u8>`.
); if !self.tcx.ty_is_opaque_future(found_ty) {
diag.note_expected_found_extra(
&expected_label,
expected,
&found_label,
found,
&sort_string(values.expected, exp_p),
&sort_string(values.found, found_p),
);
}
}
} }
} }
_ => { _ => {
@ -2854,6 +2864,7 @@ impl IntoDiagnosticArg for ObligationCauseAsDiagArg<'_> {
pub enum TyCategory { pub enum TyCategory {
Closure, Closure,
Opaque, Opaque,
OpaqueFuture,
Generator(hir::GeneratorKind), Generator(hir::GeneratorKind),
Foreign, Foreign,
} }
@ -2863,6 +2874,7 @@ impl TyCategory {
match self { match self {
Self::Closure => "closure", Self::Closure => "closure",
Self::Opaque => "opaque type", Self::Opaque => "opaque type",
Self::OpaqueFuture => "future",
Self::Generator(gk) => gk.descr(), Self::Generator(gk) => gk.descr(),
Self::Foreign => "foreign type", Self::Foreign => "foreign type",
} }
@ -2871,7 +2883,11 @@ impl TyCategory {
pub fn from_ty(tcx: TyCtxt<'_>, ty: Ty<'_>) -> Option<(Self, DefId)> { pub fn from_ty(tcx: TyCtxt<'_>, ty: Ty<'_>) -> Option<(Self, DefId)> {
match *ty.kind() { match *ty.kind() {
ty::Closure(def_id, _) => Some((Self::Closure, def_id)), ty::Closure(def_id, _) => Some((Self::Closure, def_id)),
ty::Alias(ty::Opaque, ty::AliasTy { def_id, .. }) => Some((Self::Opaque, def_id)), ty::Alias(ty::Opaque, ty::AliasTy { def_id, .. }) => {
let kind =
if tcx.ty_is_opaque_future(ty) { Self::OpaqueFuture } else { Self::Opaque };
Some((kind, def_id))
}
ty::Generator(def_id, ..) => { ty::Generator(def_id, ..) => {
Some((Self::Generator(tcx.generator_kind(def_id).unwrap()), def_id)) Some((Self::Generator(tcx.generator_kind(def_id).unwrap()), def_id))
} }

View File

@ -238,31 +238,17 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
} }
}, },
(_, Some(ty)) if self.same_type_modulo_infer(exp_found.expected, ty) => { (_, Some(ty)) if self.same_type_modulo_infer(exp_found.expected, ty) => {
diag.span_suggestion_verbose( self.suggest_await_on_future(diag, exp_span);
exp_span.shrink_to_hi(), diag.span_note(exp_span, "calling an async function returns a future");
"consider `await`ing on the `Future`",
".await",
Applicability::MaybeIncorrect,
);
} }
(Some(ty), _) if self.same_type_modulo_infer(ty, exp_found.found) => match cause.code() (Some(ty), _) if self.same_type_modulo_infer(ty, exp_found.found) => match cause.code()
{ {
ObligationCauseCode::Pattern { span: Some(then_span), .. } => { ObligationCauseCode::Pattern { span: Some(then_span), .. } => {
diag.span_suggestion_verbose( self.suggest_await_on_future(diag, then_span.shrink_to_hi());
then_span.shrink_to_hi(),
"consider `await`ing on the `Future`",
".await",
Applicability::MaybeIncorrect,
);
} }
ObligationCauseCode::IfExpression(box IfExpressionCause { then_id, .. }) => { ObligationCauseCode::IfExpression(box IfExpressionCause { then_id, .. }) => {
let then_span = self.find_block_span_from_hir_id(*then_id); let then_span = self.find_block_span_from_hir_id(*then_id);
diag.span_suggestion_verbose( self.suggest_await_on_future(diag, then_span.shrink_to_hi());
then_span.shrink_to_hi(),
"consider `await`ing on the `Future`",
".await",
Applicability::MaybeIncorrect,
);
} }
ObligationCauseCode::MatchExpressionArm(box MatchExpressionArmCause { ObligationCauseCode::MatchExpressionArm(box MatchExpressionArmCause {
ref prior_arms, ref prior_arms,
@ -283,6 +269,15 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
} }
} }
pub fn suggest_await_on_future(&self, diag: &mut Diagnostic, sp: Span) {
diag.span_suggestion_verbose(
sp.shrink_to_hi(),
"consider `await`ing on the `Future`",
".await",
Applicability::MaybeIncorrect,
);
}
pub(super) fn suggest_accessing_field_where_appropriate( pub(super) fn suggest_accessing_field_where_appropriate(
&self, &self,
cause: &ObligationCause<'tcx>, cause: &ObligationCause<'tcx>,

View File

@ -271,7 +271,7 @@ impl<'tcx> Ty<'tcx> {
ty::Infer(ty::FreshFloatTy(_)) => "fresh floating-point type".into(), ty::Infer(ty::FreshFloatTy(_)) => "fresh floating-point type".into(),
ty::Alias(ty::Projection, _) => "associated type".into(), ty::Alias(ty::Projection, _) => "associated type".into(),
ty::Param(p) => format!("type parameter `{p}`").into(), ty::Param(p) => format!("type parameter `{p}`").into(),
ty::Alias(ty::Opaque, ..) => "opaque type".into(), ty::Alias(ty::Opaque, ..) => if tcx.ty_is_opaque_future(self) { "future".into() } else { "opaque type".into() },
ty::Error(_) => "type error".into(), ty::Error(_) => "type error".into(),
_ => { _ => {
let width = tcx.sess.diagnostic_width(); let width = tcx.sess.diagnostic_width();

View File

@ -2,12 +2,15 @@ error[E0308]: mismatched types
--> $DIR/dont-suggest-missing-await.rs:14:18 --> $DIR/dont-suggest-missing-await.rs:14:18
| |
LL | take_u32(x) LL | take_u32(x)
| -------- ^ expected `u32`, found opaque type | -------- ^ expected `u32`, found future
| | | |
| arguments to this function are incorrect | arguments to this function are incorrect
| |
= note: expected type `u32` note: calling an async function returns a future
found opaque type `impl Future<Output = u32>` --> $DIR/dont-suggest-missing-await.rs:14:18
|
LL | take_u32(x)
| ^
note: function defined here note: function defined here
--> $DIR/dont-suggest-missing-await.rs:5:4 --> $DIR/dont-suggest-missing-await.rs:5:4
| |

View File

@ -17,12 +17,10 @@ error[E0308]: mismatched types
--> $DIR/generator-desc.rs:12:16 --> $DIR/generator-desc.rs:12:16
| |
LL | fun(one(), two()); LL | fun(one(), two());
| --- ^^^^^ expected opaque type, found a different opaque type | --- ^^^^^ expected future, found a different future
| | | |
| arguments to this function are incorrect | arguments to this function are incorrect
| |
= note: expected opaque type `impl Future<Output = ()>` (opaque type at <$DIR/generator-desc.rs:5:16>)
found opaque type `impl Future<Output = ()>` (opaque type at <$DIR/generator-desc.rs:6:16>)
= help: consider `await`ing on both `Future`s = help: consider `await`ing on both `Future`s
= note: distinct uses of `impl Trait` result in different opaque types = note: distinct uses of `impl Trait` result in different opaque types
note: function defined here note: function defined here

View File

@ -2,7 +2,7 @@ error[E0053]: method `foo` has an incompatible type for trait
--> $DIR/async-example-desugared-boxed-in-trait.rs:15:28 --> $DIR/async-example-desugared-boxed-in-trait.rs:15:28
| |
LL | async fn foo(&self) -> i32 { LL | async fn foo(&self) -> i32 {
| ^^^ expected `Pin<Box<dyn Future<Output = i32>>>`, found opaque type | ^^^ expected `Pin<Box<dyn Future<Output = i32>>>`, found future
| |
note: type in trait note: type in trait
--> $DIR/async-example-desugared-boxed-in-trait.rs:11:22 --> $DIR/async-example-desugared-boxed-in-trait.rs:11:22

View File

@ -86,7 +86,7 @@ async fn match_() {
match tuple() { //~ HELP consider `await`ing on the `Future` match tuple() { //~ HELP consider `await`ing on the `Future`
//~^ NOTE this expression has type `impl Future<Output = Tuple>` //~^ NOTE this expression has type `impl Future<Output = Tuple>`
Tuple(_) => {} //~ ERROR mismatched types Tuple(_) => {} //~ ERROR mismatched types
//~^ NOTE expected opaque type, found `Tuple` //~^ NOTE expected future, found `Tuple`
//~| NOTE expected opaque type `impl Future<Output = Tuple>` //~| NOTE expected opaque type `impl Future<Output = Tuple>`
} }
} }

View File

@ -62,7 +62,7 @@ LL | match tuple() {
| ------- this expression has type `impl Future<Output = Tuple>` | ------- this expression has type `impl Future<Output = Tuple>`
LL | LL |
LL | Tuple(_) => {} LL | Tuple(_) => {}
| ^^^^^^^^ expected opaque type, found `Tuple` | ^^^^^^^^ expected future, found `Tuple`
| |
= note: expected opaque type `impl Future<Output = Tuple>` = note: expected opaque type `impl Future<Output = Tuple>`
found struct `Tuple` found struct `Tuple`

View File

@ -2,10 +2,8 @@ error[E0271]: expected `callback` to be a fn item that returns `Pin<Box<dyn Futu
--> $DIR/issue-98634.rs:45:23 --> $DIR/issue-98634.rs:45:23
| |
LL | StructAsync { callback }.await; LL | StructAsync { callback }.await;
| ^^^^^^^^ expected `Pin<Box<dyn Future<Output = ()>>>`, found opaque type | ^^^^^^^^ expected `Pin<Box<dyn Future<Output = ()>>>`, found future
| |
= note: expected struct `Pin<Box<(dyn Future<Output = ()> + 'static)>>`
found opaque type `impl Future<Output = ()>`
note: required by a bound in `StructAsync` note: required by a bound in `StructAsync`
--> $DIR/issue-98634.rs:9:35 --> $DIR/issue-98634.rs:9:35
| |
@ -16,10 +14,8 @@ error[E0271]: expected `callback` to be a fn item that returns `Pin<Box<dyn Futu
--> $DIR/issue-98634.rs:45:9 --> $DIR/issue-98634.rs:45:9
| |
LL | StructAsync { callback }.await; LL | StructAsync { callback }.await;
| ^^^^^^^^^^^^^^^^^^^^^^^^ expected `Pin<Box<dyn Future<Output = ()>>>`, found opaque type | ^^^^^^^^^^^^^^^^^^^^^^^^ expected `Pin<Box<dyn Future<Output = ()>>>`, found future
| |
= note: expected struct `Pin<Box<(dyn Future<Output = ()> + 'static)>>`
found opaque type `impl Future<Output = ()>`
note: required by a bound in `StructAsync` note: required by a bound in `StructAsync`
--> $DIR/issue-98634.rs:9:35 --> $DIR/issue-98634.rs:9:35
| |
@ -30,10 +26,8 @@ error[E0271]: expected `callback` to be a fn item that returns `Pin<Box<dyn Futu
--> $DIR/issue-98634.rs:45:33 --> $DIR/issue-98634.rs:45:33
| |
LL | StructAsync { callback }.await; LL | StructAsync { callback }.await;
| ^^^^^^ expected `Pin<Box<dyn Future<Output = ()>>>`, found opaque type | ^^^^^^ expected `Pin<Box<dyn Future<Output = ()>>>`, found future
| |
= note: expected struct `Pin<Box<(dyn Future<Output = ()> + 'static)>>`
found opaque type `impl Future<Output = ()>`
note: required by a bound in `StructAsync` note: required by a bound in `StructAsync`
--> $DIR/issue-98634.rs:9:35 --> $DIR/issue-98634.rs:9:35
| |

View File

@ -4,12 +4,10 @@ error[E0308]: mismatched types
LL | std::mem::size_of_val(foo()); LL | std::mem::size_of_val(foo());
| --------------------- ^^^^^ | --------------------- ^^^^^
| | | | | |
| | expected `&_`, found opaque type | | expected `&_`, found future
| | help: consider borrowing here: `&foo()` | | help: consider borrowing here: `&foo()`
| arguments to this function are incorrect | arguments to this function are incorrect
| |
= note: expected reference `&_`
found opaque type `impl Future<Output = ()>`
note: function defined here note: function defined here
--> $SRC_DIR/core/src/mem/mod.rs:LL:COL --> $SRC_DIR/core/src/mem/mod.rs:LL:COL

View File

@ -2,12 +2,15 @@ error[E0308]: mismatched types
--> $DIR/suggest-missing-await-closure.rs:16:18 --> $DIR/suggest-missing-await-closure.rs:16:18
| |
LL | take_u32(x) LL | take_u32(x)
| -------- ^ expected `u32`, found opaque type | -------- ^ expected `u32`, found future
| | | |
| arguments to this function are incorrect | arguments to this function are incorrect
| |
= note: expected type `u32` note: calling an async function returns a future
found opaque type `impl Future<Output = u32>` --> $DIR/suggest-missing-await-closure.rs:16:18
|
LL | take_u32(x)
| ^
note: function defined here note: function defined here
--> $DIR/suggest-missing-await-closure.rs:6:4 --> $DIR/suggest-missing-await-closure.rs:6:4
| |

View File

@ -2,12 +2,15 @@ error[E0308]: mismatched types
--> $DIR/suggest-missing-await.rs:12:14 --> $DIR/suggest-missing-await.rs:12:14
| |
LL | take_u32(x) LL | take_u32(x)
| -------- ^ expected `u32`, found opaque type | -------- ^ expected `u32`, found future
| | | |
| arguments to this function are incorrect | arguments to this function are incorrect
| |
= note: expected type `u32` note: calling an async function returns a future
found opaque type `impl Future<Output = u32>` --> $DIR/suggest-missing-await.rs:12:14
|
LL | take_u32(x)
| ^
note: function defined here note: function defined here
--> $DIR/suggest-missing-await.rs:3:4 --> $DIR/suggest-missing-await.rs:3:4
| |
@ -22,10 +25,13 @@ error[E0308]: mismatched types
--> $DIR/suggest-missing-await.rs:22:5 --> $DIR/suggest-missing-await.rs:22:5
| |
LL | dummy() LL | dummy()
| ^^^^^^^ expected `()`, found opaque type | ^^^^^^^ expected `()`, found future
| |
= note: expected unit type `()` note: calling an async function returns a future
found opaque type `impl Future<Output = ()>` --> $DIR/suggest-missing-await.rs:22:5
|
LL | dummy()
| ^^^^^^^
help: consider `await`ing on the `Future` help: consider `await`ing on the `Future`
| |
LL | dummy().await LL | dummy().await
@ -45,7 +51,7 @@ LL | | dummy()
LL | | LL | |
LL | | } else { LL | | } else {
LL | | dummy().await LL | | dummy().await
| | ^^^^^^^^^^^^^ expected opaque type, found `()` | | ^^^^^^^^^^^^^ expected future, found `()`
LL | | LL | |
LL | | }; LL | | };
| |_____- `if` and `else` have incompatible types | |_____- `if` and `else` have incompatible types
@ -67,7 +73,7 @@ LL | | 0 => dummy(),
LL | | 1 => dummy(), LL | | 1 => dummy(),
| | ------- this is found to be of type `impl Future<Output = ()>` | | ------- this is found to be of type `impl Future<Output = ()>`
LL | | 2 => dummy().await, LL | | 2 => dummy().await,
| | ^^^^^^^^^^^^^ expected opaque type, found `()` | | ^^^^^^^^^^^^^ expected future, found `()`
LL | | LL | |
LL | | }; LL | | };
| |_____- `match` arms have incompatible types | |_____- `match` arms have incompatible types
@ -86,7 +92,7 @@ error[E0308]: mismatched types
LL | let _x = match dummy() { LL | let _x = match dummy() {
| ------- this expression has type `impl Future<Output = ()>` | ------- this expression has type `impl Future<Output = ()>`
LL | () => {} LL | () => {}
| ^^ expected opaque type, found `()` | ^^ expected future, found `()`
| |
= note: expected opaque type `impl Future<Output = ()>` = note: expected opaque type `impl Future<Output = ()>`
found unit type `()` found unit type `()`
@ -102,7 +108,7 @@ LL | match dummy_result() {
| -------------- this expression has type `impl Future<Output = Result<(), ()>>` | -------------- this expression has type `impl Future<Output = Result<(), ()>>`
... ...
LL | Ok(_) => {} LL | Ok(_) => {}
| ^^^^^ expected opaque type, found `Result<_, _>` | ^^^^^ expected future, found `Result<_, _>`
| |
= note: expected opaque type `impl Future<Output = Result<(), ()>>` = note: expected opaque type `impl Future<Output = Result<(), ()>>`
found enum `Result<_, _>` found enum `Result<_, _>`
@ -118,7 +124,7 @@ LL | match dummy_result() {
| -------------- this expression has type `impl Future<Output = Result<(), ()>>` | -------------- this expression has type `impl Future<Output = Result<(), ()>>`
... ...
LL | Err(_) => {} LL | Err(_) => {}
| ^^^^^^ expected opaque type, found `Result<_, _>` | ^^^^^^ expected future, found `Result<_, _>`
| |
= note: expected opaque type `impl Future<Output = Result<(), ()>>` = note: expected opaque type `impl Future<Output = Result<(), ()>>`
found enum `Result<_, _>` found enum `Result<_, _>`

View File

@ -2,12 +2,15 @@ error[E0308]: mismatched types
--> $DIR/issue-102605.rs:13:20 --> $DIR/issue-102605.rs:13:20
| |
LL | convert_result(foo()) LL | convert_result(foo())
| -------------- ^^^^^ expected `Result<(), _>`, found opaque type | -------------- ^^^^^ expected `Result<(), _>`, found future
| | | |
| arguments to this function are incorrect | arguments to this function are incorrect
| |
= note: expected enum `Result<(), _>` note: calling an async function returns a future
found opaque type `impl Future<Output = Result<(), String>>` --> $DIR/issue-102605.rs:13:20
|
LL | convert_result(foo())
| ^^^^^
note: function defined here note: function defined here
--> $DIR/issue-102605.rs:7:4 --> $DIR/issue-102605.rs:7:4
| |

View File

@ -2,10 +2,8 @@ error[E0308]: mismatched types
--> $DIR/issue-99914.rs:9:27 --> $DIR/issue-99914.rs:9:27
| |
LL | t.and_then(|t| -> _ { bar(t) }); LL | t.and_then(|t| -> _ { bar(t) });
| ^^^^^^ expected `Result<_, Error>`, found opaque type | ^^^^^^ expected `Result<_, Error>`, found future
| |
= note: expected enum `Result<_, Error>`
found opaque type `impl Future<Output = ()>`
help: try wrapping the expression in `Ok` help: try wrapping the expression in `Ok`
| |
LL | t.and_then(|t| -> _ { Ok(bar(t)) }); LL | t.and_then(|t| -> _ { Ok(bar(t)) });

View File

@ -26,8 +26,8 @@ async fn async_extra_semicolon_same() {
//~^ HELP consider removing this semicolon //~^ HELP consider removing this semicolon
} else { } else {
async_dummy() //~ ERROR `if` and `else` have incompatible types async_dummy() //~ ERROR `if` and `else` have incompatible types
//~^ NOTE expected `()`, found opaque type //~^ NOTE expected `()`, found future
//~| NOTE expected unit type `()` //~| NOTE calling an async function returns a future
//~| HELP consider `await`ing on the `Future` //~| HELP consider `await`ing on the `Future`
}; };
} }
@ -39,8 +39,8 @@ async fn async_extra_semicolon_different() {
//~^ HELP consider removing this semicolon //~^ HELP consider removing this semicolon
} else { } else {
async_dummy2() //~ ERROR `if` and `else` have incompatible types async_dummy2() //~ ERROR `if` and `else` have incompatible types
//~^ NOTE expected `()`, found opaque type //~^ NOTE expected `()`, found future
//~| NOTE expected unit type `()` //~| NOTE calling an async function returns a future
//~| HELP consider `await`ing on the `Future` //~| HELP consider `await`ing on the `Future`
}; };
} }
@ -52,8 +52,7 @@ async fn async_different_futures() {
//~| HELP consider `await`ing on both `Future`s //~| HELP consider `await`ing on both `Future`s
} else { } else {
async_dummy2() //~ ERROR `if` and `else` have incompatible types async_dummy2() //~ ERROR `if` and `else` have incompatible types
//~^ NOTE expected opaque type, found a different opaque type //~^ NOTE expected future, found a different future
//~| NOTE expected opaque type `impl Future<Output = ()>`
//~| NOTE distinct uses of `impl Trait` result in different opaque types //~| NOTE distinct uses of `impl Trait` result in different opaque types
}; };
} }

View File

@ -9,14 +9,17 @@ LL | | async_dummy();
LL | | LL | |
LL | | } else { LL | | } else {
LL | | async_dummy() LL | | async_dummy()
| | ^^^^^^^^^^^^^ expected `()`, found opaque type | | ^^^^^^^^^^^^^ expected `()`, found future
... | ... |
LL | | LL | |
LL | | }; LL | | };
| |_____- `if` and `else` have incompatible types | |_____- `if` and `else` have incompatible types
| |
= note: expected unit type `()` note: calling an async function returns a future
found opaque type `impl Future<Output = ()>` --> $DIR/if-then-neeing-semi.rs:28:9
|
LL | async_dummy()
| ^^^^^^^^^^^^^
help: consider `await`ing on the `Future` help: consider `await`ing on the `Future`
| |
LL | async_dummy().await LL | async_dummy().await
@ -38,14 +41,17 @@ LL | | async_dummy();
LL | | LL | |
LL | | } else { LL | | } else {
LL | | async_dummy2() LL | | async_dummy2()
| | ^^^^^^^^^^^^^^ expected `()`, found opaque type | | ^^^^^^^^^^^^^^ expected `()`, found future
... | ... |
LL | | LL | |
LL | | }; LL | | };
| |_____- `if` and `else` have incompatible types | |_____- `if` and `else` have incompatible types
| |
= note: expected unit type `()` note: calling an async function returns a future
found opaque type `impl Future<Output = ()>` --> $DIR/if-then-neeing-semi.rs:41:9
|
LL | async_dummy2()
| ^^^^^^^^^^^^^^
help: consider `await`ing on the `Future` help: consider `await`ing on the `Future`
| |
LL | async_dummy2().await LL | async_dummy2().await
@ -69,14 +75,12 @@ LL | | async_dummy()
LL | | LL | |
LL | | } else { LL | | } else {
LL | | async_dummy2() LL | | async_dummy2()
| | ^^^^^^^^^^^^^^ expected opaque type, found a different opaque type | | ^^^^^^^^^^^^^^ expected future, found a different future
... | LL | |
LL | | LL | |
LL | | }; LL | | };
| |_____- `if` and `else` have incompatible types | |_____- `if` and `else` have incompatible types
| |
= note: expected opaque type `impl Future<Output = ()>` (opaque type at <$DIR/if-then-neeing-semi.rs:18:24>)
found opaque type `impl Future<Output = ()>` (opaque type at <$DIR/if-then-neeing-semi.rs:20:25>)
= note: distinct uses of `impl Trait` result in different opaque types = note: distinct uses of `impl Trait` result in different opaque types
help: consider `await`ing on both `Future`s help: consider `await`ing on both `Future`s
| |

View File

@ -10,12 +10,9 @@ LL | | cx.answer_str("hi");
| | this is found to be of type `()` | | this is found to be of type `()`
LL | | } LL | | }
LL | | _ => cx.answer_str("hi"), LL | | _ => cx.answer_str("hi"),
| | ^^^^^^^^^^^^^^^^^^^ expected `()`, found opaque type | | ^^^^^^^^^^^^^^^^^^^ expected `()`, found future
LL | | } LL | | }
| |_____- `match` arms have incompatible types | |_____- `match` arms have incompatible types
|
= note: expected unit type `()`
found opaque type `impl Future<Output = Test>`
error: aborting due to previous error error: aborting due to previous error

View File

@ -24,8 +24,8 @@ async fn async_extra_semicolon_same() {
//~^ HELP consider removing this semicolon //~^ HELP consider removing this semicolon
} }
false => async_dummy(), //~ ERROR `match` arms have incompatible types false => async_dummy(), //~ ERROR `match` arms have incompatible types
//~^ NOTE expected `()`, found opaque type //~^ NOTE expected `()`, found future
//~| NOTE expected unit type `()` //~| NOTE calling an async function returns a future
//~| HELP consider `await`ing on the `Future` //~| HELP consider `await`ing on the `Future`
}; };
} }
@ -37,8 +37,8 @@ async fn async_extra_semicolon_different() {
//~^ HELP consider removing this semicolon //~^ HELP consider removing this semicolon
} }
false => async_dummy2(), //~ ERROR `match` arms have incompatible types false => async_dummy2(), //~ ERROR `match` arms have incompatible types
//~^ NOTE expected `()`, found opaque type //~^ NOTE expected `()`, found future
//~| NOTE expected unit type `()` //~| NOTE calling an async function returns a future
//~| HELP consider `await`ing on the `Future` //~| HELP consider `await`ing on the `Future`
}; };
} }
@ -48,8 +48,7 @@ async fn async_different_futures() {
true => async_dummy(), //~ NOTE this is found to be true => async_dummy(), //~ NOTE this is found to be
//~| HELP consider `await`ing on both `Future`s //~| HELP consider `await`ing on both `Future`s
false => async_dummy2(), //~ ERROR `match` arms have incompatible types false => async_dummy2(), //~ ERROR `match` arms have incompatible types
//~^ NOTE expected opaque type, found a different opaque type //~^ NOTE expected future, found a different future
//~| NOTE expected opaque type `impl Future<Output = ()>`
//~| NOTE distinct uses of `impl Trait` result in different opaque types //~| NOTE distinct uses of `impl Trait` result in different opaque types
}; };
} }

View File

@ -9,14 +9,17 @@ LL | | async_dummy();
LL | | LL | |
LL | | } LL | | }
LL | | false => async_dummy(), LL | | false => async_dummy(),
| | ^^^^^^^^^^^^^ expected `()`, found opaque type | | ^^^^^^^^^^^^^ expected `()`, found future
... | ... |
LL | | LL | |
LL | | }; LL | | };
| |_____- `match` arms have incompatible types | |_____- `match` arms have incompatible types
| |
= note: expected unit type `()` note: calling an async function returns a future
found opaque type `impl Future<Output = ()>` --> $DIR/match-prev-arm-needing-semi.rs:26:18
|
LL | false => async_dummy(),
| ^^^^^^^^^^^^^
help: consider `await`ing on the `Future` help: consider `await`ing on the `Future`
| |
LL | false => async_dummy().await, LL | false => async_dummy().await,
@ -38,14 +41,17 @@ LL | | async_dummy();
LL | | LL | |
LL | | } LL | | }
LL | | false => async_dummy2(), LL | | false => async_dummy2(),
| | ^^^^^^^^^^^^^^ expected `()`, found opaque type | | ^^^^^^^^^^^^^^ expected `()`, found future
... | ... |
LL | | LL | |
LL | | }; LL | | };
| |_____- `match` arms have incompatible types | |_____- `match` arms have incompatible types
| |
= note: expected unit type `()` note: calling an async function returns a future
found opaque type `impl Future<Output = ()>` --> $DIR/match-prev-arm-needing-semi.rs:39:18
|
LL | false => async_dummy2(),
| ^^^^^^^^^^^^^^
help: consider `await`ing on the `Future` help: consider `await`ing on the `Future`
| |
LL | false => async_dummy2().await, LL | false => async_dummy2().await,
@ -67,14 +73,12 @@ LL | | true => async_dummy(),
| | ------------- this is found to be of type `impl Future<Output = ()>` | | ------------- this is found to be of type `impl Future<Output = ()>`
LL | | LL | |
LL | | false => async_dummy2(), LL | | false => async_dummy2(),
| | ^^^^^^^^^^^^^^ expected opaque type, found a different opaque type | | ^^^^^^^^^^^^^^ expected future, found a different future
... | LL | |
LL | | LL | |
LL | | }; LL | | };
| |_____- `match` arms have incompatible types | |_____- `match` arms have incompatible types
| |
= note: expected opaque type `impl Future<Output = ()>` (opaque type at <$DIR/match-prev-arm-needing-semi.rs:16:24>)
found opaque type `impl Future<Output = ()>` (opaque type at <$DIR/match-prev-arm-needing-semi.rs:18:25>)
= note: distinct uses of `impl Trait` result in different opaque types = note: distinct uses of `impl Trait` result in different opaque types
help: consider `await`ing on both `Future`s help: consider `await`ing on both `Future`s
| |

View File

@ -2,22 +2,20 @@ error[E0308]: `if` and `else` have incompatible types
--> $DIR/opaque-type-error.rs:20:9 --> $DIR/opaque-type-error.rs:20:9
| |
LL | fn thing_one() -> impl Future<Output = Result<(), ()>> { LL | fn thing_one() -> impl Future<Output = Result<(), ()>> {
| ------------------------------------ the expected opaque type | ------------------------------------ the expected future
... ...
LL | fn thing_two() -> impl Future<Output = Result<(), ()>> { LL | fn thing_two() -> impl Future<Output = Result<(), ()>> {
| ------------------------------------ the found opaque type | ------------------------------------ the found future
... ...
LL | / if true { LL | / if true {
LL | | thing_one() LL | | thing_one()
| | ----------- expected because of this | | ----------- expected because of this
LL | | } else { LL | | } else {
LL | | thing_two() LL | | thing_two()
| | ^^^^^^^^^^^ expected opaque type, found a different opaque type | | ^^^^^^^^^^^ expected future, found a different future
LL | | }.await LL | | }.await
| |_____- `if` and `else` have incompatible types | |_____- `if` and `else` have incompatible types
| |
= note: expected opaque type `impl Future<Output = Result<(), ()>>` (opaque type at <$DIR/opaque-type-error.rs:8:19>)
found opaque type `impl Future<Output = Result<(), ()>>` (opaque type at <$DIR/opaque-type-error.rs:12:19>)
= note: distinct uses of `impl Trait` result in different opaque types = note: distinct uses of `impl Trait` result in different opaque types
help: consider `await`ing on both `Future`s help: consider `await`ing on both `Future`s
| |

View File

@ -2,10 +2,8 @@ error[E0271]: expected `test` to be a fn item that returns `Pin<Box<dyn Future<O
--> $DIR/issue-98604.rs:9:5 --> $DIR/issue-98604.rs:9:5
| |
LL | Box::new(test) as AsyncFnPtr; LL | Box::new(test) as AsyncFnPtr;
| ^^^^^^^^^^^^^^ expected `Pin<Box<dyn Future<Output = ()>>>`, found opaque type | ^^^^^^^^^^^^^^ expected `Pin<Box<dyn Future<Output = ()>>>`, found future
| |
= note: expected struct `Pin<Box<(dyn Future<Output = ()> + 'static)>>`
found opaque type `impl Future<Output = ()>`
= note: required for the cast from `fn() -> impl Future<Output = ()> {test}` to the object type `dyn Fn() -> Pin<Box<(dyn Future<Output = ()> + 'static)>>` = note: required for the cast from `fn() -> impl Future<Output = ()> {test}` to the object type `dyn Fn() -> Pin<Box<(dyn Future<Output = ()> + 'static)>>`
error: aborting due to previous error error: aborting due to previous error

View File

@ -18,10 +18,13 @@ error[E0308]: mismatched types
--> $DIR/issue-90027-async-fn-return-suggestion.rs:14:5 --> $DIR/issue-90027-async-fn-return-suggestion.rs:14:5
| |
LL | hello() LL | hello()
| ^^^^^^^ expected `()`, found opaque type | ^^^^^^^ expected `()`, found future
| |
= note: expected unit type `()` note: calling an async function returns a future
found opaque type `impl Future<Output = ()>` --> $DIR/issue-90027-async-fn-return-suggestion.rs:14:5
|
LL | hello()
| ^^^^^^^
help: consider `await`ing on the `Future` help: consider `await`ing on the `Future`
| |
LL | hello().await LL | hello().await