about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMatthias Krüger <matthias.krueger@famsik.de>2024-10-16 19:18:32 +0200
committerGitHub <noreply@github.com>2024-10-16 19:18:32 +0200
commitaac91f75e3b6cb0602ce5fdc80ccd1367699cc11 (patch)
treed086e343c01bcf4f9e6bb8258a5873eb0c0c9e2c
parent2560453256dae97676859cff822a5a0c0c5317cc (diff)
parentf956dc2e779ae5ca14c882998d308609648025e9 (diff)
downloadrust-aac91f75e3b6cb0602ce5fdc80ccd1367699cc11.tar.gz
rust-aac91f75e3b6cb0602ce5fdc80ccd1367699cc11.zip
Rollup merge of #131699 - compiler-errors:better-errors-for-projections, r=lcnr
Try to improve error messages involving aliases in the solver

1. Treat aliases as rigid only if it may not be defined and it's well formed (i.e. for projections, its trait goal is satisfied).
2. Record goals that are related to alias normalization under a new `GoalKind`, so we can look into them in the `BestObligation` visitor.
3. Try to deduplicate errors due to self types of goals that are un-normalizable aliases.

r? lcnr
-rw-r--r--compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs20
-rw-r--r--compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs2
-rw-r--r--compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs63
-rw-r--r--compiler/rustc_trait_selection/src/solve/fulfill.rs25
-rw-r--r--compiler/rustc_trait_selection/src/solve/inspect/analyse.rs6
-rw-r--r--compiler/rustc_trait_selection/src/solve/select.rs3
-rw-r--r--compiler/rustc_type_ir/src/solve/inspect.rs2
-rw-r--r--compiler/rustc_type_ir/src/solve/mod.rs4
-rw-r--r--tests/ui/for/issue-20605.next.stderr11
-rw-r--r--tests/ui/for/issue-20605.rs7
-rw-r--r--tests/ui/generic-associated-types/ambig-hr-projection-issue-93340.next.stderr16
-rw-r--r--tests/ui/generic-associated-types/ambig-hr-projection-issue-93340.old.stderr2
-rw-r--r--tests/ui/generic-associated-types/ambig-hr-projection-issue-93340.rs1
-rw-r--r--tests/ui/higher-ranked/structually-relate-aliases.rs3
-rw-r--r--tests/ui/higher-ranked/structually-relate-aliases.stderr32
-rw-r--r--tests/ui/impl-trait/in-trait/alias-bounds-when-not-wf.rs4
-rw-r--r--tests/ui/impl-trait/in-trait/alias-bounds-when-not-wf.stderr36
-rw-r--r--tests/ui/impl-trait/method-resolution4.next.stderr17
-rw-r--r--tests/ui/impl-trait/method-resolution4.rs1
-rw-r--r--tests/ui/impl-trait/recursive-coroutine-boxed.next.stderr29
-rw-r--r--tests/ui/impl-trait/recursive-coroutine-boxed.rs3
-rw-r--r--tests/ui/impl-trait/unsized_coercion.next.stderr39
-rw-r--r--tests/ui/impl-trait/unsized_coercion.rs3
-rw-r--r--tests/ui/impl-trait/unsized_coercion3.next.stderr43
-rw-r--r--tests/ui/impl-trait/unsized_coercion3.old.stderr2
-rw-r--r--tests/ui/impl-trait/unsized_coercion3.rs4
-rw-r--r--tests/ui/traits/negative-bounds/opaque-type-unsatisfied-bound.rs13
-rw-r--r--tests/ui/traits/negative-bounds/opaque-type-unsatisfied-bound.stderr58
-rw-r--r--tests/ui/traits/negative-bounds/opaque-type-unsatisfied-fn-bound.rs4
-rw-r--r--tests/ui/traits/negative-bounds/opaque-type-unsatisfied-fn-bound.stderr20
-rw-r--r--tests/ui/traits/next-solver/issue-118950-root-region.rs4
-rw-r--r--tests/ui/traits/next-solver/issue-118950-root-region.stderr22
-rw-r--r--tests/ui/traits/next-solver/normalize/normalize-region-obligations.rs2
-rw-r--r--tests/ui/typeck/issue-103899.rs10
34 files changed, 324 insertions, 187 deletions
diff --git a/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs b/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs
index cebeef76bfc..c9c0d6391fc 100644
--- a/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs
+++ b/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs
@@ -6,6 +6,7 @@ use derive_where::derive_where;
 use rustc_type_ir::fold::TypeFoldable;
 use rustc_type_ir::inherent::*;
 use rustc_type_ir::lang_items::TraitSolverLangItem;
+use rustc_type_ir::solve::inspect;
 use rustc_type_ir::visit::TypeVisitableExt as _;
 use rustc_type_ir::{self as ty, Interner, Upcast as _, elaborate};
 use tracing::{debug, instrument};
@@ -288,6 +289,25 @@ where
         let Ok(normalized_self_ty) =
             self.structurally_normalize_ty(goal.param_env, goal.predicate.self_ty())
         else {
+            // FIXME: We register a fake candidate when normalization fails so that
+            // we can point at the reason for *why*. I'm tempted to say that this
+            // is the wrong way to do this, though.
+            let result =
+                self.probe(|&result| inspect::ProbeKind::RigidAlias { result }).enter(|this| {
+                    let normalized_ty = this.next_ty_infer();
+                    let alias_relate_goal = Goal::new(
+                        this.cx(),
+                        goal.param_env,
+                        ty::PredicateKind::AliasRelate(
+                            goal.predicate.self_ty().into(),
+                            normalized_ty.into(),
+                            ty::AliasRelationDirection::Equate,
+                        ),
+                    );
+                    this.add_goal(GoalSource::AliasWellFormed, alias_relate_goal);
+                    this.evaluate_added_goals_and_make_canonical_response(Certainty::AMBIGUOUS)
+                });
+            assert_eq!(result, Err(NoSolution));
             return vec![];
         };
 
diff --git a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs
index daacc669118..0f8b796d602 100644
--- a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs
+++ b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs
@@ -983,7 +983,7 @@ where
             hidden_ty,
             &mut goals,
         );
-        self.add_goals(GoalSource::Misc, goals);
+        self.add_goals(GoalSource::AliasWellFormed, goals);
     }
 
     // Do something for each opaque/hidden pair defined with `def_id` in the
diff --git a/compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs b/compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs
index 005b293621a..4d8b193ee49 100644
--- a/compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs
+++ b/compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs
@@ -15,7 +15,7 @@ use crate::solve::assembly::{self, Candidate};
 use crate::solve::inspect::ProbeKind;
 use crate::solve::{
     BuiltinImplSource, CandidateSource, Certainty, EvalCtxt, Goal, GoalSource, MaybeCause,
-    NoSolution, QueryResult,
+    NoSolution, QueryResult, Reveal,
 };
 
 impl<D, I> EvalCtxt<'_, D>
