Skip to main content

hir_def/
lang_item.rs

1//! Collects lang items: items marked with `#[lang = "..."]` attribute.
2//!
3//! This attribute to tell the compiler about semi built-in std library
4//! features, such as Fn family of traits.
5use base_db::SourceDatabase;
6use hir_expand::name::Name;
7use intern::{Symbol, sym};
8use rustc_hash::FxHashMap;
9use rustc_type_ir::lang_items::{SolverAdtLangItem, SolverProjectionLangItem, SolverTraitLangItem};
10use stdx::impl_from;
11
12use crate::{
13    AdtId, AssocItemId, AttrDefId, ConstId, Crate, EnumId, EnumVariantId, FunctionId, ImplId,
14    ItemContainerId, MacroId, ModuleDefId, StaticId, StructId, TraitId, TypeAliasId, UnionId,
15    attrs::AttrFlags,
16    nameres::{DefMap, assoc::TraitItems, crate_def_map, crate_local_def_map},
17    unstable_features::UnstableFeatures,
18};
19
20#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
21pub enum LangItemTarget {
22    EnumId(EnumId),
23    FunctionId(FunctionId),
24    ImplId(ImplId),
25    StaticId(StaticId),
26    StructId(StructId),
27    UnionId(UnionId),
28    TypeAliasId(TypeAliasId),
29    TraitId(TraitId),
30    EnumVariantId(EnumVariantId),
31    ConstId(ConstId),
32    MacroId(MacroId),
33}
34
35impl_from!(
36    EnumId, FunctionId, ImplId, StaticId, StructId, UnionId, TypeAliasId, TraitId, EnumVariantId, ConstId, MacroId for LangItemTarget
37);
38
39/// Salsa query. This will look for lang items in a specific crate.
40#[salsa::tracked(returns(as_deref))]
41pub fn crate_lang_items(db: &dyn SourceDatabase, krate: Crate) -> Option<Box<LangItems>> {
42    if !UnstableFeatures::query(db, krate).lang_items {
43        // First query this, *before* querying the def map, to not create a dependency edge.
44        return None;
45    }
46
47    let mut lang_items = LangItems::default();
48
49    let _p = tracing::info_span!("crate_lang_items_query", ?krate).entered();
50
51    let crate_def_map = crate_def_map(db, krate);
52    for (_, module_data) in crate_def_map.modules() {
53        for impl_def in module_data.scope.inherent_impls() {
54            lang_items.collect_lang_item(db, impl_def);
55            for &(_, assoc) in impl_def.impl_items(db).items.iter() {
56                match assoc {
57                    AssocItemId::FunctionId(f) => lang_items.collect_lang_item(db, f),
58                    AssocItemId::TypeAliasId(t) => lang_items.collect_lang_item(db, t),
59                    AssocItemId::ConstId(c) => lang_items.collect_lang_item(db, c),
60                }
61            }
62        }
63
64        for def in module_data.scope.declarations() {
65            match def {
66                ModuleDefId::TraitId(trait_) => {
67                    lang_items.collect_lang_item(db, trait_);
68                    TraitItems::query(db, trait_).items.iter().for_each(|&(_, assoc_id)| {
69                        match assoc_id {
70                            AssocItemId::FunctionId(f) => {
71                                lang_items.collect_lang_item(db, f);
72                            }
73                            AssocItemId::TypeAliasId(alias) => {
74                                lang_items.collect_lang_item(db, alias)
75                            }
76                            AssocItemId::ConstId(c) => lang_items.collect_lang_item(db, c),
77                        }
78                    });
79                }
80                ModuleDefId::AdtId(AdtId::EnumId(e)) => {
81                    lang_items.collect_lang_item(db, e);
82                    e.enum_variants(db).variants.values().for_each(|&(id, _)| {
83                        lang_items.collect_lang_item(db, id);
84                    });
85                }
86                ModuleDefId::AdtId(AdtId::StructId(s)) => {
87                    lang_items.collect_lang_item(db, s);
88                }
89                ModuleDefId::AdtId(AdtId::UnionId(u)) => {
90                    lang_items.collect_lang_item(db, u);
91                }
92                ModuleDefId::FunctionId(f) => {
93                    lang_items.collect_lang_item(db, f);
94                }
95                ModuleDefId::StaticId(s) => {
96                    lang_items.collect_lang_item(db, s);
97                }
98                ModuleDefId::TypeAliasId(t) => {
99                    lang_items.collect_lang_item(db, t);
100                }
101                ModuleDefId::ConstId(c) => lang_items.collect_lang_item(db, c),
102                _ => {}
103            }
104        }
105    }
106
107    if matches!(krate.data(db).origin, base_db::CrateOrigin::Lang(base_db::LangCrateOrigin::Core)) {
108        lang_items.fill_non_lang_core_items(db, crate_def_map);
109    }
110
111    lang_items.resolve_manually(db);
112
113    if lang_items.is_empty() {
114        None
115    } else {
116        lang_items.shrink_to_fit();
117        Some(Box::new(lang_items))
118    }
119}
120
121// A firewall query, so that changing crate code for non-`feature(lang_items)` crate will not require recomputing
122// the more expensive `lang_items()` query.
123#[salsa::tracked(returns(deref))]
124fn crate_extern_prelude(db: &dyn SourceDatabase, start_crate: Crate) -> Box<[Crate]> {
125    crate_local_def_map(db, start_crate)
126        .local(db)
127        .extern_prelude()
128        .map(|(_, (module, _))| module.krate(db))
129        .filter(|&krate| {
130            // Some crates declares themselves as extern crate like `extern crate self as core`.
131            // Ignore these to prevent cycles.
132            krate != start_crate
133        })
134        .collect()
135}
136
137/// Salsa query. Look for a lang items, starting from the specified crate and recursively
138/// traversing its dependencies.
139#[salsa::tracked(returns(ref))]
140pub fn lang_items(db: &dyn SourceDatabase, start_crate: Crate) -> LangItems {
141    let _p = tracing::debug_span!("lang_items_query", ?start_crate).entered();
142
143    let mut result = crate_lang_items(db, start_crate).cloned().unwrap_or_default();
144
145    // Our `CrateGraph` eagerly inserts sysroot dependencies like `core` or `std` into dependencies
146    // even if the target crate has `#![no_std]`, `#![no_core]` or shadowed sysroot dependencies
147    // like `dependencies.std.path = ".."`. So we use `extern_prelude()` instead of
148    // `CrateData.dependencies` here, which has already come through such sysroot complexities
149    // while nameres.
150    //
151    // See https://github.com/rust-lang/rust-analyzer/pull/20475 for details.
152    for &krate in crate_extern_prelude(db, start_crate) {
153        result.merge_prefer_other(lang_items(db, krate));
154    }
155
156    result
157}
158
159impl LangItems {
160    fn collect_lang_item<T>(&mut self, db: &dyn SourceDatabase, item: T)
161    where
162        T: Into<AttrDefId> + Into<LangItemTarget> + Copy,
163    {
164        if let Some(lang_item) = AttrFlags::lang_item(db, item.into()) {
165            tracing::trace!("found lang item `{lang_item}`");
166            self.assign_lang_item(lang_item, item.into());
167        }
168    }
169}
170
171fn resolve_core_trait(
172    db: &dyn SourceDatabase,
173    core_def_map: &DefMap,
174    modules: &[Symbol],
175    name: Symbol,
176) -> Option<TraitId> {
177    let mut current = &core_def_map[core_def_map.root];
178    for module in modules {
179        let Some((ModuleDefId::ModuleId(cur), _)) =
180            current.scope.type_(&Name::new_symbol_root(module.clone()))
181        else {
182            return None;
183        };
184        if cur.krate(db) != core_def_map.krate() || cur.block(db) != core_def_map.block_id() {
185            return None;
186        }
187        current = &core_def_map[cur];
188    }
189    let Some((ModuleDefId::TraitId(trait_), _)) = current.scope.type_(&Name::new_symbol_root(name))
190    else {
191        return None;
192    };
193    Some(trait_)
194}
195
196fn resolve_core_macro(
197    db: &dyn SourceDatabase,
198    core_def_map: &DefMap,
199    modules: &[Symbol],
200    name: Symbol,
201) -> Option<MacroId> {
202    let mut current = &core_def_map[core_def_map.root];
203    for module in modules {
204        let Some((ModuleDefId::ModuleId(cur), _)) =
205            current.scope.type_(&Name::new_symbol_root(module.clone()))
206        else {
207            return None;
208        };
209        if cur.krate(db) != core_def_map.krate() || cur.block(db) != core_def_map.block_id() {
210            return None;
211        }
212        current = &core_def_map[cur];
213    }
214    current.scope.makro(&Name::new_symbol_root(name))
215}
216
217impl LangItems {
218    fn resolve_manually(&mut self, db: &dyn SourceDatabase) {
219        let parent_trait =
220            |lang_item: &mut Option<TraitId>, def: Option<FunctionId>| match def?.loc(db).container
221            {
222                ItemContainerId::TraitId(trait_) => {
223                    *lang_item = Some(trait_);
224                    Some(trait_)
225                }
226                _ => None,
227            };
228        let assoc_types =
229            |trait_: TraitId, assoc_types: &mut [(&mut Option<TypeAliasId>, Symbol)]| {
230                let trait_items = trait_.trait_items(db);
231                for (assoc_type, name) in assoc_types {
232                    **assoc_type =
233                        trait_items.associated_type_by_name(&Name::new_symbol_root(name.clone()));
234                }
235            };
236        let methods = |trait_: TraitId, assoc_types: &mut [(&mut Option<FunctionId>, Symbol)]| {
237            let trait_items = trait_.trait_items(db);
238            for (assoc_type, name) in assoc_types {
239                **assoc_type = trait_items.method_by_name(&Name::new_symbol_root(name.clone()));
240            }
241        };
242        (|| {
243            let into_future = parent_trait(&mut self.IntoFuture, self.IntoFutureIntoFuture)?;
244            assoc_types(into_future, &mut [(&mut self.IntoFutureOutput, sym::Output)]);
245            Some(())
246        })();
247
248        (|| {
249            let into_iterator = parent_trait(&mut self.IntoIterator, self.IntoIterIntoIter)?;
250            assoc_types(
251                into_iterator,
252                &mut [
253                    (&mut self.IntoIteratorItem, sym::Item),
254                    (&mut self.IntoIterIntoIterType, sym::IntoIter),
255                ],
256            );
257            Some(())
258        })();
259
260        (|| {
261            assoc_types(self.Iterator?, &mut [(&mut self.IteratorItem, sym::Item)]);
262            Some(())
263        })();
264
265        (|| {
266            assoc_types(self.AsyncIterator?, &mut [(&mut self.AsyncIteratorItem, sym::Item)]);
267            Some(())
268        })();
269
270        for (op_trait, op_method, op_method_name) in [
271            (self.Fn, &mut self.Fn_call, sym::call),
272            (self.FnMut, &mut self.FnMut_call_mut, sym::call_mut),
273            (self.FnOnce, &mut self.FnOnce_call_once, sym::call_once),
274            (self.AsyncFn, &mut self.AsyncFn_async_call, sym::async_call),
275            (self.AsyncFnMut, &mut self.AsyncFnMut_async_call_mut, sym::async_call_mut),
276            (self.AsyncFnOnce, &mut self.AsyncFnOnce_async_call_once, sym::async_call_once),
277            (self.Not, &mut self.Not_not, sym::not),
278            (self.Neg, &mut self.Neg_neg, sym::neg),
279            (self.Add, &mut self.Add_add, sym::add),
280            (self.Mul, &mut self.Mul_mul, sym::mul),
281            (self.Sub, &mut self.Sub_sub, sym::sub),
282            (self.Div, &mut self.Div_div, sym::div),
283            (self.Rem, &mut self.Rem_rem, sym::rem),
284            (self.Shl, &mut self.Shl_shl, sym::shl),
285            (self.Shr, &mut self.Shr_shr, sym::shr),
286            (self.BitXor, &mut self.BitXor_bitxor, sym::bitxor),
287            (self.BitOr, &mut self.BitOr_bitor, sym::bitor),
288            (self.BitAnd, &mut self.BitAnd_bitand, sym::bitand),
289            (self.AddAssign, &mut self.AddAssign_add_assign, sym::add_assign),
290            (self.MulAssign, &mut self.MulAssign_mul_assign, sym::mul_assign),
291            (self.SubAssign, &mut self.SubAssign_sub_assign, sym::sub_assign),
292            (self.DivAssign, &mut self.DivAssign_div_assign, sym::div_assign),
293            (self.RemAssign, &mut self.RemAssign_rem_assign, sym::rem_assign),
294            (self.ShlAssign, &mut self.ShlAssign_shl_assign, sym::shl_assign),
295            (self.ShrAssign, &mut self.ShrAssign_shr_assign, sym::shr_assign),
296            (self.BitXorAssign, &mut self.BitXorAssign_bitxor_assign, sym::bitxor_assign),
297            (self.BitOrAssign, &mut self.BitOrAssign_bitor_assign, sym::bitor_assign),
298            (self.BitAndAssign, &mut self.BitAndAssign_bitand_assign, sym::bitand_assign),
299            (self.Debug, &mut self.Debug_fmt, sym::fmt),
300            (self.Deref, &mut self.Deref_deref, sym::deref),
301            (self.DerefMut, &mut self.DerefMut_deref_mut, sym::deref_mut),
302            (self.Index, &mut self.Index_index, sym::index),
303            (self.IndexMut, &mut self.IndexMut_index_mut, sym::index_mut),
304        ] {
305            (|| {
306                methods(op_trait?, &mut [(op_method, op_method_name)]);
307                Some(())
308            })();
309        }
310        (|| {
311            methods(
312                self.PartialEq?,
313                &mut [(&mut self.PartialEq_eq, sym::eq), (&mut self.PartialEq_ne, sym::ne)],
314            );
315            Some(())
316        })();
317        (|| {
318            methods(
319                self.PartialOrd?,
320                &mut [
321                    (&mut self.PartialOrd_le, sym::le),
322                    (&mut self.PartialOrd_lt, sym::lt),
323                    (&mut self.PartialOrd_ge, sym::ge),
324                    (&mut self.PartialOrd_gt, sym::gt),
325                ],
326            );
327            Some(())
328        })();
329        (|| {
330            methods(
331                self.Drop?,
332                &mut [(&mut self.Drop_drop, sym::drop), (&mut self.Drop_pin_drop, sym::pin_drop)],
333            );
334            Some(())
335        })();
336    }
337
338    #[inline]
339    pub fn get_solver_trait(&self, lang_item: SolverTraitLangItem) -> Option<TraitId> {
340        self.solver_trait[lang_item as usize]
341    }
342
343    #[inline]
344    pub fn get_solver_projection(
345        &self,
346        lang_item: SolverProjectionLangItem,
347    ) -> Option<TypeAliasId> {
348        self.solver_projection[lang_item as usize]
349    }
350
351    #[inline]
352    pub fn get_solver_adt(&self, lang_item: SolverAdtLangItem) -> Option<AdtId> {
353        self.solver_adt[lang_item as usize]
354    }
355
356    #[inline]
357    pub fn get_reverse_solver_trait(&self, trait_: TraitId) -> Option<SolverTraitLangItem> {
358        self.reverse_solver_trait.get(&trait_).copied()
359    }
360
361    #[inline]
362    pub fn get_reverse_solver_adt(&self, adt: AdtId) -> Option<SolverAdtLangItem> {
363        self.reverse_solver_adt.get(&adt).copied()
364    }
365
366    #[inline]
367    pub fn get_reverse_solver_projection(
368        &self,
369        projection: TypeAliasId,
370    ) -> Option<SolverProjectionLangItem> {
371        self.reverse_solver_projection.get(&projection).copied()
372    }
373
374    fn shrink_to_fit(&mut self) {
375        let Self { reverse_solver_adt, reverse_solver_projection, reverse_solver_trait, .. } = self;
376        reverse_solver_adt.shrink_to_fit();
377        reverse_solver_projection.shrink_to_fit();
378        reverse_solver_trait.shrink_to_fit();
379    }
380
381    fn assign_solver_trait(&mut self, lang_item: SolverTraitLangItem, def: TraitId) {
382        self.solver_trait[lang_item as usize] = Some(def);
383        self.reverse_solver_trait.insert(def, lang_item);
384    }
385
386    fn assign_solver_projection(&mut self, lang_item: SolverProjectionLangItem, def: TypeAliasId) {
387        self.solver_projection[lang_item as usize] = Some(def);
388        self.reverse_solver_projection.insert(def, lang_item);
389    }
390
391    fn assign_solver_adt(&mut self, lang_item: SolverAdtLangItem, def: impl Into<AdtId>) {
392        let def = def.into();
393        self.solver_adt[lang_item as usize] = Some(def);
394        self.reverse_solver_adt.insert(def, lang_item);
395    }
396}
397
398#[salsa::tracked(returns(as_deref))]
399pub fn crate_notable_traits(db: &dyn SourceDatabase, krate: Crate) -> Option<Box<[TraitId]>> {
400    let mut traits = Vec::new();
401
402    let crate_def_map = crate_def_map(db, krate);
403
404    for (_, module_data) in crate_def_map.modules() {
405        for def in module_data.scope.declarations() {
406            if let ModuleDefId::TraitId(trait_) = def
407                && AttrFlags::query(db, trait_.into()).contains(AttrFlags::IS_DOC_NOTABLE_TRAIT)
408            {
409                traits.push(trait_);
410            }
411        }
412    }
413
414    if traits.is_empty() { None } else { Some(traits.into_iter().collect()) }
415}
416
417macro_rules! assign_solver {
418    ( $self:ident, $def:ident, $lang_item:ident, TraitId, solver ) => {
419        $self.assign_solver_trait(SolverTraitLangItem::$lang_item, $def);
420    };
421    ( $self:ident, $def:ident, $lang_item:ident, TypeAliasId, solver ) => {
422        $self.assign_solver_projection(SolverProjectionLangItem::$lang_item, $def);
423    };
424    ( $self:ident, $def:ident, $lang_item:ident, StructId, solver ) => {
425        $self.assign_solver_adt(SolverAdtLangItem::$lang_item, $def);
426    };
427    ( $self:ident, $def:ident, $lang_item:ident, EnumId, solver ) => {
428        $self.assign_solver_adt(SolverAdtLangItem::$lang_item, $def);
429    };
430    ( $self:ident, $def:ident, $lang_item:ident, UnionId, solver ) => {
431        $self.assign_solver_adt(SolverAdtLangItem::$lang_item, $def);
432    };
433    ( $self:ident, $def:ident, $lang_item:ident, $ty:ident ) => {};
434}
435
436macro_rules! solver_exhaustiveness_check {
437    (
438        $dollar:tt, $solver_ty:ident, $id_ty:ident,
439        [ $($id_tys:ident),* ]
440
441        $( $lang_item:ident, $target:ident $(, $solver:ident)?; )*
442    ) => {
443        const _: () = {
444            #[expect(unreachable_patterns, dead_code)]
445            fn exhaustiveness_check(lang_item: $solver_ty) {
446                macro_rules! one_variant {
447                    $(
448                        (
449                            $dollar lang_item:ident, $id_tys, solver
450                        ) => {
451                            ($solver_ty::$dollar lang_item, true)
452                        };
453                    )*
454                    ( $dollar($t:tt)* ) => {
455                        (_, false)
456                    };
457                }
458
459                match (lang_item, true) {
460                    $(
461                        one_variant!( $lang_item, $target $(, $solver )? ) => {}
462                    )*
463                }
464            }
465        };
466    };
467}
468
469macro_rules! get_solver_count {
470    (
471        $dollar:tt, $solver_ty:ident,
472        [ $($id_tys:ident),* ]
473
474        $( $lang_item:ident, $target:ident $(, $solver:ident)?; )*
475    ) => {{
476        let mut max_discriminant = 0;
477        macro_rules! one_variant {
478            $(
479                (
480                    $dollar lang_item:ident, $id_tys, solver
481                ) => {
482                    if $solver_ty::$dollar lang_item as usize > max_discriminant {
483                        max_discriminant = $solver_ty::$dollar lang_item as usize;
484                    }
485                };
486            )*
487            ( $dollar($t:tt)* ) => {};
488        }
489        $(
490            one_variant!($lang_item, $target $(, $solver)?);
491        )*
492        max_discriminant + 1
493    }};
494}
495
496fn merge_array_prefer_other<T: Copy, const N: usize>(
497    this: &mut [Option<T>; N],
498    other: &[Option<T>; N],
499) {
500    for (this, other) in std::iter::zip(this, other) {
501        *this = other.or(*this);
502    }
503}
504
505macro_rules! language_item_table {
506    (
507        $dollar:tt
508        $LangItems:ident =>
509        $( $lang_item:ident, $module:ident :: $name:ident, $target:ident $(, $solver:ident)?; )*
510
511        @non_lang_core_traits:
512
513        $( core::$($non_lang_trait_module:ident)::*, $non_lang_trait:ident; )*
514
515        @non_lang_core_macros:
516
517        $( core::$($non_lang_macro_module:ident)::*, $non_lang_macro:ident, $non_lang_macro_field:ident; )*
518
519        @resolve_manually:
520
521        $( $resolve_manually:ident, $resolve_manually_type:ident; )*
522    ) => {
523        const SOLVER_TRAITS_LEN: usize = get_solver_count! {
524            $dollar, SolverTraitLangItem,
525            [ TraitId ]
526
527            $( $lang_item, $target $(, $solver)?; )*
528        };
529        const SOLVER_PROJECTIONS_LEN: usize = get_solver_count! {
530            $dollar, SolverProjectionLangItem,
531            [ TypeAliasId ]
532
533            $( $lang_item, $target $(, $solver)?; )*
534        };
535        const SOLVER_ADTS_LEN: usize = get_solver_count! {
536            $dollar, SolverAdtLangItem,
537            [ StructId, EnumId, UnionId ]
538
539            $( $lang_item, $target $(, $solver)?; )*
540        };
541
542        #[allow(non_snake_case)] // FIXME: Should we remove this?
543        #[derive(Default, Clone)]
544        pub struct $LangItems {
545            $(
546                pub $lang_item: Option<$target>,
547            )*
548            $(
549                pub $non_lang_trait: Option<TraitId>,
550            )*
551            $(
552                pub $non_lang_macro_field: Option<MacroId>,
553            )*
554            $(
555                pub $resolve_manually: Option<$resolve_manually_type>,
556            )*
557
558            solver_trait: [Option<TraitId>; SOLVER_TRAITS_LEN],
559            solver_adt: [Option<AdtId>; SOLVER_ADTS_LEN],
560            solver_projection: [Option<TypeAliasId>; SOLVER_PROJECTIONS_LEN],
561
562            reverse_solver_trait: FxHashMap<TraitId, SolverTraitLangItem>,
563            reverse_solver_adt: FxHashMap<AdtId, SolverAdtLangItem>,
564            reverse_solver_projection: FxHashMap<TypeAliasId, SolverProjectionLangItem>,
565        }
566
567        impl std::fmt::Debug for $LangItems {
568            fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
569                let mut debug = f.debug_struct(stringify!($LangItems));
570                let Self {
571                    $( $lang_item, )*
572                    $( $non_lang_trait, )*
573                    $( $non_lang_macro_field, )*
574                    $( $resolve_manually, )*
575
576                    solver_trait: _,
577                    solver_adt: _,
578                    solver_projection: _,
579                    reverse_solver_trait: _,
580                    reverse_solver_adt: _,
581                    reverse_solver_projection: _,
582                } = self;
583                $(
584                    if let Some(it) = $lang_item {
585                        debug.field(stringify!($lang_item), it);
586                    }
587                )*
588                $(
589                    if let Some(it) = $non_lang_trait {
590                        debug.field(stringify!($non_lang_trait), it);
591                    }
592                )*
593                $(
594                    if let Some(it) = $non_lang_macro_field {
595                        debug.field(stringify!($non_lang_macro_field), it);
596                    }
597                )*
598                $(
599                    if let Some(it) = $resolve_manually {
600                        debug.field(stringify!($resolve_manually), it);
601                    }
602                )*
603                debug.finish()
604            }
605        }
606
607        impl PartialEq for $LangItems {
608            fn eq(&self, other: &Self) -> bool {
609                let Self {
610                    $( $lang_item, )*
611                    $( $non_lang_trait, )*
612                    $( $non_lang_macro_field, )*
613                    $( $resolve_manually, )*
614
615                    solver_trait: _,
616                    solver_adt: _,
617                    solver_projection: _,
618                    reverse_solver_trait: _,
619                    reverse_solver_adt: _,
620                    reverse_solver_projection: _,
621                } = *self;
622
623                true
624                    $( && $lang_item == other.$lang_item )*
625                    $( && $non_lang_trait == other.$non_lang_trait )*
626                    $( && $non_lang_macro_field == other.$non_lang_macro_field )*
627                    $( && $resolve_manually == other.$resolve_manually )*
628            }
629        }
630
631        impl Eq for $LangItems {}
632
633        impl LangItems {
634            fn is_empty(&self) -> bool {
635                let Self {
636                    $( $lang_item, )*
637                    $( $non_lang_trait, )*
638                    $( $non_lang_macro_field, )*
639                    $( $resolve_manually, )*
640
641                    solver_trait: _,
642                    solver_adt: _,
643                    solver_projection: _,
644                    reverse_solver_trait: _,
645                    reverse_solver_adt: _,
646                    reverse_solver_projection: _,
647                } = *self;
648
649                true
650                    $( && $lang_item.is_none() )*
651                    $( && $non_lang_trait.is_none() )*
652                    $( && $non_lang_macro_field.is_none() )*
653                    $( && $resolve_manually.is_none() )*
654            }
655
656            /// Merges `self` with `other`, with preference to `other` items.
657            fn merge_prefer_other(&mut self, other: &Self) {
658                $( self.$lang_item = other.$lang_item.or(self.$lang_item); )*
659                $( self.$non_lang_trait = other.$non_lang_trait.or(self.$non_lang_trait); )*
660                $( self.$non_lang_macro_field = other.$non_lang_macro_field.or(self.$non_lang_macro_field); )*
661                $( self.$resolve_manually = other.$resolve_manually.or(self.$resolve_manually); )*
662
663                merge_array_prefer_other(&mut self.solver_trait, &other.solver_trait);
664                merge_array_prefer_other(&mut self.solver_adt, &other.solver_adt);
665                merge_array_prefer_other(&mut self.solver_projection, &other.solver_projection);
666
667                self.reverse_solver_trait.extend(&other.reverse_solver_trait);
668                self.reverse_solver_adt.extend(&other.reverse_solver_adt);
669                self.reverse_solver_projection.extend(&other.reverse_solver_projection);
670            }
671
672            fn assign_lang_item(&mut self, name: Symbol, target: LangItemTarget) {
673                match name {
674                    $(
675                        _ if name == $module::$name => {
676                            if let LangItemTarget::$target(target) = target {
677                                self.$lang_item = Some(target);
678
679                                assign_solver!(self, target, $lang_item, $target $(, $solver)? );
680                            }
681                        }
682                    )*
683                    _ => {}
684                }
685            }
686
687            fn fill_non_lang_core_items(&mut self, db: &dyn SourceDatabase, core_def_map: &DefMap) {
688                $( self.$non_lang_trait = resolve_core_trait(db, core_def_map, &[ $(sym::$non_lang_trait_module),* ], sym::$non_lang_trait); )*
689                $( self.$non_lang_macro_field = resolve_core_macro(db, core_def_map, &[ $(sym::$non_lang_macro_module),* ], sym::$non_lang_macro); )*
690            }
691        }
692
693        solver_exhaustiveness_check! {
694            $dollar, SolverTraitLangItem, TraitId,
695            [ TraitId ]
696
697            $( $lang_item, $target $(, $solver)?; )*
698        }
699
700        solver_exhaustiveness_check! {
701            $dollar, SolverProjectionLangItem, TypeAliasId,
702            [ TypeAliasId ]
703
704            $( $lang_item, $target $(, $solver)?; )*
705        }
706
707        solver_exhaustiveness_check! {
708            $dollar, SolverAdtLangItem, AdtId,
709            [ StructId, EnumId, UnionId ]
710
711            $( $lang_item, $target $(, $solver)?; )*
712        }
713
714        #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
715        #[allow(non_camel_case_types)]
716        pub enum LangItemEnum {
717            $(
718                $lang_item,
719            )*
720            $( $non_lang_trait, )*
721            $( $non_lang_macro_field, )*
722            $( $resolve_manually, )*
723        }
724
725        impl LangItemEnum {
726            #[inline]
727            pub fn from_lang_items(self, lang_items: &LangItems) -> Option<LangItemTarget> {
728                match self {
729                    $( LangItemEnum::$lang_item => lang_items.$lang_item.map(Into::into), )*
730                    $( LangItemEnum::$non_lang_trait => lang_items.$non_lang_trait.map(Into::into), )*
731                    $( LangItemEnum::$non_lang_macro_field => lang_items.$non_lang_macro_field.map(Into::into), )*
732                    $( LangItemEnum::$resolve_manually => lang_items.$resolve_manually.map(Into::into), )*
733                }
734            }
735
736            #[inline]
737            pub fn from_symbol(symbol: &Symbol) -> Option<Self> {
738                match symbol {
739                    $( _ if *symbol == $module::$name => Some(Self::$lang_item), )*
740                    _ => None,
741                }
742            }
743        }
744    }
745}
746
747language_item_table! { $ LangItems =>
748//  Variant name,            Name,                     Target;
749    Sized,                   sym::sized,               TraitId,               solver;
750    MetaSized,               sym::meta_sized,          TraitId,               solver;
751    PointeeSized,            sym::pointee_sized,       TraitId,               solver;
752    Unsize,                  sym::unsize,              TraitId,               solver;
753    // Trait injected by `#[derive(PartialEq)]`, (i.e. "Partial EQ").
754    StructuralPeq,           sym::structural_peq,      TraitId;
755    // Trait injected by `#[derive(Eq)]`, (i.e. "Total EQ"; no, I will not apologize).
756    StructuralTeq,           sym::structural_teq,      TraitId;
757    Copy,                    sym::copy,                TraitId,               solver;
758    UseCloned,               sym::use_cloned,          TraitId;
759    Clone,                   sym::clone,               TraitId,               solver;
760    TrivialClone,            sym::trivial_clone,       TraitId,               solver;
761    Sync,                    sym::sync,                TraitId;
762    DiscriminantKind,        sym::discriminant_kind,   TraitId,               solver;
763    // The associated item of the `DiscriminantKind` trait.
764    Discriminant,            sym::discriminant_type,   TypeAliasId;
765
766    PointeeTrait,            sym::pointee_trait,       TraitId,               solver;
767    Metadata,                sym::metadata_type,       TypeAliasId,           solver;
768    DynMetadata,             sym::dyn_metadata,        StructId,              solver;
769
770    Freeze,                  sym::freeze,              TraitId;
771
772    NonNull,                 sym::non_null,            StructId;
773
774    FnPtrTrait,              sym::fn_ptr_trait,        TraitId,               solver;
775    FnPtrAsPtr,              sym::fn_ptr_as_ptr,       FunctionId;
776    FnPtrFromPtr,            sym::fn_ptr_from_ptr,     FunctionId;
777
778    Drop,                    sym::drop,                TraitId,               solver;
779    Destruct,                sym::destruct,            TraitId,               solver;
780    BikeshedGuaranteedNoDrop,sym::bikeshed_guaranteed_no_drop, TraitId,       solver;
781
782    CoerceUnsized,           sym::coerce_unsized,      TraitId;
783    DispatchFromDyn,         sym::dispatch_from_dyn,   TraitId;
784    Reborrow,                sym::reborrow,            TraitId;
785    CoerceShared,            sym::coerce_shared,       TraitId;
786
787    // language items relating to transmutability
788    TransmuteOpts,           sym::transmute_opts,      StructId;
789    TransmuteTrait,          sym::transmute_trait,     TraitId,               solver;
790
791    Add,                     sym::add,                 TraitId;
792    Sub,                     sym::sub,                 TraitId;
793    Mul,                     sym::mul,                 TraitId;
794    Div,                     sym::div,                 TraitId;
795    Rem,                     sym::rem,                 TraitId;
796    Neg,                     sym::neg,                 TraitId;
797    Not,                     sym::not,                 TraitId;
798    BitXor,                  sym::bitxor,              TraitId;
799    BitAnd,                  sym::bitand,              TraitId;
800    BitOr,                   sym::bitor,               TraitId;
801    Shl,                     sym::shl,                 TraitId;
802    Shr,                     sym::shr,                 TraitId;
803    AddAssign,               sym::add_assign,          TraitId;
804    SubAssign,               sym::sub_assign,          TraitId;
805    MulAssign,               sym::mul_assign,          TraitId;
806    DivAssign,               sym::div_assign,          TraitId;
807    RemAssign,               sym::rem_assign,          TraitId;
808    BitXorAssign,            sym::bitxor_assign,       TraitId;
809    BitAndAssign,            sym::bitand_assign,       TraitId;
810    BitOrAssign,             sym::bitor_assign,        TraitId;
811    ShlAssign,               sym::shl_assign,          TraitId;
812    ShrAssign,               sym::shr_assign,          TraitId;
813    Index,                   sym::index,               TraitId;
814    IndexMut,                sym::index_mut,           TraitId;
815
816    UnsafeCell,              sym::unsafe_cell,         StructId;
817    UnsafePinned,            sym::unsafe_pinned,       StructId;
818    VaList,                  sym::va_list,             StructId;
819
820    Deref,                   sym::deref,               TraitId;
821    DerefMut,                sym::deref_mut,           TraitId;
822    DerefPure,               sym::deref_pure,          TraitId;
823    DerefTarget,             sym::deref_target,        TypeAliasId;
824    Receiver,                sym::receiver,            TraitId;
825    ReceiverTarget,          sym::receiver_target,     TypeAliasId;
826
827    Fn,                      sym::fn_,                 TraitId,                solver;
828    FnMut,                   sym::fn_mut,              TraitId,                solver;
829    FnOnce,                  sym::fn_once,             TraitId,                solver;
830    AsyncFn,                 sym::async_fn,            TraitId,                solver;
831    AsyncFnMut,              sym::async_fn_mut,        TraitId,                solver;
832    AsyncFnOnce,             sym::async_fn_once,       TraitId,                solver;
833    AsyncFnKindHelper,       sym::async_fn_kind_helper,TraitId,                solver;
834    AsyncFnKindUpvars,       sym::async_fn_kind_upvars,TypeAliasId,            solver;
835
836    CallRefFuture,           sym::call_ref_future,     TypeAliasId,            solver;
837    CallOnceFuture,          sym::call_once_future,    TypeAliasId,            solver;
838    AsyncFnOnceOutput,       sym::async_fn_once_output, TypeAliasId,           solver;
839
840    FnOnceOutput,            sym::fn_once_output,      TypeAliasId;
841
842    Future,                  sym::future_trait,        TraitId,                solver;
843    AsyncIterator,           sym::async_iterator,      TraitId,                solver;
844    CoroutineState,          sym::coroutine_state,     EnumId;
845    Coroutine,               sym::coroutine,           TraitId,                solver;
846    CoroutineReturn,         sym::coroutine_return,    TypeAliasId,            solver;
847    CoroutineYield,          sym::coroutine_yield,     TypeAliasId,            solver;
848    Unpin,                   sym::unpin,               TraitId,                solver;
849    Pin,                     sym::pin,                 StructId;
850
851    AsyncGenReady,           sym::AsyncGenReady,       FunctionId;
852
853    PartialEq,               sym::eq,                  TraitId;
854    PartialOrd,              sym::partial_ord,         TraitId;
855    CVoid,                   sym::c_void,              EnumId;
856
857    // A number of panic-related lang items. The `panic` item corresponds to divide-by-zero and
858    // various panic cases with `match`. The `panic_bounds_check` item is for indexing arrays.
859    //
860    // The `begin_unwind` lang item has a predefined symbol name and is sort of a "weak lang item"
861    // in the sense that a crate is not required to have it defined to use it, but a final product
862    // is required to define it somewhere. Additionally, there are restrictions on crates that use
863    // a weak lang item, but do not have it defined.
864    Panic,                   sym::panic,               FunctionId;
865    PanicNounwind,           sym::panic_nounwind,      FunctionId;
866    PanicFmt,                sym::panic_fmt,           FunctionId;
867    PanicDisplay,            sym::panic_display,       FunctionId;
868    ConstPanicFmt,           sym::const_panic_fmt,     FunctionId;
869    PanicBoundsCheck,        sym::panic_bounds_check,  FunctionId;
870    PanicMisalignedPointerDereference, sym::panic_misaligned_pointer_dereference, FunctionId;
871    PanicInfo,               sym::panic_info,          StructId;
872    PanicLocation,           sym::panic_location,      StructId;
873    PanicImpl,               sym::panic_impl,          FunctionId;
874    PanicCannotUnwind,       sym::panic_cannot_unwind, FunctionId;
875    PanicNullPointerDereference, sym::panic_null_pointer_dereference, FunctionId;
876    // libstd panic entry point. Necessary for const eval to be able to catch it
877    BeginPanic,              sym::begin_panic,         FunctionId;
878
879    // Lang items needed for `format_args!()`.
880    FormatAlignment,         sym::format_alignment,    EnumId;
881    FormatArgument,          sym::format_argument,     StructId;
882    FormatArguments,         sym::format_arguments,    StructId;
883    FormatCount,             sym::format_count,        EnumId;
884    FormatPlaceholder,       sym::format_placeholder,  StructId;
885    FormatUnsafeArg,         sym::format_unsafe_arg,   StructId;
886
887    ExchangeMalloc,          sym::exchange_malloc,     FunctionId;
888    BoxFree,                 sym::box_free,            FunctionId;
889    DropInPlace,             sym::drop_in_place,       FunctionId;
890    AllocLayout,             sym::alloc_layout,        StructId;
891
892    Start,                   sym::start,               FunctionId;
893
894    EhPersonality,           sym::eh_personality,      FunctionId;
895    EhCatchTypeinfo,         sym::eh_catch_typeinfo,   StaticId;
896
897    OwnedBox,                sym::owned_box,           StructId;
898
899    PhantomData,             sym::phantom_data,        StructId;
900
901    ManuallyDrop,            sym::manually_drop,       StructId;
902
903    MaybeUninit,             sym::maybe_uninit,        UnionId;
904
905    // Align offset for stride != 1; must not panic.
906    AlignOffset,             sym::align_offset,        FunctionId;
907
908    Termination,             sym::termination,         TraitId;
909
910    Try,                     sym::Try,                 TraitId;
911
912    Tuple,                   sym::tuple_trait,         TraitId,               solver;
913
914    SliceLen,                sym::slice_len_fn,        FunctionId;
915
916    // Language items from AST lowering
917    TryTraitFromResidual,    sym::from_residual,       FunctionId;
918    TryTraitFromOutput,      sym::from_output,         FunctionId;
919    TryTraitBranch,          sym::branch,              FunctionId;
920    TryTraitFromYeet,        sym::from_yeet,           FunctionId;
921    ResidualIntoTryType,     sym::into_try_type,       FunctionId;
922
923    PointerLike,             sym::pointer_like,        TraitId;
924
925    ConstParamTy,            sym::const_param_ty,      TraitId;
926
927    Poll,                    sym::Poll,                EnumId,                solver;
928    PollReady,               sym::Ready,               EnumVariantId;
929    PollPending,             sym::Pending,             EnumVariantId;
930
931    // FIXME(swatinem): the following lang items are used for async lowering and
932    // should become obsolete eventually.
933    ResumeTy,                sym::ResumeTy,            StructId;
934    GetContext,              sym::get_context,         FunctionId;
935
936    Context,                 sym::Context,             StructId;
937    FuturePoll,              sym::poll,                FunctionId;
938    FutureOutput,            sym::future_output,       TypeAliasId,           solver;
939
940    Option,                  sym::Option,              EnumId,                solver;
941    OptionSome,              sym::Some,                EnumVariantId;
942    OptionNone,              sym::None,                EnumVariantId;
943
944    ResultOk,                sym::Ok,                  EnumVariantId;
945    ResultErr,               sym::Err,                 EnumVariantId;
946
947    ControlFlowContinue,     sym::Continue,            EnumVariantId;
948    ControlFlowBreak,        sym::Break,               EnumVariantId;
949
950    IntoFutureIntoFuture,    sym::into_future,         FunctionId;
951    IntoIterIntoIter,        sym::into_iter,           FunctionId;
952    IteratorNext,            sym::next,                FunctionId;
953    Iterator,                sym::iterator,            TraitId,               solver;
954    FusedIterator,           sym::fused_iterator,      TraitId,               solver;
955
956    PinNewUnchecked,         sym::new_unchecked,       FunctionId;
957
958    RangeFrom,               sym::RangeFrom,           StructId;
959    RangeFull,               sym::RangeFull,           StructId;
960    RangeInclusiveStruct,    sym::RangeInclusive,      StructId;
961    RangeInclusiveNew,       sym::range_inclusive_new, FunctionId;
962    Range,                   sym::Range,               StructId;
963    RangeToInclusive,        sym::RangeToInclusive,    StructId;
964    RangeTo,                 sym::RangeTo,             StructId;
965
966    RangeFromCopy,           sym::RangeFromCopy,           StructId;
967    RangeInclusiveCopy,      sym::RangeInclusiveCopy,      StructId;
968    RangeCopy,               sym::RangeCopy,               StructId;
969    RangeToInclusiveCopy,    sym::RangeToInclusiveCopy,    StructId;
970
971    String,                  sym::String,              StructId;
972    CStr,                    sym::CStr,                StructId;
973    Ordering,                sym::Ordering,            EnumId;
974
975    Field,                   sym::field,               TraitId,               solver;
976    FieldBase,               sym::field_base,          TypeAliasId,           solver;
977    FieldType,               sym::field_type,          TypeAliasId,           solver;
978
979    RangeMin,                sym::RangeMin,            ConstId;
980    RangeMax,                sym::RangeMax,            ConstId;
981    RangeSub,                sym::RangeSub,            FunctionId;
982
983    @non_lang_core_traits:
984    core::default, Default;
985    core::fmt, Debug;
986    core::hash, Hash;
987    core::cmp, Ord;
988    core::cmp, Eq;
989
990    @non_lang_core_macros:
991    core::default, Default, DefaultDerive;
992    core::fmt, Debug, DebugDerive;
993    core::hash, Hash, HashDerive;
994    core::cmp, PartialOrd, PartialOrdDerive;
995    core::cmp, Ord, OrdDerive;
996    core::cmp, PartialEq, PartialEqDerive;
997    core::cmp, Eq, EqDerive;
998    core::marker, CoercePointee, CoercePointeeDerive;
999    core::marker, CoerceShared, CoerceSharedDerive;
1000    core::marker, Copy, CopyDerive;
1001    core::marker, Reborrow, ReborrowDerive;
1002    core::clone, Clone, CloneDerive;
1003
1004    @resolve_manually:
1005
1006    IntoFuture,                    TraitId;
1007    IntoFutureOutput,              TypeAliasId;
1008    IntoIterator,                  TraitId;
1009    IntoIteratorItem,              TypeAliasId;
1010    IntoIterIntoIterType,          TypeAliasId;
1011    IteratorItem,                  TypeAliasId;
1012    AsyncIteratorItem,             TypeAliasId;
1013
1014    Fn_call,                       FunctionId;
1015    FnMut_call_mut,                FunctionId;
1016    FnOnce_call_once,              FunctionId;
1017    AsyncFn_async_call,            FunctionId;
1018    AsyncFnMut_async_call_mut,     FunctionId;
1019    AsyncFnOnce_async_call_once,   FunctionId;
1020    Not_not,                       FunctionId;
1021    Neg_neg,                       FunctionId;
1022    Add_add,                       FunctionId;
1023    Mul_mul,                       FunctionId;
1024    Sub_sub,                       FunctionId;
1025    Div_div,                       FunctionId;
1026    Rem_rem,                       FunctionId;
1027    Shl_shl,                       FunctionId;
1028    Shr_shr,                       FunctionId;
1029    BitXor_bitxor,                 FunctionId;
1030    BitOr_bitor,                   FunctionId;
1031    BitAnd_bitand,                 FunctionId;
1032    AddAssign_add_assign,          FunctionId;
1033    MulAssign_mul_assign,          FunctionId;
1034    SubAssign_sub_assign,          FunctionId;
1035    DivAssign_div_assign,          FunctionId;
1036    RemAssign_rem_assign,          FunctionId;
1037    ShlAssign_shl_assign,          FunctionId;
1038    ShrAssign_shr_assign,          FunctionId;
1039    BitXorAssign_bitxor_assign,    FunctionId;
1040    BitOrAssign_bitor_assign,      FunctionId;
1041    BitAndAssign_bitand_assign,    FunctionId;
1042    PartialEq_eq,                  FunctionId;
1043    PartialEq_ne,                  FunctionId;
1044    PartialOrd_le,                 FunctionId;
1045    PartialOrd_lt,                 FunctionId;
1046    PartialOrd_ge,                 FunctionId;
1047    PartialOrd_gt,                 FunctionId;
1048    Drop_drop,                     FunctionId;
1049    Drop_pin_drop,                     FunctionId;
1050    Debug_fmt,                     FunctionId;
1051    Deref_deref,                   FunctionId;
1052    DerefMut_deref_mut,            FunctionId;
1053    Index_index,                   FunctionId;
1054    IndexMut_index_mut,            FunctionId;
1055}