about summary refs log tree commit diff
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
parent2bf63a50115efad7a474e50b7a4330b506da2578 (diff)
downloadrust-7f933de1946b49960e6522d6520d9a065fdb8a8d.tar.gz
rust-7f933de1946b49960e6522d6520d9a065fdb8a8d.zip
Merge two duplicates of the same logic into a common function
-rw-r--r--compiler/rustc_infer/src/infer/opaque_types.rs45
-rw-r--r--compiler/rustc_typeck/src/check/check.rs50
-rw-r--r--compiler/rustc_typeck/src/check/closure.rs37
3 files changed, 56 insertions, 76 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>,
diff --git a/compiler/rustc_typeck/src/check/check.rs b/compiler/rustc_typeck/src/check/check.rs
index ee93a8ce535..5362ca8d719 100644
--- a/compiler/rustc_typeck/src/check/check.rs
+++ b/compiler/rustc_typeck/src/check/check.rs
@@ -3,7 +3,6 @@ use super::compare_method::check_type_bounds;
 use super::compare_method::{compare_const_impl, compare_impl_method, compare_ty_impl};
 use super::*;
 
-use hir::OpaqueTyOrigin;
 use rustc_attr as attr;
 use rustc_errors::{Applicability, ErrorGuaranteed};
 use rustc_hir as hir;
@@ -13,9 +12,8 @@ use rustc_hir::lang_items::LangItem;
 use rustc_hir::{def::Res, ItemKind, Node, PathSegment};
 use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
 use rustc_infer::infer::{RegionVariableOrigin, TyCtxtInferExt};
-use rustc_infer::traits::ObligationCause;
 use rustc_middle::hir::nested_filter;
-use rustc_middle::ty::fold::{BottomUpFolder, TypeFoldable};
+use rustc_middle::ty::fold::TypeFoldable;
 use rustc_middle::ty::layout::{LayoutError, MAX_SIMD_LANES};
 use rustc_middle::ty::subst::GenericArgKind;
 use rustc_middle::ty::util::{Discr, IntTypeExt};
@@ -97,45 +95,13 @@ pub(super) fn check_fn<'a, 'tcx>(
 
     let declared_ret_ty = fn_sig.output();
 
-    let ret_ty = declared_ret_ty.fold_with(&mut BottomUpFolder {
-        tcx: fcx.tcx,
-        ty_op: |ty| match *ty.kind() {
-            ty::Opaque(def_id, substs) => {
-                let span = tcx.def_span(def_id);
-                if let Some(origin @ OpaqueTyOrigin::FnReturn(_)) =
-                    fcx.infcx.opaque_type_origin(def_id, span)
-                {
-                    let hidden_ty = fcx.infcx.next_ty_var(TypeVariableOrigin {
-                        kind: TypeVariableOriginKind::MiscVariable,
-                        span: span,
-                    });
-
-                    let cause = ObligationCause::misc(span, body.value.hir_id);
-                    match fcx.infcx.register_hidden_type(
-                        ty::OpaqueTypeKey { def_id, substs },
-                        cause.clone(),
-                        param_env,
-                        hidden_ty,
-                        origin,
-                    ) {
-                        Ok(infer_ok) => {
-                            fcx.register_infer_ok_obligations(infer_ok);
-                            hidden_ty
-                        }
-                        Err(err) => {
-                            fcx.report_mismatched_types(&cause, ty, hidden_ty, err).emit();
-                            tcx.ty_error()
-                        }
-                    }
-                } else {
-                    ty
-                }
-            }
-            _ => ty,
-        },
-        lt_op: |lt| lt,
-        ct_op: |ct| ct,
-    });
+    let ret_ty =
+        fcx.register_infer_ok_obligations(fcx.infcx.replace_opaque_types_with_inference_vars(
+            declared_ret_ty,
+            body.value.hir_id,
+            DUMMY_SP,
+            param_env,
+        ));
     fcx.ret_coercion = Some(RefCell::new(CoerceMany::new(ret_ty)));
     fcx.ret_type_span = Some(decl.output.span());
 
diff --git a/compiler/rustc_typeck/src/check/closure.rs b/compiler/rustc_typeck/src/check/closure.rs
index 709622edb76..2f5f804c56f 100644
--- a/compiler/rustc_typeck/src/check/closure.rs
+++ b/compiler/rustc_typeck/src/check/closure.rs
@@ -4,14 +4,12 @@ use super::{check_fn, Expectation, FnCtxt, GeneratorTypes};
 
 use crate::astconv::AstConv;
 use crate::rustc_middle::ty::subst::Subst;
-use hir::OpaqueTyOrigin;
 use rustc_hir as hir;
 use rustc_hir::def_id::DefId;
 use rustc_hir::lang_items::LangItem;
 use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
 use rustc_infer::infer::LateBoundRegionConversionTime;
 use rustc_infer::infer::{InferOk, InferResult};
-use rustc_infer::traits::ObligationCause;
 use rustc_middle::ty::fold::TypeFoldable;
 use rustc_middle::ty::subst::InternalSubsts;
 use rustc_middle::ty::{self, Ty};
@@ -641,37 +639,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     }
 
     fn hide_parent_opaque_types(&self, ty: Ty<'tcx>, span: Span, body_id: hir::HirId) -> Ty<'tcx> {
-        ty.fold_with(&mut ty::fold::BottomUpFolder {
-            tcx: self.infcx.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.infcx.opaque_type_origin(def_id, DUMMY_SP),
-                        Some(OpaqueTyOrigin::FnReturn(..))
-                    ) =>
-                {
-                    let ty_var = self.next_ty_var(TypeVariableOrigin {
-                        kind: TypeVariableOriginKind::TypeInference,
-                        span,
-                    });
-                    let cause = ObligationCause::misc(span, body_id);
-                    self.register_predicates(
-                        self.infcx
-                            .handle_opaque_type(ty, ty_var, true, &cause, self.param_env)
-                            .unwrap()
-                            .obligations,
-                    );
-                    ty_var
-                }
-                _ => ty,
-            },
-        })
+        let InferOk { value, obligations } =
+            self.replace_opaque_types_with_inference_vars(ty, body_id, span, self.param_env);
+        self.register_predicates(obligations);
+        value
     }
 
     /// Invoked when we are translating the generator that results