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