Skip to content

Commit 26a71b9

Browse files
authored
Rollup merge of #127145 - compiler-errors:as_lang_item, r=lcnr
Add `as_lang_item` to `LanguageItems`, new trait solver Add `as_lang_item` which turns `DefId` into a `TraitSolverLangItem` in the new trait solver, so we can turn the large chain of if statements in `assemble_builtin_impl_candidates` into a match instead. r? lcnr
2 parents 22d4ce4 + 5a83751 commit 26a71b9

File tree

6 files changed

+164
-91
lines changed

6 files changed

+164
-91
lines changed

compiler/rustc_hir/src/lang_items.rs

+12-1
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ use crate::def_id::DefId;
1111
use crate::{MethodKind, Target};
1212

1313
use rustc_ast as ast;
14+
use rustc_data_structures::fx::FxIndexMap;
1415
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
1516
use rustc_macros::{Decodable, Encodable, HashStable_Generic};
1617
use rustc_span::symbol::{kw, sym, Symbol};
@@ -23,14 +24,19 @@ pub struct LanguageItems {
2324
/// Mappings from lang items to their possibly found [`DefId`]s.
2425
/// The index corresponds to the order in [`LangItem`].
2526
items: [Option<DefId>; std::mem::variant_count::<LangItem>()],
27+
reverse_items: FxIndexMap<DefId, LangItem>,
2628
/// Lang items that were not found during collection.
2729
pub missing: Vec<LangItem>,
2830
}
2931

