add TyCtxt::as_lang_item, use in new solver

This commit is contained in:
Michael Goulet 2024-06-29 23:01:24 -04:00
parent 49ff3909fb
commit a21ba34896
5 changed files with 126 additions and 75 deletions

View File

@ -11,6 +11,7 @@
use crate::{MethodKind, Target}; use crate::{MethodKind, Target};
use rustc_ast as ast; use rustc_ast as ast;
use rustc_data_structures::fx::FxIndexMap;
use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
use rustc_macros::{Decodable, Encodable, HashStable_Generic}; use rustc_macros::{Decodable, Encodable, HashStable_Generic};
use rustc_span::symbol::{kw, sym, Symbol}; use rustc_span::symbol::{kw, sym, Symbol};
@ -23,6 +24,7 @@ pub struct LanguageItems {
/// Mappings from lang items to their possibly found [`DefId`]s. /// Mappings from lang items to their possibly found [`DefId`]s.
/// The index corresponds to the order in [`LangItem`]. /// The index corresponds to the order in [`LangItem`].
items: [Option<DefId>; std::mem::variant_count::<LangItem>()], items: [Option<DefId>; std::mem::variant_count::<LangItem>()],
reverse_items: FxIndexMap<DefId, LangItem>,
/// Lang items that were not found during collection. /// Lang items that were not found during collection.
pub missing: Vec<LangItem>, pub missing: Vec<LangItem>,
} }
@ -30,7 +32,11 @@ pub struct LanguageItems {
impl LanguageItems { impl LanguageItems {
/// Construct an empty collection of lang items and no missing ones. /// Construct an empty collection of lang items and no missing ones.
pub fn new() -> Self { pub fn new() -> Self {
Self { items: [None; std::mem::variant_count::<LangItem>()], missing: Vec::new() } Self {
items: [None; std::mem::variant_count::<LangItem>()],
reverse_items: FxIndexMap::default(),
missing: Vec::new(),
}
} }
pub fn get(&self, item: LangItem) -> Option<DefId> { pub fn get(&self, item: LangItem) -> Option<DefId> {
@ -39,6 +45,11 @@ pub fn get(&self, item: LangItem) -> Option<DefId> {
pub fn set(&mut self, item: LangItem, def_id: DefId) { pub fn set(&mut self, item: LangItem, def_id: DefId) {
self.items[item as usize] = Some(def_id); self.items[item as usize] = Some(def_id);
self.reverse_items.insert(def_id, item);
}
pub fn from_def_id(&self, def_id: DefId) -> Option<LangItem> {
self.reverse_items.get(&def_id).copied()
} }
pub fn iter(&self) -> impl Iterator<Item = (LangItem, DefId)> + '_ { pub fn iter(&self) -> impl Iterator<Item = (LangItem, DefId)> + '_ {

View File

@ -27,6 +27,10 @@ pub fn is_lang_item(self, def_id: DefId, lang_item: LangItem) -> bool {
self.lang_items().get(lang_item) == Some(def_id) self.lang_items().get(lang_item) == Some(def_id)
} }
pub fn as_lang_item(self, def_id: DefId) -> Option<LangItem> {
self.lang_items().from_def_id(def_id)
}
/// Given a [`DefId`] of one of the [`Fn`], [`FnMut`] or [`FnOnce`] traits, /// Given a [`DefId`] of one of the [`Fn`], [`FnMut`] or [`FnOnce`] traits,
/// returns a corresponding [`ty::ClosureKind`]. /// returns a corresponding [`ty::ClosureKind`].
/// For any other [`DefId`] return `None`. /// For any other [`DefId`] return `None`.

View File

@ -366,6 +366,10 @@ fn is_lang_item(self, def_id: DefId, lang_item: TraitSolverLangItem) -> bool {
self.is_lang_item(def_id, trait_lang_item_to_lang_item(lang_item)) self.is_lang_item(def_id, trait_lang_item_to_lang_item(lang_item))
} }
fn as_lang_item(self, def_id: DefId) -> Option<TraitSolverLangItem> {
lang_item_to_trait_lang_item(self.lang_items().from_def_id(def_id)?)
}
fn associated_type_def_ids(self, def_id: DefId) -> impl IntoIterator<Item = DefId> { fn associated_type_def_ids(self, def_id: DefId) -> impl IntoIterator<Item = DefId> {
self.associated_items(def_id) self.associated_items(def_id)
.in_definition_order() .in_definition_order()
@ -584,44 +588,61 @@ fn find_const_ty_from_env(
} }
} }
fn trait_lang_item_to_lang_item(lang_item: TraitSolverLangItem) -> LangItem { macro_rules! bidirectional_lang_item_map {
($($name:ident),+ $(,)?) => {
fn trait_lang_item_to_lang_item(lang_item: TraitSolverLangItem) -> LangItem {
match lang_item { match lang_item {
TraitSolverLangItem::AsyncDestruct => LangItem::AsyncDestruct, $(TraitSolverLangItem::$name => LangItem::$name,)+
TraitSolverLangItem::AsyncFnKindHelper => LangItem::AsyncFnKindHelper,
TraitSolverLangItem::AsyncFnKindUpvars => LangItem::AsyncFnKindUpvars,
TraitSolverLangItem::AsyncFnOnceOutput => LangItem::AsyncFnOnceOutput,
TraitSolverLangItem::AsyncIterator => LangItem::AsyncIterator,
TraitSolverLangItem::CallOnceFuture => LangItem::CallOnceFuture,
TraitSolverLangItem::CallRefFuture => LangItem::CallRefFuture,
TraitSolverLangItem::Clone => LangItem::Clone,
TraitSolverLangItem::Copy => LangItem::Copy,
TraitSolverLangItem::Coroutine => LangItem::Coroutine,
TraitSolverLangItem::CoroutineReturn => LangItem::CoroutineReturn,
TraitSolverLangItem::CoroutineYield => LangItem::CoroutineYield,
TraitSolverLangItem::Destruct => LangItem::Destruct,
TraitSolverLangItem::DiscriminantKind => LangItem::DiscriminantKind,
TraitSolverLangItem::DynMetadata => LangItem::DynMetadata,
TraitSolverLangItem::EffectsMaybe => LangItem::EffectsMaybe,
TraitSolverLangItem::EffectsIntersection => LangItem::EffectsIntersection,
TraitSolverLangItem::EffectsIntersectionOutput => LangItem::EffectsIntersectionOutput,
TraitSolverLangItem::EffectsNoRuntime => LangItem::EffectsNoRuntime,
TraitSolverLangItem::EffectsRuntime => LangItem::EffectsRuntime,
TraitSolverLangItem::FnPtrTrait => LangItem::FnPtrTrait,
TraitSolverLangItem::FusedIterator => LangItem::FusedIterator,
TraitSolverLangItem::Future => LangItem::Future,
TraitSolverLangItem::FutureOutput => LangItem::FutureOutput,
TraitSolverLangItem::Iterator => LangItem::Iterator,
TraitSolverLangItem::Metadata => LangItem::Metadata,
TraitSolverLangItem::Option => LangItem::Option,
TraitSolverLangItem::PointeeTrait => LangItem::PointeeTrait,
TraitSolverLangItem::PointerLike => LangItem::PointerLike,
TraitSolverLangItem::Poll => LangItem::Poll,
TraitSolverLangItem::Sized => LangItem::Sized,
TraitSolverLangItem::TransmuteTrait => LangItem::TransmuteTrait,
TraitSolverLangItem::Tuple => LangItem::Tuple,
TraitSolverLangItem::Unpin => LangItem::Unpin,
TraitSolverLangItem::Unsize => LangItem::Unsize,
} }
}
fn lang_item_to_trait_lang_item(lang_item: LangItem) -> Option<TraitSolverLangItem> {
Some(match lang_item {
$(LangItem::$name => TraitSolverLangItem::$name,)+
_ => return None,
})
}
}
}
bidirectional_lang_item_map! {
// tidy-alphabetical-start
AsyncDestruct,
AsyncFnKindHelper,
AsyncFnKindUpvars,
AsyncFnOnceOutput,
AsyncIterator,
CallOnceFuture,
CallRefFuture,
Clone,
Copy,
Coroutine,
CoroutineReturn,
CoroutineYield,
Destruct,
DiscriminantKind,
DynMetadata,
EffectsMaybe,
EffectsIntersection,
EffectsIntersectionOutput,
EffectsNoRuntime,
EffectsRuntime,
FnPtrTrait,
FusedIterator,
Future,
FutureOutput,
Iterator,
Metadata,
Option,
PointeeTrait,
PointerLike,
Poll,
Sized,
TransmuteTrait,
Tuple,
Unpin,
Unsize,
// tidy-alphabetical-end
} }
impl<'tcx> rustc_type_ir::inherent::DefId<TyCtxt<'tcx>> for DefId { impl<'tcx> rustc_type_ir::inherent::DefId<TyCtxt<'tcx>> for DefId {

View File

@ -387,48 +387,61 @@ fn assemble_builtin_impl_candidates<G: GoalKind<D>>(
G::consider_auto_trait_candidate(self, goal) G::consider_auto_trait_candidate(self, goal)
} else if cx.trait_is_alias(trait_def_id) { } else if cx.trait_is_alias(trait_def_id) {
G::consider_trait_alias_candidate(self, goal) G::consider_trait_alias_candidate(self, goal)
} else if cx.is_lang_item(trait_def_id, TraitSolverLangItem::Sized) {
G::consider_builtin_sized_candidate(self, goal)
} else if cx.is_lang_item(trait_def_id, TraitSolverLangItem::Copy)
|| cx.is_lang_item(trait_def_id, TraitSolverLangItem::Clone)
{
G::consider_builtin_copy_clone_candidate(self, goal)
} else if cx.is_lang_item(trait_def_id, TraitSolverLangItem::PointerLike) {
G::consider_builtin_pointer_like_candidate(self, goal)
} else if cx.is_lang_item(trait_def_id, TraitSolverLangItem::FnPtrTrait) {
G::consider_builtin_fn_ptr_trait_candidate(self, goal)
} else if let Some(kind) = self.cx().fn_trait_kind_from_def_id(trait_def_id) { } else if let Some(kind) = self.cx().fn_trait_kind_from_def_id(trait_def_id) {
G::consider_builtin_fn_trait_candidates(self, goal, kind) G::consider_builtin_fn_trait_candidates(self, goal, kind)
} else if let Some(kind) = self.cx().async_fn_trait_kind_from_def_id(trait_def_id) { } else if let Some(kind) = self.cx().async_fn_trait_kind_from_def_id(trait_def_id) {
G::consider_builtin_async_fn_trait_candidates(self, goal, kind) G::consider_builtin_async_fn_trait_candidates(self, goal, kind)
} else if cx.is_lang_item(trait_def_id, TraitSolverLangItem::AsyncFnKindHelper) {
G::consider_builtin_async_fn_kind_helper_candidate(self, goal)
} else if cx.is_lang_item(trait_def_id, TraitSolverLangItem::Tuple) {
G::consider_builtin_tuple_candidate(self, goal)
} else if cx.is_lang_item(trait_def_id, TraitSolverLangItem::PointeeTrait) {
G::consider_builtin_pointee_candidate(self, goal)
} else if cx.is_lang_item(trait_def_id, TraitSolverLangItem::Future) {
G::consider_builtin_future_candidate(self, goal)
} else if cx.is_lang_item(trait_def_id, TraitSolverLangItem::Iterator) {
G::consider_builtin_iterator_candidate(self, goal)
} else if cx.is_lang_item(trait_def_id, TraitSolverLangItem::FusedIterator) {
G::consider_builtin_fused_iterator_candidate(self, goal)
} else if cx.is_lang_item(trait_def_id, TraitSolverLangItem::AsyncIterator) {
G::consider_builtin_async_iterator_candidate(self, goal)
} else if cx.is_lang_item(trait_def_id, TraitSolverLangItem::Coroutine) {
G::consider_builtin_coroutine_candidate(self, goal)
} else if cx.is_lang_item(trait_def_id, TraitSolverLangItem::DiscriminantKind) {
G::consider_builtin_discriminant_kind_candidate(self, goal)
} else if cx.is_lang_item(trait_def_id, TraitSolverLangItem::AsyncDestruct) {
G::consider_builtin_async_destruct_candidate(self, goal)
} else if cx.is_lang_item(trait_def_id, TraitSolverLangItem::Destruct) {
G::consider_builtin_destruct_candidate(self, goal)
} else if cx.is_lang_item(trait_def_id, TraitSolverLangItem::TransmuteTrait) {
G::consider_builtin_transmute_candidate(self, goal)
} else if cx.is_lang_item(trait_def_id, TraitSolverLangItem::EffectsIntersection) {
G::consider_builtin_effects_intersection_candidate(self, goal)
} else { } else {
Err(NoSolution) match cx.as_lang_item(trait_def_id) {
Some(TraitSolverLangItem::Sized) => G::consider_builtin_sized_candidate(self, goal),
Some(TraitSolverLangItem::Copy | TraitSolverLangItem::Clone) => {
G::consider_builtin_copy_clone_candidate(self, goal)
}
Some(TraitSolverLangItem::PointerLike) => {
G::consider_builtin_pointer_like_candidate(self, goal)
}
Some(TraitSolverLangItem::FnPtrTrait) => {
G::consider_builtin_fn_ptr_trait_candidate(self, goal)
}
Some(TraitSolverLangItem::AsyncFnKindHelper) => {
G::consider_builtin_async_fn_kind_helper_candidate(self, goal)
}
Some(TraitSolverLangItem::Tuple) => G::consider_builtin_tuple_candidate(self, goal),
Some(TraitSolverLangItem::PointeeTrait) => {
G::consider_builtin_pointee_candidate(self, goal)
}
Some(TraitSolverLangItem::Future) => {
G::consider_builtin_future_candidate(self, goal)
}
Some(TraitSolverLangItem::Iterator) => {
G::consider_builtin_iterator_candidate(self, goal)
}
Some(TraitSolverLangItem::FusedIterator) => {
G::consider_builtin_fused_iterator_candidate(self, goal)
}
Some(TraitSolverLangItem::AsyncIterator) => {
G::consider_builtin_async_iterator_candidate(self, goal)
}
Some(TraitSolverLangItem::Coroutine) => {
G::consider_builtin_coroutine_candidate(self, goal)
}
Some(TraitSolverLangItem::DiscriminantKind) => {
G::consider_builtin_discriminant_kind_candidate(self, goal)
}
Some(TraitSolverLangItem::AsyncDestruct) => {
G::consider_builtin_async_destruct_candidate(self, goal)
}
Some(TraitSolverLangItem::Destruct) => {
G::consider_builtin_destruct_candidate(self, goal)
}
Some(TraitSolverLangItem::TransmuteTrait) => {
G::consider_builtin_transmute_candidate(self, goal)
}
Some(TraitSolverLangItem::EffectsIntersection) => {
G::consider_builtin_effects_intersection_candidate(self, goal)
}
_ => Err(NoSolution),
}
}; };
candidates.extend(result); candidates.extend(result);

View File

@ -220,6 +220,8 @@ fn explicit_super_predicates_of(
fn is_lang_item(self, def_id: Self::DefId, lang_item: TraitSolverLangItem) -> bool; fn is_lang_item(self, def_id: Self::DefId, lang_item: TraitSolverLangItem) -> bool;
fn as_lang_item(self, def_id: Self::DefId) -> Option<TraitSolverLangItem>;
fn associated_type_def_ids(self, def_id: Self::DefId) -> impl IntoIterator<Item = Self::DefId>; fn associated_type_def_ids(self, def_id: Self::DefId) -> impl IntoIterator<Item = Self::DefId>;
// FIXME: move `fast_reject` into `rustc_type_ir`. // FIXME: move `fast_reject` into `rustc_type_ir`.