From 7f933de1946b49960e6522d6520d9a065fdb8a8d Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Thu, 17 Feb 2022 14:49:45 +0000 Subject: [PATCH] Merge two duplicates of the same logic into a common function --- .../rustc_infer/src/infer/opaque_types.rs | 45 ++++++++++++++++- compiler/rustc_typeck/src/check/check.rs | 50 +++---------------- compiler/rustc_typeck/src/check/closure.rs | 37 ++------------ 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