about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_data_structures/src/vec_map.rs4
-rw-r--r--compiler/rustc_mir/src/borrow_check/type_check/mod.rs149
-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/impl-trait/auto-trait-leak.rs1
-rw-r--r--src/test/ui/impl-trait/auto-trait-leak.stderr34
-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.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.stderr49
-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
20 files changed, 162 insertions, 261 deletions
diff --git a/compiler/rustc_data_structures/src/vec_map.rs b/compiler/rustc_data_structures/src/vec_map.rs
index 96e33184658..e3fa587985d 100644
--- a/compiler/rustc_data_structures/src/vec_map.rs
+++ b/compiler/rustc_data_structures/src/vec_map.rs
@@ -70,6 +70,10 @@ where
     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> {
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..de327047a87 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,66 @@ 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 {
+                // FIXME(oli-obk): Instead of looping, implement a visitor like
+                // FullTypeResolver. We can't use FullTypeResolver here, as that will
+                // resolve lifetimes lexically, which it can't because we didn't do old
+                // borrowck stuff. We want to use MIR borrowck information instead.
+
+                while revealed_ty.has_infer_types_or_consts() {
+                    let prev = *revealed_ty;
+                    trace!(prev=?prev.kind());
+                    let type_resolved = infcx.shallow_resolve(prev);
+                    trace!(type_resolved=?type_resolved.kind());
+                    if prev == type_resolved {
+                        infcx.tcx.sess.delay_span_bug(
+                            body.span,
+                            &format!("could not resolve {:#?}", type_resolved.kind()),
+                        );
+                        *revealed_ty = infcx.tcx.ty_error();
+                        break;
+                    }
+                    *revealed_ty = type_resolved;
+                }
+            }
+
+            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
         },
     );
 
@@ -1240,13 +1298,10 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
         }
 
         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 +1351,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");
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/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/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.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.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.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`.