about summary refs log tree commit diff
path: root/compiler/rustc_next_trait_solver/src
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/rustc_next_trait_solver/src')
-rw-r--r--compiler/rustc_next_trait_solver/src/canonicalizer.rs2
-rw-r--r--compiler/rustc_next_trait_solver/src/delegate.rs10
-rw-r--r--compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs63
-rw-r--r--compiler/rustc_next_trait_solver/src/solve/assembly/structural_traits.rs29
-rw-r--r--compiler/rustc_next_trait_solver/src/solve/effect_goals.rs9
-rw-r--r--compiler/rustc_next_trait_solver/src/solve/eval_ctxt/canonical.rs50
-rw-r--r--compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs54
-rw-r--r--compiler/rustc_next_trait_solver/src/solve/eval_ctxt/probe.rs1
-rw-r--r--compiler/rustc_next_trait_solver/src/solve/mod.rs6
-rw-r--r--compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs62
-rw-r--r--compiler/rustc_next_trait_solver/src/solve/trait_goals.rs81
11 files changed, 233 insertions, 134 deletions
diff --git a/compiler/rustc_next_trait_solver/src/canonicalizer.rs b/compiler/rustc_next_trait_solver/src/canonicalizer.rs
index 62a7c84bc28..7eeed721d5a 100644
--- a/compiler/rustc_next_trait_solver/src/canonicalizer.rs
+++ b/compiler/rustc_next_trait_solver/src/canonicalizer.rs
@@ -522,7 +522,7 @@ impl<D: SolverDelegate<Interner = I>, I: Interner> TypeFolder<I> for Canonicaliz
             // FIXME: See comment above -- we could fold the region separately or something.
             ty::ConstKind::Bound(_, _)
             | ty::ConstKind::Unevaluated(_)
-            | ty::ConstKind::Value(_, _)
+            | ty::ConstKind::Value(_)
             | ty::ConstKind::Error(_)
             | ty::ConstKind::Expr(_) => return c.super_fold_with(self),
         };
diff --git a/compiler/rustc_next_trait_solver/src/delegate.rs b/compiler/rustc_next_trait_solver/src/delegate.rs
index 2d2d50e62f9..a64941cce3a 100644
--- a/compiler/rustc_next_trait_solver/src/delegate.rs
+++ b/compiler/rustc_next_trait_solver/src/delegate.rs
@@ -4,15 +4,13 @@ use rustc_type_ir::fold::TypeFoldable;
 use rustc_type_ir::solve::{Certainty, Goal, NoSolution};
 use rustc_type_ir::{self as ty, InferCtxtLike, Interner};
 
-pub trait SolverDelegate: Deref<Target = <Self as SolverDelegate>::Infcx> + Sized {
-    type Infcx: InferCtxtLike<Interner = <Self as SolverDelegate>::Interner>;
+pub trait SolverDelegate: Deref<Target = Self::Infcx> + Sized {
+    type Infcx: InferCtxtLike<Interner = Self::Interner>;
     type Interner: Interner;
     fn cx(&self) -> Self::Interner {
         (**self).cx()
     }
 
-    type Span: Copy;
-
     fn build_with_canonical<V>(
         cx: Self::Interner,
         canonical: &ty::CanonicalQueryInput<Self::Interner, V>,
@@ -23,7 +21,7 @@ pub trait SolverDelegate: Deref<Target = <Self as SolverDelegate>::Infcx> + Size
     fn fresh_var_for_kind_with_span(
         &self,
         arg: <Self::Interner as Interner>::GenericArg,
-        span: Self::Span,
+        span: <Self::Interner as Interner>::Span,
     ) -> <Self::Interner as Interner>::GenericArg;
 
     // FIXME: Uplift the leak check into this crate.
@@ -61,6 +59,7 @@ pub trait SolverDelegate: Deref<Target = <Self as SolverDelegate>::Infcx> + Size
     fn instantiate_canonical_var_with_infer(
         &self,
         cv_info: ty::CanonicalVarInfo<Self::Interner>,
+        span: <Self::Interner as Interner>::Span,
         universe_map: impl Fn(ty::UniverseIndex) -> ty::UniverseIndex,
     ) -> <Self::Interner as Interner>::GenericArg;
 
@@ -86,6 +85,7 @@ pub trait SolverDelegate: Deref<Target = <Self as SolverDelegate>::Infcx> + Size
         &self,
         key: ty::OpaqueTypeKey<Self::Interner>,
         hidden_ty: <Self::Interner as Interner>::Ty,
+        span: <Self::Interner as Interner>::Span,
     );
 
     fn reset_opaque_types(&self);
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 63432dc199b..d0b01b14d63 100644
--- a/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs
+++ b/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs
@@ -19,6 +19,11 @@ use crate::solve::{
     MaybeCause, NoSolution, QueryResult,
 };
 
+enum AliasBoundKind {
+    SelfBounds,
+    NonSelfBounds,
+}
+
 /// A candidate is a possible way to prove a goal.
 ///
 /// It consists of both the `source`, which describes how that goal would be proven,
@@ -510,7 +515,12 @@ where
         candidates: &mut Vec<Candidate<I>>,
     ) {
         let () = self.probe(|_| ProbeKind::NormalizedSelfTyAssembly).enter(|ecx| {
-            ecx.assemble_alias_bound_candidates_recur(goal.predicate.self_ty(), goal, candidates);
+            ecx.assemble_alias_bound_candidates_recur(
+                goal.predicate.self_ty(),
+                goal,
+                candidates,
+                AliasBoundKind::SelfBounds,
+            );
         });
     }
 
@@ -528,6 +538,7 @@ where
         self_ty: I::Ty,
         goal: Goal<I, G>,
         candidates: &mut Vec<Candidate<I>>,
+        consider_self_bounds: AliasBoundKind,
     ) {
         let (kind, alias_ty) = match self_ty.kind() {
             ty::Bool
@@ -580,16 +591,37 @@ where
             }
         };
 
