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 stdx::impl_from;
9
10use crate::{
11    AdtId, AssocItemId, AttrDefId, ConstId, Crate, EnumId, EnumVariantId, FunctionId, ImplId,
12    ItemContainerId, MacroId, ModuleDefId, StaticId, StructId, TraitId, TypeAliasId, UnionId,
13    attrs::AttrFlags,
14    nameres::{DefMap, assoc::TraitItems, crate_def_map, crate_local_def_map},
15};
16
17#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
18pub enum LangItemTarget {
19    EnumId(EnumId),
20    FunctionId(FunctionId),
21    ImplId(ImplId),
22    StaticId(StaticId),
23    StructId(StructId),
24    UnionId(UnionId),
25    TypeAliasId(TypeAliasId),
26    TraitId(TraitId),
27    EnumVariantId(EnumVariantId),
28    ConstId(ConstId),
29    MacroId(MacroId),
30}
31
32impl_from!(
33    EnumId, FunctionId, ImplId, StaticId, StructId, UnionId, TypeAliasId, TraitId, EnumVariantId, ConstId, MacroId for LangItemTarget
34);
35
36/// Salsa query. This will look for lang items in a specific crate.
37#[salsa::tracked(returns(as_deref))]
38pub fn crate_lang_items(db: &dyn SourceDatabase, krate: Crate) -> Option<Box<LangItems>> {
39    let _p = tracing::info_span!("crate_lang_items_query").entered();
40
41    let mut lang_items = LangItems::default();
42
43    let crate_def_map = crate_def_map(db, krate);
44
45    if !crate_def_map.features().lang_items {
46        return None;
47    }
48
49    for (_, module_data) in crate_def_map.modules() {
50        for impl_def in module_data.scope.inherent_impls() {
51            lang_items.collect_lang_item(db, impl_def);
52            for &(_, assoc) in impl_def.impl_items(db).items.iter() {
53                match assoc {
54                    AssocItemId::FunctionId(f) => lang_items.collect_lang_item(db, f),
55                    AssocItemId::TypeAliasId(t) => lang_items.collect_lang_item(db, t),
56                    AssocItemId::ConstId(c) => lang_items.collect_lang_item(db, c),
57                }
58            }
59        }
60
61        for def in module_data.scope.declarations() {
62            match def {
63                ModuleDefId::TraitId(trait_) => {
64                    lang_items.collect_lang_item(db, trait_);
65                    TraitItems::query(db, trait_).items.iter().for_each(|&(_, assoc_id)| {
66                        match assoc_id {
67                            AssocItemId::FunctionId(f) => {
68                                lang_items.collect_lang_item(db, f);
69                            }
70                            AssocItemId::TypeAliasId(alias) => {
71                                lang_items.collect_lang_item(db, alias)
72                            }
73                            AssocItemId::ConstId(c) => lang_items.collect_lang_item(db, c),
74                        }
75                    });
76                }
77                ModuleDefId::AdtId(AdtId::EnumId(e)) => {
78                    lang_items.collect_lang_item(db, e);
79                    e.enum_variants(db).variants.values().for_each(|&(id, _)| {
80                        lang_items.collect_lang_item(db, id);
81                    });
82                }
83                ModuleDefId::AdtId(AdtId::StructId(s)) => {
84                    lang_items.collect_lang_item(db, s);
85                }
86                ModuleDefId::AdtId(AdtId::UnionId(u)) => {
87                    lang_items.collect_lang_item(db, u);
88                }
89                ModuleDefId::FunctionId(f) => {
90                    lang_items.collect_lang_item(db, f);
91                }
92                ModuleDefId::StaticId(s) => {
93                    lang_items.collect_lang_item(db, s);
94                }
95                ModuleDefId::TypeAliasId(t) => {
96                    lang_items.collect_lang_item(db, t);
97                }
98                ModuleDefId::ConstId(c) => lang_items.collect_lang_item(db, c),
99                _ => {}
100            }
101        }
102    }
103
104    if matches!(krate.data(db).origin, base_db::CrateOrigin::Lang(base_db::LangCrateOrigin::Core)) {
105        lang_items.fill_non_lang_core_items(db, crate_def_map);
106    }
107
108    lang_items.resolve_manually(db);
109
110    if lang_items.is_empty() { None } else { Some(Box::new(lang_items)) }
111}
112
113/// Salsa query. Look for a lang items, starting from the specified crate and recursively
114/// traversing its dependencies.
115#[salsa::tracked(returns(ref))]
116pub fn lang_items(db: &dyn SourceDatabase, start_crate: Crate) -> LangItems {
117    let _p = tracing::info_span!("lang_items_query").entered();
118
119    let mut result = crate_lang_items(db, start_crate).cloned().unwrap_or_default();
120
121    // Our `CrateGraph` eagerly inserts sysroot dependencies like `core` or `std` into dependencies
122    // even if the target crate has `#![no_std]`, `#![no_core]` or shadowed sysroot dependencies
123    // like `dependencies.std.path = ".."`. So we use `extern_prelude()` instead of
124    // `CrateData.dependencies` here, which has already come through such sysroot complexities
125    // while nameres.
126    //
127    // See https://github.com/rust-lang/rust-analyzer/pull/20475 for details.
128    for (_, (module, _)) in crate_local_def_map(db, start_crate).local(db).extern_prelude() {
129        // Some crates declares themselves as extern crate like `extern crate self as core`.
130        // Ignore these to prevent cycles.
131        let krate = module.krate(db);
132        if krate != start_crate {
133            result.merge_prefer_self(lang_items(db, krate));
134        }
135    }
136
137    result
138}
139
140impl LangItems {
141    fn collect_lang_item<T>(&mut self, db: &dyn SourceDatabase, item: T)
142    where
143        T: Into<AttrDefId> + Into<LangItemTarget> + Copy,
144    {
145        let _p = tracing::info_span!("collect_lang_item").entered();
146        if let Some(lang_item) = AttrFlags::lang_item(db, item.into()) {
147            self.assign_lang_item(lang_item, item.into());
148        }
149    }
150}
151
152fn resolve_core_trait(
153    db: &dyn SourceDatabase,
154    core_def_map: &DefMap,
155    modules: &[Symbol],
156    name: Symbol,
157) -> Option<TraitId> {
158    let mut current = &core_def_map[core_def_map.root];
159    for module in modules {
160        let Some((ModuleDefId::ModuleId(cur), _)) =
161            current.scope.type_(&Name::new_symbol_root(module.clone()))
162        else {
163            return None;
164        };
165        if cur.krate(db) != core_def_map.krate() || cur.block(db) != core_def_map.block_id() {
166            return None;
167        }
168        current = &core_def_map[cur];
169    }
170    let Some((ModuleDefId::TraitId(trait_), _)) = current.scope.type_(&Name::new_symbol_root(name))
171    else {
172        return None;
173    };
174    Some(trait_)
175}
176
177fn resolve_core_macro(
178    db: &dyn SourceDatabase,
179    core_def_map: &DefMap,
180    modules: &[Symbol],
181    name: Symbol,
182) -> Option<MacroId> {
183    let mut current = &core_def_map[core_def_map.root];
184    for module in modules {
185        let Some((ModuleDefId::ModuleId(cur), _)) =
186            current.scope.type_(&Name::new_symbol_root(module.clone()))
187        else {
188            return None;
189        };
190        if cur.krate(db) != core_def_map.krate() || cur.block(db) != core_def_map.block_id() {
191            return None;
192        }
193        current = &core_def_map[cur];
194    }
195    current.scope.makro(&Name::new_symbol_root(name))
196}
197
198impl LangItems {
199    fn resolve_manually(&mut self, db: &dyn SourceDatabase) {
200        let parent_trait =
201            |lang_item: &mut Option<TraitId>, def: Option<FunctionId>| match def?.loc(db).container
202            {
203                ItemContainerId::TraitId(trait_) => {
204                    *lang_item = Some(trait_);
205                    Some(trait_)
206                }
207                _ => None,
208            };
209        let assoc_types =
210            |trait_: TraitId, assoc_types: &mut [(&mut Option<TypeAliasId>, Symbol)]| {
211                let trait_items = trait_.trait_items(db);
212                for (assoc_type, name) in assoc_types {
213                    **assoc_type =
214                        trait_items.associated_type_by_name(&Name::new_symbol_root(name.clone()));
215                }
216            };
217        let methods = |trait_: TraitId, assoc_types: &mut [(&mut Option<FunctionId>, Symbol)]| {
218            let trait_items = trait_.trait_items(db);
219            for (assoc_type, name) in assoc_types {
220                **assoc_type = trait_items.method_by_name(&Name::new_symbol_root(name.clone()));
221            }
222        };
223        (|| {
224            let into_future = parent_trait(&mut self.IntoFuture, self.IntoFutureIntoFuture)?;
225            assoc_types(into_future, &mut [(&mut self.IntoFutureOutput, sym::Output)]);
226            Some(())
227        })();
228
229        (|| {
230            let into_iterator = parent_trait(&mut self.IntoIterator, self.IntoIterIntoIter)?;
231            assoc_types(
232                into_iterator,
233                &mut [
234                    (&mut self.IntoIteratorItem, sym::Item),
235                    (&mut self.IntoIterIntoIterType, sym::IntoIter),
236                ],
237            );
238            Some(())
239        })();
240
241        (|| {
242            assoc_types(self.Iterator?, &mut [(&mut self.IteratorItem, sym::Item)]);
243            Some(())
244        })();
245
246        (|| {
247            assoc_types(self.AsyncIterator?, &mut [(&mut self.AsyncIteratorItem, sym::Item)]);
248            Some(())
249        })();
250
251        for (op_trait, op_method, op_method_name) in [
252            (self.Fn, &mut self.Fn_call, sym::call),
253            (self.FnMut, &mut self.FnMut_call_mut, sym::call_mut),
254            (self.FnOnce, &mut self.FnOnce_call_once, sym::call_once),
255            (self.AsyncFn, &mut self.AsyncFn_async_call, sym::async_call),
256            (self.AsyncFnMut, &mut self.AsyncFnMut_async_call_mut, sym::async_call_mut),
257            (self.AsyncFnOnce, &mut self.AsyncFnOnce_async_call_once, sym::async_call_once),
258            (self.Not, &mut self.Not_not, sym::not),
259            (self.Neg, &mut self.Neg_neg, sym::neg),
260            (self.Add, &mut self.Add_add, sym::add),
261            (self.Mul, &mut self.Mul_mul, sym::mul),
262            (self.Sub, &mut self.Sub_sub, sym::sub),
263            (self.Div, &mut self.Div_div, sym::div),
264            (self.Rem, &mut self.Rem_rem, sym::rem),
265            (self.Shl, &mut self.Shl_shl, sym::shl),
266            (self.Shr, &mut self.Shr_shr, sym::shr),
267            (self.BitXor, &mut self.BitXor_bitxor, sym::bitxor),
268            (self.BitOr, &mut self.BitOr_bitor, sym::bitor),
269            (self.BitAnd, &mut self.BitAnd_bitand, sym::bitand),
270            (self.AddAssign, &mut self.AddAssign_add_assign, sym::add_assign),
271            (self.MulAssign, &mut self.MulAssign_mul_assign, sym::mul_assign),
272            (self.SubAssign, &mut self.SubAssign_sub_assign, sym::sub_assign),
273            (self.DivAssign, &mut self.DivAssign_div_assign, sym::div_assign),
274            (self.RemAssign, &mut self.RemAssign_rem_assign, sym::rem_assign),
275            (self.ShlAssign, &mut self.ShlAssign_shl_assign, sym::shl_assign),
276            (self.ShrAssign, &mut self.ShrAssign_shr_assign, sym::shr_assign),
277            (self.BitXorAssign, &mut self.BitXorAssign_bitxor_assign, sym::bitxor_assign),
278            (self.BitOrAssign, &mut self.BitOrAssign_bitor_assign, sym::bitor_assign),
279            (self.BitAndAssign, &mut self.BitAndAssign_bitand_assign, sym::bitand_assign),
280            (self.Debug, &mut self.Debug_fmt, sym::fmt),
281            (self.Deref, &mut self.Deref_deref, sym::deref),
282            (self.DerefMut, &mut self.DerefMut_deref_mut, sym::deref_mut),
283            (self.Index, &mut self.Index_index, sym::index),
284            (self.IndexMut, &mut self.IndexMut_index_mut, sym::index_mut),
285        ] {
286            (|| {
287                methods(op_trait?, &mut [(op_method, op_method_name)]);
288                Some(())
289            })();
290        }
291        (|| {
292            methods(
293                self.PartialEq?,
294                &mut [(&mut self.PartialEq_eq, sym::eq), (&mut self.PartialEq_ne, sym::ne)],
295            );
296            Some(())
297        })();
298        (|| {
299            methods(
300                self.PartialOrd?,
301                &mut [
302                    (&mut self.PartialOrd_le, sym::le),
303                    (&mut self.PartialOrd_lt, sym::lt),
304                    (&mut self.PartialOrd_ge, sym::ge),
305                    (&mut self.PartialOrd_gt, sym::gt),
306                ],
307            );
308            Some(())
309        })();
310        (|| {
311            methods(
312                self.Drop?,
313                &mut [(&mut self.Drop_drop, sym::drop), (&mut self.Drop_pin_drop, sym::pin_drop)],
314            );
315            Some(())
316        })();
317    }
318}
319
320#[salsa::tracked(returns(as_deref))]
321pub fn crate_notable_traits(db: &dyn SourceDatabase, krate: Crate) -> Option<Box<[TraitId]>> {
322    let mut traits = Vec::new();
323
324    let crate_def_map = crate_def_map(db, krate);
325
326    for (_, module_data) in crate_def_map.modules() {
327        for def in module_data.scope.declarations() {
328            if let ModuleDefId::TraitId(trait_) = def
329                && AttrFlags::query(db, trait_.into()).contains(AttrFlags::IS_DOC_NOTABLE_TRAIT)
330            {
331                traits.push(trait_);
332            }
333        }
334    }
335
336    if traits.is_empty() { None } else { Some(traits.into_iter().collect()) }
337}
338
339macro_rules! language_item_table {
340    (
341        $LangItems:ident =>
342        $( $(#[$attr:meta])* $lang_item:ident, $module:ident :: $name:ident, $target:ident; )*
343
344        @non_lang_core_traits:
345
346        $( core::$($non_lang_trait_module:ident)::*, $non_lang_trait:ident; )*
347
348        @non_lang_core_macros:
349
350        $( core::$($non_lang_macro_module:ident)::*, $non_lang_macro:ident, $non_lang_macro_field:ident; )*
351
352        @resolve_manually:
353
354        $( $resolve_manually:ident, $resolve_manually_type:ident; )*
355    ) => {
356        #[allow(non_snake_case)] // FIXME: Should we remove this?
357        #[derive(Debug, Default, Clone, PartialEq, Eq, Hash)]
358        pub struct $LangItems {
359            $(
360                $(#[$attr])*
361                pub $lang_item: Option<$target>,
362            )*
363            $(
364                pub $non_lang_trait: Option<TraitId>,
365            )*
366            $(
367                pub $non_lang_macro_field: Option<MacroId>,
368            )*
369            $(
370                pub $resolve_manually: Option<$resolve_manually_type>,
371            )*
372        }
373
374        impl LangItems {
375            fn is_empty(&self) -> bool {
376                $( self.$lang_item.is_none() )&&*
377            }
378
379            /// Merges `self` with `other`, with preference to `self` items.
380            fn merge_prefer_self(&mut self, other: &Self) {
381                $( self.$lang_item = self.$lang_item.or(other.$lang_item); )*
382                $( self.$non_lang_trait = self.$non_lang_trait.or(other.$non_lang_trait); )*
383                $( self.$non_lang_macro_field = self.$non_lang_macro_field.or(other.$non_lang_macro_field); )*
384                $( self.$resolve_manually = self.$resolve_manually.or(other.$resolve_manually); )*
385            }
386
387            fn assign_lang_item(&mut self, name: Symbol, target: LangItemTarget) {
388                match name {
389                    $(
390                        _ if name == $module::$name => {
391                            if let LangItemTarget::$target(target) = target {
392                                self.$lang_item = Some(target);
393                            }
394                        }
395                    )*
396                    _ => {}
397                }
398            }
399
400            fn fill_non_lang_core_items(&mut self, db: &dyn SourceDatabase, core_def_map: &DefMap) {
401                $( self.$non_lang_trait = resolve_core_trait(db, core_def_map, &[ $(sym::$non_lang_trait_module),* ], sym::$non_lang_trait); )*
402                $( self.$non_lang_macro_field = resolve_core_macro(db, core_def_map, &[ $(sym::$non_lang_macro_module),* ], sym::$non_lang_macro); )*
403            }
404        }
405
406        #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
407        #[allow(non_camel_case_types)]
408        pub enum LangItemEnum {
409            $(
410                $(#[$attr])*
411                $lang_item,
412            )*
413            $( $non_lang_trait, )*
414            $( $non_lang_macro_field, )*
415            $( $resolve_manually, )*
416        }
417
418        impl LangItemEnum {
419            #[inline]
420            pub fn from_lang_items(self, lang_items: &LangItems) -> Option<LangItemTarget> {
421                match self {
422                    $( LangItemEnum::$lang_item => lang_items.$lang_item.map(Into::into), )*
423                    $( LangItemEnum::$non_lang_trait => lang_items.$non_lang_trait.map(Into::into), )*
424                    $( LangItemEnum::$non_lang_macro_field => lang_items.$non_lang_macro_field.map(Into::into), )*
425                    $( LangItemEnum::$resolve_manually => lang_items.$resolve_manually.map(Into::into), )*
426                }
427            }
428
429            #[inline]
430            pub fn from_symbol(symbol: &Symbol) -> Option<Self> {
431                match symbol {
432                    $( _ if *symbol == $module::$name => Some(Self::$lang_item), )*
433                    _ => None,
434                }
435            }
436        }
437    }
438}
439
440language_item_table! { LangItems =>
441//  Variant name,            Name,                     Target;
442    Sized,                   sym::sized,               TraitId;
443    MetaSized,               sym::meta_sized,          TraitId;
444    PointeeSized,            sym::pointee_sized,       TraitId;
445    Unsize,                  sym::unsize,              TraitId;
446    /// Trait injected by `#[derive(PartialEq)]`, (i.e. "Partial EQ").
447    StructuralPeq,           sym::structural_peq,      TraitId;
448    /// Trait injected by `#[derive(Eq)]`, (i.e. "Total EQ"; no, I will not apologize).
449    StructuralTeq,           sym::structural_teq,      TraitId;
450    Copy,                    sym::copy,                TraitId;
451    UseCloned,               sym::use_cloned,          TraitId;
452    Clone,                   sym::clone,               TraitId;
453    TrivialClone,            sym::trivial_clone,       TraitId;
454    Sync,                    sym::sync,                TraitId;
455    DiscriminantKind,        sym::discriminant_kind,   TraitId;
456    /// The associated item of the `DiscriminantKind` trait.
457    Discriminant,            sym::discriminant_type,   TypeAliasId;
458
459    PointeeTrait,            sym::pointee_trait,       TraitId;
460    Metadata,                sym::metadata_type,       TypeAliasId;
461    DynMetadata,             sym::dyn_metadata,        StructId;
462
463    Freeze,                  sym::freeze,              TraitId;
464
465    NonNull,                 sym::non_null,            StructId;
466
467    FnPtrTrait,              sym::fn_ptr_trait,        TraitId;
468    FnPtrAsPtr,              sym::fn_ptr_as_ptr,       FunctionId;
469    FnPtrFromPtr,            sym::fn_ptr_from_ptr,     FunctionId;
470
471    Drop,                    sym::drop,                TraitId;
472    Destruct,                sym::destruct,            TraitId;
473    BikeshedGuaranteedNoDrop,sym::bikeshed_guaranteed_no_drop, TraitId;
474
475    CoerceUnsized,           sym::coerce_unsized,      TraitId;
476    DispatchFromDyn,         sym::dispatch_from_dyn,   TraitId;
477    Reborrow,                sym::reborrow,            TraitId;
478    CoerceShared,            sym::coerce_shared,       TraitId;
479
480    // language items relating to transmutability
481    TransmuteOpts,           sym::transmute_opts,      StructId;
482    TransmuteTrait,          sym::transmute_trait,     TraitId;
483
484    Add,                     sym::add,                 TraitId;
485    Sub,                     sym::sub,                 TraitId;
486    Mul,                     sym::mul,                 TraitId;
487    Div,                     sym::div,                 TraitId;
488    Rem,                     sym::rem,                 TraitId;
489    Neg,                     sym::neg,                 TraitId;
490    Not,                     sym::not,                 TraitId;
491    BitXor,                  sym::bitxor,              TraitId;
492    BitAnd,                  sym::bitand,              TraitId;
493    BitOr,                   sym::bitor,               TraitId;
494    Shl,                     sym::shl,                 TraitId;
495    Shr,                     sym::shr,                 TraitId;
496    AddAssign,               sym::add_assign,          TraitId;
497    SubAssign,               sym::sub_assign,          TraitId;
498    MulAssign,               sym::mul_assign,          TraitId;
499    DivAssign,               sym::div_assign,          TraitId;
500    RemAssign,               sym::rem_assign,          TraitId;
501    BitXorAssign,            sym::bitxor_assign,       TraitId;
502    BitAndAssign,            sym::bitand_assign,       TraitId;
503    BitOrAssign,             sym::bitor_assign,        TraitId;
504    ShlAssign,               sym::shl_assign,          TraitId;
505    ShrAssign,               sym::shr_assign,          TraitId;
506    Index,                   sym::index,               TraitId;
507    IndexMut,                sym::index_mut,           TraitId;
508
509    UnsafeCell,              sym::unsafe_cell,         StructId;
510    UnsafePinned,            sym::unsafe_pinned,       StructId;
511    VaList,                  sym::va_list,             StructId;
512
513    Deref,                   sym::deref,               TraitId;
514    DerefMut,                sym::deref_mut,           TraitId;
515    DerefPure,               sym::deref_pure,          TraitId;
516    DerefTarget,             sym::deref_target,        TypeAliasId;
517    Receiver,                sym::receiver,            TraitId;
518    ReceiverTarget,          sym::receiver_target,     TypeAliasId;
519
520    Fn,                      sym::fn_,                 TraitId;
521    FnMut,                   sym::fn_mut,              TraitId;
522    FnOnce,                  sym::fn_once,             TraitId;
523    AsyncFn,                 sym::async_fn,            TraitId;
524    AsyncFnMut,              sym::async_fn_mut,        TraitId;
525    AsyncFnOnce,             sym::async_fn_once,       TraitId;
526    AsyncFnKindHelper,       sym::async_fn_kind_helper,TraitId;
527    AsyncFnKindUpvars,       sym::async_fn_kind_upvars,TypeAliasId;
528
529    CallRefFuture,           sym::call_ref_future,     TypeAliasId;
530    CallOnceFuture,          sym::call_once_future,    TypeAliasId;
531    AsyncFnOnceOutput,       sym::async_fn_once_output, TypeAliasId;
532
533    FnOnceOutput,            sym::fn_once_output,      TypeAliasId;
534
535    Future,                  sym::future_trait,        TraitId;
536    AsyncIterator,           sym::async_iterator,      TraitId;
537    CoroutineState,          sym::coroutine_state,     EnumId;
538    Coroutine,               sym::coroutine,           TraitId;
539    CoroutineReturn,         sym::coroutine_return,    TypeAliasId;
540    CoroutineYield,          sym::coroutine_yield,     TypeAliasId;
541    Unpin,                   sym::unpin,               TraitId;
542    Pin,                     sym::pin,                 StructId;
543
544    PartialEq,               sym::eq,                  TraitId;
545    PartialOrd,              sym::partial_ord,         TraitId;
546    CVoid,                   sym::c_void,              EnumId;
547
548    // A number of panic-related lang items. The `panic` item corresponds to divide-by-zero and
549    // various panic cases with `match`. The `panic_bounds_check` item is for indexing arrays.
550    //
551    // The `begin_unwind` lang item has a predefined symbol name and is sort of a "weak lang item"
552    // in the sense that a crate is not required to have it defined to use it, but a final product
553    // is required to define it somewhere. Additionally, there are restrictions on crates that use
554    // a weak lang item, but do not have it defined.
555    Panic,                   sym::panic,               FunctionId;
556    PanicNounwind,           sym::panic_nounwind,      FunctionId;
557    PanicFmt,                sym::panic_fmt,           FunctionId;
558    PanicDisplay,            sym::panic_display,       FunctionId;
559    ConstPanicFmt,           sym::const_panic_fmt,     FunctionId;
560    PanicBoundsCheck,        sym::panic_bounds_check,  FunctionId;
561    PanicMisalignedPointerDereference, sym::panic_misaligned_pointer_dereference, FunctionId;
562    PanicInfo,               sym::panic_info,          StructId;
563    PanicLocation,           sym::panic_location,      StructId;
564    PanicImpl,               sym::panic_impl,          FunctionId;
565    PanicCannotUnwind,       sym::panic_cannot_unwind, FunctionId;
566    PanicNullPointerDereference, sym::panic_null_pointer_dereference, FunctionId;
567    /// libstd panic entry point. Necessary for const eval to be able to catch it
568    BeginPanic,              sym::begin_panic,         FunctionId;
569
570    // Lang items needed for `format_args!()`.
571    FormatAlignment,         sym::format_alignment,    EnumId;
572    FormatArgument,          sym::format_argument,     StructId;
573    FormatArguments,         sym::format_arguments,    StructId;
574    FormatCount,             sym::format_count,        EnumId;
575    FormatPlaceholder,       sym::format_placeholder,  StructId;
576    FormatUnsafeArg,         sym::format_unsafe_arg,   StructId;
577
578    ExchangeMalloc,          sym::exchange_malloc,     FunctionId;
579    BoxFree,                 sym::box_free,            FunctionId;
580    DropInPlace,             sym::drop_in_place,       FunctionId;
581    AllocLayout,             sym::alloc_layout,        StructId;
582
583    Start,                   sym::start,               FunctionId;
584
585    EhPersonality,           sym::eh_personality,      FunctionId;
586    EhCatchTypeinfo,         sym::eh_catch_typeinfo,   StaticId;
587
588    OwnedBox,                sym::owned_box,           StructId;
589
590    PhantomData,             sym::phantom_data,        StructId;
591
592    ManuallyDrop,            sym::manually_drop,       StructId;
593
594    MaybeUninit,             sym::maybe_uninit,        UnionId;
595
596    /// Align offset for stride != 1; must not panic.
597    AlignOffset,             sym::align_offset,        FunctionId;
598
599    Termination,             sym::termination,         TraitId;
600
601    Try,                     sym::Try,                 TraitId;
602
603    Tuple,                   sym::tuple_trait,         TraitId;
604
605    SliceLen,                sym::slice_len_fn,        FunctionId;
606
607    // Language items from AST lowering
608    TryTraitFromResidual,    sym::from_residual,       FunctionId;
609    TryTraitFromOutput,      sym::from_output,         FunctionId;
610    TryTraitBranch,          sym::branch,              FunctionId;
611    TryTraitFromYeet,        sym::from_yeet,           FunctionId;
612    ResidualIntoTryType,     sym::into_try_type,       FunctionId;
613
614    PointerLike,             sym::pointer_like,        TraitId;
615
616    ConstParamTy,            sym::const_param_ty,      TraitId;
617
618    Poll,                    sym::Poll,                EnumId;
619    PollReady,               sym::Ready,               EnumVariantId;
620    PollPending,             sym::Pending,             EnumVariantId;
621
622    // FIXME(swatinem): the following lang items are used for async lowering and
623    // should become obsolete eventually.
624    ResumeTy,                sym::ResumeTy,            StructId;
625    GetContext,              sym::get_context,         FunctionId;
626
627    Context,                 sym::Context,             StructId;
628    FuturePoll,              sym::poll,                FunctionId;
629    FutureOutput,            sym::future_output,       TypeAliasId;
630
631    Option,                  sym::Option,              EnumId;
632    OptionSome,              sym::Some,                EnumVariantId;
633    OptionNone,              sym::None,                EnumVariantId;
634
635    ResultOk,                sym::Ok,                  EnumVariantId;
636    ResultErr,               sym::Err,                 EnumVariantId;
637
638    ControlFlowContinue,     sym::Continue,            EnumVariantId;
639    ControlFlowBreak,        sym::Break,               EnumVariantId;
640
641    IntoFutureIntoFuture,    sym::into_future,         FunctionId;
642    IntoIterIntoIter,        sym::into_iter,           FunctionId;
643    IteratorNext,            sym::next,                FunctionId;
644    Iterator,                sym::iterator,            TraitId;
645    FusedIterator,           sym::fused_iterator,      TraitId;
646
647    PinNewUnchecked,         sym::new_unchecked,       FunctionId;
648
649    RangeFrom,               sym::RangeFrom,           StructId;
650    RangeFull,               sym::RangeFull,           StructId;
651    RangeInclusiveStruct,    sym::RangeInclusive,      StructId;
652    RangeInclusiveNew,       sym::range_inclusive_new, FunctionId;
653    Range,                   sym::Range,               StructId;
654    RangeToInclusive,        sym::RangeToInclusive,    StructId;
655    RangeTo,                 sym::RangeTo,             StructId;
656
657    RangeFromCopy,           sym::RangeFromCopy,           StructId;
658    RangeInclusiveCopy,      sym::RangeInclusiveCopy,      StructId;
659    RangeCopy,               sym::RangeCopy,               StructId;
660    RangeToInclusiveCopy,    sym::RangeToInclusiveCopy,    StructId;
661
662    String,                  sym::String,              StructId;
663    CStr,                    sym::CStr,                StructId;
664    Ordering,                sym::Ordering,            EnumId;
665
666    Field,                   sym::field,               TraitId;
667    FieldBase,               sym::field_base,          TypeAliasId;
668    FieldType,               sym::field_type,          TypeAliasId;
669
670    RangeMin,                sym::RangeMin,            ConstId;
671    RangeMax,                sym::RangeMax,            ConstId;
672    RangeSub,                sym::RangeSub,            FunctionId;
673
674    @non_lang_core_traits:
675    core::default, Default;
676    core::fmt, Debug;
677    core::hash, Hash;
678    core::cmp, Ord;
679    core::cmp, Eq;
680
681    @non_lang_core_macros:
682    core::default, Default, DefaultDerive;
683    core::fmt, Debug, DebugDerive;
684    core::hash, Hash, HashDerive;
685    core::cmp, PartialOrd, PartialOrdDerive;
686    core::cmp, Ord, OrdDerive;
687    core::cmp, PartialEq, PartialEqDerive;
688    core::cmp, Eq, EqDerive;
689    core::marker, CoercePointee, CoercePointeeDerive;
690    core::marker, CoerceShared, CoerceSharedDerive;
691    core::marker, Copy, CopyDerive;
692    core::marker, Reborrow, ReborrowDerive;
693    core::clone, Clone, CloneDerive;
694
695    @resolve_manually:
696
697    IntoFuture,                    TraitId;
698    IntoFutureOutput,              TypeAliasId;
699    IntoIterator,                  TraitId;
700    IntoIteratorItem,              TypeAliasId;
701    IntoIterIntoIterType,          TypeAliasId;
702    IteratorItem,                  TypeAliasId;
703    AsyncIteratorItem,             TypeAliasId;
704
705    Fn_call,                       FunctionId;
706    FnMut_call_mut,                FunctionId;
707    FnOnce_call_once,              FunctionId;
708    AsyncFn_async_call,            FunctionId;
709    AsyncFnMut_async_call_mut,     FunctionId;
710    AsyncFnOnce_async_call_once,   FunctionId;
711    Not_not,                       FunctionId;
712    Neg_neg,                       FunctionId;
713    Add_add,                       FunctionId;
714    Mul_mul,                       FunctionId;
715    Sub_sub,                       FunctionId;
716    Div_div,                       FunctionId;
717    Rem_rem,                       FunctionId;
718    Shl_shl,                       FunctionId;
719    Shr_shr,                       FunctionId;
720    BitXor_bitxor,                 FunctionId;
721    BitOr_bitor,                   FunctionId;
722    BitAnd_bitand,                 FunctionId;
723    AddAssign_add_assign,          FunctionId;
724    MulAssign_mul_assign,          FunctionId;
725    SubAssign_sub_assign,          FunctionId;
726    DivAssign_div_assign,          FunctionId;
727    RemAssign_rem_assign,          FunctionId;
728    ShlAssign_shl_assign,          FunctionId;
729    ShrAssign_shr_assign,          FunctionId;
730    BitXorAssign_bitxor_assign,    FunctionId;
731    BitOrAssign_bitor_assign,      FunctionId;
732    BitAndAssign_bitand_assign,    FunctionId;
733    PartialEq_eq,                  FunctionId;
734    PartialEq_ne,                  FunctionId;
735    PartialOrd_le,                 FunctionId;
736    PartialOrd_lt,                 FunctionId;
737    PartialOrd_ge,                 FunctionId;
738    PartialOrd_gt,                 FunctionId;
739    Drop_drop,                     FunctionId;
740    Drop_pin_drop,                     FunctionId;
741    Debug_fmt,                     FunctionId;
742    Deref_deref,                   FunctionId;
743    DerefMut_deref_mut,            FunctionId;
744    Index_index,                   FunctionId;
745    IndexMut_index_mut,            FunctionId;
746}