Skip to content

Commit

Permalink
Point at the async fn ident and change wording
Browse files Browse the repository at this point in the history
  • Loading branch information
estebank committed Aug 2, 2021
1 parent 052084a commit bfcaf8b
Show file tree
Hide file tree
Showing 7 changed files with 92 additions and 51 deletions.
86 changes: 56 additions & 30 deletions compiler/rustc_infer/src/infer/error_reporting/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ use rustc_middle::ty::error::TypeError;
use rustc_middle::ty::{
self,
subst::{GenericArgKind, Subst, SubstsRef},
Region, Ty, TyCtxt, TypeFoldable,
DefIdTree, Region, Ty, TyCtxt, TypeFoldable,
};
use rustc_span::{sym, BytePos, DesugaringKind, MultiSpan, Pos, Span};
use rustc_target::spec::abi;
Expand Down Expand Up @@ -1439,9 +1439,9 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
values = None;
}
struct OpaqueTypesVisitor<'tcx> {
types: FxHashMap<TyCategory, FxHashSet<Span>>,
expected: FxHashMap<TyCategory, FxHashSet<Span>>,
found: FxHashMap<TyCategory, FxHashSet<Span>>,
types: FxHashMap<TyCategory, FxHashSet<DefId>>,
expected: FxHashMap<TyCategory, FxHashSet<DefId>>,
found: FxHashMap<TyCategory, FxHashSet<DefId>>,
ignore_span: Span,
tcx: TyCtxt<'tcx>,
}
Expand Down Expand Up @@ -1479,42 +1479,68 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
&self,
err: &mut DiagnosticBuilder<'_>,
target: &str,
types: &FxHashMap<TyCategory, FxHashSet<Span>>,
types: &FxHashMap<TyCategory, FxHashSet<DefId>>,
) {
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 {
for &def_id in values {
let sp = self.tcx.def_span(def_id);
let (fn_name, fn_desc, fn_span) = match self.tcx.parent(def_id) {
Some(def_id) => (
format!("`{}`", self.tcx.def_path_str(def_id)),
format!("the async function `{}`", self.tcx.def_path_str(def_id)),
Some(
self.tcx
.hir()
.get_if_local(def_id)
.and_then(|node| node.ident())
.map_or_else(
|| self.tcx.def_span(def_id),
|ident| ident.span,
),
),
),
None => (
"the async function".to_string(),
"an async function".to_string(),
None,
),
};
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),
),
);
if let Some(fn_span) = fn_span {
span.push_span_label(
fn_span,
"async functions return futures".to_string(),
);
span.push_span_label(
sp,
format!(
"the desugared version of {} returns `impl Future<Output = {}>`",
fn_name,
if let Ok(snippet) = self.tcx.sess.source_map().span_to_snippet(sp) {
snippet
} else {
"{async return type}".to_string()
}
),
);
} else {
span.push_span_label(
sp,
format!("{} returns a future", fn_desc,),
);
}
err.span_note(
span,
"while checking the return type of the `async fn`",
&format!("while checking the return type of {}", fn_desc),
);
} 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`");
err.span_label(sp, format!("{} returns a future", fn_desc));
err.note(&format!("while checking the return type of {}", fn_name));
}
returned_async_output_error = true;
} else {
Expand Down Expand Up @@ -1552,7 +1578,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
// = note: expected unit type `()`
// found closure `[closure@$DIR/issue-20862.rs:2:5: 2:14 x:_]`
if !self.ignore_span.overlaps(span) {
self.types.entry(kind).or_default().insert(span);
self.types.entry(kind).or_default().insert(def_id);
}
}
t.super_visit_with(self)
Expand Down Expand Up @@ -2539,7 +2565,7 @@ impl<'tcx> ObligationCauseExt<'tcx> for ObligationCause<'tcx> {

/// This is a bare signal of what kind of type we're dealing with. `ty::TyKind` tracks
/// extra information about each type, but we only care about the category.
#[derive(Clone, Copy, PartialEq, Eq, Hash)]
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub enum TyCategory {
Closure,
Opaque,
Expand Down
6 changes: 4 additions & 2 deletions src/test/ui/async-await/dont-suggest-missing-await.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,13 @@ error[E0308]: mismatched types
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 function `make_u32`
--> $DIR/dont-suggest-missing-await.rs:7:24
|
LL | async fn make_u32() -> u32 {
| ^^^ checked the `Output` of this `async fn`, found opaque type
| -------- ^^^ the desugared version of `make_u32` returns `impl Future<Output = u32>`
| |
| async functions return futures
= note: expected type `u32`
found opaque type `impl Future`
help: consider `await`ing on the `Future`
Expand Down
12 changes: 8 additions & 4 deletions src/test/ui/async-await/generator-desc.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -15,16 +15,20 @@ error[E0308]: mismatched types
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 function `one`
--> $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`
| --- ^ the desugared version of `one` returns `impl Future<Output = >`
| |
| async functions return futures
note: while checking the return type of the async function `two`
--> $DIR/generator-desc.rs:6:16
|
LL | async fn two() {}
| ^ checked the `Output` of this `async fn`, found opaque type
| --- ^ the desugared version of `two` returns `impl Future<Output = >`
| |
| async functions return futures
= 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
Expand Down
5 changes: 3 additions & 2 deletions src/test/ui/async-await/issue-61076.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,9 @@ 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 while checking the return type of the async function `tuple`
//~| NOTE async functions return futures
//~| NOTE the desugared version of `tuple` returns `impl Future<Output = Tuple>`
//~| NOTE in this expansion of desugaring of `async` block or function
Tuple(1i32)
}
Expand Down
16 changes: 9 additions & 7 deletions src/test/ui/async-await/issue-61076.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ LL | foo().await?;
| ^^^^^^

