diff options
Diffstat (limited to '')
-rw-r--r-- | compiler/rustc_infer/src/infer/projection.rs | 40 |
1 files changed, 40 insertions, 0 deletions
diff --git a/compiler/rustc_infer/src/infer/projection.rs b/compiler/rustc_infer/src/infer/projection.rs new file mode 100644 index 000000000..b45a6514d --- /dev/null +++ b/compiler/rustc_infer/src/infer/projection.rs @@ -0,0 +1,40 @@ +use rustc_middle::traits::ObligationCause; +use rustc_middle::ty::{self, ToPredicate, Ty}; + +use crate::traits::{Obligation, PredicateObligation}; + +use super::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; +use super::InferCtxt; + +impl<'a, 'tcx> InferCtxt<'a, 'tcx> { + /// Instead of normalizing an associated type projection, + /// this function generates an inference variable and registers + /// an obligation that this inference variable must be the result + /// of the given projection. This allows us to proceed with projections + /// while they cannot be resolved yet due to missing information or + /// simply due to the lack of access to the trait resolution machinery. + pub fn infer_projection( + &self, + param_env: ty::ParamEnv<'tcx>, + projection_ty: ty::ProjectionTy<'tcx>, + cause: ObligationCause<'tcx>, + recursion_depth: usize, + obligations: &mut Vec<PredicateObligation<'tcx>>, + ) -> Ty<'tcx> { + let def_id = projection_ty.item_def_id; + let ty_var = self.next_ty_var(TypeVariableOrigin { + kind: TypeVariableOriginKind::NormalizeProjectionType, + span: self.tcx.def_span(def_id), + }); + let projection = + ty::Binder::dummy(ty::ProjectionPredicate { projection_ty, term: ty_var.into() }); + let obligation = Obligation::with_depth( + cause, + recursion_depth, + param_env, + projection.to_predicate(self.tcx), + ); + obligations.push(obligation); + ty_var + } +} |