1
Fork 0

Introduce structurally_normalize_const, use it in hir_typeck

This commit is contained in:
Michael Goulet 2024-09-22 13:10:12 -04:00
parent 0af7f0f4c4
commit 3b8089a320
8 changed files with 122 additions and 39 deletions

View file

@ -46,4 +46,44 @@ impl<'tcx> At<'_, 'tcx> {
Ok(self.normalize(ty).into_value_registering_obligations(self.infcx, fulfill_cx))
}
}
fn structurally_normalize_const<E: 'tcx>(
&self,
ct: ty::Const<'tcx>,
fulfill_cx: &mut dyn TraitEngine<'tcx, E>,
) -> Result<ty::Const<'tcx>, Vec<E>> {
assert!(!ct.is_ct_infer(), "should have resolved vars before calling");
if self.infcx.next_trait_solver() {
let ty::ConstKind::Unevaluated(..) = ct.kind() else {
return Ok(ct);
};
let new_infer_ct = self.infcx.next_const_var(self.cause.span);
// We simply emit an `alias-eq` goal here, since that will take care of
// normalizing the LHS of the projection until it is a rigid projection
// (or a not-yet-defined opaque in scope).
let obligation = Obligation::new(
self.infcx.tcx,
self.cause.clone(),
self.param_env,
ty::PredicateKind::AliasRelate(
ct.into(),
new_infer_ct.into(),
ty::AliasRelationDirection::Equate,
),
);
fulfill_cx.register_predicate_obligation(self.infcx, obligation);
let errors = fulfill_cx.select_where_possible(self.infcx);
if !errors.is_empty() {
return Err(errors);
}
Ok(self.infcx.resolve_vars_if_possible(new_infer_ct))
} else {
Ok(self.normalize(ct).into_value_registering_obligations(self.infcx, fulfill_cx))
}
}
}