summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_borrowck/src/region_infer/opaque_types.rs14
-rw-r--r--compiler/rustc_borrowck/src/type_check/mod.rs8
-rw-r--r--compiler/rustc_hir_analysis/src/collect/type_of/opaque.rs111
-rw-r--r--compiler/rustc_hir_typeck/src/writeback.rs12
-rw-r--r--compiler/rustc_middle/src/ty/typeck_results.rs6
-rw-r--r--tests/ui/chalkify/bugs/async.stderr13
-rw-r--r--tests/ui/dyn-star/param-env-infer.next.stderr35
-rw-r--r--tests/ui/impl-trait/auto-trait-leak.stderr70
-rw-r--r--tests/ui/impl-trait/multiple-defining-usages-in-body.rs2
-rw-r--r--tests/ui/impl-trait/multiple-defining-usages-in-body.stderr10
-rw-r--r--tests/ui/traits/new-solver/dont-remap-tait-substs.rs19
-rw-r--r--tests/ui/type-alias-impl-trait/cross_inference.rs2
-rw-r--r--tests/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn.rs1
-rw-r--r--tests/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn.stderr11
14 files changed, 127 insertions, 187 deletions
diff --git a/compiler/rustc_borrowck/src/region_infer/opaque_types.rs b/compiler/rustc_borrowck/src/region_infer/opaque_types.rs
index 33f07c1d8fc..13e346b86bc 100644
--- a/compiler/rustc_borrowck/src/region_infer/opaque_types.rs
+++ b/compiler/rustc_borrowck/src/region_infer/opaque_types.rs
@@ -279,8 +279,18 @@ impl<'tcx> InferCtxtExt<'tcx> for InferCtxt<'tcx> {
         // HACK This bubble is required for this tests to pass:
         // nested-return-type2-tait2.rs
         // nested-return-type2-tait3.rs
-        let infcx =
-            self.tcx.infer_ctxt().with_opaque_type_inference(DefiningAnchor::Bubble).build();
+        // FIXME(-Ztrait-solver=next): We probably should use `DefiningAnchor::Error`
+        // and prepopulate this `InferCtxt` with known opaque values, rather than
+        // using the `Bind` anchor here. For now it's fine.
+        let infcx = self
+            .tcx
+            .infer_ctxt()
+            .with_opaque_type_inference(if self.tcx.trait_solver_next() {
+                DefiningAnchor::Bind(def_id)
+            } else {
+                DefiningAnchor::Bubble
+            })
+            .build();
         let ocx = ObligationCtxt::new(&infcx);
         // Require the hidden type to be well-formed with only the generics of the opaque type.
         // Defining use functions may have more bounds than the opaque type, which is ok, as long as the
diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs
index 3b896f6540c..908ff3da5ca 100644
--- a/compiler/rustc_borrowck/src/type_check/mod.rs
+++ b/compiler/rustc_borrowck/src/type_check/mod.rs
@@ -188,9 +188,6 @@ pub(crate) fn type_check<'mir, 'tcx>(
 
     // FIXME(-Ztrait-solver=next): A bit dubious that we're only registering
     // predefined opaques in the typeck root.
-    // FIXME(-Ztrait-solver=next): This is also totally wrong for TAITs, since
-    // the HIR typeck map defining usages back to their definition params,
-    // they won't actually match up with the usages in this body...
     if infcx.tcx.trait_solver_next() && !infcx.tcx.is_typeck_child(body.source.def_id()) {
         checker.register_predefined_opaques_in_new_solver();
     }
@@ -1042,10 +1039,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
             .typeck(self.body.source.def_id().expect_local())
             .concrete_opaque_types
             .iter()
-            .map(|(&def_id, &hidden_ty)| {
-                let substs = ty::InternalSubsts::identity_for_item(self.infcx.tcx, def_id);
-                (ty::OpaqueTypeKey { def_id, substs }, hidden_ty)
-            })
+            .map(|(k, v)| (*k, *v))
             .collect();
 
         let renumbered_opaques = self.infcx.tcx.fold_regions(opaques, |_, _| {
diff --git a/compiler/rustc_hir_analysis/src/collect/type_of/opaque.rs b/compiler/rustc_hir_analysis/src/collect/type_of/opaque.rs
index f7c5b44678f..4d96a7ff4c3 100644
--- a/compiler/rustc_hir_analysis/src/collect/type_of/opaque.rs
+++ b/compiler/rustc_hir_analysis/src/collect/type_of/opaque.rs
@@ -1,3 +1,4 @@
+use rustc_errors::StashKey;
 use rustc_hir::def_id::LocalDefId;
 use rustc_hir::intravisit::{self, Visitor};
 use rustc_hir::{self as hir, Expr, ImplItem, Item, Node, TraitItem};
@@ -59,7 +60,20 @@ pub(super) fn find_opaque_ty_constraints_for_tait(tcx: TyCtxt<'_>, def_id: Local
         }
     }
 
-    let Some(hidden) = locator.found else {
+    if let Some(hidden) = locator.found {
+        // Only check against typeck if we didn't already error
+        if !hidden.ty.references_error() {
+            for concrete_type in locator.typeck_types {
+                if concrete_type.ty != tcx.erase_regions(hidden.ty)
+                    && !(concrete_type, hidden).references_error()
+                {
+                    hidden.report_mismatch(&concrete_type, def_id, tcx).emit();
+                }
+            }
+        }
+
+        hidden.ty
+    } else {
         let reported = tcx.sess.emit_err(UnconstrainedOpaqueType {
             span: tcx.def_span(def_id),
             name: tcx.item_name(tcx.local_parent(def_id).to_def_id()),
@@ -70,21 +84,8 @@ pub(super) fn find_opaque_ty_constraints_for_tait(tcx: TyCtxt<'_>, def_id: Local
                 _ => "item",
             },
         });
-        return tcx.ty_error(reported);
-    };
-
-    // Only check against typeck if we didn't already error
-    if !hidden.ty.references_error() {
-        for concrete_type in locator.typeck_types {
-            if concrete_type.ty != tcx.erase_regions(hidden.ty)
-                && !(concrete_type, hidden).references_error()
-            {
-                hidden.report_mismatch(&concrete_type, def_id, tcx).emit();
-            }
-        }
+        tcx.ty_error(reported)
     }
-
-    hidden.ty
 }
 
 struct TaitConstraintLocator<'tcx> {
@@ -130,13 +131,28 @@ impl TaitConstraintLocator<'_> {
             self.found = Some(ty::OpaqueHiddenType { span: DUMMY_SP, ty: self.tcx.ty_error(guar) });
             return;
         }
-        let Some(&typeck_hidden_ty) = tables.concrete_opaque_types.get(&self.def_id) else {
+
+        let mut constrained = false;
+        for (&opaque_type_key, &hidden_type) in &tables.concrete_opaque_types {
+            if opaque_type_key.def_id != self.def_id {
+                continue;
+            }
+            constrained = true;
+            let concrete_type =
+                self.tcx.erase_regions(hidden_type.remap_generic_params_to_declaration_params(
+                    opaque_type_key,
+                    self.tcx,
+                    true,
+                ));
+            if self.typeck_types.iter().all(|prev| prev.ty != concrete_type.ty) {
+                self.typeck_types.push(concrete_type);
+            }
+        }
+
+        if !constrained {
             debug!("no constraints in typeck results");
             return;
         };
-        if self.typeck_types.iter().all(|prev| prev.ty != typeck_hidden_ty.ty) {
-            self.typeck_types.push(typeck_hidden_ty);
-        }
 
         // Use borrowck to get the type with unerased regions.
         let concrete_opaque_types = &self.tcx.mir_borrowck(item_def_id).concrete_opaque_types;
@@ -190,17 +206,45 @@ impl<'tcx> intravisit::Visitor<'tcx> for TaitConstraintLocator<'tcx> {
     }
 }
 