error[E0277]: the `?` operator can only be applied to values that implement `Try`
--> $DIR/issue-61076.rs:67:5
--> $DIR/issue-61076.rs:68:5
|
LL | t?;
| ^^ the `?` operator cannot be applied to type `T`
Expand All @@ -33,7 +33,7 @@ LL | t.await?;
| ^^^^^^

error[E0609]: no field `0` on type `impl Future`
--> $DIR/issue-61076.rs:78:26
--> $DIR/issue-61076.rs:79:26
|
LL | let _: i32 = tuple().0;
| ^ field not available in `impl Future`, but it is available in its `Output`
Expand All @@ -44,7 +44,7 @@ LL | let _: i32 = tuple().await.0;
| ^^^^^^

error[E0609]: no field `a` on type `impl Future`
--> $DIR/issue-61076.rs:82:28
--> $DIR/issue-61076.rs:83:28
|
LL | let _: i32 = struct_().a;
| ^ field not available in `impl Future`, but it is available in its `Output`
Expand All @@ -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:86:15
--> $DIR/issue-61076.rs:87:15
|
LL | struct_().method();
| ^^^^^^ method not found in `impl Future`
Expand All @@ -66,16 +66,18 @@ LL | struct_().await.method();
| ^^^^^^

error[E0308]: mismatched types
--> $DIR/issue-61076.rs:94:9
--> $DIR/issue-61076.rs:95:9
|
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 function `tuple`
--> $DIR/issue-61076.rs:58:21
|
LL | async fn tuple() -> Tuple {
| ^^^^^ checked the `Output` of this `async fn`, expected opaque type
| ----- ^^^^^ the desugared version of `tuple` returns `impl Future<Output = Tuple>`
| |
| async functions return futures
= note: expected opaque type `impl Future`
found struct `Tuple`
help: consider `await`ing on the `Future`
Expand Down
6 changes: 4 additions & 2 deletions src/test/ui/async-await/suggest-missing-await-closure.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,13 @@ error[E0308]: mismatched types
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 function `make_u32`
--> $DIR/suggest-missing-await-closure.rs:8:24
|
LL | async fn make_u32() -> u32 {
| ^^^ checked the `Output` of this `async fn`, found opaque type
| -------- ^^^ the desugared version of `make_u32` returns `impl Future<Output = u32>`
| |
| async functions return futures
= note: expected type `u32`
found opaque type `impl Future`
help: consider `await`ing on the `Future`
Expand Down
12 changes: 8 additions & 4 deletions src/test/ui/async-await/suggest-missing-await.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,13 @@ error[E0308]: mismatched types
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 function `make_u32`
--> $DIR/suggest-missing-await.rs:5:24
|
LL | async fn make_u32() -> u32 {
| ^^^ checked the `Output` of this `async fn`, found opaque type
| -------- ^^^ the desugared version of `make_u32` returns `impl Future<Output = u32>`
| |
| async functions return futures
= note: expected type `u32`
found opaque type `impl Future`
help: consider `await`ing on the `Future`
Expand All @@ -22,11 +24,13 @@ error[E0308]: mismatched types
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 function `dummy`
--> $DIR/suggest-missing-await.rs:18:18
|
LL | async fn dummy() {}
| ^ checked the `Output` of this `async fn`, found opaque type
| ----- ^ the desugared version of `dummy` returns `impl Future<Output = >`
| |
| async functions return futures
= note: expected unit type `()`
found opaque type `impl Future`
help: consider `await`ing on the `Future`
Expand Down

0 comments on commit bfcaf8b

Please sign in to comment.