From a5888a22dab2f8ddd5f9b819795769d4d34ddb4b Mon Sep 17 00:00:00 2001
From: Niko Matsakis <niko@alum.mit.edu>
Date: Thu, 30 Jun 2022 16:44:41 -0400
Subject: [PATCH 1/2] don't prove WC when projecting from param-env

If the param-env tells you that, forall 'a, `T::Item<'a> = u32`,
we can believe it.
---
 .../src/traits/project.rs                     |  2 +-
 .../rustc_typeck/src/check/compare_method.rs  |  3 +
 .../feature-gate-generic_associated_types.rs  | 14 ++--
 ...ature-gate-generic_associated_types.stderr | 44 +++++------
 .../bugs/issue-87755.rs                       |  9 +--
 .../bugs/issue-87755.stderr                   |  9 ---
 .../collectivity-regression.rs                |  6 +-
 .../collectivity-regression.stderr            | 14 ----
 .../extended/lending_iterator.rs              |  7 +-
 .../extended/lending_iterator_2.rs            |  7 +-
 .../generic-associated-types-where.rs         | 16 ++--
 .../generic-associated-types-where.stderr     | 19 +----
 .../generic-associated-types/impl_bounds.rs   | 24 ++++--
 .../impl_bounds.stderr                        | 77 ++++++++-----------
 .../generic-associated-types/issue-90014.rs   |  6 +-
 .../issue-90014.stderr                        | 18 -----
 .../generic-associated-types/issue-91883.rs   |  6 +-
 .../issue-91883.stderr                        | 26 -------
 .../generic-associated-types/issue-92033.rs   |  3 +-
 .../issue-92033.stderr                        | 20 -----
 .../trait-objects.base.stderr                 |  6 +-
 .../trait-objects.extended.stderr             | 17 ----
 .../generic-associated-types/trait-objects.rs |  8 +-
 .../unsatified-item-lifetime-bound.rs         |  1 -
 .../unsatified-item-lifetime-bound.stderr     | 23 ++----
 25 files changed, 125 insertions(+), 260 deletions(-)
 delete mode 100644 src/test/ui/generic-associated-types/bugs/issue-87755.stderr
 delete mode 100644 src/test/ui/generic-associated-types/collectivity-regression.stderr
 delete mode 100644 src/test/ui/generic-associated-types/issue-90014.stderr
 delete mode 100644 src/test/ui/generic-associated-types/issue-91883.stderr
 delete mode 100644 src/test/ui/generic-associated-types/issue-92033.stderr
 delete mode 100644 src/test/ui/generic-associated-types/trait-objects.extended.stderr

diff --git a/compiler/rustc_trait_selection/src/traits/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs
index aba4f144d4bcc..3d723558fb3c4 100644
--- a/compiler/rustc_trait_selection/src/traits/project.rs
+++ b/compiler/rustc_trait_selection/src/traits/project.rs
@@ -1951,7 +1951,7 @@ fn confirm_param_env_candidate<'cx, 'tcx>(
     match infcx.at(cause, param_env).eq(cache_projection, obligation_projection) {
         Ok(InferOk { value: _, obligations }) => {
             nested_obligations.extend(obligations);
-            assoc_ty_own_obligations(selcx, obligation, &mut nested_obligations);
+            // NDM assoc_ty_own_obligations(selcx, obligation, &mut nested_obligations);
             // FIXME(associated_const_equality): Handle consts here as well? Maybe this progress type should just take
             // a term instead.
             Progress { term: cache_entry.term, obligations: nested_obligations }
diff --git a/compiler/rustc_typeck/src/check/compare_method.rs b/compiler/rustc_typeck/src/check/compare_method.rs
index 95c82a7d2c3d8..4942e314c5f17 100644
--- a/compiler/rustc_typeck/src/check/compare_method.rs
+++ b/compiler/rustc_typeck/src/check/compare_method.rs
@@ -222,8 +222,11 @@ fn compare_predicate_entailment<'tcx>(
         let impl_m_own_bounds = impl_m_predicates.instantiate_own(tcx, impl_to_placeholder_substs);
         for (predicate, span) in iter::zip(impl_m_own_bounds.predicates, impl_m_own_bounds.spans) {
             let normalize_cause = traits::ObligationCause::misc(span, impl_m_hir_id);
+            debug!("predicate before normalization: {:?}", predicate);
             let traits::Normalized { value: predicate, obligations } =
                 traits::normalize(&mut selcx, param_env, normalize_cause, predicate);
+            debug!("predicate after normalization: {:?}", predicate);
+            debug!("normalization obligations: {:#?}", obligations);
 
             inh.register_predicates(obligations);
             let cause = ObligationCause::new(
diff --git a/src/test/ui/feature-gates/feature-gate-generic_associated_types.rs b/src/test/ui/feature-gates/feature-gate-generic_associated_types.rs
index c5c1345148891..2038285d35f4f 100644
--- a/src/test/ui/feature-gates/feature-gate-generic_associated_types.rs
+++ b/src/test/ui/feature-gates/feature-gate-generic_associated_types.rs
@@ -3,8 +3,11 @@ use std::ops::Deref;
 trait PointerFamily<U> {
     type Pointer<T>: Deref<Target = T>;
     //~^ ERROR generic associated types are unstable
-    type Pointer2<T>: Deref<Target = T> where T: Clone, U: Clone;
-    //~^ ERROR generic associated types are unstable
+    type Pointer2<T>: Deref<Target = T>
+    where
+        T: Clone,
+        U: Clone;
+    //~^^^^ ERROR generic associated types are unstable
     //~| ERROR where clauses on associated types are unstable
 }
 
@@ -15,12 +18,13 @@ impl PointerFamily<u32> for Foo {
     //~^ ERROR generic associated types are unstable
     type Pointer2<U32> = Box<U32>;
     //~^ ERROR generic associated types are unstable
-    //~| ERROR the trait bound `U32: Clone` is not satisfied
 }
 
 trait Bar {
-    type Assoc where Self: Sized;
-    //~^ ERROR where clauses on associated types are unstable
+    type Assoc
+    where
+        Self: Sized;
+    //~^^^ ERROR where clauses on associated types are unstable
 }
 
 impl Bar for Foo {
diff --git a/src/test/ui/feature-gates/feature-gate-generic_associated_types.stderr b/src/test/ui/feature-gates/feature-gate-generic_associated_types.stderr
index 12a40ff0a12f5..89c6ce4072c37 100644
--- a/src/test/ui/feature-gates/feature-gate-generic_associated_types.stderr
+++ b/src/test/ui/feature-gates/feature-gate-generic_associated_types.stderr
@@ -10,8 +10,11 @@ LL |     type Pointer<T>: Deref<Target = T>;
 error[E0658]: generic associated types are unstable
   --> $DIR/feature-gate-generic_associated_types.rs:6:5
    |
-LL |     type Pointer2<T>: Deref<Target = T> where T: Clone, U: Clone;
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | /     type Pointer2<T>: Deref<Target = T>
+LL | |     where
+LL | |         T: Clone,
+LL | |         U: Clone;
+   | |_________________^
    |
    = note: see issue #44265 <https://github.com/rust-lang/rust/issues/44265> for more information
    = help: add `#![feature(generic_associated_types)]` to the crate attributes to enable