-        for assumption in
-            self.cx().item_bounds(alias_ty.def_id).iter_instantiated(self.cx(), alias_ty.args)
-        {
-            candidates.extend(G::probe_and_consider_implied_clause(
-                self,
-                CandidateSource::AliasBound,
-                goal,
-                assumption,
-                [],
-            ));
+        match consider_self_bounds {
+            AliasBoundKind::SelfBounds => {
+                for assumption in self
+                    .cx()
+                    .item_self_bounds(alias_ty.def_id)
+                    .iter_instantiated(self.cx(), alias_ty.args)
+                {
+                    candidates.extend(G::probe_and_consider_implied_clause(
+                        self,
+                        CandidateSource::AliasBound,
+                        goal,
+                        assumption,
+                        [],
+                    ));
+                }
+            }
+            AliasBoundKind::NonSelfBounds => {
+                for assumption in self
+                    .cx()
+                    .item_non_self_bounds(alias_ty.def_id)
+                    .iter_instantiated(self.cx(), alias_ty.args)
+                {
+                    candidates.extend(G::probe_and_consider_implied_clause(
+                        self,
+                        CandidateSource::AliasBound,
+                        goal,
+                        assumption,
+                        [],
+                    ));
+                }
+            }
         }
 
         candidates.extend(G::consider_additional_alias_assumptions(self, goal, alias_ty));
@@ -600,9 +632,12 @@ where
 
         // Recurse on the self type of the projection.
         match self.structurally_normalize_ty(goal.param_env, alias_ty.self_ty()) {
-            Ok(next_self_ty) => {
-                self.assemble_alias_bound_candidates_recur(next_self_ty, goal, candidates)
-            }
+            Ok(next_self_ty) => self.assemble_alias_bound_candidates_recur(
+                next_self_ty,
+                goal,
+                candidates,
+                AliasBoundKind::NonSelfBounds,
+            ),
             Err(NoSolution) => {}
         }
     }
diff --git a/compiler/rustc_next_trait_solver/src/solve/assembly/structural_traits.rs b/compiler/rustc_next_trait_solver/src/solve/assembly/structural_traits.rs
index 3c5d9b95e77..082c356cc5f 100644
--- a/compiler/rustc_next_trait_solver/src/solve/assembly/structural_traits.rs
+++ b/compiler/rustc_next_trait_solver/src/solve/assembly/structural_traits.rs
@@ -514,10 +514,11 @@ pub(in crate::solve) fn extract_tupled_inputs_and_output_from_async_callable<I:
                 // will project to the right upvars for the generator, appending the inputs and
                 // coroutine upvars respecting the closure kind.
                 nested.push(
-                    ty::TraitRef::new(cx, async_fn_kind_trait_def_id, [
-                        kind_ty,
-                        Ty::from_closure_kind(cx, goal_kind),
-                    ])
+                    ty::TraitRef::new(
+                        cx,
+                        async_fn_kind_trait_def_id,
+                        [kind_ty, Ty::from_closure_kind(cx, goal_kind)],
+                    )
                     .upcast(cx),
                 );
             }
