Make associated_item_def_ids for traits use an unstable option to also return associated types for RPITITs
This commit is contained in:
parent
be72beca68
commit
811a1cabda
2 changed files with 100 additions and 5 deletions
|
@ -90,6 +90,7 @@ rustc_queries! {
|
||||||
/// Definitions that were generated with no HIR, would be feeded to return `None`.
|
/// Definitions that were generated with no HIR, would be feeded to return `None`.
|
||||||
query opt_local_def_id_to_hir_id(key: LocalDefId) -> Option<hir::HirId>{
|
query opt_local_def_id_to_hir_id(key: LocalDefId) -> Option<hir::HirId>{
|
||||||
desc { |tcx| "getting HIR ID of `{}`", tcx.def_path_str(key.to_def_id()) }
|
desc { |tcx| "getting HIR ID of `{}`", tcx.def_path_str(key.to_def_id()) }
|
||||||
|
feedable
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Gives access to the HIR node's parent for the HIR owner `key`.
|
/// Gives access to the HIR node's parent for the HIR owner `key`.
|
||||||
|
@ -166,6 +167,7 @@ rustc_queries! {
|
||||||
}
|
}
|
||||||
cache_on_disk_if { key.is_local() }
|
cache_on_disk_if { key.is_local() }
|
||||||
separate_provide_extern
|
separate_provide_extern
|
||||||
|
feedable
|
||||||
}
|
}
|
||||||
|
|
||||||
query collect_return_position_impl_trait_in_trait_tys(key: DefId)
|
query collect_return_position_impl_trait_in_trait_tys(key: DefId)
|
||||||
|
@ -222,6 +224,7 @@ rustc_queries! {
|
||||||
arena_cache
|
arena_cache
|
||||||
cache_on_disk_if { key.is_local() }
|
cache_on_disk_if { key.is_local() }
|
||||||
separate_provide_extern
|
separate_provide_extern
|
||||||
|
feedable
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Maps from the `DefId` of an item (trait/struct/enum/fn) to the
|
/// Maps from the `DefId` of an item (trait/struct/enum/fn) to the
|
||||||
|
@ -264,6 +267,7 @@ rustc_queries! {
|
||||||
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
|
||||||
|
feedable
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Elaborated version of the predicates from `explicit_item_bounds`.
|
/// Elaborated version of the predicates from `explicit_item_bounds`.
|
||||||
|
@ -588,6 +592,7 @@ rustc_queries! {
|
||||||
desc { |tcx| "computing explicit predicates of `{}`", tcx.def_path_str(key) }
|
desc { |tcx| "computing explicit predicates 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
|
||||||
|
feedable
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the inferred outlives predicates (e.g., for `struct
|
/// Returns the inferred outlives predicates (e.g., for `struct
|
||||||
|
@ -596,6 +601,7 @@ rustc_queries! {
|
||||||
desc { |tcx| "computing inferred outlives predicates of `{}`", tcx.def_path_str(key) }
|
desc { |tcx| "computing inferred outlives predicates 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
|
||||||
|
feedable
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Maps from the `DefId` of a trait to the list of
|
/// Maps from the `DefId` of a trait to the list of
|
||||||
|
@ -728,6 +734,7 @@ rustc_queries! {
|
||||||
desc { |tcx| "computing associated item data for `{}`", tcx.def_path_str(key) }
|
desc { |tcx| "computing associated item data 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
|
||||||
|
feedable
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Collects the associated items defined on a trait or impl.
|
/// Collects the associated items defined on a trait or impl.
|
||||||
|
@ -1142,6 +1149,7 @@ rustc_queries! {
|
||||||
desc { |tcx| "looking up definition kind of `{}`", tcx.def_path_str(def_id) }
|
desc { |tcx| "looking up definition kind of `{}`", tcx.def_path_str(def_id) }
|
||||||
cache_on_disk_if { def_id.is_local() }
|
cache_on_disk_if { def_id.is_local() }
|
||||||
separate_provide_extern
|
separate_provide_extern
|
||||||
|
feedable
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The `opt_rpitit_info` query returns the pair of the def id of the function where the RPIT
|
/// The `opt_rpitit_info` query returns the pair of the def id of the function where the RPIT
|
||||||
|
@ -1165,6 +1173,7 @@ rustc_queries! {
|
||||||
desc { |tcx| "looking up span for `{}`'s identifier", tcx.def_path_str(def_id) }
|
desc { |tcx| "looking up span for `{}`'s identifier", tcx.def_path_str(def_id) }
|
||||||
cache_on_disk_if { def_id.is_local() }
|
cache_on_disk_if { def_id.is_local() }
|
||||||
separate_provide_extern
|
separate_provide_extern
|
||||||
|
feedable
|
||||||
}
|
}
|
||||||
|
|
||||||
query lookup_stability(def_id: DefId) -> Option<attr::Stability> {
|
query lookup_stability(def_id: DefId) -> Option<attr::Stability> {
|
||||||
|
@ -1506,6 +1515,7 @@ rustc_queries! {
|
||||||
desc { |tcx| "looking up whether `{}` is a default impl", tcx.def_path_str(def_id) }
|
desc { |tcx| "looking up whether `{}` is a default impl", tcx.def_path_str(def_id) }
|
||||||
cache_on_disk_if { def_id.is_local() }
|
cache_on_disk_if { def_id.is_local() }
|
||||||
separate_provide_extern
|
separate_provide_extern
|
||||||
|
feedable
|
||||||
}
|
}
|
||||||
|
|
||||||
query check_well_formed(key: hir::OwnerId) -> () {
|
query check_well_formed(key: hir::OwnerId) -> () {
|
||||||
|
@ -1703,6 +1713,7 @@ rustc_queries! {
|
||||||
query visibility(def_id: DefId) -> ty::Visibility<DefId> {
|
query visibility(def_id: DefId) -> ty::Visibility<DefId> {
|
||||||
desc { |tcx| "computing visibility of `{}`", tcx.def_path_str(def_id) }
|
desc { |tcx| "computing visibility of `{}`", tcx.def_path_str(def_id) }
|
||||||
separate_provide_extern
|
separate_provide_extern
|
||||||
|
feedable
|
||||||
}
|
}
|
||||||
|
|
||||||
query inhabited_predicate_adt(key: DefId) -> ty::inhabitedness::InhabitedPredicate<'tcx> {
|
query inhabited_predicate_adt(key: DefId) -> ty::inhabitedness::InhabitedPredicate<'tcx> {
|
||||||
|
|
|
@ -4,7 +4,8 @@ use rustc_hir::def::DefKind;
|
||||||
use rustc_hir::def_id::{DefId, LocalDefId};
|
use rustc_hir::def_id::{DefId, LocalDefId};
|
||||||
use rustc_hir::definitions::DefPathData;
|
use rustc_hir::definitions::DefPathData;
|
||||||
use rustc_hir::intravisit::{self, Visitor};
|
use rustc_hir::intravisit::{self, Visitor};
|
||||||
use rustc_middle::ty::{self, DefIdTree, TyCtxt};
|
use rustc_middle::ty::{self, DefIdTree, ImplTraitInTraitData, InternalSubsts, TyCtxt};
|
||||||
|
use rustc_span::symbol::kw;
|
||||||
|
|
||||||
pub fn provide(providers: &mut ty::query::Providers) {
|
pub fn provide(providers: &mut ty::query::Providers) {
|
||||||
*providers = ty::query::Providers {
|
*providers = ty::query::Providers {
|
||||||
|
@ -21,9 +22,37 @@ pub fn provide(providers: &mut ty::query::Providers) {
|
||||||
fn associated_item_def_ids(tcx: TyCtxt<'_>, def_id: DefId) -> &[DefId] {
|
fn associated_item_def_ids(tcx: TyCtxt<'_>, def_id: DefId) -> &[DefId] {
|
||||||
let item = tcx.hir().expect_item(def_id.expect_local());
|
let item = tcx.hir().expect_item(def_id.expect_local());
|
||||||
match item.kind {
|
match item.kind {
|
||||||
hir::ItemKind::Trait(.., ref trait_item_refs) => tcx.arena.alloc_from_iter(
|
hir::ItemKind::Trait(.., ref trait_item_refs) => {
|
||||||
trait_item_refs.iter().map(|trait_item_ref| trait_item_ref.id.owner_id.to_def_id()),
|
if tcx.sess.opts.unstable_opts.lower_impl_trait_in_trait_to_assoc_ty {
|
||||||
|
// We collect RPITITs for each trait method's return type and create a
|
||||||
|
// corresponding associated item using associated_items_for_impl_trait_in_trait
|
||||||
|
// query.
|
||||||
|
tcx.arena.alloc_from_iter(
|
||||||
|
trait_item_refs
|
||||||
|
.iter()
|
||||||
|
.map(|trait_item_ref| trait_item_ref.id.owner_id.to_def_id())
|
||||||
|
.chain(
|
||||||
|
trait_item_refs
|
||||||
|
.iter()
|
||||||
|
.filter(|trait_item_ref| {
|
||||||
|
matches!(trait_item_ref.kind, hir::AssocItemKind::Fn { .. })
|
||||||
|
})
|
||||||
|
.flat_map(|trait_item_ref| {
|
||||||
|
let trait_fn_def_id =
|
||||||
|
trait_item_ref.id.owner_id.def_id.to_def_id();
|
||||||
|
tcx.associated_items_for_impl_trait_in_trait(trait_fn_def_id)
|
||||||
|
})
|
||||||
|
.map(|def_id| *def_id),
|
||||||
),
|
),
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
tcx.arena.alloc_from_iter(
|
||||||
|
trait_item_refs
|
||||||
|
.iter()
|
||||||
|
.map(|trait_item_ref| trait_item_ref.id.owner_id.to_def_id()),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
hir::ItemKind::Impl(ref impl_) => tcx.arena.alloc_from_iter(
|
hir::ItemKind::Impl(ref impl_) => tcx.arena.alloc_from_iter(
|
||||||
impl_.items.iter().map(|impl_item_ref| impl_item_ref.id.owner_id.to_def_id()),
|
impl_.items.iter().map(|impl_item_ref| impl_item_ref.id.owner_id.to_def_id()),
|
||||||
),
|
),
|
||||||
|
@ -193,7 +222,62 @@ fn associated_item_for_impl_trait_in_trait(
|
||||||
let span = tcx.def_span(opaque_ty_def_id);
|
let span = tcx.def_span(opaque_ty_def_id);
|
||||||
let trait_assoc_ty =
|
let trait_assoc_ty =
|
||||||
tcx.at(span).create_def(trait_def_id.expect_local(), DefPathData::ImplTraitAssocTy);
|
tcx.at(span).create_def(trait_def_id.expect_local(), DefPathData::ImplTraitAssocTy);
|
||||||
trait_assoc_ty.def_id()
|
|
||||||
|
let local_def_id = trait_assoc_ty.def_id();
|
||||||
|
let def_id = local_def_id.to_def_id();
|
||||||
|
|
||||||
|
trait_assoc_ty.opt_def_kind(Some(DefKind::AssocTy));
|
||||||
|
|
||||||
|
// There's no HIR associated with this new synthesized `def_id`, so feed
|
||||||
|
// `opt_local_def_id_to_hir_id` with `None`.
|
||||||
|
trait_assoc_ty.opt_local_def_id_to_hir_id(None);
|
||||||
|
|
||||||
|
// Copy span of the opaque.
|
||||||
|
trait_assoc_ty.def_ident_span(Some(span));
|
||||||
|
|
||||||
|
// Add the def_id of the function and opaque that generated this synthesized associated type.
|
||||||
|
trait_assoc_ty.opt_rpitit_info(Some(ImplTraitInTraitData::Trait {
|
||||||
|
fn_def_id,
|
||||||
|
opaque_def_id: opaque_ty_def_id.to_def_id(),
|
||||||
|
}));
|
||||||
|
|
||||||
|
trait_assoc_ty.associated_item(ty::AssocItem {
|
||||||
|
name: kw::Empty,
|
||||||
|
kind: ty::AssocKind::Type,
|
||||||
|
def_id,
|
||||||
|
trait_item_def_id: None,
|
||||||
|
container: ty::TraitContainer,
|
||||||
|
fn_has_self_parameter: false,
|
||||||
|
});
|
||||||
|
|
||||||
|
// Copy visility of the containing function.
|
||||||
|
trait_assoc_ty.visibility(tcx.visibility(fn_def_id));
|
||||||
|
|
||||||
|
// Copy impl_defaultness of the containing function.
|
||||||
|
trait_assoc_ty.impl_defaultness(tcx.impl_defaultness(fn_def_id));
|
||||||
|
|
||||||
|
// Copy type_of of the opaque.
|
||||||
|
trait_assoc_ty.type_of(ty::EarlyBinder(tcx.mk_opaque(
|
||||||
|
opaque_ty_def_id.to_def_id(),
|
||||||
|
InternalSubsts::identity_for_item(tcx, opaque_ty_def_id.to_def_id()),
|
||||||
|
)));
|
||||||
|
|
||||||
|
// Copy generics_of of the opaque.
|
||||||
|
trait_assoc_ty.generics_of(tcx.generics_of(opaque_ty_def_id).clone());
|
||||||
|
|
||||||
|
// There are no predicates for the synthesized associated type.
|
||||||
|
trait_assoc_ty.explicit_predicates_of(ty::GenericPredicates {
|
||||||
|
parent: Some(trait_def_id),
|
||||||
|
predicates: &[],
|
||||||
|
});
|
||||||
|
|
||||||
|
// There are no inferred outlives for the synthesized associated type.
|
||||||
|
trait_assoc_ty.inferred_outlives_of(&[]);
|
||||||
|
|
||||||
|
// FIXME implement this.
|
||||||
|
trait_assoc_ty.explicit_item_bounds(&[]);
|
||||||
|
|
||||||
|
local_def_id
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Given an `trait_assoc_def_id` that corresponds to a previously synthesized impl trait in trait
|
/// Given an `trait_assoc_def_id` that corresponds to a previously synthesized impl trait in trait
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue