diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs index f885c0a4b87bd..cdc9a21253145 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs @@ -71,7 +71,7 @@ use rustc_middle::ty::{ subst::{GenericArgKind, Subst, SubstsRef}, Region, Ty, TyCtxt, TypeFoldable, }; -use rustc_span::{sym, BytePos, DesugaringKind, Pos, Span}; +use rustc_span::{sym, BytePos, DesugaringKind, MultiSpan, Pos, Span}; use rustc_target::spec::abi; use std::ops::ControlFlow; use std::{cmp, fmt, iter}; @@ -1485,31 +1485,49 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { 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`"); + for &sp in values { + if sp.is_desugaring(DesugaringKind::Async) && !returned_async_output_error { + if &[sp] != err.span.primary_spans() { + let mut span: MultiSpan = sp.into(); + span.push_span_label( + sp, + format!( + "checked the `Output` of this `async fn`, {}{} {}{}", + if count > 1 { "one of the " } else { "" }, + target, + kind, + pluralize!(count), + ), + ); + err.span_note( + span, + "while checking the return type of the `async fn`", + ); + } else { + err.span_label( + sp, + format!( + "checked the `Output` of this `async fn`, {}{} {}{}", + if count > 1 { "one of the " } else { "" }, + target, + kind, + pluralize!(count), + ), + ); + err.note("while checking the return type of the `async fn`"); + } returned_async_output_error = true; + } else { + err.span_label( + sp, + format!( + "{}{} {}{}", + if count == 1 { "the " } else { "one of the " }, + target, + kind, + pluralize!(count), + ), + ); } } } diff --git a/src/test/ui/async-await/dont-suggest-missing-await.stderr b/src/test/ui/async-await/dont-suggest-missing-await.stderr index 654a3bcc92dd8..4dc5cafb98614 100644 --- a/src/test/ui/async-await/dont-suggest-missing-await.stderr +++ b/src/test/ui/async-await/dont-suggest-missing-await.stderr @@ -1,13 +1,14 @@ error[E0308]: mismatched types --> $DIR/dont-suggest-missing-await.rs:14:18 | -LL | async fn make_u32() -> u32 { - | --- checked the `Output` of this `async fn`, found opaque type -... LL | take_u32(x) | ^ expected `u32`, found opaque type | - = note: while checking the return type of the `async fn` +note: while checking the return type of the `async fn` + --> $DIR/dont-suggest-missing-await.rs:7:24 + | +LL | async fn make_u32() -> u32 { + | ^^^ checked the `Output` of this `async fn`, found opaque type = note: expected type `u32` found opaque type `impl Future` help: consider `await`ing on the `Future` diff --git a/src/test/ui/async-await/generator-desc.stderr b/src/test/ui/async-await/generator-desc.stderr index 04f191cc5e8cb..a7aedbb2b322f 100644 --- a/src/test/ui/async-await/generator-desc.stderr +++ b/src/test/ui/async-await/generator-desc.stderr @@ -12,16 +12,19 @@ LL | fun(async {}, async {}); error[E0308]: mismatched types --> $DIR/generator-desc.rs:12:16 | -LL | async fn one() {} - | - checked the `Output` of this `async fn`, expected opaque type -LL | async fn two() {} - | - checked the `Output` of this `async fn`, found opaque type -... LL | fun(one(), two()); | ^^^^^ expected opaque type, found a different opaque type | - = note: while checking the return type of the `async fn` - = note: while checking the return type of the `async fn` +note: while checking the return type of the `async fn` + --> $DIR/generator-desc.rs:5:16 + | +LL | async fn one() {} + | ^ checked the `Output` of this `async fn`, expected opaque type +note: while checking the return type of the `async fn` + --> $DIR/generator-desc.rs:6:16 + | +LL | async fn two() {} + | ^ checked the `Output` of this `async fn`, found opaque type = note: expected opaque type `impl Future` (opaque type at <$DIR/generator-desc.rs:5:16>) found opaque type `impl Future` (opaque type at <$DIR/generator-desc.rs:6:16>) = help: consider `await`ing on both `Future`s diff --git a/src/test/ui/async-await/issue-61076.rs b/src/test/ui/async-await/issue-61076.rs index 9fe3313ee6cc6..220f0774e2d54 100644 --- a/src/test/ui/async-await/issue-61076.rs +++ b/src/test/ui/async-await/issue-61076.rs @@ -57,6 +57,8 @@ async fn struct_() -> Struct { async fn tuple() -> Tuple { //~^ NOTE checked the `Output` of this `async fn`, expected opaque type + //~| NOTE while checking the return type of the `async fn` + //~| NOTE in this expansion of desugaring of `async` block or function Tuple(1i32) } @@ -92,7 +94,6 @@ async fn match_() { Tuple(_) => {} //~ ERROR mismatched types //~^ NOTE expected opaque type, found struct `Tuple` //~| NOTE expected opaque type `impl Future` - //~| NOTE while checking the return type of the `async fn` } } diff --git a/src/test/ui/async-await/issue-61076.stderr b/src/test/ui/async-await/issue-61076.stderr index ba97e135790c1..9fb2d5bc6cb42 100644 --- a/src/test/ui/async-await/issue-61076.stderr +++ b/src/test/ui/async-await/issue-61076.stderr @@ -16,7 +16,7 @@ LL | foo().await?; | ^^^^^^ error[E0277]: the `?` operator can only be applied to values that implement `Try` - --> $DIR/issue-61076.rs:65:5 + --> $DIR/issue-61076.rs:67:5 | LL | t?; | ^^ the `?` operator cannot be applied to type `T` @@ -33,7 +33,7 @@ LL | t.await?; | ^^^^^^ error[E0609]: no field `0` on type `impl Future` - --> $DIR/issue-61076.rs:76:26 + --> $DIR/issue-61076.rs:78:26 | LL | let _: i32 = tuple().0; | ^ field not available in `impl Future`, but it is available in its `Output` @@ -44,7 +44,7 @@ LL | let _: i32 = tuple().await.0; | ^^^^^^ error[E0609]: no field `a` on type `impl Future` - --> $DIR/issue-61076.rs:80:28 + --> $DIR/issue-61076.rs:82:28 | LL | let _: i32 = struct_().a; | ^ field not available in `impl Future`, but it is available in its `Output` @@ -55,7 +55,7 @@ LL | let _: i32 = struct_().await.a; | ^^^^^^ error[E0599]: no method named `method` found for opaque type `impl Future` in the current scope - --> $DIR/issue-61076.rs:84:15 + --> $DIR/issue-61076.rs:86:15 | LL | struct_().method(); | ^^^^^^ method not found in `impl Future` @@ -66,15 +66,16 @@ LL | struct_().await.method(); | ^^^^^^ error[E0308]: mismatched types - --> $DIR/issue-61076.rs:92:9 + --> $DIR/issue-61076.rs:94:9 | -LL | async fn tuple() -> Tuple { - | ----- checked the `Output` of this `async fn`, expected opaque type -... LL | Tuple(_) => {} | ^^^^^^^^ expected opaque type, found struct `Tuple` | - = note: while checking the return type of the `async fn` +note: while checking the return type of the `async fn` + --> $DIR/issue-61076.rs:58:21 + | +LL | async fn tuple() -> Tuple { + | ^^^^^ checked the `Output` of this `async fn`, expected opaque type = note: expected opaque type `impl Future` found struct `Tuple` help: consider `await`ing on the `Future` diff --git a/src/test/ui/async-await/suggest-missing-await-closure.stderr b/src/test/ui/async-await/suggest-missing-await-closure.stderr index 483e52536a1b4..9d742049046b2 100644 --- a/src/test/ui/async-await/suggest-missing-await-closure.stderr +++ b/src/test/ui/async-await/suggest-missing-await-closure.stderr @@ -1,13 +1,14 @@ error[E0308]: mismatched types --> $DIR/suggest-missing-await-closure.rs:16:18 | -LL | async fn make_u32() -> u32 { - | --- checked the `Output` of this `async fn`, found opaque type -... LL | take_u32(x) | ^ expected `u32`, found opaque type | - = note: while checking the return type of the `async fn` +note: while checking the return type of the `async fn` + --> $DIR/suggest-missing-await-closure.rs:8:24 + | +LL | async fn make_u32() -> u32 { + | ^^^ checked the `Output` of this `async fn`, found opaque type = note: expected type `u32` found opaque type `impl Future` help: consider `await`ing on the `Future` diff --git a/src/test/ui/async-await/suggest-missing-await.stderr b/src/test/ui/async-await/suggest-missing-await.stderr index 14b5ee95ee8ba..890f66c58d0f8 100644 --- a/src/test/ui/async-await/suggest-missing-await.stderr +++ b/src/test/ui/async-await/suggest-missing-await.stderr @@ -1,13 +1,14 @@ error[E0308]: mismatched types --> $DIR/suggest-missing-await.rs:12:14 | -LL | async fn make_u32() -> u32 { - | --- checked the `Output` of this `async fn`, found opaque type -... LL | take_u32(x) | ^ expected `u32`, found opaque type | - = note: while checking the return type of the `async fn` +note: while checking the return type of the `async fn` + --> $DIR/suggest-missing-await.rs:5:24 + | +LL | async fn make_u32() -> u32 { + | ^^^ checked the `Output` of this `async fn`, found opaque type = note: expected type `u32` found opaque type `impl Future` help: consider `await`ing on the `Future` @@ -18,13 +19,14 @@ LL | take_u32(x.await) error[E0308]: mismatched types --> $DIR/suggest-missing-await.rs:22:5 | -LL | async fn dummy() {} - | - checked the `Output` of this `async fn`, found opaque type -... LL | dummy() | ^^^^^^^ expected `()`, found opaque type | - = note: while checking the return type of the `async fn` +note: while checking the return type of the `async fn` + --> $DIR/suggest-missing-await.rs:18:18 + | +LL | async fn dummy() {} + | ^ checked the `Output` of this `async fn`, found opaque type = note: expected unit type `()` found opaque type `impl Future` help: consider `await`ing on the `Future` diff --git a/src/test/ui/suggestions/issue-81839.stderr b/src/test/ui/suggestions/issue-81839.stderr index f907658708730..1e0aa9ce40d18 100644 --- a/src/test/ui/suggestions/issue-81839.stderr +++ b/src/test/ui/suggestions/issue-81839.stderr @@ -13,13 +13,12 @@ LL | | _ => cx.answer_str("hi"), | | ^^^^^^^^^^^^^^^^^^^ expected `()`, found opaque type LL | | } | |_____- `match` arms have incompatible types - | - ::: $DIR/auxiliary/issue-81839.rs:6:49 | -LL | pub async fn answer_str(&self, _s: &str) -> Test { - | ---- checked the `Output` of this `async fn`, found opaque type +note: while checking the return type of the `async fn` + --> $DIR/auxiliary/issue-81839.rs:6:49 | - = note: while checking the return type of the `async fn` +LL | pub async fn answer_str(&self, _s: &str) -> Test { + | ^^^^ checked the `Output` of this `async fn`, found opaque type = note: expected type `()` found opaque type `impl Future` diff --git a/src/test/ui/suggestions/match-prev-arm-needing-semi.rs b/src/test/ui/suggestions/match-prev-arm-needing-semi.rs index 3b2cff3140d63..990a4469764f0 100644 --- a/src/test/ui/suggestions/match-prev-arm-needing-semi.rs +++ b/src/test/ui/suggestions/match-prev-arm-needing-semi.rs @@ -14,8 +14,14 @@ fn extra_semicolon() { } async fn async_dummy() {} //~ NOTE checked the `Output` of this `async fn`, found opaque type +//~| NOTE while checking the return type of the `async fn` +//~| NOTE in this expansion of desugaring of `async` block or function async fn async_dummy2() {} //~ NOTE checked the `Output` of this `async fn`, found opaque type //~| NOTE checked the `Output` of this `async fn`, found opaque type +//~| NOTE while checking the return type of the `async fn` +//~| NOTE in this expansion of desugaring of `async` block or function +//~| NOTE while checking the return type of the `async fn` +//~| NOTE in this expansion of desugaring of `async` block or function async fn async_extra_semicolon_same() { let _ = match true { //~ NOTE `match` arms have incompatible types @@ -26,7 +32,6 @@ async fn async_extra_semicolon_same() { false => async_dummy(), //~ ERROR `match` arms have incompatible types //~^ NOTE expected `()`, found opaque type //~| NOTE expected type `()` - //~| NOTE while checking the return type of the `async fn` //~| HELP consider `await`ing on the `Future` }; } @@ -40,7 +45,6 @@ async fn async_extra_semicolon_different() { false => async_dummy2(), //~ ERROR `match` arms have incompatible types //~^ NOTE expected `()`, found opaque type //~| NOTE expected type `()` - //~| NOTE while checking the return type of the `async fn` //~| HELP consider `await`ing on the `Future` }; } @@ -53,7 +57,6 @@ async fn async_different_futures() { //~^ NOTE expected opaque type, found a different opaque type //~| NOTE expected type `impl Future` //~| NOTE distinct uses of `impl Trait` result in different opaque types - //~| NOTE while checking the return type of the `async fn` }; } diff --git a/src/test/ui/suggestions/match-prev-arm-needing-semi.stderr b/src/test/ui/suggestions/match-prev-arm-needing-semi.stderr index e31ea9679b51d..9e64b539f0fdc 100644 --- a/src/test/ui/suggestions/match-prev-arm-needing-semi.stderr +++ b/src/test/ui/suggestions/match-prev-arm-needing-semi.stderr @@ -1,9 +1,6 @@ error[E0308]: `match` arms have incompatible types - --> $DIR/match-prev-arm-needing-semi.rs:26:18 + --> $DIR/match-prev-arm-needing-semi.rs:32:18 | -LL | async fn async_dummy() {} - | - checked the `Output` of this `async fn`, found opaque type -... LL | let _ = match true { | _____________- LL | | true => { @@ -18,7 +15,11 @@ LL | | LL | | }; | |_____- `match` arms have incompatible types | - = note: while checking the return type of the `async fn` +note: while checking the return type of the `async fn` + --> $DIR/match-prev-arm-needing-semi.rs:16:24 + | +LL | async fn async_dummy() {} + | ^ checked the `Output` of this `async fn`, found opaque type = note: expected type `()` found opaque type `impl Future` help: consider `await`ing on the `Future` @@ -31,11 +32,8 @@ LL | async_dummy() | -- error[E0308]: `match` arms have incompatible types - --> $DIR/match-prev-arm-needing-semi.rs:40:18 + --> $DIR/match-prev-arm-needing-semi.rs:45:18 | -LL | async fn async_dummy2() {} - | - checked the `Output` of this `async fn`, found opaque type -... LL | let _ = match true { | _____________- LL | | true => { @@ -50,7 +48,11 @@ LL | | LL | | }; | |_____- `match` arms have incompatible types | - = note: while checking the return type of the `async fn` +note: while checking the return type of the `async fn` + --> $DIR/match-prev-arm-needing-semi.rs:19:25 + | +LL | async fn async_dummy2() {} + | ^ checked the `Output` of this `async fn`, found opaque type = note: expected type `()` found opaque type `impl Future` help: consider `await`ing on the `Future` @@ -66,11 +68,8 @@ LL | false => Box::new(async_dummy2()), | error[E0308]: `match` arms have incompatible types - --> $DIR/match-prev-arm-needing-semi.rs:52:18 + --> $DIR/match-prev-arm-needing-semi.rs:56:18 | -LL | async fn async_dummy2() {} - | - checked the `Output` of this `async fn`, found opaque type -... LL | let _ = match true { | _____________- LL | | true => async_dummy(), @@ -83,9 +82,13 @@ LL | | LL | | }; | |_____- `match` arms have incompatible types | - = note: while checking the return type of the `async fn` +note: while checking the return type of the `async fn` + --> $DIR/match-prev-arm-needing-semi.rs:19:25 + | +LL | async fn async_dummy2() {} + | ^ checked the `Output` of this `async fn`, found opaque type = note: expected type `impl Future` (opaque type at <$DIR/match-prev-arm-needing-semi.rs:16:24>) - found opaque type `impl Future` (opaque type at <$DIR/match-prev-arm-needing-semi.rs:17:25>) + found opaque type `impl Future` (opaque type at <$DIR/match-prev-arm-needing-semi.rs:19:25>) = note: distinct uses of `impl Trait` result in different opaque types help: consider `await`ing on both `Future`s |