@@ -624,14 +625,18 @@ fn coroutine_closure_to_ambiguous_coroutine<I: Interner>(
     sig: ty::CoroutineClosureSignature<I>,
 ) -> I::Ty {
     let upvars_projection_def_id = cx.require_lang_item(TraitSolverLangItem::AsyncFnKindUpvars);
-    let tupled_upvars_ty = Ty::new_projection(cx, upvars_projection_def_id, [
-        I::GenericArg::from(args.kind_ty()),
-        Ty::from_closure_kind(cx, goal_kind).into(),
-        goal_region.into(),
-        sig.tupled_inputs_ty.into(),
-        args.tupled_upvars_ty().into(),
-        args.coroutine_captures_by_ref_ty().into(),
-    ]);
+    let tupled_upvars_ty = Ty::new_projection(
+        cx,
+        upvars_projection_def_id,
+        [
+            I::GenericArg::from(args.kind_ty()),
+            Ty::from_closure_kind(cx, goal_kind).into(),
+            goal_region.into(),
+            sig.tupled_inputs_ty.into(),
+            args.tupled_upvars_ty().into(),
+            args.coroutine_captures_by_ref_ty().into(),
+        ],
+    );
     sig.to_coroutine(
         cx,
         args.parent_args(),
diff --git a/compiler/rustc_next_trait_solver/src/solve/effect_goals.rs b/compiler/rustc_next_trait_solver/src/solve/effect_goals.rs
index 7669a305d58..fb53e778e60 100644
--- a/compiler/rustc_next_trait_solver/src/solve/effect_goals.rs
+++ b/compiler/rustc_next_trait_solver/src/solve/effect_goals.rs
@@ -248,10 +248,11 @@ where
 
         let pred = inputs_and_output
             .map_bound(|(inputs, _)| {
-                ty::TraitRef::new(cx, goal.predicate.def_id(), [
-                    goal.predicate.self_ty(),
-                    Ty::new_tup(cx, inputs.as_slice()),
-                ])
+                ty::TraitRef::new(
+                    cx,
+                    goal.predicate.def_id(),
+                    [goal.predicate.self_ty(), Ty::new_tup(cx, inputs.as_slice())],
+                )
             })
             .to_host_effect_clause(cx, goal.predicate.constness);
 
diff --git a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/canonical.rs b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/canonical.rs
index e99cd3d2727..2491f09a0e2 100644
--- a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/canonical.rs
+++ b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/canonical.rs
@@ -60,13 +60,16 @@ where
             (goal, opaque_types).fold_with(&mut EagerResolver::new(self.delegate));
 
         let mut orig_values = Default::default();
-        let canonical =
-            Canonicalizer::canonicalize_input(self.delegate, &mut orig_values, QueryInput {
+        let canonical = Canonicalizer::canonicalize_input(
+            self.delegate,
+            &mut orig_values,
+            QueryInput {
                 goal,
                 predefined_opaques_in_body: self
                     .cx()
                     .mk_predefined_opaques_in_body(PredefinedOpaquesData { opaque_types }),
-            });
+            },
+        );
         let query_input = ty::CanonicalQueryInput { canonical, typing_mode: self.typing_mode() };
         (orig_values, query_input)
     }
@@ -142,7 +145,7 @@ where
         // Remove any trivial region constraints once we've resolved regions
         external_constraints
             .region_constraints
-            .retain(|outlives| outlives.0.as_region().map_or(true, |re| re != outlives.1));
+            .retain(|outlives| outlives.0.as_region().is_none_or(|re| re != outlives.1));
 
         let canonical = Canonicalizer::canonicalize_response(
             self.delegate,
@@ -255,20 +258,29 @@ where
             self.delegate,
             &original_values,
             &response,
+            self.origin_span,
         );
 
         let Response { var_values, external_constraints, certainty } =
             self.delegate.instantiate_canonical(response, instantiation);
 
-        Self::unify_query_var_values(self.delegate, param_env, &original_values, var_values);
+        Self::unify_query_var_values(
+            self.delegate,
+            param_env,
+            &original_values,
+            var_values,
+            self.origin_span,
+        );
 
         let ExternalConstraintsData {
             region_constraints,
             opaque_types,
             normalization_nested_goals,
         } = &*external_constraints;
+
         self.register_region_constraints(region_constraints);
         self.register_new_opaque_types(opaque_types);
+
         (normalization_nested_goals.clone(), certainty)
     }
 
@@ -279,6 +291,7 @@ where
         delegate: &D,
         original_values: &[I::GenericArg],
         response: &Canonical<I, T>,
