From 1c35634efe5f69961d84b35a4e5c32cb16ecc0f6 Mon Sep 17 00:00:00 2001
From: Michael Goulet <michael@errs.io>
Date: Mon, 31 Jul 2023 18:23:12 +0000
Subject: [PATCH] Suppress unnecessary outlives

---
 .../rustc_hir_analysis/src/check/wfcheck.rs   |  9 +++++----
 .../src/infer/lexical_region_resolve/mod.rs   |  4 ++++
 .../missing-lt-outlives-in-rpitit-114274.rs   |  1 -
 ...issing-lt-outlives-in-rpitit-114274.stderr | 19 ++-----------------
 4 files changed, 11 insertions(+), 22 deletions(-)

diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs
index 4df572f6199..22e4c69f605 100644
--- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs
+++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs
@@ -552,8 +552,8 @@ fn gather_gat_bounds<'tcx, T: TypeFoldable<TyCtxt<'tcx>>>(
     for (region_a, region_a_idx) in &regions {
         // Ignore `'static` lifetimes for the purpose of this lint: it's
         // because we know it outlives everything and so doesn't give meaningful
-        // clues
-        if let ty::ReStatic = **region_a {
+        // clues. Also ignore `ReError`, to avoid knock-down errors.
+        if let ty::ReStatic | ty::ReError(_) = **region_a {
             continue;
         }
         // For each region argument (e.g., `'a` in our example), check for a
@@ -596,8 +596,9 @@ fn gather_gat_bounds<'tcx, T: TypeFoldable<TyCtxt<'tcx>>>(
         // on the GAT itself.
         for (region_b, region_b_idx) in &regions {
             // Again, skip `'static` because it outlives everything. Also, we trivially
-            // know that a region outlives itself.
-            if ty::ReStatic == **region_b || region_a == region_b {
+            // know that a region outlives itself. Also ignore `ReError`, to avoid
+            // knock-down errors.
+            if matches!(**region_b, ty::ReStatic | ty::ReError(_)) || region_a == region_b {
                 continue;
             }
             if region_known_to_outlive(
diff --git a/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs b/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs
index be424424f3a..60d9d6578f5 100644
--- a/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs
+++ b/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs
@@ -942,6 +942,10 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> {
         generic_ty: Ty<'tcx>,
         min: ty::Region<'tcx>,
     ) -> bool {
+        if let ty::ReError(_) = *min {
+            return true;
+        }
+
         match bound {
             VerifyBound::IfEq(verify_if_eq_b) => {
                 let verify_if_eq_b = var_values.normalize(self.region_rels.tcx, *verify_if_eq_b);
diff --git a/tests/ui/impl-trait/in-trait/missing-lt-outlives-in-rpitit-114274.rs b/tests/ui/impl-trait/in-trait/missing-lt-outlives-in-rpitit-114274.rs
index 2fbc977b165..abc845d3afa 100644
--- a/tests/ui/impl-trait/in-trait/missing-lt-outlives-in-rpitit-114274.rs
+++ b/tests/ui/impl-trait/in-trait/missing-lt-outlives-in-rpitit-114274.rs
@@ -7,7 +7,6 @@ trait Iterable {
 
     fn iter(&self) -> impl Iterator<Item = Self::Item<'missing>>;
     //~^ ERROR use of undeclared lifetime name `'missing`
-    //~| ERROR the parameter type `Self` may not live long enough
 }
 
 fn main() {}
diff --git a/tests/ui/impl-trait/in-trait/missing-lt-outlives-in-rpitit-114274.stderr b/tests/ui/impl-trait/in-trait/missing-lt-outlives-in-rpitit-114274.stderr
index dad308936dc..0d74c0b69ce 100644
--- a/tests/ui/impl-trait/in-trait/missing-lt-outlives-in-rpitit-114274.stderr
+++ b/tests/ui/impl-trait/in-trait/missing-lt-outlives-in-rpitit-114274.stderr
@@ -18,21 +18,6 @@ help: consider introducing lifetime `'missing` here
 LL | trait Iterable<'missing> {
    |               ++++++++++
 
-error[E0311]: the parameter type `Self` may not live long enough
-  --> $DIR/missing-lt-outlives-in-rpitit-114274.rs:8:37
-   |
-LL |     fn iter(&self) -> impl Iterator<Item = Self::Item<'missing>>;
-   |                                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = help: consider adding an explicit lifetime bound `Self: 'a`...
-   = note: ...so that the type `Self` will meet its required lifetime bounds...
-note: ...that is required by this bound
-  --> $DIR/missing-lt-outlives-in-rpitit-114274.rs:6:15
-   |
-LL |         Self: 'a;
-   |               ^^
+error: aborting due to previous error
 
-error: aborting due to 2 previous errors
-
-Some errors have detailed explanations: E0261, E0311.
-For more information about an error, try `rustc --explain E0261`.
+For more information about this error, try `rustc --explain E0261`.