From dfb11a8a265d967e55c5515e78e741dfdba4db4d Mon Sep 17 00:00:00 2001
From: Oli Scherer <github35764891676564198441@oli-obk.de>
Date: Tue, 10 Aug 2021 11:12:11 +0000
Subject: [PATCH] Add helper function to `InferCtxt` that generates inference
 vars for unresolved associated types

---
 compiler/rustc_infer/src/infer/mod.rs         |  1 +
 compiler/rustc_infer/src/infer/projection.rs  | 33 +++++++++++++++++++
 .../src/traits/project.rs                     | 12 +------
 3 files changed, 35 insertions(+), 11 deletions(-)
 create mode 100644 compiler/rustc_infer/src/infer/projection.rs

diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs
index 354b8e26d53..43d3730c049 100644
--- a/compiler/rustc_infer/src/infer/mod.rs
+++ b/compiler/rustc_infer/src/infer/mod.rs
@@ -64,6 +64,7 @@ mod lub;
 pub mod nll_relate;
 pub mod opaque_types;
 pub mod outlives;
+mod projection;
 pub mod region_constraints;
 pub mod resolve;
 mod sub;
diff --git a/compiler/rustc_infer/src/infer/projection.rs b/compiler/rustc_infer/src/infer/projection.rs
new file mode 100644
index 00000000000..aa0fddf9b6f
--- /dev/null
+++ b/compiler/rustc_infer/src/infer/projection.rs
@@ -0,0 +1,33 @@
+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> {
+    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, ty: ty_var });
+        let obligation = Obligation::with_depth(
+            cause,
+            recursion_depth,
+            param_env,
+            projection.to_predicate(self.tcx),
+        );
+        obligations.push(obligation);
+        ty_var
+    }
+}
diff --git a/compiler/rustc_trait_selection/src/traits/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs
index 4f22543950c..873c058c55c 100644
--- a/compiler/rustc_trait_selection/src/traits/project.rs
+++ b/compiler/rustc_trait_selection/src/traits/project.rs
@@ -810,17 +810,7 @@ pub fn normalize_projection_type<'a, 'b, 'tcx>(
         // and a deferred predicate to resolve this when more type
         // information is available.
 
-        let tcx = selcx.infcx().tcx;
-        let def_id = projection_ty.item_def_id;
-        let ty_var = selcx.infcx().next_ty_var(TypeVariableOrigin {
-            kind: TypeVariableOriginKind::NormalizeProjectionType,
-            span: tcx.def_span(def_id),
-        });
-        let projection = ty::Binder::dummy(ty::ProjectionPredicate { projection_ty, ty: ty_var });
-        let obligation =
-            Obligation::with_depth(cause, depth + 1, param_env, projection.to_predicate(tcx));
-        obligations.push(obligation);
-        ty_var
+        selcx.infcx().infer_projection(param_env, projection_ty, cause, depth + 1, obligations)
     })
 }