Skip to content

Commit fe816a3

Browse files
committed
Fix suggestion for returning async closures
1 parent 401ae55 commit fe816a3

File tree

5 files changed

+237
-0
lines changed

5 files changed

+237
-0
lines changed

compiler/rustc_hir_analysis/src/collect.rs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1263,6 +1263,21 @@ pub fn suggest_impl_trait<'tcx>(
12631263
infcx.tcx.lang_items().future_output(),
12641264
format_as_assoc,
12651265
),
1266+
(
1267+
infcx.tcx.lang_items().async_fn_trait(),
1268+
infcx.tcx.lang_items().async_fn_once_output(),
1269+
format_as_parenthesized,
1270+
),
1271+
(
1272+
infcx.tcx.lang_items().async_fn_mut_trait(),
1273+
infcx.tcx.lang_items().async_fn_once_output(),
1274+
format_as_parenthesized,
1275+
),
1276+
(
1277+
infcx.tcx.lang_items().async_fn_once_trait(),
1278+
infcx.tcx.lang_items().async_fn_once_output(),
1279+
format_as_parenthesized,
1280+
),
12661281
(
12671282
infcx.tcx.lang_items().fn_trait(),
12681283
infcx.tcx.lang_items().fn_once_output(),

compiler/rustc_middle/src/ty/diagnostics.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -698,6 +698,7 @@ impl<'tcx> FallibleTypeFolder<TyCtxt<'tcx>> for MakeSuggestableFolder<'tcx> {
698698
}
699699

