diff options
| author | Michael Goulet <michael@errs.io> | 2025-05-07 16:27:48 +0000 |
|---|---|---|
| committer | Michael Goulet <michael@errs.io> | 2025-05-07 16:29:49 +0000 |
| commit | 8a21d1b495556554dc4ee55338423870b4f7dd53 (patch) | |
| tree | 724c6307cb394125d666d334c3f4f268cdd54a0f | |
| parent | 1f774d74b3858154564f8f1609c21f618ba28d96 (diff) | |
| download | rust-8a21d1b495556554dc4ee55338423870b4f7dd53.tar.gz rust-8a21d1b495556554dc4ee55338423870b4f7dd53.zip | |
Review
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 /// |
