Make OpaqueTypeKey the key of opaque types map
This commit is contained in:
parent
3405725e00
commit
7f8cad2019
10 changed files with 134 additions and 98 deletions
|
@ -9,6 +9,7 @@ use rustc_hir as hir;
|
||||||
use rustc_hir::def_id::{DefId, LocalDefId};
|
use rustc_hir::def_id::{DefId, LocalDefId};
|
||||||
use rustc_index::bit_set::BitMatrix;
|
use rustc_index::bit_set::BitMatrix;
|
||||||
use rustc_index::vec::IndexVec;
|
use rustc_index::vec::IndexVec;
|
||||||
|
use rustc_middle::ty::OpaqueTypeKey;
|
||||||
use rustc_span::Span;
|
use rustc_span::Span;
|
||||||
use rustc_target::abi::VariantIdx;
|
use rustc_target::abi::VariantIdx;
|
||||||
use smallvec::SmallVec;
|
use smallvec::SmallVec;
|
||||||
|
@ -210,7 +211,7 @@ pub struct BorrowCheckResult<'tcx> {
|
||||||
/// All the opaque types that are restricted to concrete types
|
/// All the opaque types that are restricted to concrete types
|
||||||
/// by this function. Unlike the value in `TypeckResults`, this has
|
/// by this function. Unlike the value in `TypeckResults`, this has
|
||||||
/// unerased regions.
|
/// unerased regions.
|
||||||
pub concrete_opaque_types: VecMap<DefId, ty::ResolvedOpaqueTy<'tcx>>,
|
pub concrete_opaque_types: VecMap<OpaqueTypeKey<'tcx>, ty::ResolvedOpaqueTy<'tcx>>,
|
||||||
pub closure_requirements: Option<ClosureRegionRequirements<'tcx>>,
|
pub closure_requirements: Option<ClosureRegionRequirements<'tcx>>,
|
||||||
pub used_mut_upvars: SmallVec<[Field; 8]>,
|
pub used_mut_upvars: SmallVec<[Field; 8]>,
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,6 +48,7 @@ use rustc_hir::{
|
||||||
use rustc_index::vec::{Idx, IndexVec};
|
use rustc_index::vec::{Idx, IndexVec};
|
||||||
use rustc_macros::HashStable;
|
use rustc_macros::HashStable;
|
||||||
use rustc_middle::mir::FakeReadCause;
|
use rustc_middle::mir::FakeReadCause;
|
||||||
|
use rustc_middle::ty::OpaqueTypeKey;
|
||||||
use rustc_serialize::opaque::{FileEncodeResult, FileEncoder};
|
use rustc_serialize::opaque::{FileEncodeResult, FileEncoder};
|
||||||
use rustc_session::config::{BorrowckMode, CrateType, OutputFilenames};
|
use rustc_session::config::{BorrowckMode, CrateType, OutputFilenames};
|
||||||
use rustc_session::lint::{Level, Lint};
|
use rustc_session::lint::{Level, Lint};
|
||||||
|
@ -425,7 +426,7 @@ pub struct TypeckResults<'tcx> {
|
||||||
|
|
||||||
/// All the opaque types that are restricted to concrete types
|
/// All the opaque types that are restricted to concrete types
|
||||||
/// by this function.
|
/// by this function.
|
||||||
pub concrete_opaque_types: VecMap<DefId, ResolvedOpaqueTy<'tcx>>,
|
pub concrete_opaque_types: VecMap<OpaqueTypeKey<'tcx>, ResolvedOpaqueTy<'tcx>>,
|
||||||
|
|
||||||
/// Tracks the minimum captures required for a closure;
|
/// Tracks the minimum captures required for a closure;
|
||||||
/// see `MinCaptureInformationMap` for more details.
|
/// see `MinCaptureInformationMap` for more details.
|
||||||
|
|
|
@ -835,6 +835,12 @@ impl<'tcx> InstantiatedPredicates<'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Copy, Clone, Debug, PartialEq, Eq, HashStable, TyEncodable, TyDecodable)]
|
||||||
|
pub struct OpaqueTypeKey<'tcx> {
|
||||||
|
pub def_id: DefId,
|
||||||
|
pub substs: SubstsRef<'tcx>,
|
||||||
|
}
|
||||||
|
|
||||||
rustc_index::newtype_index! {
|
rustc_index::newtype_index! {
|
||||||
/// "Universes" are used during type- and trait-checking in the
|
/// "Universes" are used during type- and trait-checking in the
|
||||||
/// presence of `for<..>` binders to control what sets of names are
|
/// presence of `for<..>` binders to control what sets of names are
|
||||||
|
|
|
@ -2,7 +2,6 @@
|
||||||
|
|
||||||
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
|
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
|
||||||
use rustc_data_structures::graph::dominators::Dominators;
|
use rustc_data_structures::graph::dominators::Dominators;
|
||||||
use rustc_data_structures::vec_map::VecMap;
|
|
||||||
use rustc_errors::{Applicability, Diagnostic, DiagnosticBuilder, ErrorReported};
|
use rustc_errors::{Applicability, Diagnostic, DiagnosticBuilder, ErrorReported};
|
||||||
use rustc_hir as hir;
|
use rustc_hir as hir;
|
||||||
use rustc_hir::def_id::LocalDefId;
|
use rustc_hir::def_id::LocalDefId;
|
||||||
|
@ -26,7 +25,7 @@ use either::Either;
|
||||||
use smallvec::SmallVec;
|
use smallvec::SmallVec;
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
use std::collections::BTreeMap;
|
use std::collections::BTreeMap;
|
||||||
use std::iter::{self, FromIterator};
|
use std::iter;
|
||||||
use std::mem;
|
use std::mem;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
|
||||||
|
@ -442,7 +441,7 @@ fn do_mir_borrowck<'a, 'tcx>(
|
||||||
}
|
}
|
||||||
|
|
||||||
let result = BorrowCheckResult {
|
let result = BorrowCheckResult {
|
||||||
concrete_opaque_types: VecMap::from_iter(opaque_type_values.into_iter()),
|
concrete_opaque_types: opaque_type_values,
|
||||||
closure_requirements: opt_closure_req,
|
closure_requirements: opt_closure_req,
|
||||||
used_mut_upvars: mbcx.used_mut_upvars,
|
used_mut_upvars: mbcx.used_mut_upvars,
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,15 +1,14 @@
|
||||||
//! The entry point of the NLL borrow checker.
|
//! The entry point of the NLL borrow checker.
|
||||||
|
|
||||||
use rustc_data_structures::fx::FxHashMap;
|
use rustc_data_structures::vec_map::VecMap;
|
||||||
use rustc_errors::Diagnostic;
|
use rustc_errors::Diagnostic;
|
||||||
use rustc_hir::def_id::DefId;
|
|
||||||
use rustc_index::vec::IndexVec;
|
use rustc_index::vec::IndexVec;
|
||||||
use rustc_infer::infer::InferCtxt;
|
use rustc_infer::infer::InferCtxt;
|
||||||
use rustc_middle::mir::{
|
use rustc_middle::mir::{
|
||||||
BasicBlock, Body, ClosureOutlivesSubject, ClosureRegionRequirements, LocalKind, Location,
|
BasicBlock, Body, ClosureOutlivesSubject, ClosureRegionRequirements, LocalKind, Location,
|
||||||
Promoted,
|
Promoted,
|
||||||
};
|
};
|
||||||
use rustc_middle::ty::{self, RegionKind, RegionVid};
|
use rustc_middle::ty::{self, OpaqueTypeKey, RegionKind, RegionVid};
|
||||||
use rustc_span::symbol::sym;
|
use rustc_span::symbol::sym;
|
||||||
use std::env;
|
use std::env;
|
||||||
use std::fmt::Debug;
|
use std::fmt::Debug;
|
||||||
|
@ -47,7 +46,7 @@ crate type PoloniusOutput = Output<RustcFacts>;
|
||||||
/// closure requirements to propagate, and any generated errors.
|
/// closure requirements to propagate, and any generated errors.
|
||||||
crate struct NllOutput<'tcx> {
|
crate struct NllOutput<'tcx> {
|
||||||
pub regioncx: RegionInferenceContext<'tcx>,
|
pub regioncx: RegionInferenceContext<'tcx>,
|
||||||
pub opaque_type_values: FxHashMap<DefId, ty::ResolvedOpaqueTy<'tcx>>,
|
pub opaque_type_values: VecMap<OpaqueTypeKey<'tcx>, ty::ResolvedOpaqueTy<'tcx>>,
|
||||||
pub polonius_output: Option<Rc<PoloniusOutput>>,
|
pub polonius_output: Option<Rc<PoloniusOutput>>,
|
||||||
pub opt_closure_req: Option<ClosureRegionRequirements<'tcx>>,
|
pub opt_closure_req: Option<ClosureRegionRequirements<'tcx>>,
|
||||||
pub nll_errors: RegionErrors<'tcx>,
|
pub nll_errors: RegionErrors<'tcx>,
|
||||||
|
@ -367,7 +366,7 @@ pub(super) fn dump_annotation<'a, 'tcx>(
|
||||||
body: &Body<'tcx>,
|
body: &Body<'tcx>,
|
||||||
regioncx: &RegionInferenceContext<'tcx>,
|
regioncx: &RegionInferenceContext<'tcx>,
|
||||||
closure_region_requirements: &Option<ClosureRegionRequirements<'_>>,
|
closure_region_requirements: &Option<ClosureRegionRequirements<'_>>,
|
||||||
opaque_type_values: &FxHashMap<DefId, ty::ResolvedOpaqueTy<'tcx>>,
|
opaque_type_values: &VecMap<OpaqueTypeKey<'tcx>, ty::ResolvedOpaqueTy<'tcx>>,
|
||||||
errors_buffer: &mut Vec<Diagnostic>,
|
errors_buffer: &mut Vec<Diagnostic>,
|
||||||
) {
|
) {
|
||||||
let tcx = infcx.tcx;
|
let tcx = infcx.tcx;
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
use rustc_data_structures::fx::FxHashMap;
|
use rustc_data_structures::vec_map::VecMap;
|
||||||
use rustc_hir::def_id::DefId;
|
|
||||||
use rustc_infer::infer::InferCtxt;
|
use rustc_infer::infer::InferCtxt;
|
||||||
use rustc_middle::ty::{self, TyCtxt, TypeFoldable};
|
use rustc_middle::ty::{self, OpaqueTypeKey, TyCtxt, TypeFoldable};
|
||||||
use rustc_span::Span;
|
use rustc_span::Span;
|
||||||
use rustc_trait_selection::opaque_types::InferCtxtExt;
|
use rustc_trait_selection::opaque_types::InferCtxtExt;
|
||||||
|
|
||||||
|
@ -51,12 +50,12 @@ impl<'tcx> RegionInferenceContext<'tcx> {
|
||||||
pub(in crate::borrow_check) fn infer_opaque_types(
|
pub(in crate::borrow_check) fn infer_opaque_types(
|
||||||
&self,
|
&self,
|
||||||
infcx: &InferCtxt<'_, 'tcx>,
|
infcx: &InferCtxt<'_, 'tcx>,
|
||||||
opaque_ty_decls: FxHashMap<DefId, ty::ResolvedOpaqueTy<'tcx>>,
|
opaque_ty_decls: VecMap<OpaqueTypeKey<'tcx>, ty::ResolvedOpaqueTy<'tcx>>,
|
||||||
span: Span,
|
span: Span,
|
||||||
) -> FxHashMap<DefId, ty::ResolvedOpaqueTy<'tcx>> {
|
) -> VecMap<OpaqueTypeKey<'tcx>, ty::ResolvedOpaqueTy<'tcx>> {
|
||||||
opaque_ty_decls
|
opaque_ty_decls
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|(opaque_def_id, ty::ResolvedOpaqueTy { concrete_type, substs })| {
|
.map(|(opaque_type_key, ty::ResolvedOpaqueTy { concrete_type, substs })| {
|
||||||
debug!(?concrete_type, ?substs);
|
debug!(?concrete_type, ?substs);
|
||||||
|
|
||||||
let mut subst_regions = vec![self.universal_regions.fr_static];
|
let mut subst_regions = vec![self.universal_regions.fr_static];
|
||||||
|
@ -110,14 +109,15 @@ impl<'tcx> RegionInferenceContext<'tcx> {
|
||||||
|
|
||||||
debug!(?universal_concrete_type, ?universal_substs);
|
debug!(?universal_concrete_type, ?universal_substs);
|
||||||
|
|
||||||
|
let opaque_type_key =
|
||||||
|
OpaqueTypeKey { def_id: opaque_type_key.def_id, substs: universal_substs };
|
||||||
let remapped_type = infcx.infer_opaque_definition_from_instantiation(
|
let remapped_type = infcx.infer_opaque_definition_from_instantiation(
|
||||||
opaque_def_id,
|
opaque_type_key,
|
||||||
universal_substs,
|
|
||||||
universal_concrete_type,
|
universal_concrete_type,
|
||||||
span,
|
span,
|
||||||
);
|
);
|
||||||
(
|
(
|
||||||
opaque_def_id,
|
opaque_type_key,
|
||||||
ty::ResolvedOpaqueTy { concrete_type: remapped_type, substs: universal_substs },
|
ty::ResolvedOpaqueTy { concrete_type: remapped_type, substs: universal_substs },
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
|
@ -7,9 +7,10 @@ use either::Either;
|
||||||
|
|
||||||
use rustc_data_structures::frozen::Frozen;
|
use rustc_data_structures::frozen::Frozen;
|
||||||
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
|
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
|
||||||
|
use rustc_data_structures::vec_map::VecMap;
|
||||||
use rustc_errors::struct_span_err;
|
use rustc_errors::struct_span_err;
|
||||||
use rustc_hir as hir;
|
use rustc_hir as hir;
|
||||||
use rustc_hir::def_id::{DefId, LocalDefId};
|
use rustc_hir::def_id::LocalDefId;
|
||||||
use rustc_hir::lang_items::LangItem;
|
use rustc_hir::lang_items::LangItem;
|
||||||
use rustc_index::vec::{Idx, IndexVec};
|
use rustc_index::vec::{Idx, IndexVec};
|
||||||
use rustc_infer::infer::canonical::QueryRegionConstraints;
|
use rustc_infer::infer::canonical::QueryRegionConstraints;
|
||||||
|
@ -27,8 +28,8 @@ use rustc_middle::ty::cast::CastTy;
|
||||||
use rustc_middle::ty::fold::TypeFoldable;
|
use rustc_middle::ty::fold::TypeFoldable;
|
||||||
use rustc_middle::ty::subst::{GenericArgKind, Subst, SubstsRef, UserSubsts};
|
use rustc_middle::ty::subst::{GenericArgKind, Subst, SubstsRef, UserSubsts};
|
||||||
use rustc_middle::ty::{
|
use rustc_middle::ty::{
|
||||||
self, CanonicalUserTypeAnnotation, CanonicalUserTypeAnnotations, RegionVid, ToPredicate, Ty,
|
self, CanonicalUserTypeAnnotation, CanonicalUserTypeAnnotations, OpaqueTypeKey, RegionVid,
|
||||||
TyCtxt, UserType, UserTypeAnnotationIndex, WithConstness,
|
ToPredicate, Ty, TyCtxt, UserType, UserTypeAnnotationIndex, WithConstness,
|
||||||
};
|
};
|
||||||
use rustc_span::{Span, DUMMY_SP};
|
use rustc_span::{Span, DUMMY_SP};
|
||||||
use rustc_target::abi::VariantIdx;
|
use rustc_target::abi::VariantIdx;
|
||||||
|
@ -818,7 +819,7 @@ struct TypeChecker<'a, 'tcx> {
|
||||||
reported_errors: FxHashSet<(Ty<'tcx>, Span)>,
|
reported_errors: FxHashSet<(Ty<'tcx>, Span)>,
|
||||||
borrowck_context: &'a mut BorrowCheckContext<'a, 'tcx>,
|
borrowck_context: &'a mut BorrowCheckContext<'a, 'tcx>,
|
||||||
universal_region_relations: &'a UniversalRegionRelations<'tcx>,
|
universal_region_relations: &'a UniversalRegionRelations<'tcx>,
|
||||||
opaque_type_values: FxHashMap<DefId, ty::ResolvedOpaqueTy<'tcx>>,
|
opaque_type_values: VecMap<OpaqueTypeKey<'tcx>, ty::ResolvedOpaqueTy<'tcx>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
struct BorrowCheckContext<'a, 'tcx> {
|
struct BorrowCheckContext<'a, 'tcx> {
|
||||||
|
@ -833,7 +834,7 @@ struct BorrowCheckContext<'a, 'tcx> {
|
||||||
crate struct MirTypeckResults<'tcx> {
|
crate struct MirTypeckResults<'tcx> {
|
||||||
crate constraints: MirTypeckRegionConstraints<'tcx>,
|
crate constraints: MirTypeckRegionConstraints<'tcx>,
|
||||||
pub(in crate::borrow_check) universal_region_relations: Frozen<UniversalRegionRelations<'tcx>>,
|
pub(in crate::borrow_check) universal_region_relations: Frozen<UniversalRegionRelations<'tcx>>,
|
||||||
crate opaque_type_values: FxHashMap<DefId, ty::ResolvedOpaqueTy<'tcx>>,
|
crate opaque_type_values: VecMap<OpaqueTypeKey<'tcx>, ty::ResolvedOpaqueTy<'tcx>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A collection of region constraints that must be satisfied for the
|
/// A collection of region constraints that must be satisfied for the
|
||||||
|
@ -978,7 +979,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
||||||
borrowck_context,
|
borrowck_context,
|
||||||
reported_errors: Default::default(),
|
reported_errors: Default::default(),
|
||||||
universal_region_relations,
|
universal_region_relations,
|
||||||
opaque_type_values: FxHashMap::default(),
|
opaque_type_values: VecMap::default(),
|
||||||
};
|
};
|
||||||
checker.check_user_type_annotations();
|
checker.check_user_type_annotations();
|
||||||
checker
|
checker
|
||||||
|
@ -1240,7 +1241,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
||||||
let param_env = self.param_env;
|
let param_env = self.param_env;
|
||||||
let body = self.body;
|
let body = self.body;
|
||||||
let concrete_opaque_types = &tcx.typeck(anon_owner_def_id).concrete_opaque_types;
|
let concrete_opaque_types = &tcx.typeck(anon_owner_def_id).concrete_opaque_types;
|
||||||
let mut opaque_type_values = Vec::new();
|
let mut opaque_type_values = VecMap::new();
|
||||||
|
|
||||||
debug!("eq_opaque_type_and_type: mir_def_id={:?}", body.source.def_id());
|
debug!("eq_opaque_type_and_type: mir_def_id={:?}", body.source.def_id());
|
||||||
let opaque_type_map = self.fully_perform_op(
|
let opaque_type_map = self.fully_perform_op(
|
||||||
|
@ -1288,7 +1289,14 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
||||||
} else {
|
} else {
|
||||||
false
|
false
|
||||||
};
|
};
|
||||||
let opaque_defn_ty = match concrete_opaque_types.get(&opaque_def_id) {
|
|
||||||
|
let opaque_type_key =
|
||||||
|
OpaqueTypeKey { def_id: opaque_def_id, substs: opaque_decl.substs };
|
||||||
|
let opaque_defn_ty = match concrete_opaque_types
|
||||||
|
.iter()
|
||||||
|
.find(|(opaque_type_key, _)| opaque_type_key.def_id == opaque_def_id)
|
||||||
|
.map(|(_, resolved_opaque_ty)| resolved_opaque_ty)
|
||||||
|
{
|
||||||
None => {
|
None => {
|
||||||
if !concrete_is_opaque {
|
if !concrete_is_opaque {
|
||||||
tcx.sess.delay_span_bug(
|
tcx.sess.delay_span_bug(
|
||||||
|
@ -1322,13 +1330,13 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
||||||
.at(&ObligationCause::dummy(), param_env)
|
.at(&ObligationCause::dummy(), param_env)
|
||||||
.eq(opaque_decl.concrete_ty, renumbered_opaque_defn_ty)?,
|
.eq(opaque_decl.concrete_ty, renumbered_opaque_defn_ty)?,
|
||||||
);
|
);
|
||||||
opaque_type_values.push((
|
opaque_type_values.insert(
|
||||||
opaque_def_id,
|
opaque_type_key,
|
||||||
ty::ResolvedOpaqueTy {
|
ty::ResolvedOpaqueTy {
|
||||||
concrete_type: renumbered_opaque_defn_ty,
|
concrete_type: renumbered_opaque_defn_ty,
|
||||||
substs: opaque_decl.substs,
|
substs: opaque_decl.substs,
|
||||||
},
|
},
|
||||||
));
|
);
|
||||||
} else {
|
} else {
|
||||||
// We're using an opaque `impl Trait` type without
|
// We're using an opaque `impl Trait` type without
|
||||||
// 'revealing' it. For example, code like this:
|
// 'revealing' it. For example, code like this:
|
||||||
|
|
|
@ -12,7 +12,7 @@ use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKi
|
||||||
use rustc_infer::infer::{self, InferCtxt, InferOk};
|
use rustc_infer::infer::{self, InferCtxt, InferOk};
|
||||||
use rustc_middle::ty::fold::{BottomUpFolder, TypeFoldable, TypeFolder, TypeVisitor};
|
use rustc_middle::ty::fold::{BottomUpFolder, TypeFoldable, TypeFolder, TypeVisitor};
|
||||||
use rustc_middle::ty::subst::{GenericArg, GenericArgKind, InternalSubsts, Subst, SubstsRef};
|
use rustc_middle::ty::subst::{GenericArg, GenericArgKind, InternalSubsts, Subst, SubstsRef};
|
||||||
use rustc_middle::ty::{self, Ty, TyCtxt};
|
use rustc_middle::ty::{self, OpaqueTypeKey, Ty, TyCtxt};
|
||||||
use rustc_span::Span;
|
use rustc_span::Span;
|
||||||
|
|
||||||
use std::ops::ControlFlow;
|
use std::ops::ControlFlow;
|
||||||
|
@ -143,8 +143,7 @@ pub trait InferCtxtExt<'tcx> {
|
||||||
|
|
||||||
fn infer_opaque_definition_from_instantiation(
|
fn infer_opaque_definition_from_instantiation(
|
||||||
&self,
|
&self,
|
||||||
def_id: DefId,
|
opaque_type_key: OpaqueTypeKey<'tcx>,
|
||||||
substs: SubstsRef<'tcx>,
|
|
||||||
instantiated_ty: Ty<'tcx>,
|
instantiated_ty: Ty<'tcx>,
|
||||||
span: Span,
|
span: Span,
|
||||||
) -> Ty<'tcx>;
|
) -> Ty<'tcx>;
|
||||||
|
@ -573,11 +572,12 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
|
||||||
/// `opaque_defn.concrete_ty`
|
/// `opaque_defn.concrete_ty`
|
||||||
fn infer_opaque_definition_from_instantiation(
|
fn infer_opaque_definition_from_instantiation(
|
||||||
&self,
|
&self,
|
||||||
def_id: DefId,
|
opaque_type_key: OpaqueTypeKey<'tcx>,
|
||||||
substs: SubstsRef<'tcx>,
|
|
||||||
instantiated_ty: Ty<'tcx>,
|
instantiated_ty: Ty<'tcx>,
|
||||||
span: Span,
|
span: Span,
|
||||||
) -> Ty<'tcx> {
|
) -> Ty<'tcx> {
|
||||||
|
let OpaqueTypeKey { def_id, substs } = opaque_type_key;
|
||||||
|
|
||||||
debug!(
|
debug!(
|
||||||
"infer_opaque_definition_from_instantiation(def_id={:?}, instantiated_ty={:?})",
|
"infer_opaque_definition_from_instantiation(def_id={:?}, instantiated_ty={:?})",
|
||||||
def_id, instantiated_ty
|
def_id, instantiated_ty
|
||||||
|
|
|
@ -15,7 +15,7 @@ use rustc_middle::hir::place::Place as HirPlace;
|
||||||
use rustc_middle::mir::FakeReadCause;
|
use rustc_middle::mir::FakeReadCause;
|
||||||
use rustc_middle::ty::adjustment::{Adjust, Adjustment, PointerCast};
|
use rustc_middle::ty::adjustment::{Adjust, Adjustment, PointerCast};
|
||||||
use rustc_middle::ty::fold::{TypeFoldable, TypeFolder};
|
use rustc_middle::ty::fold::{TypeFoldable, TypeFolder};
|
||||||
use rustc_middle::ty::{self, Ty, TyCtxt};
|
use rustc_middle::ty::{self, OpaqueTypeKey, Ty, TyCtxt};
|
||||||
use rustc_span::symbol::sym;
|
use rustc_span::symbol::sym;
|
||||||
use rustc_span::Span;
|
use rustc_span::Span;
|
||||||
use rustc_trait_selection::opaque_types::InferCtxtExt;
|
use rustc_trait_selection::opaque_types::InferCtxtExt;
|
||||||
|
@ -493,9 +493,9 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> {
|
||||||
// fn foo<U>() -> Foo<U> { .. }
|
// fn foo<U>() -> Foo<U> { .. }
|
||||||
// ```
|
// ```
|
||||||
// figures out the concrete type with `U`, but the stored type is with `T`.
|
// figures out the concrete type with `U`, but the stored type is with `T`.
|
||||||
|
let opaque_type_key = OpaqueTypeKey { def_id, substs: opaque_defn.substs };
|
||||||
let definition_ty = self.fcx.infer_opaque_definition_from_instantiation(
|
let definition_ty = self.fcx.infer_opaque_definition_from_instantiation(
|
||||||
def_id,
|
opaque_type_key,
|
||||||
opaque_defn.substs,
|
|
||||||
instantiated_ty,
|
instantiated_ty,
|
||||||
span,
|
span,
|
||||||
);
|
);
|
||||||
|
@ -527,7 +527,9 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> {
|
||||||
substs: opaque_defn.substs,
|
substs: opaque_defn.substs,
|
||||||
};
|
};
|
||||||
|
|
||||||
let old = self.typeck_results.concrete_opaque_types.insert(def_id, new);
|
let opaque_type_key = OpaqueTypeKey { def_id, substs: opaque_defn.substs };
|
||||||
|
let old =
|
||||||
|
self.typeck_results.concrete_opaque_types.insert(opaque_type_key, new);
|
||||||
if let Some(old) = old {
|
if let Some(old) = old {
|
||||||
if old.concrete_type != definition_ty || old.substs != opaque_defn.substs {
|
if old.concrete_type != definition_ty || old.substs != opaque_defn.substs {
|
||||||
span_bug!(
|
span_bug!(
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
use rustc_data_structures::fx::FxHashSet;
|
use rustc_data_structures::fx::FxHashSet;
|
||||||
|
use rustc_data_structures::vec_map::VecMap;
|
||||||
use rustc_errors::{Applicability, ErrorReported, StashKey};
|
use rustc_errors::{Applicability, ErrorReported, StashKey};
|
||||||
use rustc_hir as hir;
|
use rustc_hir as hir;
|
||||||
use rustc_hir::def::{DefKind, Res};
|
use rustc_hir::def::{DefKind, Res};
|
||||||
|
@ -9,7 +10,9 @@ use rustc_hir::{HirId, Node};
|
||||||
use rustc_middle::hir::map::Map;
|
use rustc_middle::hir::map::Map;
|
||||||
use rustc_middle::ty::subst::{GenericArgKind, InternalSubsts};
|
use rustc_middle::ty::subst::{GenericArgKind, InternalSubsts};
|
||||||
use rustc_middle::ty::util::IntTypeExt;
|
use rustc_middle::ty::util::IntTypeExt;
|
||||||
use rustc_middle::ty::{self, DefIdTree, Ty, TyCtxt, TypeFoldable};
|
use rustc_middle::ty::{
|
||||||
|
self, DefIdTree, OpaqueTypeKey, ResolvedOpaqueTy, Ty, TyCtxt, TypeFoldable,
|
||||||
|
};
|
||||||
use rustc_span::symbol::Ident;
|
use rustc_span::symbol::Ident;
|
||||||
use rustc_span::{Span, DUMMY_SP};
|
use rustc_span::{Span, DUMMY_SP};
|
||||||
|
|
||||||
|
@ -346,36 +349,36 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> {
|
||||||
}
|
}
|
||||||
// Opaque types desugared from `impl Trait`.
|
// Opaque types desugared from `impl Trait`.
|
||||||
ItemKind::OpaqueTy(OpaqueTy { impl_trait_fn: Some(owner), .. }) => {
|
ItemKind::OpaqueTy(OpaqueTy { impl_trait_fn: Some(owner), .. }) => {
|
||||||
let concrete_ty = tcx
|
let concrete_ty = find_concrete_ty_from_def_id(
|
||||||
.mir_borrowck(owner.expect_local())
|
&tcx.mir_borrowck(owner.expect_local()).concrete_opaque_types,
|
||||||
.concrete_opaque_types
|
def_id.to_def_id(),
|
||||||
.get(&def_id.to_def_id())
|
)
|
||||||
.map(|opaque| opaque.concrete_type)
|
.map(|opaque| opaque.concrete_type)
|
||||||
.unwrap_or_else(|| {
|
.unwrap_or_else(|| {
|
||||||
tcx.sess.delay_span_bug(
|
tcx.sess.delay_span_bug(
|
||||||
DUMMY_SP,
|
DUMMY_SP,
|
||||||
&format!(
|
&format!(
|
||||||
"owner {:?} has no opaque type for {:?} in its typeck results",
|
"owner {:?} has no opaque type for {:?} in its typeck results",
|
||||||
owner, def_id,
|
owner, def_id,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
if let Some(ErrorReported) =
|
if let Some(ErrorReported) =
|
||||||
tcx.typeck(owner.expect_local()).tainted_by_errors
|
tcx.typeck(owner.expect_local()).tainted_by_errors
|
||||||
{
|
{
|
||||||
// Some error in the
|
// Some error in the
|
||||||
// owner fn prevented us from populating
|
// owner fn prevented us from populating
|
||||||
// the `concrete_opaque_types` table.
|
// the `concrete_opaque_types` table.
|
||||||
tcx.ty_error()
|
tcx.ty_error()
|
||||||
} else {
|
} else {
|
||||||
// We failed to resolve the opaque type or it
|
// We failed to resolve the opaque type or it
|
||||||
// resolves to itself. Return the non-revealed
|
// resolves to itself. Return the non-revealed
|
||||||
// type, which should result in E0720.
|
// type, which should result in E0720.
|
||||||
tcx.mk_opaque(
|
tcx.mk_opaque(
|
||||||
def_id.to_def_id(),
|
def_id.to_def_id(),
|
||||||
InternalSubsts::identity_for_item(tcx, def_id.to_def_id()),
|
InternalSubsts::identity_for_item(tcx, def_id.to_def_id()),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
debug!("concrete_ty = {:?}", concrete_ty);
|
debug!("concrete_ty = {:?}", concrete_ty);
|
||||||
concrete_ty
|
concrete_ty
|
||||||
}
|
}
|
||||||
|
@ -515,7 +518,12 @@ fn find_opaque_ty_constraints(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Ty<'_> {
|
||||||
}
|
}
|
||||||
// Calling `mir_borrowck` can lead to cycle errors through
|
// Calling `mir_borrowck` can lead to cycle errors through
|
||||||
// const-checking, avoid calling it if we don't have to.
|
// const-checking, avoid calling it if we don't have to.
|
||||||
if !self.tcx.typeck(def_id).concrete_opaque_types.contains_key(&self.def_id) {
|
if find_concrete_ty_from_def_id(
|
||||||
|
&self.tcx.typeck(def_id).concrete_opaque_types,
|
||||||
|
self.def_id,
|
||||||
|
)
|
||||||
|
.is_none()
|
||||||
|
{
|
||||||
debug!(
|
debug!(
|
||||||
"find_opaque_ty_constraints: no constraint for `{:?}` at `{:?}`",
|
"find_opaque_ty_constraints: no constraint for `{:?}` at `{:?}`",
|
||||||
self.def_id, def_id,
|
self.def_id, def_id,
|
||||||
|
@ -523,7 +531,10 @@ fn find_opaque_ty_constraints(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Ty<'_> {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// Use borrowck to get the type with unerased regions.
|
// Use borrowck to get the type with unerased regions.
|
||||||
let ty = self.tcx.mir_borrowck(def_id).concrete_opaque_types.get(&self.def_id);
|
let ty = find_concrete_ty_from_def_id(
|
||||||
|
&self.tcx.mir_borrowck(def_id).concrete_opaque_types,
|
||||||
|
self.def_id,
|
||||||
|
);
|
||||||
if let Some(ty::ResolvedOpaqueTy { concrete_type, substs }) = ty {
|
if let Some(ty::ResolvedOpaqueTy { concrete_type, substs }) = ty {
|
||||||
debug!(
|
debug!(
|
||||||
"find_opaque_ty_constraints: found constraint for `{:?}` at `{:?}`: {:?}",
|
"find_opaque_ty_constraints: found constraint for `{:?}` at `{:?}`: {:?}",
|
||||||
|
@ -697,32 +708,31 @@ fn let_position_impl_trait_type(tcx: TyCtxt<'_>, opaque_ty_id: LocalDefId) -> Ty
|
||||||
let opaque_ty_def_id = opaque_ty_id.to_def_id();
|
let opaque_ty_def_id = opaque_ty_id.to_def_id();
|
||||||
|
|
||||||
let owner_typeck_results = tcx.typeck(scope_def_id);
|
let owner_typeck_results = tcx.typeck(scope_def_id);
|
||||||
let concrete_ty = owner_typeck_results
|
let concrete_ty =
|
||||||
.concrete_opaque_types
|
find_concrete_ty_from_def_id(&owner_typeck_results.concrete_opaque_types, opaque_ty_def_id)
|
||||||
.get(&opaque_ty_def_id)
|
.map(|opaque| opaque.concrete_type)
|
||||||
.map(|opaque| opaque.concrete_type)
|
.unwrap_or_else(|| {
|
||||||
.unwrap_or_else(|| {
|
tcx.sess.delay_span_bug(
|
||||||
tcx.sess.delay_span_bug(
|
DUMMY_SP,
|
||||||
DUMMY_SP,
|
&format!(
|
||||||
&format!(
|
"owner {:?} has no opaque type for {:?} in its typeck results",
|
||||||
"owner {:?} has no opaque type for {:?} in its typeck results",
|
scope_def_id, opaque_ty_id
|
||||||
scope_def_id, opaque_ty_id
|
),
|
||||||
),
|
);
|
||||||
);
|
if let Some(ErrorReported) = owner_typeck_results.tainted_by_errors {
|
||||||
if let Some(ErrorReported) = owner_typeck_results.tainted_by_errors {
|
// Some error in the owner fn prevented us from populating the
|
||||||
// Some error in the owner fn prevented us from populating the
|
// `concrete_opaque_types` table.
|
||||||
// `concrete_opaque_types` table.
|
tcx.ty_error()
|
||||||
tcx.ty_error()
|
} else {
|
||||||
} else {
|
// We failed to resolve the opaque type or it resolves to
|
||||||
// We failed to resolve the opaque type or it resolves to
|
// itself. Return the non-revealed type, which should result in
|
||||||
// itself. Return the non-revealed type, which should result in
|
// E0720.
|
||||||
// E0720.
|
tcx.mk_opaque(
|
||||||
tcx.mk_opaque(
|
opaque_ty_def_id,
|
||||||
opaque_ty_def_id,
|
InternalSubsts::identity_for_item(tcx, opaque_ty_def_id),
|
||||||
InternalSubsts::identity_for_item(tcx, opaque_ty_def_id),
|
)
|
||||||
)
|
}
|
||||||
}
|
});
|
||||||
});
|
|
||||||
debug!("concrete_ty = {:?}", concrete_ty);
|
debug!("concrete_ty = {:?}", concrete_ty);
|
||||||
if concrete_ty.has_erased_regions() {
|
if concrete_ty.has_erased_regions() {
|
||||||
// FIXME(impl_trait_in_bindings) Handle this case.
|
// FIXME(impl_trait_in_bindings) Handle this case.
|
||||||
|
@ -796,3 +806,13 @@ fn check_feature_inherent_assoc_ty(tcx: TyCtxt<'_>, span: Span) {
|
||||||
.emit();
|
.emit();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn find_concrete_ty_from_def_id<'tcx>(
|
||||||
|
concrete_opaque_types: &'tcx VecMap<OpaqueTypeKey<'tcx>, ResolvedOpaqueTy<'tcx>>,
|
||||||
|
def_id: DefId,
|
||||||
|
) -> Option<&'tcx ResolvedOpaqueTy<'tcx>> {
|
||||||
|
concrete_opaque_types
|
||||||
|
.iter()
|
||||||
|
.find(|(opaque_type_key, _)| opaque_type_key.def_id == def_id)
|
||||||
|
.map(|(_, resolved_opaque_ty)| resolved_opaque_ty)
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue