Merge two duplicates of the same logic into a common function
This commit is contained in:
parent
2bf63a5011
commit
7f933de194
3 changed files with 56 additions and 76 deletions
|
@ -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>,
|
||||||
|
|
|
@ -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());
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue