mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-22 06:44:35 +00:00
Rollup merge of #125597 - compiler-errors:early-binder, r=jackh726
Uplift `EarlyBinder` into `rustc_type_ir` We also need to give `EarlyBinder` a `'tcx` param, so that we can carry the `Interner` in the `EarlyBinder` too. This is necessary because otherwise we have an unconstrained `I: Interner` parameter in many of the `EarlyBinder`'s inherent impls. I also generally think that this is desirable to have, in case we later want to track some state in the `EarlyBinder`. r? lcnr
This commit is contained in:
commit
a9c125f864
@ -4686,6 +4686,7 @@ dependencies = [
|
|||||||
"rustc_span",
|
"rustc_span",
|
||||||
"rustc_type_ir_macros",
|
"rustc_type_ir_macros",
|
||||||
"smallvec",
|
"smallvec",
|
||||||
|
"tracing",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -449,7 +449,7 @@ impl<'tcx> TypeFolder<TyCtxt<'tcx>> for RemapLateBound<'_, 'tcx> {
|
|||||||
pub(super) fn collect_return_position_impl_trait_in_trait_tys<'tcx>(
|
pub(super) fn collect_return_position_impl_trait_in_trait_tys<'tcx>(
|
||||||
tcx: TyCtxt<'tcx>,
|
tcx: TyCtxt<'tcx>,
|
||||||
impl_m_def_id: LocalDefId,
|
impl_m_def_id: LocalDefId,
|
||||||
) -> Result<&'tcx DefIdMap<ty::EarlyBinder<Ty<'tcx>>>, ErrorGuaranteed> {
|
) -> Result<&'tcx DefIdMap<ty::EarlyBinder<'tcx, Ty<'tcx>>>, ErrorGuaranteed> {
|
||||||
let impl_m = tcx.opt_associated_item(impl_m_def_id.to_def_id()).unwrap();
|
let impl_m = tcx.opt_associated_item(impl_m_def_id.to_def_id()).unwrap();
|
||||||
let trait_m = tcx.opt_associated_item(impl_m.trait_item_def_id.unwrap()).unwrap();
|
let trait_m = tcx.opt_associated_item(impl_m.trait_item_def_id.unwrap()).unwrap();
|
||||||
let impl_trait_ref =
|
let impl_trait_ref =
|
||||||
|
@ -1277,7 +1277,7 @@ fn trait_def(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::TraitDef {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[instrument(level = "debug", skip(tcx))]
|
#[instrument(level = "debug", skip(tcx))]
|
||||||
fn fn_sig(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<ty::PolyFnSig<'_>> {
|
fn fn_sig(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<'_, ty::PolyFnSig<'_>> {
|
||||||
use rustc_hir::Node::*;
|
use rustc_hir::Node::*;
|
||||||
use rustc_hir::*;
|
use rustc_hir::*;
|
||||||
|
|
||||||
|
@ -82,14 +82,14 @@ fn opaque_type_bounds<'tcx>(
|
|||||||
pub(super) fn explicit_item_bounds(
|
pub(super) fn explicit_item_bounds(
|
||||||
tcx: TyCtxt<'_>,
|
tcx: TyCtxt<'_>,
|
||||||
def_id: LocalDefId,
|
def_id: LocalDefId,
|
||||||
) -> ty::EarlyBinder<&'_ [(ty::Clause<'_>, Span)]> {
|
) -> ty::EarlyBinder<'_, &'_ [(ty::Clause<'_>, Span)]> {
|
||||||
explicit_item_bounds_with_filter(tcx, def_id, PredicateFilter::All)
|
explicit_item_bounds_with_filter(tcx, def_id, PredicateFilter::All)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn explicit_item_super_predicates(
|
pub(super) fn explicit_item_super_predicates(
|
||||||
tcx: TyCtxt<'_>,
|
tcx: TyCtxt<'_>,
|
||||||
def_id: LocalDefId,
|
def_id: LocalDefId,
|
||||||
) -> ty::EarlyBinder<&'_ [(ty::Clause<'_>, Span)]> {
|
) -> ty::EarlyBinder<'_, &'_ [(ty::Clause<'_>, Span)]> {
|
||||||
explicit_item_bounds_with_filter(tcx, def_id, PredicateFilter::SelfOnly)
|
explicit_item_bounds_with_filter(tcx, def_id, PredicateFilter::SelfOnly)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -97,7 +97,7 @@ pub(super) fn explicit_item_bounds_with_filter(
|
|||||||
tcx: TyCtxt<'_>,
|
tcx: TyCtxt<'_>,
|
||||||
def_id: LocalDefId,
|
def_id: LocalDefId,
|
||||||
filter: PredicateFilter,
|
filter: PredicateFilter,
|
||||||
) -> ty::EarlyBinder<&'_ [(ty::Clause<'_>, Span)]> {
|
) -> ty::EarlyBinder<'_, &'_ [(ty::Clause<'_>, Span)]> {
|
||||||
match tcx.opt_rpitit_info(def_id.to_def_id()) {
|
match tcx.opt_rpitit_info(def_id.to_def_id()) {
|
||||||
// RPITIT's bounds are the same as opaque type bounds, but with
|
// RPITIT's bounds are the same as opaque type bounds, but with
|
||||||
// a projection self type.
|
// a projection self type.
|
||||||
@ -166,7 +166,7 @@ pub(super) fn explicit_item_bounds_with_filter(
|
|||||||
ty::EarlyBinder::bind(bounds)
|
ty::EarlyBinder::bind(bounds)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn item_bounds(tcx: TyCtxt<'_>, def_id: DefId) -> ty::EarlyBinder<ty::Clauses<'_>> {
|
pub(super) fn item_bounds(tcx: TyCtxt<'_>, def_id: DefId) -> ty::EarlyBinder<'_, ty::Clauses<'_>> {
|
||||||
tcx.explicit_item_bounds(def_id).map_bound(|bounds| {
|
tcx.explicit_item_bounds(def_id).map_bound(|bounds| {
|
||||||
tcx.mk_clauses_from_iter(util::elaborate(tcx, bounds.iter().map(|&(bound, _span)| bound)))
|
tcx.mk_clauses_from_iter(util::elaborate(tcx, bounds.iter().map(|&(bound, _span)| bound)))
|
||||||
})
|
})
|
||||||
@ -175,7 +175,7 @@ pub(super) fn item_bounds(tcx: TyCtxt<'_>, def_id: DefId) -> ty::EarlyBinder<ty:
|
|||||||
pub(super) fn item_super_predicates(
|
pub(super) fn item_super_predicates(
|
||||||
tcx: TyCtxt<'_>,
|
tcx: TyCtxt<'_>,
|
||||||
def_id: DefId,
|
def_id: DefId,
|
||||||
) -> ty::EarlyBinder<ty::Clauses<'_>> {
|
) -> ty::EarlyBinder<'_, ty::Clauses<'_>> {
|
||||||
tcx.explicit_item_super_predicates(def_id).map_bound(|bounds| {
|
tcx.explicit_item_super_predicates(def_id).map_bound(|bounds| {
|
||||||
tcx.mk_clauses_from_iter(
|
tcx.mk_clauses_from_iter(
|
||||||
util::elaborate(tcx, bounds.iter().map(|&(bound, _span)| bound)).filter_only_self(),
|
util::elaborate(tcx, bounds.iter().map(|&(bound, _span)| bound)).filter_only_self(),
|
||||||
@ -186,7 +186,7 @@ pub(super) fn item_super_predicates(
|
|||||||
pub(super) fn item_non_self_assumptions(
|
pub(super) fn item_non_self_assumptions(
|
||||||
tcx: TyCtxt<'_>,
|
tcx: TyCtxt<'_>,
|
||||||
def_id: DefId,
|
def_id: DefId,
|
||||||
) -> ty::EarlyBinder<ty::Clauses<'_>> {
|
) -> ty::EarlyBinder<'_, ty::Clauses<'_>> {
|
||||||
let all_bounds: FxIndexSet<_> = tcx.item_bounds(def_id).skip_binder().iter().collect();
|
let all_bounds: FxIndexSet<_> = tcx.item_bounds(def_id).skip_binder().iter().collect();
|
||||||
let own_bounds: FxIndexSet<_> =
|
let own_bounds: FxIndexSet<_> =
|
||||||
tcx.item_super_predicates(def_id).skip_binder().iter().collect();
|
tcx.item_super_predicates(def_id).skip_binder().iter().collect();
|
||||||
|
@ -309,7 +309,7 @@ fn get_path_containing_arg_in_pat<'hir>(
|
|||||||
arg_path
|
arg_path
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<Ty<'_>> {
|
pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<'_, Ty<'_>> {
|
||||||
use rustc_hir::*;
|
use rustc_hir::*;
|
||||||
use rustc_middle::ty::Ty;
|
use rustc_middle::ty::Ty;
|
||||||
|
|
||||||
@ -512,7 +512,7 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<Ty
|
|||||||
pub(super) fn type_of_opaque(
|
pub(super) fn type_of_opaque(
|
||||||
tcx: TyCtxt<'_>,
|
tcx: TyCtxt<'_>,
|
||||||
def_id: DefId,
|
def_id: DefId,
|
||||||
) -> Result<ty::EarlyBinder<Ty<'_>>, CyclePlaceholder> {
|
) -> Result<ty::EarlyBinder<'_, Ty<'_>>, CyclePlaceholder> {
|
||||||
if let Some(def_id) = def_id.as_local() {
|
if let Some(def_id) = def_id.as_local() {
|
||||||
use rustc_hir::*;
|
use rustc_hir::*;
|
||||||
|
|
||||||
|
@ -6,7 +6,7 @@ use super::utils::*;
|
|||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct ExplicitPredicatesMap<'tcx> {
|
pub struct ExplicitPredicatesMap<'tcx> {
|
||||||
map: FxIndexMap<DefId, ty::EarlyBinder<RequiredPredicates<'tcx>>>,
|
map: FxIndexMap<DefId, ty::EarlyBinder<'tcx, RequiredPredicates<'tcx>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> ExplicitPredicatesMap<'tcx> {
|
impl<'tcx> ExplicitPredicatesMap<'tcx> {
|
||||||
@ -18,7 +18,7 @@ impl<'tcx> ExplicitPredicatesMap<'tcx> {
|
|||||||
&mut self,
|
&mut self,
|
||||||
tcx: TyCtxt<'tcx>,
|
tcx: TyCtxt<'tcx>,
|
||||||
def_id: DefId,
|
def_id: DefId,
|
||||||
) -> &ty::EarlyBinder<RequiredPredicates<'tcx>> {
|
) -> &ty::EarlyBinder<'tcx, RequiredPredicates<'tcx>> {
|
||||||
self.map.entry(def_id).or_insert_with(|| {
|
self.map.entry(def_id).or_insert_with(|| {
|
||||||
let predicates = if def_id.is_local() {
|
let predicates = if def_id.is_local() {
|
||||||
tcx.explicit_predicates_of(def_id)
|
tcx.explicit_predicates_of(def_id)
|
||||||
|
@ -15,7 +15,7 @@ use super::utils::*;
|
|||||||
/// now be filled with inferred predicates.
|
/// now be filled with inferred predicates.
|
||||||
pub(super) fn infer_predicates(
|
pub(super) fn infer_predicates(
|
||||||
tcx: TyCtxt<'_>,
|
tcx: TyCtxt<'_>,
|
||||||
) -> FxIndexMap<DefId, ty::EarlyBinder<RequiredPredicates<'_>>> {
|
) -> FxIndexMap<DefId, ty::EarlyBinder<'_, RequiredPredicates<'_>>> {
|
||||||
debug!("infer_predicates");
|
debug!("infer_predicates");
|
||||||
|
|
||||||
let mut explicit_map = ExplicitPredicatesMap::new();
|
let mut explicit_map = ExplicitPredicatesMap::new();
|
||||||
@ -101,7 +101,7 @@ fn insert_required_predicates_to_be_wf<'tcx>(
|
|||||||
tcx: TyCtxt<'tcx>,
|
tcx: TyCtxt<'tcx>,
|
||||||
ty: Ty<'tcx>,
|
ty: Ty<'tcx>,
|
||||||
span: Span,
|
span: Span,
|
||||||
global_inferred_outlives: &FxIndexMap<DefId, ty::EarlyBinder<RequiredPredicates<'tcx>>>,
|
global_inferred_outlives: &FxIndexMap<DefId, ty::EarlyBinder<'tcx, RequiredPredicates<'tcx>>>,
|
||||||
required_predicates: &mut RequiredPredicates<'tcx>,
|
required_predicates: &mut RequiredPredicates<'tcx>,
|
||||||
explicit_map: &mut ExplicitPredicatesMap<'tcx>,
|
explicit_map: &mut ExplicitPredicatesMap<'tcx>,
|
||||||
) {
|
) {
|
||||||
@ -322,7 +322,7 @@ fn check_inferred_predicates<'tcx>(
|
|||||||
tcx: TyCtxt<'tcx>,
|
tcx: TyCtxt<'tcx>,
|
||||||
def_id: DefId,
|
def_id: DefId,
|
||||||
args: ty::GenericArgsRef<'tcx>,
|
args: ty::GenericArgsRef<'tcx>,
|
||||||
global_inferred_outlives: &FxIndexMap<DefId, ty::EarlyBinder<RequiredPredicates<'tcx>>>,
|
global_inferred_outlives: &FxIndexMap<DefId, ty::EarlyBinder<'tcx, RequiredPredicates<'tcx>>>,
|
||||||
required_predicates: &mut RequiredPredicates<'tcx>,
|
required_predicates: &mut RequiredPredicates<'tcx>,
|
||||||
) {
|
) {
|
||||||
// Load the current set of inferred and explicit predicates from `global_inferred_outlives`
|
// Load the current set of inferred and explicit predicates from `global_inferred_outlives`
|
||||||
|
@ -270,7 +270,7 @@ fn impl_trait_ref_has_enough_non_local_candidates<'tcx>(
|
|||||||
tcx: TyCtxt<'tcx>,
|
tcx: TyCtxt<'tcx>,
|
||||||
infer_span: Span,
|
infer_span: Span,
|
||||||
trait_def_id: DefId,
|
trait_def_id: DefId,
|
||||||
binder: EarlyBinder<TraitRef<'tcx>>,
|
binder: EarlyBinder<'tcx, TraitRef<'tcx>>,
|
||||||
mut did_has_local_parent: impl FnMut(DefId) -> bool,
|
mut did_has_local_parent: impl FnMut(DefId) -> bool,
|
||||||
) -> bool {
|
) -> bool {
|
||||||
let infcx = tcx
|
let infcx = tcx
|
||||||
|
@ -1074,7 +1074,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
|
|||||||
self,
|
self,
|
||||||
index: DefIndex,
|
index: DefIndex,
|
||||||
tcx: TyCtxt<'tcx>,
|
tcx: TyCtxt<'tcx>,
|
||||||
) -> ty::EarlyBinder<&'tcx [(ty::Clause<'tcx>, Span)]> {
|
) -> ty::EarlyBinder<'tcx, &'tcx [(ty::Clause<'tcx>, Span)]> {
|
||||||
let lazy = self.root.tables.explicit_item_bounds.get(self, index);
|
let lazy = self.root.tables.explicit_item_bounds.get(self, index);
|
||||||
let output = if lazy.is_default() {
|
let output = if lazy.is_default() {
|
||||||
&mut []
|
&mut []
|
||||||
@ -1088,7 +1088,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
|
|||||||
self,
|
self,
|
||||||
index: DefIndex,
|
index: DefIndex,
|
||||||
tcx: TyCtxt<'tcx>,
|
tcx: TyCtxt<'tcx>,
|
||||||
) -> ty::EarlyBinder<&'tcx [(ty::Clause<'tcx>, Span)]> {
|
) -> ty::EarlyBinder<'tcx, &'tcx [(ty::Clause<'tcx>, Span)]> {
|
||||||
let lazy = self.root.tables.explicit_item_super_predicates.get(self, index);
|
let lazy = self.root.tables.explicit_item_super_predicates.get(self, index);
|
||||||
let output = if lazy.is_default() {
|
let output = if lazy.is_default() {
|
||||||
&mut []
|
&mut []
|
||||||
|
@ -418,19 +418,19 @@ define_tables! {
|
|||||||
// As an optimization, we only store this for trait aliases,
|
// As an optimization, we only store this for trait aliases,
|
||||||
// since it's identical to super_predicates_of for traits.
|
// since it's identical to super_predicates_of for traits.
|
||||||
implied_predicates_of: Table<DefIndex, LazyValue<ty::GenericPredicates<'static>>>,
|
implied_predicates_of: Table<DefIndex, LazyValue<ty::GenericPredicates<'static>>>,
|
||||||
type_of: Table<DefIndex, LazyValue<ty::EarlyBinder<Ty<'static>>>>,
|
type_of: Table<DefIndex, LazyValue<ty::EarlyBinder<'static, Ty<'static>>>>,
|
||||||
variances_of: Table<DefIndex, LazyArray<ty::Variance>>,
|
variances_of: Table<DefIndex, LazyArray<ty::Variance>>,
|
||||||
fn_sig: Table<DefIndex, LazyValue<ty::EarlyBinder<ty::PolyFnSig<'static>>>>,
|
fn_sig: Table<DefIndex, LazyValue<ty::EarlyBinder<'static, ty::PolyFnSig<'static>>>>,
|
||||||
codegen_fn_attrs: Table<DefIndex, LazyValue<CodegenFnAttrs>>,
|
codegen_fn_attrs: Table<DefIndex, LazyValue<CodegenFnAttrs>>,
|
||||||
impl_trait_header: Table<DefIndex, LazyValue<ty::ImplTraitHeader<'static>>>,
|
impl_trait_header: Table<DefIndex, LazyValue<ty::ImplTraitHeader<'static>>>,
|
||||||
const_param_default: Table<DefIndex, LazyValue<ty::EarlyBinder<rustc_middle::ty::Const<'static>>>>,
|
const_param_default: Table<DefIndex, LazyValue<ty::EarlyBinder<'static, rustc_middle::ty::Const<'static>>>>,
|
||||||
object_lifetime_default: Table<DefIndex, LazyValue<ObjectLifetimeDefault>>,
|
object_lifetime_default: Table<DefIndex, LazyValue<ObjectLifetimeDefault>>,
|
||||||
optimized_mir: Table<DefIndex, LazyValue<mir::Body<'static>>>,
|
optimized_mir: Table<DefIndex, LazyValue<mir::Body<'static>>>,
|
||||||
mir_for_ctfe: Table<DefIndex, LazyValue<mir::Body<'static>>>,
|
mir_for_ctfe: Table<DefIndex, LazyValue<mir::Body<'static>>>,
|
||||||
closure_saved_names_of_captured_variables: Table<DefIndex, LazyValue<IndexVec<FieldIdx, Symbol>>>,
|
closure_saved_names_of_captured_variables: Table<DefIndex, LazyValue<IndexVec<FieldIdx, Symbol>>>,
|
||||||
mir_coroutine_witnesses: Table<DefIndex, LazyValue<mir::CoroutineLayout<'static>>>,
|
mir_coroutine_witnesses: Table<DefIndex, LazyValue<mir::CoroutineLayout<'static>>>,
|
||||||
promoted_mir: Table<DefIndex, LazyValue<IndexVec<mir::Promoted, mir::Body<'static>>>>,
|
promoted_mir: Table<DefIndex, LazyValue<IndexVec<mir::Promoted, mir::Body<'static>>>>,
|
||||||
thir_abstract_const: Table<DefIndex, LazyValue<ty::EarlyBinder<ty::Const<'static>>>>,
|
thir_abstract_const: Table<DefIndex, LazyValue<ty::EarlyBinder<'static, ty::Const<'static>>>>,
|
||||||
impl_parent: Table<DefIndex, RawDefId>,
|
impl_parent: Table<DefIndex, RawDefId>,
|
||||||
constness: Table<DefIndex, hir::Constness>,
|
constness: Table<DefIndex, hir::Constness>,
|
||||||
defaultness: Table<DefIndex, hir::Defaultness>,
|
defaultness: Table<DefIndex, hir::Defaultness>,
|
||||||
@ -459,7 +459,7 @@ define_tables! {
|
|||||||
macro_definition: Table<DefIndex, LazyValue<ast::DelimArgs>>,
|
macro_definition: Table<DefIndex, LazyValue<ast::DelimArgs>>,
|
||||||
proc_macro: Table<DefIndex, MacroKind>,
|
proc_macro: Table<DefIndex, MacroKind>,
|
||||||
deduced_param_attrs: Table<DefIndex, LazyArray<DeducedParamAttrs>>,
|
deduced_param_attrs: Table<DefIndex, LazyArray<DeducedParamAttrs>>,
|
||||||
trait_impl_trait_tys: Table<DefIndex, LazyValue<DefIdMap<ty::EarlyBinder<Ty<'static>>>>>,
|
trait_impl_trait_tys: Table<DefIndex, LazyValue<DefIdMap<ty::EarlyBinder<'static, Ty<'static>>>>>,
|
||||||
doc_link_resolutions: Table<DefIndex, LazyValue<DocLinkResMap>>,
|
doc_link_resolutions: Table<DefIndex, LazyValue<DocLinkResMap>>,
|
||||||
doc_link_traits_in_scope: Table<DefIndex, LazyArray<DefId>>,
|
doc_link_traits_in_scope: Table<DefIndex, LazyArray<DefId>>,
|
||||||
assumed_wf_types_for_rpitit: Table<DefIndex, LazyArray<(Ty<'static>, Span)>>,
|
assumed_wf_types_for_rpitit: Table<DefIndex, LazyArray<(Ty<'static>, Span)>>,
|
||||||
|
@ -108,7 +108,7 @@ macro_rules! arena_types {
|
|||||||
[decode] trait_impl_trait_tys:
|
[decode] trait_impl_trait_tys:
|
||||||
rustc_data_structures::unord::UnordMap<
|
rustc_data_structures::unord::UnordMap<
|
||||||
rustc_hir::def_id::DefId,
|
rustc_hir::def_id::DefId,
|
||||||
rustc_middle::ty::EarlyBinder<rustc_middle::ty::Ty<'tcx>>
|
rustc_middle::ty::EarlyBinder<'tcx, rustc_middle::ty::Ty<'tcx>>
|
||||||
>,
|
>,
|
||||||
[] external_constraints: rustc_middle::traits::solve::ExternalConstraintsData<'tcx>,
|
[] external_constraints: rustc_middle::traits::solve::ExternalConstraintsData<'tcx>,
|
||||||
[] predefined_opaques_in_body: rustc_middle::traits::solve::PredefinedOpaquesData<'tcx>,
|
[] predefined_opaques_in_body: rustc_middle::traits::solve::PredefinedOpaquesData<'tcx>,
|
||||||
|
@ -121,7 +121,7 @@ impl<'tcx> TyCtxt<'tcx> {
|
|||||||
LocalModDefId::new_unchecked(id)
|
LocalModDefId::new_unchecked(id)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn impl_subject(self, def_id: DefId) -> EarlyBinder<ImplSubject<'tcx>> {
|
pub fn impl_subject(self, def_id: DefId) -> EarlyBinder<'tcx, ImplSubject<'tcx>> {
|
||||||
match self.impl_trait_ref(def_id) {
|
match self.impl_trait_ref(def_id) {
|
||||||
Some(t) => t.map_bound(ImplSubject::Trait),
|
Some(t) => t.map_bound(ImplSubject::Trait),
|
||||||
None => self.type_of(def_id).map_bound(ImplSubject::Inherent),
|
None => self.type_of(def_id).map_bound(ImplSubject::Inherent),
|
||||||
|
@ -220,7 +220,10 @@ pub enum Const<'tcx> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> Const<'tcx> {
|
impl<'tcx> Const<'tcx> {
|
||||||
pub fn identity_unevaluated(tcx: TyCtxt<'tcx>, def_id: DefId) -> ty::EarlyBinder<Const<'tcx>> {
|
pub fn identity_unevaluated(
|
||||||
|
tcx: TyCtxt<'tcx>,
|
||||||
|
def_id: DefId,
|
||||||
|
) -> ty::EarlyBinder<'tcx, Const<'tcx>> {
|
||||||
ty::EarlyBinder::bind(Const::Unevaluated(
|
ty::EarlyBinder::bind(Const::Unevaluated(
|
||||||
UnevaluatedConst {
|
UnevaluatedConst {
|
||||||
def: def_id,
|
def: def_id,
|
||||||
|
@ -624,7 +624,7 @@ impl<'tcx> Body<'tcx> {
|
|||||||
|
|
||||||
/// Returns the return type; it always return first element from `local_decls` array.
|
/// Returns the return type; it always return first element from `local_decls` array.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn bound_return_ty(&self) -> ty::EarlyBinder<Ty<'tcx>> {
|
pub fn bound_return_ty(&self) -> ty::EarlyBinder<'tcx, Ty<'tcx>> {
|
||||||
ty::EarlyBinder::bind(self.local_decls[RETURN_PLACE].ty)
|
ty::EarlyBinder::bind(self.local_decls[RETURN_PLACE].ty)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -114,9 +114,11 @@ impl EraseType for Result<CoerceUnsizedInfo, rustc_errors::ErrorGuaranteed> {
|
|||||||
type Result = [u8; size_of::<Result<CoerceUnsizedInfo, rustc_errors::ErrorGuaranteed>>()];
|
type Result = [u8; size_of::<Result<CoerceUnsizedInfo, rustc_errors::ErrorGuaranteed>>()];
|
||||||
}
|
}
|
||||||
|
|
||||||
impl EraseType for Result<Option<ty::EarlyBinder<ty::Const<'_>>>, rustc_errors::ErrorGuaranteed> {
|
impl EraseType
|
||||||
|
for Result<Option<ty::EarlyBinder<'_, ty::Const<'_>>>, rustc_errors::ErrorGuaranteed>
|
||||||
|
{
|
||||||
type Result = [u8; size_of::<
|
type Result = [u8; size_of::<
|
||||||
Result<Option<ty::EarlyBinder<ty::Const<'static>>>, rustc_errors::ErrorGuaranteed>,
|
Result<Option<ty::EarlyBinder<'static, ty::Const<'static>>>, rustc_errors::ErrorGuaranteed>,
|
||||||
>()];
|
>()];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -165,8 +167,8 @@ impl EraseType for Result<&'_ ty::List<Ty<'_>>, ty::util::AlwaysRequiresDrop> {
|
|||||||
[u8; size_of::<Result<&'static ty::List<Ty<'static>>, ty::util::AlwaysRequiresDrop>>()];
|
[u8; size_of::<Result<&'static ty::List<Ty<'static>>, ty::util::AlwaysRequiresDrop>>()];
|
||||||
}
|
}
|
||||||
|
|
||||||
impl EraseType for Result<ty::EarlyBinder<Ty<'_>>, CyclePlaceholder> {
|
impl EraseType for Result<ty::EarlyBinder<'_, Ty<'_>>, CyclePlaceholder> {
|
||||||
type Result = [u8; size_of::<Result<ty::EarlyBinder<Ty<'_>>, CyclePlaceholder>>()];
|
type Result = [u8; size_of::<Result<ty::EarlyBinder<'static, Ty<'_>>, CyclePlaceholder>>()];
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> EraseType for Option<&'_ T> {
|
impl<T> EraseType for Option<&'_ T> {
|
||||||
@ -185,15 +187,15 @@ impl EraseType for Option<ty::ImplTraitHeader<'_>> {
|
|||||||
type Result = [u8; size_of::<Option<ty::ImplTraitHeader<'static>>>()];
|
type Result = [u8; size_of::<Option<ty::ImplTraitHeader<'static>>>()];
|
||||||
}
|
}
|
||||||
|
|
||||||
impl EraseType for Option<ty::EarlyBinder<Ty<'_>>> {
|
impl EraseType for Option<ty::EarlyBinder<'_, Ty<'_>>> {
|
||||||
type Result = [u8; size_of::<Option<ty::EarlyBinder<Ty<'static>>>>()];
|
type Result = [u8; size_of::<Option<ty::EarlyBinder<'static, Ty<'static>>>>()];
|
||||||
}
|
}
|
||||||
|
|
||||||
impl EraseType for rustc_hir::MaybeOwner<'_> {
|
impl EraseType for rustc_hir::MaybeOwner<'_> {
|
||||||
type Result = [u8; size_of::<rustc_hir::MaybeOwner<'static>>()];
|
type Result = [u8; size_of::<rustc_hir::MaybeOwner<'static>>()];
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: EraseType> EraseType for ty::EarlyBinder<T> {
|
impl<T: EraseType> EraseType for ty::EarlyBinder<'_, T> {
|
||||||
type Result = T::Result;
|
type Result = T::Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -209,7 +209,7 @@ rustc_queries! {
|
|||||||
|
|
||||||
/// Given the def_id of a const-generic parameter, computes the associated default const
|
/// Given the def_id of a const-generic parameter, computes the associated default const
|
||||||
/// parameter. e.g. `fn example<const N: usize=3>` called on `N` would return `3`.
|
/// parameter. e.g. `fn example<const N: usize=3>` called on `N` would return `3`.
|
||||||
query const_param_default(param: DefId) -> ty::EarlyBinder<ty::Const<'tcx>> {
|
query const_param_default(param: DefId) -> ty::EarlyBinder<'tcx, ty::Const<'tcx>> {
|
||||||
desc { |tcx| "computing const default for a given parameter `{}`", tcx.def_path_str(param) }
|
desc { |tcx| "computing const default for a given parameter `{}`", tcx.def_path_str(param) }
|
||||||
cache_on_disk_if { param.is_local() }
|
cache_on_disk_if { param.is_local() }
|
||||||
separate_provide_extern
|
separate_provide_extern
|
||||||
@ -219,7 +219,7 @@ rustc_queries! {
|
|||||||
/// to an alias, it will "skip" this alias to return the aliased type.
|
/// to an alias, it will "skip" this alias to return the aliased type.
|
||||||
///
|
///
|
||||||
/// [`DefId`]: rustc_hir::def_id::DefId
|
/// [`DefId`]: rustc_hir::def_id::DefId
|
||||||
query type_of(key: DefId) -> ty::EarlyBinder<Ty<'tcx>> {
|
query type_of(key: DefId) -> ty::EarlyBinder<'tcx, Ty<'tcx>> {
|
||||||
desc { |tcx|
|
desc { |tcx|
|
||||||
"{action} `{path}`",
|
"{action} `{path}`",
|
||||||
action = {
|
action = {
|
||||||
@ -240,7 +240,7 @@ rustc_queries! {
|
|||||||
/// Specialized instance of `type_of` that detects cycles that are due to
|
/// Specialized instance of `type_of` that detects cycles that are due to
|
||||||
/// revealing opaque because of an auto trait bound. Unless `CyclePlaceholder` needs
|
/// revealing opaque because of an auto trait bound. Unless `CyclePlaceholder` needs
|
||||||
/// to be handled separately, call `type_of` instead.
|
/// to be handled separately, call `type_of` instead.
|
||||||
query type_of_opaque(key: DefId) -> Result<ty::EarlyBinder<Ty<'tcx>>, CyclePlaceholder> {
|
query type_of_opaque(key: DefId) -> Result<ty::EarlyBinder<'tcx, Ty<'tcx>>, CyclePlaceholder> {
|
||||||
desc { |tcx|
|
desc { |tcx|
|
||||||
"computing type of opaque `{path}`",
|
"computing type of opaque `{path}`",
|
||||||
path = tcx.def_path_str(key),
|
path = tcx.def_path_str(key),
|
||||||
@ -257,7 +257,7 @@ rustc_queries! {
|
|||||||
}
|
}
|
||||||
|
|
||||||
query collect_return_position_impl_trait_in_trait_tys(key: DefId)
|
query collect_return_position_impl_trait_in_trait_tys(key: DefId)
|
||||||
-> Result<&'tcx DefIdMap<ty::EarlyBinder<Ty<'tcx>>>, ErrorGuaranteed>
|
-> Result<&'tcx DefIdMap<ty::EarlyBinder<'tcx, Ty<'tcx>>>, ErrorGuaranteed>
|
||||||
{
|
{
|
||||||
desc { "comparing an impl and trait method signature, inferring any hidden `impl Trait` types in the process" }
|
desc { "comparing an impl and trait method signature, inferring any hidden `impl Trait` types in the process" }
|
||||||
cache_on_disk_if { key.is_local() }
|
cache_on_disk_if { key.is_local() }
|
||||||
@ -363,7 +363,7 @@ rustc_queries! {
|
|||||||
/// `key` is the `DefId` of the associated type or opaque type.
|
/// `key` is the `DefId` of the associated type or opaque type.
|
||||||
///
|
///
|
||||||
/// Bounds from the parent (e.g. with nested impl trait) are not included.
|
/// Bounds from the parent (e.g. with nested impl trait) are not included.
|
||||||
query explicit_item_bounds(key: DefId) -> ty::EarlyBinder<&'tcx [(ty::Clause<'tcx>, Span)]> {
|
query explicit_item_bounds(key: DefId) -> ty::EarlyBinder<'tcx, &'tcx [(ty::Clause<'tcx>, Span)]> {
|
||||||
desc { |tcx| "finding item bounds for `{}`", tcx.def_path_str(key) }
|
desc { |tcx| "finding item bounds for `{}`", tcx.def_path_str(key) }
|
||||||
cache_on_disk_if { key.is_local() }
|
cache_on_disk_if { key.is_local() }
|
||||||
separate_provide_extern
|
separate_provide_extern
|
||||||
@ -373,7 +373,7 @@ rustc_queries! {
|
|||||||
/// share the `Self` type of the item. These are a subset of the bounds
|
/// share the `Self` type of the item. These are a subset of the bounds
|
||||||
/// that may explicitly be used for things like closure signature
|
/// that may explicitly be used for things like closure signature
|
||||||
/// deduction.
|
/// deduction.
|
||||||
query explicit_item_super_predicates(key: DefId) -> ty::EarlyBinder<&'tcx [(ty::Clause<'tcx>, Span)]> {
|
query explicit_item_super_predicates(key: DefId) -> ty::EarlyBinder<'tcx, &'tcx [(ty::Clause<'tcx>, Span)]> {
|
||||||
desc { |tcx| "finding item bounds for `{}`", tcx.def_path_str(key) }
|
desc { |tcx| "finding item bounds for `{}`", tcx.def_path_str(key) }
|
||||||
cache_on_disk_if { key.is_local() }
|
cache_on_disk_if { key.is_local() }
|
||||||
separate_provide_extern
|
separate_provide_extern
|
||||||
@ -399,15 +399,15 @@ rustc_queries! {
|
|||||||
/// ```
|
/// ```
|
||||||
///
|
///
|
||||||
/// Bounds from the parent (e.g. with nested impl trait) are not included.
|
/// Bounds from the parent (e.g. with nested impl trait) are not included.
|
||||||
query item_bounds(key: DefId) -> ty::EarlyBinder<ty::Clauses<'tcx>> {
|
query item_bounds(key: DefId) -> ty::EarlyBinder<'tcx, ty::Clauses<'tcx>> {
|
||||||
desc { |tcx| "elaborating item bounds for `{}`", tcx.def_path_str(key) }
|
desc { |tcx| "elaborating item bounds for `{}`", tcx.def_path_str(key) }
|
||||||
}
|
}
|
||||||
|
|
||||||
query item_super_predicates(key: DefId) -> ty::EarlyBinder<ty::Clauses<'tcx>> {
|
query item_super_predicates(key: DefId) -> ty::EarlyBinder<'tcx, ty::Clauses<'tcx>> {
|
||||||
desc { |tcx| "elaborating item assumptions for `{}`", tcx.def_path_str(key) }
|
desc { |tcx| "elaborating item assumptions for `{}`", tcx.def_path_str(key) }
|
||||||
}
|
}
|
||||||
|
|
||||||
query item_non_self_assumptions(key: DefId) -> ty::EarlyBinder<ty::Clauses<'tcx>> {
|
query item_non_self_assumptions(key: DefId) -> ty::EarlyBinder<'tcx, ty::Clauses<'tcx>> {
|
||||||
desc { |tcx| "elaborating item assumptions for `{}`", tcx.def_path_str(key) }
|
desc { |tcx| "elaborating item assumptions for `{}`", tcx.def_path_str(key) }
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -504,7 +504,7 @@ rustc_queries! {
|
|||||||
/// Try to build an abstract representation of the given constant.
|
/// Try to build an abstract representation of the given constant.
|
||||||
query thir_abstract_const(
|
query thir_abstract_const(
|
||||||
key: DefId
|
key: DefId
|
||||||
) -> Result<Option<ty::EarlyBinder<ty::Const<'tcx>>>, ErrorGuaranteed> {
|
) -> Result<Option<ty::EarlyBinder<'tcx, ty::Const<'tcx>>>, ErrorGuaranteed> {
|
||||||
desc {
|
desc {
|
||||||
|tcx| "building an abstract representation for `{}`", tcx.def_path_str(key),
|
|tcx| "building an abstract representation for `{}`", tcx.def_path_str(key),
|
||||||
}
|
}
|
||||||
@ -704,7 +704,7 @@ rustc_queries! {
|
|||||||
separate_provide_extern
|
separate_provide_extern
|
||||||
}
|
}
|
||||||
|
|
||||||
query adt_sized_constraint(key: DefId) -> Option<ty::EarlyBinder<Ty<'tcx>>> {
|
query adt_sized_constraint(key: DefId) -> Option<ty::EarlyBinder<'tcx, Ty<'tcx>>> {
|
||||||
desc { |tcx| "computing the `Sized` constraint for `{}`", tcx.def_path_str(key) }
|
desc { |tcx| "computing the `Sized` constraint for `{}`", tcx.def_path_str(key) }
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -849,7 +849,7 @@ rustc_queries! {
|
|||||||
|
|
||||||
query self_ty_of_trait_impl_enabling_order_dep_trait_object_hack(
|
query self_ty_of_trait_impl_enabling_order_dep_trait_object_hack(
|
||||||
key: DefId
|
key: DefId
|
||||||
) -> Option<ty::EarlyBinder<ty::Ty<'tcx>>> {
|
) -> Option<ty::EarlyBinder<'tcx, ty::Ty<'tcx>>> {
|
||||||
desc { |tcx| "computing self type wrt issue #33140 `{}`", tcx.def_path_str(key) }
|
desc { |tcx| "computing self type wrt issue #33140 `{}`", tcx.def_path_str(key) }
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -888,7 +888,7 @@ rustc_queries! {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Computes the signature of the function.
|
/// Computes the signature of the function.
|
||||||
query fn_sig(key: DefId) -> ty::EarlyBinder<ty::PolyFnSig<'tcx>> {
|
query fn_sig(key: DefId) -> ty::EarlyBinder<'tcx, ty::PolyFnSig<'tcx>> {
|
||||||
desc { |tcx| "computing function signature of `{}`", tcx.def_path_str(key) }
|
desc { |tcx| "computing function signature of `{}`", tcx.def_path_str(key) }
|
||||||
cache_on_disk_if { key.is_local() }
|
cache_on_disk_if { key.is_local() }
|
||||||
separate_provide_extern
|
separate_provide_extern
|
||||||
|
@ -752,7 +752,7 @@ impl<'a, 'tcx> Decodable<CacheDecoder<'a, 'tcx>> for &'tcx UnordSet<LocalDefId>
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, 'tcx> Decodable<CacheDecoder<'a, 'tcx>>
|
impl<'a, 'tcx> Decodable<CacheDecoder<'a, 'tcx>>
|
||||||
for &'tcx UnordMap<DefId, ty::EarlyBinder<Ty<'tcx>>>
|
for &'tcx UnordMap<DefId, ty::EarlyBinder<'tcx, Ty<'tcx>>>
|
||||||
{
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
fn decode(d: &mut CacheDecoder<'a, 'tcx>) -> Self {
|
fn decode(d: &mut CacheDecoder<'a, 'tcx>) -> Self {
|
||||||
|
@ -30,7 +30,8 @@ impl From<ErrorGuaranteed> for NotConstEvaluatable {
|
|||||||
|
|
||||||
TrivialTypeTraversalImpls! { NotConstEvaluatable }
|
TrivialTypeTraversalImpls! { NotConstEvaluatable }
|
||||||
|
|
||||||
pub type BoundAbstractConst<'tcx> = Result<Option<EarlyBinder<ty::Const<'tcx>>>, ErrorGuaranteed>;
|
pub type BoundAbstractConst<'tcx> =
|
||||||
|
Result<Option<EarlyBinder<'tcx, ty::Const<'tcx>>>, ErrorGuaranteed>;
|
||||||
|
|
||||||
impl<'tcx> TyCtxt<'tcx> {
|
impl<'tcx> TyCtxt<'tcx> {
|
||||||
pub fn expand_abstract_consts<T: TypeFoldable<TyCtxt<'tcx>>>(self, ac: T) -> T {
|
pub fn expand_abstract_consts<T: TypeFoldable<TyCtxt<'tcx>>>(self, ac: T) -> T {
|
||||||
|
@ -579,7 +579,7 @@ impl<'tcx> AdtDef<'tcx> {
|
|||||||
|
|
||||||
/// Returns a type such that `Self: Sized` if and only if that type is `Sized`,
|
/// Returns a type such that `Self: Sized` if and only if that type is `Sized`,
|
||||||
/// or `None` if the type is always sized.
|
/// or `None` if the type is always sized.
|
||||||
pub fn sized_constraint(self, tcx: TyCtxt<'tcx>) -> Option<ty::EarlyBinder<Ty<'tcx>>> {
|
pub fn sized_constraint(self, tcx: TyCtxt<'tcx>) -> Option<ty::EarlyBinder<'tcx, Ty<'tcx>>> {
|
||||||
if self.is_struct() { tcx.adt_sized_constraint(self.did()) } else { None }
|
if self.is_struct() { tcx.adt_sized_constraint(self.did()) } else { None }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -184,6 +184,15 @@ impl<'tcx> rustc_type_ir::inherent::Const<TyCtxt<'tcx>> for Const<'tcx> {
|
|||||||
Const::new_var(tcx, vid, ty)
|
Const::new_var(tcx, vid, ty)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn new_bound(
|
||||||
|
interner: TyCtxt<'tcx>,
|
||||||
|
debruijn: ty::DebruijnIndex,
|
||||||
|
var: ty::BoundVar,
|
||||||
|
ty: Ty<'tcx>,
|
||||||
|
) -> Self {
|
||||||
|
Const::new_bound(interner, debruijn, var, ty)
|
||||||
|
}
|
||||||
|
|
||||||
fn new_anon_bound(
|
fn new_anon_bound(
|
||||||
tcx: TyCtxt<'tcx>,
|
tcx: TyCtxt<'tcx>,
|
||||||
debruijn: ty::DebruijnIndex,
|
debruijn: ty::DebruijnIndex,
|
||||||
@ -486,7 +495,10 @@ impl<'tcx> Const<'tcx> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn const_param_default(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<Const<'_>> {
|
pub fn const_param_default<'tcx>(
|
||||||
|
tcx: TyCtxt<'tcx>,
|
||||||
|
def_id: LocalDefId,
|
||||||
|
) -> ty::EarlyBinder<'tcx, Const<'tcx>> {
|
||||||
let default_def_id = match tcx.hir_node_by_def_id(def_id) {
|
let default_def_id = match tcx.hir_node_by_def_id(def_id) {
|
||||||
hir::Node::GenericParam(hir::GenericParam {
|
hir::Node::GenericParam(hir::GenericParam {
|
||||||
kind: hir::GenericParamKind::Const { default: Some(ac), .. },
|
kind: hir::GenericParamKind::Const { default: Some(ac), .. },
|
||||||
|
@ -149,8 +149,8 @@ impl<'tcx> Interner for TyCtxt<'tcx> {
|
|||||||
self.generics_of(def_id)
|
self.generics_of(def_id)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn type_of_instantiated(self, def_id: DefId, args: ty::GenericArgsRef<'tcx>) -> Ty<'tcx> {
|
fn type_of(self, def_id: DefId) -> ty::EarlyBinder<'tcx, Ty<'tcx>> {
|
||||||
self.type_of(def_id).instantiate(self, args)
|
self.type_of(def_id)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn alias_ty_kind(self, alias: ty::AliasTy<'tcx>) -> ty::AliasTyKind {
|
fn alias_ty_kind(self, alias: ty::AliasTy<'tcx>) -> ty::AliasTyKind {
|
||||||
@ -679,7 +679,7 @@ impl<'tcx> TyCtxt<'tcx> {
|
|||||||
/// In order to break cycles involving `AnonConst`, we need to set the expected type by side
|
/// In order to break cycles involving `AnonConst`, we need to set the expected type by side
|
||||||
/// effect. However, we do not want this as a general capability, so this interface restricts
|
/// effect. However, we do not want this as a general capability, so this interface restricts
|
||||||
/// to the only allowed case.
|
/// to the only allowed case.
|
||||||
pub fn feed_anon_const_type(self, key: LocalDefId, value: ty::EarlyBinder<Ty<'tcx>>) {
|
pub fn feed_anon_const_type(self, key: LocalDefId, value: ty::EarlyBinder<'tcx, Ty<'tcx>>) {
|
||||||
debug_assert_eq!(self.def_kind(key), DefKind::AnonConst);
|
debug_assert_eq!(self.def_kind(key), DefKind::AnonConst);
|
||||||
TyCtxtFeed { tcx: self, key }.type_of(value)
|
TyCtxtFeed { tcx: self, key }.type_of(value)
|
||||||
}
|
}
|
||||||
@ -2741,7 +2741,7 @@ impl<'tcx> TyCtxt<'tcx> {
|
|||||||
pub fn impl_trait_ref(
|
pub fn impl_trait_ref(
|
||||||
self,
|
self,
|
||||||
def_id: impl IntoQueryParam<DefId>,
|
def_id: impl IntoQueryParam<DefId>,
|
||||||
) -> Option<ty::EarlyBinder<ty::TraitRef<'tcx>>> {
|
) -> Option<ty::EarlyBinder<'tcx, ty::TraitRef<'tcx>>> {
|
||||||
Some(self.impl_trait_header(def_id)?.trait_ref)
|
Some(self.impl_trait_header(def_id)?.trait_ref)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,7 +3,9 @@ use rustc_data_structures::fx::FxIndexMap;
|
|||||||
use rustc_hir::def_id::DefId;
|
use rustc_hir::def_id::DefId;
|
||||||
use tracing::{debug, instrument};
|
use tracing::{debug, instrument};
|
||||||
|
|
||||||
pub use rustc_type_ir::fold::{FallibleTypeFolder, TypeFoldable, TypeFolder, TypeSuperFoldable};
|
pub use rustc_type_ir::fold::{
|
||||||
|
shift_region, shift_vars, FallibleTypeFolder, TypeFoldable, TypeFolder, TypeSuperFoldable,
|
||||||
|
};
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
||||||
// Some sample folders
|
// Some sample folders
|
||||||
@ -412,103 +414,3 @@ impl<'tcx> TyCtxt<'tcx> {
|
|||||||
Binder::bind_with_vars(inner, bound_vars)
|
Binder::bind_with_vars(inner, bound_vars)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
// Shifter
|
|
||||||
//
|
|
||||||
// Shifts the De Bruijn indices on all escaping bound vars by a
|
|
||||||
// fixed amount. Useful in instantiation or when otherwise introducing
|
|
||||||
// a binding level that is not intended to capture the existing bound
|
|
||||||
// vars. See comment on `shift_vars_through_binders` method in
|
|
||||||
// `rustc_middle/src/ty/generic_args.rs` for more details.
|
|
||||||
|
|
||||||
struct Shifter<'tcx> {
|
|
||||||
tcx: TyCtxt<'tcx>,
|
|
||||||
current_index: ty::DebruijnIndex,
|
|
||||||
amount: u32,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'tcx> Shifter<'tcx> {
|
|
||||||
pub fn new(tcx: TyCtxt<'tcx>, amount: u32) -> Self {
|
|
||||||
Shifter { tcx, current_index: ty::INNERMOST, amount }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'tcx> TypeFolder<TyCtxt<'tcx>> for Shifter<'tcx> {
|
|
||||||
fn interner(&self) -> TyCtxt<'tcx> {
|
|
||||||
self.tcx
|
|
||||||
}
|
|
||||||
|
|
||||||
fn fold_binder<T: TypeFoldable<TyCtxt<'tcx>>>(
|
|
||||||
&mut self,
|
|
||||||
t: ty::Binder<'tcx, T>,
|
|
||||||
) -> ty::Binder<'tcx, T> {
|
|
||||||
self.current_index.shift_in(1);
|
|
||||||
let t = t.super_fold_with(self);
|
|
||||||
self.current_index.shift_out(1);
|
|
||||||
t
|
|
||||||
}
|
|
||||||
|
|
||||||
fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> {
|
|
||||||
match *r {
|
|
||||||
ty::ReBound(debruijn, br) if debruijn >= self.current_index => {
|
|
||||||
let debruijn = debruijn.shifted_in(self.amount);
|
|
||||||
ty::Region::new_bound(self.tcx, debruijn, br)
|
|
||||||
}
|
|
||||||
_ => r,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {
|
|
||||||
match *ty.kind() {
|
|
||||||
ty::Bound(debruijn, bound_ty) if debruijn >= self.current_index => {
|
|
||||||
let debruijn = debruijn.shifted_in(self.amount);
|
|
||||||
Ty::new_bound(self.tcx, debruijn, bound_ty)
|
|
||||||
}
|
|
||||||
|
|
||||||
_ if ty.has_vars_bound_at_or_above(self.current_index) => ty.super_fold_with(self),
|
|
||||||
_ => ty,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn fold_const(&mut self, ct: ty::Const<'tcx>) -> ty::Const<'tcx> {
|
|
||||||
if let ty::ConstKind::Bound(debruijn, bound_ct) = ct.kind()
|
|
||||||
&& debruijn >= self.current_index
|
|
||||||
{
|
|
||||||
let debruijn = debruijn.shifted_in(self.amount);
|
|
||||||
ty::Const::new_bound(self.tcx, debruijn, bound_ct, ct.ty())
|
|
||||||
} else {
|
|
||||||
ct.super_fold_with(self)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn fold_predicate(&mut self, p: ty::Predicate<'tcx>) -> ty::Predicate<'tcx> {
|
|
||||||
if p.has_vars_bound_at_or_above(self.current_index) { p.super_fold_with(self) } else { p }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn shift_region<'tcx>(
|
|
||||||
tcx: TyCtxt<'tcx>,
|
|
||||||
region: ty::Region<'tcx>,
|
|
||||||
amount: u32,
|
|
||||||
) -> ty::Region<'tcx> {
|
|
||||||
match *region {
|
|
||||||
ty::ReBound(debruijn, br) if amount > 0 => {
|
|
||||||
ty::Region::new_bound(tcx, debruijn.shifted_in(amount), br)
|
|
||||||
}
|
|
||||||
_ => region,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn shift_vars<'tcx, T>(tcx: TyCtxt<'tcx>, value: T, amount: u32) -> T
|
|
||||||
where
|
|
||||||
T: TypeFoldable<TyCtxt<'tcx>>,
|
|
||||||
{
|
|
||||||
debug!("shift_vars(value={:?}, amount={})", value, amount);
|
|
||||||
|
|
||||||
if amount == 0 || !value.has_escaping_bound_vars() {
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
value.fold_with(&mut Shifter::new(tcx, amount))
|
|
||||||
}
|
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
// Generic arguments.
|
// Generic arguments.
|
||||||
|
|
||||||
use crate::ty::codec::{TyDecoder, TyEncoder};
|
use crate::ty::codec::{TyDecoder, TyEncoder};
|
||||||
use crate::ty::fold::{FallibleTypeFolder, TypeFoldable, TypeFolder, TypeSuperFoldable};
|
use crate::ty::fold::{FallibleTypeFolder, TypeFoldable};
|
||||||
use crate::ty::sty::{ClosureArgs, CoroutineArgs, CoroutineClosureArgs, InlineConstArgs};
|
use crate::ty::sty::{ClosureArgs, CoroutineArgs, CoroutineClosureArgs, InlineConstArgs};
|
||||||
use crate::ty::visit::{TypeVisitable, TypeVisitableExt, TypeVisitor};
|
use crate::ty::visit::{TypeVisitable, TypeVisitor};
|
||||||
use crate::ty::{self, Lift, List, ParamConst, Ty, TyCtxt};
|
use crate::ty::{self, Lift, List, Ty, TyCtxt};
|
||||||
|
|
||||||
use rustc_ast_ir::visit::VisitorResult;
|
use rustc_ast_ir::visit::VisitorResult;
|
||||||
use rustc_ast_ir::walk_visitable_list;
|
use rustc_ast_ir::walk_visitable_list;
|
||||||
@ -12,19 +12,15 @@ use rustc_data_structures::intern::Interned;
|
|||||||
use rustc_errors::{DiagArgValue, IntoDiagArg};
|
use rustc_errors::{DiagArgValue, IntoDiagArg};
|
||||||
use rustc_hir::def_id::DefId;
|
use rustc_hir::def_id::DefId;
|
||||||
use rustc_macros::extension;
|
use rustc_macros::extension;
|
||||||
use rustc_macros::{
|
use rustc_macros::{HashStable, TyDecodable, TyEncodable, TypeFoldable, TypeVisitable};
|
||||||
Decodable, Encodable, HashStable, TyDecodable, TyEncodable, TypeFoldable, TypeVisitable,
|
|
||||||
};
|
|
||||||
use rustc_serialize::{Decodable, Encodable};
|
use rustc_serialize::{Decodable, Encodable};
|
||||||
use rustc_type_ir::WithCachedTypeInfo;
|
use rustc_type_ir::WithCachedTypeInfo;
|
||||||
use smallvec::SmallVec;
|
use smallvec::SmallVec;
|
||||||
use tracing::debug;
|
|
||||||
|
|
||||||
use core::intrinsics;
|
use core::intrinsics;
|
||||||
use std::marker::PhantomData;
|
use std::marker::PhantomData;
|
||||||
use std::mem;
|
use std::mem;
|
||||||
use std::num::NonZero;
|
use std::num::NonZero;
|
||||||
use std::ops::Deref;
|
|
||||||
use std::ptr::NonNull;
|
use std::ptr::NonNull;
|
||||||
|
|
||||||
pub type GenericArgKind<'tcx> = rustc_type_ir::GenericArgKind<TyCtxt<'tcx>>;
|
pub type GenericArgKind<'tcx> = rustc_type_ir::GenericArgKind<TyCtxt<'tcx>>;
|
||||||
@ -576,490 +572,6 @@ impl<'tcx, T: TypeVisitable<TyCtxt<'tcx>>> TypeVisitable<TyCtxt<'tcx>> for &'tcx
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Similar to [`super::Binder`] except that it tracks early bound generics, i.e. `struct Foo<T>(T)`
|
|
||||||
/// needs `T` instantiated immediately. This type primarily exists to avoid forgetting to call
|
|
||||||
/// `instantiate`.
|
|
||||||
///
|
|
||||||
/// If you don't have anything to `instantiate`, you may be looking for
|
|
||||||
/// [`instantiate_identity`](EarlyBinder::instantiate_identity) or [`skip_binder`](EarlyBinder::skip_binder).
|
|
||||||
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
|
|
||||||
#[derive(Encodable, Decodable, HashStable)]
|
|
||||||
pub struct EarlyBinder<T> {
|
|
||||||
value: T,
|
|
||||||
}
|
|
||||||
|
|
||||||
/// For early binders, you should first call `instantiate` before using any visitors.
|
|
||||||
impl<'tcx, T> !TypeFoldable<TyCtxt<'tcx>> for ty::EarlyBinder<T> {}
|
|
||||||
impl<'tcx, T> !TypeVisitable<TyCtxt<'tcx>> for ty::EarlyBinder<T> {}
|
|
||||||
|
|
||||||
impl<T> EarlyBinder<T> {
|
|
||||||
pub fn bind(value: T) -> EarlyBinder<T> {
|
|
||||||
EarlyBinder { value }
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn as_ref(&self) -> EarlyBinder<&T> {
|
|
||||||
EarlyBinder { value: &self.value }
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn map_bound_ref<F, U>(&self, f: F) -> EarlyBinder<U>
|
|
||||||
where
|
|
||||||
F: FnOnce(&T) -> U,
|
|
||||||
{
|
|
||||||
self.as_ref().map_bound(f)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn map_bound<F, U>(self, f: F) -> EarlyBinder<U>
|
|
||||||
where
|
|
||||||
F: FnOnce(T) -> U,
|
|
||||||
{
|
|
||||||
let value = f(self.value);
|
|
||||||
EarlyBinder { value }
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn try_map_bound<F, U, E>(self, f: F) -> Result<EarlyBinder<U>, E>
|
|
||||||
where
|
|
||||||
F: FnOnce(T) -> Result<U, E>,
|
|
||||||
{
|
|
||||||
let value = f(self.value)?;
|
|
||||||
Ok(EarlyBinder { value })
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn rebind<U>(&self, value: U) -> EarlyBinder<U> {
|
|
||||||
EarlyBinder { value }
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Skips the binder and returns the "bound" value.
|
|
||||||
/// This can be used to extract data that does not depend on generic parameters
|
|
||||||
/// (e.g., getting the `DefId` of the inner value or getting the number of
|
|
||||||
/// arguments of an `FnSig`). Otherwise, consider using
|
|
||||||
/// [`instantiate_identity`](EarlyBinder::instantiate_identity).
|
|
||||||
///
|
|
||||||
/// To skip the binder on `x: &EarlyBinder<T>` to obtain `&T`, leverage
|
|
||||||
/// [`EarlyBinder::as_ref`](EarlyBinder::as_ref): `x.as_ref().skip_binder()`.
|
|
||||||
///
|
|
||||||
/// See also [`Binder::skip_binder`](super::Binder::skip_binder), which is
|
|
||||||
/// the analogous operation on [`super::Binder`].
|
|
||||||
pub fn skip_binder(self) -> T {
|
|
||||||
self.value
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T> EarlyBinder<Option<T>> {
|
|
||||||
pub fn transpose(self) -> Option<EarlyBinder<T>> {
|
|
||||||
self.value.map(|value| EarlyBinder { value })
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'tcx, 's, I: IntoIterator> EarlyBinder<I>
|
|
||||||
where
|
|
||||||
I::Item: TypeFoldable<TyCtxt<'tcx>>,
|
|
||||||
{
|
|
||||||
pub fn iter_instantiated(
|
|
||||||
self,
|
|
||||||
tcx: TyCtxt<'tcx>,
|
|
||||||
args: &'s [GenericArg<'tcx>],
|
|
||||||
) -> IterInstantiated<'s, 'tcx, I> {
|
|
||||||
IterInstantiated { it: self.value.into_iter(), tcx, args }
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Similar to [`instantiate_identity`](EarlyBinder::instantiate_identity),
|
|
||||||
/// but on an iterator of `TypeFoldable` values.
|
|
||||||
pub fn instantiate_identity_iter(self) -> I::IntoIter {
|
|
||||||
self.value.into_iter()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct IterInstantiated<'s, 'tcx, I: IntoIterator> {
|
|
||||||
it: I::IntoIter,
|
|
||||||
tcx: TyCtxt<'tcx>,
|
|
||||||
args: &'s [GenericArg<'tcx>],
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'tcx, I: IntoIterator> Iterator for IterInstantiated<'_, 'tcx, I>
|
|
||||||
where
|
|
||||||
I::Item: TypeFoldable<TyCtxt<'tcx>>,
|
|
||||||
{
|
|
||||||
type Item = I::Item;
|
|
||||||
|
|
||||||
fn next(&mut self) -> Option<Self::Item> {
|
|
||||||
Some(EarlyBinder { value: self.it.next()? }.instantiate(self.tcx, self.args))
|
|
||||||
}
|
|
||||||
|
|
||||||
fn size_hint(&self) -> (usize, Option<usize>) {
|
|
||||||
self.it.size_hint()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'tcx, I: IntoIterator> DoubleEndedIterator for IterInstantiated<'_, 'tcx, I>
|
|
||||||
where
|
|
||||||
I::IntoIter: DoubleEndedIterator,
|
|
||||||
I::Item: TypeFoldable<TyCtxt<'tcx>>,
|
|
||||||
{
|
|
||||||
fn next_back(&mut self) -> Option<Self::Item> {
|
|
||||||
Some(EarlyBinder { value: self.it.next_back()? }.instantiate(self.tcx, self.args))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'tcx, I: IntoIterator> ExactSizeIterator for IterInstantiated<'_, 'tcx, I>
|
|
||||||
where
|
|
||||||
I::IntoIter: ExactSizeIterator,
|
|
||||||
I::Item: TypeFoldable<TyCtxt<'tcx>>,
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'tcx, 's, I: IntoIterator> EarlyBinder<I>
|
|
||||||
where
|
|
||||||
I::Item: Deref,
|
|
||||||
<I::Item as Deref>::Target: Copy + TypeFoldable<TyCtxt<'tcx>>,
|
|
||||||
{
|
|
||||||
pub fn iter_instantiated_copied(
|
|
||||||
self,
|
|
||||||
tcx: TyCtxt<'tcx>,
|
|
||||||
args: &'s [GenericArg<'tcx>],
|
|
||||||
) -> IterInstantiatedCopied<'s, 'tcx, I> {
|
|
||||||
IterInstantiatedCopied { it: self.value.into_iter(), tcx, args }
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Similar to [`instantiate_identity`](EarlyBinder::instantiate_identity),
|
|
||||||
/// but on an iterator of values that deref to a `TypeFoldable`.
|
|
||||||
pub fn instantiate_identity_iter_copied(
|
|
||||||
self,
|
|
||||||
) -> impl Iterator<Item = <I::Item as Deref>::Target> {
|
|
||||||
self.value.into_iter().map(|v| *v)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct IterInstantiatedCopied<'a, 'tcx, I: IntoIterator> {
|
|
||||||
it: I::IntoIter,
|
|
||||||
tcx: TyCtxt<'tcx>,
|
|
||||||
args: &'a [GenericArg<'tcx>],
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'tcx, I: IntoIterator> Iterator for IterInstantiatedCopied<'_, 'tcx, I>
|
|
||||||
where
|
|
||||||
I::Item: Deref,
|
|
||||||
<I::Item as Deref>::Target: Copy + TypeFoldable<TyCtxt<'tcx>>,
|
|
||||||
{
|
|
||||||
type Item = <I::Item as Deref>::Target;
|
|
||||||
|
|
||||||
fn next(&mut self) -> Option<Self::Item> {
|
|
||||||
self.it.next().map(|value| EarlyBinder { value: *value }.instantiate(self.tcx, self.args))
|
|
||||||
}
|
|
||||||
|
|
||||||
fn size_hint(&self) -> (usize, Option<usize>) {
|
|
||||||
self.it.size_hint()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'tcx, I: IntoIterator> DoubleEndedIterator for IterInstantiatedCopied<'_, 'tcx, I>
|
|
||||||
where
|
|
||||||
I::IntoIter: DoubleEndedIterator,
|
|
||||||
I::Item: Deref,
|
|
||||||
<I::Item as Deref>::Target: Copy + TypeFoldable<TyCtxt<'tcx>>,
|
|
||||||
{
|
|
||||||
fn next_back(&mut self) -> Option<Self::Item> {
|
|
||||||
self.it
|
|
||||||
.next_back()
|
|
||||||
.map(|value| EarlyBinder { value: *value }.instantiate(self.tcx, self.args))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'tcx, I: IntoIterator> ExactSizeIterator for IterInstantiatedCopied<'_, 'tcx, I>
|
|
||||||
where
|
|
||||||
I::IntoIter: ExactSizeIterator,
|
|
||||||
I::Item: Deref,
|
|
||||||
<I::Item as Deref>::Target: Copy + TypeFoldable<TyCtxt<'tcx>>,
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct EarlyBinderIter<T> {
|
|
||||||
t: T,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T: IntoIterator> EarlyBinder<T> {
|
|
||||||
pub fn transpose_iter(self) -> EarlyBinderIter<T::IntoIter> {
|
|
||||||
EarlyBinderIter { t: self.value.into_iter() }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T: Iterator> Iterator for EarlyBinderIter<T> {
|
|
||||||
type Item = EarlyBinder<T::Item>;
|
|
||||||
|
|
||||||
fn next(&mut self) -> Option<Self::Item> {
|
|
||||||
self.t.next().map(|value| EarlyBinder { value })
|
|
||||||
}
|
|
||||||
|
|
||||||
fn size_hint(&self) -> (usize, Option<usize>) {
|
|
||||||
self.t.size_hint()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'tcx, T: TypeFoldable<TyCtxt<'tcx>>> ty::EarlyBinder<T> {
|
|
||||||
pub fn instantiate(self, tcx: TyCtxt<'tcx>, args: &[GenericArg<'tcx>]) -> T {
|
|
||||||
let mut folder = ArgFolder { tcx, args, binders_passed: 0 };
|
|
||||||
self.value.fold_with(&mut folder)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Makes the identity replacement `T0 => T0, ..., TN => TN`.
|
|
||||||
/// Conceptually, this converts universally bound variables into placeholders
|
|
||||||
/// when inside of a given item.
|
|
||||||
///
|
|
||||||
/// For example, consider `for<T> fn foo<T>(){ .. }`:
|
|
||||||
/// - Outside of `foo`, `T` is bound (represented by the presence of `EarlyBinder`).
|
|
||||||
/// - Inside of the body of `foo`, we treat `T` as a placeholder by calling
|
|
||||||
/// `instantiate_identity` to discharge the `EarlyBinder`.
|
|
||||||
pub fn instantiate_identity(self) -> T {
|
|
||||||
self.value
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns the inner value, but only if it contains no bound vars.
|
|
||||||
pub fn no_bound_vars(self) -> Option<T> {
|
|
||||||
if !self.value.has_param() { Some(self.value) } else { None }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
// The actual instantiation engine itself is a type folder.
|
|
||||||
|
|
||||||
struct ArgFolder<'a, 'tcx> {
|
|
||||||
tcx: TyCtxt<'tcx>,
|
|
||||||
args: &'a [GenericArg<'tcx>],
|
|
||||||
|
|
||||||
/// Number of region binders we have passed through while doing the instantiation
|
|
||||||
binders_passed: u32,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a, 'tcx> TypeFolder<TyCtxt<'tcx>> for ArgFolder<'a, 'tcx> {
|
|
||||||
#[inline]
|
|
||||||
fn interner(&self) -> TyCtxt<'tcx> {
|
|
||||||
self.tcx
|
|
||||||
}
|
|
||||||
|
|
||||||
fn fold_binder<T: TypeFoldable<TyCtxt<'tcx>>>(
|
|
||||||
&mut self,
|
|
||||||
t: ty::Binder<'tcx, T>,
|
|
||||||
) -> ty::Binder<'tcx, T> {
|
|
||||||
self.binders_passed += 1;
|
|
||||||
let t = t.super_fold_with(self);
|
|
||||||
self.binders_passed -= 1;
|
|
||||||
t
|
|
||||||
}
|
|
||||||
|
|
||||||
fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> {
|
|
||||||
#[cold]
|
|
||||||
#[inline(never)]
|
|
||||||
fn region_param_out_of_range(data: ty::EarlyParamRegion, args: &[GenericArg<'_>]) -> ! {
|
|
||||||
bug!(
|
|
||||||
"Region parameter out of range when instantiating in region {} (index={}, args = {:?})",
|
|
||||||
data.name,
|
|
||||||
data.index,
|
|
||||||
args,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cold]
|
|
||||||
#[inline(never)]
|
|
||||||
fn region_param_invalid(data: ty::EarlyParamRegion, other: GenericArgKind<'_>) -> ! {
|
|
||||||
bug!(
|
|
||||||
"Unexpected parameter {:?} when instantiating in region {} (index={})",
|
|
||||||
other,
|
|
||||||
data.name,
|
|
||||||
data.index
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Note: This routine only handles regions that are bound on
|
|
||||||
// type declarations and other outer declarations, not those
|
|
||||||
// bound in *fn types*. Region instantiation of the bound
|
|
||||||
// regions that appear in a function signature is done using
|
|
||||||
// the specialized routine `ty::replace_late_regions()`.
|
|
||||||
match *r {
|
|
||||||
ty::ReEarlyParam(data) => {
|
|
||||||
let rk = self.args.get(data.index as usize).map(|k| k.unpack());
|
|
||||||
match rk {
|
|
||||||
Some(GenericArgKind::Lifetime(lt)) => self.shift_region_through_binders(lt),
|
|
||||||
Some(other) => region_param_invalid(data, other),
|
|
||||||
None => region_param_out_of_range(data, self.args),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ty::ReBound(..)
|
|
||||||
| ty::ReLateParam(_)
|
|
||||||
| ty::ReStatic
|
|
||||||
| ty::RePlaceholder(_)
|
|
||||||
| ty::ReErased
|
|
||||||
| ty::ReError(_) => r,
|
|
||||||
ty::ReVar(_) => bug!("unexpected region: {r:?}"),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> {
|
|
||||||
if !t.has_param() {
|
|
||||||
return t;
|
|
||||||
}
|
|
||||||
|
|
||||||
match *t.kind() {
|
|
||||||
ty::Param(p) => self.ty_for_param(p, t),
|
|
||||||
_ => t.super_fold_with(self),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn fold_const(&mut self, c: ty::Const<'tcx>) -> ty::Const<'tcx> {
|
|
||||||
if let ty::ConstKind::Param(p) = c.kind() {
|
|
||||||
self.const_for_param(p, c)
|
|
||||||
} else {
|
|
||||||
c.super_fold_with(self)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a, 'tcx> ArgFolder<'a, 'tcx> {
|
|
||||||
fn ty_for_param(&self, p: ty::ParamTy, source_ty: Ty<'tcx>) -> Ty<'tcx> {
|
|
||||||
// Look up the type in the args. It really should be in there.
|
|
||||||
let opt_ty = self.args.get(p.index as usize).map(|k| k.unpack());
|
|
||||||
let ty = match opt_ty {
|
|
||||||
Some(GenericArgKind::Type(ty)) => ty,
|
|
||||||
Some(kind) => self.type_param_expected(p, source_ty, kind),
|
|
||||||
None => self.type_param_out_of_range(p, source_ty),
|
|
||||||
};
|
|
||||||
|
|
||||||
self.shift_vars_through_binders(ty)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cold]
|
|
||||||
#[inline(never)]
|
|
||||||
fn type_param_expected(&self, p: ty::ParamTy, ty: Ty<'tcx>, kind: GenericArgKind<'tcx>) -> ! {
|
|
||||||
bug!(
|
|
||||||
"expected type for `{:?}` ({:?}/{}) but found {:?} when instantiating, args={:?}",
|
|
||||||
p,
|
|
||||||
ty,
|
|
||||||
p.index,
|
|
||||||
kind,
|
|
||||||
self.args,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cold]
|
|
||||||
#[inline(never)]
|
|
||||||
fn type_param_out_of_range(&self, p: ty::ParamTy, ty: Ty<'tcx>) -> ! {
|
|
||||||
bug!(
|
|
||||||
"type parameter `{:?}` ({:?}/{}) out of range when instantiating, args={:?}",
|
|
||||||
p,
|
|
||||||
ty,
|
|
||||||
p.index,
|
|
||||||
self.args,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn const_for_param(&self, p: ParamConst, source_ct: ty::Const<'tcx>) -> ty::Const<'tcx> {
|
|
||||||
// Look up the const in the args. It really should be in there.
|
|
||||||
let opt_ct = self.args.get(p.index as usize).map(|k| k.unpack());
|
|
||||||
let ct = match opt_ct {
|
|
||||||
Some(GenericArgKind::Const(ct)) => ct,
|
|
||||||
Some(kind) => self.const_param_expected(p, source_ct, kind),
|
|
||||||
None => self.const_param_out_of_range(p, source_ct),
|
|
||||||
};
|
|
||||||
|
|
||||||
self.shift_vars_through_binders(ct)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cold]
|
|
||||||
#[inline(never)]
|
|
||||||
fn const_param_expected(
|
|
||||||
&self,
|
|
||||||
p: ty::ParamConst,
|
|
||||||
ct: ty::Const<'tcx>,
|
|
||||||
kind: GenericArgKind<'tcx>,
|
|
||||||
) -> ! {
|
|
||||||
bug!(
|
|
||||||
"expected const for `{:?}` ({:?}/{}) but found {:?} when instantiating args={:?}",
|
|
||||||
p,
|
|
||||||
ct,
|
|
||||||
p.index,
|
|
||||||
kind,
|
|
||||||
self.args,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cold]
|
|
||||||
#[inline(never)]
|
|
||||||
fn const_param_out_of_range(&self, p: ty::ParamConst, ct: ty::Const<'tcx>) -> ! {
|
|
||||||
bug!(
|
|
||||||
"const parameter `{:?}` ({:?}/{}) out of range when instantiating args={:?}",
|
|
||||||
p,
|
|
||||||
ct,
|
|
||||||
p.index,
|
|
||||||
self.args,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// It is sometimes necessary to adjust the De Bruijn indices during instantiation. This occurs
|
|
||||||
/// when we are instantating a type with escaping bound vars into a context where we have
|
|
||||||
/// passed through binders. That's quite a mouthful. Let's see an example:
|
|
||||||
///
|
|
||||||
/// ```
|
|
||||||
/// type Func<A> = fn(A);
|
|
||||||
/// type MetaFunc = for<'a> fn(Func<&'a i32>);
|
|
||||||
/// ```
|
|
||||||
///
|
|
||||||
/// The type `MetaFunc`, when fully expanded, will be
|
|
||||||
/// ```ignore (illustrative)
|
|
||||||
/// for<'a> fn(fn(&'a i32))
|
|
||||||
/// // ^~ ^~ ^~~
|
|
||||||
/// // | | |
|
|
||||||
/// // | | DebruijnIndex of 2
|
|
||||||
/// // Binders
|
|
||||||
/// ```
|
|
||||||
/// Here the `'a` lifetime is bound in the outer function, but appears as an argument of the
|
|
||||||
/// inner one. Therefore, that appearance will have a DebruijnIndex of 2, because we must skip
|
|
||||||
/// over the inner binder (remember that we count De Bruijn indices from 1). However, in the
|
|
||||||
/// definition of `MetaFunc`, the binder is not visible, so the type `&'a i32` will have a
|
|
||||||
/// De Bruijn index of 1. It's only during the instantiation that we can see we must increase the
|
|
||||||
/// depth by 1 to account for the binder that we passed through.
|
|
||||||
///
|
|
||||||
/// As a second example, consider this twist:
|
|
||||||
///
|
|
||||||
/// ```
|
|
||||||
/// type FuncTuple<A> = (A,fn(A));
|
|
||||||
/// type MetaFuncTuple = for<'a> fn(FuncTuple<&'a i32>);
|
|
||||||
/// ```
|
|
||||||
///
|
|
||||||
/// Here the final type will be:
|
|
||||||
/// ```ignore (illustrative)
|
|
||||||
/// for<'a> fn((&'a i32, fn(&'a i32)))
|
|
||||||
/// // ^~~ ^~~
|
|
||||||
/// // | |
|
|
||||||
/// // DebruijnIndex of 1 |
|
|
||||||
/// // DebruijnIndex of 2
|
|
||||||
/// ```
|
|
||||||
/// As indicated in the diagram, here the same type `&'a i32` is instantiated once, but in the
|
|
||||||
/// first case we do not increase the De Bruijn index and in the second case we do. The reason
|
|
||||||
/// is that only in the second case have we passed through a fn binder.
|
|
||||||
fn shift_vars_through_binders<T: TypeFoldable<TyCtxt<'tcx>>>(&self, val: T) -> T {
|
|
||||||
debug!(
|
|
||||||
"shift_vars(val={:?}, binders_passed={:?}, has_escaping_bound_vars={:?})",
|
|
||||||
val,
|
|
||||||
self.binders_passed,
|
|
||||||
val.has_escaping_bound_vars()
|
|
||||||
);
|
|
||||||
|
|
||||||
if self.binders_passed == 0 || !val.has_escaping_bound_vars() {
|
|
||||||
return val;
|
|
||||||
}
|
|
||||||
|
|
||||||
let result = ty::fold::shift_vars(TypeFolder::interner(self), val, self.binders_passed);
|
|
||||||
debug!("shift_vars: shifted result = {:?}", result);
|
|
||||||
|
|
||||||
result
|
|
||||||
}
|
|
||||||
|
|
||||||
fn shift_region_through_binders(&self, region: ty::Region<'tcx>) -> ty::Region<'tcx> {
|
|
||||||
if self.binders_passed == 0 || !region.has_escaping_bound_vars() {
|
|
||||||
return region;
|
|
||||||
}
|
|
||||||
ty::fold::shift_region(self.tcx, region, self.binders_passed)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Stores the user-given args to reach some fully qualified path
|
/// Stores the user-given args to reach some fully qualified path
|
||||||
/// (e.g., `<T>::Item` or `<T as Trait>::Item`).
|
/// (e.g., `<T>::Item` or `<T as Trait>::Item`).
|
||||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, TyEncodable, TyDecodable)]
|
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, TyEncodable, TyDecodable)]
|
||||||
|
@ -88,7 +88,7 @@ impl GenericParamDef {
|
|||||||
pub fn default_value<'tcx>(
|
pub fn default_value<'tcx>(
|
||||||
&self,
|
&self,
|
||||||
tcx: TyCtxt<'tcx>,
|
tcx: TyCtxt<'tcx>,
|
||||||
) -> Option<EarlyBinder<ty::GenericArg<'tcx>>> {
|
) -> Option<EarlyBinder<'tcx, ty::GenericArg<'tcx>>> {
|
||||||
match self.kind {
|
match self.kind {
|
||||||
GenericParamDefKind::Type { has_default, .. } if has_default => {
|
GenericParamDefKind::Type { has_default, .. } if has_default => {
|
||||||
Some(tcx.type_of(self.def_id).map_bound(|t| t.into()))
|
Some(tcx.type_of(self.def_id).map_bound(|t| t.into()))
|
||||||
|
@ -764,7 +764,7 @@ impl<'tcx> Instance<'tcx> {
|
|||||||
self.def.has_polymorphic_mir_body().then_some(self.args)
|
self.def.has_polymorphic_mir_body().then_some(self.args)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn instantiate_mir<T>(&self, tcx: TyCtxt<'tcx>, v: EarlyBinder<&T>) -> T
|
pub fn instantiate_mir<T>(&self, tcx: TyCtxt<'tcx>, v: EarlyBinder<'tcx, &T>) -> T
|
||||||
where
|
where
|
||||||
T: TypeFoldable<TyCtxt<'tcx>> + Copy,
|
T: TypeFoldable<TyCtxt<'tcx>> + Copy,
|
||||||
{
|
{
|
||||||
@ -782,7 +782,7 @@ impl<'tcx> Instance<'tcx> {
|
|||||||
&self,
|
&self,
|
||||||
tcx: TyCtxt<'tcx>,
|
tcx: TyCtxt<'tcx>,
|
||||||
param_env: ty::ParamEnv<'tcx>,
|
param_env: ty::ParamEnv<'tcx>,
|
||||||
v: EarlyBinder<T>,
|
v: EarlyBinder<'tcx, T>,
|
||||||
) -> T
|
) -> T
|
||||||
where
|
where
|
||||||
T: TypeFoldable<TyCtxt<'tcx>>,
|
T: TypeFoldable<TyCtxt<'tcx>>,
|
||||||
@ -800,7 +800,7 @@ impl<'tcx> Instance<'tcx> {
|
|||||||
&self,
|
&self,
|
||||||
tcx: TyCtxt<'tcx>,
|
tcx: TyCtxt<'tcx>,
|
||||||
param_env: ty::ParamEnv<'tcx>,
|
param_env: ty::ParamEnv<'tcx>,
|
||||||
v: EarlyBinder<T>,
|
v: EarlyBinder<'tcx, T>,
|
||||||
) -> Result<T, NormalizationError<'tcx>>
|
) -> Result<T, NormalizationError<'tcx>>
|
||||||
where
|
where
|
||||||
T: TypeFoldable<TyCtxt<'tcx>>,
|
T: TypeFoldable<TyCtxt<'tcx>>,
|
||||||
|
@ -114,9 +114,9 @@ pub use self::rvalue_scopes::RvalueScopes;
|
|||||||
pub use self::sty::{
|
pub use self::sty::{
|
||||||
AliasTy, Article, Binder, BoundTy, BoundTyKind, BoundVariableKind, CanonicalPolyFnSig,
|
AliasTy, Article, Binder, BoundTy, BoundTyKind, BoundVariableKind, CanonicalPolyFnSig,
|
||||||
ClosureArgs, ClosureArgsParts, CoroutineArgs, CoroutineArgsParts, CoroutineClosureArgs,
|
ClosureArgs, ClosureArgsParts, CoroutineArgs, CoroutineArgsParts, CoroutineClosureArgs,
|
||||||
CoroutineClosureArgsParts, CoroutineClosureSignature, FnSig, GenSig, InlineConstArgs,
|
CoroutineClosureArgsParts, CoroutineClosureSignature, EarlyBinder, FnSig, GenSig,
|
||||||
InlineConstArgsParts, ParamConst, ParamTy, PolyFnSig, TyKind, TypeAndMut, UpvarArgs,
|
InlineConstArgs, InlineConstArgsParts, ParamConst, ParamTy, PolyFnSig, TyKind, TypeAndMut,
|
||||||
VarianceDiagInfo,
|
UpvarArgs, VarianceDiagInfo,
|
||||||
};
|
};
|
||||||
pub use self::trait_def::TraitDef;
|
pub use self::trait_def::TraitDef;
|
||||||
pub use self::typeck_results::{
|
pub use self::typeck_results::{
|
||||||
@ -266,7 +266,7 @@ pub struct ImplHeader<'tcx> {
|
|||||||
|
|
||||||
#[derive(Copy, Clone, Debug, TyEncodable, TyDecodable, HashStable)]
|
#[derive(Copy, Clone, Debug, TyEncodable, TyDecodable, HashStable)]
|
||||||
pub struct ImplTraitHeader<'tcx> {
|
pub struct ImplTraitHeader<'tcx> {
|
||||||
pub trait_ref: ty::EarlyBinder<ty::TraitRef<'tcx>>,
|
pub trait_ref: ty::EarlyBinder<'tcx, ty::TraitRef<'tcx>>,
|
||||||
pub polarity: ImplPolarity,
|
pub polarity: ImplPolarity,
|
||||||
pub safety: hir::Safety,
|
pub safety: hir::Safety,
|
||||||
}
|
}
|
||||||
|
@ -125,7 +125,7 @@ impl<'tcx> TyCtxt<'tcx> {
|
|||||||
self,
|
self,
|
||||||
param_args: GenericArgsRef<'tcx>,
|
param_args: GenericArgsRef<'tcx>,
|
||||||
param_env: ty::ParamEnv<'tcx>,
|
param_env: ty::ParamEnv<'tcx>,
|
||||||
value: EarlyBinder<T>,
|
value: EarlyBinder<'tcx, T>,
|
||||||
) -> T
|
) -> T
|
||||||
where
|
where
|
||||||
T: TypeFoldable<TyCtxt<'tcx>>,
|
T: TypeFoldable<TyCtxt<'tcx>>,
|
||||||
@ -143,7 +143,7 @@ impl<'tcx> TyCtxt<'tcx> {
|
|||||||
self,
|
self,
|
||||||
param_args: GenericArgsRef<'tcx>,
|
param_args: GenericArgsRef<'tcx>,
|
||||||
param_env: ty::ParamEnv<'tcx>,
|
param_env: ty::ParamEnv<'tcx>,
|
||||||
value: EarlyBinder<T>,
|
value: EarlyBinder<'tcx, T>,
|
||||||
) -> Result<T, NormalizationError<'tcx>>
|
) -> Result<T, NormalizationError<'tcx>>
|
||||||
where
|
where
|
||||||
T: TypeFoldable<TyCtxt<'tcx>>,
|
T: TypeFoldable<TyCtxt<'tcx>>,
|
||||||
|
@ -33,8 +33,8 @@ impl<T: ParameterizedOverTcx> ParameterizedOverTcx for ty::Binder<'static, T> {
|
|||||||
type Value<'tcx> = ty::Binder<'tcx, T::Value<'tcx>>;
|
type Value<'tcx> = ty::Binder<'tcx, T::Value<'tcx>>;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: ParameterizedOverTcx> ParameterizedOverTcx for ty::EarlyBinder<T> {
|
impl<T: ParameterizedOverTcx> ParameterizedOverTcx for ty::EarlyBinder<'static, T> {
|
||||||
type Value<'tcx> = ty::EarlyBinder<T::Value<'tcx>>;
|
type Value<'tcx> = ty::EarlyBinder<'tcx, T::Value<'tcx>>;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
|
@ -138,6 +138,14 @@ impl<'tcx> Region<'tcx> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> rustc_type_ir::inherent::Region<TyCtxt<'tcx>> for Region<'tcx> {
|
impl<'tcx> rustc_type_ir::inherent::Region<TyCtxt<'tcx>> for Region<'tcx> {
|
||||||
|
fn new_bound(
|
||||||
|
interner: TyCtxt<'tcx>,
|
||||||
|
debruijn: ty::DebruijnIndex,
|
||||||
|
var: ty::BoundRegion,
|
||||||
|
) -> Self {
|
||||||
|
Region::new_bound(interner, debruijn, var)
|
||||||
|
}
|
||||||
|
|
||||||
fn new_anon_bound(tcx: TyCtxt<'tcx>, debruijn: ty::DebruijnIndex, var: ty::BoundVar) -> Self {
|
fn new_anon_bound(tcx: TyCtxt<'tcx>, debruijn: ty::DebruijnIndex, var: ty::BoundVar) -> Self {
|
||||||
Region::new_bound(tcx, debruijn, ty::BoundRegion { var, kind: ty::BoundRegionKind::BrAnon })
|
Region::new_bound(tcx, debruijn, ty::BoundRegion { var, kind: ty::BoundRegionKind::BrAnon })
|
||||||
}
|
}
|
||||||
@ -327,6 +335,12 @@ pub struct EarlyParamRegion {
|
|||||||
pub name: Symbol,
|
pub name: Symbol,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl rustc_type_ir::inherent::ParamLike for EarlyParamRegion {
|
||||||
|
fn index(self) -> u32 {
|
||||||
|
self.index
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl std::fmt::Debug for EarlyParamRegion {
|
impl std::fmt::Debug for EarlyParamRegion {
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
write!(f, "{}/#{}", self.name, self.index)
|
write!(f, "{}/#{}", self.name, self.index)
|
||||||
|
@ -40,6 +40,7 @@ pub type TypeAndMut<'tcx> = ir::TypeAndMut<TyCtxt<'tcx>>;
|
|||||||
pub type AliasTy<'tcx> = ir::AliasTy<TyCtxt<'tcx>>;
|
pub type AliasTy<'tcx> = ir::AliasTy<TyCtxt<'tcx>>;
|
||||||
pub type FnSig<'tcx> = ir::FnSig<TyCtxt<'tcx>>;
|
pub type FnSig<'tcx> = ir::FnSig<TyCtxt<'tcx>>;
|
||||||
pub type Binder<'tcx, T> = ir::Binder<TyCtxt<'tcx>, T>;
|
pub type Binder<'tcx, T> = ir::Binder<TyCtxt<'tcx>, T>;
|
||||||
|
pub type EarlyBinder<'tcx, T> = ir::EarlyBinder<TyCtxt<'tcx>, T>;
|
||||||
|
|
||||||
pub trait Article {
|
pub trait Article {
|
||||||
fn article(&self) -> &'static str;
|
fn article(&self) -> &'static str;
|
||||||
@ -954,6 +955,12 @@ pub struct ParamTy {
|
|||||||
pub name: Symbol,
|
pub name: Symbol,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl rustc_type_ir::inherent::ParamLike for ParamTy {
|
||||||
|
fn index(self) -> u32 {
|
||||||
|
self.index
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<'tcx> ParamTy {
|
impl<'tcx> ParamTy {
|
||||||
pub fn new(index: u32, name: Symbol) -> ParamTy {
|
pub fn new(index: u32, name: Symbol) -> ParamTy {
|
||||||
ParamTy { index, name }
|
ParamTy { index, name }
|
||||||
@ -982,6 +989,12 @@ pub struct ParamConst {
|
|||||||
pub name: Symbol,
|
pub name: Symbol,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl rustc_type_ir::inherent::ParamLike for ParamConst {
|
||||||
|
fn index(self) -> u32 {
|
||||||
|
self.index
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl ParamConst {
|
impl ParamConst {
|
||||||
pub fn new(index: u32, name: Symbol) -> ParamConst {
|
pub fn new(index: u32, name: Symbol) -> ParamConst {
|
||||||
ParamConst { index, name }
|
ParamConst { index, name }
|
||||||
@ -1423,6 +1436,10 @@ impl<'tcx> rustc_type_ir::inherent::Ty<TyCtxt<'tcx>> for Ty<'tcx> {
|
|||||||
Ty::new_var(tcx, vid)
|
Ty::new_var(tcx, vid)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn new_bound(interner: TyCtxt<'tcx>, debruijn: ty::DebruijnIndex, var: ty::BoundTy) -> Self {
|
||||||
|
Ty::new_bound(interner, debruijn, var)
|
||||||
|
}
|
||||||
|
|
||||||
fn new_anon_bound(tcx: TyCtxt<'tcx>, debruijn: ty::DebruijnIndex, var: ty::BoundVar) -> Self {
|
fn new_anon_bound(tcx: TyCtxt<'tcx>, debruijn: ty::DebruijnIndex, var: ty::BoundVar) -> Self {
|
||||||
Ty::new_bound(tcx, debruijn, ty::BoundTy { var, kind: ty::BoundTyKind::Anon })
|
Ty::new_bound(tcx, debruijn, ty::BoundTy { var, kind: ty::BoundTyKind::Anon })
|
||||||
}
|
}
|
||||||
@ -2055,7 +2072,7 @@ impl<'tcx> Ty<'tcx> {
|
|||||||
fn async_destructor_combinator(
|
fn async_destructor_combinator(
|
||||||
tcx: TyCtxt<'tcx>,
|
tcx: TyCtxt<'tcx>,
|
||||||
lang_item: LangItem,
|
lang_item: LangItem,
|
||||||
) -> ty::EarlyBinder<Ty<'tcx>> {
|
) -> ty::EarlyBinder<'tcx, Ty<'tcx>> {
|
||||||
tcx.fn_sig(tcx.require_lang_item(lang_item, None))
|
tcx.fn_sig(tcx.require_lang_item(lang_item, None))
|
||||||
.map_bound(|fn_sig| fn_sig.output().no_bound_vars().unwrap())
|
.map_bound(|fn_sig| fn_sig.output().no_bound_vars().unwrap())
|
||||||
}
|
}
|
||||||
|
@ -694,7 +694,7 @@ impl<'tcx> TyCtxt<'tcx> {
|
|||||||
pub fn coroutine_hidden_types(
|
pub fn coroutine_hidden_types(
|
||||||
self,
|
self,
|
||||||
def_id: DefId,
|
def_id: DefId,
|
||||||
) -> impl Iterator<Item = ty::EarlyBinder<Ty<'tcx>>> {
|
) -> impl Iterator<Item = ty::EarlyBinder<'tcx, Ty<'tcx>>> {
|
||||||
let coroutine_layout = self.mir_coroutine_witnesses(def_id);
|
let coroutine_layout = self.mir_coroutine_witnesses(def_id);
|
||||||
coroutine_layout
|
coroutine_layout
|
||||||
.as_ref()
|
.as_ref()
|
||||||
@ -709,7 +709,7 @@ impl<'tcx> TyCtxt<'tcx> {
|
|||||||
pub fn bound_coroutine_hidden_types(
|
pub fn bound_coroutine_hidden_types(
|
||||||
self,
|
self,
|
||||||
def_id: DefId,
|
def_id: DefId,
|
||||||
) -> impl Iterator<Item = ty::EarlyBinder<ty::Binder<'tcx, Ty<'tcx>>>> {
|
) -> impl Iterator<Item = ty::EarlyBinder<'tcx, ty::Binder<'tcx, Ty<'tcx>>>> {
|
||||||
let coroutine_layout = self.mir_coroutine_witnesses(def_id);
|
let coroutine_layout = self.mir_coroutine_witnesses(def_id);
|
||||||
coroutine_layout
|
coroutine_layout
|
||||||
.as_ref()
|
.as_ref()
|
||||||
|
@ -23,7 +23,7 @@ impl<'tcx> Value<TyCtxt<'tcx>> for Ty<'_> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> Value<TyCtxt<'tcx>> for Result<ty::EarlyBinder<Ty<'_>>, CyclePlaceholder> {
|
impl<'tcx> Value<TyCtxt<'tcx>> for Result<ty::EarlyBinder<'_, Ty<'_>>, CyclePlaceholder> {
|
||||||
fn from_cycle_error(_tcx: TyCtxt<'tcx>, _: &CycleError, guar: ErrorGuaranteed) -> Self {
|
fn from_cycle_error(_tcx: TyCtxt<'tcx>, _: &CycleError, guar: ErrorGuaranteed) -> Self {
|
||||||
Err(CyclePlaceholder(guar))
|
Err(CyclePlaceholder(guar))
|
||||||
}
|
}
|
||||||
@ -111,7 +111,7 @@ impl<'tcx> Value<TyCtxt<'tcx>> for Representability {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> Value<TyCtxt<'tcx>> for ty::EarlyBinder<Ty<'_>> {
|
impl<'tcx> Value<TyCtxt<'tcx>> for ty::EarlyBinder<'_, Ty<'_>> {
|
||||||
fn from_cycle_error(
|
fn from_cycle_error(
|
||||||
tcx: TyCtxt<'tcx>,
|
tcx: TyCtxt<'tcx>,
|
||||||
cycle_error: &CycleError,
|
cycle_error: &CycleError,
|
||||||
@ -121,7 +121,7 @@ impl<'tcx> Value<TyCtxt<'tcx>> for ty::EarlyBinder<Ty<'_>> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> Value<TyCtxt<'tcx>> for ty::EarlyBinder<ty::Binder<'_, ty::FnSig<'_>>> {
|
impl<'tcx> Value<TyCtxt<'tcx>> for ty::EarlyBinder<'_, ty::Binder<'_, ty::FnSig<'_>>> {
|
||||||
fn from_cycle_error(
|
fn from_cycle_error(
|
||||||
tcx: TyCtxt<'tcx>,
|
tcx: TyCtxt<'tcx>,
|
||||||
cycle_error: &CycleError,
|
cycle_error: &CycleError,
|
||||||
|
@ -194,7 +194,7 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx, S, V> Stable<'tcx> for ty::EarlyBinder<S>
|
impl<'tcx, S, V> Stable<'tcx> for ty::EarlyBinder<'tcx, S>
|
||||||
where
|
where
|
||||||
S: Stable<'tcx, T = V>,
|
S: Stable<'tcx, T = V>,
|
||||||
{
|
{
|
||||||
|
@ -2097,7 +2097,7 @@ fn confirm_impl_candidate<'cx, 'tcx>(
|
|||||||
let args = translate_args(selcx.infcx, param_env, impl_def_id, args, assoc_ty.defining_node);
|
let args = translate_args(selcx.infcx, param_env, impl_def_id, args, assoc_ty.defining_node);
|
||||||
let ty = tcx.type_of(assoc_ty.item.def_id);
|
let ty = tcx.type_of(assoc_ty.item.def_id);
|
||||||
let is_const = matches!(tcx.def_kind(assoc_ty.item.def_id), DefKind::AssocConst);
|
let is_const = matches!(tcx.def_kind(assoc_ty.item.def_id), DefKind::AssocConst);
|
||||||
let term: ty::EarlyBinder<ty::Term<'tcx>> = if is_const {
|
let term: ty::EarlyBinder<'tcx, ty::Term<'tcx>> = if is_const {
|
||||||
let did = assoc_ty.item.def_id;
|
let did = assoc_ty.item.def_id;
|
||||||
let identity_args = crate::traits::GenericArgs::identity_for_item(tcx, did);
|
let identity_args = crate::traits::GenericArgs::identity_for_item(tcx, did);
|
||||||
let uv = ty::UnevaluatedConst::new(did, identity_args);
|
let uv = ty::UnevaluatedConst::new(did, identity_args);
|
||||||
|
@ -398,10 +398,10 @@ impl<'a, 'tcx> visit::Visitor<'a, 'tcx> for IsThirPolymorphic<'a, 'tcx> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Builds an abstract const, do not use this directly, but use `AbstractConst::new` instead.
|
/// Builds an abstract const, do not use this directly, but use `AbstractConst::new` instead.
|
||||||
fn thir_abstract_const(
|
fn thir_abstract_const<'tcx>(
|
||||||
tcx: TyCtxt<'_>,
|
tcx: TyCtxt<'tcx>,
|
||||||
def: LocalDefId,
|
def: LocalDefId,
|
||||||
) -> Result<Option<ty::EarlyBinder<ty::Const<'_>>>, ErrorGuaranteed> {
|
) -> Result<Option<ty::EarlyBinder<'tcx, ty::Const<'tcx>>>, ErrorGuaranteed> {
|
||||||
if !tcx.features().generic_const_exprs {
|
if !tcx.features().generic_const_exprs {
|
||||||
return Ok(None);
|
return Ok(None);
|
||||||
}
|
}
|
||||||
|
@ -77,7 +77,7 @@ fn defaultness(tcx: TyCtxt<'_>, def_id: LocalDefId) -> hir::Defaultness {
|
|||||||
fn adt_sized_constraint<'tcx>(
|
fn adt_sized_constraint<'tcx>(
|
||||||
tcx: TyCtxt<'tcx>,
|
tcx: TyCtxt<'tcx>,
|
||||||
def_id: DefId,
|
def_id: DefId,
|
||||||
) -> Option<ty::EarlyBinder<Ty<'tcx>>> {
|
) -> Option<ty::EarlyBinder<'tcx, Ty<'tcx>>> {
|
||||||
if let Some(def_id) = def_id.as_local() {
|
if let Some(def_id) = def_id.as_local() {
|
||||||
if let ty::Representability::Infinite(_) = tcx.representability(def_id) {
|
if let ty::Representability::Infinite(_) = tcx.representability(def_id) {
|
||||||
return None;
|
return None;
|
||||||
@ -253,7 +253,7 @@ fn param_env_reveal_all_normalized(tcx: TyCtxt<'_>, def_id: DefId) -> ty::ParamE
|
|||||||
fn self_ty_of_trait_impl_enabling_order_dep_trait_object_hack(
|
fn self_ty_of_trait_impl_enabling_order_dep_trait_object_hack(
|
||||||
tcx: TyCtxt<'_>,
|
tcx: TyCtxt<'_>,
|
||||||
def_id: DefId,
|
def_id: DefId,
|
||||||
) -> Option<EarlyBinder<Ty<'_>>> {
|
) -> Option<EarlyBinder<'_, Ty<'_>>> {
|
||||||
let impl_ =
|
let impl_ =
|
||||||
tcx.impl_trait_header(def_id).unwrap_or_else(|| bug!("called on inherent impl {def_id:?}"));
|
tcx.impl_trait_header(def_id).unwrap_or_else(|| bug!("called on inherent impl {def_id:?}"));
|
||||||
|
|
||||||
|
@ -15,6 +15,7 @@ rustc_serialize = { path = "../rustc_serialize", optional = true }
|
|||||||
rustc_span = { path = "../rustc_span", optional = true }
|
rustc_span = { path = "../rustc_span", optional = true }
|
||||||
rustc_type_ir_macros = { path = "../rustc_type_ir_macros" }
|
rustc_type_ir_macros = { path = "../rustc_type_ir_macros" }
|
||||||
smallvec = { version = "1.8.1", default-features = false }
|
smallvec = { version = "1.8.1", default-features = false }
|
||||||
|
tracing = "0.1"
|
||||||
# tidy-alphabetical-end
|
# tidy-alphabetical-end
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
|
@ -1,12 +1,14 @@
|
|||||||
use std::fmt::Debug;
|
use std::fmt::Debug;
|
||||||
use std::hash::Hash;
|
use std::hash::Hash;
|
||||||
|
use std::marker::PhantomData;
|
||||||
use std::ops::{ControlFlow, Deref};
|
use std::ops::{ControlFlow, Deref};
|
||||||
|
|
||||||
#[cfg(feature = "nightly")]
|
#[cfg(feature = "nightly")]
|
||||||
use rustc_macros::HashStable_NoContext;
|
use rustc_macros::{HashStable_NoContext, TyDecodable, TyEncodable};
|
||||||
use rustc_serialize::Decodable;
|
use rustc_serialize::Decodable;
|
||||||
|
use tracing::debug;
|
||||||
|
|
||||||
use crate::fold::{FallibleTypeFolder, TypeFoldable, TypeSuperFoldable};
|
use crate::fold::{FallibleTypeFolder, TypeFoldable, TypeFolder, TypeSuperFoldable};
|
||||||
use crate::inherent::*;
|
use crate::inherent::*;
|
||||||
use crate::lift::Lift;
|
use crate::lift::Lift;
|
||||||
use crate::visit::{Flags, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor};
|
use crate::visit::{Flags, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor};
|
||||||
@ -338,3 +340,516 @@ impl<I: Interner> TypeVisitor<I> for ValidateBoundVars<I> {
|
|||||||
ControlFlow::Continue(())
|
ControlFlow::Continue(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Similar to [`super::Binder`] except that it tracks early bound generics, i.e. `struct Foo<T>(T)`
|
||||||
|
/// needs `T` instantiated immediately. This type primarily exists to avoid forgetting to call
|
||||||
|
/// `instantiate`.
|
||||||
|
///
|
||||||
|
/// If you don't have anything to `instantiate`, you may be looking for
|
||||||
|
/// [`instantiate_identity`](EarlyBinder::instantiate_identity) or [`skip_binder`](EarlyBinder::skip_binder).
|
||||||
|
#[derive(derivative::Derivative)]
|
||||||
|
#[derivative(
|
||||||
|
Clone(bound = "T: Clone"),
|
||||||
|
Copy(bound = "T: Copy"),
|
||||||
|
PartialEq(bound = "T: PartialEq"),
|
||||||
|
Eq(bound = "T: Eq"),
|
||||||
|
Ord(bound = "T: Ord"),
|
||||||
|
PartialOrd(bound = "T: Ord"),
|
||||||
|
Hash(bound = "T: Hash"),
|
||||||
|
Debug(bound = "T: Debug")
|
||||||
|
)]
|
||||||
|
#[cfg_attr(feature = "nightly", derive(TyEncodable, TyDecodable, HashStable_NoContext))]
|
||||||
|
pub struct EarlyBinder<I: Interner, T> {
|
||||||
|
value: T,
|
||||||
|
_tcx: PhantomData<I>,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// For early binders, you should first call `instantiate` before using any visitors.
|
||||||
|
#[cfg(feature = "nightly")]
|
||||||
|
impl<I: Interner, T> !TypeFoldable<I> for ty::EarlyBinder<I, T> {}
|
||||||
|
|
||||||
|
/// For early binders, you should first call `instantiate` before using any visitors.
|
||||||
|
#[cfg(feature = "nightly")]
|
||||||
|
impl<I: Interner, T> !TypeVisitable<I> for ty::EarlyBinder<I, T> {}
|
||||||
|
|
||||||
|
impl<I: Interner, T> EarlyBinder<I, T> {
|
||||||
|
pub fn bind(value: T) -> EarlyBinder<I, T> {
|
||||||
|
EarlyBinder { value, _tcx: PhantomData }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn as_ref(&self) -> EarlyBinder<I, &T> {
|
||||||
|
EarlyBinder { value: &self.value, _tcx: PhantomData }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn map_bound_ref<F, U>(&self, f: F) -> EarlyBinder<I, U>
|
||||||
|
where
|
||||||
|
F: FnOnce(&T) -> U,
|
||||||
|
{
|
||||||
|
self.as_ref().map_bound(f)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn map_bound<F, U>(self, f: F) -> EarlyBinder<I, U>
|
||||||
|
where
|
||||||
|
F: FnOnce(T) -> U,
|
||||||
|
{
|
||||||
|
let value = f(self.value);
|
||||||
|
EarlyBinder { value, _tcx: PhantomData }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn try_map_bound<F, U, E>(self, f: F) -> Result<EarlyBinder<I, U>, E>
|
||||||
|
where
|
||||||
|
F: FnOnce(T) -> Result<U, E>,
|
||||||
|
{
|
||||||
|
let value = f(self.value)?;
|
||||||
|
Ok(EarlyBinder { value, _tcx: PhantomData })
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn rebind<U>(&self, value: U) -> EarlyBinder<I, U> {
|
||||||
|
EarlyBinder { value, _tcx: PhantomData }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Skips the binder and returns the "bound" value.
|
||||||
|
/// This can be used to extract data that does not depend on generic parameters
|
||||||
|
/// (e.g., getting the `DefId` of the inner value or getting the number of
|
||||||
|
/// arguments of an `FnSig`). Otherwise, consider using
|
||||||
|
/// [`instantiate_identity`](EarlyBinder::instantiate_identity).
|
||||||
|
///
|
||||||
|
/// To skip the binder on `x: &EarlyBinder<I, T>` to obtain `&T`, leverage
|
||||||
|
/// [`EarlyBinder::as_ref`](EarlyBinder::as_ref): `x.as_ref().skip_binder()`.
|
||||||
|
///
|
||||||
|
/// See also [`Binder::skip_binder`](super::Binder::skip_binder), which is
|
||||||
|
/// the analogous operation on [`super::Binder`].
|
||||||
|
pub fn skip_binder(self) -> T {
|
||||||
|
self.value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<I: Interner, T> EarlyBinder<I, Option<T>> {
|
||||||
|
pub fn transpose(self) -> Option<EarlyBinder<I, T>> {
|
||||||
|
self.value.map(|value| EarlyBinder { value, _tcx: PhantomData })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'s, I: Interner, Iter: IntoIterator> EarlyBinder<I, Iter>
|
||||||
|
where
|
||||||
|
Iter::Item: TypeFoldable<I>,
|
||||||
|
{
|
||||||
|
pub fn iter_instantiated(
|
||||||
|
self,
|
||||||
|
tcx: I,
|
||||||
|
args: &'s [I::GenericArg],
|
||||||
|
) -> IterInstantiated<'s, I, Iter> {
|
||||||
|
IterInstantiated { it: self.value.into_iter(), tcx, args }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Similar to [`instantiate_identity`](EarlyBinder::instantiate_identity),
|
||||||
|
/// but on an iterator of `TypeFoldable` values.
|
||||||
|
pub fn instantiate_identity_iter(self) -> Iter::IntoIter {
|
||||||
|
self.value.into_iter()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct IterInstantiated<'s, I: Interner, Iter: IntoIterator> {
|
||||||
|
it: Iter::IntoIter,
|
||||||
|
tcx: I,
|
||||||
|
args: &'s [I::GenericArg],
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<I: Interner, Iter: IntoIterator> Iterator for IterInstantiated<'_, I, Iter>
|
||||||
|
where
|
||||||
|
Iter::Item: TypeFoldable<I>,
|
||||||
|
{
|
||||||
|
type Item = Iter::Item;
|
||||||
|
|
||||||
|
fn next(&mut self) -> Option<Self::Item> {
|
||||||
|
Some(
|
||||||
|
EarlyBinder { value: self.it.next()?, _tcx: PhantomData }
|
||||||
|
.instantiate(self.tcx, self.args),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn size_hint(&self) -> (usize, Option<usize>) {
|
||||||
|
self.it.size_hint()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<I: Interner, Iter: IntoIterator> DoubleEndedIterator for IterInstantiated<'_, I, Iter>
|
||||||
|
where
|
||||||
|
Iter::IntoIter: DoubleEndedIterator,
|
||||||
|
Iter::Item: TypeFoldable<I>,
|
||||||
|
{
|
||||||
|
fn next_back(&mut self) -> Option<Self::Item> {
|
||||||
|
Some(
|
||||||
|
EarlyBinder { value: self.it.next_back()?, _tcx: PhantomData }
|
||||||
|
.instantiate(self.tcx, self.args),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<I: Interner, Iter: IntoIterator> ExactSizeIterator for IterInstantiated<'_, I, Iter>
|
||||||
|
where
|
||||||
|
Iter::IntoIter: ExactSizeIterator,
|
||||||
|
Iter::Item: TypeFoldable<I>,
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'s, I: Interner, Iter: IntoIterator> EarlyBinder<I, Iter>
|
||||||
|
where
|
||||||
|
Iter::Item: Deref,
|
||||||
|
<Iter::Item as Deref>::Target: Copy + TypeFoldable<I>,
|
||||||
|
{
|
||||||
|
pub fn iter_instantiated_copied(
|
||||||
|
self,
|
||||||
|
tcx: I,
|
||||||
|
args: &'s [I::GenericArg],
|
||||||
|
) -> IterInstantiatedCopied<'s, I, Iter> {
|
||||||
|
IterInstantiatedCopied { it: self.value.into_iter(), tcx, args }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Similar to [`instantiate_identity`](EarlyBinder::instantiate_identity),
|
||||||
|
/// but on an iterator of values that deref to a `TypeFoldable`.
|
||||||
|
pub fn instantiate_identity_iter_copied(
|
||||||
|
self,
|
||||||
|
) -> impl Iterator<Item = <Iter::Item as Deref>::Target> {
|
||||||
|
self.value.into_iter().map(|v| *v)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct IterInstantiatedCopied<'a, I: Interner, Iter: IntoIterator> {
|
||||||
|
it: Iter::IntoIter,
|
||||||
|
tcx: I,
|
||||||
|
args: &'a [I::GenericArg],
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<I: Interner, Iter: IntoIterator> Iterator for IterInstantiatedCopied<'_, I, Iter>
|
||||||
|
where
|
||||||
|
Iter::Item: Deref,
|
||||||
|
<Iter::Item as Deref>::Target: Copy + TypeFoldable<I>,
|
||||||
|
{
|
||||||
|
type Item = <Iter::Item as Deref>::Target;
|
||||||
|
|
||||||
|
fn next(&mut self) -> Option<Self::Item> {
|
||||||
|
self.it.next().map(|value| {
|
||||||
|
EarlyBinder { value: *value, _tcx: PhantomData }.instantiate(self.tcx, self.args)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn size_hint(&self) -> (usize, Option<usize>) {
|
||||||
|
self.it.size_hint()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<I: Interner, Iter: IntoIterator> DoubleEndedIterator for IterInstantiatedCopied<'_, I, Iter>
|
||||||
|
where
|
||||||
|
Iter::IntoIter: DoubleEndedIterator,
|
||||||
|
Iter::Item: Deref,
|
||||||
|
<Iter::Item as Deref>::Target: Copy + TypeFoldable<I>,
|
||||||
|
{
|
||||||
|
fn next_back(&mut self) -> Option<Self::Item> {
|
||||||
|
self.it.next_back().map(|value| {
|
||||||
|
EarlyBinder { value: *value, _tcx: PhantomData }.instantiate(self.tcx, self.args)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<I: Interner, Iter: IntoIterator> ExactSizeIterator for IterInstantiatedCopied<'_, I, Iter>
|
||||||
|
where
|
||||||
|
Iter::IntoIter: ExactSizeIterator,
|
||||||
|
Iter::Item: Deref,
|
||||||
|
<Iter::Item as Deref>::Target: Copy + TypeFoldable<I>,
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct EarlyBinderIter<I, T> {
|
||||||
|
t: T,
|
||||||
|
_tcx: PhantomData<I>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<I: Interner, T: IntoIterator> EarlyBinder<I, T> {
|
||||||
|
pub fn transpose_iter(self) -> EarlyBinderIter<I, T::IntoIter> {
|
||||||
|
EarlyBinderIter { t: self.value.into_iter(), _tcx: PhantomData }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<I: Interner, T: Iterator> Iterator for EarlyBinderIter<I, T> {
|
||||||
|
type Item = EarlyBinder<I, T::Item>;
|
||||||
|
|
||||||
|
fn next(&mut self) -> Option<Self::Item> {
|
||||||
|
self.t.next().map(|value| EarlyBinder { value, _tcx: PhantomData })
|
||||||
|
}
|
||||||
|
|
||||||
|
fn size_hint(&self) -> (usize, Option<usize>) {
|
||||||
|
self.t.size_hint()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<I: Interner, T: TypeFoldable<I>> ty::EarlyBinder<I, T> {
|
||||||
|
pub fn instantiate(self, tcx: I, args: &[I::GenericArg]) -> T {
|
||||||
|
let mut folder = ArgFolder { tcx, args, binders_passed: 0 };
|
||||||
|
self.value.fold_with(&mut folder)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Makes the identity replacement `T0 => T0, ..., TN => TN`.
|
||||||
|
/// Conceptually, this converts universally bound variables into placeholders
|
||||||
|
/// when inside of a given item.
|
||||||
|
///
|
||||||
|
/// For example, consider `for<T> fn foo<T>(){ .. }`:
|
||||||
|
/// - Outside of `foo`, `T` is bound (represented by the presence of `EarlyBinder`).
|
||||||
|
/// - Inside of the body of `foo`, we treat `T` as a placeholder by calling
|
||||||
|
/// `instantiate_identity` to discharge the `EarlyBinder`.
|
||||||
|
pub fn instantiate_identity(self) -> T {
|
||||||
|
self.value
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the inner value, but only if it contains no bound vars.
|
||||||
|
pub fn no_bound_vars(self) -> Option<T> {
|
||||||
|
if !self.value.has_param() { Some(self.value) } else { None }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
// The actual instantiation engine itself is a type folder.
|
||||||
|
|
||||||
|
struct ArgFolder<'a, I: Interner> {
|
||||||
|
tcx: I,
|
||||||
|
args: &'a [I::GenericArg],
|
||||||
|
|
||||||
|
/// Number of region binders we have passed through while doing the instantiation
|
||||||
|
binders_passed: u32,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a, I: Interner> TypeFolder<I> for ArgFolder<'a, I> {
|
||||||
|
#[inline]
|
||||||
|
fn interner(&self) -> I {
|
||||||
|
self.tcx
|
||||||
|
}
|
||||||
|
|
||||||
|
fn fold_binder<T: TypeFoldable<I>>(&mut self, t: ty::Binder<I, T>) -> ty::Binder<I, T> {
|
||||||
|
self.binders_passed += 1;
|
||||||
|
let t = t.super_fold_with(self);
|
||||||
|
self.binders_passed -= 1;
|
||||||
|
t
|
||||||
|
}
|
||||||
|
|
||||||
|
fn fold_region(&mut self, r: I::Region) -> I::Region {
|
||||||
|
// Note: This routine only handles regions that are bound on
|
||||||
|
// type declarations and other outer declarations, not those
|
||||||
|
// bound in *fn types*. Region instantiation of the bound
|
||||||
|
// regions that appear in a function signature is done using
|
||||||
|
// the specialized routine `ty::replace_late_regions()`.
|
||||||
|
match r.kind() {
|
||||||
|
ty::ReEarlyParam(data) => {
|
||||||
|
let rk = self.args.get(data.index() as usize).map(|k| k.kind());
|
||||||
|
match rk {
|
||||||
|
Some(ty::GenericArgKind::Lifetime(lt)) => self.shift_region_through_binders(lt),
|
||||||
|
Some(other) => self.region_param_expected(data, r, other),
|
||||||
|
None => self.region_param_out_of_range(data, r),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ty::ReBound(..)
|
||||||
|
| ty::ReLateParam(_)
|
||||||
|
| ty::ReStatic
|
||||||
|
| ty::RePlaceholder(_)
|
||||||
|
| ty::ReErased
|
||||||
|
| ty::ReError(_) => r,
|
||||||
|
ty::ReVar(_) => panic!("unexpected region: {r:?}"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn fold_ty(&mut self, t: I::Ty) -> I::Ty {
|
||||||
|
if !t.has_param() {
|
||||||
|
return t;
|
||||||
|
}
|
||||||
|
|
||||||
|
match t.kind() {
|
||||||
|
ty::Param(p) => self.ty_for_param(p, t),
|
||||||
|
_ => t.super_fold_with(self),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn fold_const(&mut self, c: I::Const) -> I::Const {
|
||||||
|
if let ty::ConstKind::Param(p) = c.kind() {
|
||||||
|
self.const_for_param(p, c)
|
||||||
|
} else {
|
||||||
|
c.super_fold_with(self)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a, I: Interner> ArgFolder<'a, I> {
|
||||||
|
fn ty_for_param(&self, p: I::ParamTy, source_ty: I::Ty) -> I::Ty {
|
||||||
|
// Look up the type in the args. It really should be in there.
|
||||||
|
let opt_ty = self.args.get(p.index() as usize).map(|k| k.kind());
|
||||||
|
let ty = match opt_ty {
|
||||||
|
Some(ty::GenericArgKind::Type(ty)) => ty,
|
||||||
|
Some(kind) => self.type_param_expected(p, source_ty, kind),
|
||||||
|
None => self.type_param_out_of_range(p, source_ty),
|
||||||
|
};
|
||||||
|
|
||||||
|
self.shift_vars_through_binders(ty)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cold]
|
||||||
|
#[inline(never)]
|
||||||
|
fn type_param_expected(&self, p: I::ParamTy, ty: I::Ty, kind: ty::GenericArgKind<I>) -> ! {
|
||||||
|
panic!(
|
||||||
|
"expected type for `{:?}` ({:?}/{}) but found {:?} when instantiating, args={:?}",
|
||||||
|
p,
|
||||||
|
ty,
|
||||||
|
p.index(),
|
||||||
|
kind,
|
||||||
|
self.args,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cold]
|
||||||
|
#[inline(never)]
|
||||||
|
fn type_param_out_of_range(&self, p: I::ParamTy, ty: I::Ty) -> ! {
|
||||||
|
panic!(
|
||||||
|
"type parameter `{:?}` ({:?}/{}) out of range when instantiating, args={:?}",
|
||||||
|
p,
|
||||||
|
ty,
|
||||||
|
p.index(),
|
||||||
|
self.args,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn const_for_param(&self, p: I::ParamConst, source_ct: I::Const) -> I::Const {
|
||||||
|
// Look up the const in the args. It really should be in there.
|
||||||
|
let opt_ct = self.args.get(p.index() as usize).map(|k| k.kind());
|
||||||
|
let ct = match opt_ct {
|
||||||
|
Some(ty::GenericArgKind::Const(ct)) => ct,
|
||||||
|
Some(kind) => self.const_param_expected(p, source_ct, kind),
|
||||||
|
None => self.const_param_out_of_range(p, source_ct),
|
||||||
|
};
|
||||||
|
|
||||||
|
self.shift_vars_through_binders(ct)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cold]
|
||||||
|
#[inline(never)]
|
||||||
|
fn const_param_expected(
|
||||||
|
&self,
|
||||||
|
p: I::ParamConst,
|
||||||
|
ct: I::Const,
|
||||||
|
kind: ty::GenericArgKind<I>,
|
||||||
|
) -> ! {
|
||||||
|
panic!(
|
||||||
|
"expected const for `{:?}` ({:?}/{}) but found {:?} when instantiating args={:?}",
|
||||||
|
p,
|
||||||
|
ct,
|
||||||
|
p.index(),
|
||||||
|
kind,
|
||||||
|
self.args,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cold]
|
||||||
|
#[inline(never)]
|
||||||
|
fn const_param_out_of_range(&self, p: I::ParamConst, ct: I::Const) -> ! {
|
||||||
|
panic!(
|
||||||
|
"const parameter `{:?}` ({:?}/{}) out of range when instantiating args={:?}",
|
||||||
|
p,
|
||||||
|
ct,
|
||||||
|
p.index(),
|
||||||
|
self.args,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cold]
|
||||||
|
#[inline(never)]
|
||||||
|
fn region_param_expected(
|
||||||
|
&self,
|
||||||
|
ebr: I::EarlyParamRegion,
|
||||||
|
r: I::Region,
|
||||||
|
kind: ty::GenericArgKind<I>,
|
||||||
|
) -> ! {
|
||||||
|
panic!(
|
||||||
|
"expected region for `{:?}` ({:?}/{}) but found {:?} when instantiating args={:?}",
|
||||||
|
ebr,
|
||||||
|
r,
|
||||||
|
ebr.index(),
|
||||||
|
kind,
|
||||||
|
self.args,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cold]
|
||||||
|
#[inline(never)]
|
||||||
|
fn region_param_out_of_range(&self, ebr: I::EarlyParamRegion, r: I::Region) -> ! {
|
||||||
|
panic!(
|
||||||
|
"const parameter `{:?}` ({:?}/{}) out of range when instantiating args={:?}",
|
||||||
|
ebr,
|
||||||
|
r,
|
||||||
|
ebr.index(),
|
||||||
|
self.args,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// It is sometimes necessary to adjust the De Bruijn indices during instantiation. This occurs
|
||||||
|
/// when we are instantating a type with escaping bound vars into a context where we have
|
||||||
|
/// passed through binders. That's quite a mouthful. Let's see an example:
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// type Func<A> = fn(A);
|
||||||
|
/// type MetaFunc = for<'a> fn(Func<&'a i32>);
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// The type `MetaFunc`, when fully expanded, will be
|
||||||
|
/// ```ignore (illustrative)
|
||||||
|
/// for<'a> fn(fn(&'a i32))
|
||||||
|
/// // ^~ ^~ ^~~
|
||||||
|
/// // | | |
|
||||||
|
/// // | | DebruijnIndex of 2
|
||||||
|
/// // Binders
|
||||||
|
/// ```
|
||||||
|
/// Here the `'a` lifetime is bound in the outer function, but appears as an argument of the
|
||||||
|
/// inner one. Therefore, that appearance will have a DebruijnIndex of 2, because we must skip
|
||||||
|
/// over the inner binder (remember that we count De Bruijn indices from 1). However, in the
|
||||||
|
/// definition of `MetaFunc`, the binder is not visible, so the type `&'a i32` will have a
|
||||||
|
/// De Bruijn index of 1. It's only during the instantiation that we can see we must increase the
|
||||||
|
/// depth by 1 to account for the binder that we passed through.
|
||||||
|
///
|
||||||
|
/// As a second example, consider this twist:
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// type FuncTuple<A> = (A,fn(A));
|
||||||
|
/// type MetaFuncTuple = for<'a> fn(FuncTuple<&'a i32>);
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// Here the final type will be:
|
||||||
|
/// ```ignore (illustrative)
|
||||||
|
/// for<'a> fn((&'a i32, fn(&'a i32)))
|
||||||
|
/// // ^~~ ^~~
|
||||||
|
/// // | |
|
||||||
|
/// // DebruijnIndex of 1 |
|
||||||
|
/// // DebruijnIndex of 2
|
||||||
|
/// ```
|
||||||
|
/// As indicated in the diagram, here the same type `&'a i32` is instantiated once, but in the
|
||||||
|
/// first case we do not increase the De Bruijn index and in the second case we do. The reason
|
||||||
|
/// is that only in the second case have we passed through a fn binder.
|
||||||
|
fn shift_vars_through_binders<T: TypeFoldable<I>>(&self, val: T) -> T {
|
||||||
|
debug!(
|
||||||
|
"shift_vars(val={:?}, binders_passed={:?}, has_escaping_bound_vars={:?})",
|
||||||
|
val,
|
||||||
|
self.binders_passed,
|
||||||
|
val.has_escaping_bound_vars()
|
||||||
|
);
|
||||||
|
|
||||||
|
if self.binders_passed == 0 || !val.has_escaping_bound_vars() {
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
|
||||||
|
let result = ty::fold::shift_vars(TypeFolder::interner(self), val, self.binders_passed);
|
||||||
|
debug!("shift_vars: shifted result = {:?}", result);
|
||||||
|
|
||||||
|
result
|
||||||
|
}
|
||||||
|
|
||||||
|
fn shift_region_through_binders(&self, region: I::Region) -> I::Region {
|
||||||
|
if self.binders_passed == 0 || !region.has_escaping_bound_vars() {
|
||||||
|
return region;
|
||||||
|
}
|
||||||
|
ty::fold::shift_region(self.tcx, region, self.binders_passed)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -47,8 +47,10 @@
|
|||||||
|
|
||||||
use rustc_index::{Idx, IndexVec};
|
use rustc_index::{Idx, IndexVec};
|
||||||
use std::mem;
|
use std::mem;
|
||||||
|
use tracing::debug;
|
||||||
|
|
||||||
use crate::visit::TypeVisitable;
|
use crate::inherent::*;
|
||||||
|
use crate::visit::{TypeVisitable, TypeVisitableExt as _};
|
||||||
use crate::{self as ty, Interner, Lrc};
|
use crate::{self as ty, Interner, Lrc};
|
||||||
|
|
||||||
#[cfg(feature = "nightly")]
|
#[cfg(feature = "nightly")]
|
||||||
@ -325,3 +327,95 @@ impl<I: Interner, T: TypeFoldable<I>, Ix: Idx> TypeFoldable<I> for IndexVec<Ix,
|
|||||||
self.raw.try_fold_with(folder).map(IndexVec::from_raw)
|
self.raw.try_fold_with(folder).map(IndexVec::from_raw)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
// Shifter
|
||||||
|
//
|
||||||
|
// Shifts the De Bruijn indices on all escaping bound vars by a
|
||||||
|
// fixed amount. Useful in instantiation or when otherwise introducing
|
||||||
|
// a binding level that is not intended to capture the existing bound
|
||||||
|
// vars. See comment on `shift_vars_through_binders` method in
|
||||||
|
// `rustc_middle/src/ty/generic_args.rs` for more details.
|
||||||
|
|
||||||
|
struct Shifter<I: Interner> {
|
||||||
|
tcx: I,
|
||||||
|
current_index: ty::DebruijnIndex,
|
||||||
|
amount: u32,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<I: Interner> Shifter<I> {
|
||||||
|
pub fn new(tcx: I, amount: u32) -> Self {
|
||||||
|
Shifter { tcx, current_index: ty::INNERMOST, amount }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<I: Interner> TypeFolder<I> for Shifter<I> {
|
||||||
|
fn interner(&self) -> I {
|
||||||
|
self.tcx
|
||||||
|
}
|
||||||
|
|
||||||
|
fn fold_binder<T: TypeFoldable<I>>(&mut self, t: ty::Binder<I, T>) -> ty::Binder<I, T> {
|
||||||
|
self.current_index.shift_in(1);
|
||||||
|
let t = t.super_fold_with(self);
|
||||||
|
self.current_index.shift_out(1);
|
||||||
|
t
|
||||||
|
}
|
||||||
|
|
||||||
|
fn fold_region(&mut self, r: I::Region) -> I::Region {
|
||||||
|
match r.kind() {
|
||||||
|
ty::ReBound(debruijn, br) if debruijn >= self.current_index => {
|
||||||
|
let debruijn = debruijn.shifted_in(self.amount);
|
||||||
|
Region::new_bound(self.tcx, debruijn, br)
|
||||||
|
}
|
||||||
|
_ => r,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn fold_ty(&mut self, ty: I::Ty) -> I::Ty {
|
||||||
|
match ty.kind() {
|
||||||
|
ty::Bound(debruijn, bound_ty) if debruijn >= self.current_index => {
|
||||||
|
let debruijn = debruijn.shifted_in(self.amount);
|
||||||
|
Ty::new_bound(self.tcx, debruijn, bound_ty)
|
||||||
|
}
|
||||||
|
|
||||||
|
_ if ty.has_vars_bound_at_or_above(self.current_index) => ty.super_fold_with(self),
|
||||||
|
_ => ty,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn fold_const(&mut self, ct: I::Const) -> I::Const {
|
||||||
|
match ct.kind() {
|
||||||
|
ty::ConstKind::Bound(debruijn, bound_ct) if debruijn >= self.current_index => {
|
||||||
|
let debruijn = debruijn.shifted_in(self.amount);
|
||||||
|
Const::new_bound(self.tcx, debruijn, bound_ct, ct.ty())
|
||||||
|
}
|
||||||
|
_ => ct.super_fold_with(self),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn fold_predicate(&mut self, p: I::Predicate) -> I::Predicate {
|
||||||
|
if p.has_vars_bound_at_or_above(self.current_index) { p.super_fold_with(self) } else { p }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn shift_region<I: Interner>(tcx: I, region: I::Region, amount: u32) -> I::Region {
|
||||||
|
match region.kind() {
|
||||||
|
ty::ReBound(debruijn, br) if amount > 0 => {
|
||||||
|
Region::new_bound(tcx, debruijn.shifted_in(amount), br)
|
||||||
|
}
|
||||||
|
_ => region,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn shift_vars<I: Interner, T>(tcx: I, value: T, amount: u32) -> T
|
||||||
|
where
|
||||||
|
T: TypeFoldable<I>,
|
||||||
|
{
|
||||||
|
debug!("shift_vars(value={:?}, amount={})", value, amount);
|
||||||
|
|
||||||
|
if amount == 0 || !value.has_escaping_bound_vars() {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
value.fold_with(&mut Shifter::new(tcx, amount))
|
||||||
|
}
|
||||||
|
@ -29,6 +29,8 @@ pub trait Ty<I: Interner<Ty = Self>>:
|
|||||||
|
|
||||||
fn new_var(interner: I, var: ty::TyVid) -> Self;
|
fn new_var(interner: I, var: ty::TyVid) -> Self;
|
||||||
|
|
||||||
|
fn new_bound(interner: I, debruijn: ty::DebruijnIndex, var: I::BoundTy) -> Self;
|
||||||
|
|
||||||
fn new_anon_bound(interner: I, debruijn: ty::DebruijnIndex, var: ty::BoundVar) -> Self;
|
fn new_anon_bound(interner: I, debruijn: ty::DebruijnIndex, var: ty::BoundVar) -> Self;
|
||||||
|
|
||||||
fn new_alias(interner: I, kind: ty::AliasTyKind, alias_ty: ty::AliasTy<I>) -> Self;
|
fn new_alias(interner: I, kind: ty::AliasTyKind, alias_ty: ty::AliasTy<I>) -> Self;
|
||||||
@ -65,7 +67,10 @@ pub trait Region<I: Interner<Region = Self>>:
|
|||||||
+ Into<I::GenericArg>
|
+ Into<I::GenericArg>
|
||||||
+ IntoKind<Kind = ty::RegionKind<I>>
|
+ IntoKind<Kind = ty::RegionKind<I>>
|
||||||
+ Flags
|
+ Flags
|
||||||
|
+ TypeVisitable<I>
|
||||||
{
|
{
|
||||||
|
fn new_bound(interner: I, debruijn: ty::DebruijnIndex, var: I::BoundRegion) -> Self;
|
||||||
|
|
||||||
fn new_anon_bound(interner: I, debruijn: ty::DebruijnIndex, var: ty::BoundVar) -> Self;
|
fn new_anon_bound(interner: I, debruijn: ty::DebruijnIndex, var: ty::BoundVar) -> Self;
|
||||||
|
|
||||||
fn new_static(interner: I) -> Self;
|
fn new_static(interner: I) -> Self;
|
||||||
@ -87,6 +92,8 @@ pub trait Const<I: Interner<Const = Self>>:
|
|||||||
|
|
||||||
fn new_var(interner: I, var: ty::ConstVid, ty: I::Ty) -> Self;
|
fn new_var(interner: I, var: ty::ConstVid, ty: I::Ty) -> Self;
|
||||||
|
|
||||||
|
fn new_bound(interner: I, debruijn: ty::DebruijnIndex, var: I::BoundConst, ty: I::Ty) -> Self;
|
||||||
|
|
||||||
fn new_anon_bound(
|
fn new_anon_bound(
|
||||||
interner: I,
|
interner: I,
|
||||||
debruijn: ty::DebruijnIndex,
|
debruijn: ty::DebruijnIndex,
|
||||||
@ -162,3 +169,7 @@ pub trait BoundVarLike<I: Interner> {
|
|||||||
|
|
||||||
fn assert_eq(self, var: I::BoundVarKind);
|
fn assert_eq(self, var: I::BoundVarKind);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub trait ParamLike {
|
||||||
|
fn index(self) -> u32;
|
||||||
|
}
|
||||||
|
@ -7,26 +7,22 @@ use crate::inherent::*;
|
|||||||
use crate::ir_print::IrPrint;
|
use crate::ir_print::IrPrint;
|
||||||
use crate::solve::inspect::CanonicalGoalEvaluationStep;
|
use crate::solve::inspect::CanonicalGoalEvaluationStep;
|
||||||
use crate::visit::{Flags, TypeSuperVisitable, TypeVisitable};
|
use crate::visit::{Flags, TypeSuperVisitable, TypeVisitable};
|
||||||
use crate::{
|
use crate::{self as ty, DebugWithInfcx};
|
||||||
AliasTerm, AliasTermKind, AliasTy, AliasTyKind, CanonicalVarInfo, CoercePredicate,
|
|
||||||
DebugWithInfcx, ExistentialProjection, ExistentialTraitRef, FnSig, GenericArgKind,
|
|
||||||
NormalizesTo, ProjectionPredicate, SubtypePredicate, TermKind, TraitPredicate, TraitRef,
|
|
||||||
};
|
|
||||||
|
|
||||||
pub trait Interner:
|
pub trait Interner:
|
||||||
Sized
|
Sized
|
||||||
+ Copy
|
+ Copy
|
||||||
+ IrPrint<AliasTy<Self>>
|
+ IrPrint<ty::AliasTy<Self>>
|
||||||
+ IrPrint<AliasTerm<Self>>
|
+ IrPrint<ty::AliasTerm<Self>>
|
||||||
+ IrPrint<TraitRef<Self>>
|
+ IrPrint<ty::TraitRef<Self>>
|
||||||
+ IrPrint<TraitPredicate<Self>>
|
+ IrPrint<ty::TraitPredicate<Self>>
|
||||||
+ IrPrint<ExistentialTraitRef<Self>>
|
+ IrPrint<ty::ExistentialTraitRef<Self>>
|
||||||
+ IrPrint<ExistentialProjection<Self>>
|
+ IrPrint<ty::ExistentialProjection<Self>>
|
||||||
+ IrPrint<ProjectionPredicate<Self>>
|
+ IrPrint<ty::ProjectionPredicate<Self>>
|
||||||
+ IrPrint<NormalizesTo<Self>>
|
+ IrPrint<ty::NormalizesTo<Self>>
|
||||||
+ IrPrint<SubtypePredicate<Self>>
|
+ IrPrint<ty::SubtypePredicate<Self>>
|
||||||
+ IrPrint<CoercePredicate<Self>>
|
+ IrPrint<ty::CoercePredicate<Self>>
|
||||||
+ IrPrint<FnSig<Self>>
|
+ IrPrint<ty::FnSig<Self>>
|
||||||
{
|
{
|
||||||
type DefId: Copy + Debug + Hash + Eq + TypeVisitable<Self>;
|
type DefId: Copy + Debug + Hash + Eq + TypeVisitable<Self>;
|
||||||
type AdtDef: Copy + Debug + Hash + Eq;
|
type AdtDef: Copy + Debug + Hash + Eq;
|
||||||
@ -39,9 +35,9 @@ pub trait Interner:
|
|||||||
+ DebugWithInfcx<Self>
|
+ DebugWithInfcx<Self>
|
||||||
+ Hash
|
+ Hash
|
||||||
+ Eq
|
+ Eq
|
||||||
+ IntoKind<Kind = GenericArgKind<Self>>
|
+ IntoKind<Kind = ty::GenericArgKind<Self>>
|
||||||
+ TypeVisitable<Self>;
|
+ TypeVisitable<Self>;
|
||||||
type Term: Copy + Debug + Hash + Eq + IntoKind<Kind = TermKind<Self>> + TypeVisitable<Self>;
|
type Term: Copy + Debug + Hash + Eq + IntoKind<Kind = ty::TermKind<Self>> + TypeVisitable<Self>;
|
||||||
|
|
||||||
type BoundVarKinds: Copy
|
type BoundVarKinds: Copy
|
||||||
+ Debug
|
+ Debug
|
||||||
@ -51,7 +47,7 @@ pub trait Interner:
|
|||||||
+ Default;
|
+ Default;
|
||||||
type BoundVarKind: Copy + Debug + Hash + Eq;
|
type BoundVarKind: Copy + Debug + Hash + Eq;
|
||||||
|
|
||||||
type CanonicalVars: Copy + Debug + Hash + Eq + IntoIterator<Item = CanonicalVarInfo<Self>>;
|
type CanonicalVars: Copy + Debug + Hash + Eq + IntoIterator<Item = ty::CanonicalVarInfo<Self>>;
|
||||||
type PredefinedOpaques: Copy + Debug + Hash + Eq;
|
type PredefinedOpaques: Copy + Debug + Hash + Eq;
|
||||||
type DefiningOpaqueTypes: Copy + Debug + Hash + Default + Eq + TypeVisitable<Self>;
|
type DefiningOpaqueTypes: Copy + Debug + Hash + Default + Eq + TypeVisitable<Self>;
|
||||||
type ExternalConstraints: Copy + Debug + Hash + Eq;
|
type ExternalConstraints: Copy + Debug + Hash + Eq;
|
||||||
@ -65,7 +61,7 @@ pub trait Interner:
|
|||||||
type Ty: Ty<Self>;
|
type Ty: Ty<Self>;
|
||||||
type Tys: Tys<Self>;
|
type Tys: Tys<Self>;
|
||||||
type FnInputTys: Copy + Debug + Hash + Eq + Deref<Target = [Self::Ty]> + TypeVisitable<Self>;
|
type FnInputTys: Copy + Debug + Hash + Eq + Deref<Target = [Self::Ty]> + TypeVisitable<Self>;
|
||||||
type ParamTy: Copy + Debug + Hash + Eq;
|
type ParamTy: Copy + Debug + Hash + Eq + ParamLike;
|
||||||
type BoundTy: Copy + Debug + Hash + Eq + BoundVarLike<Self>;
|
type BoundTy: Copy + Debug + Hash + Eq + BoundVarLike<Self>;
|
||||||
type PlaceholderTy: PlaceholderLike;
|
type PlaceholderTy: PlaceholderLike;
|
||||||
|
|
||||||
@ -81,14 +77,14 @@ pub trait Interner:
|
|||||||
// Kinds of consts
|
// Kinds of consts
|
||||||
type Const: Const<Self>;
|
type Const: Const<Self>;
|
||||||
type PlaceholderConst: PlaceholderLike;
|
type PlaceholderConst: PlaceholderLike;
|
||||||
type ParamConst: Copy + Debug + Hash + Eq;
|
type ParamConst: Copy + Debug + Hash + Eq + ParamLike;
|
||||||
type BoundConst: Copy + Debug + Hash + Eq + BoundVarLike<Self>;
|
type BoundConst: Copy + Debug + Hash + Eq + BoundVarLike<Self>;
|
||||||
type ValueConst: Copy + Debug + Hash + Eq;
|
type ValueConst: Copy + Debug + Hash + Eq;
|
||||||
type ExprConst: Copy + DebugWithInfcx<Self> + Hash + Eq;
|
type ExprConst: Copy + DebugWithInfcx<Self> + Hash + Eq;
|
||||||
|
|
||||||
// Kinds of regions
|
// Kinds of regions
|
||||||
type Region: Region<Self>;
|
type Region: Region<Self>;
|
||||||
type EarlyParamRegion: Copy + Debug + Hash + Eq;
|
type EarlyParamRegion: Copy + Debug + Hash + Eq + ParamLike;
|
||||||
type LateParamRegion: Copy + Debug + Hash + Eq;
|
type LateParamRegion: Copy + Debug + Hash + Eq;
|
||||||
type BoundRegion: Copy + Debug + Hash + Eq + BoundVarLike<Self>;
|
type BoundRegion: Copy + Debug + Hash + Eq + BoundVarLike<Self>;
|
||||||
type PlaceholderRegion: PlaceholderLike;
|
type PlaceholderRegion: PlaceholderLike;
|
||||||
@ -99,23 +95,23 @@ pub trait Interner:
|
|||||||
type Clause: Clause<Self>;
|
type Clause: Clause<Self>;
|
||||||
type Clauses: Copy + Debug + Hash + Eq + TypeSuperVisitable<Self> + Flags;
|
type Clauses: Copy + Debug + Hash + Eq + TypeSuperVisitable<Self> + Flags;
|
||||||
|
|
||||||
fn mk_canonical_var_infos(self, infos: &[CanonicalVarInfo<Self>]) -> Self::CanonicalVars;
|
fn mk_canonical_var_infos(self, infos: &[ty::CanonicalVarInfo<Self>]) -> Self::CanonicalVars;
|
||||||
|
|
||||||
type GenericsOf: GenericsOf<Self>;
|
type GenericsOf: GenericsOf<Self>;
|
||||||
fn generics_of(self, def_id: Self::DefId) -> Self::GenericsOf;
|
fn generics_of(self, def_id: Self::DefId) -> Self::GenericsOf;
|
||||||
|
|
||||||
// FIXME: Remove after uplifting `EarlyBinder`
|
// FIXME: Remove after uplifting `EarlyBinder`
|
||||||
fn type_of_instantiated(self, def_id: Self::DefId, args: Self::GenericArgs) -> Self::Ty;
|
fn type_of(self, def_id: Self::DefId) -> ty::EarlyBinder<Self, Self::Ty>;
|
||||||
|
|
||||||
fn alias_ty_kind(self, alias: AliasTy<Self>) -> AliasTyKind;
|
fn alias_ty_kind(self, alias: ty::AliasTy<Self>) -> ty::AliasTyKind;
|
||||||
|
|
||||||
fn alias_term_kind(self, alias: AliasTerm<Self>) -> AliasTermKind;
|
fn alias_term_kind(self, alias: ty::AliasTerm<Self>) -> ty::AliasTermKind;
|
||||||
|
|
||||||
fn trait_ref_and_own_args_for_alias(
|
fn trait_ref_and_own_args_for_alias(
|
||||||
self,
|
self,
|
||||||
def_id: Self::DefId,
|
def_id: Self::DefId,
|
||||||
args: Self::GenericArgs,
|
args: Self::GenericArgs,
|
||||||
) -> (TraitRef<Self>, Self::OwnItemArgs);
|
) -> (ty::TraitRef<Self>, Self::OwnItemArgs);
|
||||||
|
|
||||||
fn mk_args(self, args: &[Self::GenericArg]) -> Self::GenericArgs;
|
fn mk_args(self, args: &[Self::GenericArg]) -> Self::GenericArgs;
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
#![cfg_attr(
|
#![cfg_attr(
|
||||||
feature = "nightly",
|
feature = "nightly",
|
||||||
feature(associated_type_defaults, min_specialization, never_type, rustc_attrs)
|
feature(associated_type_defaults, min_specialization, never_type, rustc_attrs, negative_impls)
|
||||||
)]
|
)]
|
||||||
#![allow(rustc::usage_of_ty_tykind)]
|
#![allow(rustc::usage_of_ty_tykind)]
|
||||||
#![cfg_attr(feature = "nightly", allow(internal_features))]
|
#![cfg_attr(feature = "nightly", allow(internal_features))]
|
||||||
|
@ -567,7 +567,7 @@ impl<I: Interner> AliasTerm<I> {
|
|||||||
I::Const::new_unevaluated(
|
I::Const::new_unevaluated(
|
||||||
interner,
|
interner,
|
||||||
ty::UnevaluatedConst::new(self.def_id, self.args),
|
ty::UnevaluatedConst::new(self.def_id, self.args),
|
||||||
interner.type_of_instantiated(self.def_id, self.args),
|
interner.type_of(self.def_id).instantiate(interner, &self.args),
|
||||||
)
|
)
|
||||||
.into()
|
.into()
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user