about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_data_structures/src/lib.rs1
-rw-r--r--compiler/rustc_data_structures/src/vec_map.rs14
-rw-r--r--compiler/rustc_mir/src/borrow_check/type_check/mod.rs140
-rw-r--r--compiler/rustc_trait_selection/src/opaque_types.rs22
-rw-r--r--src/test/ui/associated-type-bounds/assoc-type-eq-with-dyn-atb-fail.rs1
-rw-r--r--src/test/ui/associated-type-bounds/assoc-type-eq-with-dyn-atb-fail.stderr8
-rw-r--r--src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-one.nll.stderr16
-rw-r--r--src/test/ui/impl-trait/auto-trait-leak.rs1
-rw-r--r--src/test/ui/impl-trait/auto-trait-leak.stderr34
-rw-r--r--src/test/ui/impl-trait/issue-86465.rs10
-rw-r--r--src/test/ui/impl-trait/issue-86465.stderr14
-rw-r--r--src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait-async.nll.stderr4
-rw-r--r--src/test/ui/type-alias-impl-trait/generic_type_does_not_live_long_enough.full_tait.nll.stderr2
-rw-r--r--src/test/ui/type-alias-impl-trait/generic_type_does_not_live_long_enough.full_tait.stderr11
-rw-r--r--src/test/ui/type-alias-impl-trait/generic_type_does_not_live_long_enough.min_tait.nll.stderr2
-rw-r--r--src/test/ui/type-alias-impl-trait/generic_type_does_not_live_long_enough.min_tait.stderr11
-rw-r--r--src/test/ui/type-alias-impl-trait/generic_type_does_not_live_long_enough.rs1
-rw-r--r--src/test/ui/type-alias-impl-trait/issue-57611-trait-alias.full_tait.nll.stderr6
-rw-r--r--src/test/ui/type-alias-impl-trait/issue-57611-trait-alias.full_tait.stderr49
-rw-r--r--src/test/ui/type-alias-impl-trait/issue-57611-trait-alias.min_tait.nll.stderr6
-rw-r--r--src/test/ui/type-alias-impl-trait/issue-57611-trait-alias.min_tait.stderr49
-rw-r--r--src/test/ui/type-alias-impl-trait/issue-57611-trait-alias.rs4
-rw-r--r--src/test/ui/type-alias-impl-trait/issue-60371.rs1
-rw-r--r--src/test/ui/type-alias-impl-trait/issue-60371.stderr13
-rw-r--r--src/test/ui/type-alias-impl-trait/issue-74761-2.rs19
-rw-r--r--src/test/ui/type-alias-impl-trait/issue-74761-2.stderr34
-rw-r--r--src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn2.rs2
-rw-r--r--src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn2.stderr14
-rw-r--r--src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn3.rs1
-rw-r--r--src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn3.stderr17
30 files changed, 206 insertions, 301 deletions
diff --git a/compiler/rustc_data_structures/src/lib.rs b/compiler/rustc_data_structures/src/lib.rs
index 16151e9dca5..4467980054f 100644
--- a/compiler/rustc_data_structures/src/lib.rs
+++ b/compiler/rustc_data_structures/src/lib.rs
@@ -24,6 +24,7 @@
 #![feature(new_uninit)]
 #![feature(once_cell)]
 #![feature(maybe_uninit_uninit_array)]
+#![feature(min_type_alias_impl_trait)]
 #![allow(rustc::default_hash_types)]
 #![deny(unaligned_references)]
 
diff --git a/compiler/rustc_data_structures/src/vec_map.rs b/compiler/rustc_data_structures/src/vec_map.rs
index 1786fa340cc..e3fa587985d 100644
--- a/compiler/rustc_data_structures/src/vec_map.rs
+++ b/compiler/rustc_data_structures/src/vec_map.rs
@@ -1,6 +1,6 @@
 use std::borrow::Borrow;
 use std::iter::FromIterator;
-use std::slice::{Iter, IterMut};
+use std::slice::Iter;
 use std::vec::IntoIter;
 
 use crate::stable_hasher::{HashStable, StableHasher};
@@ -67,9 +67,13 @@ where
         self.into_iter()
     }
 
-    pub fn iter_mut(&mut self) -> IterMut<'_, (K, V)> {
+    pub fn iter_mut(&mut self) -> impl Iterator<Item = (&K, &mut V)> {
         self.into_iter()
     }
