From dce98c52ff3e431d9b1358298fe8da9db545a3e2 Mon Sep 17 00:00:00 2001
From: Oli Scherer <git-spam-no-reply9815368754983@oli-obk.de>
Date: Thu, 4 Jul 2024 10:27:00 +0000
Subject: [PATCH] Avoid follow-up errors and ICEs after missing lifetime errors
 on data structures

---
 .gitignore                                    |  1 +
 compiler/rustc_infer/src/infer/mod.rs         |  3 +++
 tests/crashes/124083.rs                       |  9 --------
 tests/crashes/124262.rs                       |  5 ----
 tests/crashes/125155.rs                       | 17 --------------
 tests/crashes/125888.rs                       | 17 --------------
 tests/crashes/125992.rs                       | 19 ---------------
 tests/crashes/126648.rs                       |  8 -------
 tests/crashes/126666.rs                       | 18 ---------------
 tests/crashes/127266.rs                       | 17 --------------
 tests/crashes/127304.rs                       | 20 ----------------
 tests/rustdoc-ui/unable-fulfill-trait.rs      |  1 -
 tests/rustdoc-ui/unable-fulfill-trait.stderr  | 23 +++----------------
 .../issues/issue-71381.full.stderr            | 18 +++------------
 .../issues/issue-71381.min.stderr             | 20 ++++------------
 tests/ui/const-generics/issues/issue-71381.rs |  1 -
 tests/ui/impl-trait/issue-72911.rs            |  1 -
 tests/ui/impl-trait/issue-72911.stderr        | 13 ++---------
 .../issue-74918-missing-lifetime.rs           |  1 -
 .../issue-74918-missing-lifetime.stderr       | 16 +------------
 tests/ui/statics/missing_lifetime.rs          |  9 ++++++++
 tests/ui/statics/missing_lifetime.stderr      | 11 +++++++++
 22 files changed, 37 insertions(+), 211 deletions(-)
 delete mode 100644 tests/crashes/124083.rs
 delete mode 100644 tests/crashes/124262.rs
 delete mode 100644 tests/crashes/125155.rs
 delete mode 100644 tests/crashes/125888.rs
 delete mode 100644 tests/crashes/125992.rs
 delete mode 100644 tests/crashes/126648.rs
 delete mode 100644 tests/crashes/126666.rs
 delete mode 100644 tests/crashes/127266.rs
 delete mode 100644 tests/crashes/127304.rs
 create mode 100644 tests/ui/statics/missing_lifetime.rs
 create mode 100644 tests/ui/statics/missing_lifetime.stderr

diff --git a/.gitignore b/.gitignore
index 87d02563ed048..f1ca6a79b5c5c 100644
--- a/.gitignore
+++ b/.gitignore
@@ -50,6 +50,7 @@ build/
 /target
 /src/bootstrap/target
 /src/tools/x/target
+/inc-fat/
 # Created by default with `src/ci/docker/run.sh`
 /obj/
 /rustc-ice*
diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs
index 9f55939c165e0..a0be545d46fed 100644
--- a/compiler/rustc_infer/src/infer/mod.rs
+++ b/compiler/rustc_infer/src/infer/mod.rs
@@ -1264,6 +1264,9 @@ impl<'tcx> InferCtxt<'tcx> {
     where
         T: TypeFoldable<TyCtxt<'tcx>>,
     {
+        if let Err(guar) = value.error_reported() {
+            self.set_tainted_by_errors(guar);
+        }
         if !value.has_non_region_infer() {
             return value;
         }
diff --git a/tests/crashes/124083.rs b/tests/crashes/124083.rs
deleted file mode 100644
index e9cbf3f708614..0000000000000
--- a/tests/crashes/124083.rs
+++ /dev/null
@@ -1,9 +0,0 @@
-//@ known-bug: #124083
-
-struct Outest(&'a ());
-
-fn make() -> Outest {}
-
-fn main() {
-    if let Outest("foo") = make() {}
-}
diff --git a/tests/crashes/124262.rs b/tests/crashes/124262.rs
deleted file mode 100644
index b9dac5eca2276..0000000000000
--- a/tests/crashes/124262.rs
+++ /dev/null
@@ -1,5 +0,0 @@
-//@ known-bug: #124262
-//@ edition:2021
-
-struct Foo(<&[fn()] as ::core::ops::Deref>::Target);
-const _: *const Foo = 0 as _;
diff --git a/tests/crashes/125155.rs b/tests/crashes/125155.rs
deleted file mode 100644
index 165061d4b5296..0000000000000
--- a/tests/crashes/125155.rs
+++ /dev/null
@@ -1,17 +0,0 @@
-//@ known-bug: rust-lang/rust#125155
-
-enum NestedEnum {
-    First,
-    Second,
-    Third
-}
-enum Enum {
-    Variant2(Option<*mut &'a &'b ()>)
-}
-
-
-fn foo(x: Enum) -> isize {
-    match x {
-      Enum::Variant2(NestedEnum::Third) => 4,
-    }
-}
diff --git a/tests/crashes/125888.rs b/tests/crashes/125888.rs
deleted file mode 100644
index ae8f2d6576b74..0000000000000
--- a/tests/crashes/125888.rs
+++ /dev/null
@@ -1,17 +0,0 @@
-//@ known-bug: rust-lang/rust#125888
-enum NestedEnum {
-    First,
-    Second,
-}
-
-enum Enum {
-    Variant(*const &'a ()),
-}
-
-fn foo(x: Enum) {
-    match x {
-        Enum::Variant(NestedEnum::Second) => {}
-    }
-}
-
-fn main() {}
diff --git a/tests/crashes/125992.rs b/tests/crashes/125992.rs
deleted file mode 100644
index d78f28ce6de41..0000000000000
--- a/tests/crashes/125992.rs
+++ /dev/null
@@ -1,19 +0,0 @@
-//@ known-bug: rust-lang/rust#125992
-//@ compile-flags:  -Zpolonius=next
-
-#![feature(inherent_associated_types)]
-
-type Function = for<'a> fn(&'a i32) -> S<'a>::P;
-
-struct S<'a>(&'a ());
-
-impl<'a> S {
-    type P = &'a i32;
-}
-
-fn ret_ref_local<'e>() -> &'e i32 {
-    let f: Function = |x| x;
-
-    let local = 0;
-    f(&local)
-}
diff --git a/tests/crashes/126648.rs b/tests/crashes/126648.rs
deleted file mode 100644
index 1cf3e44bba9bc..0000000000000
--- a/tests/crashes/126648.rs
+++ /dev/null
@@ -1,8 +0,0 @@
-//@ known-bug: rust-lang/rust#126648
-struct Outest(*const &'a ());
-
-fn make() -> Outest {}
-
-fn main() {
-    if let Outest("foo") = make() {}
-}
diff --git a/tests/crashes/126666.rs b/tests/crashes/126666.rs
deleted file mode 100644
index 58526707c9ab4..0000000000000
--- a/tests/crashes/126666.rs
+++ /dev/null
@@ -1,18 +0,0 @@
-//@ known-bug: rust-lang/rust#126666
-#![feature(const_mut_refs)]
-#![feature(const_refs_to_static)]
-#![feature(object_safe_for_dispatch)]
-
-struct Meh {
-    x: &'static dyn UnsafeCell,
-}
-
-const MUH: Meh = Meh {
-    x: &mut *(&READONLY as *const _ as *mut _),
-};
-
-static READONLY: i32 = 0;
-
-trait UnsafeCell<'a> {}
-
-pub fn main() {}
diff --git a/tests/crashes/127266.rs b/tests/crashes/127266.rs
deleted file mode 100644
index 2bdbe03e373a9..0000000000000
--- a/tests/crashes/127266.rs
+++ /dev/null
@@ -1,17 +0,0 @@
-//@ known-bug: rust-lang/rust#127266
-#![feature(const_mut_refs)]
-#![feature(const_refs_to_static)]
-
-struct Meh {
-    x: &'static dyn UnsafeCell,
-}
-
-const MUH: Meh = Meh {
-    x: &mut *(READONLY as *mut _),
-};
-
-static READONLY: i32 = 0;
-
-trait UnsafeCell<'a> {}
-
-pub fn main() {}
diff --git a/tests/crashes/127304.rs b/tests/crashes/127304.rs
deleted file mode 100644
index 2975fc27f6766..0000000000000
--- a/tests/crashes/127304.rs
+++ /dev/null
@@ -1,20 +0,0 @@
-//@ known-bug: rust-lang/rust #127304
-#![feature(adt_const_params)]
-
-trait Trait<T> {}
-impl Trait<u16> for () {}
-
-struct MyStr(str);
-impl std::marker::ConstParamTy for MyStr {}
-
-fn function_with_my_str<const S: &'static MyStr>() -> &'static MyStr {
-    S
-}
-
-impl MyStr {
-    const fn new(s: &Trait str) -> &'static MyStr {}
-}
-
-pub fn main() {
-    let f = function_with_my_str::<{ MyStr::new("hello") }>();
-}
diff --git a/tests/rustdoc-ui/unable-fulfill-trait.rs b/tests/rustdoc-ui/unable-fulfill-trait.rs
index f3b6256346f0c..4edc7ab76c198 100644
--- a/tests/rustdoc-ui/unable-fulfill-trait.rs
+++ b/tests/rustdoc-ui/unable-fulfill-trait.rs
@@ -4,7 +4,6 @@ pub struct Foo<'a, 'b, T> {
     field1: dyn Bar<'a, 'b>,
     //~^ ERROR
     //~| ERROR
-    //~| ERROR
 }
 
 pub trait Bar<'x, 's, U>
diff --git a/tests/rustdoc-ui/unable-fulfill-trait.stderr b/tests/rustdoc-ui/unable-fulfill-trait.stderr
index 40d103f2a62e7..12e53546cdacc 100644
--- a/tests/rustdoc-ui/unable-fulfill-trait.stderr
+++ b/tests/rustdoc-ui/unable-fulfill-trait.stderr
@@ -5,7 +5,7 @@ LL |     field1: dyn Bar<'a, 'b>,
    |                 ^^^ expected 1 generic argument
    |
 note: trait defined here, with 1 generic parameter: `U`
-  --> $DIR/unable-fulfill-trait.rs:10:11
+  --> $DIR/unable-fulfill-trait.rs:9:11
    |
 LL | pub trait Bar<'x, 's, U>
    |           ^^^         -
@@ -20,24 +20,7 @@ error[E0227]: ambiguous lifetime bound, explicit lifetime bound required
 LL |     field1: dyn Bar<'a, 'b>,
    |             ^^^^^^^^^^^^^^^
 
-error[E0478]: lifetime bound not satisfied
-  --> $DIR/unable-fulfill-trait.rs:4:13
-   |
-LL |     field1: dyn Bar<'a, 'b>,
-   |             ^^^^^^^^^^^^^^^
-   |
-note: lifetime parameter instantiated with the lifetime `'b` as defined here
-  --> $DIR/unable-fulfill-trait.rs:3:20
-   |
-LL | pub struct Foo<'a, 'b, T> {
-   |                    ^^
-note: but lifetime parameter must outlive the lifetime `'a` as defined here
-  --> $DIR/unable-fulfill-trait.rs:3:16
-   |
-LL | pub struct Foo<'a, 'b, T> {
-   |                ^^
-
-error: aborting due to 3 previous errors
+error: aborting due to 2 previous errors
 
-Some errors have detailed explanations: E0107, E0227, E0478.
+Some errors have detailed explanations: E0107, E0227.
 For more information about an error, try `rustc --explain E0107`.
diff --git a/tests/ui/const-generics/issues/issue-71381.full.stderr b/tests/ui/const-generics/issues/issue-71381.full.stderr
index 05e847cf4c841..b6460e0017fa5 100644
--- a/tests/ui/const-generics/issues/issue-71381.full.stderr
+++ b/tests/ui/const-generics/issues/issue-71381.full.stderr
@@ -7,25 +7,13 @@ LL |     pub fn call_me<Args: Sized, const IDX: usize, const FN: unsafe extern "
    = note: type parameters may not be used in the type of const parameters
 
 error[E0770]: the type of const parameters must not depend on other generic parameters
-  --> $DIR/issue-71381.rs:24:40
+  --> $DIR/issue-71381.rs:23:40
    |
 LL |         const FN: unsafe extern "C" fn(Args),
    |                                        ^^^^ the type must not depend on the parameter `Args`
    |
    = note: type parameters may not be used in the type of const parameters
 
-error[E0594]: cannot assign to `self.0`, which is behind a `&` reference
-  --> $DIR/issue-71381.rs:17:9
-   |
-LL |         self.0 = Self::trampiline::<Args, IDX, FN> as _
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `self` is a `&` reference, so the data it refers to cannot be written
-   |
-help: consider changing this to be a mutable reference
-   |
-LL |     pub fn call_me<Args: Sized, const IDX: usize, const FN: unsafe extern "C" fn(Args)>(&mut self) {
-   |                                                                                         ~~~~~~~~~
-
-error: aborting due to 3 previous errors
+error: aborting due to 2 previous errors
 
-Some errors have detailed explanations: E0594, E0770.
-For more information about an error, try `rustc --explain E0594`.
+For more information about this error, try `rustc --explain E0770`.
diff --git a/tests/ui/const-generics/issues/issue-71381.min.stderr b/tests/ui/const-generics/issues/issue-71381.min.stderr
index 1c30e885d1b7d..e16d3b7a8a469 100644
--- a/tests/ui/const-generics/issues/issue-71381.min.stderr
+++ b/tests/ui/const-generics/issues/issue-71381.min.stderr
@@ -7,7 +7,7 @@ LL |     pub fn call_me<Args: Sized, const IDX: usize, const FN: unsafe extern "
    = note: type parameters may not be used in the type of const parameters
 
 error[E0770]: the type of const parameters must not depend on other generic parameters
-  --> $DIR/issue-71381.rs:24:40
+  --> $DIR/issue-71381.rs:23:40
    |
 LL |         const FN: unsafe extern "C" fn(Args),
    |                                        ^^^^ the type must not depend on the parameter `Args`
@@ -23,25 +23,13 @@ LL |     pub fn call_me<Args: Sized, const IDX: usize, const FN: unsafe extern "
    = note: the only supported types are integers, `bool` and `char`
 
 error: using function pointers as const generic parameters is forbidden
-  --> $DIR/issue-71381.rs:24:19
+  --> $DIR/issue-71381.rs:23:19
    |
 LL |         const FN: unsafe extern "C" fn(Args),
    |                   ^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = note: the only supported types are integers, `bool` and `char`
 
-error[E0594]: cannot assign to `self.0`, which is behind a `&` reference
-  --> $DIR/issue-71381.rs:17:9
-   |
-LL |         self.0 = Self::trampiline::<Args, IDX, FN> as _
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `self` is a `&` reference, so the data it refers to cannot be written
-   |
-help: consider changing this to be a mutable reference
-   |
-LL |     pub fn call_me<Args: Sized, const IDX: usize, const FN: unsafe extern "C" fn(Args)>(&mut self) {
-   |                                                                                         ~~~~~~~~~
-
-error: aborting due to 5 previous errors
+error: aborting due to 4 previous errors
 
-Some errors have detailed explanations: E0594, E0770.
-For more information about an error, try `rustc --explain E0594`.
+For more information about this error, try `rustc --explain E0770`.
diff --git a/tests/ui/const-generics/issues/issue-71381.rs b/tests/ui/const-generics/issues/issue-71381.rs
index 166b724a7a33a..e472ef31fcdd3 100644
--- a/tests/ui/const-generics/issues/issue-71381.rs
+++ b/tests/ui/const-generics/issues/issue-71381.rs
@@ -15,7 +15,6 @@ impl Test {
         //~^ ERROR: the type of const parameters must not depend on other generic parameters
         //[min]~^^ ERROR: using function pointers as const generic parameters is forbidden
         self.0 = Self::trampiline::<Args, IDX, FN> as _
-        //~^ ERROR: cannot assign to `self.0`
     }
 
     unsafe extern "C" fn trampiline<
diff --git a/tests/ui/impl-trait/issue-72911.rs b/tests/ui/impl-trait/issue-72911.rs
index 7ba8579e24fb1..63f4898f4306b 100644
--- a/tests/ui/impl-trait/issue-72911.rs
+++ b/tests/ui/impl-trait/issue-72911.rs
@@ -15,7 +15,6 @@ fn gather_from_file(dir_entry: &foo::MissingItem) -> impl Iterator<Item = Lint>
 
 fn lint_files() -> impl Iterator<Item = foo::MissingItem> {
     //~^ ERROR: failed to resolve
-    //~| ERROR: `()` is not an iterator
     unimplemented!()
 }
 
diff --git a/tests/ui/impl-trait/issue-72911.stderr b/tests/ui/impl-trait/issue-72911.stderr
index 44c20a7be53df..0e86561aa2779 100644
--- a/tests/ui/impl-trait/issue-72911.stderr
+++ b/tests/ui/impl-trait/issue-72911.stderr
@@ -1,11 +1,3 @@
-error[E0277]: `()` is not an iterator
-  --> $DIR/issue-72911.rs:16:20
-   |
-LL | fn lint_files() -> impl Iterator<Item = foo::MissingItem> {
-   |                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `()` is not an iterator
-   |
-   = help: the trait `Iterator` is not implemented for `()`
-
 error[E0433]: failed to resolve: use of undeclared crate or module `foo`
   --> $DIR/issue-72911.rs:11:33
    |
@@ -18,7 +10,6 @@ error[E0433]: failed to resolve: use of undeclared crate or module `foo`
 LL | fn lint_files() -> impl Iterator<Item = foo::MissingItem> {
    |                                         ^^^ use of undeclared crate or module `foo`
 
-error: aborting due to 3 previous errors
+error: aborting due to 2 previous errors
 
-Some errors have detailed explanations: E0277, E0433.
-For more information about an error, try `rustc --explain E0277`.
+For more information about this error, try `rustc --explain E0433`.
diff --git a/tests/ui/mismatched_types/issue-74918-missing-lifetime.rs b/tests/ui/mismatched_types/issue-74918-missing-lifetime.rs
index c7842667dc614..6aa34354a7ad9 100644
--- a/tests/ui/mismatched_types/issue-74918-missing-lifetime.rs
+++ b/tests/ui/mismatched_types/issue-74918-missing-lifetime.rs
@@ -9,7 +9,6 @@ impl<T, S: Iterator<Item = T>> Iterator for ChunkingIterator<T, S> {
     type Item = IteratorChunk<T, S>; //~ ERROR missing lifetime
 
     fn next(&mut self) -> Option<IteratorChunk<T, S>> {
-        //~^ ERROR `impl` item signature doesn't match `trait` item signature
         todo!()
     }
 }
diff --git a/tests/ui/mismatched_types/issue-74918-missing-lifetime.stderr b/tests/ui/mismatched_types/issue-74918-missing-lifetime.stderr
index b523182309959..5020395eb6aea 100644
--- a/tests/ui/mismatched_types/issue-74918-missing-lifetime.stderr
+++ b/tests/ui/mismatched_types/issue-74918-missing-lifetime.stderr
@@ -9,20 +9,6 @@ help: consider introducing a named lifetime parameter
 LL |     type Item<'a> = IteratorChunk<'a, T, S>;
    |              ++++                 +++
 
-error: `impl` item signature doesn't match `trait` item signature
-  --> $DIR/issue-74918-missing-lifetime.rs:11:5
-   |
-LL |     fn next(&mut self) -> Option<IteratorChunk<T, S>> {
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ found `fn(&'1 mut ChunkingIterator<T, S>) -> Option<IteratorChunk<'1, T, S>>`
-  --> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL
-   |
-   = note: expected `fn(&'1 mut ChunkingIterator<T, S>) -> Option<IteratorChunk<'2, T, S>>`
-   |
-   = note: expected signature `fn(&'1 mut ChunkingIterator<T, S>) -> Option<IteratorChunk<'2, T, S>>`
-              found signature `fn(&'1 mut ChunkingIterator<T, S>) -> Option<IteratorChunk<'1, T, S>>`
-   = help: the lifetime requirements from the `impl` do not correspond to the requirements in the `trait`
-   = help: verify the lifetime relationships in the `trait` and `impl` between the `self` argument, the other inputs and its output
-
-error: aborting due to 2 previous errors
+error: aborting due to 1 previous error
 
 For more information about this error, try `rustc --explain E0106`.
diff --git a/tests/ui/statics/missing_lifetime.rs b/tests/ui/statics/missing_lifetime.rs
new file mode 100644
index 0000000000000..e6a63ef221c6a
--- /dev/null
+++ b/tests/ui/statics/missing_lifetime.rs
@@ -0,0 +1,9 @@
+//! This test checks that we taint typeck results when there are
+//! error lifetimes, even though typeck doesn't actually care about lifetimes.
+
+struct Slice(&'reborrow [&'static [u8]]);
+//~^ ERROR undeclared lifetime
+
+static MAP: Slice = Slice(&[b"" as &'static [u8]]);
+
+fn main() {}
diff --git a/tests/ui/statics/missing_lifetime.stderr b/tests/ui/statics/missing_lifetime.stderr
new file mode 100644
index 0000000000000..e23b27f7a6a6d
--- /dev/null
+++ b/tests/ui/statics/missing_lifetime.stderr
@@ -0,0 +1,11 @@
+error[E0261]: use of undeclared lifetime name `'reborrow`
+  --> $DIR/missing_lifetime.rs:4:15
+   |
+LL | struct Slice(&'reborrow [&'static [u8]]);
+   |             - ^^^^^^^^^ undeclared lifetime
+   |             |
+   |             help: consider introducing lifetime `'reborrow` here: `<'reborrow>`
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0261`.