Skip to content

Commit bfcaf8b

Browse files
committed
Point at the async fn ident and change wording
1 parent 052084a commit bfcaf8b

File tree

7 files changed

+92
-51
lines changed

7 files changed

+92
-51
lines changed

compiler/rustc_infer/src/infer/error_reporting/mod.rs

+56-30
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ use rustc_middle::ty::error::TypeError;
6969
use rustc_middle::ty::{
7070
self,
7171
subst::{GenericArgKind, Subst, SubstsRef},
72-
Region, Ty, TyCtxt, TypeFoldable,
72+
DefIdTree, Region, Ty, TyCtxt, TypeFoldable,
7373
};
7474
use rustc_span::{sym, BytePos, DesugaringKind, MultiSpan, Pos, Span};
7575
use rustc_target::spec::abi;
@@ -1439,9 +1439,9 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
14391439
values = None;
14401440
}
14411441
struct OpaqueTypesVisitor<'tcx> {
1442-
types: FxHashMap<TyCategory, FxHashSet<Span>>,
1443-
expected: FxHashMap<TyCategory, FxHashSet<Span>>,
1444-
found: FxHashMap<TyCategory, FxHashSet<Span>>,
1442+
types: FxHashMap<TyCategory, FxHashSet<DefId>>,
1443+
expected: FxHashMap<TyCategory, FxHashSet<DefId>>,
1444+
found: FxHashMap<TyCategory, FxHashSet<DefId>>,
14451445
ignore_span: Span,
14461446
tcx: TyCtxt<'tcx>,
14471447
}
@@ -1479,42 +1479,68 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
14791479
&self,
14801480
err: &mut DiagnosticBuilder<'_>,
14811481
target: &str,
1482-
types: &FxHashMap<TyCategory, FxHashSet<Span>>,
1482+
types: &FxHashMap<TyCategory, FxHashSet<DefId>>,
14831483
) {
14841484
for (key, values) in types.iter() {
14851485
let count = values.len();
14861486
let kind = key.descr();
14871487
let mut returned_async_output_error = false;
1488-
for &sp in values {
1488+
for &def_id in values {
1489+
let sp = self.tcx.def_span(def_id);
1490+
let (fn_name, fn_desc, fn_span) = match self.tcx.parent(def_id) {
1491+
Some(def_id) => (
1492+
format!("`{}`", self.tcx.def_path_str(def_id)),
1493+
format!("the async function `{}`", self.tcx.def_path_str(def_id)),
1494+
Some(
1495+
self.tcx
1496+
.hir()
1497+
.get_if_local(def_id)
1498+
.and_then(|node| node.ident())
1499+
.map_or_else(
1500+
|| self.tcx.def_span(def_id),
1501+
|ident| ident.span,
1502+
),
1503+
),
1504+
),
1505+
None => (
1506+
"the async function".to_string(),
1507+
"an async function".to_string(),
1508+
None,
1509+
),
1510+
};
14891511
if sp.is_desugaring(DesugaringKind::Async) && !returned_async_output_error {
14901512
if &[sp] != err.span.primary_spans() {
14911513
let mut span: MultiSpan = sp.into();
1492-
span.push_span_label(
1493-
sp,
1494-
format!(
1495-
"checked the `Output` of this `async fn`, {}{} {}{}",
1496-
if count > 1 { "one of the " } else { "" },
1497-
target,
1498-
kind,
1499-
pluralize!(count),
1500-
),
1501-
);
1514+
if let Some(fn_span) = fn_span {
1515+
span.push_span_label(
1516+
fn_span,
1517+
"async functions return futures".to_string(),
1518+
);
1519+
span.push_span_label(
1520+
sp,
1521+
format!(
1522+
"the desugared version of {} returns `impl Future<Output = {}>`",
1523+
fn_name,
1524+
if let Ok(snippet) = self.tcx.sess.source_map().span_to_snippet(sp) {
1525+
snippet
1526+
} else {
1527+
"{async return type}".to_string()
1528+
}
1529+
),
1530+
);
1531+
} else {
1532+
span.push_span_label(
1533+
sp,
1534+
format!("{} returns a future", fn_desc,),
1535+
);
1536+
}
15021537
err.span_note(
15031538
span,
1504-
"while checking the return type of the `async fn`",
1539+
&format!("while checking the return type of {}", fn_desc),
15051540
);
15061541
} else {
1507-
err.span_label(
1508-
sp,
1509-
format!(
1510-
"checked the `Output` of this `async fn`, {}{} {}{}",
1511-
if count > 1 { "one of the " } else { "" },
1512-
target,
1513-
kind,
1514-
pluralize!(count),
1515-
),
1516-
);
1517-
err.note("while checking the return type of the `async fn`");
1542+
err.span_label(sp, format!("{} returns a future", fn_desc));
1543+
err.note(&format!("while checking the return type of {}", fn_name));
15181544
}
15191545
returned_async_output_error = true;
15201546
} else {
@@ -1552,7 +1578,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
15521578
// = note: expected unit type `()`
15531579
// found closure `[closure@$DIR/issue-20862.rs:2:5: 2:14 x:_]`
15541580
if !self.ignore_span.overlaps(span) {
1555-
self.types.entry(kind).or_default().insert(span);
1581+
self.types.entry(kind).or_default().insert(def_id);
15561582
}
15571583
}
15581584
t.super_visit_with(self)
@@ -2539,7 +2565,7 @@ impl<'tcx> ObligationCauseExt<'tcx> for ObligationCause<'tcx> {
25392565

25402566
/// This is a bare signal of what kind of type we're dealing with. `ty::TyKind` tracks
25412567
/// extra information about each type, but we only care about the category.
2542-
#[derive(Clone, Copy, PartialEq, Eq, Hash)]
2568+
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
25432569
pub enum TyCategory {
25442570
Closure,
25452571
Opaque,

src/test/ui/async-await/dont-suggest-missing-await.stderr

+4-2
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,13 @@ error[E0308]: mismatched types
44
LL | take_u32(x)
55
| ^ expected `u32`, found opaque type
66
|
7-
note: while checking the return type of the `async fn`
7+
note: while checking the return type of the async function `make_u32`
88
--> $DIR/dont-suggest-missing-await.rs:7:24
99
|
1010
LL | async fn make_u32() -> u32 {
11-
| ^^^ checked the `Output` of this `async fn`, found opaque type
11+
| -------- ^^^ the desugared version of `make_u32` returns `impl Future<Output = u32>`
12+
| |
13+
| async functions return futures
1214
= note: expected type `u32`
1315
found opaque type `impl Future`
1416
help: consider `await`ing on the `Future`

src/test/ui/async-await/generator-desc.stderr

+8-4
Original file line numberDiff line numberDiff line change
@@ -15,16 +15,20 @@ error[E0308]: mismatched types
1515
LL | fun(one(), two());
1616
| ^^^^^ expected opaque type, found a different opaque type
1717
|
18-
note: while checking the return type of the `async fn`
18+
note: while checking the return type of the async function `one`
1919
--> $DIR/generator-desc.rs:5:16
2020
|
2121
LL | async fn one() {}
22-
| ^ checked the `Output` of this `async fn`, expected opaque type
23-
note: while checking the return type of the `async fn`
22+
| --- ^ the desugared version of `one` returns `impl Future<Output = >`
23+
| |
24+
| async functions return futures
25+
note: while checking the return type of the async function `two`
2426
--> $DIR/generator-desc.rs:6:16
2527
|
2628
LL | async fn two() {}
27-
| ^ checked the `Output` of this `async fn`, found opaque type
29+
| --- ^ the desugared version of `two` returns `impl Future<Output = >`
30+
| |
31+
| async functions return futures
2832
= note: expected opaque type `impl Future` (opaque type at <$DIR/generator-desc.rs:5:16>)
2933
found opaque type `impl Future` (opaque type at <$DIR/generator-desc.rs:6:16>)
3034
= help: consider `await`ing on both `Future`s

src/test/ui/async-await/issue-61076.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -56,8 +56,9 @@ async fn struct_() -> Struct {
5656
}
5757

5858
async fn tuple() -> Tuple {
59-
//~^ NOTE checked the `Output` of this `async fn`, expected opaque type
60-
//~| NOTE while checking the return type of the `async fn`
59+
//~^ NOTE while checking the return type of the async function `tuple`
60+
//~| NOTE async functions return futures
61+
//~| NOTE the desugared version of `tuple` returns `impl Future<Output = Tuple>`
6162
//~| NOTE in this expansion of desugaring of `async` block or function
6263
Tuple(1i32)
6364
}

src/test/ui/async-await/issue-61076.stderr

+9-7
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ LL | foo().await?;
1616
| ^^^^^^
1717

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

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

4646
error[E0609]: no field `a` on type `impl Future`
47-
--> $DIR/issue-61076.rs:82:28
47+
--> $DIR/issue-61076.rs:83:28
4848
|
4949
LL | let _: i32 = struct_().a;
5050
| ^ field not available in `impl Future`, but it is available in its `Output`
@@ -55,7 +55,7 @@ LL | let _: i32 = struct_().await.a;
5555
| ^^^^^^
5656

5757
error[E0599]: no method named `method` found for opaque type `impl Future` in the current scope
58-
--> $DIR/issue-61076.rs:86:15
58+
--> $DIR/issue-61076.rs:87:15
5959
|
6060
LL | struct_().method();
6161
| ^^^^^^ method not found in `impl Future`
@@ -66,16 +66,18 @@ LL | struct_().await.method();
6666
| ^^^^^^
6767

6868
error[E0308]: mismatched types
69-
--> $DIR/issue-61076.rs:94:9
69+
--> $DIR/issue-61076.rs:95:9
7070
|
7171
LL | Tuple(_) => {}
7272
| ^^^^^^^^ expected opaque type, found struct `Tuple`
7373
|
74-
note: while checking the return type of the `async fn`
74+
note: while checking the return type of the async function `tuple`
7575
--> $DIR/issue-61076.rs:58:21
7676
|
7777
LL | async fn tuple() -> Tuple {
78-
| ^^^^^ checked the `Output` of this `async fn`, expected opaque type
78+
| ----- ^^^^^ the desugared version of `tuple` returns `impl Future<Output = Tuple>`
79+
| |
80+
| async functions return futures
7981
= note: expected opaque type `impl Future`
8082
found struct `Tuple`
8183
help: consider `await`ing on the `Future`

src/test/ui/async-await/suggest-missing-await-closure.stderr

+4-2
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,13 @@ error[E0308]: mismatched types
44
LL | take_u32(x)
55
| ^ expected `u32`, found opaque type
66
|
7-
note: while checking the return type of the `async fn`
7+
note: while checking the return type of the async function `make_u32`
88
--> $DIR/suggest-missing-await-closure.rs:8:24
99
|
1010
LL | async fn make_u32() -> u32 {
11-
| ^^^ checked the `Output` of this `async fn`, found opaque type
11+
| -------- ^^^ the desugared version of `make_u32` returns `impl Future<Output = u32>`
12+
| |
13+
| async functions return futures
1214
= note: expected type `u32`
1315
found opaque type `impl Future`
1416
help: consider `await`ing on the `Future`

src/test/ui/async-await/suggest-missing-await.stderr

+8-4
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,13 @@ error[E0308]: mismatched types
44
LL | take_u32(x)
55
| ^ expected `u32`, found opaque type
66
|
7-
note: while checking the return type of the `async fn`
7+
note: while checking the return type of the async function `make_u32`
88
--> $DIR/suggest-missing-await.rs:5:24
99
|
1010
LL | async fn make_u32() -> u32 {
11-
| ^^^ checked the `Output` of this `async fn`, found opaque type
11+
| -------- ^^^ the desugared version of `make_u32` returns `impl Future<Output = u32>`
12+
| |
13+
| async functions return futures
1214
= note: expected type `u32`
1315
found opaque type `impl Future`
1416
help: consider `await`ing on the `Future`
@@ -22,11 +24,13 @@ error[E0308]: mismatched types
2224
LL | dummy()
2325
| ^^^^^^^ expected `()`, found opaque type
2426
|
25-
note: while checking the return type of the `async fn`
27+
note: while checking the return type of the async function `dummy`
2628
--> $DIR/suggest-missing-await.rs:18:18
2729
|
2830
LL | async fn dummy() {}
29-
| ^ checked the `Output` of this `async fn`, found opaque type
31+
| ----- ^ the desugared version of `dummy` returns `impl Future<Output = >`
32+
| |
33+
| async functions return futures
3034
= note: expected unit type `()`
3135
found opaque type `impl Future`
3236
help: consider `await`ing on the `Future`

0 commit comments

Comments
 (0)