+
+    pub fn retain(&mut self, f: impl Fn(&(K, V)) -> bool) {
+        self.0.retain(f)
+    }
 }
 
 impl<K, V> Default for VecMap<K, V> {
@@ -108,12 +112,12 @@ impl<'a, K, V> IntoIterator for &'a VecMap<K, V> {
 }
 
 impl<'a, K, V> IntoIterator for &'a mut VecMap<K, V> {
-    type Item = &'a mut (K, V);
-    type IntoIter = IterMut<'a, (K, V)>;
+    type Item = (&'a K, &'a mut V);
+    type IntoIter = impl Iterator<Item = Self::Item>;
 
     #[inline]
     fn into_iter(self) -> Self::IntoIter {
-        self.0.iter_mut()
+        self.0.iter_mut().map(|(k, v)| (&*k, v))
     }
 }
 
diff --git a/compiler/rustc_mir/src/borrow_check/type_check/mod.rs b/compiler/rustc_mir/src/borrow_check/type_check/mod.rs
index aa3ff98f7ff..3fb06cd2f5f 100644
--- a/compiler/rustc_mir/src/borrow_check/type_check/mod.rs
+++ b/compiler/rustc_mir/src/borrow_check/type_check/mod.rs
@@ -26,7 +26,7 @@ use rustc_middle::mir::*;
 use rustc_middle::ty::adjustment::PointerCast;
 use rustc_middle::ty::cast::CastTy;
 use rustc_middle::ty::fold::TypeFoldable;
-use rustc_middle::ty::subst::{GenericArgKind, Subst, SubstsRef, UserSubsts};
+use rustc_middle::ty::subst::{GenericArgKind, SubstsRef, UserSubsts};
 use rustc_middle::ty::{
     self, CanonicalUserTypeAnnotation, CanonicalUserTypeAnnotations, OpaqueTypeKey, RegionVid,
     ToPredicate, Ty, TyCtxt, UserType, UserTypeAnnotationIndex, WithConstness,
@@ -60,7 +60,6 @@ use crate::borrow_check::{
         LivenessValues, PlaceholderIndex, PlaceholderIndices, RegionValueElements,
     },
     region_infer::{ClosureRegionRequirementsExt, TypeTest},
-    renumber,
     type_check::free_region_relations::{CreateResult, UniversalRegionRelations},
     universal_regions::{DefiningTy, UniversalRegions},
     Upvar,
@@ -180,7 +179,54 @@ pub(crate) fn type_check<'mir, 'tcx>(
             liveness::generate(&mut cx, body, elements, flow_inits, move_data, location_table);
 
             translate_outlives_facts(&mut cx);
-            cx.opaque_type_values
+            let mut opaque_type_values = cx.opaque_type_values;
+
+            for (_, revealed_ty) in &mut opaque_type_values {
+                *revealed_ty = infcx.resolve_vars_if_possible(*revealed_ty);
+                if revealed_ty.has_infer_types_or_consts() {
+                    infcx.tcx.sess.delay_span_bug(
+                        body.span,
+                        &format!("could not resolve {:#?}", revealed_ty.kind()),
+                    );
+                    *revealed_ty = infcx.tcx.ty_error();
+                }
+            }
+
+            opaque_type_values.retain(|(opaque_type_key, resolved_ty)| {
+                let concrete_is_opaque = if let ty::Opaque(def_id, _) = resolved_ty.kind() {
+                    *def_id == opaque_type_key.def_id
+                } else {
+                    false
+                };
+
+                if concrete_is_opaque {
+                    // We're using an opaque `impl Trait` type without
+                    // 'revealing' it. For example, code like this:
+                    //
+                    // type Foo = impl Debug;
+                    // fn foo1() -> Foo { ... }
+                    // fn foo2() -> Foo { foo1() }
+                    //
+                    // In `foo2`, we're not revealing the type of `Foo` - we're
+                    // just treating it as the opaque type.
+                    //
+                    // When this occurs, we do *not* want to try to equate
+                    // the concrete type with the underlying defining type
+                    // of the opaque type - this will always fail, since
+                    // the defining type of an opaque type is always
+                    // some other type (e.g. not itself)
+                    // Essentially, none of the normal obligations apply here -
+                    // we're just passing around some unknown opaque type,
+                    // without actually looking at the underlying type it
+                    // gets 'revealed' into
+                    debug!(
+                        "eq_opaque_type_and_type: non-defining use of {:?}",
+                        opaque_type_key.def_id,
+                    );
+                }
+                !concrete_is_opaque
+            });
+            opaque_type_values
         },
     );
 
@@ -1239,14 +1285,10 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
             return Ok(());
         }
 
-        let infcx = self.infcx;
-        let tcx = infcx.tcx;
         let param_env = self.param_env;
         let body = self.body;
         let mir_def_id = body.source.def_id().expect_local();
 
-        // the "concrete opaque types" maps
-        let concrete_opaque_types = &tcx.typeck(mir_def_id).concrete_opaque_types;
         let mut opaque_type_values = VecMap::new();
 
         debug!("eq_opaque_type_and_type: mir_def_id={:?}", mir_def_id);
@@ -1296,88 +1338,8 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
                             .eq(output_ty, revealed_ty)?,
                     );
 
-                    // For each opaque type `Foo<T>` inferred by this value, we want to equate
-                    // the inference variable `?T` with the revealed type that was computed
-                    // earlier by type check.
                     for &(opaque_type_key, opaque_decl) in &opaque_type_map {
-                        let resolved_ty = infcx.resolve_vars_if_possible(opaque_decl.concrete_ty);
-                        let concrete_is_opaque = if let ty::Opaque(def_id, _) = resolved_ty.kind() {
-                            *def_id == opaque_type_key.def_id
-                        } else {
-                            false
-                        };
-
-                        // The revealed type computed by the earlier phase of type check.
-                        // In our example, this would be `(U, u32)`. Note that this references
-                        // the type parameter `U` from the definition of `Foo`.
-                        let concrete_ty = match concrete_opaque_types
-                            .get_by(|(key, _)| key.def_id == opaque_type_key.def_id)
-                        {
-                            None => {
-                                if !concrete_is_opaque {
-                                    tcx.sess.delay_span_bug(
-                                        body.span,
-                                        &format!(
-                                            "Non-defining use of {:?} with revealed type",
-                                            opaque_type_key.def_id,
-                                        ),
-                                    );
-                                }
-                                continue;
-                            }
-                            Some(concrete_ty) => concrete_ty,
-                        };
-                        debug!("concrete_ty = {:?}", concrete_ty);
-
-                        // Apply the substitution, in this case `[U -> T]`, so that the
-                        // concrete type becomes `Foo<(T, u32)>`
-                        let subst_opaque_defn_ty = concrete_ty.subst(tcx, opaque_type_key.substs);
-
-                        // "Renumber" this, meaning that we replace all the regions
-                        // with fresh inference variables. Not relevant to our example.
-                        let renumbered_opaque_defn_ty =
-                            renumber::renumber_regions(infcx, subst_opaque_defn_ty);
-
-                        debug!(
-                            "eq_opaque_type_and_type: concrete_ty={:?}={:?} opaque_defn_ty={:?}",
-                            concrete_ty, resolved_ty, renumbered_opaque_defn_ty,
-                        );
-
-                        if !concrete_is_opaque {
-                            // Equate the instantiated opaque type `opaque_decl.concrete_ty` (`?T`,
-                            // in our example) with the renumbered version that we took from
-                            // the type check results (`Foo<(T, u32)>`).
-                            obligations.add(
-                                infcx
-                                    .at(&ObligationCause::dummy(), param_env)
-                                    .eq(opaque_decl.concrete_ty, renumbered_opaque_defn_ty)?,
-                            );
-                            opaque_type_values.insert(opaque_type_key, renumbered_opaque_defn_ty);
-                        } else {
-                            // We're using an opaque `impl Trait` type without
-                            // 'revealing' it. For example, code like this:
-                            //
-                            // type Foo = impl Debug;
-                            // fn foo1() -> Foo { ... }
-                            // fn foo2() -> Foo { foo1() }
-                            //
-                            // In `foo2`, we're not revealing the type of `Foo` - we're
-                            // just treating it as the opaque type.
-                            //
-                            // When this occurs, we do *not* want to try to equate
-                            // the concrete type with the underlying defining type
-                            // of the opaque type - this will always fail, since
-                            // the defining type of an opaque type is always
-                            // some other type (e.g. not itself)
-                            // Essentially, none of the normal obligations apply here -
-                            // we're just passing around some unknown opaque type,
-                            // without actually looking at the underlying type it
-                            // gets 'revealed' into
-                            debug!(
-                                "eq_opaque_type_and_type: non-defining use of {:?}",
-                                opaque_type_key.def_id,
-                            );
-                        }
+                        opaque_type_values.insert(opaque_type_key, opaque_decl.concrete_ty);
                     }
 
                     debug!("eq_opaque_type_and_type: equated");