@@ -19,14 +22,17 @@ LL |     type Pointer2<T>: Deref<Target = T> where T: Clone, U: Clone;
 error[E0658]: where clauses on associated types are unstable
   --> $DIR/feature-gate-generic_associated_types.rs:6:5
    |
-LL |     type Pointer2<T>: Deref<Target = T> where T: Clone, U: Clone;
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | /     type Pointer2<T>: Deref<Target = T>
+LL | |     where
+LL | |         T: Clone,
+LL | |         U: Clone;
+   | |_________________^
    |
    = note: see issue #44265 <https://github.com/rust-lang/rust/issues/44265> for more information
    = help: add `#![feature(generic_associated_types)]` to the crate attributes to enable
 
 error[E0658]: generic associated types are unstable
-  --> $DIR/feature-gate-generic_associated_types.rs:14:5
+  --> $DIR/feature-gate-generic_associated_types.rs:17:5
    |
 LL |     type Pointer<Usize> = Box<Usize>;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -35,7 +41,7 @@ LL |     type Pointer<Usize> = Box<Usize>;
    = help: add `#![feature(generic_associated_types)]` to the crate attributes to enable
 
 error[E0658]: generic associated types are unstable
-  --> $DIR/feature-gate-generic_associated_types.rs:16:5
+  --> $DIR/feature-gate-generic_associated_types.rs:19:5
    |
 LL |     type Pointer2<U32> = Box<U32>;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -44,16 +50,18 @@ LL |     type Pointer2<U32> = Box<U32>;
    = help: add `#![feature(generic_associated_types)]` to the crate attributes to enable
 
 error[E0658]: where clauses on associated types are unstable
-  --> $DIR/feature-gate-generic_associated_types.rs:22:5
+  --> $DIR/feature-gate-generic_associated_types.rs:24:5
    |
-LL |     type Assoc where Self: Sized;
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | /     type Assoc
+LL | |     where
+LL | |         Self: Sized;
+   | |____________________^
    |
    = note: see issue #44265 <https://github.com/rust-lang/rust/issues/44265> for more information
    = help: add `#![feature(generic_associated_types)]` to the crate attributes to enable
 
 error[E0658]: where clauses on associated types are unstable
-  --> $DIR/feature-gate-generic_associated_types.rs:27:5
+  --> $DIR/feature-gate-generic_associated_types.rs:31:5
    |
 LL |     type Assoc = Foo where Self: Sized;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -61,18 +69,6 @@ LL |     type Assoc = Foo where Self: Sized;
    = note: see issue #44265 <https://github.com/rust-lang/rust/issues/44265> for more information
    = help: add `#![feature(generic_associated_types)]` to the crate attributes to enable
 
-error[E0277]: the trait bound `U32: Clone` is not satisfied
-  --> $DIR/feature-gate-generic_associated_types.rs:16:26
-   |
-LL |     type Pointer2<U32> = Box<U32>;
-   |                          ^^^^^^^^ the trait `Clone` is not implemented for `U32`
-   |
-help: consider restricting type parameter `U32`
-   |
-LL |     type Pointer2<U32: std::clone::Clone> = Box<U32>;
-   |                      +++++++++++++++++++
-
-error: aborting due to 8 previous errors
+error: aborting due to 7 previous errors
 
-Some errors have detailed explanations: E0277, E0658.
-For more information about an error, try `rustc --explain E0277`.
+For more information about this error, try `rustc --explain E0658`.
diff --git a/src/test/ui/generic-associated-types/bugs/issue-87755.rs b/src/test/ui/generic-associated-types/bugs/issue-87755.rs
index efa487d624fd9..c0c8081164ca3 100644
--- a/src/test/ui/generic-associated-types/bugs/issue-87755.rs
+++ b/src/test/ui/generic-associated-types/bugs/issue-87755.rs
@@ -1,14 +1,13 @@
-// check-fail
-// known-bug: #87755
-
-// This should pass.
+// check-pass
 
 #![feature(generic_associated_types)]
 
 use std::fmt::Debug;
 
 trait Foo {
-    type Ass where Self::Ass: Debug;
+    type Ass
+    where
+        Self::Ass: Debug;
 }
 
 #[derive(Debug)]
diff --git a/src/test/ui/generic-associated-types/bugs/issue-87755.stderr b/src/test/ui/generic-associated-types/bugs/issue-87755.stderr
deleted file mode 100644
index 5d1aff0117c13..0000000000000
--- a/src/test/ui/generic-associated-types/bugs/issue-87755.stderr
+++ /dev/null
@@ -1,9 +0,0 @@
-error[E0275]: overflow evaluating the requirement `<Bar as Foo>::Ass == _`
-  --> $DIR/issue-87755.rs:18:16
-   |
-LL |     type Ass = Bar;
-   |                ^^^
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0275`.
diff --git a/src/test/ui/generic-associated-types/collectivity-regression.rs b/src/test/ui/generic-associated-types/collectivity-regression.rs
index fb73684390737..04bd17ded4a93 100644
--- a/src/test/ui/generic-associated-types/collectivity-regression.rs
+++ b/src/test/ui/generic-associated-types/collectivity-regression.rs
@@ -1,4 +1,6 @@
 // Regression test from https://github.com/rust-lang/rust/pull/98109
+//
+// check-pass
 
 #![feature(generic_associated_types)]
 
@@ -13,10 +15,6 @@ where
     for<'a> T: Get<Value<'a> = ()>,
 {
     || {
-        //~^ `T` does not live long enough
-        //
-        // FIXME(#98437). This regressed at some point and
-        // probably should work.
         let _x = x;
     };
 }
diff --git a/src/test/ui/generic-associated-types/collectivity-regression.stderr b/src/test/ui/generic-associated-types/collectivity-regression.stderr
deleted file mode 100644
index a858dd7fddcd2..0000000000000
--- a/src/test/ui/generic-associated-types/collectivity-regression.stderr
+++ /dev/null
@@ -1,14 +0,0 @@
-error: `T` does not live long enough
-  --> $DIR/collectivity-regression.rs:15:5
-   |
-LL | /     || {
-LL | |
-LL | |         //
-LL | |         // FIXME(#98437). This regressed at some point and
-LL | |         // probably should work.
-LL | |         let _x = x;
-LL | |     };
-   | |_____^
-
-error: aborting due to previous error
-
diff --git a/src/test/ui/generic-associated-types/extended/lending_iterator.rs b/src/test/ui/generic-associated-types/extended/lending_iterator.rs
index ede164766361e..e80443fada35d 100644
--- a/src/test/ui/generic-associated-types/extended/lending_iterator.rs
+++ b/src/test/ui/generic-associated-types/extended/lending_iterator.rs
@@ -1,10 +1,6 @@
-// revisions: base extended
-//[base] check-fail
-//[extended] check-pass
+// check-pass
 
 #![feature(generic_associated_types)]
-#![cfg_attr(extended, feature(generic_associated_types_extended))]
-#![cfg_attr(extended, allow(incomplete_features))]
 
 pub trait FromLendingIterator<A>: Sized {
     fn from_iter<T: for<'x> LendingIterator<Item<'x> = A>>(iter: T) -> Self;
@@ -12,7 +8,6 @@ pub trait FromLendingIterator<A>: Sized {
 
 impl<A> FromLendingIterator<A> for Vec<A> {
     fn from_iter<I: for<'x> LendingIterator<Item<'x> = A>>(mut iter: I) -> Self {
-        //[base]~^ impl has stricter
         let mut v = vec![];
         while let Some(item) = iter.next() {
             v.push(item);
diff --git a/src/test/ui/generic-associated-types/extended/lending_iterator_2.rs b/src/test/ui/generic-associated-types/extended/lending_iterator_2.rs
index 3c4a2184db90c..7eb012074e09f 100644
--- a/src/test/ui/generic-associated-types/extended/lending_iterator_2.rs
+++ b/src/test/ui/generic-associated-types/extended/lending_iterator_2.rs
@@ -1,10 +1,6 @@
-// revisions: base extended
-//[base] check-fail
-//[extended] check-pass
+// check-pass
 
 #![feature(generic_associated_types)]
-#![cfg_attr(extended, feature(generic_associated_types_extended))]
-#![cfg_attr(extended, allow(incomplete_features))]
 
 pub trait FromLendingIterator<A>: Sized {
     fn from_iter<T: for<'x> LendingIterator<Item<'x> = A>>(iter: T) -> Self;
@@ -12,7 +8,6 @@ pub trait FromLendingIterator<A>: Sized {
 
 impl<A> FromLendingIterator<A> for Vec<A> {
     fn from_iter<I: for<'x> LendingIterator<Item<'x> = A>>(mut iter: I) -> Self {
-        //[base]~^ impl has stricter
         let mut v = vec![];
         while let Some(item) = iter.next() {
             v.push(item);
diff --git a/src/test/ui/generic-associated-types/generic-associated-types-where.rs b/src/test/ui/generic-associated-types/generic-associated-types-where.rs
index 2ecbc8c591259..0b0f6f56e41ce 100644
--- a/src/test/ui/generic-associated-types/generic-associated-types-where.rs
+++ b/src/test/ui/generic-associated-types/generic-associated-types-where.rs
@@ -1,15 +1,18 @@
 #![feature(generic_associated_types)]
-
 // Checking the interaction with this other feature
 #![feature(associated_type_defaults)]
 
-use std::fmt::{Display, Debug};
+use std::fmt::{Debug, Display};
 
 trait Foo {
-    type Assoc where Self: Sized;
-    type Assoc2<T> where T: Display;
+    type Assoc
+    where
+        Self: Sized;
+    type Assoc2<T>
+    where
+        T: Display;
     type Assoc3<T>;
-    type WithDefault<'a, T: Debug + 'a>: ?Sized = dyn Iterator<Item=T>;
+    type WithDefault<'a, T: Debug + 'a>: ?Sized = dyn Iterator<Item = T>;
     type NoGenerics;
 }
 
@@ -18,10 +21,9 @@ struct Bar;
 impl Foo for Bar {
     type Assoc = usize;
     type Assoc2<T> = Vec<T>;
-    //~^ ERROR `T` doesn't implement `std::fmt::Display`
     type Assoc3<T> = Vec<T> where T: Iterator;
     //~^ ERROR impl has stricter requirements than trait
-    type WithDefault<'a, T: Debug + 'a> = &'a dyn Iterator<Item=T>;
+    type WithDefault<'a, T: Debug + 'a> = &'a dyn Iterator<Item = T>;
     type NoGenerics = ::std::cell::Cell<i32>;
 }
 
diff --git a/src/test/ui/generic-associated-types/generic-associated-types-where.stderr b/src/test/ui/generic-associated-types/generic-associated-types-where.stderr
index 68594bba48632..83aefe8686ce1 100644
--- a/src/test/ui/generic-associated-types/generic-associated-types-where.stderr
+++ b/src/test/ui/generic-associated-types/generic-associated-types-where.stderr
@@ -1,17 +1,5 @@
-error[E0277]: `T` doesn't implement `std::fmt::Display`
-  --> $DIR/generic-associated-types-where.rs:20:22
-   |
-LL |     type Assoc2<T> = Vec<T>;
-   |                      ^^^^^^ `T` cannot be formatted with the default formatter
-   |
-   = note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead
-help: consider restricting type parameter `T`
-   |
-LL |     type Assoc2<T: std::fmt::Display> = Vec<T>;
-   |                  +++++++++++++++++++
-
 error[E0276]: impl has stricter requirements than trait
-  --> $DIR/generic-associated-types-where.rs:22:5
+  --> $DIR/generic-associated-types-where.rs:24:5
    |
 LL |     type Assoc3<T>;
    |     --------------- definition of `Assoc3` from trait
@@ -19,7 +7,6 @@ LL |     type Assoc3<T>;
 LL |     type Assoc3<T> = Vec<T> where T: Iterator;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl has extra requirement `T: Iterator`
 
-error: aborting due to 2 previous errors
+error: aborting due to previous error
 
-Some errors have detailed explanations: E0276, E0277.
-For more information about an error, try `rustc --explain E0276`.
+For more information about this error, try `rustc --explain E0276`.
diff --git a/src/test/ui/generic-associated-types/impl_bounds.rs b/src/test/ui/generic-associated-types/impl_bounds.rs
index bb5992c88f08f..3331484af2406 100644
--- a/src/test/ui/generic-associated-types/impl_bounds.rs
+++ b/src/test/ui/generic-associated-types/impl_bounds.rs
@@ -2,10 +2,18 @@
 #![feature(associated_type_defaults)]
 
 trait Foo {
-    type A<'a> where Self: 'a;
-    type B<'a, 'b> where 'a: 'b;
-    type C where Self: Clone;
-    fn d() where Self: Clone;
+    type A<'a>
+    where
+        Self: 'a;
+    type B<'a, 'b>
+    where
+        'a: 'b;
+    type C
+    where
+        Self: Clone;
+    fn d()
+    where
+        Self: Clone;
 }
 
 #[derive(Copy, Clone)]
@@ -16,11 +24,13 @@ impl<T> Foo for Fooy<T> {
     //~^ ERROR `impl` associated type
     type B<'a, 'b> = (&'a(), &'b ()) where 'b: 'a;
     //~^ ERROR `impl` associated type
-    //~| ERROR lifetime bound not satisfied
     type C = String where Self: Copy;
     //~^ ERROR the trait bound `T: Copy` is not satisfied
-    fn d() where Self: Copy {}
-    //~^ ERROR the trait bound `T: Copy` is not satisfied
+    fn d()
+    where
+        Self: Copy, //~ ERROR the trait bound `T: Copy` is not satisfied
+    {
+    }
 }
 
 fn main() {}
diff --git a/src/test/ui/generic-associated-types/impl_bounds.stderr b/src/test/ui/generic-associated-types/impl_bounds.stderr
index 3d90471e398e6..bca92f1ba6640 100644
--- a/src/test/ui/generic-associated-types/impl_bounds.stderr
+++ b/src/test/ui/generic-associated-types/impl_bounds.stderr
@@ -1,60 +1,46 @@
 error: `impl` associated type signature for `A` doesn't match `trait` associated type signature
-  --> $DIR/impl_bounds.rs:15:5
+  --> $DIR/impl_bounds.rs:23:5
    |
-LL |     type A<'a> where Self: 'a;
-   |     -------------------------- expected
+LL | /     type A<'a>
+LL | |     where
+LL | |         Self: 'a;
+   | |_________________- expected
 ...
-LL |     type A<'a> = (&'a ()) where Self: 'static;
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ found
+LL |       type A<'a> = (&'a ()) where Self: 'static;
+   |       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ found
 
 error: `impl` associated type signature for `B` doesn't match `trait` associated type signature
-  --> $DIR/impl_bounds.rs:17:5
+  --> $DIR/impl_bounds.rs:25:5
    |
-LL |     type B<'a, 'b> where 'a: 'b;
-   |     ---------------------------- expected
+LL | /     type B<'a, 'b>
+LL | |     where
+LL | |         'a: 'b;
+   | |_______________- expected
 ...
-LL |     type B<'a, 'b> = (&'a(), &'b ()) where 'b: 'a;
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ found
-
-error[E0478]: lifetime bound not satisfied
-  --> $DIR/impl_bounds.rs:17:22
-   |
-LL |     type B<'a, 'b> where 'a: 'b;
-   |     ---------------------------- definition of `B` from trait
-...
-LL |     type B<'a, 'b> = (&'a(), &'b ()) where 'b: 'a;
-   |                      ^^^^^^^^^^^^^^^             - help: try copying this clause from the trait: `, 'a: 'b`
-   |
-note: lifetime parameter instantiated with the lifetime `'a` as defined here
-  --> $DIR/impl_bounds.rs:17:12
-   |
-LL |     type B<'a, 'b> = (&'a(), &'b ()) where 'b: 'a;
-   |            ^^
-note: but lifetime parameter must outlive the lifetime `'b` as defined here
-  --> $DIR/impl_bounds.rs:17:16
-   |
-LL |     type B<'a, 'b> = (&'a(), &'b ()) where 'b: 'a;
-   |                ^^
+LL |       type B<'a, 'b> = (&'a(), &'b ()) where 'b: 'a;
+   |       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ found
 
 error[E0277]: the trait bound `T: Copy` is not satisfied