-pub(super) fn find_opaque_ty_constraints_for_rpit(
-    tcx: TyCtxt<'_>,
+pub(super) fn find_opaque_ty_constraints_for_rpit<'tcx>(
+    tcx: TyCtxt<'tcx>,
     def_id: LocalDefId,
     owner_def_id: LocalDefId,
 ) -> Ty<'_> {
-    let concrete = tcx.mir_borrowck(owner_def_id).concrete_opaque_types.get(&def_id).copied();
+    let tables = tcx.typeck(owner_def_id);
+
+    // Check that all of the opaques we inferred during HIR are compatible.
+    // FIXME: We explicitly don't check that the types inferred during HIR
+    // typeck are compatible with the one that we infer during borrowck,
+    // because that one actually sometimes has consts evaluated eagerly so
+    // using strict type equality will fail.
+    let mut hir_opaque_ty: Option<ty::OpaqueHiddenType<'tcx>> = None;
+    if tables.tainted_by_errors.is_none() {
+        for (&opaque_type_key, &hidden_type) in &tables.concrete_opaque_types {
+            if opaque_type_key.def_id != def_id {
+                continue;
+            }
+            let concrete_type = tcx.erase_regions(
+                hidden_type.remap_generic_params_to_declaration_params(opaque_type_key, tcx, true),
+            );
+            if let Some(prev) = &mut hir_opaque_ty {
+                if concrete_type.ty != prev.ty && !(concrete_type, prev.ty).references_error() {
+                    prev.report_mismatch(&concrete_type, def_id, tcx).stash(
+                        tcx.def_span(opaque_type_key.def_id),
+                        StashKey::OpaqueHiddenTypeMismatch,
+                    );
+                }
+            } else {
+                hir_opaque_ty = Some(concrete_type);
+            }
+        }
+    }
 