@@ -37,10 +37,61 @@ where
         match normalize_result {
             Ok(res) => Ok(res),
             Err(NoSolution) => {
-                let Goal { param_env, predicate: NormalizesTo { alias, term } } = goal;
-                self.relate_rigid_alias_non_alias(param_env, alias, ty::Invariant, term)?;
-                self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
+                self.probe(|&result| ProbeKind::RigidAlias { result }).enter(|this| {
+                    let Goal { param_env, predicate: NormalizesTo { alias, term } } = goal;
+                    this.add_rigid_constraints(param_env, alias)?;
+                    this.relate_rigid_alias_non_alias(param_env, alias, ty::Invariant, term)?;
+                    this.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
+                })
+            }
+        }
+    }
+
+    /// Register any obligations that are used to validate that an alias should be
+    /// treated as rigid.
+    ///
+    /// An alias may be considered rigid if it fails normalization, but we also don't
+    /// want to consider aliases that are not well-formed to be rigid simply because
+    /// they fail normalization.
+    ///
+    /// For example, some `<T as Trait>::Assoc` where `T: Trait` does not hold, or an
+    /// opaque type whose hidden type doesn't actually satisfy the opaque item bounds.
+    fn add_rigid_constraints(
+        &mut self,
+        param_env: I::ParamEnv,
+        rigid_alias: ty::AliasTerm<I>,
+    ) -> Result<(), NoSolution> {
+        let cx = self.cx();
+        match rigid_alias.kind(cx) {
+            // Projections are rigid only if their trait ref holds,
+            // and the GAT where-clauses hold.
+            ty::AliasTermKind::ProjectionTy | ty::AliasTermKind::ProjectionConst => {
+                let trait_ref = rigid_alias.trait_ref(cx);
+                self.add_goal(GoalSource::AliasWellFormed, Goal::new(cx, param_env, trait_ref));
+                Ok(())
+            }
+            ty::AliasTermKind::OpaqueTy => {
+                match param_env.reveal() {
+                    // In user-facing mode, paques are only rigid if we may not define it.
+                    Reveal::UserFacing => {
+                        if rigid_alias
+                            .def_id
+                            .as_local()
+                            .is_some_and(|def_id| self.can_define_opaque_ty(def_id))
+                        {
+                            Err(NoSolution)
+                        } else {
+                            Ok(())
+                        }
+                    }
+                    // Opaques are never rigid in reveal-all mode.
+                    Reveal::All => Err(NoSolution),
+                }
             }
+            // FIXME(generic_const_exprs): we would need to support generic consts here
+            ty::AliasTermKind::UnevaluatedConst => Err(NoSolution),
+            // Inherent and weak types are never rigid. This type must not be well-formed.
+            ty::AliasTermKind::WeakTy | ty::AliasTermKind::InherentTy => Err(NoSolution),
         }
     }
 
@@ -124,6 +175,7 @@ where
                     ecx.instantiate_normalizes_to_term(goal, assumption_projection_pred.term);
 
                     // Add GAT where clauses from the trait's definition
+                    // FIXME: We don't need these, since these are the type's own WF obligations.
                     ecx.add_goals(
                         GoalSource::Misc,
                         cx.own_predicates_of(goal.predicate.def_id())
@@ -179,7 +231,8 @@ where
                 .map(|pred| goal.with(cx, pred));
             ecx.add_goals(GoalSource::ImplWhereBound, where_clause_bounds);
 
-            // Add GAT where clauses from the trait's definition
+            // Add GAT where clauses from the trait's definition.
+            // FIXME: We don't need these, since these are the type's own WF obligations.
             ecx.add_goals(
                 GoalSource::Misc,
                 cx.own_predicates_of(goal.predicate.def_id())
diff --git a/compiler/rustc_trait_selection/src/solve/fulfill.rs b/compiler/rustc_trait_selection/src/solve/fulfill.rs
index d9dc772eca9..53e5420d27a 100644
--- a/compiler/rustc_trait_selection/src/solve/fulfill.rs
+++ b/compiler/rustc_trait_selection/src/solve/fulfill.rs
@@ -14,7 +14,7 @@ use rustc_middle::bug;
 use rustc_middle::ty::error::{ExpectedFound, TypeError};
 use rustc_middle::ty::{self, TyCtxt};
 use rustc_next_trait_solver::solve::{GenerateProofTree, HasChanged, SolverDelegateEvalExt as _};
-use tracing::instrument;
+use tracing::{instrument, trace};
 
 use super::Certainty;
 use super::delegate::SolverDelegate;
@@ -401,6 +401,7 @@ impl<'tcx> BestObligation<'tcx> {
                                         nested_goal.source(),
                                         GoalSource::ImplWhereBound
                                             | GoalSource::InstantiateHigherRanked
+                                            | GoalSource::AliasWellFormed
                                     ) && match self.consider_ambiguities {
                                         true => {
                                             matches!(
@@ -415,6 +416,13 @@ impl<'tcx> BestObligation<'tcx> {
                         })
                     });
                 }
+
+                // Prefer a non-rigid candidate if there is one.
+                if candidates.len() > 1 {
+                    candidates.retain(|candidate| {
+                        !matches!(candidate.kind(), inspect::ProbeKind::RigidAlias { .. })
+                    });
+                }
             }
         }
 
@@ -429,8 +437,11 @@ impl<'tcx> ProofTreeVisitor<'tcx> for BestObligation<'tcx> {
         self.obligation.cause.span
     }
 
+    #[instrument(level = "trace", skip(self, goal), fields(goal = ?goal.goal()))]
     fn visit_goal(&mut self, goal: &inspect::InspectGoal<'_, 'tcx>) -> Self::Result {
         let candidates = self.non_trivial_candidates(goal);
+        trace!(candidates = ?candidates.iter().map(|c| c.kind()).collect::<Vec<_>>());
+
         let [candidate] = candidates.as_slice() else {
             return ControlFlow::Break(self.obligation.clone());
         };
@@ -464,17 +475,13 @@ impl<'tcx> ProofTreeVisitor<'tcx> for BestObligation<'tcx> {
                     polarity: ty::PredicatePolarity::Positive,
                 }))
             }
