Elaborate comment, make sure we do normalizes-to hack eventually for IATs, don't partially support const projection for impls
This commit is contained in:
parent
8912015f71
commit
84196f3371
@ -25,29 +25,39 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
|
|||||||
let def_id = goal.predicate.def_id();
|
let def_id = goal.predicate.def_id();
|
||||||
match self.tcx().def_kind(def_id) {
|
match self.tcx().def_kind(def_id) {
|
||||||
DefKind::AssocTy | DefKind::AssocConst => {
|
DefKind::AssocTy | DefKind::AssocConst => {
|
||||||
match self.tcx().associated_item(def_id).container {
|
// To only compute normalization once for each projection we only
|
||||||
ty::AssocItemContainer::TraitContainer => {
|
// assemble normalization candidates if the expected term is an
|
||||||
// To only compute normalization once for each projection we only
|
// unconstrained inference variable.
|
||||||
// normalize if the expected term is an unconstrained inference variable.
|
//
|
||||||
//
|
// Why: For better cache hits, since if we have an unconstrained RHS then
|
||||||
// E.g. for `<T as Trait>::Assoc == u32` we recursively compute the goal
|
// there are only as many cache keys as there are (canonicalized) alias
|
||||||
// `exists<U> <T as Trait>::Assoc == U` and then take the resulting type for
|
// types in each normalizes-to goal. This also weakens inference in a
|
||||||
// `U` and equate it with `u32`. This means that we don't need a separate
|
// forwards-compatible way so we don't use the value of the RHS term to
|
||||||
// projection cache in the solver.
|
// affect candidate assembly for projections.
|
||||||
if self.term_is_fully_unconstrained(goal) {
|
//
|
||||||
|
// E.g. for `<T as Trait>::Assoc == u32` we recursively compute the goal
|
||||||
|
// `exists<U> <T as Trait>::Assoc == U` and then take the resulting type for
|
||||||
|
// `U` and equate it with `u32`. This means that we don't need a separate
|
||||||
|
// projection cache in the solver, since we're piggybacking off of regular
|
||||||
|
// goal caching.
|
||||||
|
if self.term_is_fully_unconstrained(goal) {
|
||||||
|
match self.tcx().associated_item(def_id).container {
|
||||||
|
ty::AssocItemContainer::TraitContainer => {
|
||||||
let candidates = self.assemble_and_evaluate_candidates(goal);
|
let candidates = self.assemble_and_evaluate_candidates(goal);
|
||||||
self.merge_candidates(candidates)
|
self.merge_candidates(candidates)
|
||||||
} else {
|
}
|
||||||
self.set_normalizes_to_hack_goal(goal);
|
ty::AssocItemContainer::ImplContainer => {
|
||||||
self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
|
bug!("IATs not supported here yet")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ty::AssocItemContainer::ImplContainer => bug!("IATs not supported here yet"),
|
} else {
|
||||||
|
self.set_normalizes_to_hack_goal(goal);
|
||||||
|
self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
DefKind::AnonConst => self.normalize_anon_const(goal),
|
DefKind::AnonConst => self.normalize_anon_const(goal),
|
||||||
DefKind::OpaqueTy => self.normalize_opaque_type(goal),
|
DefKind::OpaqueTy => self.normalize_opaque_type(goal),
|
||||||
kind => bug!("uknown DefKind {} in projection goal: {goal:#?}", kind.descr(def_id)),
|
kind => bug!("unknown DefKind {} in projection goal: {goal:#?}", kind.descr(def_id)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -203,17 +213,10 @@ impl<'tcx> assembly::GoalKind<'tcx> for ProjectionPredicate<'tcx> {
|
|||||||
);
|
);
|
||||||
|
|
||||||
// Finally we construct the actual value of the associated type.
|
// Finally we construct the actual value of the associated type.
|
||||||
let is_const = matches!(tcx.def_kind(assoc_def.item.def_id), DefKind::AssocConst);
|
let term = match assoc_def.item.kind {
|
||||||
let ty = tcx.type_of(assoc_def.item.def_id);
|
ty::AssocKind::Type => tcx.type_of(assoc_def.item.def_id).map_bound(|ty| ty.into()),
|
||||||
let term: ty::EarlyBinder<ty::Term<'tcx>> = if is_const {
|
ty::AssocKind::Const => bug!("associated const projection is not supported yet"),
|
||||||
let identity_substs =
|
ty::AssocKind::Fn => unreachable!("we should never project to a fn"),
|
||||||
ty::InternalSubsts::identity_for_item(tcx, assoc_def.item.def_id);
|
|
||||||
let did = assoc_def.item.def_id;
|
|
||||||
let kind =
|
|
||||||
ty::ConstKind::Unevaluated(ty::UnevaluatedConst::new(did, identity_substs));
|
|
||||||
ty.map_bound(|ty| tcx.mk_const(kind, ty).into())
|
|
||||||
} else {
|
|
||||||
ty.map_bound(|ty| ty.into())
|
|
||||||
};
|
};
|
||||||
|
|
||||||
ecx.eq(goal.param_env, goal.predicate.term, term.subst(tcx, substs))
|
ecx.eq(goal.param_env, goal.predicate.term, term.subst(tcx, substs))
|
||||||
|
Loading…
x
Reference in New Issue
Block a user