+        span: I::Span,
     ) -> CanonicalVarValues<I> {
         // FIXME: Longterm canonical queries should deal with all placeholders
         // created inside of the query directly instead of returning them to the
@@ -331,7 +344,7 @@ where
                     // A variable from inside a binder of the query. While ideally these shouldn't
                     // exist at all (see the FIXME at the start of this method), we have to deal with
                     // them for now.
-                    delegate.instantiate_canonical_var_with_infer(info, |idx| {
+                    delegate.instantiate_canonical_var_with_infer(info, span, |idx| {
                         ty::UniverseIndex::from(prev_universe.index() + idx.index())
                     })
                 } else if info.is_existential() {
@@ -345,7 +358,7 @@ where
                     if let Some(v) = opt_values[ty::BoundVar::from_usize(index)] {
                         v
                     } else {
-                        delegate.instantiate_canonical_var_with_infer(info, |_| prev_universe)
+                        delegate.instantiate_canonical_var_with_infer(info, span, |_| prev_universe)
                     }
                 } else {
                     // For placeholders which were already part of the input, we simply map this
@@ -376,12 +389,13 @@ where
         param_env: I::ParamEnv,
         original_values: &[I::GenericArg],
         var_values: CanonicalVarValues<I>,
+        span: I::Span,
     ) {
         assert_eq!(original_values.len(), var_values.len());
 
         for (&orig, response) in iter::zip(original_values, var_values.var_values.iter()) {
             let goals =
-                delegate.eq_structurally_relating_aliases(param_env, orig, response).unwrap();
+                delegate.eq_structurally_relating_aliases(param_env, orig, response, span).unwrap();
             assert!(goals.is_empty());
         }
     }
@@ -401,7 +415,7 @@ where
 
     fn register_new_opaque_types(&mut self, opaque_types: &[(ty::OpaqueTypeKey<I>, I::Ty)]) {
         for &(key, ty) in opaque_types {
-            self.delegate.inject_new_hidden_type_unchecked(key, ty);
+            self.delegate.inject_new_hidden_type_unchecked(key, ty, self.origin_span);
         }
     }
 }
@@ -431,7 +445,7 @@ where
 // `rustc_trait_selection::solve::inspect::analyse`.
 pub fn instantiate_canonical_state<D, I, T: TypeFoldable<I>>(
     delegate: &D,
-    span: D::Span,
+    span: I::Span,
     param_env: I::ParamEnv,
     orig_values: &mut Vec<I::GenericArg>,
     state: inspect::CanonicalState<I, T>,
@@ -442,19 +456,17 @@ where
 {
     // In case any fresh inference variables have been created between `state`
     // and the previous instantiation, extend `orig_values` for it.
-    assert!(orig_values.len() <= state.value.var_values.len());
-    for &arg in &state.value.var_values.var_values.as_slice()
-        [orig_values.len()..state.value.var_values.len()]
-    {
-        let unconstrained = delegate.fresh_var_for_kind_with_span(arg, span);
-        orig_values.push(unconstrained);
-    }
+    orig_values.extend(
+        state.value.var_values.var_values.as_slice()[orig_values.len()..]
+            .iter()
+            .map(|&arg| delegate.fresh_var_for_kind_with_span(arg, span)),
+    );
 
     let instantiation =
-        EvalCtxt::compute_query_response_instantiation_values(delegate, orig_values, &state);
+        EvalCtxt::compute_query_response_instantiation_values(delegate, orig_values, &state, span);
 
     let inspect::State { var_values, data } = delegate.instantiate_canonical(state, instantiation);
 
-    EvalCtxt::unify_query_var_values(delegate, param_env, orig_values, var_values);
+    EvalCtxt::unify_query_var_values(delegate, param_env, orig_values, var_values, span);
     data
 }
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 91ad24bff67..b0a34b9ce75 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
@@ -78,6 +78,8 @@ where
 
     nested_goals: NestedGoals<I>,
 
+    pub(super) origin_span: I::Span,
+
     // Has this `EvalCtxt` errored out with `NoSolution` in `try_evaluate_added_goals`?
     //
     // If so, then it can no longer be used to make a canonical query response,
@@ -134,6 +136,7 @@ pub trait SolverDelegateEvalExt: SolverDelegate {
         &self,
         goal: Goal<Self::Interner, <Self::Interner as Interner>::Predicate>,
         generate_proof_tree: GenerateProofTree,
+        span: <Self::Interner as Interner>::Span,
     ) -> (
         Result<(HasChanged, Certainty), NoSolution>,
         Option<inspect::GoalEvaluation<Self::Interner>>,
@@ -174,8 +177,9 @@ where
         &self,
         goal: Goal<I, I::Predicate>,
         generate_proof_tree: GenerateProofTree,
+        span: I::Span,
     ) -> (Result<(HasChanged, Certainty), NoSolution>, Option<inspect::GoalEvaluation<I>>) {
-        EvalCtxt::enter_root(self, self.cx().recursion_limit(), generate_proof_tree, |ecx| {
+        EvalCtxt::enter_root(self, self.cx().recursion_limit(), generate_proof_tree, span, |ecx| {
             ecx.evaluate_goal(GoalEvaluationKind::Root, GoalSource::Misc, goal)
         })
     }
@@ -186,7 +190,7 @@ where
         goal: Goal<Self::Interner, <Self::Interner as Interner>::Predicate>,
     ) -> bool {
         self.probe(|| {
-            EvalCtxt::enter_root(self, root_depth, GenerateProofTree::No, |ecx| {
+            EvalCtxt::enter_root(self, root_depth, GenerateProofTree::No, I::Span::dummy(), |ecx| {
                 ecx.evaluate_goal(GoalEvaluationKind::Root, GoalSource::Misc, goal)
             })
             .0
@@ -203,9 +207,13 @@ where
         Result<(NestedNormalizationGoals<I>, HasChanged, Certainty), NoSolution>,
         Option<inspect::GoalEvaluation<I>>,
     ) {
-        EvalCtxt::enter_root(self, self.cx().recursion_limit(), generate_proof_tree, |ecx| {
-            ecx.evaluate_goal_raw(GoalEvaluationKind::Root, GoalSource::Misc, goal)
-        })
+        EvalCtxt::enter_root(
+            self,
+            self.cx().recursion_limit(),
+            generate_proof_tree,
+            I::Span::dummy(),
+            |ecx| ecx.evaluate_goal_raw(GoalEvaluationKind::Root, GoalSource::Misc, goal),
+        )
     }
 }
 
@@ -229,6 +237,7 @@ where
         delegate: &D,
         root_depth: usize,
         generate_proof_tree: GenerateProofTree,
+        origin_span: I::Span,
         f: impl FnOnce(&mut EvalCtxt<'_, D>) -> R,
     ) -> (R, Option<inspect::GoalEvaluation<I>>) {
         let mut search_graph = SearchGraph::new(root_depth);
@@ -248,6 +257,7 @@ where
             variables: Default::default(),
             var_values: CanonicalVarValues::dummy(),
             is_normalizes_to_goal: false,
+            origin_span,
             tainted: Ok(()),
         };
         let result = f(&mut ecx);
@@ -289,12 +299,13 @@ where
             max_input_universe: canonical_input.canonical.max_universe,
             search_graph,
             nested_goals: NestedGoals::new(),
+            origin_span: I::Span::dummy(),
             tainted: Ok(()),
             inspect: canonical_goal_evaluation.new_goal_evaluation_step(var_values),
         };
 
         for &(key, ty) in &input.predefined_opaques_in_body.opaque_types {
-            ecx.delegate.inject_new_hidden_type_unchecked(key, ty);
+            ecx.delegate.inject_new_hidden_type_unchecked(key, ty, ecx.origin_span);
         }
 
         if !ecx.nested_goals.is_empty() {
@@ -537,10 +548,10 @@ where
             // Replace the goal with an unconstrained infer var, so the
             // RHS does not affect projection candidate assembly.
             let unconstrained_rhs = self.next_term_infer_of_kind(goal.predicate.term);
-            let unconstrained_goal = goal.with(cx, ty::NormalizesTo {
-                alias: goal.predicate.alias,
-                term: unconstrained_rhs,
-            });
+            let unconstrained_goal = goal.with(
+                cx,
+                ty::NormalizesTo { alias: goal.predicate.alias, term: unconstrained_rhs },
+            );
 
             let (NestedNormalizationGoals(nested_goals), _, certainty) = self.evaluate_goal_raw(
                 GoalEvaluationKind::Nested,
@@ -822,8 +833,12 @@ where
             let identity_args = self.fresh_args_for_item(alias.def_id);
             let rigid_ctor = ty::AliasTerm::new_from_args(cx, alias.def_id, identity_args);
             let ctor_term = rigid_ctor.to_term(cx);
-            let obligations =
-                self.delegate.eq_structurally_relating_aliases(param_env, term, ctor_term)?;
+            let obligations = self.delegate.eq_structurally_relating_aliases(
+                param_env,
+                term,
+                ctor_term,
+                self.origin_span,
+            )?;
             debug_assert!(obligations.is_empty());
             self.relate(param_env, alias, variance, rigid_ctor)
         } else {
@@ -841,7 +856,12 @@ where
         lhs: T,
         rhs: T,
     ) -> Result<(), NoSolution> {
-        let result = self.delegate.eq_structurally_relating_aliases(param_env, lhs, rhs)?;
+        let result = self.delegate.eq_structurally_relating_aliases(
+            param_env,
+            lhs,
+            rhs,
+            self.origin_span,
+        )?;
         assert_eq!(result, vec![]);
         Ok(())
     }
@@ -864,7 +884,7 @@ where
         variance: ty::Variance,
         rhs: T,
     ) -> Result<(), NoSolution> {
-        let goals = self.delegate.relate(param_env, lhs, variance, rhs)?;
+        let goals = self.delegate.relate(param_env, lhs, variance, rhs, self.origin_span)?;
         self.add_goals(GoalSource::Misc, goals);
         Ok(())
     }
@@ -881,7 +901,7 @@ where
         lhs: T,
         rhs: T,
     ) -> Result<Vec<Goal<I, I::Predicate>>, NoSolution> {
-        Ok(self.delegate.relate(param_env, lhs, ty::Variance::Invariant, rhs)?)
+        Ok(self.delegate.relate(param_env, lhs, ty::Variance::Invariant, rhs, self.origin_span)?)
     }
 
     pub(super) fn instantiate_binder_with_infer<T: TypeFoldable<I> + Copy>(
@@ -917,12 +937,12 @@ where
     }
 
     pub(super) fn register_ty_outlives(&self, ty: I::Ty, lt: I::Region) {
-        self.delegate.register_ty_outlives(ty, lt);
+        self.delegate.register_ty_outlives(ty, lt, self.origin_span);
     }
 
     pub(super) fn register_region_outlives(&self, a: I::Region, b: I::Region) {
         // `b : a` ==> `a <= b`
-        self.delegate.sub_regions(b, a);
+        self.delegate.sub_regions(b, a, self.origin_span);
     }
 
     /// Computes the list of goals required for `arg` to be well-formed
diff --git a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/probe.rs b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/probe.rs
index be69a6e84ea..add96a1fdf7 100644
--- a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/probe.rs
+++ b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/probe.rs
@@ -39,6 +39,7 @@ where
             max_input_universe,
             search_graph: outer_ecx.search_graph,
             nested_goals: outer_ecx.nested_goals.clone(),
+            origin_span: outer_ecx.origin_span,
             tainted: outer_ecx.tainted,
             inspect: outer_ecx.inspect.take_and_enter_probe(),
         };
diff --git a/compiler/rustc_next_trait_solver/src/solve/mod.rs b/compiler/rustc_next_trait_solver/src/solve/mod.rs
index 8d1194ee539..1fa35b60304 100644
--- a/compiler/rustc_next_trait_solver/src/solve/mod.rs
+++ b/compiler/rustc_next_trait_solver/src/solve/mod.rs
@@ -160,9 +160,7 @@ where
             ty::ConstKind::Infer(_) => {
                 self.evaluate_added_goals_and_make_canonical_response(Certainty::AMBIGUOUS)
             }
-            ty::ConstKind::Placeholder(_)
-            | ty::ConstKind::Value(_, _)
-            | ty::ConstKind::Error(_) => {
+            ty::ConstKind::Placeholder(_) | ty::ConstKind::Value(_) | ty::ConstKind::Error(_) => {
                 self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
             }
             // We can freely ICE here as:
@@ -199,7 +197,7 @@ where
                 unreachable!("`ConstKind::Param` should have been canonicalized to `Placeholder`")
             }
             ty::ConstKind::Bound(_, _) => panic!("escaping bound vars in {:?}", ct),
-            ty::ConstKind::Value(ty, _) => ty,
+            ty::ConstKind::Value(cv) => cv.ty(),
             ty::ConstKind::Placeholder(placeholder) => {
                 self.cx().find_const_ty_from_env(goal.param_env, placeholder)
             }
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 76cbe5758b2..c8ea0b119ff 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
@@ -398,10 +398,11 @@ where
 
         let pred = tupled_inputs_and_output
             .map_bound(|(inputs, output)| ty::ProjectionPredicate {
-                projection_term: ty::AliasTerm::new(cx, goal.predicate.def_id(), [
-                    goal.predicate.self_ty(),
-                    inputs,
-                ]),
+                projection_term: ty::AliasTerm::new(
+                    cx,
+                    goal.predicate.def_id(),
+                    [goal.predicate.self_ty(), inputs],
+                ),
                 term: output.into(),
             })
             .upcast(cx);
@@ -454,21 +455,26 @@ where
                         .is_lang_item(goal.predicate.def_id(), TraitSolverLangItem::CallOnceFuture)
                     {
                         (
-                            ty::AliasTerm::new(cx, goal.predicate.def_id(), [
-                                goal.predicate.self_ty(),
-                                tupled_inputs_ty,
-                            ]),
+                            ty::AliasTerm::new(
+                                cx,
+                                goal.predicate.def_id(),
+                                [goal.predicate.self_ty(), tupled_inputs_ty],
+                            ),
                             output_coroutine_ty.into(),
                         )
                     } else if cx
                         .is_lang_item(goal.predicate.def_id(), TraitSolverLangItem::CallRefFuture)
                     {
                         (
-                            ty::AliasTerm::new(cx, goal.predicate.def_id(), [
-                                I::GenericArg::from(goal.predicate.self_ty()),
-                                tupled_inputs_ty.into(),
-                                env_region.into(),
-                            ]),
+                            ty::AliasTerm::new(
+                                cx,
+                                goal.predicate.def_id(),
+                                [
+                                    I::GenericArg::from(goal.predicate.self_ty()),
+                                    tupled_inputs_ty.into(),
+                                    env_region.into(),
+                                ],
+                            ),
                             output_coroutine_ty.into(),
                         )
                     } else if cx.is_lang_item(
@@ -476,10 +482,14 @@ where
                         TraitSolverLangItem::AsyncFnOnceOutput,
                     ) {
                         (
-                            ty::AliasTerm::new(cx, goal.predicate.def_id(), [
-                                I::GenericArg::from(goal.predicate.self_ty()),
-                                tupled_inputs_ty.into(),
-                            ]),
+                            ty::AliasTerm::new(
+                                cx,
+                                goal.predicate.def_id(),
+                                [
+                                    I::GenericArg::from(goal.predicate.self_ty()),
+                                    tupled_inputs_ty.into(),
+                                ],
+                            ),
                             coroutine_return_ty.into(),
                         )
                     } else {
@@ -603,10 +613,11 @@ where
                     // and opaque types: If the `self_ty` is `Sized`, then the metadata is `()`.
                     // FIXME(ptr_metadata): This impl overlaps with the other impls and shouldn't
                     // exist. Instead, `Pointee<Metadata = ()>` should be a supertrait of `Sized`.
-                    let sized_predicate =
-                        ty::TraitRef::new(cx, cx.require_lang_item(TraitSolverLangItem::Sized), [
-                            I::GenericArg::from(goal.predicate.self_ty()),
-                        ]);
+                    let sized_predicate = ty::TraitRef::new(
+                        cx,
+                        cx.require_lang_item(TraitSolverLangItem::Sized),
+                        [I::GenericArg::from(goal.predicate.self_ty())],
+                    );
                     // FIXME(-Znext-solver=coinductive): Should this be `GoalSource::ImplWhereBound`?
                     ecx.add_goal(GoalSource::Misc, goal.with(cx, sized_predicate));
                     Ty::new_unit(cx)
@@ -782,10 +793,11 @@ where
             CandidateSource::BuiltinImpl(BuiltinImplSource::Misc),
             goal,
             ty::ProjectionPredicate {
-                projection_term: ty::AliasTerm::new(ecx.cx(), goal.predicate.def_id(), [
-                    self_ty,
-                    coroutine.resume_ty(),
-                ]),
+                projection_term: ty::AliasTerm::new(
+                    ecx.cx(),
+                    goal.predicate.def_id(),
+                    [self_ty, coroutine.resume_ty()],
+                ),
                 term,
             }
             .upcast(cx),
diff --git a/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs b/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs
index 4faa243c02a..46fae5c6fa4 100644
--- a/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs
+++ b/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs
@@ -8,7 +8,6 @@ use rustc_type_ir::lang_items::TraitSolverLangItem;
 use rustc_type_ir::solve::CanonicalResponse;
 use rustc_type_ir::visit::TypeVisitableExt as _;
 use rustc_type_ir::{self as ty, Interner, TraitPredicate, TypingMode, Upcast as _, elaborate};
-use smallvec::SmallVec;
 use tracing::{instrument, trace};
 
 use crate::delegate::SolverDelegate;
@@ -343,18 +342,21 @@ where
         // (FIXME: technically we only need to check this if the type is a fn ptr...)
         let output_is_sized_pred = tupled_inputs_and_output_and_coroutine.map_bound(
             |AsyncCallableRelevantTypes { output_coroutine_ty, .. }| {
-                ty::TraitRef::new(cx, cx.require_lang_item(TraitSolverLangItem::Sized), [
-                    output_coroutine_ty,
-                ])
+                ty::TraitRef::new(
+                    cx,
+                    cx.require_lang_item(TraitSolverLangItem::Sized),
+                    [output_coroutine_ty],
+                )
             },
         );
 
         let pred = tupled_inputs_and_output_and_coroutine
             .map_bound(|AsyncCallableRelevantTypes { tupled_inputs_ty, .. }| {
-                ty::TraitRef::new(cx, goal.predicate.def_id(), [
-                    goal.predicate.self_ty(),
-                    tupled_inputs_ty,
-                ])
+                ty::TraitRef::new(
+                    cx,
+                    goal.predicate.def_id(),
+                    [goal.predicate.self_ty(), tupled_inputs_ty],
+                )
             })
             .upcast(cx);
         Self::probe_and_consider_implied_clause(
@@ -976,9 +978,11 @@ where
             GoalSource::ImplWhereBound,
             goal.with(
                 cx,
-                ty::TraitRef::new(cx, cx.require_lang_item(TraitSolverLangItem::Unsize), [
-                    a_tail_ty, b_tail_ty,
-                ]),
+                ty::TraitRef::new(
+                    cx,
+                    cx.require_lang_item(TraitSolverLangItem::Unsize),
+                    [a_tail_ty, b_tail_ty],
+                ),
             ),
         );
         self.probe_builtin_trait_candidate(BuiltinImplSource::Misc)
@@ -1016,9 +1020,11 @@ where
             GoalSource::ImplWhereBound,
             goal.with(
                 cx,
-                ty::TraitRef::new(cx, cx.require_lang_item(TraitSolverLangItem::Unsize), [
-                    a_last_ty, b_last_ty,
-                ]),
+                ty::TraitRef::new(
+                    cx,
+                    cx.require_lang_item(TraitSolverLangItem::Unsize),
+                    [a_last_ty, b_last_ty],
+                ),
             ),
         );
         self.probe_builtin_trait_candidate(BuiltinImplSource::TupleUnsizing)
@@ -1199,33 +1205,42 @@ where
         // nested requirements, over all others. This is a fix for #53123 and
         // prevents where-bounds from accidentally extending the lifetime of a
         // variable.
-        if candidates
-            .iter()
-            .any(|c| matches!(c.source, CandidateSource::BuiltinImpl(BuiltinImplSource::Trivial)))
-        {
-            let trivial_builtin_impls: SmallVec<[_; 1]> = candidates
-                .iter()
-                .filter(|c| {
-                    matches!(c.source, CandidateSource::BuiltinImpl(BuiltinImplSource::Trivial))
-                })
-                .map(|c| c.result)
-                .collect();
+        let mut trivial_builtin_impls = candidates.iter().filter(|c| {
+            matches!(c.source, CandidateSource::BuiltinImpl(BuiltinImplSource::Trivial))
+        });
+        if let Some(candidate) = trivial_builtin_impls.next() {
             // There should only ever be a single trivial builtin candidate
             // as they would otherwise overlap.
-            assert_eq!(trivial_builtin_impls.len(), 1);
-            return if let Some(response) = self.try_merge_responses(&trivial_builtin_impls) {
-                Ok((response, Some(TraitGoalProvenVia::Misc)))
-            } else {
-                Ok((self.bail_with_ambiguity(&trivial_builtin_impls), None))
-            };
+            assert!(trivial_builtin_impls.next().is_none());
+            return Ok((candidate.result, Some(TraitGoalProvenVia::Misc)));
         }
 
         // If there are non-global where-bounds, prefer where-bounds
         // (including global ones) over everything else.
         let has_non_global_where_bounds = candidates.iter().any(|c| match c.source {
             CandidateSource::ParamEnv(idx) => {
-                let where_bound = goal.param_env.caller_bounds().get(idx);
-                where_bound.has_bound_vars() || !where_bound.is_global()
+                let where_bound = goal.param_env.caller_bounds().get(idx).unwrap();
+                let ty::ClauseKind::Trait(trait_pred) = where_bound.kind().skip_binder() else {
+                    unreachable!("expected trait-bound: {where_bound:?}");
+                };
+
+                if trait_pred.has_bound_vars() || !trait_pred.is_global() {
+                    return true;
+                }
+
+                // We don't consider a trait-bound global if it has a projection bound.
+                //
+                // See ui/traits/next-solver/normalization-shadowing/global-trait-with-project.rs
+                // for an example where this is necessary.
+                for p in goal.param_env.caller_bounds().iter() {
+                    if let ty::ClauseKind::Projection(proj) = p.kind().skip_binder() {
+                        if proj.projection_term.trait_ref(self.cx()) == trait_pred.trait_ref {
+                            return true;
+                        }
+                    }
+                }
+
+                false
             }
             _ => false,
         });