-            ty::PredicateKind::Clause(
-                ty::ClauseKind::WellFormed(_) | ty::ClauseKind::Projection(..),
-            )
-            | ty::PredicateKind::AliasRelate(..) => ChildMode::PassThrough,
-            _ => {
-                return ControlFlow::Break(self.obligation.clone());
-            }
+            _ => ChildMode::PassThrough,
         };
 
         let mut impl_where_bound_count = 0;
         for nested_goal in candidate.instantiate_nested_goals(self.span()) {
+            trace!(nested_goal = ?(nested_goal.goal(), nested_goal.source(), nested_goal.result()));
+
             let make_obligation = |cause| Obligation {
                 cause,
                 param_env: nested_goal.goal().param_env,
@@ -501,7 +508,7 @@ impl<'tcx> ProofTreeVisitor<'tcx> for BestObligation<'tcx> {
                 (_, GoalSource::InstantiateHigherRanked) => {
                     obligation = self.obligation.clone();
                 }
-                (ChildMode::PassThrough, _) => {
+                (ChildMode::PassThrough, _) | (_, GoalSource::AliasWellFormed) => {
                     obligation = make_obligation(self.obligation.cause.clone());
                 }
             }
diff --git a/compiler/rustc_trait_selection/src/solve/inspect/analyse.rs b/compiler/rustc_trait_selection/src/solve/inspect/analyse.rs
index 254620e0b59..4975a9ce0c7 100644
--- a/compiler/rustc_trait_selection/src/solve/inspect/analyse.rs
+++ b/compiler/rustc_trait_selection/src/solve/inspect/analyse.rs
@@ -292,7 +292,8 @@ impl<'a, 'tcx> InspectGoal<'a, 'tcx> {
                         | inspect::ProbeKind::Root { .. }
                         | inspect::ProbeKind::TryNormalizeNonRigid { .. }
                         | inspect::ProbeKind::TraitCandidate { .. }
-                        | inspect::ProbeKind::OpaqueTypeStorageLookup { .. } => {
+                        | inspect::ProbeKind::OpaqueTypeStorageLookup { .. }
+                        | inspect::ProbeKind::RigidAlias { .. } => {
                             // Nested probes have to prove goals added in their parent
                             // but do not leak them, so we truncate the added goals
                             // afterwards.
@@ -316,7 +317,8 @@ impl<'a, 'tcx> InspectGoal<'a, 'tcx> {
             inspect::ProbeKind::Root { result }
             | inspect::ProbeKind::TryNormalizeNonRigid { result }
             | inspect::ProbeKind::TraitCandidate { source: _, result }
-            | inspect::ProbeKind::OpaqueTypeStorageLookup { result } => {
+            | inspect::ProbeKind::OpaqueTypeStorageLookup { result }
+            | inspect::ProbeKind::RigidAlias { result } => {
                 // We only add a candidate if `shallow_certainty` was set, which means
                 // that we ended up calling `evaluate_added_goals_and_make_canonical_response`.
                 if let Some(shallow_certainty) = shallow_certainty {
diff --git a/compiler/rustc_trait_selection/src/solve/select.rs b/compiler/rustc_trait_selection/src/solve/select.rs
index 257fd263b94..1661852903c 100644
--- a/compiler/rustc_trait_selection/src/solve/select.rs
+++ b/compiler/rustc_trait_selection/src/solve/select.rs
@@ -177,7 +177,8 @@ fn to_selection<'tcx>(
         | ProbeKind::UpcastProjectionCompatibility
         | ProbeKind::OpaqueTypeStorageLookup { result: _ }
         | ProbeKind::Root { result: _ }
-        | ProbeKind::ShadowedEnvProbing => {
+        | ProbeKind::ShadowedEnvProbing
+        | ProbeKind::RigidAlias { result: _ } => {
             span_bug!(span, "didn't expect to assemble trait candidate from {:#?}", cand.kind())
         }
     })
diff --git a/compiler/rustc_type_ir/src/solve/inspect.rs b/compiler/rustc_type_ir/src/solve/inspect.rs
index 099c66f6bdc..138ba8bac88 100644
--- a/compiler/rustc_type_ir/src/solve/inspect.rs
+++ b/compiler/rustc_type_ir/src/solve/inspect.rs
@@ -135,4 +135,6 @@ pub enum ProbeKind<I: Interner> {
     ShadowedEnvProbing,
     /// Try to unify an opaque type with an existing key in the storage.
     OpaqueTypeStorageLookup { result: QueryResult<I> },
+    /// Checking that a rigid alias is well-formed.
+    RigidAlias { result: QueryResult<I> },
 }
diff --git a/compiler/rustc_type_ir/src/solve/mod.rs b/compiler/rustc_type_ir/src/solve/mod.rs
index a0f7658212f..f02c7a32071 100644
--- a/compiler/rustc_type_ir/src/solve/mod.rs
+++ b/compiler/rustc_type_ir/src/solve/mod.rs
@@ -130,6 +130,10 @@ pub enum GoalSource {
     ImplWhereBound,
     /// Instantiating a higher-ranked goal and re-proving it.
     InstantiateHigherRanked,
+    /// Predicate required for an alias projection to be well-formed.
+    /// This is used in two places: projecting to an opaque whose hidden type
+    /// is already registered in the opaque type storage, and for rigid projections.
+    AliasWellFormed,
 }
 
 #[derive_where(Clone; I: Interner, Goal<I, P>: Clone)]
diff --git a/tests/ui/for/issue-20605.next.stderr b/tests/ui/for/issue-20605.next.stderr
index 98609211865..1a66cb41464 100644
--- a/tests/ui/for/issue-20605.next.stderr
+++ b/tests/ui/for/issue-20605.next.stderr
@@ -11,13 +11,6 @@ help: consider mutably borrowing here
 LL |     for item in &mut *things { *item = 0 }
    |                 ++++
 
-error[E0614]: type `<dyn Iterator<Item = &'a mut u8> as IntoIterator>::Item` cannot be dereferenced
-  --> $DIR/issue-20605.rs:6:27
-   |
-LL |     for item in *things { *item = 0 }
-   |                           ^^^^^
-
-error: aborting due to 2 previous errors
+error: aborting due to 1 previous error
 
-Some errors have detailed explanations: E0277, E0614.
-For more information about an error, try `rustc --explain E0277`.
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/for/issue-20605.rs b/tests/ui/for/issue-20605.rs
index 647dc84028c..5c56e64a017 100644
--- a/tests/ui/for/issue-20605.rs
+++ b/tests/ui/for/issue-20605.rs
@@ -4,12 +4,7 @@
 
 fn changer<'a>(mut things: Box<dyn Iterator<Item=&'a mut u8>>) {
     for item in *things { *item = 0 }
-    //[current]~^ ERROR `dyn Iterator<Item = &'a mut u8>` is not an iterator
-    //[next]~^^ ERROR `dyn Iterator<Item = &'a mut u8>` is not an iterator
-    //[next]~| ERROR type `<dyn Iterator<Item = &'a mut u8> as IntoIterator>::Item` cannot be dereferenced
-
-    // FIXME(-Znext-solver): these error messages are horrible and have to be
-    // improved before we stabilize the new solver.
+    //~^ ERROR `dyn Iterator<Item = &'a mut u8>` is not an iterator
 }
 
 fn main() {}
diff --git a/tests/ui/generic-associated-types/ambig-hr-projection-issue-93340.next.stderr b/tests/ui/generic-associated-types/ambig-hr-projection-issue-93340.next.stderr
index d913b2e91ca..d624fb1e42b 100644
--- a/tests/ui/generic-associated-types/ambig-hr-projection-issue-93340.next.stderr
+++ b/tests/ui/generic-associated-types/ambig-hr-projection-issue-93340.next.stderr
@@ -1,5 +1,5 @@
 error[E0283]: type annotations needed
-  --> $DIR/ambig-hr-projection-issue-93340.rs:16:5
+  --> $DIR/ambig-hr-projection-issue-93340.rs:17:5
    |
 LL |     cmp_eq
    |     ^^^^^^ cannot infer type of the type parameter `A` declared on the function `cmp_eq`
@@ -15,6 +15,16 @@ help: consider specifying the generic arguments
 LL |     cmp_eq::<A, B, O>
    |           +++++++++++
 
-error: aborting due to 1 previous error
+error[E0277]: expected a `Fn(<A as Scalar>::RefType<'_>, <B as Scalar>::RefType<'_>)` closure, found `for<'a, 'b> fn(<O as Scalar>::RefType<'a>, <_ as Scalar>::RefType<'b>) -> O {cmp_eq::<O, _, O>}`
+  --> $DIR/ambig-hr-projection-issue-93340.rs:14:1
+   |
+LL | / fn build_expression<A: Scalar, B: Scalar, O: Scalar>(
+LL | | ) -> impl Fn(A::RefType<'_>, B::RefType<'_>) -> O {
+   | |_________________________________________________^ expected an `Fn(<A as Scalar>::RefType<'_>, <B as Scalar>::RefType<'_>)` closure, found `for<'a, 'b> fn(<O as Scalar>::RefType<'a>, <_ as Scalar>::RefType<'b>) -> O {cmp_eq::<O, _, O>}`
+   |
+   = help: the trait `for<'a, 'b> Fn(<A as Scalar>::RefType<'a>, <B as Scalar>::RefType<'b>)` is not implemented for fn item `for<'a, 'b> fn(<O as Scalar>::RefType<'a>, <_ as Scalar>::RefType<'b>) -> O {cmp_eq::<O, _, O>}`
+
+error: aborting due to 2 previous errors
 
-For more information about this error, try `rustc --explain E0283`.
+Some errors have detailed explanations: E0277, E0283.
+For more information about an error, try `rustc --explain E0277`.
diff --git a/tests/ui/generic-associated-types/ambig-hr-projection-issue-93340.old.stderr b/tests/ui/generic-associated-types/ambig-hr-projection-issue-93340.old.stderr
index d913b2e91ca..4a293d44e0e 100644
--- a/tests/ui/generic-associated-types/ambig-hr-projection-issue-93340.old.stderr
+++ b/tests/ui/generic-associated-types/ambig-hr-projection-issue-93340.old.stderr
@@ -1,5 +1,5 @@
 error[E0283]: type annotations needed
-  --> $DIR/ambig-hr-projection-issue-93340.rs:16:5
+  --> $DIR/ambig-hr-projection-issue-93340.rs:17:5
    |
 LL |     cmp_eq
    |     ^^^^^^ cannot infer type of the type parameter `A` declared on the function `cmp_eq`
diff --git a/tests/ui/generic-associated-types/ambig-hr-projection-issue-93340.rs b/tests/ui/generic-associated-types/ambig-hr-projection-issue-93340.rs
index acfebad38db..5f2e134109e 100644
--- a/tests/ui/generic-associated-types/ambig-hr-projection-issue-93340.rs
+++ b/tests/ui/generic-associated-types/ambig-hr-projection-issue-93340.rs
@@ -13,6 +13,7 @@ fn cmp_eq<'a, 'b, A: Scalar, B: Scalar, O: Scalar>(a: A::RefType<'a>, b: B::RefT
 
 fn build_expression<A: Scalar, B: Scalar, O: Scalar>(
 ) -> impl Fn(A::RefType<'_>, B::RefType<'_>) -> O {
+    //[next]~^^ expected a `Fn(<A as Scalar>::RefType<'_>, <B as Scalar>::RefType<'_>)` closure
     cmp_eq
     //~^ ERROR type annotations needed
 }
diff --git a/tests/ui/higher-ranked/structually-relate-aliases.rs b/tests/ui/higher-ranked/structually-relate-aliases.rs
index 69882450961..73c2cd23d86 100644
--- a/tests/ui/higher-ranked/structually-relate-aliases.rs
+++ b/tests/ui/higher-ranked/structually-relate-aliases.rs
@@ -11,6 +11,7 @@ type Assoc<'a, T> = <T as ToUnit<'a>>::Unit;
 impl<T> Overlap<T> for T {}
 
 impl<T> Overlap<for<'a> fn(&'a (), Assoc<'a, T>)> for T {}
-//~^ ERROR conflicting implementations of trait `Overlap<for<'a> fn(&'a (), _)>`
+//~^ ERROR the trait bound `for<'a> T: ToUnit<'a>` is not satisfied
+//~| ERROR the trait bound `for<'a> T: ToUnit<'a>` is not satisfied
 
 fn main() {}
diff --git a/tests/ui/higher-ranked/structually-relate-aliases.stderr b/tests/ui/higher-ranked/structually-relate-aliases.stderr
index 4ecd5829bc3..e9d91e45e21 100644
--- a/tests/ui/higher-ranked/structually-relate-aliases.stderr
+++ b/tests/ui/higher-ranked/structually-relate-aliases.stderr
@@ -1,18 +1,26 @@
  WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: AliasTy { args: [?1t, '^0.Named(DefId(0:15 ~ structually_relate_aliases[de75]::{impl#1}::'a), "'a")], def_id: DefId(0:5 ~ structually_relate_aliases[de75]::ToUnit::Unit), .. }
- WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: AliasTy { args: [?1t, '^0.Named(DefId(0:15 ~ structually_relate_aliases[de75]::{impl#1}::'a), "'a")], def_id: DefId(0:5 ~ structually_relate_aliases[de75]::ToUnit::Unit), .. }
- WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: AliasTy { args: [?1t, '^0.Named(DefId(0:15 ~ structually_relate_aliases[de75]::{impl#1}::'a), "'a")], def_id: DefId(0:5 ~ structually_relate_aliases[de75]::ToUnit::Unit), .. }
- WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: AliasTy { args: [?1t, '^0.Named(DefId(0:15 ~ structually_relate_aliases[de75]::{impl#1}::'a), "'a")], def_id: DefId(0:5 ~ structually_relate_aliases[de75]::ToUnit::Unit), .. }
-error[E0119]: conflicting implementations of trait `Overlap<for<'a> fn(&'a (), _)>` for type `for<'a> fn(&'a (), _)`
-  --> $DIR/structually-relate-aliases.rs:13:1
+error[E0277]: the trait bound `for<'a> T: ToUnit<'a>` is not satisfied
+  --> $DIR/structually-relate-aliases.rs:13:36
    |
-LL | impl<T> Overlap<T> for T {}
-   | ------------------------ first implementation here
-LL |
 LL | impl<T> Overlap<for<'a> fn(&'a (), Assoc<'a, T>)> for T {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `for<'a> fn(&'a (), _)`
+   |                                    ^^^^^^^^^^^^ the trait `for<'a> ToUnit<'a>` is not implemented for `T`
+   |
+help: consider restricting type parameter `T`
+   |
+LL | impl<T: for<'a> ToUnit<'a>> Overlap<for<'a> fn(&'a (), Assoc<'a, T>)> for T {}
+   |       ++++++++++++++++++++
+
+error[E0277]: the trait bound `for<'a> T: ToUnit<'a>` is not satisfied
+  --> $DIR/structually-relate-aliases.rs:13:17
+   |
+LL | impl<T> Overlap<for<'a> fn(&'a (), Assoc<'a, T>)> for T {}
+   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `for<'a> ToUnit<'a>` is not implemented for `T`
+   |
+help: consider restricting type parameter `T`
    |
-   = note: this behavior recently changed as a result of a bug fix; see rust-lang/rust#56105 for details
+LL | impl<T: for<'a> ToUnit<'a>> Overlap<for<'a> fn(&'a (), Assoc<'a, T>)> for T {}
+   |       ++++++++++++++++++++
 
-error: aborting due to 1 previous error
+error: aborting due to 2 previous errors
 
-For more information about this error, try `rustc --explain E0119`.
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/impl-trait/in-trait/alias-bounds-when-not-wf.rs b/tests/ui/impl-trait/in-trait/alias-bounds-when-not-wf.rs
index 5a6bf9bfaef..351cdad4ee1 100644
--- a/tests/ui/impl-trait/in-trait/alias-bounds-when-not-wf.rs
+++ b/tests/ui/impl-trait/in-trait/alias-bounds-when-not-wf.rs
@@ -14,6 +14,8 @@ struct W<T>(T);
 // `usize: Foo` doesn't hold. Therefore we ICE, because we don't expect to still
 // encounter weak types in `assemble_alias_bound_candidates_recur`.
 fn hello(_: W<A<usize>>) {}
-//~^ ERROR the size for values of type `A<usize>` cannot be known at compilation time
+//~^ ERROR the trait bound `usize: Foo` is not satisfied
+//~| ERROR the trait bound `usize: Foo` is not satisfied
+//~| ERROR the trait bound `usize: Foo` is not satisfied
 
 fn main() {}
diff --git a/tests/ui/impl-trait/in-trait/alias-bounds-when-not-wf.stderr b/tests/ui/impl-trait/in-trait/alias-bounds-when-not-wf.stderr
index 9663fab3d8c..79581066a3a 100644
--- a/tests/ui/impl-trait/in-trait/alias-bounds-when-not-wf.stderr
+++ b/tests/ui/impl-trait/in-trait/alias-bounds-when-not-wf.stderr
@@ -7,14 +7,42 @@ LL | #![feature(lazy_type_alias)]
    = note: see issue #112792 <https://github.com/rust-lang/rust/issues/112792> for more information
    = note: `#[warn(incomplete_features)]` on by default
 
-error[E0277]: the size for values of type `A<usize>` cannot be known at compilation time
+error[E0277]: the trait bound `usize: Foo` is not satisfied
   --> $DIR/alias-bounds-when-not-wf.rs:16:13
    |
 LL | fn hello(_: W<A<usize>>) {}
-   |             ^^^^^^^^^^^ doesn't have a size known at compile-time
+   |             ^^^^^^^^^^^ the trait `Foo` is not implemented for `usize`
    |
-   = help: the trait `Sized` is not implemented for `A<usize>`
+help: this trait has no implementations, consider adding one
+  --> $DIR/alias-bounds-when-not-wf.rs:6:1
+   |
+LL | trait Foo {}
+   | ^^^^^^^^^
+
+error[E0277]: the trait bound `usize: Foo` is not satisfied
+  --> $DIR/alias-bounds-when-not-wf.rs:16:10
+   |
+LL | fn hello(_: W<A<usize>>) {}
+   |          ^ the trait `Foo` is not implemented for `usize`
+   |
+help: this trait has no implementations, consider adding one
+  --> $DIR/alias-bounds-when-not-wf.rs:6:1
+   |
+LL | trait Foo {}
+   | ^^^^^^^^^
+
+error[E0277]: the trait bound `usize: Foo` is not satisfied
+  --> $DIR/alias-bounds-when-not-wf.rs:16:1
+   |
+LL | fn hello(_: W<A<usize>>) {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Foo` is not implemented for `usize`
+   |
+help: this trait has no implementations, consider adding one
+  --> $DIR/alias-bounds-when-not-wf.rs:6:1
+   |
+LL | trait Foo {}
+   | ^^^^^^^^^
 
-error: aborting due to 1 previous error; 1 warning emitted
+error: aborting due to 3 previous errors; 1 warning emitted
 
 For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/impl-trait/method-resolution4.next.stderr b/tests/ui/impl-trait/method-resolution4.next.stderr
index b48de0af357..0524f49f98e 100644
--- a/tests/ui/impl-trait/method-resolution4.next.stderr
+++ b/tests/ui/impl-trait/method-resolution4.next.stderr
@@ -4,19 +4,6 @@ error[E0282]: type annotations needed
 LL |         foo(false).next().unwrap();
    |         ^^^^^^^^^^ cannot infer type
 
-error[E0308]: mismatched types
-  --> $DIR/method-resolution4.rs:16:5
-   |
-LL | fn foo(b: bool) -> impl Iterator<Item = ()> {
-   |                    ------------------------ the expected opaque type
-...
-LL |     std::iter::empty()
-   |     ^^^^^^^^^^^^^^^^^^ types differ
-   |
-   = note: expected opaque type `impl Iterator<Item = ()>`
-                   found struct `std::iter::Empty<_>`
-
-error: aborting due to 2 previous errors
+error: aborting due to 1 previous error
 
-Some errors have detailed explanations: E0282, E0308.
-For more information about an error, try `rustc --explain E0282`.
+For more information about this error, try `rustc --explain E0282`.
diff --git a/tests/ui/impl-trait/method-resolution4.rs b/tests/ui/impl-trait/method-resolution4.rs
index 91884eb59fd..5c8813ed792 100644
--- a/tests/ui/impl-trait/method-resolution4.rs
+++ b/tests/ui/impl-trait/method-resolution4.rs
@@ -14,7 +14,6 @@ fn foo(b: bool) -> impl Iterator<Item = ()> {
         //[next]~^ type annotations needed
     }
     std::iter::empty()
-    //[next]~^ mismatched types
 }
 
 fn main() {}
diff --git a/tests/ui/impl-trait/recursive-coroutine-boxed.next.stderr b/tests/ui/impl-trait/recursive-coroutine-boxed.next.stderr
index 96db2030a40..132f7de4ef2 100644
--- a/tests/ui/impl-trait/recursive-coroutine-boxed.next.stderr
+++ b/tests/ui/impl-trait/recursive-coroutine-boxed.next.stderr
@@ -1,5 +1,5 @@
 error[E0282]: type annotations needed
-  --> $DIR/recursive-coroutine-boxed.rs:15:23
+  --> $DIR/recursive-coroutine-boxed.rs:14:23
    |
 LL |         let mut gen = Box::pin(foo());
    |                       ^^^^^^^^ cannot infer type of the type parameter `T` declared on the struct `Box`
@@ -12,29 +12,6 @@ help: consider specifying the generic argument
 LL |         let mut gen = Box::<T>::pin(foo());
    |                          +++++
 
-error[E0308]: mismatched types
-  --> $DIR/recursive-coroutine-boxed.rs:14:18
-   |
-LL |   fn foo() -> impl Coroutine<Yield = (), Return = ()> {
-   |               ---------------------------------------
-   |               |
-   |               the expected opaque type
-   |               expected `impl Coroutine<Yield = (), Return = ()>` because of return type
-...
-LL |       #[coroutine] || {
-   |  __________________^
-LL | |         let mut gen = Box::pin(foo());
-LL | |
-LL | |         let mut r = gen.as_mut().resume(());
-...  |
-LL | |         }
-LL | |     }
-   | |_____^ types differ
-   |
-   = note: expected opaque type `impl Coroutine<Yield = (), Return = ()>`
-                found coroutine `{coroutine@$DIR/recursive-coroutine-boxed.rs:14:18: 14:20}`
-
-error: aborting due to 2 previous errors
+error: aborting due to 1 previous error
 
-Some errors have detailed explanations: E0282, E0308.
-For more information about an error, try `rustc --explain E0282`.
+For more information about this error, try `rustc --explain E0282`.
diff --git a/tests/ui/impl-trait/recursive-coroutine-boxed.rs b/tests/ui/impl-trait/recursive-coroutine-boxed.rs
index 24a77d73114..8d38e6aed12 100644
--- a/tests/ui/impl-trait/recursive-coroutine-boxed.rs
+++ b/tests/ui/impl-trait/recursive-coroutine-boxed.rs
@@ -10,8 +10,7 @@ fn foo() -> impl Coroutine<Yield = (), Return = ()> {
     // FIXME(-Znext-solver): this fails with a mismatched types as the
     // hidden type of the opaque ends up as {type error}. We should not
     // emit errors for such goals.
-
-    #[coroutine] || { //[next]~ ERROR mismatched types
+    #[coroutine] || {
         let mut gen = Box::pin(foo());
         //[next]~^ ERROR type annotations needed
         let mut r = gen.as_mut().resume(());
diff --git a/tests/ui/impl-trait/unsized_coercion.next.stderr b/tests/ui/impl-trait/unsized_coercion.next.stderr
index 49ac3f1845f..4cebd26a5be 100644
--- a/tests/ui/impl-trait/unsized_coercion.next.stderr
+++ b/tests/ui/impl-trait/unsized_coercion.next.stderr
@@ -1,26 +1,35 @@
-error[E0271]: type mismatch resolving `impl Trait <: dyn Trait`
-  --> $DIR/unsized_coercion.rs:14:17
+error[E0277]: the size for values of type `dyn Trait` cannot be known at compilation time
+  --> $DIR/unsized_coercion.rs:15:17
    |
 LL |         let x = hello();
-   |                 ^^^^^^^ types differ
+   |                 ^^^^^^^ doesn't have a size known at compile-time
+   |
+   = help: the trait `Sized` is not implemented for `dyn Trait`
 
 error[E0308]: mismatched types
-  --> $DIR/unsized_coercion.rs:18:14
+  --> $DIR/unsized_coercion.rs:19:5
    |
 LL | fn hello() -> Box<impl Trait> {
-   |                   ---------- the expected opaque type
+   |               ---------------
+   |               |   |
+   |               |   the expected opaque type
+   |               expected `Box<impl Trait>` because of return type
 ...
 LL |     Box::new(1u32)
-   |     -------- ^^^^ types differ
-   |     |
-   |     arguments to this function are incorrect
+   |     ^^^^^^^^^^^^^^ types differ
+   |
+   = note: expected struct `Box<impl Trait>`
+              found struct `Box<u32>`
+
+error[E0277]: the size for values of type `dyn Trait` cannot be known at compilation time
+  --> $DIR/unsized_coercion.rs:12:1
+   |
+LL | fn hello() -> Box<impl Trait> {
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
    |
-   = note: expected opaque type `impl Trait`
-                     found type `u32`
-note: associated function defined here
-  --> $SRC_DIR/alloc/src/boxed.rs:LL:COL
+   = help: the trait `Sized` is not implemented for `dyn Trait`
 
-error: aborting due to 2 previous errors
+error: aborting due to 3 previous errors
 
-Some errors have detailed explanations: E0271, E0308.
-For more information about an error, try `rustc --explain E0271`.
+Some errors have detailed explanations: E0277, E0308.
+For more information about an error, try `rustc --explain E0277`.
diff --git a/tests/ui/impl-trait/unsized_coercion.rs b/tests/ui/impl-trait/unsized_coercion.rs
index 46e040c1428..b3791b38abc 100644
--- a/tests/ui/impl-trait/unsized_coercion.rs
+++ b/tests/ui/impl-trait/unsized_coercion.rs
@@ -10,9 +10,10 @@ trait Trait {}
 impl Trait for u32 {}
 
 fn hello() -> Box<impl Trait> {
+    //[next]~^ ERROR the size for values of type `dyn Trait` cannot be known at compilation time
     if true {
         let x = hello();
-        //[next]~^ ERROR: type mismatch resolving `impl Trait <: dyn Trait`
+        //[next]~^ ERROR: the size for values of type `dyn Trait` cannot be known at compilation time
         let y: Box<dyn Trait> = x;
     }
     Box::new(1u32) //[next]~ ERROR: mismatched types
diff --git a/tests/ui/impl-trait/unsized_coercion3.next.stderr b/tests/ui/impl-trait/unsized_coercion3.next.stderr
index 586ae076028..d1e1809cf16 100644
--- a/tests/ui/impl-trait/unsized_coercion3.next.stderr
+++ b/tests/ui/impl-trait/unsized_coercion3.next.stderr
@@ -1,38 +1,35 @@
-error[E0271]: type mismatch resolving `impl Trait + ?Sized <: dyn Send`
-  --> $DIR/unsized_coercion3.rs:13:17
+error[E0277]: the trait bound `dyn Send: Trait` is not satisfied
+  --> $DIR/unsized_coercion3.rs:14:17
    |
 LL |         let x = hello();
-   |                 ^^^^^^^ types differ
+   |                 ^^^^^^^ the trait `Trait` is not implemented for `dyn Send`
+   |
+   = help: the trait `Trait` is implemented for `u32`
 
 error[E0308]: mismatched types
-  --> $DIR/unsized_coercion3.rs:18:14
+  --> $DIR/unsized_coercion3.rs:19:5
    |
 LL | fn hello() -> Box<impl Trait + ?Sized> {
-   |                   ------------------- the expected opaque type
+   |               ------------------------
+   |               |   |
+   |               |   the expected opaque type
+   |               expected `Box<impl Trait + ?Sized>` because of return type
 ...
 LL |     Box::new(1u32)
-   |     -------- ^^^^ types differ
-   |     |
-   |     arguments to this function are incorrect
+   |     ^^^^^^^^^^^^^^ types differ
    |
-   = note: expected opaque type `impl Trait + ?Sized`
-                     found type `u32`
-note: associated function defined here
-  --> $SRC_DIR/alloc/src/boxed.rs:LL:COL
+   = note: expected struct `Box<impl Trait + ?Sized>`
+              found struct `Box<u32>`
 
-error[E0277]: the size for values of type `impl Trait + ?Sized` cannot be known at compilation time
-  --> $DIR/unsized_coercion3.rs:18:14
+error[E0277]: the trait bound `dyn Send: Trait` is not satisfied
+  --> $DIR/unsized_coercion3.rs:11:1
    |
-LL |     Box::new(1u32)
-   |     -------- ^^^^ doesn't have a size known at compile-time
-   |     |
-   |     required by a bound introduced by this call
+LL | fn hello() -> Box<impl Trait + ?Sized> {
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Trait` is not implemented for `dyn Send`
    |
-   = help: the trait `Sized` is not implemented for `impl Trait + ?Sized`
-note: required by a bound in `Box::<T>::new`
-  --> $SRC_DIR/alloc/src/boxed.rs:LL:COL
+   = help: the trait `Trait` is implemented for `u32`
 
 error: aborting due to 3 previous errors
 
-Some errors have detailed explanations: E0271, E0277, E0308.
-For more information about an error, try `rustc --explain E0271`.
+Some errors have detailed explanations: E0277, E0308.
+For more information about an error, try `rustc --explain E0277`.
diff --git a/tests/ui/impl-trait/unsized_coercion3.old.stderr b/tests/ui/impl-trait/unsized_coercion3.old.stderr
index 52a72b84a8d..3bb9f9c2095 100644
--- a/tests/ui/impl-trait/unsized_coercion3.old.stderr
+++ b/tests/ui/impl-trait/unsized_coercion3.old.stderr
@@ -1,5 +1,5 @@
 error[E0277]: the size for values of type `impl Trait + ?Sized` cannot be known at compilation time
-  --> $DIR/unsized_coercion3.rs:15:32
+  --> $DIR/unsized_coercion3.rs:16:32
    |
 LL |         let y: Box<dyn Send> = x;
    |                                ^ doesn't have a size known at compile-time
diff --git a/tests/ui/impl-trait/unsized_coercion3.rs b/tests/ui/impl-trait/unsized_coercion3.rs
index 7e862de2157..c1dd5350e22 100644
--- a/tests/ui/impl-trait/unsized_coercion3.rs
+++ b/tests/ui/impl-trait/unsized_coercion3.rs
@@ -9,15 +9,15 @@ trait Trait {}
 impl Trait for u32 {}
 
 fn hello() -> Box<impl Trait + ?Sized> {
+    //[next]~^ ERROR: the trait bound `dyn Send: Trait` is not satisfied
     if true {
         let x = hello();
-        //[next]~^ ERROR: type mismatch resolving `impl Trait + ?Sized <: dyn Send`
+        //[next]~^ ERROR: the trait bound `dyn Send: Trait` is not satisfied
         let y: Box<dyn Send> = x;
         //[old]~^ ERROR: the size for values of type `impl Trait + ?Sized` cannot be know
     }
     Box::new(1u32)
     //[next]~^ ERROR: mismatched types
-    //[next]~| ERROR: the size for values of type `impl Trait + ?Sized` cannot be know
 }
 
 fn main() {}
diff --git a/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-bound.rs b/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-bound.rs
index 35757f2339d..1260cca5106 100644
--- a/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-bound.rs
+++ b/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-bound.rs
@@ -13,9 +13,14 @@ fn main() {
 }
 
 fn weird0() -> impl Sized + !Sized {}
-//~^ ERROR type mismatch resolving `impl !Sized + Sized == ()`
+//~^ ERROR the trait bound `(): !Sized` is not satisfied
+//~| ERROR the trait bound `(): !Sized` is not satisfied
+//~| ERROR the trait bound `(): !Sized` is not satisfied
 fn weird1() -> impl !Sized + Sized {}
-//~^ ERROR type mismatch resolving `impl !Sized + Sized == ()`
+//~^ ERROR the trait bound `(): !Sized` is not satisfied
+//~| ERROR the trait bound `(): !Sized` is not satisfied
+//~| ERROR the trait bound `(): !Sized` is not satisfied
 fn weird2() -> impl !Sized {}
-//~^ ERROR type mismatch resolving `impl !Sized == ()`
-//~| ERROR the size for values of type `impl !Sized` cannot be known at compilation time
+//~^ ERROR the trait bound `(): !Sized` is not satisfied
+//~| ERROR the trait bound `(): !Sized` is not satisfied
+//~| ERROR the trait bound `(): !Sized` is not satisfied
diff --git a/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-bound.stderr b/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-bound.stderr
index 3dd2b27b55b..4ec578a3b7b 100644
--- a/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-bound.stderr
+++ b/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-bound.stderr
@@ -1,29 +1,56 @@
-error[E0271]: type mismatch resolving `impl !Sized + Sized == ()`
+error[E0277]: the trait bound `(): !Sized` is not satisfied
   --> $DIR/opaque-type-unsatisfied-bound.rs:15:16
    |
 LL | fn weird0() -> impl Sized + !Sized {}
-   |                ^^^^^^^^^^^^^^^^^^^ types differ
+   |                ^^^^^^^^^^^^^^^^^^^ the trait bound `(): !Sized` is not satisfied
 
-error[E0271]: type mismatch resolving `impl !Sized + Sized == ()`
-  --> $DIR/opaque-type-unsatisfied-bound.rs:17:16
+error[E0277]: the trait bound `(): !Sized` is not satisfied
+  --> $DIR/opaque-type-unsatisfied-bound.rs:15:36
    |
-LL | fn weird1() -> impl !Sized + Sized {}
-   |                ^^^^^^^^^^^^^^^^^^^ types differ
+LL | fn weird0() -> impl Sized + !Sized {}
+   |                                    ^^ the trait bound `(): !Sized` is not satisfied
+
+error[E0277]: the trait bound `(): !Sized` is not satisfied
+  --> $DIR/opaque-type-unsatisfied-bound.rs:15:1
+   |
+LL | fn weird0() -> impl Sized + !Sized {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait bound `(): !Sized` is not satisfied
 
-error[E0271]: type mismatch resolving `impl !Sized == ()`
+error[E0277]: the trait bound `(): !Sized` is not satisfied
   --> $DIR/opaque-type-unsatisfied-bound.rs:19:16
    |
+LL | fn weird1() -> impl !Sized + Sized {}
+   |                ^^^^^^^^^^^^^^^^^^^ the trait bound `(): !Sized` is not satisfied
+
+error[E0277]: the trait bound `(): !Sized` is not satisfied
+  --> $DIR/opaque-type-unsatisfied-bound.rs:19:36
+   |
+LL | fn weird1() -> impl !Sized + Sized {}
+   |                                    ^^ the trait bound `(): !Sized` is not satisfied
+
+error[E0277]: the trait bound `(): !Sized` is not satisfied
+  --> $DIR/opaque-type-unsatisfied-bound.rs:19:1
+   |
+LL | fn weird1() -> impl !Sized + Sized {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait bound `(): !Sized` is not satisfied
+
+error[E0277]: the trait bound `(): !Sized` is not satisfied
+  --> $DIR/opaque-type-unsatisfied-bound.rs:23:16
+   |
 LL | fn weird2() -> impl !Sized {}
-   |                ^^^^^^^^^^^ types differ
+   |                ^^^^^^^^^^^ the trait bound `(): !Sized` is not satisfied
 
-error[E0277]: the size for values of type `impl !Sized` cannot be known at compilation time
-  --> $DIR/opaque-type-unsatisfied-bound.rs:19:16
+error[E0277]: the trait bound `(): !Sized` is not satisfied
+  --> $DIR/opaque-type-unsatisfied-bound.rs:23:28
    |
 LL | fn weird2() -> impl !Sized {}
-   |                ^^^^^^^^^^^ doesn't have a size known at compile-time
+   |                            ^^ the trait bound `(): !Sized` is not satisfied
+
+error[E0277]: the trait bound `(): !Sized` is not satisfied
+  --> $DIR/opaque-type-unsatisfied-bound.rs:23:1
    |
-   = help: the trait `Sized` is not implemented for `impl !Sized`
-   = note: the return type of a function must have a statically known size
+LL | fn weird2() -> impl !Sized {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait bound `(): !Sized` is not satisfied
 
 error[E0277]: the trait bound `impl !Trait: Trait` is not satisfied
   --> $DIR/opaque-type-unsatisfied-bound.rs:12:13
@@ -39,7 +66,6 @@ note: required by a bound in `consume`
 LL | fn consume(_: impl Trait) {}
    |                    ^^^^^ required by this bound in `consume`
 
-error: aborting due to 5 previous errors
+error: aborting due to 10 previous errors
 
-Some errors have detailed explanations: E0271, E0277.
-For more information about an error, try `rustc --explain E0271`.
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-fn-bound.rs b/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-fn-bound.rs
index 9951826a846..c6826578658 100644
--- a/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-fn-bound.rs
+++ b/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-fn-bound.rs
@@ -3,6 +3,8 @@
 #![feature(negative_bounds, unboxed_closures)]
 
 fn produce() -> impl !Fn<(u32,)> {}
-//~^ ERROR type mismatch resolving `impl !Fn<(u32,)> == ()`
+//~^ ERROR the trait bound `(): !Fn(u32)` is not satisfied
+//~| ERROR the trait bound `(): !Fn(u32)` is not satisfied
+//~| ERROR the trait bound `(): !Fn(u32)` is not satisfied
 
 fn main() {}
diff --git a/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-fn-bound.stderr b/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-fn-bound.stderr
index e1b84e0df7a..f81f0a23ac3 100644
--- a/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-fn-bound.stderr
+++ b/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-fn-bound.stderr
@@ -1,9 +1,21 @@
-error[E0271]: type mismatch resolving `impl !Fn<(u32,)> == ()`
+error[E0277]: the trait bound `(): !Fn(u32)` is not satisfied
   --> $DIR/opaque-type-unsatisfied-fn-bound.rs:5:17
    |
 LL | fn produce() -> impl !Fn<(u32,)> {}
-   |                 ^^^^^^^^^^^^^^^^ types differ
+   |                 ^^^^^^^^^^^^^^^^ the trait bound `(): !Fn(u32)` is not satisfied
 
-error: aborting due to 1 previous error
+error[E0277]: the trait bound `(): !Fn(u32)` is not satisfied
+  --> $DIR/opaque-type-unsatisfied-fn-bound.rs:5:34
+   |
+LL | fn produce() -> impl !Fn<(u32,)> {}
+   |                                  ^^ the trait bound `(): !Fn(u32)` is not satisfied
+
+error[E0277]: the trait bound `(): !Fn(u32)` is not satisfied
+  --> $DIR/opaque-type-unsatisfied-fn-bound.rs:5:1
+   |
+LL | fn produce() -> impl !Fn<(u32,)> {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait bound `(): !Fn(u32)` is not satisfied
+
+error: aborting due to 3 previous errors
 
-For more information about this error, try `rustc --explain E0271`.
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/traits/next-solver/issue-118950-root-region.rs b/tests/ui/traits/next-solver/issue-118950-root-region.rs
index 9f6dea5d5bf..e1bd234a275 100644
--- a/tests/ui/traits/next-solver/issue-118950-root-region.rs
+++ b/tests/ui/traits/next-solver/issue-118950-root-region.rs
@@ -17,7 +17,7 @@ type Assoc<'a, T> = <*const T as ToUnit<'a>>::Unit;
 impl<T> Overlap<T> for T {}
 
 impl<T> Overlap<for<'a> fn(Assoc<'a, T>)> for T where Missing: Overlap<T> {}
-//~^ ERROR conflicting implementations of trait `Overlap<fn(_)>` for type `fn(_)`
-//~| ERROR cannot find type `Missing` in this scope
+//~^ ERROR cannot find type `Missing` in this scope
+//~| ERROR the trait bound `for<'a> *const T: ToUnit<'a>` is not satisfied
 
 fn main() {}
diff --git a/tests/ui/traits/next-solver/issue-118950-root-region.stderr b/tests/ui/traits/next-solver/issue-118950-root-region.stderr
index 7c3e22fb401..f6545c6ebf9 100644
--- a/tests/ui/traits/next-solver/issue-118950-root-region.stderr
+++ b/tests/ui/traits/next-solver/issue-118950-root-region.stderr
@@ -26,21 +26,19 @@ LL | trait ToUnit<'a> {
    | ^^^^^^^^^^^^^^^^
 
  WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: AliasTy { args: ['^0.Named(DefId(0:15 ~ issue_118950_root_region[d54f]::{impl#1}::'a), "'a"), ?1t], def_id: DefId(0:8 ~ issue_118950_root_region[d54f]::Assoc), .. }
- WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: AliasTy { args: ['^0.Named(DefId(0:15 ~ issue_118950_root_region[d54f]::{impl#1}::'a), "'a"), ?1t], def_id: DefId(0:8 ~ issue_118950_root_region[d54f]::Assoc), .. }
- WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: AliasTy { args: ['^0.Named(DefId(0:15 ~ issue_118950_root_region[d54f]::{impl#1}::'a), "'a"), ?1t], def_id: DefId(0:8 ~ issue_118950_root_region[d54f]::Assoc), .. }
- WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: AliasTy { args: ['^0.Named(DefId(0:15 ~ issue_118950_root_region[d54f]::{impl#1}::'a), "'a"), ?1t], def_id: DefId(0:8 ~ issue_118950_root_region[d54f]::Assoc), .. }
-error[E0119]: conflicting implementations of trait `Overlap<fn(_)>` for type `fn(_)`
-  --> $DIR/issue-118950-root-region.rs:19:1
+error[E0277]: the trait bound `for<'a> *const T: ToUnit<'a>` is not satisfied
+  --> $DIR/issue-118950-root-region.rs:19:17
    |
