1use intern::{Symbol, sym};
6use stdx::impl_from;
7
8use crate::{
9 AdtId, AssocItemId, AttrDefId, Crate, EnumId, EnumVariantId, FunctionId, ImplId, ModuleDefId,
10 StaticId, StructId, TraitId, TypeAliasId, UnionId,
11 attrs::AttrFlags,
12 db::DefDatabase,
13 nameres::{assoc::TraitItems, crate_def_map, crate_local_def_map},
14};
15
16#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
17pub enum LangItemTarget {
18 EnumId(EnumId),
19 FunctionId(FunctionId),
20 ImplId(ImplId),
21 StaticId(StaticId),
22 StructId(StructId),
23 UnionId(UnionId),
24 TypeAliasId(TypeAliasId),
25 TraitId(TraitId),
26 EnumVariantId(EnumVariantId),
27}
28
29impl_from!(
30 EnumId, FunctionId, ImplId, StaticId, StructId, UnionId, TypeAliasId, TraitId, EnumVariantId for LangItemTarget
31);
32
33#[salsa_macros::tracked(returns(as_deref))]
35pub fn crate_lang_items(db: &dyn DefDatabase, krate: Crate) -> Option<Box<LangItems>> {
36 let _p = tracing::info_span!("crate_lang_items_query").entered();
37
38 let mut lang_items = LangItems::default();
39
40 let crate_def_map = crate_def_map(db, krate);
41
42 for (_, module_data) in crate_def_map.modules() {
43 for impl_def in module_data.scope.impls() {
44 lang_items.collect_lang_item(db, impl_def);
45 for &(_, assoc) in impl_def.impl_items(db).items.iter() {
46 match assoc {
47 AssocItemId::FunctionId(f) => lang_items.collect_lang_item(db, f),
48 AssocItemId::TypeAliasId(t) => lang_items.collect_lang_item(db, t),
49 AssocItemId::ConstId(_) => (),
50 }
51 }
52 }
53
54 for def in module_data.scope.declarations() {
55 match def {
56 ModuleDefId::TraitId(trait_) => {
57 lang_items.collect_lang_item(db, trait_);
58 TraitItems::query(db, trait_).items.iter().for_each(|&(_, assoc_id)| {
59 match assoc_id {
60 AssocItemId::FunctionId(f) => {
61 lang_items.collect_lang_item(db, f);
62 }
63 AssocItemId::TypeAliasId(alias) => {
64 lang_items.collect_lang_item(db, alias)
65 }
66 AssocItemId::ConstId(_) => {}
67 }
68 });
69 }
70 ModuleDefId::AdtId(AdtId::EnumId(e)) => {
71 lang_items.collect_lang_item(db, e);
72 e.enum_variants(db).variants.iter().for_each(|&(id, _, _)| {
73 lang_items.collect_lang_item(db, id);
74 });
75 }
76 ModuleDefId::AdtId(AdtId::StructId(s)) => {
77 lang_items.collect_lang_item(db, s);
78 }
79 ModuleDefId::AdtId(AdtId::UnionId(u)) => {
80 lang_items.collect_lang_item(db, u);
81 }
82 ModuleDefId::FunctionId(f) => {
83 lang_items.collect_lang_item(db, f);
84 }
85 ModuleDefId::StaticId(s) => {
86 lang_items.collect_lang_item(db, s);
87 }
88 ModuleDefId::TypeAliasId(t) => {
89 lang_items.collect_lang_item(db, t);
90 }
91 _ => {}
92 }
93 }
94 }
95
96 if lang_items.is_empty() { None } else { Some(Box::new(lang_items)) }
97}
98
99#[salsa_macros::tracked(returns(ref))]
102pub fn lang_items(db: &dyn DefDatabase, start_crate: Crate) -> LangItems {
103 let _p = tracing::info_span!("lang_items_query").entered();
104
105 let mut result = crate_lang_items(db, start_crate).cloned().unwrap_or_default();
106
107 for (_, (module, _)) in crate_local_def_map(db, start_crate).local(db).extern_prelude() {
115 let krate = module.krate(db);
118 if krate != start_crate {
119 result.merge_prefer_self(lang_items(db, krate));
120 }
121 }
122
123 result
124}
125
126impl LangItems {
127 fn collect_lang_item<T>(&mut self, db: &dyn DefDatabase, item: T)
128 where
129 T: Into<AttrDefId> + Into<LangItemTarget> + Copy,
130 {
131 let _p = tracing::info_span!("collect_lang_item").entered();
132 if let Some(lang_item) = AttrFlags::lang_item(db, item.into()) {
133 self.assign_lang_item(lang_item, item.into());
134 }
135 }
136}
137
138#[salsa::tracked(returns(as_deref))]
139pub(crate) fn crate_notable_traits(db: &dyn DefDatabase, krate: Crate) -> Option<Box<[TraitId]>> {
140 let mut traits = Vec::new();
141
142 let crate_def_map = crate_def_map(db, krate);
143
144 for (_, module_data) in crate_def_map.modules() {
145 for def in module_data.scope.declarations() {
146 if let ModuleDefId::TraitId(trait_) = def
147 && AttrFlags::query(db, trait_.into()).contains(AttrFlags::IS_DOC_NOTABLE_TRAIT)
148 {
149 traits.push(trait_);
150 }
151 }
152 }
153
154 if traits.is_empty() { None } else { Some(traits.into_iter().collect()) }
155}
156
157pub enum GenericRequirement {
158 None,
159 Minimum(usize),
160 Exact(usize),
161}
162
163macro_rules! language_item_table {
164 (
165 $LangItems:ident =>
166 $( $(#[$attr:meta])* $lang_item:ident, $module:ident :: $name:ident, $method:ident, $target:ident, $generics:expr; )*
167 ) => {
168 #[allow(non_snake_case)] #[derive(Debug, Default, Clone, PartialEq, Eq, Hash)]
170 pub struct $LangItems {
171 $(
172 $(#[$attr])*
173 pub $lang_item: Option<$target>,
174 )*
175 }
176
177 impl LangItems {
178 fn is_empty(&self) -> bool {
179 $( self.$lang_item.is_none() )&&*
180 }
181
182 fn merge_prefer_self(&mut self, other: &Self) {
184 $( self.$lang_item = self.$lang_item.or(other.$lang_item); )*
185 }
186
187 fn assign_lang_item(&mut self, name: Symbol, target: LangItemTarget) {
188 match name {
189 $(
190 _ if name == $module::$name => {
191 if let LangItemTarget::$target(target) = target {
192 self.$lang_item = Some(target);
193 }
194 }
195 )*
196 _ => {}
197 }
198 }
199 }
200
201 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
202 pub enum LangItemEnum {
203 $(
204 $(#[$attr])*
205 $lang_item,
206 )*
207 }
208
209 impl LangItemEnum {
210 #[inline]
211 pub fn from_lang_items(self, lang_items: &LangItems) -> Option<LangItemTarget> {
212 match self {
213 $( LangItemEnum::$lang_item => lang_items.$lang_item.map(Into::into), )*
214 }
215 }
216
217 #[inline]
218 pub fn from_symbol(symbol: &Symbol) -> Option<Self> {
219 match symbol {
220 $( _ if *symbol == $module::$name => Some(Self::$lang_item), )*
221 _ => None,
222 }
223 }
224 }
225 }
226}
227
228language_item_table! { LangItems =>
229Sized, sym::sized, sized_trait, TraitId, GenericRequirement::Exact(0);
231 MetaSized, sym::meta_sized, sized_trait, TraitId, GenericRequirement::Exact(0);
232 PointeeSized, sym::pointee_sized, sized_trait, TraitId, GenericRequirement::Exact(0);
233 Unsize, sym::unsize, unsize_trait, TraitId, GenericRequirement::Minimum(1);
234 StructuralPeq, sym::structural_peq, structural_peq_trait, TraitId, GenericRequirement::None;
236 StructuralTeq, sym::structural_teq, structural_teq_trait, TraitId, GenericRequirement::None;
238 Copy, sym::copy, copy_trait, TraitId, GenericRequirement::Exact(0);
239 Clone, sym::clone, clone_trait, TraitId, GenericRequirement::None;
240 TrivialClone, sym::trivial_clone, clone_trait, TraitId, GenericRequirement::None;
241 Sync, sym::sync, sync_trait, TraitId, GenericRequirement::Exact(0);
242 DiscriminantKind, sym::discriminant_kind, discriminant_kind_trait, TraitId, GenericRequirement::None;
243 Discriminant, sym::discriminant_type, discriminant_type, TypeAliasId, GenericRequirement::None;
245
246 PointeeTrait, sym::pointee_trait, pointee_trait, TraitId, GenericRequirement::None;
247 Metadata, sym::metadata_type, metadata_type, TypeAliasId, GenericRequirement::None;
248 DynMetadata, sym::dyn_metadata, dyn_metadata, StructId, GenericRequirement::None;
249
250 Freeze, sym::freeze, freeze_trait, TraitId, GenericRequirement::Exact(0);
251
252 FnPtrTrait, sym::fn_ptr_trait, fn_ptr_trait, TraitId, GenericRequirement::Exact(0);
253 FnPtrAddr, sym::fn_ptr_addr, fn_ptr_addr, FunctionId, GenericRequirement::None;
254
255 Drop, sym::drop, drop_trait, TraitId, GenericRequirement::None;
256 Destruct, sym::destruct, destruct_trait, TraitId, GenericRequirement::None;
257
258 CoerceUnsized, sym::coerce_unsized, coerce_unsized_trait, TraitId, GenericRequirement::Minimum(1);
259 DispatchFromDyn, sym::dispatch_from_dyn, dispatch_from_dyn_trait, TraitId, GenericRequirement::Minimum(1);
260
261 TransmuteOpts, sym::transmute_opts, transmute_opts, StructId, GenericRequirement::Exact(0);
263 TransmuteTrait, sym::transmute_trait, transmute_trait, TraitId, GenericRequirement::Exact(3);
264
265 Add, sym::add, add_trait, TraitId, GenericRequirement::Exact(1);
266 Sub, sym::sub, sub_trait, TraitId, GenericRequirement::Exact(1);
267 Mul, sym::mul, mul_trait, TraitId, GenericRequirement::Exact(1);
268 Div, sym::div, div_trait, TraitId, GenericRequirement::Exact(1);
269 Rem, sym::rem, rem_trait, TraitId, GenericRequirement::Exact(1);
270 Neg, sym::neg, neg_trait, TraitId, GenericRequirement::Exact(0);
271 Not, sym::not, not_trait, TraitId, GenericRequirement::Exact(0);
272 BitXor, sym::bitxor, bitxor_trait, TraitId, GenericRequirement::Exact(1);
273 BitAnd, sym::bitand, bitand_trait, TraitId, GenericRequirement::Exact(1);
274 BitOr, sym::bitor, bitor_trait, TraitId, GenericRequirement::Exact(1);
275 Shl, sym::shl, shl_trait, TraitId, GenericRequirement::Exact(1);
276 Shr, sym::shr, shr_trait, TraitId, GenericRequirement::Exact(1);
277 AddAssign, sym::add_assign, add_assign_trait, TraitId, GenericRequirement::Exact(1);
278 SubAssign, sym::sub_assign, sub_assign_trait, TraitId, GenericRequirement::Exact(1);
279 MulAssign, sym::mul_assign, mul_assign_trait, TraitId, GenericRequirement::Exact(1);
280 DivAssign, sym::div_assign, div_assign_trait, TraitId, GenericRequirement::Exact(1);
281 RemAssign, sym::rem_assign, rem_assign_trait, TraitId, GenericRequirement::Exact(1);
282 BitXorAssign, sym::bitxor_assign, bitxor_assign_trait, TraitId, GenericRequirement::Exact(1);
283 BitAndAssign, sym::bitand_assign, bitand_assign_trait, TraitId, GenericRequirement::Exact(1);
284 BitOrAssign, sym::bitor_assign, bitor_assign_trait, TraitId, GenericRequirement::Exact(1);
285 ShlAssign, sym::shl_assign, shl_assign_trait, TraitId, GenericRequirement::Exact(1);
286 ShrAssign, sym::shr_assign, shr_assign_trait, TraitId, GenericRequirement::Exact(1);
287 Index, sym::index, index_trait, TraitId, GenericRequirement::Exact(1);
288 IndexMut, sym::index_mut, index_mut_trait, TraitId, GenericRequirement::Exact(1);
289
290 UnsafeCell, sym::unsafe_cell, unsafe_cell_type, StructId, GenericRequirement::None;
291 UnsafePinned, sym::unsafe_pinned, unsafe_pinned_type, StructId, GenericRequirement::None;
292 VaList, sym::va_list, va_list, StructId, GenericRequirement::None;
293
294 Deref, sym::deref, deref_trait, TraitId, GenericRequirement::Exact(0);
295 DerefMut, sym::deref_mut, deref_mut_trait, TraitId, GenericRequirement::Exact(0);
296 DerefTarget, sym::deref_target, deref_target, TypeAliasId, GenericRequirement::None;
297 Receiver, sym::receiver, receiver_trait, TraitId, GenericRequirement::None;
298 ReceiverTarget, sym::receiver_target, receiver_target, TypeAliasId, GenericRequirement::None;
299
300 Fn, sym::fn_, fn_trait, TraitId, GenericRequirement::Exact(1);
301 FnMut, sym::fn_mut, fn_mut_trait, TraitId, GenericRequirement::Exact(1);
302 FnOnce, sym::fn_once, fn_once_trait, TraitId, GenericRequirement::Exact(1);
303 AsyncFn, sym::async_fn, async_fn_trait, TraitId, GenericRequirement::Exact(1);
304 AsyncFnMut, sym::async_fn_mut, async_fn_mut_trait, TraitId, GenericRequirement::Exact(1);
305 AsyncFnOnce, sym::async_fn_once, async_fn_once_trait, TraitId, GenericRequirement::Exact(1);
306
307 CallRefFuture, sym::call_ref_future, call_ref_future_ty, TypeAliasId, GenericRequirement::None;
308 CallOnceFuture, sym::call_once_future, call_once_future_ty, TypeAliasId, GenericRequirement::None;
309 AsyncFnOnceOutput, sym::async_fn_once_output, async_fn_once_output_ty, TypeAliasId, GenericRequirement::None;
310
311 FnOnceOutput, sym::fn_once_output, fn_once_output, TypeAliasId, GenericRequirement::None;
312
313 Future, sym::future_trait, future_trait, TraitId, GenericRequirement::Exact(0);
314 CoroutineState, sym::coroutine_state, coroutine_state, EnumId, GenericRequirement::None;
315 Coroutine, sym::coroutine, coroutine_trait, TraitId, GenericRequirement::Minimum(1);
316 CoroutineReturn, sym::coroutine_return, coroutine_return_ty, TypeAliasId, GenericRequirement::None;
317 CoroutineYield, sym::coroutine_yield, coroutine_yield_ty, TypeAliasId, GenericRequirement::None;
318 Unpin, sym::unpin, unpin_trait, TraitId, GenericRequirement::None;
319 Pin, sym::pin, pin_type, StructId, GenericRequirement::None;
320
321 PartialEq, sym::eq, eq_trait, TraitId, GenericRequirement::Exact(1);
322 PartialOrd, sym::partial_ord, partial_ord_trait, TraitId, GenericRequirement::Exact(1);
323 CVoid, sym::c_void, c_void, EnumId, GenericRequirement::None;
324
325 Panic, sym::panic, panic_fn, FunctionId, GenericRequirement::Exact(0);
333 PanicNounwind, sym::panic_nounwind, panic_nounwind, FunctionId, GenericRequirement::Exact(0);
334 PanicFmt, sym::panic_fmt, panic_fmt, FunctionId, GenericRequirement::None;
335 PanicDisplay, sym::panic_display, panic_display, FunctionId, GenericRequirement::None;
336 ConstPanicFmt, sym::const_panic_fmt, const_panic_fmt, FunctionId, GenericRequirement::None;
337 PanicBoundsCheck, sym::panic_bounds_check, panic_bounds_check_fn, FunctionId, GenericRequirement::Exact(0);
338 PanicMisalignedPointerDereference, sym::panic_misaligned_pointer_dereference, panic_misaligned_pointer_dereference_fn, FunctionId, GenericRequirement::Exact(0);
339 PanicInfo, sym::panic_info, panic_info, StructId, GenericRequirement::None;
340 PanicLocation, sym::panic_location, panic_location, StructId, GenericRequirement::None;
341 PanicImpl, sym::panic_impl, panic_impl, FunctionId, GenericRequirement::None;
342 PanicCannotUnwind, sym::panic_cannot_unwind, panic_cannot_unwind, FunctionId, GenericRequirement::Exact(0);
343 PanicNullPointerDereference, sym::panic_null_pointer_dereference, panic_null_pointer_dereference, FunctionId, GenericRequirement::None;
344 BeginPanic, sym::begin_panic, begin_panic_fn, FunctionId, GenericRequirement::None;
346
347 FormatAlignment, sym::format_alignment, format_alignment, EnumId, GenericRequirement::None;
349 FormatArgument, sym::format_argument, format_argument, StructId, GenericRequirement::None;
350 FormatArguments, sym::format_arguments, format_arguments, StructId, GenericRequirement::None;
351 FormatCount, sym::format_count, format_count, EnumId, GenericRequirement::None;
352 FormatPlaceholder, sym::format_placeholder, format_placeholder, StructId, GenericRequirement::None;
353 FormatUnsafeArg, sym::format_unsafe_arg, format_unsafe_arg, StructId, GenericRequirement::None;
354
355 ExchangeMalloc, sym::exchange_malloc, exchange_malloc_fn, FunctionId, GenericRequirement::None;
356 BoxFree, sym::box_free, box_free_fn, FunctionId, GenericRequirement::Minimum(1);
357 DropInPlace, sym::drop_in_place, drop_in_place_fn, FunctionId, GenericRequirement::Minimum(1);
358 AllocLayout, sym::alloc_layout, alloc_layout, StructId, GenericRequirement::None;
359
360 Start, sym::start, start_fn, FunctionId, GenericRequirement::Exact(1);
361
362 EhPersonality, sym::eh_personality, eh_personality, FunctionId, GenericRequirement::None;
363 EhCatchTypeinfo, sym::eh_catch_typeinfo, eh_catch_typeinfo, StaticId, GenericRequirement::None;
364
365 OwnedBox, sym::owned_box, owned_box, StructId, GenericRequirement::Minimum(1);
366
367 PhantomData, sym::phantom_data, phantom_data, StructId, GenericRequirement::Exact(1);
368
369 ManuallyDrop, sym::manually_drop, manually_drop, StructId, GenericRequirement::None;
370
371 MaybeUninit, sym::maybe_uninit, maybe_uninit, UnionId, GenericRequirement::None;
372
373 AlignOffset, sym::align_offset, align_offset_fn, FunctionId, GenericRequirement::None;
375
376 Termination, sym::termination, termination, TraitId, GenericRequirement::None;
377
378 Try, sym::Try, try_trait, TraitId, GenericRequirement::None;
379
380 Tuple, sym::tuple_trait, tuple_trait, TraitId, GenericRequirement::Exact(0);
381
382 SliceLen, sym::slice_len_fn, slice_len_fn, FunctionId, GenericRequirement::None;
383
384 TryTraitFromResidual, sym::from_residual, from_residual_fn, FunctionId, GenericRequirement::None;
386 TryTraitFromOutput, sym::from_output, from_output_fn, FunctionId, GenericRequirement::None;
387 TryTraitBranch, sym::branch, branch_fn, FunctionId, GenericRequirement::None;
388 TryTraitFromYeet, sym::from_yeet, from_yeet_fn, FunctionId, GenericRequirement::None;
389
390 PointerLike, sym::pointer_like, pointer_like, TraitId, GenericRequirement::Exact(0);
391
392 ConstParamTy, sym::const_param_ty, const_param_ty_trait, TraitId, GenericRequirement::Exact(0);
393
394 Poll, sym::Poll, poll, EnumId, GenericRequirement::None;
395 PollReady, sym::Ready, poll_ready_variant, EnumVariantId, GenericRequirement::None;
396 PollPending, sym::Pending, poll_pending_variant, EnumVariantId, GenericRequirement::None;
397
398 ResumeTy, sym::ResumeTy, resume_ty, StructId, GenericRequirement::None;
401 GetContext, sym::get_context, get_context_fn, FunctionId, GenericRequirement::None;
402
403 Context, sym::Context, context, StructId, GenericRequirement::None;
404 FuturePoll, sym::poll, future_poll_fn, FunctionId, GenericRequirement::None;
405 FutureOutput, sym::future_output, future_output, TypeAliasId, GenericRequirement::None;
406
407 Option, sym::Option, option_type, EnumId, GenericRequirement::None;
408 OptionSome, sym::Some, option_some_variant, EnumVariantId, GenericRequirement::None;
409 OptionNone, sym::None, option_none_variant, EnumVariantId, GenericRequirement::None;
410
411 ResultOk, sym::Ok, result_ok_variant, EnumVariantId, GenericRequirement::None;
412 ResultErr, sym::Err, result_err_variant, EnumVariantId, GenericRequirement::None;
413
414 ControlFlowContinue, sym::Continue, cf_continue_variant, EnumVariantId, GenericRequirement::None;
415 ControlFlowBreak, sym::Break, cf_break_variant, EnumVariantId, GenericRequirement::None;
416
417 IntoFutureIntoFuture, sym::into_future, into_future_fn, FunctionId, GenericRequirement::None;
418 IntoIterIntoIter, sym::into_iter, into_iter_fn, FunctionId, GenericRequirement::None;
419 IteratorNext, sym::next, next_fn, FunctionId, GenericRequirement::None;
420 Iterator, sym::iterator, iterator, TraitId, GenericRequirement::None;
421
422 PinNewUnchecked, sym::new_unchecked, new_unchecked_fn, FunctionId, GenericRequirement::None;
423
424 RangeFrom, sym::RangeFrom, range_from_struct, StructId, GenericRequirement::None;
425 RangeFull, sym::RangeFull, range_full_struct, StructId, GenericRequirement::None;
426 RangeInclusiveStruct, sym::RangeInclusive, range_inclusive_struct, StructId, GenericRequirement::None;
427 RangeInclusiveNew, sym::range_inclusive_new, range_inclusive_new_method, FunctionId, GenericRequirement::None;
428 Range, sym::Range, range_struct, StructId, GenericRequirement::None;
429 RangeToInclusive, sym::RangeToInclusive, range_to_inclusive_struct, StructId, GenericRequirement::None;
430 RangeTo, sym::RangeTo, range_to_struct, StructId, GenericRequirement::None;
431
432 String, sym::String, string, StructId, GenericRequirement::None;
433 CStr, sym::CStr, c_str, StructId, GenericRequirement::None;
434 Ordering, sym::Ordering, ordering, EnumId, GenericRequirement::None;
435}