Skip to content

Commit f7eaaf7

Browse files
committed
Account for async fn in traits and impls
1 parent 8c63852 commit f7eaaf7

File tree

7 files changed

+176
-11
lines changed

7 files changed

+176
-11
lines changed

compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1886,7 +1886,9 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
18861886
let ty::Dynamic(_, _) = trait_pred.self_ty().skip_binder().kind() else {
18871887
return false;
18881888
};
1889-
if let Node::Item(hir::Item { kind: hir::ItemKind::Fn { sig: fn_sig, .. }, .. }) =
1889+
if let Node::Item(hir::Item { kind: hir::ItemKind::Fn { sig: fn_sig, .. }, .. })
1890+
| Node::ImplItem(hir::ImplItem { kind: hir::ImplItemKind::Fn(fn_sig, _), .. })
1891+
| Node::TraitItem(hir::TraitItem { kind: hir::TraitItemKind::Fn(fn_sig, _), .. }) =
18901892
self.tcx.hir_node_by_def_id(obligation.cause.body_id)
18911893
&& let hir::FnRetTy::Return(ty) = fn_sig.decl.output
18921894
&& let hir::TyKind::Path(qpath) = ty.kind
@@ -1918,11 +1920,14 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
19181920
let mut span = obligation.cause.span;
19191921
if let DefKind::Closure = self.tcx.def_kind(obligation.cause.body_id)
19201922
&& let parent = self.tcx.parent(obligation.cause.body_id.into())
1921-
&& let DefKind::Fn = self.tcx.def_kind(parent)
1923+
&& let DefKind::Fn | DefKind::AssocFn = self.tcx.def_kind(parent)
19221924
&& self.tcx.asyncness(parent).is_async()
19231925
&& let Some(parent) = parent.as_local()
1924-
&& let Node::Item(hir::Item { kind: hir::ItemKind::Fn { sig: fn_sig, .. }, .. }) =
1925-
self.tcx.hir_node_by_def_id(parent)
1926+
&& let Node::Item(hir::Item { kind: hir::ItemKind::Fn { sig: fn_sig, .. }, .. })
1927+
| Node::ImplItem(hir::ImplItem { kind: hir::ImplItemKind::Fn(fn_sig, _), .. })
1928+
| Node::TraitItem(hir::TraitItem {
1929+
kind: hir::TraitItemKind::Fn(fn_sig, _), ..
1930+
}) = self.tcx.hir_node_by_def_id(parent)
19261931
{
19271932
// Do not suggest (#147894)
19281933
// async fn foo() -> dyn Display impl { .. }
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
//@ edition:2024
2+
//@ run-rustfix
3+
4+
async fn f() -> Box<impl core::fmt::Debug> {
5+
//~^ ERROR return type cannot be a trait object without pointer indirection
6+
//~| HELP consider returning an `impl Trait` instead of a `dyn Trait`
7+
//~| HELP alternatively, box the return type, and wrap all of the returned values in `Box::new`
8+
Box::new("")
9+
}
10+
trait T {
11+
async fn f(&self) -> Box<impl core::fmt::Debug> {
12+
//~^ ERROR return type cannot be a trait object without pointer indirection
13+
//~| HELP consider returning an `impl Trait` instead of a `dyn Trait`
14+
//~| HELP alternatively, box the return type, and wrap all of the returned values in `Box::new`
15+
Box::new("")
16+
}
17+
}
18+
impl T for () {
19+
async fn f(&self) -> Box<impl core::fmt::Debug> {
20+
//~^ ERROR return type cannot be a trait object without pointer indirection
21+
//~| HELP consider returning an `impl Trait` instead of a `dyn Trait`
22+
//~| HELP alternatively, box the return type, and wrap all of the returned values in `Box::new`
23+
Box::new("")
24+
}
25+
}
26+
27+
fn main() {
28+
let _ = f();
29+
let _ = ().f();
30+
}
Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,30 @@
11
//@ edition:2024
2+
//@ run-rustfix
23

34
async fn f() -> dyn core::fmt::Debug {
45
//~^ ERROR return type cannot be a trait object without pointer indirection
56
//~| HELP consider returning an `impl Trait` instead of a `dyn Trait`
67
//~| HELP alternatively, box the return type, and wrap all of the returned values in `Box::new`
7-
loop {}
8+
Box::new("")
9+
}
10+
trait T {
11+
async fn f(&self) -> dyn core::fmt::Debug {
12+
//~^ ERROR return type cannot be a trait object without pointer indirection
13+
//~| HELP consider returning an `impl Trait` instead of a `dyn Trait`
14+
//~| HELP alternatively, box the return type, and wrap all of the returned values in `Box::new`
15+
Box::new("")
16+
}
17+
}
18+
impl T for () {
19+
async fn f(&self) -> dyn core::fmt::Debug {
20+
//~^ ERROR return type cannot be a trait object without pointer indirection
21+
//~| HELP consider returning an `impl Trait` instead of a `dyn Trait`
22+
//~| HELP alternatively, box the return type, and wrap all of the returned values in `Box::new`
23+
Box::new("")
24+
}
825
}
926

10-
fn main() {}
27+
fn main() {
28+
let _ = f();
29+
let _ = ().f();
30+
}

tests/ui/async-await/async-fn/dyn-in-return-type.stderr

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
error[E0746]: return type cannot be a trait object without pointer indirection
2-
--> $DIR/dyn-in-return-type.rs:3:17
2+
--> $DIR/dyn-in-return-type.rs:4:17
33
|
44
LL | async fn f() -> dyn core::fmt::Debug {
55
| ^^^^^^^^^^^^^^^^^^^^
@@ -14,6 +14,38 @@ help: alternatively, box the return type, and wrap all of the returned values in
1414
LL | async fn f() -> Box<dyn core::fmt::Debug> {
1515
| ++++ +
1616

17-
error: aborting due to 1 previous error
17+
error[E0746]: return type cannot be a trait object without pointer indirection
18+
--> $DIR/dyn-in-return-type.rs:11:26
19+
|
20+
LL | async fn f(&self) -> dyn core::fmt::Debug {
21+
| ^^^^^^^^^^^^^^^^^^^^
22+
|
23+
help: consider returning an `impl Trait` instead of a `dyn Trait`
24+
|
25+
LL - async fn f(&self) -> dyn core::fmt::Debug {
26+
LL + async fn f(&self) -> impl core::fmt::Debug {
27+
|
28+
help: alternatively, box the return type, and wrap all of the returned values in `Box::new`
29+
|
30+
LL | async fn f(&self) -> Box<dyn core::fmt::Debug> {
31+
| ++++ +
32+
33+
error[E0746]: return type cannot be a trait object without pointer indirection
34+
--> $DIR/dyn-in-return-type.rs:19:26
35+
|
36+
LL | async fn f(&self) -> dyn core::fmt::Debug {
37+
| ^^^^^^^^^^^^^^^^^^^^
38+
|
39+
help: consider returning an `impl Trait` instead of a `dyn Trait`
40+
|
41+
LL - async fn f(&self) -> dyn core::fmt::Debug {
42+
LL + async fn f(&self) -> impl core::fmt::Debug {
43+
|
44+
help: alternatively, box the return type, and wrap all of the returned values in `Box::new`
45+
|
46+
LL | async fn f(&self) -> Box<dyn core::fmt::Debug> {
47+
| ++++ +
48+
49+
error: aborting due to 3 previous errors
1850

1951
For more information about this error, try `rustc --explain E0746`.

tests/ui/type-alias/dyn-trait-type-alias-return-type.fixed

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
//@ run-rustfix
22
type T = dyn core::fmt::Debug;
33
//~^ NOTE this type alias is unsized
4+
//~| NOTE this type alias is unsized
5+
//~| NOTE this type alias is unsized
46

57
fn f() -> Box<T> { loop {} }
68
//~^ ERROR the size for values of type `(dyn Debug + 'static)` cannot be known at compilation time
@@ -9,10 +11,29 @@ fn f() -> Box<T> { loop {} }
911
//~| NOTE the return type of a function must have a statically known size
1012
//~| HELP consider boxing the return type
1113

14+
trait X {
15+
fn f(&self) -> Box<T> { loop {} }
16+
//~^ ERROR the size for values of type `(dyn Debug + 'static)` cannot be known at compilation time
17+
//~| HELP the trait `Sized` is not implemented for `(dyn Debug + 'static)`
18+
//~| NOTE doesn't have a size known at compile-time
19+
//~| NOTE the return type of a function must have a statically known size
20+
//~| HELP consider boxing the return type
21+
}
22+
23+
impl X for () {
24+
fn f(&self) -> Box<T> { loop {} }
25+
//~^ ERROR the size for values of type `(dyn Debug + 'static)` cannot be known at compilation time
26+
//~| HELP the trait `Sized` is not implemented for `(dyn Debug + 'static)`
27+
//~| NOTE doesn't have a size known at compile-time
28+
//~| NOTE the return type of a function must have a statically known size
29+
//~| HELP consider boxing the return type
30+
}
31+
1232
fn main() {
1333
f();
1434
//~^ ERROR the size for values of type `(dyn Debug + 'static)` cannot be known at compilation time
1535
//~| HELP the trait `Sized` is not implemented for `(dyn Debug + 'static)`
1636
//~| NOTE doesn't have a size known at compile-time
1737
//~| NOTE the return type of a function must have a statically known size
38+
().f();
1839
}

tests/ui/type-alias/dyn-trait-type-alias-return-type.rs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
//@ run-rustfix
22
type T = dyn core::fmt::Debug;
33
//~^ NOTE this type alias is unsized
4+
//~| NOTE this type alias is unsized
5+
//~| NOTE this type alias is unsized
46

57
fn f() -> T { loop {} }
68
//~^ ERROR the size for values of type `(dyn Debug + 'static)` cannot be known at compilation time
@@ -9,10 +11,29 @@ fn f() -> T { loop {} }
911
//~| NOTE the return type of a function must have a statically known size
1012
//~| HELP consider boxing the return type
1113

14+
trait X {
15+
fn f(&self) -> T { loop {} }
16+
//~^ ERROR the size for values of type `(dyn Debug + 'static)` cannot be known at compilation time
17+
//~| HELP the trait `Sized` is not implemented for `(dyn Debug + 'static)`
18+
//~| NOTE doesn't have a size known at compile-time
19+
//~| NOTE the return type of a function must have a statically known size
20+
//~| HELP consider boxing the return type
21+
}
22+
23+
impl X for () {
24+
fn f(&self) -> T { loop {} }
25+
//~^ ERROR the size for values of type `(dyn Debug + 'static)` cannot be known at compilation time
26+
//~| HELP the trait `Sized` is not implemented for `(dyn Debug + 'static)`
27+
//~| NOTE doesn't have a size known at compile-time
28+
//~| NOTE the return type of a function must have a statically known size
29+
//~| HELP consider boxing the return type
30+
}
31+
1232
fn main() {
1333
f();
1434
//~^ ERROR the size for values of type `(dyn Debug + 'static)` cannot be known at compilation time
1535
//~| HELP the trait `Sized` is not implemented for `(dyn Debug + 'static)`
1636
//~| NOTE doesn't have a size known at compile-time
1737
//~| NOTE the return type of a function must have a statically known size
38+
().f();
1839
}

tests/ui/type-alias/dyn-trait-type-alias-return-type.stderr

Lines changed: 39 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
error[E0277]: the size for values of type `(dyn Debug + 'static)` cannot be known at compilation time
2-
--> $DIR/dyn-trait-type-alias-return-type.rs:5:11
2+
--> $DIR/dyn-trait-type-alias-return-type.rs:7:11
33
|
44
LL | fn f() -> T { loop {} }
55
| ^ doesn't have a size known at compile-time
@@ -17,14 +17,50 @@ LL | fn f() -> Box<T> { loop {} }
1717
| ++++ +
1818

1919
error[E0277]: the size for values of type `(dyn Debug + 'static)` cannot be known at compilation time
20-
--> $DIR/dyn-trait-type-alias-return-type.rs:13:5
20+
--> $DIR/dyn-trait-type-alias-return-type.rs:24:20
21+
|
22+
LL | fn f(&self) -> T { loop {} }
23+
| ^ doesn't have a size known at compile-time
24+
|
25+
= help: the trait `Sized` is not implemented for `(dyn Debug + 'static)`
26+
note: this type alias is unsized
27+
--> $DIR/dyn-trait-type-alias-return-type.rs:2:1
28+
|
29+
LL | type T = dyn core::fmt::Debug;
30+
| ^^^^^^
31+
= note: the return type of a function must have a statically known size
32+
help: consider boxing the return type, and wrapping all of the returned values in `Box::new`
33+
|
34+
LL | fn f(&self) -> Box<T> { loop {} }
35+
| ++++ +
36+
37+
error[E0277]: the size for values of type `(dyn Debug + 'static)` cannot be known at compilation time
38+
--> $DIR/dyn-trait-type-alias-return-type.rs:15:20
39+
|
40+
LL | fn f(&self) -> T { loop {} }
41+
| ^ doesn't have a size known at compile-time
42+
|
43+
= help: the trait `Sized` is not implemented for `(dyn Debug + 'static)`
44+
note: this type alias is unsized
45+
--> $DIR/dyn-trait-type-alias-return-type.rs:2:1
46+
|
47+
LL | type T = dyn core::fmt::Debug;
48+
| ^^^^^^
49+
= note: the return type of a function must have a statically known size
50+
help: consider boxing the return type, and wrapping all of the returned values in `Box::new`
51+
|
52+
LL | fn f(&self) -> Box<T> { loop {} }
53+
| ++++ +
54+
55+
error[E0277]: the size for values of type `(dyn Debug + 'static)` cannot be known at compilation time
56+
--> $DIR/dyn-trait-type-alias-return-type.rs:33:5
2157
|
2258
LL | f();
2359
| ^^^ doesn't have a size known at compile-time
2460
|
2561
= help: the trait `Sized` is not implemented for `(dyn Debug + 'static)`
2662
= note: the return type of a function must have a statically known size
2763

28-
error: aborting due to 2 previous errors
64+
error: aborting due to 4 previous errors
2965

3066
For more information about this error, try `rustc --explain E0277`.

0 commit comments

Comments
 (0)