diff options
Diffstat (limited to 'compiler')
4 files changed, 77 insertions, 1 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 5e604a5d74f..f6a5f20a639 100644 --- a/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs +++ b/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs @@ -100,6 +100,15 @@ where }) } + /// Assemble additional assumptions for an alias that are not included + /// in the item bounds of the alias. For now, this is limited to the + /// `implied_const_bounds` for an associated type. + fn consider_additional_alias_assumptions( + ecx: &mut EvalCtxt<'_, D>, + goal: Goal<I, Self>, + alias_ty: ty::AliasTy<I>, + ) -> Vec<Candidate<I>>; + fn consider_impl_candidate( ecx: &mut EvalCtxt<'_, D>, goal: Goal<I, Self>, @@ -594,6 +603,8 @@ where )); } + candidates.extend(G::consider_additional_alias_assumptions(self, goal, alias_ty)); + if kind != ty::Projection { return; } 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 62b4bb0004c..8d57ad8f255 100644 --- a/compiler/rustc_next_trait_solver/src/solve/effect_goals.rs +++ b/compiler/rustc_next_trait_solver/src/solve/effect_goals.rs @@ -3,7 +3,7 @@ use rustc_type_ir::fast_reject::DeepRejectCtxt; use rustc_type_ir::inherent::*; -use rustc_type_ir::{self as ty, Interner}; +use rustc_type_ir::{self as ty, Interner, elaborate}; use tracing::instrument; use super::assembly::Candidate; @@ -70,6 +70,55 @@ where } } + /// Register additional assumptions for aliases corresponding to `~const` item bounds. + /// + /// Unlike item bounds, they are not simply implied by the well-formedness of the alias. + /// Instead, they only hold if the const conditons on the alias also hold. This is why + /// we also register the const conditions of the alias after matching the goal against + /// the assumption. + fn consider_additional_alias_assumptions( + ecx: &mut EvalCtxt<'_, D>, + goal: Goal<I, Self>, + alias_ty: ty::AliasTy<I>, + ) -> Vec<Candidate<I>> { + let cx = ecx.cx(); + let mut candidates = vec![]; + + // FIXME(effects): We elaborate here because the implied const bounds + // aren't necessarily elaborated. We probably should prefix this query + // with `explicit_`... + for clause in elaborate::elaborate( + cx, + cx.implied_const_bounds(alias_ty.def_id) + .iter_instantiated(cx, alias_ty.args) + .map(|trait_ref| trait_ref.to_host_effect_clause(cx, goal.predicate.host)), + ) { + candidates.extend(Self::probe_and_match_goal_against_assumption( + ecx, + CandidateSource::AliasBound, + goal, + clause, + |ecx| { + // Const conditions must hold for the implied const bound to hold. + ecx.add_goals( + GoalSource::Misc, + cx.const_conditions(alias_ty.def_id) + .iter_instantiated(cx, alias_ty.args) + .map(|trait_ref| { + goal.with( + cx, + trait_ref.to_host_effect_clause(cx, goal.predicate.host), + ) + }), + ); + ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes) + }, + )); + } + + candidates + } + fn consider_impl_candidate( ecx: &mut EvalCtxt<'_, D>, goal: Goal<I, Self>, 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 c98fd853551..7287cdf74bf 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 @@ -193,6 +193,14 @@ where } } + fn consider_additional_alias_assumptions( + _ecx: &mut EvalCtxt<'_, D>, + _goal: Goal<I, Self>, + _alias_ty: ty::AliasTy<I>, + ) -> Vec<Candidate<I>> { + vec![] + } + fn consider_impl_candidate( ecx: &mut EvalCtxt<'_, D>, goal: Goal<I, NormalizesTo<I>>, 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 6b26f960286..08cc89d950e 100644 --- a/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs +++ b/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs @@ -39,6 +39,14 @@ where self.def_id() } + fn consider_additional_alias_assumptions( + _ecx: &mut EvalCtxt<'_, D>, + _goal: Goal<I, Self>, + _alias_ty: ty::AliasTy<I>, + ) -> Vec<Candidate<I>> { + vec![] + } + fn consider_impl_candidate( ecx: &mut EvalCtxt<'_, D>, goal: Goal<I, TraitPredicate<I>>, |
