rustc_infer/infer/
projection.rs

1use rustc_middle::traits::ObligationCause;
2use rustc_middle::ty;
3
4use super::InferCtxt;
5use crate::infer::Term;
6use crate::traits::{Obligation, PredicateObligations};
7
8impl<'tcx> InferCtxt<'tcx> {
9    /// Instead of normalizing an associated type projection,
10    /// this function generates an inference variable and registers
11    /// an obligation that this inference variable must be the result
12    /// of the given projection. This allows us to proceed with projections
13    /// while they cannot be resolved yet due to missing information or
14    /// simply due to the lack of access to the trait resolution machinery.
15    pub fn projection_term_to_infer(
16        &self,
17        param_env: ty::ParamEnv<'tcx>,
18        alias_term: ty::AliasTerm<'tcx>,
19        cause: ObligationCause<'tcx>,
20        recursion_depth: usize,
21        obligations: &mut PredicateObligations<'tcx>,
22    ) -> Term<'tcx> {
23        debug_assert!(!self.next_trait_solver());
24
25        let span = self.tcx.def_span(alias_term.def_id);
26        let infer_var = if alias_term.kind(self.tcx).is_type() {
27            self.next_ty_var(span).into()
28        } else {
29            self.next_const_var(span).into()
30        };
31
32        let projection =
33            ty::PredicateKind::Clause(ty::ClauseKind::Projection(ty::ProjectionPredicate {
34                projection_term: alias_term,
35                term: infer_var,
36            }));
37        let obligation =
38            Obligation::with_depth(self.tcx, cause, recursion_depth, param_env, projection);
39        obligations.push(obligation);
40
41        infer_var
42    }
43}