1 //! Defines language items.
3 //! Language items are items that represent concepts intrinsic to the language
4 //! itself. Examples are:
6 //! * Traits that specify "kinds"; e.g., `Sync`, `Send`.
7 //! * Traits that represent operators; e.g., `Add`, `Sub`, `Index`.
8 //! * Functions called by the compiler itself.
10 use crate::def_id
::DefId
;
11 use crate::{MethodKind, Target}
;
14 use rustc_data_structures
::fx
::FxHashMap
;
15 use rustc_data_structures
::stable_hasher
::{HashStable, StableHasher}
;
16 use rustc_macros
::HashStable_Generic
;
17 use rustc_span
::symbol
::{kw, sym, Symbol}
;
20 use std
::sync
::LazyLock
;
22 pub enum LangItemGroup
{
27 const NUM_GROUPS
: usize = 2;
29 macro_rules
! expand_group
{
38 // The actual lang items defined come at the end of this file in one handy table.
39 // So you probably just want to nip down to the end.
40 macro_rules
! language_item_table
{
42 $
( $
(#[$attr:meta])* $variant:ident $($group:expr)?, $module:ident :: $name:ident, $method:ident, $target:expr, $generics:expr; )*
46 /// A representation of all the valid language items in Rust.
47 #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, Encodable, Decodable)]
50 #[doc = concat!("The `", stringify!($name), "` lang item.")]
59 /// Returns the `name` symbol in `#[lang = "$name"]`.
60 /// For example, [`LangItem::PartialEq`]`.name()`
61 /// would result in [`sym::eq`] since it is `#[lang = "eq"]`.
62 pub fn name(self) -> Symbol
{
64 $
( LangItem
::$variant
=> $module
::$name
, )*
68 /// The [group](LangItemGroup) that this lang item belongs to,
69 /// or `None` if it doesn't belong to a group.
70 pub fn group(self) -> Option
<LangItemGroup
> {
73 $
( LangItem
::$variant
=> expand_group
!($
($group
)*), )*
77 pub fn required_generics(&self) -> GenericRequirement
{
79 $
( LangItem
::$variant
=> $generics
, )*
84 /// All of the language items, defined or not.
85 /// Defined lang items can come from the current crate or its dependencies.
86 #[derive(HashStable_Generic, Debug)]
87 pub struct LanguageItems
{
88 /// Mappings from lang items to their possibly found [`DefId`]s.
89 /// The index corresponds to the order in [`LangItem`].
90 pub items
: Vec
<Option
<DefId
>>,
91 /// Lang items that were not found during collection.
92 pub missing
: Vec
<LangItem
>,
93 /// Mapping from [`LangItemGroup`] discriminants to all
94 /// [`DefId`]s of lang items in that group.
95 pub groups
: [Vec
<DefId
>; NUM_GROUPS
],
99 /// Construct an empty collection of lang items and no missing ones.
100 pub fn new() -> Self {
101 fn init_none(_
: LangItem
) -> Option
<DefId
> { None }
102 const EMPTY
: Vec
<DefId
> = Vec
::new();
105 items
: vec
![$
(init_none(LangItem
::$variant
)),*],
107 groups
: [EMPTY
; NUM_GROUPS
],
111 /// Returns the mappings to the possibly found `DefId`s for each lang item.
112 pub fn items(&self) -> &[Option
<DefId
>] {
116 /// Requires that a given `LangItem` was bound and returns the corresponding `DefId`.
117 /// If it wasn't bound, e.g. due to a missing `#[lang = "<it.name()>"]`,
118 /// returns an error message as a string.
119 pub fn require(&self, it
: LangItem
) -> Result
<DefId
, String
> {
120 self.items
[it
as usize].ok_or_else(|| format
!("requires `{}` lang_item", it
.name()))
123 /// Returns the [`DefId`]s of all lang items in a group.
124 pub fn group(&self, group
: LangItemGroup
) -> &[DefId
] {
125 self.groups
[group
as usize].as_ref()
129 #[doc = concat!("Returns the [`DefId`] of the `", stringify!($name), "` lang item if it is defined.")]
130 pub fn $
method(&self) -> Option
<DefId
> {
131 self.items
[LangItem
::$variant
as usize]
136 /// A mapping from the name of the lang item to its order and the form it must be of.
137 pub static ITEM_REFS
: LazyLock
<FxHashMap
<Symbol
, (usize, Target
)>> = LazyLock
::new(|| {
138 let mut item_refs
= FxHashMap
::default();
139 $
( item_refs
.insert($module
::$name
, (LangItem
::$variant
as usize, $target
)); )*
147 impl<CTX
> HashStable
<CTX
> for LangItem
{
148 fn hash_stable(&self, _
: &mut CTX
, hasher
: &mut StableHasher
) {
149 ::std
::hash
::Hash
::hash(self, hasher
);
153 /// Extracts the first `lang = "$name"` out of a list of attributes.
154 /// The attributes `#[panic_handler]` and `#[alloc_error_handler]`
155 /// are also extracted out when found.
156 pub fn extract(attrs
: &[ast
::Attribute
]) -> Option
<(Symbol
, Span
)> {
157 attrs
.iter().find_map(|attr
| {
159 _
if attr
.has_name(sym
::lang
) => (attr
.value_str()?
, attr
.span
),
160 _
if attr
.has_name(sym
::panic_handler
) => (sym
::panic_impl
, attr
.span
),
161 _
if attr
.has_name(sym
::alloc_error_handler
) => (sym
::oom
, attr
.span
),
167 language_item_table
! {
168 // Variant name, Name, Method name, Target Generic requirements;
169 Sized
, sym
::sized
, sized_trait
, Target
::Trait
, GenericRequirement
::Exact(0);
170 Unsize
, sym
::unsize
, unsize_trait
, Target
::Trait
, GenericRequirement
::Minimum(1);
171 /// Trait injected by `#[derive(PartialEq)]`, (i.e. "Partial EQ").
172 StructuralPeq
, sym
::structural_peq
, structural_peq_trait
, Target
::Trait
, GenericRequirement
::None
;
173 /// Trait injected by `#[derive(Eq)]`, (i.e. "Total EQ"; no, I will not apologize).
174 StructuralTeq
, sym
::structural_teq
, structural_teq_trait
, Target
::Trait
, GenericRequirement
::None
;
175 Copy
, sym
::copy
, copy_trait
, Target
::Trait
, GenericRequirement
::Exact(0);
176 Clone
, sym
::clone
, clone_trait
, Target
::Trait
, GenericRequirement
::None
;
177 Sync
, sym
::sync
, sync_trait
, Target
::Trait
, GenericRequirement
::Exact(0);
178 DiscriminantKind
, sym
::discriminant_kind
, discriminant_kind_trait
, Target
::Trait
, GenericRequirement
::None
;
179 /// The associated item of the [`DiscriminantKind`] trait.
180 Discriminant
, sym
::discriminant_type
, discriminant_type
, Target
::AssocTy
, GenericRequirement
::None
;
182 PointeeTrait
, sym
::pointee_trait
, pointee_trait
, Target
::Trait
, GenericRequirement
::None
;
183 Metadata
, sym
::metadata_type
, metadata_type
, Target
::AssocTy
, GenericRequirement
::None
;
184 DynMetadata
, sym
::dyn_metadata
, dyn_metadata
, Target
::Struct
, GenericRequirement
::None
;
186 Freeze
, sym
::freeze
, freeze_trait
, Target
::Trait
, GenericRequirement
::Exact(0);
188 Drop
, sym
::drop
, drop_trait
, Target
::Trait
, GenericRequirement
::None
;
189 Destruct
, sym
::destruct
, destruct_trait
, Target
::Trait
, GenericRequirement
::None
;
191 CoerceUnsized
, sym
::coerce_unsized
, coerce_unsized_trait
, Target
::Trait
, GenericRequirement
::Minimum(1);
192 DispatchFromDyn
, sym
::dispatch_from_dyn
, dispatch_from_dyn_trait
, Target
::Trait
, GenericRequirement
::Minimum(1);
194 Add(Op
), sym
::add
, add_trait
, Target
::Trait
, GenericRequirement
::Exact(1);
195 Sub(Op
), sym
::sub
, sub_trait
, Target
::Trait
, GenericRequirement
::Exact(1);
196 Mul(Op
), sym
::mul
, mul_trait
, Target
::Trait
, GenericRequirement
::Exact(1);
197 Div(Op
), sym
::div
, div_trait
, Target
::Trait
, GenericRequirement
::Exact(1);
198 Rem(Op
), sym
::rem
, rem_trait
, Target
::Trait
, GenericRequirement
::Exact(1);
199 Neg(Op
), sym
::neg
, neg_trait
, Target
::Trait
, GenericRequirement
::Exact(0);
200 Not(Op
), sym
::not
, not_trait
, Target
::Trait
, GenericRequirement
::Exact(0);
201 BitXor(Op
), sym
::bitxor
, bitxor_trait
, Target
::Trait
, GenericRequirement
::Exact(1);
202 BitAnd(Op
), sym
::bitand
, bitand_trait
, Target
::Trait
, GenericRequirement
::Exact(1);
203 BitOr(Op
), sym
::bitor
, bitor_trait
, Target
::Trait
, GenericRequirement
::Exact(1);
204 Shl(Op
), sym
::shl
, shl_trait
, Target
::Trait
, GenericRequirement
::Exact(1);
205 Shr(Op
), sym
::shr
, shr_trait
, Target
::Trait
, GenericRequirement
::Exact(1);
206 AddAssign(Op
), sym
::add_assign
, add_assign_trait
, Target
::Trait
, GenericRequirement
::Exact(1);
207 SubAssign(Op
), sym
::sub_assign
, sub_assign_trait
, Target
::Trait
, GenericRequirement
::Exact(1);
208 MulAssign(Op
), sym
::mul_assign
, mul_assign_trait
, Target
::Trait
, GenericRequirement
::Exact(1);
209 DivAssign(Op
), sym
::div_assign
, div_assign_trait
, Target
::Trait
, GenericRequirement
::Exact(1);
210 RemAssign(Op
), sym
::rem_assign
, rem_assign_trait
, Target
::Trait
, GenericRequirement
::Exact(1);
211 BitXorAssign(Op
), sym
::bitxor_assign
, bitxor_assign_trait
, Target
::Trait
, GenericRequirement
::Exact(1);
212 BitAndAssign(Op
), sym
::bitand_assign
, bitand_assign_trait
, Target
::Trait
, GenericRequirement
::Exact(1);
213 BitOrAssign(Op
), sym
::bitor_assign
, bitor_assign_trait
, Target
::Trait
, GenericRequirement
::Exact(1);
214 ShlAssign(Op
), sym
::shl_assign
, shl_assign_trait
, Target
::Trait
, GenericRequirement
::Exact(1);
215 ShrAssign(Op
), sym
::shr_assign
, shr_assign_trait
, Target
::Trait
, GenericRequirement
::Exact(1);
216 Index(Op
), sym
::index
, index_trait
, Target
::Trait
, GenericRequirement
::Exact(1);
217 IndexMut(Op
), sym
::index_mut
, index_mut_trait
, Target
::Trait
, GenericRequirement
::Exact(1);
219 UnsafeCell
, sym
::unsafe_cell
, unsafe_cell_type
, Target
::Struct
, GenericRequirement
::None
;
220 VaList
, sym
::va_list
, va_list
, Target
::Struct
, GenericRequirement
::None
;
222 Deref
, sym
::deref
, deref_trait
, Target
::Trait
, GenericRequirement
::Exact(0);
223 DerefMut
, sym
::deref_mut
, deref_mut_trait
, Target
::Trait
, GenericRequirement
::Exact(0);
224 DerefTarget
, sym
::deref_target
, deref_target
, Target
::AssocTy
, GenericRequirement
::None
;
225 Receiver
, sym
::receiver
, receiver_trait
, Target
::Trait
, GenericRequirement
::None
;
227 Fn(Fn
), kw
::Fn
, fn_trait
, Target
::Trait
, GenericRequirement
::Exact(1);
228 FnMut(Fn
), sym
::fn_mut
, fn_mut_trait
, Target
::Trait
, GenericRequirement
::Exact(1);
229 FnOnce(Fn
), sym
::fn_once
, fn_once_trait
, Target
::Trait
, GenericRequirement
::Exact(1);
231 FnOnceOutput
, sym
::fn_once_output
, fn_once_output
, Target
::AssocTy
, GenericRequirement
::None
;
233 Future
, sym
::future_trait
, future_trait
, Target
::Trait
, GenericRequirement
::Exact(0);
234 GeneratorState
, sym
::generator_state
, gen_state
, Target
::Enum
, GenericRequirement
::None
;
235 Generator
, sym
::generator
, gen_trait
, Target
::Trait
, GenericRequirement
::Minimum(1);
236 GeneratorReturn
, sym
::generator_return
, generator_return
, Target
::AssocTy
, GenericRequirement
::None
;
237 Unpin
, sym
::unpin
, unpin_trait
, Target
::Trait
, GenericRequirement
::None
;
238 Pin
, sym
::pin
, pin_type
, Target
::Struct
, GenericRequirement
::None
;
240 PartialEq(Op
), sym
::eq
, eq_trait
, Target
::Trait
, GenericRequirement
::Exact(1);
241 PartialOrd(Op
), sym
::partial_ord
, partial_ord_trait
, Target
::Trait
, GenericRequirement
::Exact(1);
243 // A number of panic-related lang items. The `panic` item corresponds to divide-by-zero and
244 // various panic cases with `match`. The `panic_bounds_check` item is for indexing arrays.
246 // The `begin_unwind` lang item has a predefined symbol name and is sort of a "weak lang item"
247 // in the sense that a crate is not required to have it defined to use it, but a final product
248 // is required to define it somewhere. Additionally, there are restrictions on crates that use
249 // a weak lang item, but do not have it defined.
250 Panic
, sym
::panic
, panic_fn
, Target
::Fn
, GenericRequirement
::Exact(0);
251 PanicFmt
, sym
::panic_fmt
, panic_fmt
, Target
::Fn
, GenericRequirement
::None
;
252 PanicDisplay
, sym
::panic_display
, panic_display
, Target
::Fn
, GenericRequirement
::None
;
253 ConstPanicFmt
, sym
::const_panic_fmt
, const_panic_fmt
, Target
::Fn
, GenericRequirement
::None
;
254 PanicBoundsCheck
, sym
::panic_bounds_check
, panic_bounds_check_fn
, Target
::Fn
, GenericRequirement
::Exact(0);
255 PanicInfo
, sym
::panic_info
, panic_info
, Target
::Struct
, GenericRequirement
::None
;
256 PanicLocation
, sym
::panic_location
, panic_location
, Target
::Struct
, GenericRequirement
::None
;
257 PanicImpl
, sym
::panic_impl
, panic_impl
, Target
::Fn
, GenericRequirement
::None
;
258 PanicNoUnwind
, sym
::panic_no_unwind
, panic_no_unwind
, Target
::Fn
, GenericRequirement
::Exact(0);
259 /// libstd panic entry point. Necessary for const eval to be able to catch it
260 BeginPanic
, sym
::begin_panic
, begin_panic_fn
, Target
::Fn
, GenericRequirement
::None
;
262 ExchangeMalloc
, sym
::exchange_malloc
, exchange_malloc_fn
, Target
::Fn
, GenericRequirement
::None
;
263 BoxFree
, sym
::box_free
, box_free_fn
, Target
::Fn
, GenericRequirement
::Minimum(1);
264 DropInPlace
, sym
::drop_in_place
, drop_in_place_fn
, Target
::Fn
, GenericRequirement
::Minimum(1);
265 Oom
, sym
::oom
, oom
, Target
::Fn
, GenericRequirement
::None
;
266 AllocLayout
, sym
::alloc_layout
, alloc_layout
, Target
::Struct
, GenericRequirement
::None
;
267 ConstEvalSelect
, sym
::const_eval_select
, const_eval_select
, Target
::Fn
, GenericRequirement
::Exact(4);
268 ConstConstEvalSelect
, sym
::const_eval_select_ct
,const_eval_select_ct
, Target
::Fn
, GenericRequirement
::Exact(4);
270 Start
, sym
::start
, start_fn
, Target
::Fn
, GenericRequirement
::Exact(1);
272 EhPersonality
, sym
::eh_personality
, eh_personality
, Target
::Fn
, GenericRequirement
::None
;
273 EhCatchTypeinfo
, sym
::eh_catch_typeinfo
, eh_catch_typeinfo
, Target
::Static
, GenericRequirement
::None
;
275 OwnedBox
, sym
::owned_box
, owned_box
, Target
::Struct
, GenericRequirement
::Minimum(1);
277 PhantomData
, sym
::phantom_data
, phantom_data
, Target
::Struct
, GenericRequirement
::Exact(1);
279 ManuallyDrop
, sym
::manually_drop
, manually_drop
, Target
::Struct
, GenericRequirement
::None
;
281 MaybeUninit
, sym
::maybe_uninit
, maybe_uninit
, Target
::Union
, GenericRequirement
::None
;
283 /// Align offset for stride != 1; must not panic.
284 AlignOffset
, sym
::align_offset
, align_offset_fn
, Target
::Fn
, GenericRequirement
::None
;
286 Termination
, sym
::termination
, termination
, Target
::Trait
, GenericRequirement
::None
;
288 Try
, sym
::Try
, try_trait
, Target
::Trait
, GenericRequirement
::None
;
290 SliceLen
, sym
::slice_len_fn
, slice_len_fn
, Target
::Method(MethodKind
::Inherent
), GenericRequirement
::None
;
292 // Language items from AST lowering
293 TryTraitFromResidual
, sym
::from_residual
, from_residual_fn
, Target
::Method(MethodKind
::Trait { body: false }
), GenericRequirement
::None
;
294 TryTraitFromOutput
, sym
::from_output
, from_output_fn
, Target
::Method(MethodKind
::Trait { body: false }
), GenericRequirement
::None
;
295 TryTraitBranch
, sym
::branch
, branch_fn
, Target
::Method(MethodKind
::Trait { body: false }
), GenericRequirement
::None
;
296 TryTraitFromYeet
, sym
::from_yeet
, from_yeet_fn
, Target
::Fn
, GenericRequirement
::None
;
298 PollReady
, sym
::Ready
, poll_ready_variant
, Target
::Variant
, GenericRequirement
::None
;
299 PollPending
, sym
::Pending
, poll_pending_variant
, Target
::Variant
, GenericRequirement
::None
;
301 FromGenerator
, sym
::from_generator
, from_generator_fn
, Target
::Fn
, GenericRequirement
::None
;
302 GetContext
, sym
::get_context
, get_context_fn
, Target
::Fn
, GenericRequirement
::None
;
304 FuturePoll
, sym
::poll
, future_poll_fn
, Target
::Method(MethodKind
::Trait { body: false }
), GenericRequirement
::None
;
306 FromFrom
, sym
::from
, from_fn
, Target
::Method(MethodKind
::Trait { body: false }
), GenericRequirement
::None
;
308 OptionSome
, sym
::Some
, option_some_variant
, Target
::Variant
, GenericRequirement
::None
;
309 OptionNone
, sym
::None
, option_none_variant
, Target
::Variant
, GenericRequirement
::None
;
311 ResultOk
, sym
::Ok
, result_ok_variant
, Target
::Variant
, GenericRequirement
::None
;
312 ResultErr
, sym
::Err
, result_err_variant
, Target
::Variant
, GenericRequirement
::None
;
314 ControlFlowContinue
, sym
::Continue
, cf_continue_variant
, Target
::Variant
, GenericRequirement
::None
;
315 ControlFlowBreak
, sym
::Break
, cf_break_variant
, Target
::Variant
, GenericRequirement
::None
;
317 IntoFutureIntoFuture
, sym
::into_future
, into_future_fn
, Target
::Method(MethodKind
::Trait { body: false }
), GenericRequirement
::None
;
318 IntoIterIntoIter
, sym
::into_iter
, into_iter_fn
, Target
::Method(MethodKind
::Trait { body: false }
), GenericRequirement
::None
;
319 IteratorNext
, sym
::next
, next_fn
, Target
::Method(MethodKind
::Trait { body: false}
), GenericRequirement
::None
;
321 PinNewUnchecked
, sym
::new_unchecked
, new_unchecked_fn
, Target
::Method(MethodKind
::Inherent
), GenericRequirement
::None
;
323 RangeFrom
, sym
::RangeFrom
, range_from_struct
, Target
::Struct
, GenericRequirement
::None
;
324 RangeFull
, sym
::RangeFull
, range_full_struct
, Target
::Struct
, GenericRequirement
::None
;
325 RangeInclusiveStruct
, sym
::RangeInclusive
, range_inclusive_struct
, Target
::Struct
, GenericRequirement
::None
;
326 RangeInclusiveNew
, sym
::range_inclusive_new
, range_inclusive_new_method
, Target
::Method(MethodKind
::Inherent
), GenericRequirement
::None
;
327 Range
, sym
::Range
, range_struct
, Target
::Struct
, GenericRequirement
::None
;
328 RangeToInclusive
, sym
::RangeToInclusive
, range_to_inclusive_struct
, Target
::Struct
, GenericRequirement
::None
;
329 RangeTo
, sym
::RangeTo
, range_to_struct
, Target
::Struct
, GenericRequirement
::None
;
332 pub enum GenericRequirement
{