700700
Closure(..)
701+
| CoroutineClosure(..)
701702
| FnDef(..)
702703
| Infer(..)
703704
| Coroutine(..)
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
#![allow(dead_code)]
2+
//@ run-rustfix
3+
//@ edition: 2021
4+
5+
// Regression test for issue #148493
6+
// the suggestion is `impl AsyncFn()` instead of `{async closure@...}`
7+
8+
fn test1() -> impl AsyncFn() {
9+
//~^ ERROR the placeholder `_` is not allowed within types on item signatures for return types
10+
//~| HELP replace with an appropriate return type
11+
//~| SUGGESTION impl AsyncFn()
12+
async || {}
13+
}
14+
15+
fn test2() -> impl AsyncFn(i32) -> i32 {
16+
//~^ ERROR the placeholder `_` is not allowed within types on item signatures for return types
17+
//~| HELP replace with an appropriate return type
18+
//~| SUGGESTION impl AsyncFn(i32) -> i32
19+
async |x: i32| x + 1
20+
}
21+
22+
fn test3() -> impl AsyncFn(i32, i32) -> i32 {
23+
//~^ ERROR the placeholder `_` is not allowed within types on item signatures for return types
24+
//~| HELP replace with an appropriate return type
25+
//~| SUGGESTION impl AsyncFn(i32, i32) -> i32
26+
async |x: i32, y: i32| x + y
27+
}
28+
29+
fn test4() -> impl AsyncFn() {
30+
//~^ ERROR the placeholder `_` is not allowed within types on item signatures for return types
31+
//~| HELP replace with an appropriate return type
32+
//~| SUGGESTION impl AsyncFn()
33+
async || -> () { () }
34+
}
35+
36+
fn test5() -> impl AsyncFn() -> i32 {
37+
//~^ ERROR the placeholder `_` is not allowed within types on item signatures for return types
38+
//~| HELP replace with an appropriate return type
39+
//~| SUGGESTION impl AsyncFn() -> i32
40+
let z = 42;
41+
async move || z
42+
}
43+
44+
// Test AsyncFnMut - mutably borrows captured variable
45+
fn test6() -> impl AsyncFnMut() -> i32 {
46+
//~^ ERROR the placeholder `_` is not allowed within types on item signatures for return types
47+
//~| HELP replace with an appropriate return type
48+
//~| SUGGESTION impl AsyncFnMut() -> i32
49+
let mut x = 0;
50+
async move || {
51+
x += 1;
52+
x
53+
}
54+
}
55+
56+
// Test AsyncFnOnce - consumes captured variable
57+
fn test7() -> impl AsyncFnOnce() {
58+
//~^ ERROR the placeholder `_` is not allowed within types on item signatures for return types
59+
//~| HELP replace with an appropriate return type
60+
//~| SUGGESTION impl AsyncFnOnce()
61+
let s = String::from("hello");
62+
async move || {
63+
drop(s);
64+
}
65+
}
66+
67+
fn main() {}
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
#![allow(dead_code)]
2+
//@ run-rustfix
3+
//@ edition: 2021
4+
5+
// Regression test for issue #148493
6+
// the suggestion is `impl AsyncFn()` instead of `{async closure@...}`
7+
8+
fn test1() -> _ {
9+
//~^ ERROR the placeholder `_` is not allowed within types on item signatures for return types
10+
//~| HELP replace with an appropriate return type
11+
//~| SUGGESTION impl AsyncFn()
12+
async || {}
13+
}
14+
15+
fn test2() -> _ {
16+
//~^ ERROR the placeholder `_` is not allowed within types on item signatures for return types
17+
//~| HELP replace with an appropriate return type
18+
//~| SUGGESTION impl AsyncFn(i32) -> i32
19+
async |x: i32| x + 1
20+
}
21+
22+
fn test3() -> _ {
23+
//~^ ERROR the placeholder `_` is not allowed within types on item signatures for return types
24+
//~| HELP replace with an appropriate return type
25+
//~| SUGGESTION impl AsyncFn(i32, i32) -> i32
26+
async |x: i32, y: i32| x + y
27+
}
28+
29+
fn test4() -> _ {
30+
//~^ ERROR the placeholder `_` is not allowed within types on item signatures for return types
31+
//~| HELP replace with an appropriate return type
32+
//~| SUGGESTION impl AsyncFn()
33+
async || -> () { () }
34+
}
35+
36+
fn test5() -> _ {
37+
//~^ ERROR the placeholder `_` is not allowed within types on item signatures for return types
38+
//~| HELP replace with an appropriate return type
39+
//~| SUGGESTION impl AsyncFn() -> i32
40+
let z = 42;
41+
async move || z
42+
}
43+
44+
// Test AsyncFnMut - mutably borrows captured variable
45+
fn test6() -> _ {
46+
//~^ ERROR the placeholder `_` is not allowed within types on item signatures for return types
47+
//~| HELP replace with an appropriate return type
48+
//~| SUGGESTION impl AsyncFnMut() -> i32
49+
let mut x = 0;
50+
async move || {
51+
x += 1;
52+
x
53+
}
54+
}
55+
56+
// Test AsyncFnOnce - consumes captured variable
57+
fn test7() -> _ {
58+
//~^ ERROR the placeholder `_` is not allowed within types on item signatures for return types
59+
//~| HELP replace with an appropriate return type
60+
//~| SUGGESTION impl AsyncFnOnce()
61+
let s = String::from("hello");
62+
async move || {
63+
drop(s);
64+
}
65+
}
66+
67+
fn main() {}
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
error[E0121]: the placeholder `_` is not allowed within types on item signatures for return types
2+
--> $DIR/suggest-impl-async-fn-issue-148493.rs:8:15
3+
|
4+
LL | fn test1() -> _ {
5+
| ^ not allowed in type signatures
6+
|
7+
help: replace with an appropriate return type
8+
|
9+
LL - fn test1() -> _ {
10+
LL + fn test1() -> impl AsyncFn() {
11+
|
12+
13+
error[E0121]: the placeholder `_` is not allowed within types on item signatures for return types
14+
--> $DIR/suggest-impl-async-fn-issue-148493.rs:15:15
15+
|
16+
LL | fn test2() -> _ {
17+
| ^ not allowed in type signatures
18+
|
19+
help: replace with an appropriate return type
20+
|
21+
LL - fn test2() -> _ {
22+
LL + fn test2() -> impl AsyncFn(i32) -> i32 {
23+
|
24+
25+
error[E0121]: the placeholder `_` is not allowed within types on item signatures for return types
26+
--> $DIR/suggest-impl-async-fn-issue-148493.rs:22:15
27+
|
28+
LL | fn test3() -> _ {
29+
| ^ not allowed in type signatures
30+
|
31+
help: replace with an appropriate return type
32+
|
33+
LL - fn test3() -> _ {
34+
LL + fn test3() -> impl AsyncFn(i32, i32) -> i32 {
35+
|
36+
37+
error[E0121]: the placeholder `_` is not allowed within types on item signatures for return types
38+
--> $DIR/suggest-impl-async-fn-issue-148493.rs:29:15
39+
|
40+
LL | fn test4() -> _ {
41+
| ^ not allowed in type signatures
42+
|
43+
help: replace with an appropriate return type
44+
|
45+
LL - fn test4() -> _ {
46+
LL + fn test4() -> impl AsyncFn() {
47+
|
48+
49+
error[E0121]: the placeholder `_` is not allowed within types on item signatures for return types
50+
--> $DIR/suggest-impl-async-fn-issue-148493.rs:36:15
51+
|
52+
LL | fn test5() -> _ {
53+
| ^ not allowed in type signatures
54+
|
55+
help: replace with an appropriate return type
56+
|
57+
LL - fn test5() -> _ {
58+
LL + fn test5() -> impl AsyncFn() -> i32 {
59+
|
60+
61+
error[E0121]: the placeholder `_` is not allowed within types on item signatures for return types
62+
--> $DIR/suggest-impl-async-fn-issue-148493.rs:45:15
63+
|
64+
LL | fn test6() -> _ {
65+
| ^ not allowed in type signatures
66+
|
67+
help: replace with an appropriate return type
68+
|
69+
LL - fn test6() -> _ {
70+
LL + fn test6() -> impl AsyncFnMut() -> i32 {
71+
|
72+
73+
error[E0121]: the placeholder `_` is not allowed within types on item signatures for return types
74+
--> $DIR/suggest-impl-async-fn-issue-148493.rs:57:15
75+
|
76+
LL | fn test7() -> _ {
77+
| ^ not allowed in type signatures
78+
|
79+
help: replace with an appropriate return type
80+
|
81+
LL - fn test7() -> _ {
82+
LL + fn test7() -> impl AsyncFnOnce() {
83+
|
84+
85+
error: aborting due to 7 previous errors
86+
87+
For more information about this error, try `rustc --explain E0121`.

0 commit comments

Comments
 (0)