-    if let Some(concrete) = concrete {
+    let mir_opaque_ty = tcx.mir_borrowck(owner_def_id).concrete_opaque_types.get(&def_id).copied();
+    if let Some(mir_opaque_ty) = mir_opaque_ty {
         let scope = tcx.hir().local_def_id_to_hir_id(owner_def_id);
         debug!(?scope);
-        let mut locator = RpitConstraintChecker { def_id, tcx, found: concrete };
+        let mut locator = RpitConstraintChecker { def_id, tcx, found: mir_opaque_ty };
 
         match tcx.hir().get(scope) {
             Node::Item(it) => intravisit::walk_item(&mut locator, it),
@@ -208,17 +252,18 @@ pub(super) fn find_opaque_ty_constraints_for_rpit(
             Node::TraitItem(it) => intravisit::walk_trait_item(&mut locator, it),
             other => bug!("{:?} is not a valid scope for an opaque type item", other),
         }
-    }
 
-    concrete.map(|concrete| concrete.ty).unwrap_or_else(|| {
-        let table = tcx.typeck(owner_def_id);
-        if let Some(guar) = table.tainted_by_errors {
-            // Some error in the
-            // owner fn prevented us from populating
+        mir_opaque_ty.ty
+    } else {
+        if let Some(guar) = tables.tainted_by_errors {
+            // Some error in the owner fn prevented us from populating
             // the `concrete_opaque_types` table.
             tcx.ty_error(guar)
         } else {
-            table.concrete_opaque_types.get(&def_id).map(|ty| ty.ty).unwrap_or_else(|| {
+            // Fall back to the RPIT we inferred during HIR typeck
+            if let Some(hir_opaque_ty) = hir_opaque_ty {
+                hir_opaque_ty.ty
+            } else {
                 // We failed to resolve the opaque type or it
                 // resolves to itself. We interpret this as the
                 // no values of the hidden type ever being constructed,
@@ -226,9 +271,9 @@ pub(super) fn find_opaque_ty_constraints_for_rpit(
                 // For backwards compatibility reasons, we fall back to
                 // `()` until we the diverging default is changed.
                 tcx.mk_diverging_default()
-            })
+            }
         }
-    })
+    }
 }
 
 struct RpitConstraintChecker<'tcx> {
diff --git a/compiler/rustc_hir_typeck/src/writeback.rs b/compiler/rustc_hir_typeck/src/writeback.rs
index 0f21fc1e662..964acc4eb77 100644
--- a/compiler/rustc_hir_typeck/src/writeback.rs
+++ b/compiler/rustc_hir_typeck/src/writeback.rs
@@ -583,19 +583,15 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> {
                 continue;
             }
 
-            let hidden_type =
-                self.tcx().erase_regions(hidden_type.remap_generic_params_to_declaration_params(
-                    opaque_type_key,
-                    self.tcx(),
-                    true,
-                ));
-
+            // Here we only detect impl trait definition conflicts when they
+            // are equal modulo regions.
             if let Some(last_opaque_ty) = self
                 .typeck_results
                 .concrete_opaque_types
-                .insert(opaque_type_key.def_id, hidden_type)
+                .insert(opaque_type_key, hidden_type)
                 && last_opaque_ty.ty != hidden_type.ty
             {
+                assert!(!self.tcx().trait_solver_next());
                 hidden_type
                     .report_mismatch(&last_opaque_ty, opaque_type_key.def_id, self.tcx())
                     .stash(
diff --git a/compiler/rustc_middle/src/ty/typeck_results.rs b/compiler/rustc_middle/src/ty/typeck_results.rs
index e04dbbff9a7..8cbffa14850 100644
--- a/compiler/rustc_middle/src/ty/typeck_results.rs
+++ b/compiler/rustc_middle/src/ty/typeck_results.rs
@@ -155,11 +155,7 @@ pub struct TypeckResults<'tcx> {
     /// We also store the type here, so that the compiler can use it as a hint
     /// for figuring out hidden types, even if they are only set in dead code
     /// (which doesn't show up in MIR).
-    ///
-    /// These types are mapped back to the opaque's identity substitutions
-    /// (with erased regions), which is why we don't associated substs with any
-    /// of these usages.
-    pub concrete_opaque_types: FxIndexMap<LocalDefId, ty::OpaqueHiddenType<'tcx>>,
+    pub concrete_opaque_types: FxIndexMap<ty::OpaqueTypeKey<'tcx>, ty::OpaqueHiddenType<'tcx>>,
 
     /// Tracks the minimum captures required for a closure;
     /// see `MinCaptureInformationMap` for more details.
diff --git a/tests/ui/chalkify/bugs/async.stderr b/tests/ui/chalkify/bugs/async.stderr
index 7e64e67f24c..e6d46b02706 100644
--- a/tests/ui/chalkify/bugs/async.stderr
+++ b/tests/ui/chalkify/bugs/async.stderr
@@ -13,16 +13,9 @@ error: internal compiler error: projection clauses should be implied from elsewh
 LL | async fn foo(x: u32) -> u32 {
    |                         ^^^query stack during panic:
 #0 [typeck] type-checking `foo`
-#1 [thir_body] building THIR for `foo`
-#2 [check_match] match-checking `foo`
-#3 [mir_built] building MIR for `foo`
-#4 [unsafety_check_result] unsafety-checking `foo`
-#5 [mir_const] preparing `foo` for borrow checking
-#6 [mir_promoted] promoting constants in MIR for `foo`
-#7 [mir_borrowck] borrow-checking `foo`
-#8 [type_of] computing type of `foo::{opaque#0}`
-#9 [check_mod_item_types] checking item types in top-level module
-#10 [analysis] running analysis passes on this crate
+#1 [type_of] computing type of `foo::{opaque#0}`
+#2 [check_mod_item_types] checking item types in top-level module
+#3 [analysis] running analysis passes on this crate
 end of query stack
 error: aborting due to 2 previous errors
 
diff --git a/tests/ui/dyn-star/param-env-infer.next.stderr b/tests/ui/dyn-star/param-env-infer.next.stderr
index 64d76bb04b1..408abecc30d 100644
--- a/tests/ui/dyn-star/param-env-infer.next.stderr
+++ b/tests/ui/dyn-star/param-env-infer.next.stderr
@@ -13,41 +13,6 @@ error[E0391]: cycle detected when computing type of `make_dyn_star::{opaque#0}`
 LL | fn make_dyn_star<'a, T: PointerLike + Debug + 'a>(t: T) -> impl PointerLike + Debug + 'a {
    |                                                            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-note: ...which requires borrow-checking `make_dyn_star`...
-  --> $DIR/param-env-infer.rs:11:1
-   |
-LL | fn make_dyn_star<'a, T: PointerLike + Debug + 'a>(t: T) -> impl PointerLike + Debug + 'a {
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-note: ...which requires promoting constants in MIR for `make_dyn_star`...
-  --> $DIR/param-env-infer.rs:11:1
-   |
-LL | fn make_dyn_star<'a, T: PointerLike + Debug + 'a>(t: T) -> impl PointerLike + Debug + 'a {
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-note: ...which requires preparing `make_dyn_star` for borrow checking...
-  --> $DIR/param-env-infer.rs:11:1
-   |
-LL | fn make_dyn_star<'a, T: PointerLike + Debug + 'a>(t: T) -> impl PointerLike + Debug + 'a {
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-note: ...which requires unsafety-checking `make_dyn_star`...
-  --> $DIR/param-env-infer.rs:11:1
-   |
-LL | fn make_dyn_star<'a, T: PointerLike + Debug + 'a>(t: T) -> impl PointerLike + Debug + 'a {
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-note: ...which requires building MIR for `make_dyn_star`...
-  --> $DIR/param-env-infer.rs:11:1
-   |
-LL | fn make_dyn_star<'a, T: PointerLike + Debug + 'a>(t: T) -> impl PointerLike + Debug + 'a {
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-note: ...which requires match-checking `make_dyn_star`...
-  --> $DIR/param-env-infer.rs:11:1
-   |
-LL | fn make_dyn_star<'a, T: PointerLike + Debug + 'a>(t: T) -> impl PointerLike + Debug + 'a {
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-note: ...which requires building THIR for `make_dyn_star`...
-  --> $DIR/param-env-infer.rs:11:1
-   |
-LL | fn make_dyn_star<'a, T: PointerLike + Debug + 'a>(t: T) -> impl PointerLike + Debug + 'a {
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 note: ...which requires type-checking `make_dyn_star`...
   --> $DIR/param-env-infer.rs:11:1
    |
diff --git a/tests/ui/impl-trait/auto-trait-leak.stderr b/tests/ui/impl-trait/auto-trait-leak.stderr
index aa4ee75bb75..c0c4cd5013e 100644
--- a/tests/ui/impl-trait/auto-trait-leak.stderr
+++ b/tests/ui/impl-trait/auto-trait-leak.stderr
@@ -4,41 +4,6 @@ error[E0391]: cycle detected when computing type of `cycle1::{opaque#0}`
 LL | fn cycle1() -> impl Clone {
    |                ^^^^^^^^^^
    |
-note: ...which requires borrow-checking `cycle1`...
-  --> $DIR/auto-trait-leak.rs:12:1
-   |
-LL | fn cycle1() -> impl Clone {
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^
-note: ...which requires promoting constants in MIR for `cycle1`...
-  --> $DIR/auto-trait-leak.rs:12:1
-   |
-LL | fn cycle1() -> impl Clone {
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^
-note: ...which requires preparing `cycle1` for borrow checking...
-  --> $DIR/auto-trait-leak.rs:12:1
-   |
-LL | fn cycle1() -> impl Clone {
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^
-note: ...which requires unsafety-checking `cycle1`...
-  --> $DIR/auto-trait-leak.rs:12:1
-   |
-LL | fn cycle1() -> impl Clone {
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^
-note: ...which requires building MIR for `cycle1`...
-  --> $DIR/auto-trait-leak.rs:12:1
-   |
-LL | fn cycle1() -> impl Clone {
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^
-note: ...which requires match-checking `cycle1`...
-  --> $DIR/auto-trait-leak.rs:12:1
-   |
-LL | fn cycle1() -> impl Clone {
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^
-note: ...which requires building THIR for `cycle1`...
-  --> $DIR/auto-trait-leak.rs:12:1
-   |
-LL | fn cycle1() -> impl Clone {
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^
 note: ...which requires type-checking `cycle1`...
   --> $DIR/auto-trait-leak.rs:14:5
    |
@@ -50,41 +15,6 @@ note: ...which requires computing type of `cycle2::{opaque#0}`...
    |
 LL | fn cycle2() -> impl Clone {
    |                ^^^^^^^^^^
-note: ...which requires borrow-checking `cycle2`...
-  --> $DIR/auto-trait-leak.rs:19:1
-   |
-LL | fn cycle2() -> impl Clone {
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^
-note: ...which requires promoting constants in MIR for `cycle2`...
-  --> $DIR/auto-trait-leak.rs:19:1
-   |
-LL | fn cycle2() -> impl Clone {
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^
-note: ...which requires preparing `cycle2` for borrow checking...
-  --> $DIR/auto-trait-leak.rs:19:1
-   |
-LL | fn cycle2() -> impl Clone {
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^
-note: ...which requires unsafety-checking `cycle2`...
-  --> $DIR/auto-trait-leak.rs:19:1
-   |
-LL | fn cycle2() -> impl Clone {
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^
-note: ...which requires building MIR for `cycle2`...
-  --> $DIR/auto-trait-leak.rs:19:1
-   |
-LL | fn cycle2() -> impl Clone {
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^
-note: ...which requires match-checking `cycle2`...
-  --> $DIR/auto-trait-leak.rs:19:1
-   |
-LL | fn cycle2() -> impl Clone {
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^
-note: ...which requires building THIR for `cycle2`...
-  --> $DIR/auto-trait-leak.rs:19:1
-   |
-LL | fn cycle2() -> impl Clone {
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^
 note: ...which requires type-checking `cycle2`...
   --> $DIR/auto-trait-leak.rs:20:5
    |
diff --git a/tests/ui/impl-trait/multiple-defining-usages-in-body.rs b/tests/ui/impl-trait/multiple-defining-usages-in-body.rs
index c3a6f09f86d..86661153a0d 100644
--- a/tests/ui/impl-trait/multiple-defining-usages-in-body.rs
+++ b/tests/ui/impl-trait/multiple-defining-usages-in-body.rs
@@ -4,9 +4,9 @@ impl Trait for () {}
 fn foo<T: Trait, U: Trait>() -> impl Trait {
     //~^ WARN function cannot return without recursing [unconditional_recursion]
     let a: T = foo::<T, U>();
-    //~^ ERROR concrete type differs from previous defining opaque type use
     loop {}
     let _: T = foo::<U, T>();
+    //~^ ERROR concrete type differs from previous defining opaque type use
 }
 
 fn main() {}
diff --git a/tests/ui/impl-trait/multiple-defining-usages-in-body.stderr b/tests/ui/impl-trait/multiple-defining-usages-in-body.stderr
index 06991749bfa..f3c090408b4 100644
--- a/tests/ui/impl-trait/multiple-defining-usages-in-body.stderr
+++ b/tests/ui/impl-trait/multiple-defining-usages-in-body.stderr
@@ -11,15 +11,15 @@ LL |     let a: T = foo::<T, U>();
    = note: `#[warn(unconditional_recursion)]` on by default
 
 error: concrete type differs from previous defining opaque type use
-  --> $DIR/multiple-defining-usages-in-body.rs:6:16
+  --> $DIR/multiple-defining-usages-in-body.rs:8:16
    |
-LL |     let a: T = foo::<T, U>();
-   |                ^^^^^^^^^^^^^ expected `U`, got `T`
+LL |     let _: T = foo::<U, T>();
+   |                ^^^^^^^^^^^^^ expected `T`, got `U`
    |
 note: previous use here
-  --> $DIR/multiple-defining-usages-in-body.rs:9:16
+  --> $DIR/multiple-defining-usages-in-body.rs:6:16
    |
-LL |     let _: T = foo::<U, T>();
+LL |     let a: T = foo::<T, U>();
    |                ^^^^^^^^^^^^^
 
 error: aborting due to previous error; 1 warning emitted
diff --git a/tests/ui/traits/new-solver/dont-remap-tait-substs.rs b/tests/ui/traits/new-solver/dont-remap-tait-substs.rs
new file mode 100644
index 00000000000..028222f4e6d
--- /dev/null
+++ b/tests/ui/traits/new-solver/dont-remap-tait-substs.rs
@@ -0,0 +1,19 @@
+// compile-flags: -Ztrait-solver=next
+// check-pass
+
+// Makes sure we don't prepopulate the MIR typeck of `define`
+// with `Foo<T, U> = T`, but instead, `Foo<B, A> = B`, so that
+// the param-env predicates actually apply.
+
+#![feature(type_alias_impl_trait)]
+
+type Foo<T: Send, U> = impl NeedsSend<T>;
+
+trait NeedsSend<T> {}
+impl<T: Send> NeedsSend<T> for T {}
+
+fn define<A, B: Send>(a: A, b: B) {
+    let y: Option<Foo<B, A>> = Some(b);
+}
+
+fn main() {}
diff --git a/tests/ui/type-alias-impl-trait/cross_inference.rs b/tests/ui/type-alias-impl-trait/cross_inference.rs
index dafaf40a69d..07f3dd1997b 100644
--- a/tests/ui/type-alias-impl-trait/cross_inference.rs
+++ b/tests/ui/type-alias-impl-trait/cross_inference.rs
@@ -1,3 +1,5 @@
+// revisions: current next
+//[next] compile-flags: -Ztrait-solver=next
 // check-pass
 
 #![feature(type_alias_impl_trait)]
diff --git a/tests/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn.rs b/tests/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn.rs
index 9ae2c34b935..da845e86147 100644
--- a/tests/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn.rs
+++ b/tests/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn.rs
@@ -8,7 +8,6 @@ type X<A, B> = impl Into<&'static A>;
 
 fn f<A, B: 'static>(a: &'static A, b: B) -> (X<A, B>, X<B, A>) {
     //~^ ERROR the trait bound `&'static B: From<&A>` is not satisfied
-    //~| ERROR concrete type differs from previous defining opaque type use
     (a, a)
 }
 
diff --git a/tests/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn.stderr b/tests/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn.stderr
index 0d24d42ba62..66a6b0bbf74 100644
--- a/tests/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn.stderr
+++ b/tests/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn.stderr
@@ -10,15 +10,6 @@ help: consider introducing a `where` clause, but there might be an alternative b
 LL | fn f<A, B: 'static>(a: &'static A, b: B) -> (X<A, B>, X<B, A>) where &'static B: From<&A> {
    |                                                                ++++++++++++++++++++++++++
 
-error: concrete type differs from previous defining opaque type use
-  --> $DIR/multiple-def-uses-in-one-fn.rs:9:45
-   |
-LL | fn f<A, B: 'static>(a: &'static A, b: B) -> (X<A, B>, X<B, A>) {
-   |                                             ^^^^^^^^^^^^^^^^^^
-   |                                             |
-   |                                             expected `&B`, got `&A`
-   |                                             this expression supplies two conflicting concrete types for the same opaque type
-
-error: aborting due to 2 previous errors
+error: aborting due to previous error
 
 For more information about this error, try `rustc --explain E0277`.