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
::lazy
::SyncLazy
;
22 pub enum LangItemGroup
{
26 const NUM_GROUPS
: usize = 1;
28 macro_rules
! expand_group
{
37 // The actual lang items defined come at the end of this file in one handy table.
38 // So you probably just want to nip down to the end.
39 macro_rules
! language_item_table
{
41 $
( $variant
:ident $
($group
:expr
)?
, $name
:expr
, $method
:ident
, $target
:expr
; )*
45 /// A representation of all the valid language items in Rust.
46 #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, Encodable, Decodable)]
53 /// Returns the `name` symbol in `#[lang = "$name"]`.
54 /// For example, `LangItem::EqTraitLangItem`,
55 /// that is `#[lang = "eq"]` would result in `sym::eq`.
56 pub fn name(self) -> Symbol
{
58 $
( LangItem
::$variant
=> $name
, )*
62 pub fn group(self) -> Option
<LangItemGroup
> {
65 $
( LangItem
::$variant
=> expand_group
!($
($group
)*), )*
70 #[derive(HashStable_Generic)]
71 pub struct LanguageItems
{
72 /// Mappings from lang items to their possibly found `DefId`s.
73 /// The index corresponds to the order in `LangItem`.
74 pub items
: Vec
<Option
<DefId
>>,
75 /// Lang items that were not found during collection.
76 pub missing
: Vec
<LangItem
>,
77 /// Mapping from `LangItemGroup` discriminants to all
78 /// `DefId`s of lang items in that group.
79 pub groups
: [Vec
<DefId
>; NUM_GROUPS
],
83 /// Construct an empty collection of lang items and no missing ones.
84 pub fn new() -> Self {
85 fn init_none(_
: LangItem
) -> Option
<DefId
> { None }
88 items
: vec
![$
(init_none(LangItem
::$variant
)),*],
90 groups
: [vec
![]; NUM_GROUPS
],
94 /// Returns the mappings to the possibly found `DefId`s for each lang item.
95 pub fn items(&self) -> &[Option
<DefId
>] {
99 /// Requires that a given `LangItem` was bound and returns the corresponding `DefId`.
100 /// If it wasn't bound, e.g. due to a missing `#[lang = "<it.name()>"]`,
101 /// returns an error message as a string.
102 pub fn require(&self, it
: LangItem
) -> Result
<DefId
, String
> {
103 self.items
[it
as usize].ok_or_else(|| format
!("requires `{}` lang_item", it
.name()))
106 pub fn group(&self, group
: LangItemGroup
) -> &[DefId
] {
107 self.groups
[group
as usize].as_ref()
111 /// Returns the corresponding `DefId` for the lang item if it
114 pub fn $
method(&self) -> Option
<DefId
> {
115 self.items
[LangItem
::$variant
as usize]
120 /// A mapping from the name of the lang item to its order and the form it must be of.
121 pub static ITEM_REFS
: SyncLazy
<FxHashMap
<Symbol
, (usize, Target
)>> = SyncLazy
::new(|| {
122 let mut item_refs
= FxHashMap
::default();
123 $
( item_refs
.insert($name
, (LangItem
::$variant
as usize, $target
)); )*
131 impl<CTX
> HashStable
<CTX
> for LangItem
{
132 fn hash_stable(&self, _
: &mut CTX
, hasher
: &mut StableHasher
) {
133 ::std
::hash
::Hash
::hash(self, hasher
);
137 /// Extracts the first `lang = "$name"` out of a list of attributes.
138 /// The attributes `#[panic_handler]` and `#[alloc_error_handler]`
139 /// are also extracted out when found.
141 /// About the `check_name` argument: passing in a `Session` would be simpler,
142 /// because then we could call `Session::check_name` directly. But we want to
143 /// avoid the need for `librustc_hir` to depend on `librustc_session`, so we
144 /// use a closure instead.
145 pub fn extract
<'a
, F
>(check_name
: F
, attrs
: &'a
[ast
::Attribute
]) -> Option
<(Symbol
, Span
)>
147 F
: Fn(&'a ast
::Attribute
, Symbol
) -> bool
,
149 attrs
.iter().find_map(|attr
| {
151 _
if check_name(attr
, sym
::lang
) => (attr
.value_str()?
, attr
.span
),
152 _
if check_name(attr
, sym
::panic_handler
) => (sym
::panic_impl
, attr
.span
),
153 _
if check_name(attr
, sym
::alloc_error_handler
) => (sym
::oom
, attr
.span
),
159 language_item_table
! {
160 // Variant name, Name, Method name, Target;
161 Bool
, sym
::bool
, bool_impl
, Target
::Impl
;
162 Char
, sym
::char, char_impl
, Target
::Impl
;
163 Str
, sym
::str, str_impl
, Target
::Impl
;
164 Array
, sym
::array
, array_impl
, Target
::Impl
;
165 Slice
, sym
::slice
, slice_impl
, Target
::Impl
;
166 SliceU8
, sym
::slice_u8
, slice_u8_impl
, Target
::Impl
;
167 StrAlloc
, sym
::str_alloc
, str_alloc_impl
, Target
::Impl
;
168 SliceAlloc
, sym
::slice_alloc
, slice_alloc_impl
, Target
::Impl
;
169 SliceU8Alloc
, sym
::slice_u8_alloc
, slice_u8_alloc_impl
, Target
::Impl
;
170 ConstPtr
, sym
::const_ptr
, const_ptr_impl
, Target
::Impl
;
171 MutPtr
, sym
::mut_ptr
, mut_ptr_impl
, Target
::Impl
;
172 ConstSlicePtr
, sym
::const_slice_ptr
, const_slice_ptr_impl
, Target
::Impl
;
173 MutSlicePtr
, sym
::mut_slice_ptr
, mut_slice_ptr_impl
, Target
::Impl
;
174 I8
, sym
::i8, i8_impl
, Target
::Impl
;
175 I16
, sym
::i16, i16_impl
, Target
::Impl
;
176 I32
, sym
::i32, i32_impl
, Target
::Impl
;
177 I64
, sym
::i64, i64_impl
, Target
::Impl
;
178 I128
, sym
::i128
, i128_impl
, Target
::Impl
;
179 Isize
, sym
::isize, isize_impl
, Target
::Impl
;
180 U8
, sym
::u8, u8_impl
, Target
::Impl
;
181 U16
, sym
::u16, u16_impl
, Target
::Impl
;
182 U32
, sym
::u32, u32_impl
, Target
::Impl
;
183 U64
, sym
::u64, u64_impl
, Target
::Impl
;
184 U128
, sym
::u128
, u128_impl
, Target
::Impl
;
185 Usize
, sym
::usize, usize_impl
, Target
::Impl
;
186 F32
, sym
::f32, f32_impl
, Target
::Impl
;
187 F64
, sym
::f64, f64_impl
, Target
::Impl
;
188 F32Runtime
, sym
::f32_runtime
, f32_runtime_impl
, Target
::Impl
;
189 F64Runtime
, sym
::f64_runtime
, f64_runtime_impl
, Target
::Impl
;
191 Sized
, sym
::sized
, sized_trait
, Target
::Trait
;
192 Unsize
, sym
::unsize
, unsize_trait
, Target
::Trait
;
193 // Trait injected by #[derive(PartialEq)], (i.e. "Partial EQ").
194 StructuralPeq
, sym
::structural_peq
, structural_peq_trait
, Target
::Trait
;
195 // Trait injected by #[derive(Eq)], (i.e. "Total EQ"; no, I will not apologize).
196 StructuralTeq
, sym
::structural_teq
, structural_teq_trait
, Target
::Trait
;
197 Copy
, sym
::copy
, copy_trait
, Target
::Trait
;
198 Clone
, sym
::clone
, clone_trait
, Target
::Trait
;
199 Sync
, sym
::sync
, sync_trait
, Target
::Trait
;
200 DiscriminantKind
, sym
::discriminant_kind
, discriminant_kind_trait
, Target
::Trait
;
201 // The associated item of `trait DiscriminantKind`.
202 Discriminant
, sym
::discriminant_type
, discriminant_type
, Target
::AssocTy
;
204 Freeze
, sym
::freeze
, freeze_trait
, Target
::Trait
;
206 Drop
, sym
::drop
, drop_trait
, Target
::Trait
;
208 CoerceUnsized
, sym
::coerce_unsized
, coerce_unsized_trait
, Target
::Trait
;
209 DispatchFromDyn
, sym
::dispatch_from_dyn
, dispatch_from_dyn_trait
, Target
::Trait
;
211 Add(Op
), sym
::add
, add_trait
, Target
::Trait
;
212 Sub(Op
), sym
::sub
, sub_trait
, Target
::Trait
;
213 Mul(Op
), sym
::mul
, mul_trait
, Target
::Trait
;
214 Div(Op
), sym
::div
, div_trait
, Target
::Trait
;
215 Rem(Op
), sym
::rem
, rem_trait
, Target
::Trait
;
216 Neg(Op
), sym
::neg
, neg_trait
, Target
::Trait
;
217 Not(Op
), sym
::not
, not_trait
, Target
::Trait
;
218 BitXor(Op
), sym
::bitxor
, bitxor_trait
, Target
::Trait
;
219 BitAnd(Op
), sym
::bitand
, bitand_trait
, Target
::Trait
;
220 BitOr(Op
), sym
::bitor
, bitor_trait
, Target
::Trait
;
221 Shl(Op
), sym
::shl
, shl_trait
, Target
::Trait
;
222 Shr(Op
), sym
::shr
, shr_trait
, Target
::Trait
;
223 AddAssign(Op
), sym
::add_assign
, add_assign_trait
, Target
::Trait
;
224 SubAssign(Op
), sym
::sub_assign
, sub_assign_trait
, Target
::Trait
;
225 MulAssign(Op
), sym
::mul_assign
, mul_assign_trait
, Target
::Trait
;
226 DivAssign(Op
), sym
::div_assign
, div_assign_trait
, Target
::Trait
;
227 RemAssign(Op
), sym
::rem_assign
, rem_assign_trait
, Target
::Trait
;
228 BitXorAssign(Op
), sym
::bitxor_assign
, bitxor_assign_trait
, Target
::Trait
;
229 BitAndAssign(Op
), sym
::bitand_assign
, bitand_assign_trait
, Target
::Trait
;
230 BitOrAssign(Op
), sym
::bitor_assign
, bitor_assign_trait
, Target
::Trait
;
231 ShlAssign(Op
), sym
::shl_assign
, shl_assign_trait
, Target
::Trait
;
232 ShrAssign(Op
), sym
::shr_assign
, shr_assign_trait
, Target
::Trait
;
233 Index(Op
), sym
::index
, index_trait
, Target
::Trait
;
234 IndexMut(Op
), sym
::index_mut
, index_mut_trait
, Target
::Trait
;
236 UnsafeCell
, sym
::unsafe_cell
, unsafe_cell_type
, Target
::Struct
;
237 VaList
, sym
::va_list
, va_list
, Target
::Struct
;
239 Deref
, sym
::deref
, deref_trait
, Target
::Trait
;
240 DerefMut
, sym
::deref_mut
, deref_mut_trait
, Target
::Trait
;
241 Receiver
, sym
::receiver
, receiver_trait
, Target
::Trait
;
243 Fn
, kw
::Fn
, fn_trait
, Target
::Trait
;
244 FnMut
, sym
::fn_mut
, fn_mut_trait
, Target
::Trait
;
245 FnOnce
, sym
::fn_once
, fn_once_trait
, Target
::Trait
;
247 FnOnceOutput
, sym
::fn_once_output
, fn_once_output
, Target
::AssocTy
;
249 Future
, sym
::future_trait
, future_trait
, Target
::Trait
;
250 GeneratorState
, sym
::generator_state
, gen_state
, Target
::Enum
;
251 Generator
, sym
::generator
, gen_trait
, Target
::Trait
;
252 Unpin
, sym
::unpin
, unpin_trait
, Target
::Trait
;
253 Pin
, sym
::pin
, pin_type
, Target
::Struct
;
255 PartialEq
, sym
::eq
, eq_trait
, Target
::Trait
;
256 PartialOrd
, sym
::partial_ord
, partial_ord_trait
, Target
::Trait
;
258 // A number of panic-related lang items. The `panic` item corresponds to divide-by-zero and
259 // various panic cases with `match`. The `panic_bounds_check` item is for indexing arrays.
261 // The `begin_unwind` lang item has a predefined symbol name and is sort of a "weak lang item"
262 // in the sense that a crate is not required to have it defined to use it, but a final product
263 // is required to define it somewhere. Additionally, there are restrictions on crates that use
264 // a weak lang item, but do not have it defined.
265 Panic
, sym
::panic
, panic_fn
, Target
::Fn
;
266 PanicStr
, sym
::panic_str
, panic_str
, Target
::Fn
;
267 PanicBoundsCheck
, sym
::panic_bounds_check
, panic_bounds_check_fn
, Target
::Fn
;
268 PanicInfo
, sym
::panic_info
, panic_info
, Target
::Struct
;
269 PanicLocation
, sym
::panic_location
, panic_location
, Target
::Struct
;
270 PanicImpl
, sym
::panic_impl
, panic_impl
, Target
::Fn
;
271 // libstd panic entry point. Necessary for const eval to be able to catch it
272 BeginPanic
, sym
::begin_panic
, begin_panic_fn
, Target
::Fn
;
274 ExchangeMalloc
, sym
::exchange_malloc
, exchange_malloc_fn
, Target
::Fn
;
275 BoxFree
, sym
::box_free
, box_free_fn
, Target
::Fn
;
276 DropInPlace
, sym
::drop_in_place
, drop_in_place_fn
, Target
::Fn
;
277 Oom
, sym
::oom
, oom
, Target
::Fn
;
278 AllocLayout
, sym
::alloc_layout
, alloc_layout
, Target
::Struct
;
280 Start
, sym
::start
, start_fn
, Target
::Fn
;
282 EhPersonality
, sym
::eh_personality
, eh_personality
, Target
::Fn
;
283 EhCatchTypeinfo
, sym
::eh_catch_typeinfo
, eh_catch_typeinfo
, Target
::Static
;
285 OwnedBox
, sym
::owned_box
, owned_box
, Target
::Struct
;
287 PhantomData
, sym
::phantom_data
, phantom_data
, Target
::Struct
;
289 ManuallyDrop
, sym
::manually_drop
, manually_drop
, Target
::Struct
;
291 MaybeUninit
, sym
::maybe_uninit
, maybe_uninit
, Target
::Union
;
293 // Align offset for stride != 1; must not panic.
294 AlignOffset
, sym
::align_offset
, align_offset_fn
, Target
::Fn
;
296 Termination
, sym
::termination
, termination
, Target
::Trait
;
298 Try
, kw
::Try
, try_trait
, Target
::Trait
;
300 // Language items from AST lowering
301 TryFromError
, sym
::from_error
, from_error_fn
, Target
::Method(MethodKind
::Trait { body: false }
);
302 TryFromOk
, sym
::from_ok
, from_ok_fn
, Target
::Method(MethodKind
::Trait { body: false }
);
303 TryIntoResult
, sym
::into_result
, into_result_fn
, Target
::Method(MethodKind
::Trait { body: false }
);
305 PollReady
, sym
::Ready
, poll_ready_variant
, Target
::Variant
;
306 PollPending
, sym
::Pending
, poll_pending_variant
, Target
::Variant
;
308 FromGenerator
, sym
::from_generator
, from_generator_fn
, Target
::Fn
;
309 GetContext
, sym
::get_context
, get_context_fn
, Target
::Fn
;
311 FuturePoll
, sym
::poll
, future_poll_fn
, Target
::Method(MethodKind
::Trait { body: false }
);
313 FromFrom
, sym
::from
, from_fn
, Target
::Method(MethodKind
::Trait { body: false }
);
315 OptionSome
, sym
::Some
, option_some_variant
, Target
::Variant
;
316 OptionNone
, sym
::None
, option_none_variant
, Target
::Variant
;
318 ResultOk
, sym
::Ok
, result_ok_variant
, Target
::Variant
;
319 ResultErr
, sym
::Err
, result_err_variant
, Target
::Variant
;
321 IntoIterIntoIter
, sym
::into_iter
, into_iter_fn
, Target
::Method(MethodKind
::Trait { body: false }
);
322 IteratorNext
, sym
::next
, next_fn
, Target
::Method(MethodKind
::Trait { body: false}
);
324 PinNewUnchecked
, sym
::new_unchecked
, new_unchecked_fn
, Target
::Method(MethodKind
::Inherent
);
326 RangeFrom
, sym
::RangeFrom
, range_from_struct
, Target
::Struct
;
327 RangeFull
, sym
::RangeFull
, range_full_struct
, Target
::Struct
;
328 RangeInclusiveStruct
, sym
::RangeInclusive
, range_inclusive_struct
, Target
::Struct
;
329 RangeInclusiveNew
, sym
::range_inclusive_new
, range_inclusive_new_method
, Target
::Method(MethodKind
::Inherent
);
330 Range
, sym
::Range
, range_struct
, Target
::Struct
;
331 RangeToInclusive
, sym
::RangeToInclusive
, range_to_inclusive_struct
, Target
::Struct
;
332 RangeTo
, sym
::RangeTo
, range_to_struct
, Target
::Struct
;