1 //! Collects lang items: items marked with `#[lang = "..."]` attribute.
3 //! This attribute to tell the compiler about semi built-in std library
4 //! features, such as Fn family of traits.
7 use rustc_hash
::FxHashMap
;
11 db
::DefDatabase
, AdtId
, AssocItemId
, AttrDefId
, CrateId
, EnumId
, EnumVariantId
, FunctionId
,
12 ImplId
, ModuleDefId
, StaticId
, StructId
, TraitId
, TypeAliasId
, UnionId
,
15 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
16 pub enum LangItemTarget
{
23 TypeAlias(TypeAliasId
),
25 EnumVariant(EnumVariantId
),
29 pub fn as_enum(self) -> Option
<EnumId
> {
31 LangItemTarget
::EnumId(id
) => Some(id
),
36 pub fn as_function(self) -> Option
<FunctionId
> {
38 LangItemTarget
::Function(id
) => Some(id
),
43 pub fn as_impl_def(self) -> Option
<ImplId
> {
45 LangItemTarget
::ImplDef(id
) => Some(id
),
50 pub fn as_static(self) -> Option
<StaticId
> {
52 LangItemTarget
::Static(id
) => Some(id
),
57 pub fn as_struct(self) -> Option
<StructId
> {
59 LangItemTarget
::Struct(id
) => Some(id
),
64 pub fn as_trait(self) -> Option
<TraitId
> {
66 LangItemTarget
::Trait(id
) => Some(id
),
71 pub fn as_enum_variant(self) -> Option
<EnumVariantId
> {
73 LangItemTarget
::EnumVariant(id
) => Some(id
),
79 #[derive(Default, Debug, Clone, PartialEq, Eq)]
80 pub struct LangItems
{
81 items
: FxHashMap
<LangItem
, LangItemTarget
>,
85 pub fn target(&self, item
: LangItem
) -> Option
<LangItemTarget
> {
86 self.items
.get(&item
).copied()
89 /// Salsa query. This will look for lang items in a specific crate.
90 pub(crate) fn crate_lang_items_query(db
: &dyn DefDatabase
, krate
: CrateId
) -> Arc
<LangItems
> {
91 let _p
= profile
::span("crate_lang_items_query");
93 let mut lang_items
= LangItems
::default();
95 let crate_def_map
= db
.crate_def_map(krate
);
97 for (_
, module_data
) in crate_def_map
.modules() {
98 for impl_def
in module_data
.scope
.impls() {
99 lang_items
.collect_lang_item(db
, impl_def
, LangItemTarget
::ImplDef
);
100 for assoc
in db
.impl_data(impl_def
).items
.iter().copied() {
102 AssocItemId
::FunctionId(f
) => {
103 lang_items
.collect_lang_item(db
, f
, LangItemTarget
::Function
)
105 AssocItemId
::TypeAliasId(t
) => {
106 lang_items
.collect_lang_item(db
, t
, LangItemTarget
::TypeAlias
)
108 AssocItemId
::ConstId(_
) => (),
113 for def
in module_data
.scope
.declarations() {
115 ModuleDefId
::TraitId(trait_
) => {
116 lang_items
.collect_lang_item(db
, trait_
, LangItemTarget
::Trait
);
117 db
.trait_data(trait_
).items
.iter().for_each(|&(_
, assoc_id
)| {
118 if let AssocItemId
::FunctionId(f
) = assoc_id
{
119 lang_items
.collect_lang_item(db
, f
, LangItemTarget
::Function
);
123 ModuleDefId
::AdtId(AdtId
::EnumId(e
)) => {
124 lang_items
.collect_lang_item(db
, e
, LangItemTarget
::EnumId
);
125 db
.enum_data(e
).variants
.iter().for_each(|(local_id
, _
)| {
126 lang_items
.collect_lang_item(
128 EnumVariantId { parent: e, local_id }
,
129 LangItemTarget
::EnumVariant
,
133 ModuleDefId
::AdtId(AdtId
::StructId(s
)) => {
134 lang_items
.collect_lang_item(db
, s
, LangItemTarget
::Struct
);
136 ModuleDefId
::AdtId(AdtId
::UnionId(u
)) => {
137 lang_items
.collect_lang_item(db
, u
, LangItemTarget
::Union
);
139 ModuleDefId
::FunctionId(f
) => {
140 lang_items
.collect_lang_item(db
, f
, LangItemTarget
::Function
);
142 ModuleDefId
::StaticId(s
) => {
143 lang_items
.collect_lang_item(db
, s
, LangItemTarget
::Static
);
145 ModuleDefId
::TypeAliasId(t
) => {
146 lang_items
.collect_lang_item(db
, t
, LangItemTarget
::TypeAlias
);
156 /// Salsa query. Look for a lang item, starting from the specified crate and recursively
157 /// traversing its dependencies.
158 pub(crate) fn lang_item_query(
159 db
: &dyn DefDatabase
,
160 start_crate
: CrateId
,
162 ) -> Option
<LangItemTarget
> {
163 let _p
= profile
::span("lang_item_query");
164 let lang_items
= db
.crate_lang_items(start_crate
);
165 let start_crate_target
= lang_items
.items
.get(&item
);
166 if let Some(&target
) = start_crate_target
{
169 db
.crate_graph()[start_crate
]
172 .find_map(|dep
| db
.lang_item(dep
.crate_id
, item
))
175 fn collect_lang_item
<T
>(
177 db
: &dyn DefDatabase
,
179 constructor
: fn(T
) -> LangItemTarget
,
181 T
: Into
<AttrDefId
> + Copy
,
183 let _p
= profile
::span("collect_lang_item");
184 if let Some(lang_item
) = lang_attr(db
, item
) {
185 self.items
.entry(lang_item
).or_insert_with(|| constructor(item
));
190 pub fn lang_attr(db
: &dyn DefDatabase
, item
: impl Into
<AttrDefId
> + Copy
) -> Option
<LangItem
> {
191 let attrs
= db
.attrs(item
.into());
192 attrs
.by_key("lang").string_value().cloned().and_then(|it
| LangItem
::from_str(&it
))
195 pub enum GenericRequirement
{
201 macro_rules
! language_item_table
{
203 $
( $
(#[$attr:meta])* $variant:ident, $name:ident, $method:ident, $target:expr, $generics:expr; )*
206 /// A representation of all the valid language items in Rust.
207 #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
210 #[doc = concat!("The `", stringify!($name), "` lang item.")]
217 pub fn name(self) -> SmolStr
{
219 $
( LangItem
::$variant
=> SmolStr
::new(stringify
!($name
)), )*
223 /// Opposite of [`LangItem::name`]
224 pub fn from_name(name
: &hir_expand
::name
::Name
) -> Option
<Self> {
225 Self::from_str(name
.as_str()?
)
228 /// Opposite of [`LangItem::name`]
229 pub fn from_str(name
: &str) -> Option
<Self> {
231 $
( stringify
!($name
) => Some(LangItem
::$variant
), )*
239 language_item_table
! {
240 // Variant name, Name, Getter method name, Target Generic requirements;
241 Sized
, sized
, sized_trait
, Target
::Trait
, GenericRequirement
::Exact(0);
242 Unsize
, unsize
, unsize_trait
, Target
::Trait
, GenericRequirement
::Minimum(1);
243 /// Trait injected by `#[derive(PartialEq)]`, (i.e. "Partial EQ").
244 StructuralPeq
, structural_peq
, structural_peq_trait
, Target
::Trait
, GenericRequirement
::None
;
245 /// Trait injected by `#[derive(Eq)]`, (i.e. "Total EQ"; no, I will not apologize).
246 StructuralTeq
, structural_teq
, structural_teq_trait
, Target
::Trait
, GenericRequirement
::None
;
247 Copy
, copy
, copy_trait
, Target
::Trait
, GenericRequirement
::Exact(0);
248 Clone
, clone
, clone_trait
, Target
::Trait
, GenericRequirement
::None
;
249 Sync
, sync
, sync_trait
, Target
::Trait
, GenericRequirement
::Exact(0);
250 DiscriminantKind
, discriminant_kind
, discriminant_kind_trait
, Target
::Trait
, GenericRequirement
::None
;
251 /// The associated item of the [`DiscriminantKind`] trait.
252 Discriminant
, discriminant_type
, discriminant_type
, Target
::AssocTy
, GenericRequirement
::None
;
254 PointeeTrait
, pointee_trait
, pointee_trait
, Target
::Trait
, GenericRequirement
::None
;
255 Metadata
, metadata_type
, metadata_type
, Target
::AssocTy
, GenericRequirement
::None
;
256 DynMetadata
, dyn_metadata
, dyn_metadata
, Target
::Struct
, GenericRequirement
::None
;
258 Freeze
, freeze
, freeze_trait
, Target
::Trait
, GenericRequirement
::Exact(0);
260 Drop
, drop
, drop_trait
, Target
::Trait
, GenericRequirement
::None
;
261 Destruct
, destruct
, destruct_trait
, Target
::Trait
, GenericRequirement
::None
;
263 CoerceUnsized
, coerce_unsized
, coerce_unsized_trait
, Target
::Trait
, GenericRequirement
::Minimum(1);
264 DispatchFromDyn
, dispatch_from_dyn
, dispatch_from_dyn_trait
, Target
::Trait
, GenericRequirement
::Minimum(1);
266 // language items relating to transmutability
267 TransmuteOpts
, transmute_opts
, transmute_opts
, Target
::Struct
, GenericRequirement
::Exact(0);
268 TransmuteTrait
, transmute_trait
, transmute_trait
, Target
::Trait
, GenericRequirement
::Exact(3);
270 Add
, add
, add_trait
, Target
::Trait
, GenericRequirement
::Exact(1);
271 Sub
, sub
, sub_trait
, Target
::Trait
, GenericRequirement
::Exact(1);
272 Mul
, mul
, mul_trait
, Target
::Trait
, GenericRequirement
::Exact(1);
273 Div
, div
, div_trait
, Target
::Trait
, GenericRequirement
::Exact(1);
274 Rem
, rem
, rem_trait
, Target
::Trait
, GenericRequirement
::Exact(1);
275 Neg
, neg
, neg_trait
, Target
::Trait
, GenericRequirement
::Exact(0);
276 Not
, not
, not_trait
, Target
::Trait
, GenericRequirement
::Exact(0);
277 BitXor
, bitxor
, bitxor_trait
, Target
::Trait
, GenericRequirement
::Exact(1);
278 BitAnd
, bitand
, bitand_trait
, Target
::Trait
, GenericRequirement
::Exact(1);
279 BitOr
, bitor
, bitor_trait
, Target
::Trait
, GenericRequirement
::Exact(1);
280 Shl
, shl
, shl_trait
, Target
::Trait
, GenericRequirement
::Exact(1);
281 Shr
, shr
, shr_trait
, Target
::Trait
, GenericRequirement
::Exact(1);
282 AddAssign
, add_assign
, add_assign_trait
, Target
::Trait
, GenericRequirement
::Exact(1);
283 SubAssign
, sub_assign
, sub_assign_trait
, Target
::Trait
, GenericRequirement
::Exact(1);
284 MulAssign
, mul_assign
, mul_assign_trait
, Target
::Trait
, GenericRequirement
::Exact(1);
285 DivAssign
, div_assign
, div_assign_trait
, Target
::Trait
, GenericRequirement
::Exact(1);
286 RemAssign
, rem_assign
, rem_assign_trait
, Target
::Trait
, GenericRequirement
::Exact(1);
287 BitXorAssign
, bitxor_assign
, bitxor_assign_trait
, Target
::Trait
, GenericRequirement
::Exact(1);
288 BitAndAssign
, bitand_assign
, bitand_assign_trait
, Target
::Trait
, GenericRequirement
::Exact(1);
289 BitOrAssign
, bitor_assign
, bitor_assign_trait
, Target
::Trait
, GenericRequirement
::Exact(1);
290 ShlAssign
, shl_assign
, shl_assign_trait
, Target
::Trait
, GenericRequirement
::Exact(1);
291 ShrAssign
, shr_assign
, shr_assign_trait
, Target
::Trait
, GenericRequirement
::Exact(1);
292 Index
, index
, index_trait
, Target
::Trait
, GenericRequirement
::Exact(1);
293 IndexMut
, index_mut
, index_mut_trait
, Target
::Trait
, GenericRequirement
::Exact(1);
295 UnsafeCell
, unsafe_cell
, unsafe_cell_type
, Target
::Struct
, GenericRequirement
::None
;
296 VaList
, va_list
, va_list
, Target
::Struct
, GenericRequirement
::None
;
298 Deref
, deref
, deref_trait
, Target
::Trait
, GenericRequirement
::Exact(0);
299 DerefMut
, deref_mut
, deref_mut_trait
, Target
::Trait
, GenericRequirement
::Exact(0);
300 DerefTarget
, deref_target
, deref_target
, Target
::AssocTy
, GenericRequirement
::None
;
301 Receiver
, receiver
, receiver_trait
, Target
::Trait
, GenericRequirement
::None
;
303 Fn
, fn, fn_trait
, Target
::Trait
, GenericRequirement
::Exact(1);
304 FnMut
, fn_mut
, fn_mut_trait
, Target
::Trait
, GenericRequirement
::Exact(1);
305 FnOnce
, fn_once
, fn_once_trait
, Target
::Trait
, GenericRequirement
::Exact(1);
307 FnOnceOutput
, fn_once_output
, fn_once_output
, Target
::AssocTy
, GenericRequirement
::None
;
309 Future
, future_trait
, future_trait
, Target
::Trait
, GenericRequirement
::Exact(0);
310 GeneratorState
, generator_state
, gen_state
, Target
::Enum
, GenericRequirement
::None
;
311 Generator
, generator
, gen_trait
, Target
::Trait
, GenericRequirement
::Minimum(1);
312 Unpin
, unpin
, unpin_trait
, Target
::Trait
, GenericRequirement
::None
;
313 Pin
, pin
, pin_type
, Target
::Struct
, GenericRequirement
::None
;
315 PartialEq
, eq
, eq_trait
, Target
::Trait
, GenericRequirement
::Exact(1);
316 PartialOrd
, partial_ord
, partial_ord_trait
, Target
::Trait
, GenericRequirement
::Exact(1);
318 // A number of panic-related lang items. The `panic` item corresponds to divide-by-zero and
319 // various panic cases with `match`. The `panic_bounds_check` item is for indexing arrays.
321 // The `begin_unwind` lang item has a predefined symbol name and is sort of a "weak lang item"
322 // in the sense that a crate is not required to have it defined to use it, but a final product
323 // is required to define it somewhere. Additionally, there are restrictions on crates that use
324 // a weak lang item, but do not have it defined.
325 Panic
, panic
, panic_fn
, Target
::Fn
, GenericRequirement
::Exact(0);
326 PanicNounwind
, panic_nounwind
, panic_nounwind
, Target
::Fn
, GenericRequirement
::Exact(0);
327 PanicFmt
, panic_fmt
, panic_fmt
, Target
::Fn
, GenericRequirement
::None
;
328 PanicDisplay
, panic_display
, panic_display
, Target
::Fn
, GenericRequirement
::None
;
329 ConstPanicFmt
, const_panic_fmt
, const_panic_fmt
, Target
::Fn
, GenericRequirement
::None
;
330 PanicBoundsCheck
, panic_bounds_check
, panic_bounds_check_fn
, Target
::Fn
, GenericRequirement
::Exact(0);
331 PanicInfo
, panic_info
, panic_info
, Target
::Struct
, GenericRequirement
::None
;
332 PanicLocation
, panic_location
, panic_location
, Target
::Struct
, GenericRequirement
::None
;
333 PanicImpl
, panic_impl
, panic_impl
, Target
::Fn
, GenericRequirement
::None
;
334 PanicCannotUnwind
, panic_cannot_unwind
, panic_cannot_unwind
, Target
::Fn
, GenericRequirement
::Exact(0);
335 /// libstd panic entry point. Necessary for const eval to be able to catch it
336 BeginPanic
, begin_panic
, begin_panic_fn
, Target
::Fn
, GenericRequirement
::None
;
338 ExchangeMalloc
, exchange_malloc
, exchange_malloc_fn
, Target
::Fn
, GenericRequirement
::None
;
339 BoxFree
, box_free
, box_free_fn
, Target
::Fn
, GenericRequirement
::Minimum(1);
340 DropInPlace
, drop_in_place
, drop_in_place_fn
, Target
::Fn
, GenericRequirement
::Minimum(1);
341 AllocLayout
, alloc_layout
, alloc_layout
, Target
::Struct
, GenericRequirement
::None
;
343 Start
, start
, start_fn
, Target
::Fn
, GenericRequirement
::Exact(1);
345 EhPersonality
, eh_personality
, eh_personality
, Target
::Fn
, GenericRequirement
::None
;
346 EhCatchTypeinfo
, eh_catch_typeinfo
, eh_catch_typeinfo
, Target
::Static
, GenericRequirement
::None
;
348 OwnedBox
, owned_box
, owned_box
, Target
::Struct
, GenericRequirement
::Minimum(1);
350 PhantomData
, phantom_data
, phantom_data
, Target
::Struct
, GenericRequirement
::Exact(1);
352 ManuallyDrop
, manually_drop
, manually_drop
, Target
::Struct
, GenericRequirement
::None
;
354 MaybeUninit
, maybe_uninit
, maybe_uninit
, Target
::Union
, GenericRequirement
::None
;
356 /// Align offset for stride != 1; must not panic.
357 AlignOffset
, align_offset
, align_offset_fn
, Target
::Fn
, GenericRequirement
::None
;
359 Termination
, termination
, termination
, Target
::Trait
, GenericRequirement
::None
;
361 Try
, Try
, try_trait
, Target
::Trait
, GenericRequirement
::None
;
363 Tuple
, tuple_trait
, tuple_trait
, Target
::Trait
, GenericRequirement
::Exact(0);
365 SliceLen
, slice_len_fn
, slice_len_fn
, Target
::Method(MethodKind
::Inherent
), GenericRequirement
::None
;
367 // Language items from AST lowering
368 TryTraitFromResidual
, from_residual
, from_residual_fn
, Target
::Method(MethodKind
::Trait { body: false }
), GenericRequirement
::None
;
369 TryTraitFromOutput
, from_output
, from_output_fn
, Target
::Method(MethodKind
::Trait { body: false }
), GenericRequirement
::None
;
370 TryTraitBranch
, branch
, branch_fn
, Target
::Method(MethodKind
::Trait { body: false }
), GenericRequirement
::None
;
371 TryTraitFromYeet
, from_yeet
, from_yeet_fn
, Target
::Fn
, GenericRequirement
::None
;
373 PointerSized
, pointer_sized
, pointer_sized
, Target
::Trait
, GenericRequirement
::Exact(0);
375 Poll
, Poll
, poll
, Target
::Enum
, GenericRequirement
::None
;
376 PollReady
, Ready
, poll_ready_variant
, Target
::Variant
, GenericRequirement
::None
;
377 PollPending
, Pending
, poll_pending_variant
, Target
::Variant
, GenericRequirement
::None
;
379 // FIXME(swatinem): the following lang items are used for async lowering and
380 // should become obsolete eventually.
381 ResumeTy
, ResumeTy
, resume_ty
, Target
::Struct
, GenericRequirement
::None
;
382 GetContext
, get_context
, get_context_fn
, Target
::Fn
, GenericRequirement
::None
;
384 Context
, Context
, context
, Target
::Struct
, GenericRequirement
::None
;
385 FuturePoll
, poll
, future_poll_fn
, Target
::Method(MethodKind
::Trait { body: false }
), GenericRequirement
::None
;
387 FromFrom
, from
, from_fn
, Target
::Method(MethodKind
::Trait { body: false }
), GenericRequirement
::None
;
389 OptionSome
, Some
, option_some_variant
, Target
::Variant
, GenericRequirement
::None
;
390 OptionNone
, None
, option_none_variant
, Target
::Variant
, GenericRequirement
::None
;
392 ResultOk
, Ok
, result_ok_variant
, Target
::Variant
, GenericRequirement
::None
;
393 ResultErr
, Err
, result_err_variant
, Target
::Variant
, GenericRequirement
::None
;
395 ControlFlowContinue
, Continue
, cf_continue_variant
, Target
::Variant
, GenericRequirement
::None
;
396 ControlFlowBreak
, Break
, cf_break_variant
, Target
::Variant
, GenericRequirement
::None
;
398 IntoFutureIntoFuture
, into_future
, into_future_fn
, Target
::Method(MethodKind
::Trait { body: false }
), GenericRequirement
::None
;
399 IntoIterIntoIter
, into_iter
, into_iter_fn
, Target
::Method(MethodKind
::Trait { body: false }
), GenericRequirement
::None
;
400 IteratorNext
, next
, next_fn
, Target
::Method(MethodKind
::Trait { body: false}
), GenericRequirement
::None
;
402 PinNewUnchecked
, new_unchecked
, new_unchecked_fn
, Target
::Method(MethodKind
::Inherent
), GenericRequirement
::None
;
404 RangeFrom
, RangeFrom
, range_from_struct
, Target
::Struct
, GenericRequirement
::None
;
405 RangeFull
, RangeFull
, range_full_struct
, Target
::Struct
, GenericRequirement
::None
;
406 RangeInclusiveStruct
, RangeInclusive
, range_inclusive_struct
, Target
::Struct
, GenericRequirement
::None
;
407 RangeInclusiveNew
, range_inclusive_new
, range_inclusive_new_method
, Target
::Method(MethodKind
::Inherent
), GenericRequirement
::None
;
408 Range
, Range
, range_struct
, Target
::Struct
, GenericRequirement
::None
;
409 RangeToInclusive
, RangeToInclusive
, range_to_inclusive_struct
, Target
::Struct
, GenericRequirement
::None
;
410 RangeTo
, RangeTo
, range_to_struct
, Target
::Struct
, GenericRequirement
::None
;
412 String
, String
, string
, Target
::Struct
, GenericRequirement
::None
;