• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 use rustc_infer::infer::canonical::{Canonical, QueryResponse};
2 use rustc_infer::infer::TyCtxtInferExt;
3 use rustc_middle::query::Providers;
4 use rustc_middle::ty::{ParamEnvAnd, TyCtxt};
5 use rustc_trait_selection::infer::InferCtxtBuilderExt;
6 use rustc_trait_selection::traits::query::{
7     normalize::NormalizationResult, CanonicalProjectionGoal, NoSolution,
8 };
9 use rustc_trait_selection::traits::{self, ObligationCause, SelectionContext};
10 use std::sync::atomic::Ordering;
11 
provide(p: &mut Providers)12 pub(crate) fn provide(p: &mut Providers) {
13     *p = Providers {
14         normalize_projection_ty,
15         normalize_weak_ty,
16         normalize_inherent_projection_ty,
17         ..*p
18     };
19 }
20 
normalize_projection_ty<'tcx>( tcx: TyCtxt<'tcx>, goal: CanonicalProjectionGoal<'tcx>, ) -> Result<&'tcx Canonical<'tcx, QueryResponse<'tcx, NormalizationResult<'tcx>>>, NoSolution>21 fn normalize_projection_ty<'tcx>(
22     tcx: TyCtxt<'tcx>,
23     goal: CanonicalProjectionGoal<'tcx>,
24 ) -> Result<&'tcx Canonical<'tcx, QueryResponse<'tcx, NormalizationResult<'tcx>>>, NoSolution> {
25     debug!("normalize_provider(goal={:#?})", goal);
26 
27     tcx.sess.perf_stats.normalize_projection_ty.fetch_add(1, Ordering::Relaxed);
28     tcx.infer_ctxt().enter_canonical_trait_query(
29         &goal,
30         |ocx, ParamEnvAnd { param_env, value: goal }| {
31             let selcx = &mut SelectionContext::new(ocx.infcx);
32             let cause = ObligationCause::dummy();
33             let mut obligations = vec![];
34             let answer = traits::normalize_projection_type(
35                 selcx,
36                 param_env,
37                 goal,
38                 cause,
39                 0,
40                 &mut obligations,
41             );
42             ocx.register_obligations(obligations);
43             // FIXME(associated_const_equality): All users of normalize_projection_ty expected
44             // a type, but there is the possibility it could've been a const now. Maybe change
45             // it to a Term later?
46             Ok(NormalizationResult { normalized_ty: answer.ty().unwrap() })
47         },
48     )
49 }
50 
normalize_weak_ty<'tcx>( tcx: TyCtxt<'tcx>, goal: CanonicalProjectionGoal<'tcx>, ) -> Result<&'tcx Canonical<'tcx, QueryResponse<'tcx, NormalizationResult<'tcx>>>, NoSolution>51 fn normalize_weak_ty<'tcx>(
52     tcx: TyCtxt<'tcx>,
53     goal: CanonicalProjectionGoal<'tcx>,
54 ) -> Result<&'tcx Canonical<'tcx, QueryResponse<'tcx, NormalizationResult<'tcx>>>, NoSolution> {
55     debug!("normalize_provider(goal={:#?})", goal);
56 
57     tcx.sess.perf_stats.normalize_projection_ty.fetch_add(1, Ordering::Relaxed);
58     tcx.infer_ctxt().enter_canonical_trait_query(
59         &goal,
60         |ocx, ParamEnvAnd { param_env, value: goal }| {
61             let obligations = tcx.predicates_of(goal.def_id).instantiate_own(tcx, goal.substs).map(
62                 |(predicate, span)| {
63                     traits::Obligation::new(
64                         tcx,
65                         ObligationCause::dummy_with_span(span),
66                         param_env,
67                         predicate,
68                     )
69                 },
70             );
71             ocx.register_obligations(obligations);
72             let normalized_ty = tcx.type_of(goal.def_id).subst(tcx, goal.substs);
73             Ok(NormalizationResult { normalized_ty })
74         },
75     )
76 }
77 
normalize_inherent_projection_ty<'tcx>( tcx: TyCtxt<'tcx>, goal: CanonicalProjectionGoal<'tcx>, ) -> Result<&'tcx Canonical<'tcx, QueryResponse<'tcx, NormalizationResult<'tcx>>>, NoSolution>78 fn normalize_inherent_projection_ty<'tcx>(
79     tcx: TyCtxt<'tcx>,
80     goal: CanonicalProjectionGoal<'tcx>,
81 ) -> Result<&'tcx Canonical<'tcx, QueryResponse<'tcx, NormalizationResult<'tcx>>>, NoSolution> {
82     debug!("normalize_provider(goal={:#?})", goal);
83 
84     tcx.infer_ctxt().enter_canonical_trait_query(
85         &goal,
86         |ocx, ParamEnvAnd { param_env, value: goal }| {
87             let selcx = &mut SelectionContext::new(ocx.infcx);
88             let cause = ObligationCause::dummy();
89             let mut obligations = vec![];
90             let answer = traits::normalize_inherent_projection(
91                 selcx,
92                 param_env,
93                 goal,
94                 cause,
95                 0,
96                 &mut obligations,
97             );
98             ocx.register_obligations(obligations);
99 
100             Ok(NormalizationResult { normalized_ty: answer })
101         },
102     )
103 }
104