mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-27 01:04:03 +00:00
Merge two duplicates of the same logic into a common function
This commit is contained in:
parent
2bf63a5011
commit
7f933de194
@ -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>,
|
||||
|
@ -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());
|
||||
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user