about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMichael Goulet <michael@errs.io>2025-05-07 16:27:48 +0000
committerMichael Goulet <michael@errs.io>2025-05-07 16:29:49 +0000
commit8a21d1b495556554dc4ee55338423870b4f7dd53 (patch)
tree724c6307cb394125d666d334c3f4f268cdd54a0f
parent1f774d74b3858154564f8f1609c21f618ba28d96 (diff)
downloadrust-8a21d1b495556554dc4ee55338423870b4f7dd53.tar.gz
rust-8a21d1b495556554dc4ee55338423870b4f7dd53.zip
Review
-rw-r--r--compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs24
-rw-r--r--compiler/rustc_next_trait_solver/src/solve/effect_goals.rs4
-rw-r--r--compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs12
-rw-r--r--compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs4
-rw-r--r--compiler/rustc_next_trait_solver/src/solve/trait_goals.rs4
-rw-r--r--compiler/rustc_type_ir/src/solve/mod.rs5
6 files changed, 29 insertions, 24 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 0cc46a0670e..345a272895d 100644
--- a/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs
+++ b/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs
@@ -123,7 +123,7 @@ where
                 result: Ok(candidate.result),
             },
             Err(NoSolution) => inspect::ProbeKind::TraitCandidate {
-                source: CandidateSource::BuiltinImpl(BuiltinImplSource::Misc),
+                source: CandidateSource::ParamEnv(ParamEnvSource::Global),
                 result: Err(NoSolution),
             },
         })
@@ -157,7 +157,7 @@ where
     }
 
     /// Try to reject the assumption based off of simple heuristics, such as [`ty::ClauseKind`]
-    /// and [`I::DefId`].
+    /// and `DefId`.
     fn fast_reject_assumption(
         ecx: &mut EvalCtxt<'_, D>,
         goal: Goal<I, Self>,
@@ -990,12 +990,26 @@ where
         }
     }
 
+    /// Compute whether a param-env assumption is global or non-global after normalizing it.
+    ///
+    /// This is necessary because, for example, given:
+    ///
+    /// ```ignore,rust
+    /// where
+    ///     T: Trait<Assoc = u32>,
+    ///     i32: From<T::Assoc>,
+    /// ```
+    ///
+    /// The `i32: From<T::Assoc>` bound is non-global before normalization, but is global after.
+    /// Since the old trait solver normalized param-envs eagerly, we want to emulate this
+    /// behavior lazily.
     fn characterize_param_env_assumption(
         &mut self,
         param_env: I::ParamEnv,
         assumption: I::Clause,
     ) -> Result<CandidateSource<I>, NoSolution> {
-        // FIXME:
+        // FIXME: This should be fixed, but it also requires changing the behavior
+        // in the old solver which is currently relied on.
         if assumption.has_bound_vars() {
             return Ok(CandidateSource::ParamEnv(ParamEnvSource::NonGlobal));
         }
@@ -1030,7 +1044,6 @@ where
         let Ok(ty) = self.ecx.structurally_normalize_ty(self.param_env, ty) else {
             return ControlFlow::Break(Err(NoSolution));
         };
-        let ty = self.ecx.eager_resolve(ty);
 
         if let ty::Placeholder(_) = ty.kind() {
             ControlFlow::Break(Ok(()))
@@ -1043,7 +1056,6 @@ where
         let Ok(ct) = self.ecx.structurally_normalize_const(self.param_env, ct) else {
             return ControlFlow::Break(Err(NoSolution));
         };
-        let ct = self.ecx.eager_resolve(ct);
 
         if let ty::ConstKind::Placeholder(_) = ct.kind() {
             ControlFlow::Break(Ok(()))
@@ -1053,7 +1065,7 @@ where
     }
 
     fn visit_region(&mut self, r: I::Region) -> Self::Result {
-        match r.kind() {
+        match self.ecx.eager_resolve_region(r).kind() {
             ty::ReStatic | ty::ReError(_) => ControlFlow::Continue(()),
             ty::ReVar(_) | ty::RePlaceholder(_) => ControlFlow::Break(Ok(())),
             ty::ReErased | ty::ReEarlyParam(_) | ty::ReLateParam(_) | ty::ReBound(..) => {
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 ab0ba100553..84a83d79cf0 100644
--- a/compiler/rustc_next_trait_solver/src/solve/effect_goals.rs
+++ b/compiler/rustc_next_trait_solver/src/solve/effect_goals.rs
@@ -62,9 +62,7 @@ where
         goal: Goal<I, Self>,
         assumption: I::Clause,
     ) -> Result<(), NoSolution> {
-        let Some(host_clause) = assumption.as_host_effect_clause() else {
-            panic!("fast_reject_assumption should have avoided this");
-        };
+        let host_clause = assumption.as_host_effect_clause().unwrap();
 
         let assumption_trait_pred = ecx.instantiate_binder_with_infer(host_clause);
         ecx.eq(goal.param_env, goal.predicate.trait_ref, assumption_trait_pred.trait_ref)?;
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 4a9daad1746..bf9f21d05f6 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
@@ -19,7 +19,6 @@ use tracing::{debug, instrument, trace};
 use super::has_only_region_constraints;
 use crate::coherence;
 use crate::delegate::SolverDelegate;
-use crate::resolve::EagerResolver;
 use crate::solve::inspect::{self, ProofTreeBuilder};
 use crate::solve::search_graph::SearchGraph;
 use crate::solve::{
@@ -1001,11 +1000,12 @@ where
         self.delegate.resolve_vars_if_possible(value)
     }
 
-    pub(super) fn eager_resolve<T>(&self, value: T) -> T
-    where
-        T: TypeFoldable<I>,
-    {
-        value.fold_with(&mut EagerResolver::new(self.delegate))
+    pub(super) fn eager_resolve_region(&self, r: I::Region) -> I::Region {
+        if let ty::ReVar(vid) = r.kind() {
+            self.delegate.opportunistic_resolve_lt_var(vid)
+        } else {
+            r
+        }
     }
 
     pub(super) fn fresh_args_for_item(&mut self, def_id: I::DefId) -> I::GenericArgs {
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 9c17a15bb0e..b90e34e7810 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
@@ -130,9 +130,7 @@ where
         goal: Goal<I, Self>,
         assumption: I::Clause,
     ) -> Result<(), NoSolution> {
-        let Some(projection_pred) = assumption.as_projection_clause() else {
-            panic!("fast_reject_assumption should have avoided this");
-        };
+        let projection_pred = assumption.as_projection_clause().unwrap();
 
         let assumption_projection_pred = ecx.instantiate_binder_with_infer(projection_pred);
         ecx.eq(goal.param_env, goal.predicate.alias, assumption_projection_pred.projection_term)?;
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 4d42bb137f0..e3addf8bf93 100644
--- a/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs
+++ b/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs
@@ -151,9 +151,7 @@ where
         goal: Goal<I, Self>,
         assumption: I::Clause,
     ) -> Result<(), NoSolution> {
-        let Some(trait_clause) = assumption.as_trait_clause() else {
-            panic!("fast_reject_assumption should have avoided this");
-        };
+        let trait_clause = assumption.as_trait_clause().unwrap();
 
         let assumption_trait_pred = ecx.instantiate_binder_with_infer(trait_clause);
         ecx.eq(goal.param_env, goal.predicate.trait_ref, assumption_trait_pred.trait_ref)?;
diff --git a/compiler/rustc_type_ir/src/solve/mod.rs b/compiler/rustc_type_ir/src/solve/mod.rs
index 994ec2b341d..e45a7b7fbc1 100644
--- a/compiler/rustc_type_ir/src/solve/mod.rs
+++ b/compiler/rustc_type_ir/src/solve/mod.rs
@@ -147,9 +147,8 @@ pub enum CandidateSource<I: Interner> {
     /// For a list of all traits with builtin impls, check out the
     /// `EvalCtxt::assemble_builtin_impl_candidates` method.
     BuiltinImpl(BuiltinImplSource),
-    /// An assumption from the environment.
-    ///
-    /// More precisely we've used the `n-th` assumption in the `param_env`.
+    /// An assumption from the environment. Stores a [`ParamEnvSource`], since we
+    /// prefer non-global param-env candidates in candidate assembly.
     ///
     /// ## Examples
     ///