Make const trait aliases work in next solver

This commit is contained in:
Oli Scherer
2025-07-21 13:57:44 +00:00
committed by Oli Scherer
parent 8b122f1e11
commit 544a5a3e0e
5 changed files with 45 additions and 46 deletions

View File

@@ -1031,9 +1031,11 @@ pub(super) fn const_conditions<'tcx>(
Node::Item(item) => match item.kind {
hir::ItemKind::Impl(impl_) => (impl_.generics, None, false),
hir::ItemKind::Fn { generics, .. } => (generics, None, false),
hir::ItemKind::TraitAlias(_, _, generics, supertraits)
| hir::ItemKind::Trait(_, _, _, _, generics, supertraits, _) => {
(generics, Some((item.owner_id.def_id, supertraits)), false)
hir::ItemKind::Trait(_, _, _, _, generics, supertraits, _) => {
(generics, Some((Some(item.owner_id.def_id), supertraits)), false)
}
hir::ItemKind::TraitAlias(_, _, generics, supertraits) => {
(generics, Some((None, supertraits)), false)
}
_ => bug!("const_conditions called on wrong item: {def_id:?}"),
},
@@ -1090,12 +1092,14 @@ pub(super) fn const_conditions<'tcx>(
}
if let Some((def_id, supertraits)) = trait_def_id_and_supertraits {
// We've checked above that the trait is conditionally const.
bounds.push((
ty::Binder::dummy(ty::TraitRef::identity(tcx, def_id.to_def_id()))
.to_host_effect_clause(tcx, ty::BoundConstness::Maybe),
DUMMY_SP,
));
if let Some(def_id) = def_id {
// We've checked above that the trait is conditionally const.
bounds.push((
ty::Binder::dummy(ty::TraitRef::identity(tcx, def_id.to_def_id()))
.to_host_effect_clause(tcx, ty::BoundConstness::Maybe),
DUMMY_SP,
));
}
icx.lowerer().lower_bounds(
tcx.types.self_param,

View File

@@ -196,10 +196,35 @@ where
}
fn consider_trait_alias_candidate(
_ecx: &mut EvalCtxt<'_, D>,
_goal: Goal<I, Self>,
ecx: &mut EvalCtxt<'_, D>,
goal: Goal<I, Self>,
) -> Result<Candidate<I>, NoSolution> {
unreachable!("trait aliases are never const")
let cx = ecx.cx();
ecx.probe_builtin_trait_candidate(BuiltinImplSource::Misc).enter(|ecx| {
let where_clause_bounds = cx
.predicates_of(goal.predicate.def_id().into())
.iter_instantiated(cx, goal.predicate.trait_ref.args)
.map(|p| goal.with(cx, p));
let const_conditions = cx
.const_conditions(goal.predicate.def_id().into())
.iter_instantiated(cx, goal.predicate.trait_ref.args)
.map(|bound_trait_ref| {
goal.with(
cx,
bound_trait_ref.to_host_effect_clause(cx, goal.predicate.constness),
)
});
// While you could think of trait aliases to have a single builtin impl
// which uses its implied trait bounds as where-clauses, using
// `GoalSource::ImplWhereClause` here would be incorrect, as we also
// impl them, which means we're "stepping out of the impl constructor"
// again. To handle this, we treat these cycles as ambiguous for now.
ecx.add_goals(GoalSource::Misc, where_clause_bounds);
ecx.add_goals(GoalSource::Misc, const_conditions);
ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
})
}
fn consider_builtin_sizedness_candidates(