hir_ty/next_solver/
structural_normalize.rs1use rustc_type_ir::{AliasRelationDirection, inherent::Term as _};
2
3use crate::next_solver::{
4 Const, PredicateKind, Term, Ty,
5 fulfill::{FulfillmentCtxt, NextSolverError},
6 infer::{at::At, traits::Obligation},
7};
8
9impl<'db> At<'_, 'db> {
10 pub(crate) fn structurally_normalize_ty(
11 &self,
12 ty: Ty<'db>,
13 fulfill_cx: &mut FulfillmentCtxt<'db>,
14 ) -> Result<Ty<'db>, Vec<NextSolverError<'db>>> {
15 self.structurally_normalize_term(ty.into(), fulfill_cx).map(|term| term.expect_type())
16 }
17
18 pub(crate) fn structurally_normalize_const(
19 &self,
20 ct: Const<'db>,
21 fulfill_cx: &mut FulfillmentCtxt<'db>,
22 ) -> Result<Const<'db>, Vec<NextSolverError<'db>>> {
23 self.structurally_normalize_term(ct.into(), fulfill_cx).map(|term| term.expect_const())
24 }
25
26 pub(crate) fn structurally_normalize_term(
27 &self,
28 term: Term<'db>,
29 fulfill_cx: &mut FulfillmentCtxt<'db>,
30 ) -> Result<Term<'db>, Vec<NextSolverError<'db>>> {
31 assert!(!term.is_infer(), "should have resolved vars before calling");
32
33 if term.to_alias_term(self.infcx.interner).is_none() {
34 return Ok(term);
35 }
36
37 let new_infer = self.infcx.next_term_var_of_kind(term, self.cause.span());
38
39 let obligation = Obligation::new(
43 self.infcx.interner,
44 *self.cause,
45 self.param_env,
46 PredicateKind::AliasRelate(term, new_infer, AliasRelationDirection::Equate),
47 );
48
49 fulfill_cx.register_predicate_obligation(self.infcx, obligation);
50 let errors = fulfill_cx.try_evaluate_obligations(self.infcx);
51 if !errors.is_empty() {
52 return Err(errors);
53 }
54
55 Ok(self.infcx.resolve_vars_if_possible(new_infer))
56 }
57}