Account for `async fn` with `dyn Trait` return type in `impl Trait` suggestion
diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs index 1094f00..16bb4c1 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs
@@ -1891,7 +1891,21 @@ pub(super) fn suggest_impl_trait( err.primary_message("return type cannot be a trait object without pointer indirection"); err.children.clear(); - let span = obligation.cause.span; + let mut span = obligation.cause.span; + if let DefKind::Closure = self.tcx.def_kind(obligation.cause.body_id) + && let parent = self.tcx.parent(obligation.cause.body_id.into()) + && let DefKind::Fn = self.tcx.def_kind(parent) + && self.tcx.asyncness(parent).is_async() + && let Some(parent) = parent.as_local() + && let Node::Item(hir::Item { kind: hir::ItemKind::Fn { sig: fn_sig, .. }, .. }) = + self.tcx.hir_node_by_def_id(parent) + { + // Do not suggest (#147894) + // async fn foo() -> dyn Display impl { .. } + // and + // async fn foo() -> dyn Display Box<dyn { .. }> + span = fn_sig.decl.output.span(); + } let body = self.tcx.hir_body_owned_by(obligation.cause.body_id); let mut visitor = ReturnsVisitor::default();
diff --git a/tests/ui/async-await/async-fn/dyn-in-return-type.stderr b/tests/ui/async-await/async-fn/dyn-in-return-type.stderr index 6b1b092..bd2ee4c 100644 --- a/tests/ui/async-await/async-fn/dyn-in-return-type.stderr +++ b/tests/ui/async-await/async-fn/dyn-in-return-type.stderr
@@ -9,16 +9,13 @@ | help: consider returning an `impl Trait` instead of a `dyn Trait` | -LL | async fn f() -> dyn core::fmt::Debug impl { - | ++++ +LL - async fn f() -> dyn core::fmt::Debug { +LL + async fn f() -> impl core::fmt::Debug { + | help: alternatively, box the return type, and wrap all of the returned values in `Box::new` | -LL ~ async fn f() -> dyn core::fmt::Debug Box<dyn { -LL | -... -LL | loop {} -LL ~ }> - | +LL | async fn f() -> Box<dyn core::fmt::Debug> { + | ++++ + error: aborting due to 1 previous error