Skip to content

Commit 7f8a587

Browse files
committed
Account for async fn with dyn Trait return type in impl Trait suggestion
1 parent 4f8b125 commit 7f8a587

File tree

2 files changed

+20
-9
lines changed

2 files changed

+20
-9
lines changed

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

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1886,7 +1886,21 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
18861886
err.primary_message("return type cannot be a trait object without pointer indirection");
18871887
err.children.clear();
18881888

1889-
let span = obligation.cause.span;
1889+
let mut span = obligation.cause.span;
1890+
if let DefKind::Closure = self.tcx.def_kind(obligation.cause.body_id)
1891+
&& let parent = self.tcx.parent(obligation.cause.body_id.into())
1892+
&& let DefKind::Fn = self.tcx.def_kind(parent)
1893+
&& self.tcx.asyncness(parent).is_async()
1894+
&& let Some(parent) = parent.as_local()
1895+
&& let Node::Item(hir::Item { kind: hir::ItemKind::Fn { sig: fn_sig, .. }, .. }) =
1896+
self.tcx.hir_node_by_def_id(parent)
1897+
{
1898+
// Do not suggest (#147894)
1899+
// async fn foo() -> dyn Display impl { .. }
1900+
// and
1901+
// async fn foo() -> dyn Display Box<dyn { .. }>
1902+
span = fn_sig.decl.output.span();
1903+
}
18901904
let body = self.tcx.hir_body_owned_by(obligation.cause.body_id);
18911905

18921906
let mut visitor = ReturnsVisitor::default();

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

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,16 +9,13 @@ LL | | }
99
|
1010
help: consider returning an `impl Trait` instead of a `dyn Trait`
1111
|
12-
LL | async fn f() -> dyn core::fmt::Debug impl {
13-
| ++++
14-
help: alternatively, box the return type, and wrap all of the returned values in `Box::new`
12+
LL - async fn f() -> dyn core::fmt::Debug {
13+
LL + async fn f() -> impl core::fmt::Debug {
1514
|
16-
LL ~ async fn f() -> dyn core::fmt::Debug Box<dyn {
17-
LL |
18-
...
19-
LL | loop {}
20-
LL ~ }>
15+
help: alternatively, box the return type, and wrap all of the returned values in `Box::new`
2116
|
17+
LL | async fn f() -> Box<dyn core::fmt::Debug> {
18+
| ++++ +
2219

2320
error: aborting due to 1 previous error
2421

0 commit comments

Comments
 (0)