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

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)
}
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,
/// returns a corresponding [`ty::ClosureKind`].
/// 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))
}
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> {
self.associated_items(def_id)
.in_definition_order()
@ -584,46 +588,63 @@ fn find_const_ty_from_env(
}
}
fn trait_lang_item_to_lang_item(lang_item: TraitSolverLangItem) -> LangItem {
match lang_item {
TraitSolverLangItem::AsyncDestruct => LangItem::AsyncDestruct,
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,
macro_rules! bidirectional_lang_item_map {
($($name:ident),+ $(,)?) => {
fn trait_lang_item_to_lang_item(lang_item: TraitSolverLangItem) -> LangItem {
match lang_item {
$(TraitSolverLangItem::$name => LangItem::$name,)+
}
}
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 {
fn as_local(self) -> Option<LocalDefId> {
self.as_local()

View File

@ -387,48 +387,61 @@ fn assemble_builtin_impl_candidates<G: GoalKind<D>>(
G::consider_auto_trait_candidate(self, goal)
} else if cx.trait_is_alias(trait_def_id) {
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) {
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) {
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 {
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);

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 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>;
// FIXME: move `fast_reject` into `rustc_type_ir`.