1
Fork 0

Merge two duplicates of the same logic into a common function

This commit is contained in:
Oli Scherer 2022-02-17 14:49:45 +00:00
parent 2bf63a5011
commit 7f933de194
3 changed files with 56 additions and 76 deletions

View file

@ -1,7 +1,7 @@
use crate::infer::{InferCtxt, InferOk}; use crate::infer::{InferCtxt, InferOk};
use crate::traits; use crate::traits;
use hir::def_id::{DefId, LocalDefId}; use hir::def_id::{DefId, LocalDefId};
use hir::OpaqueTyOrigin; use hir::{HirId, OpaqueTyOrigin};
use rustc_data_structures::sync::Lrc; use rustc_data_structures::sync::Lrc;
use rustc_data_structures::vec_map::VecMap; use rustc_data_structures::vec_map::VecMap;
use rustc_hir as hir; use rustc_hir as hir;
@ -21,6 +21,7 @@ mod table;
pub use table::{OpaqueTypeStorage, OpaqueTypeTable}; pub use table::{OpaqueTypeStorage, OpaqueTypeTable};
use super::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
use super::InferResult; use super::InferResult;
/// Information about the opaque types whose values we /// Information about the opaque types whose values we
@ -38,6 +39,48 @@ pub struct OpaqueTypeDecl<'tcx> {
} }
impl<'a, 'tcx> InferCtxt<'a, '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( pub fn handle_opaque_type(
&self, &self,
a: Ty<'tcx>, a: Ty<'tcx>,

View file

@ -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::compare_method::{compare_const_impl, compare_impl_method, compare_ty_impl};
use super::*; use super::*;
use hir::OpaqueTyOrigin;
use rustc_attr as attr; use rustc_attr as attr;
use rustc_errors::{Applicability, ErrorGuaranteed}; use rustc_errors::{Applicability, ErrorGuaranteed};
use rustc_hir as hir; 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_hir::{def::Res, ItemKind, Node, PathSegment};
use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
use rustc_infer::infer::{RegionVariableOrigin, TyCtxtInferExt}; use rustc_infer::infer::{RegionVariableOrigin, TyCtxtInferExt};
use rustc_infer::traits::ObligationCause;
use rustc_middle::hir::nested_filter; 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::layout::{LayoutError, MAX_SIMD_LANES};
use rustc_middle::ty::subst::GenericArgKind; use rustc_middle::ty::subst::GenericArgKind;
use rustc_middle::ty::util::{Discr, IntTypeExt}; 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 declared_ret_ty = fn_sig.output();
let ret_ty = declared_ret_ty.fold_with(&mut BottomUpFolder { let ret_ty =
tcx: fcx.tcx, fcx.register_infer_ok_obligations(fcx.infcx.replace_opaque_types_with_inference_vars(
ty_op: |ty| match *ty.kind() { declared_ret_ty,
ty::Opaque(def_id, substs) => { body.value.hir_id,
let span = tcx.def_span(def_id); DUMMY_SP,
if let Some(origin @ OpaqueTyOrigin::FnReturn(_)) = param_env,
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,
});
fcx.ret_coercion = Some(RefCell::new(CoerceMany::new(ret_ty))); fcx.ret_coercion = Some(RefCell::new(CoerceMany::new(ret_ty)));
fcx.ret_type_span = Some(decl.output.span()); fcx.ret_type_span = Some(decl.output.span());

View file

@ -4,14 +4,12 @@ use super::{check_fn, Expectation, FnCtxt, GeneratorTypes};
use crate::astconv::AstConv; use crate::astconv::AstConv;
use crate::rustc_middle::ty::subst::Subst; use crate::rustc_middle::ty::subst::Subst;
use hir::OpaqueTyOrigin;
use rustc_hir as hir; use rustc_hir as hir;
use rustc_hir::def_id::DefId; use rustc_hir::def_id::DefId;
use rustc_hir::lang_items::LangItem; use rustc_hir::lang_items::LangItem;
use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
use rustc_infer::infer::LateBoundRegionConversionTime; use rustc_infer::infer::LateBoundRegionConversionTime;
use rustc_infer::infer::{InferOk, InferResult}; use rustc_infer::infer::{InferOk, InferResult};
use rustc_infer::traits::ObligationCause;
use rustc_middle::ty::fold::TypeFoldable; use rustc_middle::ty::fold::TypeFoldable;
use rustc_middle::ty::subst::InternalSubsts; use rustc_middle::ty::subst::InternalSubsts;
use rustc_middle::ty::{self, Ty}; 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> { fn hide_parent_opaque_types(&self, ty: Ty<'tcx>, span: Span, body_id: hir::HirId) -> Ty<'tcx> {
ty.fold_with(&mut ty::fold::BottomUpFolder { let InferOk { value, obligations } =
tcx: self.infcx.tcx, self.replace_opaque_types_with_inference_vars(ty, body_id, span, self.param_env);
lt_op: |lt| lt, self.register_predicates(obligations);
ct_op: |ct| ct, value
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,
},
})
} }
/// Invoked when we are translating the generator that results /// Invoked when we are translating the generator that results