@@ -1405,7 +1367,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
                     locations,
                     ConstraintCategory::OpaqueType,
                     CustomTypeOp::new(
-                        |_cx| {
+                        |infcx| {
                             infcx.constrain_opaque_type(
                                 opaque_type_key,
                                 &opaque_decl,
diff --git a/compiler/rustc_trait_selection/src/opaque_types.rs b/compiler/rustc_trait_selection/src/opaque_types.rs
index 39013a317fd..95c81c5c729 100644
--- a/compiler/rustc_trait_selection/src/opaque_types.rs
+++ b/compiler/rustc_trait_selection/src/opaque_types.rs
@@ -83,6 +83,7 @@ pub struct OpaqueTypeDecl<'tcx> {
 }
 
 /// Whether member constraints should be generated for all opaque types
+#[derive(Debug)]
 pub enum GenerateMemberConstraints {
     /// The default, used by typeck
     WhenRequired,
@@ -354,8 +355,6 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
         opaque_types: &OpaqueTypeMap<'tcx>,
         free_region_relations: &FRR,
     ) {
-        debug!("constrain_opaque_types()");
-
         for &(opaque_type_key, opaque_defn) in opaque_types {
             self.constrain_opaque_type(
                 opaque_type_key,
@@ -367,6 +366,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
     }
 
     /// See `constrain_opaque_types` for documentation.
+    #[instrument(level = "debug", skip(self, free_region_relations))]
     fn constrain_opaque_type<FRR: FreeRegionRelations<'tcx>>(
         &self,
         opaque_type_key: OpaqueTypeKey<'tcx>,
@@ -376,15 +376,11 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
     ) {
         let def_id = opaque_type_key.def_id;
 
-        debug!("constrain_opaque_type()");
-        debug!("constrain_opaque_type: def_id={:?}", def_id);
-        debug!("constrain_opaque_type: opaque_defn={:#?}", opaque_defn);
-
         let tcx = self.tcx;
 
         let concrete_ty = self.resolve_vars_if_possible(opaque_defn.concrete_ty);
 
-        debug!("constrain_opaque_type: concrete_ty={:?}", concrete_ty);
+        debug!(?concrete_ty);
 
         let first_own_region = match opaque_defn.origin {
             hir::OpaqueTyOrigin::FnReturn | hir::OpaqueTyOrigin::AsyncFn => {
@@ -397,7 +393,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
                 // type foo::<'p0..'pn>::Foo<'q0..'qm>
                 // fn foo<l0..'ln>() -> foo::<'static..'static>::Foo<'l0..'lm>.
                 //
-                // For these types we onlt iterate over `'l0..lm` below.
+                // For these types we only iterate over `'l0..lm` below.
                 tcx.generics_of(def_id).parent_count
             }
             // These opaque type inherit all lifetime parameters from their
@@ -410,10 +406,10 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
         // If there are required region bounds, we can use them.
         if opaque_defn.has_required_region_bounds {
             let bounds = tcx.explicit_item_bounds(def_id);
-            debug!("constrain_opaque_type: predicates: {:#?}", bounds);
+            debug!("{:#?}", bounds);
             let bounds: Vec<_> =
                 bounds.iter().map(|(bound, _)| bound.subst(tcx, opaque_type_key.substs)).collect();
-            debug!("constrain_opaque_type: bounds={:#?}", bounds);
+            debug!("{:#?}", bounds);
             let opaque_type = tcx.mk_opaque(def_id, opaque_type_key.substs);
 
             let required_region_bounds =
@@ -452,8 +448,8 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
             };
 
             // Compute the least upper bound of it with the other regions.
-            debug!("constrain_opaque_types: least_region={:?}", least_region);
-            debug!("constrain_opaque_types: subst_region={:?}", subst_region);
+            debug!(?least_region);
+            debug!(?subst_region);
             match least_region {
                 None => least_region = Some(subst_region),
                 Some(lr) => {
@@ -484,7 +480,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
         }
 
         let least_region = least_region.unwrap_or(tcx.lifetimes.re_static);
-        debug!("constrain_opaque_types: least_region={:?}", least_region);
+        debug!(?least_region);
 
         if let GenerateMemberConstraints::IfNoStaticBound = mode {
             if least_region != tcx.lifetimes.re_static {
diff --git a/src/test/ui/associated-type-bounds/assoc-type-eq-with-dyn-atb-fail.rs b/src/test/ui/associated-type-bounds/assoc-type-eq-with-dyn-atb-fail.rs
index 73b23da5bcb..7950dd3e99e 100644
--- a/src/test/ui/associated-type-bounds/assoc-type-eq-with-dyn-atb-fail.rs
+++ b/src/test/ui/associated-type-bounds/assoc-type-eq-with-dyn-atb-fail.rs
@@ -29,7 +29,6 @@ impl Bar for AssocNoCopy {
 impl Thing for AssocNoCopy {
     type Out = Box<dyn Bar<Assoc: Copy>>;
     //~^ ERROR the trait bound `String: Copy` is not satisfied
-    //~| ERROR the trait bound `String: Copy` is not satisfied
 
     fn func() -> Self::Out {
         Box::new(AssocNoCopy)
diff --git a/src/test/ui/associated-type-bounds/assoc-type-eq-with-dyn-atb-fail.stderr b/src/test/ui/associated-type-bounds/assoc-type-eq-with-dyn-atb-fail.stderr
index 414d74d4786..0f1d35be0eb 100644
--- a/src/test/ui/associated-type-bounds/assoc-type-eq-with-dyn-atb-fail.stderr
+++ b/src/test/ui/associated-type-bounds/assoc-type-eq-with-dyn-atb-fail.stderr
@@ -4,12 +4,6 @@ error[E0277]: the trait bound `String: Copy` is not satisfied
 LL |     type Out = Box<dyn Bar<Assoc: Copy>>;
    |                            ^^^^^^^^^^^ the trait `Copy` is not implemented for `String`
 
-error[E0277]: the trait bound `String: Copy` is not satisfied
-  --> $DIR/assoc-type-eq-with-dyn-atb-fail.rs:30:28
-   |
-LL |     type Out = Box<dyn Bar<Assoc: Copy>>;
-   |                            ^^^^^^^^^^^ the trait `Copy` is not implemented for `String`
-
-error: aborting due to 2 previous errors
+error: aborting due to previous error
 
 For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-one.nll.stderr b/src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-one.nll.stderr
index eed90772d29..b6841da1f0b 100644
--- a/src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-one.nll.stderr
+++ b/src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-one.nll.stderr
@@ -1,15 +1,11 @@
 error: lifetime may not live long enough
-  --> $DIR/ret-impl-trait-one.rs:10:80
+  --> $DIR/ret-impl-trait-one.rs:10:65
    |
-LL |   async fn async_ret_impl_trait1<'a, 'b>(a: &'a u8, b: &'b u8) -> impl Trait<'a> {
-   |  ________________________________--__--__________________________________________^
-   | |                                |   |
-   | |                                |   lifetime `'b` defined here
-   | |                                lifetime `'a` defined here
-LL | |
-LL | |     (a, b)
-LL | | }
-   | |_^ function was supposed to return data with lifetime `'a` but it is returning data with lifetime `'b`
+LL | async fn async_ret_impl_trait1<'a, 'b>(a: &'a u8, b: &'b u8) -> impl Trait<'a> {
+   |                                --  --                           ^^^^^^^^^^^^^^ opaque type requires that `'b` must outlive `'a`
+   |                                |   |
+   |                                |   lifetime `'b` defined here
+   |                                lifetime `'a` defined here
    |
    = help: consider adding the following bound: `'b: 'a`
 
diff --git a/src/test/ui/impl-trait/auto-trait-leak.rs b/src/test/ui/impl-trait/auto-trait-leak.rs
index 087f4582b21..c2fbbf94fd6 100644
--- a/src/test/ui/impl-trait/auto-trait-leak.rs
+++ b/src/test/ui/impl-trait/auto-trait-leak.rs
@@ -12,7 +12,6 @@ fn main() {
 fn cycle1() -> impl Clone {
     //~^ ERROR cycle detected
     send(cycle2().clone());
-    //~^ ERROR cannot be sent between threads safely
 
     Rc::new(Cell::new(5))
 }
diff --git a/src/test/ui/impl-trait/auto-trait-leak.stderr b/src/test/ui/impl-trait/auto-trait-leak.stderr
index e578c4b4f81..3eb141cc2bb 100644
--- a/src/test/ui/impl-trait/auto-trait-leak.stderr
+++ b/src/test/ui/impl-trait/auto-trait-leak.stderr
@@ -36,37 +36,37 @@ LL | fn cycle1() -> impl Clone {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^
    = note: ...which requires evaluating trait selection obligation `impl std::clone::Clone: std::marker::Send`...
 note: ...which requires computing type of `cycle2::{opaque#0}`...
-  --> $DIR/auto-trait-leak.rs:20:16
+  --> $DIR/auto-trait-leak.rs:19:16
    |
 LL | fn cycle2() -> impl Clone {
    |                ^^^^^^^^^^
 note: ...which requires borrow-checking `cycle2`...
-  --> $DIR/auto-trait-leak.rs:20:1
+  --> $DIR/auto-trait-leak.rs:19:1
    |
 LL | fn cycle2() -> impl Clone {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^
 note: ...which requires processing `cycle2`...
-  --> $DIR/auto-trait-leak.rs:20:1
+  --> $DIR/auto-trait-leak.rs:19:1
    |
 LL | fn cycle2() -> impl Clone {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^
 note: ...which requires processing MIR for `cycle2`...
-  --> $DIR/auto-trait-leak.rs:20:1
+  --> $DIR/auto-trait-leak.rs:19:1
    |
 LL | fn cycle2() -> impl Clone {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^
 note: ...which requires unsafety-checking `cycle2`...
-  --> $DIR/auto-trait-leak.rs:20:1
+  --> $DIR/auto-trait-leak.rs:19:1
    |
 LL | fn cycle2() -> impl Clone {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^
 note: ...which requires building MIR for `cycle2`...
-  --> $DIR/auto-trait-leak.rs:20:1
+  --> $DIR/auto-trait-leak.rs:19:1
    |
 LL | fn cycle2() -> impl Clone {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^
 note: ...which requires type-checking `cycle2`...
-  --> $DIR/auto-trait-leak.rs:20:1
+  --> $DIR/auto-trait-leak.rs:19:1
    |
 LL | fn cycle2() -> impl Clone {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -84,22 +84,6 @@ LL | |     Rc::new(String::from("foo"))
 LL | | }
    | |_^
 
-error[E0277]: `Rc<String>` cannot be sent between threads safely
-  --> $DIR/auto-trait-leak.rs:14:5
-   |
-LL | fn send<T: Send>(_: T) {}
-   |            ---- required by this bound in `send`
-...
-LL |     send(cycle2().clone());
-   |     ^^^^ `Rc<String>` cannot be sent between threads safely
-...
-LL | fn cycle2() -> impl Clone {
-   |                ---------- within this `impl Clone`
-   |
-   = help: within `impl Clone`, the trait `Send` is not implemented for `Rc<String>`
-   = note: required because it appears within the type `impl Clone`
-
-error: aborting due to 2 previous errors
+error: aborting due to previous error
 
-Some errors have detailed explanations: E0277, E0391.
-For more information about an error, try `rustc --explain E0277`.
+For more information about this error, try `rustc --explain E0391`.
diff --git a/src/test/ui/impl-trait/issue-86465.rs b/src/test/ui/impl-trait/issue-86465.rs
new file mode 100644
index 00000000000..23a3748c12c
--- /dev/null
+++ b/src/test/ui/impl-trait/issue-86465.rs
@@ -0,0 +1,10 @@
+#![feature(min_type_alias_impl_trait)]
+
+type X<'a, 'b> = impl std::fmt::Debug;
+
+fn f<'t, 'u>(a: &'t u32, b: &'u u32) -> (X<'t, 'u>, X<'u, 't>) {
+    //~^ ERROR concrete type differs from previous defining opaque type use
+    (a, a)
+}
+
+fn main() {}
diff --git a/src/test/ui/impl-trait/issue-86465.stderr b/src/test/ui/impl-trait/issue-86465.stderr
new file mode 100644
index 00000000000..595b16aa685
--- /dev/null
+++ b/src/test/ui/impl-trait/issue-86465.stderr
@@ -0,0 +1,14 @@
+error: concrete type differs from previous defining opaque type use
+  --> $DIR/issue-86465.rs:5:1
+   |
+LL | fn f<'t, 'u>(a: &'t u32, b: &'u u32) -> (X<'t, 'u>, X<'u, 't>) {
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `&'a u32`, got `&'b u32`
+   |
+note: previous use here
+  --> $DIR/issue-86465.rs:5:1
+   |
+LL | fn f<'t, 'u>(a: &'t u32, b: &'u u32) -> (X<'t, 'u>, X<'u, 't>) {
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait-async.nll.stderr b/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait-async.nll.stderr
index a678731934f..e25c6363515 100644
--- a/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait-async.nll.stderr
+++ b/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait-async.nll.stderr
@@ -1,8 +1,8 @@
 error: lifetime may not live long enough
-  --> $DIR/arbitrary_self_types_pin_lifetime_impl_trait-async.rs:8:48
+  --> $DIR/arbitrary_self_types_pin_lifetime_impl_trait-async.rs:8:37
    |
 LL |     async fn f(self: Pin<&Self>) -> impl Clone { self }
-   |                          -                     ^^^^^^^^ returning this value requires that `'1` must outlive `'static`
+   |                          -          ^^^^^^^^^^ opaque type requires that `'1` must outlive `'static`
    |                          |
    |                          let's call the lifetime of this reference `'1`
    |
diff --git a/src/test/ui/type-alias-impl-trait/generic_type_does_not_live_long_enough.full_tait.nll.stderr b/src/test/ui/type-alias-impl-trait/generic_type_does_not_live_long_enough.full_tait.nll.stderr
index d0f3be336dc..28ac61a6b98 100644
--- a/src/test/ui/type-alias-impl-trait/generic_type_does_not_live_long_enough.full_tait.nll.stderr
+++ b/src/test/ui/type-alias-impl-trait/generic_type_does_not_live_long_enough.full_tait.nll.stderr
@@ -28,7 +28,7 @@ LL | type WrongGeneric<T> = impl 'static;
            found opaque type `impl Sized`
 
 error[E0310]: the parameter type `T` may not live long enough
-  --> $DIR/generic_type_does_not_live_long_enough.rs:17:30
+  --> $DIR/generic_type_does_not_live_long_enough.rs:16:30
    |
 LL | fn wrong_generic<T>(t: T) -> WrongGeneric<T> {
    |                              ^^^^^^^^^^^^^^^
diff --git a/src/test/ui/type-alias-impl-trait/generic_type_does_not_live_long_enough.full_tait.stderr b/src/test/ui/type-alias-impl-trait/generic_type_does_not_live_long_enough.full_tait.stderr
index 6394a1f8e85..90a753b5a6d 100644
--- a/src/test/ui/type-alias-impl-trait/generic_type_does_not_live_long_enough.full_tait.stderr
+++ b/src/test/ui/type-alias-impl-trait/generic_type_does_not_live_long_enough.full_tait.stderr
@@ -36,16 +36,7 @@ LL | type WrongGeneric<T> = impl 'static;
 LL | fn wrong_generic<T>(t: T) -> WrongGeneric<T> {
    |                  - help: consider adding an explicit lifetime bound...: `T: 'static`
 
-error[E0310]: the parameter type `T` may not live long enough
-  --> $DIR/generic_type_does_not_live_long_enough.rs:12:24
-   |
-LL | type WrongGeneric<T> = impl 'static;
-   |                        ^^^^^^^^^^^^
-   |
-   = help: consider adding an explicit lifetime bound `T: 'static`...
-   = note: ...so that the type `T` will meet its required lifetime bounds
-
-error: aborting due to 4 previous errors; 1 warning emitted
+error: aborting due to 3 previous errors; 1 warning emitted
 
 Some errors have detailed explanations: E0308, E0310.
 For more information about an error, try `rustc --explain E0308`.
diff --git a/src/test/ui/type-alias-impl-trait/generic_type_does_not_live_long_enough.min_tait.nll.stderr b/src/test/ui/type-alias-impl-trait/generic_type_does_not_live_long_enough.min_tait.nll.stderr
index 7496d96fa21..b8ca8e46079 100644
--- a/src/test/ui/type-alias-impl-trait/generic_type_does_not_live_long_enough.min_tait.nll.stderr
+++ b/src/test/ui/type-alias-impl-trait/generic_type_does_not_live_long_enough.min_tait.nll.stderr
@@ -19,7 +19,7 @@ LL | type WrongGeneric<T> = impl 'static;
            found opaque type `impl Sized`
 
 error[E0310]: the parameter type `T` may not live long enough
-  --> $DIR/generic_type_does_not_live_long_enough.rs:17:30
+  --> $DIR/generic_type_does_not_live_long_enough.rs:16:30
    |
 LL | fn wrong_generic<T>(t: T) -> WrongGeneric<T> {
    |                              ^^^^^^^^^^^^^^^
diff --git a/src/test/ui/type-alias-impl-trait/generic_type_does_not_live_long_enough.min_tait.stderr b/src/test/ui/type-alias-impl-trait/generic_type_does_not_live_long_enough.min_tait.stderr
index 49ead8b094c..e5028220107 100644
--- a/src/test/ui/type-alias-impl-trait/generic_type_does_not_live_long_enough.min_tait.stderr
+++ b/src/test/ui/type-alias-impl-trait/generic_type_does_not_live_long_enough.min_tait.stderr
@@ -27,16 +27,7 @@ LL | type WrongGeneric<T> = impl 'static;
 LL | fn wrong_generic<T>(t: T) -> WrongGeneric<T> {
    |                  - help: consider adding an explicit lifetime bound...: `T: 'static`
 
-error[E0310]: the parameter type `T` may not live long enough
-  --> $DIR/generic_type_does_not_live_long_enough.rs:12:24
-   |
-LL | type WrongGeneric<T> = impl 'static;
-   |                        ^^^^^^^^^^^^
-   |
-   = help: consider adding an explicit lifetime bound `T: 'static`...
-   = note: ...so that the type `T` will meet its required lifetime bounds
-
-error: aborting due to 4 previous errors
+error: aborting due to 3 previous errors
 
 Some errors have detailed explanations: E0308, E0310.
 For more information about an error, try `rustc --explain E0308`.
diff --git a/src/test/ui/type-alias-impl-trait/generic_type_does_not_live_long_enough.rs b/src/test/ui/type-alias-impl-trait/generic_type_does_not_live_long_enough.rs
index 3dda34ff668..9f647d9e737 100644
--- a/src/test/ui/type-alias-impl-trait/generic_type_does_not_live_long_enough.rs
+++ b/src/test/ui/type-alias-impl-trait/generic_type_does_not_live_long_enough.rs
@@ -11,7 +11,6 @@ fn main() {
 
 type WrongGeneric<T> = impl 'static;
 //~^ ERROR the parameter type `T` may not live long enough
-//~| ERROR the parameter type `T` may not live long enough
 //~| ERROR: at least one trait must be specified
 
 fn wrong_generic<T>(t: T) -> WrongGeneric<T> {
diff --git a/src/test/ui/type-alias-impl-trait/issue-57611-trait-alias.full_tait.nll.stderr b/src/test/ui/type-alias-impl-trait/issue-57611-trait-alias.full_tait.nll.stderr
index 481d66dd811..e2b8b19aeba 100644
--- a/src/test/ui/type-alias-impl-trait/issue-57611-trait-alias.full_tait.nll.stderr
+++ b/src/test/ui/type-alias-impl-trait/issue-57611-trait-alias.full_tait.nll.stderr
@@ -8,13 +8,13 @@ LL | #![cfg_attr(full_tait, feature(type_alias_impl_trait))]
    = note: see issue #63063 <https://github.com/rust-lang/rust/issues/63063> for more information
 
 error: higher-ranked subtype error
-  --> $DIR/issue-57611-trait-alias.rs:28:9
+  --> $DIR/issue-57611-trait-alias.rs:24:9
    |
 LL |         |x| x
    |         ^^^^^
 
 error: higher-ranked subtype error
-  --> $DIR/issue-57611-trait-alias.rs:28:9
+  --> $DIR/issue-57611-trait-alias.rs:24:9
    |
 LL |         |x| x
    |         ^^^^^
@@ -28,7 +28,7 @@ LL |     type Bar = impl Baz<Self, Self>;
    = note: expected type `for<'r> Fn<(&'r X,)>`
               found type `Fn<(&'static X,)>`
 note: this closure does not fulfill the lifetime requirements
-  --> $DIR/issue-57611-trait-alias.rs:28:9
+  --> $DIR/issue-57611-trait-alias.rs:24:9
    |
 LL |         |x| x
    |         ^^^^^
diff --git a/src/test/ui/type-alias-impl-trait/issue-57611-trait-alias.full_tait.stderr b/src/test/ui/type-alias-impl-trait/issue-57611-trait-alias.full_tait.stderr
index d90f328708a..61e8da91bba 100644
--- a/src/test/ui/type-alias-impl-trait/issue-57611-trait-alias.full_tait.stderr
+++ b/src/test/ui/type-alias-impl-trait/issue-57611-trait-alias.full_tait.stderr
@@ -16,52 +16,5 @@ LL |     type Bar = impl Baz<Self, Self>;
    = note: closure with signature `fn(&'2 X) -> &X` must implement `FnOnce<(&'1 X,)>`, for any lifetime `'1`...
    = note: ...but it actually implements `FnOnce<(&'2 X,)>`, for some specific lifetime `'2`
 
-error[E0308]: mismatched types
-  --> $DIR/issue-57611-trait-alias.rs:20:16
-   |
-LL |     type Bar = impl Baz<Self, Self>;
-   |                ^^^^^^^^^^^^^^^^^^^^ one type is more general than the other
-   |
-   = note: expected type `for<'r> Fn<(&'r X,)>`
-              found type `Fn<(&'<empty> X,)>`
-note: this closure does not fulfill the lifetime requirements
-  --> $DIR/issue-57611-trait-alias.rs:28:9
-   |
-LL |         |x| x
-   |         ^^^^^
-
-error: implementation of `FnOnce` is not general enough
-  --> $DIR/issue-57611-trait-alias.rs:20:16
-   |
-LL |     type Bar = impl Baz<Self, Self>;
-   |                ^^^^^^^^^^^^^^^^^^^^ implementation of `FnOnce` is not general enough
-   |
-   = note: closure with signature `fn(&'2 X) -> &'2 X` must implement `FnOnce<(&'1 X,)>`, for any lifetime `'1`...
-   = note: ...but it actually implements `FnOnce<(&'2 X,)>`, for some specific lifetime `'2`
-
-error[E0308]: mismatched types
-  --> $DIR/issue-57611-trait-alias.rs:20:16
-   |
-LL |     type Bar = impl Baz<Self, Self>;
-   |                ^^^^^^^^^^^^^^^^^^^^ one type is more general than the other
-   |
-   = note: expected type `for<'r> Fn<(&'r X,)>`
-              found type `Fn<(&'<empty> X,)>`
-note: this closure does not fulfill the lifetime requirements
-  --> $DIR/issue-57611-trait-alias.rs:28:9
-   |
-LL |         |x| x
-   |         ^^^^^
-
-error: implementation of `FnOnce` is not general enough
-  --> $DIR/issue-57611-trait-alias.rs:20:16
-   |
-LL |     type Bar = impl Baz<Self, Self>;
-   |                ^^^^^^^^^^^^^^^^^^^^ implementation of `FnOnce` is not general enough
-   |
-   = note: closure with signature `fn(&'2 X) -> &'2 X` must implement `FnOnce<(&'1 X,)>`, for any lifetime `'1`...
-   = note: ...but it actually implements `FnOnce<(&'2 X,)>`, for some specific lifetime `'2`
-
-error: aborting due to 5 previous errors; 1 warning emitted
+error: aborting due to previous error; 1 warning emitted
 
-For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/type-alias-impl-trait/issue-57611-trait-alias.min_tait.nll.stderr b/src/test/ui/type-alias-impl-trait/issue-57611-trait-alias.min_tait.nll.stderr
index 0343a769564..3a4d1d90c03 100644
--- a/src/test/ui/type-alias-impl-trait/issue-57611-trait-alias.min_tait.nll.stderr
+++ b/src/test/ui/type-alias-impl-trait/issue-57611-trait-alias.min_tait.nll.stderr
@@ -1,11 +1,11 @@
 error: higher-ranked subtype error
-  --> $DIR/issue-57611-trait-alias.rs:28:9
+  --> $DIR/issue-57611-trait-alias.rs:24:9
    |
 LL |         |x| x
    |         ^^^^^
 
 error: higher-ranked subtype error
-  --> $DIR/issue-57611-trait-alias.rs:28:9
+  --> $DIR/issue-57611-trait-alias.rs:24:9
    |
 LL |         |x| x
    |         ^^^^^
@@ -19,7 +19,7 @@ LL |     type Bar = impl Baz<Self, Self>;
    = note: expected type `for<'r> Fn<(&'r X,)>`
               found type `Fn<(&'static X,)>`
 note: this closure does not fulfill the lifetime requirements
-  --> $DIR/issue-57611-trait-alias.rs:28:9
+  --> $DIR/issue-57611-trait-alias.rs:24:9
    |
 LL |         |x| x
    |         ^^^^^
diff --git a/src/test/ui/type-alias-impl-trait/issue-57611-trait-alias.min_tait.stderr b/src/test/ui/type-alias-impl-trait/issue-57611-trait-alias.min_tait.stderr
index d019f40757e..f65e91e52c7 100644
--- a/src/test/ui/type-alias-impl-trait/issue-57611-trait-alias.min_tait.stderr
+++ b/src/test/ui/type-alias-impl-trait/issue-57611-trait-alias.min_tait.stderr
@@ -7,52 +7,5 @@ LL |     type Bar = impl Baz<Self, Self>;
    = note: closure with signature `fn(&'2 X) -> &X` must implement `FnOnce<(&'1 X,)>`, for any lifetime `'1`...
    = note: ...but it actually implements `FnOnce<(&'2 X,)>`, for some specific lifetime `'2`
 
-error[E0308]: mismatched types
-  --> $DIR/issue-57611-trait-alias.rs:20:16
-   |
-LL |     type Bar = impl Baz<Self, Self>;
-   |                ^^^^^^^^^^^^^^^^^^^^ one type is more general than the other
-   |
-   = note: expected type `for<'r> Fn<(&'r X,)>`
-              found type `Fn<(&'<empty> X,)>`
-note: this closure does not fulfill the lifetime requirements
-  --> $DIR/issue-57611-trait-alias.rs:28:9
-   |
-LL |         |x| x
-   |         ^^^^^
-
-error: implementation of `FnOnce` is not general enough
-  --> $DIR/issue-57611-trait-alias.rs:20:16
-   |
-LL |     type Bar = impl Baz<Self, Self>;
-   |                ^^^^^^^^^^^^^^^^^^^^ implementation of `FnOnce` is not general enough
-   |
-   = note: closure with signature `fn(&'2 X) -> &'2 X` must implement `FnOnce<(&'1 X,)>`, for any lifetime `'1`...
-   = note: ...but it actually implements `FnOnce<(&'2 X,)>`, for some specific lifetime `'2`
-
-error[E0308]: mismatched types
-  --> $DIR/issue-57611-trait-alias.rs:20:16
-   |
-LL |     type Bar = impl Baz<Self, Self>;
-   |                ^^^^^^^^^^^^^^^^^^^^ one type is more general than the other
-   |
-   = note: expected type `for<'r> Fn<(&'r X,)>`
-              found type `Fn<(&'<empty> X,)>`
-note: this closure does not fulfill the lifetime requirements
-  --> $DIR/issue-57611-trait-alias.rs:28:9
-   |
-LL |         |x| x
-   |         ^^^^^
-
-error: implementation of `FnOnce` is not general enough
-  --> $DIR/issue-57611-trait-alias.rs:20:16
-   |
-LL |     type Bar = impl Baz<Self, Self>;
-   |                ^^^^^^^^^^^^^^^^^^^^ implementation of `FnOnce` is not general enough
-   |
-   = note: closure with signature `fn(&'2 X) -> &'2 X` must implement `FnOnce<(&'1 X,)>`, for any lifetime `'1`...
-   = note: ...but it actually implements `FnOnce<(&'2 X,)>`, for some specific lifetime `'2`
-
-error: aborting due to 5 previous errors
+error: aborting due to previous error
 
-For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/type-alias-impl-trait/issue-57611-trait-alias.rs b/src/test/ui/type-alias-impl-trait/issue-57611-trait-alias.rs
index ccc727e0bf0..508ecdd88a4 100644
--- a/src/test/ui/type-alias-impl-trait/issue-57611-trait-alias.rs
+++ b/src/test/ui/type-alias-impl-trait/issue-57611-trait-alias.rs
@@ -19,10 +19,6 @@ struct X;
 impl Foo for X {
     type Bar = impl Baz<Self, Self>;
     //~^ ERROR implementation of `FnOnce` is not general enough
-    //~| ERROR implementation of `FnOnce` is not general enough
-    //~| ERROR implementation of `FnOnce` is not general enough
-    //~| ERROR mismatched types
-    //~| ERROR mismatched types
 
     fn bar(&self) -> Self::Bar {
         |x| x
diff --git a/src/test/ui/type-alias-impl-trait/issue-60371.rs b/src/test/ui/type-alias-impl-trait/issue-60371.rs
index b7c8a58a656..cee5e5a01cc 100644
--- a/src/test/ui/type-alias-impl-trait/issue-60371.rs
+++ b/src/test/ui/type-alias-impl-trait/issue-60371.rs
@@ -9,7 +9,6 @@ trait Bug {
 impl Bug for &() {
     type Item = impl Bug; //~ ERROR `impl Trait` in type aliases is unstable
     //~^ ERROR the trait bound `(): Bug` is not satisfied
-    //~^^ ERROR the trait bound `(): Bug` is not satisfied
 
     const FUN: fn() -> Self::Item = || ();
     //~^ ERROR type alias impl trait is not permitted here
diff --git a/src/test/ui/type-alias-impl-trait/issue-60371.stderr b/src/test/ui/type-alias-impl-trait/issue-60371.stderr
index 4906ea9c2e2..a9df74689df 100644
--- a/src/test/ui/type-alias-impl-trait/issue-60371.stderr
+++ b/src/test/ui/type-alias-impl-trait/issue-60371.stderr
@@ -8,7 +8,7 @@ LL |     type Item = impl Bug;
    = help: add `#![feature(min_type_alias_impl_trait)]` to the crate attributes to enable
 
 error[E0658]: type alias impl trait is not permitted here
-  --> $DIR/issue-60371.rs:14:40
+  --> $DIR/issue-60371.rs:13:40
    |
 LL |     const FUN: fn() -> Self::Item = || ();
    |                                        ^
@@ -25,16 +25,7 @@ LL |     type Item = impl Bug;
    = help: the following implementations were found:
              <&() as Bug>
 
-error[E0277]: the trait bound `(): Bug` is not satisfied
-  --> $DIR/issue-60371.rs:10:17
-   |
-LL |     type Item = impl Bug;
-   |                 ^^^^^^^^ the trait `Bug` is not implemented for `()`
-   |
-   = help: the following implementations were found:
-             <&() as Bug>
-
-error: aborting due to 4 previous errors
+error: aborting due to 3 previous errors
 
 Some errors have detailed explanations: E0277, E0658.
 For more information about an error, try `rustc --explain E0277`.
diff --git a/src/test/ui/type-alias-impl-trait/issue-74761-2.rs b/src/test/ui/type-alias-impl-trait/issue-74761-2.rs
new file mode 100644
index 00000000000..4b0f2afee54
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/issue-74761-2.rs
@@ -0,0 +1,19 @@
+#![feature(member_constraints)]
+#![feature(type_alias_impl_trait)]
+//~^ WARN incomplete
+
+pub trait A {
+    type B;
+    fn f(&self) -> Self::B;
+}
+impl<'a, 'b> A for () {
+    //~^ ERROR the lifetime parameter `'a` is not constrained
+    //~| ERROR the lifetime parameter `'b` is not constrained
+    type B = impl core::fmt::Debug;
+    //~^ ERROR is unstable
+
+
+    fn f(&self) -> Self::B {}
+}
+
+fn main() {}
diff --git a/src/test/ui/type-alias-impl-trait/issue-74761-2.stderr b/src/test/ui/type-alias-impl-trait/issue-74761-2.stderr
new file mode 100644
index 00000000000..4506a6e23d5
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/issue-74761-2.stderr
@@ -0,0 +1,34 @@
+error[E0658]: `impl Trait` in type aliases is unstable
+  --> $DIR/issue-74761-2.rs:12:14
+   |
+LL |     type B = impl core::fmt::Debug;
+   |              ^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #63063 <https://github.com/rust-lang/rust/issues/63063> for more information
+   = help: add `#![feature(min_type_alias_impl_trait)]` to the crate attributes to enable
+
+warning: the feature `type_alias_impl_trait` is incomplete and may not be safe to use and/or cause compiler crashes
+  --> $DIR/issue-74761-2.rs:2:12
+   |
+LL | #![feature(type_alias_impl_trait)]
+   |            ^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: `#[warn(incomplete_features)]` on by default
+   = note: see issue #63063 <https://github.com/rust-lang/rust/issues/63063> for more information
+
+error[E0207]: the lifetime parameter `'a` is not constrained by the impl trait, self type, or predicates
+  --> $DIR/issue-74761-2.rs:9:6
+   |
+LL | impl<'a, 'b> A for () {
+   |      ^^ unconstrained lifetime parameter
+
+error[E0207]: the lifetime parameter `'b` is not constrained by the impl trait, self type, or predicates
+  --> $DIR/issue-74761-2.rs:9:10
+   |
+LL | impl<'a, 'b> A for () {
+   |          ^^ unconstrained lifetime parameter
+
+error: aborting due to 3 previous errors; 1 warning emitted
+
+Some errors have detailed explanations: E0207, E0658.
+For more information about an error, try `rustc --explain E0207`.
diff --git a/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn2.rs b/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn2.rs
index 38aa18fe40e..11756017ad8 100644
--- a/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn2.rs
+++ b/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn2.rs
@@ -5,9 +5,9 @@
 #![feature(min_type_alias_impl_trait)]
 
 type X<A: ToString + Clone, B: ToString + Clone> = impl ToString;
-//~^ ERROR could not find defining uses
 
 fn f<A: ToString + Clone, B: ToString + Clone>(a: A, b: B) -> (X<A, B>, X<B, A>) {
+    //~^ ERROR concrete type differs from previous defining opaque type
     (a.clone(), a)
 }
 
diff --git a/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn2.stderr b/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn2.stderr
index c00973c0761..52b0462de98 100644
--- a/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn2.stderr
+++ b/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn2.stderr
@@ -1,8 +1,14 @@
-error: could not find defining uses
-  --> $DIR/multiple-def-uses-in-one-fn2.rs:7:52
+error: concrete type differs from previous defining opaque type use
+  --> $DIR/multiple-def-uses-in-one-fn2.rs:9:1
    |
-LL | type X<A: ToString + Clone, B: ToString + Clone> = impl ToString;
-   |                                                    ^^^^^^^^^^^^^
+LL | fn f<A: ToString + Clone, B: ToString + Clone>(a: A, b: B) -> (X<A, B>, X<B, A>) {
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `A`, got `B`
+   |
+note: previous use here
+  --> $DIR/multiple-def-uses-in-one-fn2.rs:9:1
+   |
+LL | fn f<A: ToString + Clone, B: ToString + Clone>(a: A, b: B) -> (X<A, B>, X<B, A>) {
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn3.rs b/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn3.rs
index 17e90005811..5f25365666c 100644
--- a/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn3.rs
+++ b/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn3.rs
@@ -11,6 +11,7 @@ fn f<A: ToString + Clone, B: ToString + Clone>(a: A, b: B) -> (X<A, B>, X<B, A>)
 }
 
 fn g<A: ToString + Clone, B: ToString + Clone>(a: A, b: B) -> (X<A, B>, X<A, B>) {
+    //~^ ERROR concrete type differs from previous defining opaque type
     (a, b)
     //~^ ERROR mismatched types
 }
diff --git a/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn3.stderr b/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn3.stderr
index bbe709dccab..3d943b77af5 100644
--- a/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn3.stderr
+++ b/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn3.stderr
@@ -1,10 +1,11 @@
 error[E0308]: mismatched types
-  --> $DIR/multiple-def-uses-in-one-fn3.rs:14:9
+  --> $DIR/multiple-def-uses-in-one-fn3.rs:15:9
    |
 LL | fn g<A: ToString + Clone, B: ToString + Clone>(a: A, b: B) -> (X<A, B>, X<A, B>) {
    |      -                    - found type parameter
    |      |
    |      expected type parameter
+LL |
 LL |     (a, b)
    |         ^ expected type parameter `A`, found type parameter `B`
    |
@@ -13,6 +14,18 @@ LL |     (a, b)
    = note: a type parameter was expected, but a different one was found; you might be missing a type parameter or trait bound
    = note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters
 
-error: aborting due to previous error
+error: concrete type differs from previous defining opaque type use
+  --> $DIR/multiple-def-uses-in-one-fn3.rs:13:1
+   |
+LL | fn g<A: ToString + Clone, B: ToString + Clone>(a: A, b: B) -> (X<A, B>, X<A, B>) {
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `A`, got `[type error]`
+   |
+note: previous use here
+  --> $DIR/multiple-def-uses-in-one-fn3.rs:9:1
+   |
+LL | fn f<A: ToString + Clone, B: ToString + Clone>(a: A, b: B) -> (X<A, B>, X<B, A>) {
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 2 previous errors
 
 For more information about this error, try `rustc --explain E0308`.