-LL | impl<T> Overlap<T> for T {}
-   | ------------------------ first implementation here
-LL |
 LL | impl<T> Overlap<for<'a> fn(Assoc<'a, T>)> for T where Missing: Overlap<T> {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `fn(_)`
+   |                 ^^^^^^^^^^^^^^^^^^^^^^^^ the trait `for<'a> ToUnit<'a>` is not implemented for `*const T`
+   |
+help: this trait has no implementations, consider adding one
+  --> $DIR/issue-118950-root-region.rs:8:1
    |
-   = note: this behavior recently changed as a result of a bug fix; see rust-lang/rust#56105 for details
+LL | trait ToUnit<'a> {
+   | ^^^^^^^^^^^^^^^^
 
 error: aborting due to 3 previous errors; 1 warning emitted
 
-Some errors have detailed explanations: E0119, E0277, E0412.
-For more information about an error, try `rustc --explain E0119`.
+Some errors have detailed explanations: E0277, E0412.
+For more information about an error, try `rustc --explain E0277`.
diff --git a/tests/ui/traits/next-solver/normalize/normalize-region-obligations.rs b/tests/ui/traits/next-solver/normalize/normalize-region-obligations.rs
index 7bf3274f9c6..c4c2e695a1d 100644
--- a/tests/ui/traits/next-solver/normalize/normalize-region-obligations.rs
+++ b/tests/ui/traits/next-solver/normalize/normalize-region-obligations.rs
@@ -15,7 +15,7 @@ trait Mirror { type Assoc: ?Sized; }
 impl<T: ?Sized> Mirror for T { type Assoc = T; }
 
 trait MirrorRegion<'a> { type Assoc: ?Sized; }
-impl<'a, T> MirrorRegion<'a> for T { type Assoc = T; }
+impl<'a, T: ?Sized> MirrorRegion<'a> for T { type Assoc = T; }
 
 impl<T> Foo for T {
     #[cfg(normalize_param_env)]
diff --git a/tests/ui/typeck/issue-103899.rs b/tests/ui/typeck/issue-103899.rs
index 38882e9dc54..81ab92a8994 100644
--- a/tests/ui/typeck/issue-103899.rs
+++ b/tests/ui/typeck/issue-103899.rs
@@ -1,11 +1,9 @@
 //@ revisions: current next
-//@[next] compile-flags: -Znext-solver
-//@[next] check-pass
 //@ ignore-compare-mode-next-solver (explicit revisions)
-//@[current] check-fail
-//@[current] failure-status: 101
-//@[current] dont-check-compiler-stderr
-//@[current] known-bug: #103899
+//@ check-fail
+//@ failure-status: 101
+//@ dont-check-compiler-stderr
+//@ known-bug: #103899
 
 trait BaseWithAssoc {
     type Assoc;