-  --> $DIR/impl_bounds.rs:20:5
+  --> $DIR/impl_bounds.rs:27:5
    |
 LL |     type C = String where Self: Copy;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `T`
    |
 note: required because of the requirements on the impl of `Copy` for `Fooy<T>`
-  --> $DIR/impl_bounds.rs:11:10
+  --> $DIR/impl_bounds.rs:19:10
    |
 LL | #[derive(Copy, Clone)]
    |          ^^^^
 note: the requirement `Fooy<T>: Copy` appears on the associated impl type `C` but not on the corresponding associated trait type
-  --> $DIR/impl_bounds.rs:7:5
+  --> $DIR/impl_bounds.rs:11:5
    |
-LL | trait Foo {
-   |       --- in this trait
+LL |   trait Foo {
+   |         --- in this trait
 ...
-LL |     type C where Self: Clone;
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^ this trait associated type doesn't have the requirement `Fooy<T>: Copy`
+LL | /     type C
+LL | |     where
+LL | |         Self: Clone;
+   | |____________________^ this trait associated type doesn't have the requirement `Fooy<T>: Copy`
    = note: this error originates in the derive macro `Copy` (in Nightly builds, run with -Z macro-backtrace for more info)
 help: consider restricting type parameter `T`
    |
@@ -62,23 +48,23 @@ LL | impl<T: std::marker::Copy> Foo for Fooy<T> {
    |       +++++++++++++++++++
 
 error[E0277]: the trait bound `T: Copy` is not satisfied
-  --> $DIR/impl_bounds.rs:22:24
+  --> $DIR/impl_bounds.rs:31:15
    |
-LL |     fn d() where Self: Copy {}
-   |                        ^^^^ the trait `Copy` is not implemented for `T`
+LL |         Self: Copy,
+   |               ^^^^ the trait `Copy` is not implemented for `T`
    |
 note: required because of the requirements on the impl of `Copy` for `Fooy<T>`
-  --> $DIR/impl_bounds.rs:11:10
+  --> $DIR/impl_bounds.rs:19:10
    |
 LL | #[derive(Copy, Clone)]
    |          ^^^^
 note: the requirement `Fooy<T>: Copy` appears on the impl method `d` but not on the corresponding trait method
-  --> $DIR/impl_bounds.rs:8:8
+  --> $DIR/impl_bounds.rs:14:8
    |
 LL | trait Foo {
    |       --- in this trait
 ...
-LL |     fn d() where Self: Clone;
+LL |     fn d()
    |        ^ this trait method doesn't have the requirement `Fooy<T>: Copy`
    = note: this error originates in the derive macro `Copy` (in Nightly builds, run with -Z macro-backtrace for more info)
 help: consider restricting type parameter `T`
@@ -86,7 +72,6 @@ help: consider restricting type parameter `T`
 LL | impl<T: std::marker::Copy> Foo for Fooy<T> {
    |       +++++++++++++++++++
 
-error: aborting due to 5 previous errors
+error: aborting due to 4 previous errors
 
-Some errors have detailed explanations: E0277, E0478.
-For more information about an error, try `rustc --explain E0277`.
+For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/generic-associated-types/issue-90014.rs b/src/test/ui/generic-associated-types/issue-90014.rs
index f110b069383d3..3835950d75988 100644
--- a/src/test/ui/generic-associated-types/issue-90014.rs
+++ b/src/test/ui/generic-associated-types/issue-90014.rs
@@ -1,4 +1,5 @@
 // edition:2018
+// check-pass
 
 #![feature(generic_associated_types)]
 #![feature(type_alias_impl_trait)]
@@ -6,13 +7,14 @@
 use std::future::Future;
 
 trait MakeFut {
-    type Fut<'a> where Self: 'a;
+    type Fut<'a>
+    where
+        Self: 'a;
     fn make_fut<'a>(&'a self) -> Self::Fut<'a>;
 }
 
 impl MakeFut for &'_ mut () {
     type Fut<'a> = impl Future<Output = ()>;
-    //~^ ERROR: the type `&mut ()` does not fulfill the required lifetime
 
     fn make_fut<'a>(&'a self) -> Self::Fut<'a> {
         async { () }
diff --git a/src/test/ui/generic-associated-types/issue-90014.stderr b/src/test/ui/generic-associated-types/issue-90014.stderr
deleted file mode 100644
index 51fe3360c7eb2..0000000000000
--- a/src/test/ui/generic-associated-types/issue-90014.stderr
+++ /dev/null
@@ -1,18 +0,0 @@
-error[E0477]: the type `&mut ()` does not fulfill the required lifetime
-  --> $DIR/issue-90014.rs:14:20
-   |
-LL |     type Fut<'a> where Self: 'a;
-   |     ---------------------------- definition of `Fut` from trait
-...
-LL |     type Fut<'a> = impl Future<Output = ()>;
-   |                    ^^^^^^^^^^^^^^^^^^^^^^^^- help: try copying this clause from the trait: `where Self: 'a`
-   |
-note: type must outlive the lifetime `'a` as defined here
-  --> $DIR/issue-90014.rs:14:14
-   |
-LL |     type Fut<'a> = impl Future<Output = ()>;
-   |              ^^
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0477`.
diff --git a/src/test/ui/generic-associated-types/issue-91883.rs b/src/test/ui/generic-associated-types/issue-91883.rs
index 3d4585a44df80..31d08f16867c1 100644
--- a/src/test/ui/generic-associated-types/issue-91883.rs
+++ b/src/test/ui/generic-associated-types/issue-91883.rs
@@ -1,3 +1,7 @@
+// Regression test.
+//
+// check-pass
+
 #![feature(generic_associated_types)]
 
 use std::fmt::Debug;
@@ -29,7 +33,7 @@ pub trait Transaction<'db>: Send + Sync + Debug + Sized {
 impl<'tx> Cursor<'tx> for CursorImpl<'tx> {}
 
 impl<'db> Transaction<'db> for TransactionImpl<'db> {
-    type Cursor<'tx> = CursorImpl<'tx>; //~ ERROR lifetime bound not satisfied
+    type Cursor<'tx> = CursorImpl<'tx>;
 
     fn cursor<'tx>(&'tx self) -> Result<Self::Cursor<'tx>, ()>
     where
diff --git a/src/test/ui/generic-associated-types/issue-91883.stderr b/src/test/ui/generic-associated-types/issue-91883.stderr
deleted file mode 100644
index ed700876e02dd..0000000000000
--- a/src/test/ui/generic-associated-types/issue-91883.stderr
+++ /dev/null
@@ -1,26 +0,0 @@
-error[E0478]: lifetime bound not satisfied
-  --> $DIR/issue-91883.rs:32:24
-   |
-LL | /     type Cursor<'tx>: Cursor<'tx>
-LL | |     where
-LL | |         'db: 'tx,
-LL | |         Self: 'tx;
-   | |__________________- definition of `Cursor` from trait
-...
-LL |       type Cursor<'tx> = CursorImpl<'tx>;
-   |                          ^^^^^^^^^^^^^^^- help: try copying these clauses from the trait: `where 'db: 'tx, Self: 'tx`
-   |
-note: lifetime parameter instantiated with the lifetime `'db` as defined here
-  --> $DIR/issue-91883.rs:31:6
-   |
-LL | impl<'db> Transaction<'db> for TransactionImpl<'db> {
-   |      ^^^
-note: but lifetime parameter must outlive the lifetime `'tx` as defined here
-  --> $DIR/issue-91883.rs:32:17
-   |
-LL |     type Cursor<'tx> = CursorImpl<'tx>;
-   |                 ^^^
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0478`.
diff --git a/src/test/ui/generic-associated-types/issue-92033.rs b/src/test/ui/generic-associated-types/issue-92033.rs
index 1d5f7d5c0099e..7770222b603f6 100644
--- a/src/test/ui/generic-associated-types/issue-92033.rs
+++ b/src/test/ui/generic-associated-types/issue-92033.rs
@@ -1,3 +1,5 @@
+// check-pass
+
 #![feature(generic_associated_types)]
 
 struct Texture;
@@ -20,7 +22,6 @@ trait Swapchain {
 
 impl<'s> Surface for &'s Texture {
     type TextureIter<'a> = std::option::IntoIter<&'a Texture>;
-    //~^ ERROR the type
 
     fn get_texture(&self) -> Self::TextureIter<'_> {
         let option: Option<&Texture> = Some(self);
diff --git a/src/test/ui/generic-associated-types/issue-92033.stderr b/src/test/ui/generic-associated-types/issue-92033.stderr
deleted file mode 100644
index 5b90199b8091f..0000000000000
--- a/src/test/ui/generic-associated-types/issue-92033.stderr
+++ /dev/null
@@ -1,20 +0,0 @@
-error[E0477]: the type `&'s Texture` does not fulfill the required lifetime
-  --> $DIR/issue-92033.rs:22:28
-   |
-LL | /     type TextureIter<'a>: Iterator<Item = &'a Texture>
-LL | |     where
-LL | |         Self: 'a;
-   | |_________________- definition of `TextureIter` from trait
-...
-LL |       type TextureIter<'a> = std::option::IntoIter<&'a Texture>;
-   |                              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^- help: try copying this clause from the trait: `where Self: 'a`
-   |
-note: type must outlive the lifetime `'a` as defined here
-  --> $DIR/issue-92033.rs:22:22
-   |
-LL |     type TextureIter<'a> = std::option::IntoIter<&'a Texture>;
-   |                      ^^
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0477`.
diff --git a/src/test/ui/generic-associated-types/trait-objects.base.stderr b/src/test/ui/generic-associated-types/trait-objects.base.stderr
index 1df76a21bf9b4..066a535868981 100644
--- a/src/test/ui/generic-associated-types/trait-objects.base.stderr
+++ b/src/test/ui/generic-associated-types/trait-objects.base.stderr
@@ -1,15 +1,15 @@
 error[E0038]: the trait `StreamingIterator` cannot be made into an object
-  --> $DIR/trait-objects.rs:14:21
+  --> $DIR/trait-objects.rs:17:21
    |
 LL | fn min_size(x: &mut dyn for<'a> StreamingIterator<Item<'a> = &'a i32>) -> usize {
    |                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `StreamingIterator` cannot be made into an object
    |
 note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
-  --> $DIR/trait-objects.rs:8:10
+  --> $DIR/trait-objects.rs:9:10
    |
 LL | trait StreamingIterator {
    |       ----------------- this trait cannot be made into an object...
-LL |     type Item<'a> where Self: 'a;
+LL |     type Item<'a>
    |          ^^^^ ...because it contains the generic associated type `Item`
    = help: consider moving `Item` to another trait
 
diff --git a/src/test/ui/generic-associated-types/trait-objects.extended.stderr b/src/test/ui/generic-associated-types/trait-objects.extended.stderr
deleted file mode 100644
index 52d48d57859f4..0000000000000
--- a/src/test/ui/generic-associated-types/trait-objects.extended.stderr
+++ /dev/null
@@ -1,17 +0,0 @@
-error[E0521]: borrowed data escapes outside of function
-  --> $DIR/trait-objects.rs:16:5
-   |
-LL | fn min_size(x: &mut dyn for<'a> StreamingIterator<Item<'a> = &'a i32>) -> usize {
-   |             -  - let's call the lifetime of this reference `'1`
-   |             |
-   |             `x` is a reference that is only valid in the function body
-LL |
-LL |     x.size_hint().0
-   |     ^^^^^^^^^^^^^
-   |     |
-   |     `x` escapes the function body here
-   |     argument requires that `'1` must outlive `'static`
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0521`.
diff --git a/src/test/ui/generic-associated-types/trait-objects.rs b/src/test/ui/generic-associated-types/trait-objects.rs
index c1da1e0a326d4..1772e0992bd10 100644
--- a/src/test/ui/generic-associated-types/trait-objects.rs
+++ b/src/test/ui/generic-associated-types/trait-objects.rs
@@ -1,20 +1,22 @@
 // revisions: base extended
+//[extended] check-pass
 
 #![feature(generic_associated_types)]
 #![cfg_attr(extended, feature(generic_associated_types_extended))]
 #![cfg_attr(extended, allow(incomplete_features))]
 
 trait StreamingIterator {
-    type Item<'a> where Self: 'a;
+    type Item<'a>
+    where
+        Self: 'a;
     fn size_hint(&self) -> (usize, Option<usize>);
     // Uncommenting makes `StreamingIterator` not object safe
-//    fn next(&mut self) -> Self::Item<'_>;
+    //    fn next(&mut self) -> Self::Item<'_>;
 }
 
 fn min_size(x: &mut dyn for<'a> StreamingIterator<Item<'a> = &'a i32>) -> usize {
     //[base]~^ the trait `StreamingIterator` cannot be made into an object
     x.size_hint().0
-    //[extended]~^ borrowed data escapes
 }
 
 fn main() {}
diff --git a/src/test/ui/generic-associated-types/unsatified-item-lifetime-bound.rs b/src/test/ui/generic-associated-types/unsatified-item-lifetime-bound.rs
index 8b40dac574a43..bd84f7ccaf6ca 100644
--- a/src/test/ui/generic-associated-types/unsatified-item-lifetime-bound.rs
+++ b/src/test/ui/generic-associated-types/unsatified-item-lifetime-bound.rs
@@ -11,7 +11,6 @@ impl X for () {
 
 struct B<'a, T: for<'r> X<Y<'r> = &'r ()>> {
     f: <T as X>::Y<'a>,
-    //~^ ERROR lifetime bound not satisfied
 }
 
 struct C<'a, T: X> {
diff --git a/src/test/ui/generic-associated-types/unsatified-item-lifetime-bound.stderr b/src/test/ui/generic-associated-types/unsatified-item-lifetime-bound.stderr
index ae52010cc50a2..9e5fc221b9846 100644
--- a/src/test/ui/generic-associated-types/unsatified-item-lifetime-bound.stderr
+++ b/src/test/ui/generic-associated-types/unsatified-item-lifetime-bound.stderr
@@ -7,44 +7,31 @@ LL |     type Y<'a: 'static>;
    = help: you can use the `'static` lifetime directly, in place of `'a`
 
 error[E0478]: lifetime bound not satisfied
-  --> $DIR/unsatified-item-lifetime-bound.rs:13:8
+  --> $DIR/unsatified-item-lifetime-bound.rs:17:8
    |
 LL |     f: <T as X>::Y<'a>,
    |        ^^^^^^^^^^^^^^^
    |
 note: lifetime parameter instantiated with the lifetime `'a` as defined here
-  --> $DIR/unsatified-item-lifetime-bound.rs:12:10
-   |
-LL | struct B<'a, T: for<'r> X<Y<'r> = &'r ()>> {
-   |          ^^
-   = note: but lifetime parameter must outlive the static lifetime
-
-error[E0478]: lifetime bound not satisfied
-  --> $DIR/unsatified-item-lifetime-bound.rs:18:8
-   |
-LL |     f: <T as X>::Y<'a>,
-   |        ^^^^^^^^^^^^^^^
-   |
-note: lifetime parameter instantiated with the lifetime `'a` as defined here
-  --> $DIR/unsatified-item-lifetime-bound.rs:17:10
+  --> $DIR/unsatified-item-lifetime-bound.rs:16:10
    |
 LL | struct C<'a, T: X> {
    |          ^^
    = note: but lifetime parameter must outlive the static lifetime
 
 error[E0478]: lifetime bound not satisfied
-  --> $DIR/unsatified-item-lifetime-bound.rs:23:8
+  --> $DIR/unsatified-item-lifetime-bound.rs:22:8
    |
 LL |     f: <() as X>::Y<'a>,
    |        ^^^^^^^^^^^^^^^^
    |
 note: lifetime parameter instantiated with the lifetime `'a` as defined here
-  --> $DIR/unsatified-item-lifetime-bound.rs:22:10
+  --> $DIR/unsatified-item-lifetime-bound.rs:21:10
    |
 LL | struct D<'a> {
    |          ^^
    = note: but lifetime parameter must outlive the static lifetime
 
-error: aborting due to 3 previous errors; 1 warning emitted
+error: aborting due to 2 previous errors; 1 warning emitted
 
 For more information about this error, try `rustc --explain E0478`.

From 20ebe8c48883d0c1f455e20d38da51ccc03f34e6 Mon Sep 17 00:00:00 2001
From: Niko Matsakis <niko@alum.mit.edu>
Date: Thu, 30 Jun 2022 16:49:49 -0400
Subject: [PATCH 2/2] add soundness, backwards-incompat test cases

`call-forall` shows the expected behavior: the where-clause proves
too much, so we can't prove it.

`backwards-incompat` shows the problem with that: we can construct
types that we ought not to be able to construct.
---
 .../call-back-compat.rs                       | 33 ++++++++++++++
 .../generic-associated-types/call-forall.rs   | 43 +++++++++++++++++++
 .../call-forall.stderr                        | 11 +++++
 3 files changed, 87 insertions(+)
 create mode 100644 src/test/ui/generic-associated-types/call-back-compat.rs
 create mode 100644 src/test/ui/generic-associated-types/call-forall.rs
 create mode 100644 src/test/ui/generic-associated-types/call-forall.stderr

diff --git a/src/test/ui/generic-associated-types/call-back-compat.rs b/src/test/ui/generic-associated-types/call-back-compat.rs
new file mode 100644
index 0000000000000..6705780396c99
--- /dev/null
+++ b/src/test/ui/generic-associated-types/call-back-compat.rs
@@ -0,0 +1,33 @@
+// known-bug
+// check-pass
+
+#![feature(generic_associated_types)]
+
+trait LendingIterator {
+    type Item<'a>
+    where
+        Self: 'a;
+}
+
+impl<'slice> LendingIterator for &'slice [u32] {
+    type Item<'a> = &'a [u32]
+    where
+        Self: 'a;
+}
+
+impl<'slice> LendingIterator for [u32] {
+    type Item<'a> = &'a [u32]
+    where
+        Self: 'a;
+}
+
+fn broke<T: ?Sized>() -> Option<&'static [u32]>
+where
+    for<'a> T: LendingIterator<Item<'a> = &'a [u32]>,
+{
+    None::<<T as LendingIterator>::Item<'static>>
+    // FIXME: Should not compile, but does, because we are trusting the where-clauses
+    // and don't have implied bounds.
+}
+
+fn main() {}
diff --git a/src/test/ui/generic-associated-types/call-forall.rs b/src/test/ui/generic-associated-types/call-forall.rs
new file mode 100644
index 0000000000000..e33abac1c8ad5
--- /dev/null
+++ b/src/test/ui/generic-associated-types/call-forall.rs
@@ -0,0 +1,43 @@
+#![feature(generic_associated_types)]
+
+trait LendingIterator {
+    type Item<'a>
+    where
+        Self: 'a;
+}
+
+impl<'slice> LendingIterator for &'slice [u32] {
+    type Item<'a> = &'a [u32]
+    where
+        Self: 'a;
+}
+
+impl<'slice> LendingIterator for [u32] {
+    type Item<'a> = &'a [u32]
+    where
+        Self: 'a;
+}
+
+fn call_me<T: ?Sized>()
+where
+    for<'a> T: LendingIterator<Item<'a> = &'a [u32]>,
+{
+    if false {
+        call_me::<T>();
+    }
+}
+
+fn ok_i_will1<'test>() {
+    // Gets an error because we cannot prove that, for all 'a, `&'test [u32]: 'a`.
+    //
+    // This is a bug -- what should happen is that there is an implied bound
+    // so that `for<'a>` really means "for all `'a` that make sense", in which case
+    // this ought to be provable.
+    call_me::<&'test [u32]>; //~ ERROR lifetime may not live long enough
+}
+
+fn ok_i_will2() {
+    // OK because, for all 'a, `[u32]: 'a`.
+    call_me::<[u32]>;
+}
+fn main() {}
diff --git a/src/test/ui/generic-associated-types/call-forall.stderr b/src/test/ui/generic-associated-types/call-forall.stderr
new file mode 100644
index 0000000000000..b4ace1bdd503b
--- /dev/null
+++ b/src/test/ui/generic-associated-types/call-forall.stderr
@@ -0,0 +1,11 @@
+error: lifetime may not live long enough
+  --> $DIR/call-forall.rs:36:5
+   |
+LL | fn ok_i_will1<'test>() {
+   |               ----- lifetime `'test` defined here
+...
+LL |     call_me::<&'test [u32]>;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^ requires that `'test` must outlive `'static`
+
+error: aborting due to previous error
+