about summary refs log tree commit diff
path: root/compiler/rustc_infer
diff options
context:
space:
mode:
authorOli Scherer <git-spam-no-reply9815368754983@oli-obk.de>2022-02-17 14:49:45 +0000
committerOli Scherer <git-spam-no-reply9815368754983@oli-obk.de>2022-03-28 16:59:11 +0000
commit7f933de1946b49960e6522d6520d9a065fdb8a8d (patch)
tree30f79e91fd1e34ff6b322bbefc887edbb1579ad0 /compiler/rustc_infer
parent2bf63a50115efad7a474e50b7a4330b506da2578 (diff)
downloadrust-7f933de1946b49960e6522d6520d9a065fdb8a8d.tar.gz
rust-7f933de1946b49960e6522d6520d9a065fdb8a8d.zip
Merge two duplicates of the same logic into a common function
Diffstat (limited to 'compiler/rustc_infer')
-rw-r--r--compiler/rustc_infer/src/infer/opaque_types.rs45
1 files changed, 44 insertions, 1 deletions
diff --git a/compiler/rustc_infer/src/infer/opaque_types.rs b/compiler/rustc_infer/src/infer/opaque_types.rs
index b2f62637cf2..5920d12a93c 100644
--- a/compiler/rustc_infer/src/infer/opaque_types.rs
+++ b/compiler/rustc_infer/src/infer/opaque_types.rs
@@ -1,7 +1,7 @@
 use crate::infer::{InferCtxt, InferOk};
 use crate::traits;
 use hir::def_id::{DefId, LocalDefId};
-use hir::OpaqueTyOrigin;
+use hir::{HirId, OpaqueTyOrigin};
 use rustc_data_structures::sync::Lrc;
 use rustc_data_structures::vec_map::VecMap;
 use rustc_hir as hir;
@@ -21,6 +21,7 @@ mod table;
 
 pub use table::{OpaqueTypeStorage, OpaqueTypeTable};
 
+use super::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
 use super::InferResult;
 
 /// Information about the opaque types whose values we
@@ -38,6 +39,48 @@ pub struct OpaqueTypeDecl<'tcx> {
 }
 
 impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
+    pub fn replace_opaque_types_with_inference_vars(
+        &self,
+        ty: Ty<'tcx>,
+        body_id: HirId,
+        span: Span,
+        param_env: ty::ParamEnv<'tcx>,
+    ) -> InferOk<'tcx, Ty<'tcx>> {
+        let mut obligations = vec![];
+        let value = ty.fold_with(&mut ty::fold::BottomUpFolder {
+            tcx: self.tcx,
+            lt_op: |lt| lt,
+            ct_op: |ct| ct,
+            ty_op: |ty| match *ty.kind() {
+                // Closures can't create hidden types for opaque types of their parent, as they
+                // do not have all the outlives information available. Also `type_of` looks for
+                // hidden types in the owner (so the closure's parent), so it would not find these
+                // definitions.
+                ty::Opaque(def_id, _substs)
+                    if matches!(
+                        self.opaque_type_origin(def_id, span),
+                        Some(OpaqueTyOrigin::FnReturn(..))
+                    ) =>
+                {
+                    let span = if span.is_dummy() { self.tcx.def_span(def_id) } else { span };
+                    let cause = ObligationCause::misc(span, body_id);
+                    let ty_var = self.next_ty_var(TypeVariableOrigin {
+                        kind: TypeVariableOriginKind::TypeInference,
+                        span: cause.span,
+                    });
+                    obligations.extend(
+                        self.handle_opaque_type(ty, ty_var, true, &cause, param_env)
+                            .unwrap()
+                            .obligations,
+                    );
+                    ty_var
+                }
+                _ => ty,
+            },
+        });
+        InferOk { value, obligations }
+    }
+
     pub fn handle_opaque_type(
         &self,
         a: Ty<'tcx>,