From a4768fea3545a799b9c19e65777f6fee7b50a561 Mon Sep 17 00:00:00 2001
From: bohan <bohan-zhang@foxmail.com>
Date: Sat, 4 Nov 2023 17:00:33 +0800
Subject: [PATCH] fallback for `construct_generic_bound_failure`

---
 .../src/infer/error_reporting/mod.rs          | 20 +++++++++++--------
 .../impl-trait/in-trait/async-and-ret-ref.rs  | 11 ++++++++++
 .../in-trait/async-and-ret-ref.stderr         | 14 +++++++++++++
 3 files changed, 37 insertions(+), 8 deletions(-)
 create mode 100644 tests/ui/impl-trait/in-trait/async-and-ret-ref.rs
 create mode 100644 tests/ui/impl-trait/in-trait/async-and-ret-ref.stderr

diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs
index e4be435fded30..26d071a01397a 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs
+++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs
@@ -2444,18 +2444,22 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
                 let suggestion =
                     if has_lifetimes { format!(" + {lt_name}") } else { format!(": {lt_name}") };
                 suggs.push((sp, suggestion))
-            } else {
-                let generics = self.tcx.hir().get_generics(suggestion_scope).unwrap();
+            } else if let Some(generics) = self.tcx.hir().get_generics(suggestion_scope) {
                 let pred = format!("{bound_kind}: {lt_name}");
-                let suggestion = format!("{} {}", generics.add_where_or_trailing_comma(), pred,);
+                let suggestion = format!("{} {}", generics.add_where_or_trailing_comma(), pred);
                 suggs.push((generics.tail_span_for_predicate_suggestion(), suggestion))
+            } else {
+                let consider = format!("{msg} `{bound_kind}: {sub}`...");
+                err.help(consider);
             }
 
-            err.multipart_suggestion_verbose(
-                format!("{msg}"),
-                suggs,
-                Applicability::MaybeIncorrect, // Issue #41966
-            );
+            if !suggs.is_empty() {
+                err.multipart_suggestion_verbose(
+                    format!("{msg}"),
+                    suggs,
+                    Applicability::MaybeIncorrect, // Issue #41966
+                );
+            }
         }
 
         err
diff --git a/tests/ui/impl-trait/in-trait/async-and-ret-ref.rs b/tests/ui/impl-trait/in-trait/async-and-ret-ref.rs
new file mode 100644
index 0000000000000..af6ffe8339452
--- /dev/null
+++ b/tests/ui/impl-trait/in-trait/async-and-ret-ref.rs
@@ -0,0 +1,11 @@
+// edition:2021
+// https://github.com/rust-lang/rust/issues/117547
+
+trait T {}
+
+trait MyTrait {
+    async fn foo() -> &'static impl T;
+    //~^ ERROR the associated type `<Self as MyTrait>::{opaque#0}` may not live long enough
+}
+
+fn main() {}
diff --git a/tests/ui/impl-trait/in-trait/async-and-ret-ref.stderr b/tests/ui/impl-trait/in-trait/async-and-ret-ref.stderr
new file mode 100644
index 0000000000000..7c9028a8cd53c
--- /dev/null
+++ b/tests/ui/impl-trait/in-trait/async-and-ret-ref.stderr
@@ -0,0 +1,14 @@
+error[E0310]: the associated type `<Self as MyTrait>::{opaque#0}` may not live long enough
+  --> $DIR/async-and-ret-ref.rs:7:5
+   |
+LL |     async fn foo() -> &'static impl T;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |     |
+   |     the associated type `<Self as MyTrait>::{opaque#0}` must be valid for the static lifetime...
+   |     ...so that the reference type `&'static impl T` does not outlive the data it points at
+   |
+   = help: consider adding an explicit lifetime bound `<Self as MyTrait>::{opaque#0}: 'static`...
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0310`.