3032
impl LanguageItems {
3133
/// Construct an empty collection of lang items and no missing ones.
3234
pub fn new() -> Self {
33-
Self { items: [None; std::mem::variant_count::<LangItem>()], missing: Vec::new() }
35+
Self {
36+
items: [None; std::mem::variant_count::<LangItem>()],
37+
reverse_items: FxIndexMap::default(),
38+
missing: Vec::new(),
39+
}
3440
}
3541

3642
pub fn get(&self, item: LangItem) -> Option<DefId> {
@@ -39,6 +45,11 @@ impl LanguageItems {
3945

4046
pub fn set(&mut self, item: LangItem, def_id: DefId) {
4147
self.items[item as usize] = Some(def_id);
48+
self.reverse_items.insert(def_id, item);
49+
}
50+
51+
pub fn from_def_id(&self, def_id: DefId) -> Option<LangItem> {
52+
self.reverse_items.get(&def_id).copied()
4253
}
4354

4455
pub fn iter(&self) -> impl Iterator<Item = (LangItem, DefId)> + '_ {

compiler/rustc_middle/src/middle/lang_items.rs

+4
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,10 @@ impl<'tcx> TyCtxt<'tcx> {
2727
self.lang_items().get(lang_item) == Some(def_id)
2828
}
2929

30+
pub fn as_lang_item(self, def_id: DefId) -> Option<LangItem> {
31+
self.lang_items().from_def_id(def_id)
32+
}
33+
3034
/// Given a [`DefId`] of one of the [`Fn`], [`FnMut`] or [`FnOnce`] traits,
3135
/// returns a corresponding [`ty::ClosureKind`].
3236
/// For any other [`DefId`] return `None`.

compiler/rustc_middle/src/ty/context.rs

+64-45
Original file line numberDiff line numberDiff line change
@@ -366,6 +366,10 @@ impl<'tcx> Interner for TyCtxt<'tcx> {
366366
self.is_lang_item(def_id, trait_lang_item_to_lang_item(lang_item))
367367
}
368368

369+
fn as_lang_item(self, def_id: DefId) -> Option<TraitSolverLangItem> {
370+
lang_item_to_trait_lang_item(self.lang_items().from_def_id(def_id)?)
371+
}
372+
369373
fn associated_type_def_ids(self, def_id: DefId) -> impl IntoIterator<Item = DefId> {
370374
self.associated_items(def_id)
371375
.in_definition_order()
@@ -533,14 +537,6 @@ impl<'tcx> Interner for TyCtxt<'tcx> {
533537
self.trait_def(trait_def_id).implement_via_object
534538
}
535539

536-
fn fn_trait_kind_from_def_id(self, trait_def_id: DefId) -> Option<ty::ClosureKind> {
537-
self.fn_trait_kind_from_def_id(trait_def_id)
538-
}
539-
540-
fn async_fn_trait_kind_from_def_id(self, trait_def_id: DefId) -> Option<ty::ClosureKind> {
541-
self.async_fn_trait_kind_from_def_id(trait_def_id)
542-
}
543-
544540
fn supertrait_def_ids(self, trait_def_id: DefId) -> impl IntoIterator<Item = DefId> {
545541
self.supertrait_def_ids(trait_def_id)
546542
}
@@ -584,46 +580,69 @@ impl<'tcx> Interner for TyCtxt<'tcx> {
584580
}
585581
}
586582

587-
fn trait_lang_item_to_lang_item(lang_item: TraitSolverLangItem) -> LangItem {
588-
match lang_item {
589-
TraitSolverLangItem::AsyncDestruct => LangItem::AsyncDestruct,
590-
TraitSolverLangItem::AsyncFnKindHelper => LangItem::AsyncFnKindHelper,
591-
TraitSolverLangItem::AsyncFnKindUpvars => LangItem::AsyncFnKindUpvars,
592-
TraitSolverLangItem::AsyncFnOnceOutput => LangItem::AsyncFnOnceOutput,
593-
TraitSolverLangItem::AsyncIterator => LangItem::AsyncIterator,
594-
TraitSolverLangItem::CallOnceFuture => LangItem::CallOnceFuture,
595-
TraitSolverLangItem::CallRefFuture => LangItem::CallRefFuture,
596-
TraitSolverLangItem::Clone => LangItem::Clone,
597-
TraitSolverLangItem::Copy => LangItem::Copy,
598-
TraitSolverLangItem::Coroutine => LangItem::Coroutine,
599-
TraitSolverLangItem::CoroutineReturn => LangItem::CoroutineReturn,
600-
TraitSolverLangItem::CoroutineYield => LangItem::CoroutineYield,
601-
TraitSolverLangItem::Destruct => LangItem::Destruct,
602-
TraitSolverLangItem::DiscriminantKind => LangItem::DiscriminantKind,
603-
TraitSolverLangItem::DynMetadata => LangItem::DynMetadata,
604-
TraitSolverLangItem::EffectsMaybe => LangItem::EffectsMaybe,
605-
TraitSolverLangItem::EffectsIntersection => LangItem::EffectsIntersection,
606-
TraitSolverLangItem::EffectsIntersectionOutput => LangItem::EffectsIntersectionOutput,
607-
TraitSolverLangItem::EffectsNoRuntime => LangItem::EffectsNoRuntime,
608-
TraitSolverLangItem::EffectsRuntime => LangItem::EffectsRuntime,
609-
TraitSolverLangItem::FnPtrTrait => LangItem::FnPtrTrait,
610-
TraitSolverLangItem::FusedIterator => LangItem::FusedIterator,
611-
TraitSolverLangItem::Future => LangItem::Future,
612-
TraitSolverLangItem::FutureOutput => LangItem::FutureOutput,
613-
TraitSolverLangItem::Iterator => LangItem::Iterator,
614-
TraitSolverLangItem::Metadata => LangItem::Metadata,
615-
TraitSolverLangItem::Option => LangItem::Option,
616-
TraitSolverLangItem::PointeeTrait => LangItem::PointeeTrait,
617-
TraitSolverLangItem::PointerLike => LangItem::PointerLike,
618-
TraitSolverLangItem::Poll => LangItem::Poll,
619-
TraitSolverLangItem::Sized => LangItem::Sized,
620-
TraitSolverLangItem::TransmuteTrait => LangItem::TransmuteTrait,
621-
TraitSolverLangItem::Tuple => LangItem::Tuple,
622-
TraitSolverLangItem::Unpin => LangItem::Unpin,
623-
TraitSolverLangItem::Unsize => LangItem::Unsize,
583+
macro_rules! bidirectional_lang_item_map {
584+
($($name:ident),+ $(,)?) => {
585+
fn trait_lang_item_to_lang_item(lang_item: TraitSolverLangItem) -> LangItem {
586+
match lang_item {
587+
$(TraitSolverLangItem::$name => LangItem::$name,)+
588+
}
589+
}
590+
591+
fn lang_item_to_trait_lang_item(lang_item: LangItem) -> Option<TraitSolverLangItem> {
592+
Some(match lang_item {
593+
$(LangItem::$name => TraitSolverLangItem::$name,)+
594+
_ => return None,
595+
})
596+
}
624597
}
625598
}
626599

600+
bidirectional_lang_item_map! {
601+
// tidy-alphabetical-start
602+
AsyncDestruct,
603+
AsyncFn,
604+
AsyncFnKindHelper,
605+
AsyncFnKindUpvars,
606+
AsyncFnMut,
607+
AsyncFnOnce,
608+
AsyncFnOnceOutput,
609+
AsyncIterator,
610+
CallOnceFuture,
611+
CallRefFuture,
612+
Clone,
613+
Copy,
614+
Coroutine,
615+
CoroutineReturn,
616+
CoroutineYield,
617+
Destruct,
618+
DiscriminantKind,
619+
DynMetadata,
620+
EffectsIntersection,
621+
EffectsIntersectionOutput,
622+
EffectsMaybe,
623+
EffectsNoRuntime,
624+
EffectsRuntime,
625+
Fn,
626+
FnMut,
627+
FnOnce,
628+
FnPtrTrait,
629+
FusedIterator,
630+
Future,
631+
FutureOutput,
632+
Iterator,
633+
Metadata,
634+
Option,
635+
PointeeTrait,
636+
PointerLike,
637+
Poll,
638+
Sized,
639+
TransmuteTrait,
640+
Tuple,
641+
Unpin,
642+
Unsize,
643+
// tidy-alphabetical-end
644+
}
645+
627646
impl<'tcx> rustc_type_ir::inherent::DefId<TyCtxt<'tcx>> for DefId {
628647
fn as_local(self) -> Option<LocalDefId> {
629648
self.as_local()

compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs

+76-41
Original file line numberDiff line numberDiff line change
@@ -387,48 +387,83 @@ where
387387
G::consider_auto_trait_candidate(self, goal)
388388
} else if cx.trait_is_alias(trait_def_id) {
389389
G::consider_trait_alias_candidate(self, goal)
390-
} else if cx.is_lang_item(trait_def_id, TraitSolverLangItem::Sized) {
391-
G::consider_builtin_sized_candidate(self, goal)
392-
} else if cx.is_lang_item(trait_def_id, TraitSolverLangItem::Copy)
393-
|| cx.is_lang_item(trait_def_id, TraitSolverLangItem::Clone)
394-
{
395-
G::consider_builtin_copy_clone_candidate(self, goal)
396-
} else if cx.is_lang_item(trait_def_id, TraitSolverLangItem::PointerLike) {
397-
G::consider_builtin_pointer_like_candidate(self, goal)
398-
} else if cx.is_lang_item(trait_def_id, TraitSolverLangItem::FnPtrTrait) {
399-
G::consider_builtin_fn_ptr_trait_candidate(self, goal)
400-
} else if let Some(kind) = self.cx().fn_trait_kind_from_def_id(trait_def_id) {
401-
G::consider_builtin_fn_trait_candidates(self, goal, kind)
402-
} else if let Some(kind) = self.cx().async_fn_trait_kind_from_def_id(trait_def_id) {
403-
G::consider_builtin_async_fn_trait_candidates(self, goal, kind)
404-
} else if cx.is_lang_item(trait_def_id, TraitSolverLangItem::AsyncFnKindHelper) {
405-
G::consider_builtin_async_fn_kind_helper_candidate(self, goal)
406-
} else if cx.is_lang_item(trait_def_id, TraitSolverLangItem::Tuple) {
407-
G::consider_builtin_tuple_candidate(self, goal)
408-
} else if cx.is_lang_item(trait_def_id, TraitSolverLangItem::PointeeTrait) {
409-
G::consider_builtin_pointee_candidate(self, goal)
410-
} else if cx.is_lang_item(trait_def_id, TraitSolverLangItem::Future) {
411-
G::consider_builtin_future_candidate(self, goal)
412-
} else if cx.is_lang_item(trait_def_id, TraitSolverLangItem::Iterator) {
413-
G::consider_builtin_iterator_candidate(self, goal)
414-
} else if cx.is_lang_item(trait_def_id, TraitSolverLangItem::FusedIterator) {
415-
G::consider_builtin_fused_iterator_candidate(self, goal)
416-
} else if cx.is_lang_item(trait_def_id, TraitSolverLangItem::AsyncIterator) {
417-
G::consider_builtin_async_iterator_candidate(self, goal)
418-
} else if cx.is_lang_item(trait_def_id, TraitSolverLangItem::Coroutine) {
419-
G::consider_builtin_coroutine_candidate(self, goal)
420-
} else if cx.is_lang_item(trait_def_id, TraitSolverLangItem::DiscriminantKind) {
421-
G::consider_builtin_discriminant_kind_candidate(self, goal)
422-
} else if cx.is_lang_item(trait_def_id, TraitSolverLangItem::AsyncDestruct) {
423-
G::consider_builtin_async_destruct_candidate(self, goal)
424-
} else if cx.is_lang_item(trait_def_id, TraitSolverLangItem::Destruct) {
425-
G::consider_builtin_destruct_candidate(self, goal)
426-
} else if cx.is_lang_item(trait_def_id, TraitSolverLangItem::TransmuteTrait) {
427-
G::consider_builtin_transmute_candidate(self, goal)
428-
} else if cx.is_lang_item(trait_def_id, TraitSolverLangItem::EffectsIntersection) {
429-
G::consider_builtin_effects_intersection_candidate(self, goal)
430390
} else {
431-
Err(NoSolution)
391+
match cx.as_lang_item(trait_def_id) {
392+
Some(TraitSolverLangItem::Sized) => G::consider_builtin_sized_candidate(self, goal),
393+
Some(TraitSolverLangItem::Copy | TraitSolverLangItem::Clone) => {
394+
G::consider_builtin_copy_clone_candidate(self, goal)
395+
}
396+
Some(TraitSolverLangItem::Fn) => {
397+
G::consider_builtin_fn_trait_candidates(self, goal, ty::ClosureKind::Fn)
398+
}
399+
Some(TraitSolverLangItem::FnMut) => {
400+
G::consider_builtin_fn_trait_candidates(self, goal, ty::ClosureKind::FnMut)
401+
}
402+
Some(TraitSolverLangItem::FnOnce) => {
403+
G::consider_builtin_fn_trait_candidates(self, goal, ty::ClosureKind::FnOnce)
404+
}
405+
Some(TraitSolverLangItem::AsyncFn) => {
406+
G::consider_builtin_async_fn_trait_candidates(self, goal, ty::ClosureKind::Fn)
407+
}
408+
Some(TraitSolverLangItem::AsyncFnMut) => {
409+
G::consider_builtin_async_fn_trait_candidates(
410+
self,
411+
goal,
412+
ty::ClosureKind::FnMut,
413+
)
414+
}
415+
Some(TraitSolverLangItem::AsyncFnOnce) => {
416+
G::consider_builtin_async_fn_trait_candidates(
417+
self,
418+
goal,
419+
ty::ClosureKind::FnOnce,
420+
)
421+
}
422+
Some(TraitSolverLangItem::PointerLike) => {
423+
G::consider_builtin_pointer_like_candidate(self, goal)
424+
}
425+
Some(TraitSolverLangItem::FnPtrTrait) => {
426+
G::consider_builtin_fn_ptr_trait_candidate(self, goal)
427+
}
428+
Some(TraitSolverLangItem::AsyncFnKindHelper) => {
429+
G::consider_builtin_async_fn_kind_helper_candidate(self, goal)
430+
}
431+
Some(TraitSolverLangItem::Tuple) => G::consider_builtin_tuple_candidate(self, goal),
432+
Some(TraitSolverLangItem::PointeeTrait) => {
433+
G::consider_builtin_pointee_candidate(self, goal)
434+
}
435+
Some(TraitSolverLangItem::Future) => {
436+
G::consider_builtin_future_candidate(self, goal)
437+
}
438+
Some(TraitSolverLangItem::Iterator) => {
439+
G::consider_builtin_iterator_candidate(self, goal)
440+
}
441+
Some(TraitSolverLangItem::FusedIterator) => {
442+
G::consider_builtin_fused_iterator_candidate(self, goal)
443+
}
444+
Some(TraitSolverLangItem::AsyncIterator) => {
445+
G::consider_builtin_async_iterator_candidate(self, goal)
446+
}
447+
Some(TraitSolverLangItem::Coroutine) => {
448+
G::consider_builtin_coroutine_candidate(self, goal)
449+
}
450+
Some(TraitSolverLangItem::DiscriminantKind) => {
451+
G::consider_builtin_discriminant_kind_candidate(self, goal)
452+
}
453+
Some(TraitSolverLangItem::AsyncDestruct) => {
454+
G::consider_builtin_async_destruct_candidate(self, goal)
455+
}
456+
Some(TraitSolverLangItem::Destruct) => {
457+
G::consider_builtin_destruct_candidate(self, goal)
458+
}
459+
Some(TraitSolverLangItem::TransmuteTrait) => {
460+
G::consider_builtin_transmute_candidate(self, goal)
461+
}
462+
Some(TraitSolverLangItem::EffectsIntersection) => {
463+
G::consider_builtin_effects_intersection_candidate(self, goal)
464+
}
465+
_ => Err(NoSolution),
466+
}
432467
};
433468

434469
candidates.extend(result);

compiler/rustc_type_ir/src/interner.rs

+2-4
Original file line numberDiff line numberDiff line change
@@ -220,6 +220,8 @@ pub trait Interner:
220220

221221
fn is_lang_item(self, def_id: Self::DefId, lang_item: TraitSolverLangItem) -> bool;
222222

223+
fn as_lang_item(self, def_id: Self::DefId) -> Option<TraitSolverLangItem>;
224+
223225
fn associated_type_def_ids(self, def_id: Self::DefId) -> impl IntoIterator<Item = Self::DefId>;
224226

225227
// FIXME: move `fast_reject` into `rustc_type_ir`.
@@ -252,10 +254,6 @@ pub trait Interner:
252254

253255
fn trait_may_be_implemented_via_object(self, trait_def_id: Self::DefId) -> bool;
254256

255-
fn fn_trait_kind_from_def_id(self, trait_def_id: Self::DefId) -> Option<ty::ClosureKind>;
256-
257-
fn async_fn_trait_kind_from_def_id(self, trait_def_id: Self::DefId) -> Option<ty::ClosureKind>;
258-
259257
fn supertrait_def_ids(self, trait_def_id: Self::DefId)
260258
-> impl IntoIterator<Item = Self::DefId>;
261259

compiler/rustc_type_ir/src/lang_items.rs

+6
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,11 @@
33
pub enum TraitSolverLangItem {
44
// tidy-alphabetical-start
55
AsyncDestruct,
6+
AsyncFn,
67
AsyncFnKindHelper,
78
AsyncFnKindUpvars,
9+
AsyncFnMut,
10+
AsyncFnOnce,
811
AsyncFnOnceOutput,
912
AsyncIterator,
1013
CallOnceFuture,
@@ -22,6 +25,9 @@ pub enum TraitSolverLangItem {
2225
EffectsMaybe,
2326
EffectsNoRuntime,
2427
EffectsRuntime,
28+
Fn,
29+
FnMut,
30+
FnOnce,
2531
FnPtrTrait,
2632
FusedIterator,
2733
Future,

0 commit comments

Comments
 (0)