1use base_db::SourceDatabase;
6use hir_expand::name::Name;
7use intern::{Symbol, sym};
8use rustc_hash::FxHashMap;
9use rustc_type_ir::lang_items::{SolverAdtLangItem, SolverProjectionLangItem, SolverTraitLangItem};
10use stdx::impl_from;
11
12use crate::{
13 AdtId, AssocItemId, AttrDefId, ConstId, Crate, EnumId, EnumVariantId, FunctionId, ImplId,
14 ItemContainerId, MacroId, ModuleDefId, StaticId, StructId, TraitId, TypeAliasId, UnionId,
15 attrs::AttrFlags,
16 nameres::{DefMap, assoc::TraitItems, crate_def_map, crate_local_def_map},
17 unstable_features::UnstableFeatures,
18};
19
20#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
21pub enum LangItemTarget {
22 EnumId(EnumId),
23 FunctionId(FunctionId),
24 ImplId(ImplId),
25 StaticId(StaticId),
26 StructId(StructId),
27 UnionId(UnionId),
28 TypeAliasId(TypeAliasId),
29 TraitId(TraitId),
30 EnumVariantId(EnumVariantId),
31 ConstId(ConstId),
32 MacroId(MacroId),
33}
34
35impl_from!(
36 EnumId, FunctionId, ImplId, StaticId, StructId, UnionId, TypeAliasId, TraitId, EnumVariantId, ConstId, MacroId for LangItemTarget
37);
38
39#[salsa::tracked(returns(as_deref))]
41pub fn crate_lang_items(db: &dyn SourceDatabase, krate: Crate) -> Option<Box<LangItems>> {
42 if !UnstableFeatures::query(db, krate).lang_items {
43 return None;
45 }
46
47 let mut lang_items = LangItems::default();
48
49 let _p = tracing::info_span!("crate_lang_items_query", ?krate).entered();
50
51 let crate_def_map = crate_def_map(db, krate);
52 for (_, module_data) in crate_def_map.modules() {
53 for impl_def in module_data.scope.inherent_impls() {
54 lang_items.collect_lang_item(db, impl_def);
55 for &(_, assoc) in impl_def.impl_items(db).items.iter() {
56 match assoc {
57 AssocItemId::FunctionId(f) => lang_items.collect_lang_item(db, f),
58 AssocItemId::TypeAliasId(t) => lang_items.collect_lang_item(db, t),
59 AssocItemId::ConstId(c) => lang_items.collect_lang_item(db, c),
60 }
61 }
62 }
63
64 for def in module_data.scope.declarations() {
65 match def {
66 ModuleDefId::TraitId(trait_) => {
67 lang_items.collect_lang_item(db, trait_);
68 TraitItems::query(db, trait_).items.iter().for_each(|&(_, assoc_id)| {
69 match assoc_id {
70 AssocItemId::FunctionId(f) => {
71 lang_items.collect_lang_item(db, f);
72 }
73 AssocItemId::TypeAliasId(alias) => {
74 lang_items.collect_lang_item(db, alias)
75 }
76 AssocItemId::ConstId(c) => lang_items.collect_lang_item(db, c),
77 }
78 });
79 }
80 ModuleDefId::AdtId(AdtId::EnumId(e)) => {
81 lang_items.collect_lang_item(db, e);
82 e.enum_variants(db).variants.values().for_each(|&(id, _)| {
83 lang_items.collect_lang_item(db, id);
84 });
85 }
86 ModuleDefId::AdtId(AdtId::StructId(s)) => {
87 lang_items.collect_lang_item(db, s);
88 }
89 ModuleDefId::AdtId(AdtId::UnionId(u)) => {
90 lang_items.collect_lang_item(db, u);
91 }
92 ModuleDefId::FunctionId(f) => {
93 lang_items.collect_lang_item(db, f);
94 }
95 ModuleDefId::StaticId(s) => {
96 lang_items.collect_lang_item(db, s);
97 }
98 ModuleDefId::TypeAliasId(t) => {
99 lang_items.collect_lang_item(db, t);
100 }
101 ModuleDefId::ConstId(c) => lang_items.collect_lang_item(db, c),
102 _ => {}
103 }
104 }
105 }
106
107 if matches!(krate.data(db).origin, base_db::CrateOrigin::Lang(base_db::LangCrateOrigin::Core)) {
108 lang_items.fill_non_lang_core_items(db, crate_def_map);
109 }
110
111 lang_items.resolve_manually(db);
112
113 if lang_items.is_empty() {
114 None
115 } else {
116 lang_items.shrink_to_fit();
117 Some(Box::new(lang_items))
118 }
119}
120
121#[salsa::tracked(returns(deref))]
124fn crate_extern_prelude(db: &dyn SourceDatabase, start_crate: Crate) -> Box<[Crate]> {
125 crate_local_def_map(db, start_crate)
126 .local(db)
127 .extern_prelude()
128 .map(|(_, (module, _))| module.krate(db))
129 .filter(|&krate| {
130 krate != start_crate
133 })
134 .collect()
135}
136
137#[salsa::tracked(returns(ref))]
140pub fn lang_items(db: &dyn SourceDatabase, start_crate: Crate) -> LangItems {
141 let _p = tracing::debug_span!("lang_items_query", ?start_crate).entered();
142
143 let mut result = crate_lang_items(db, start_crate).cloned().unwrap_or_default();
144
145 for &krate in crate_extern_prelude(db, start_crate) {
153 result.merge_prefer_other(lang_items(db, krate));
154 }
155
156 result
157}
158
159impl LangItems {
160 fn collect_lang_item<T>(&mut self, db: &dyn SourceDatabase, item: T)
161 where
162 T: Into<AttrDefId> + Into<LangItemTarget> + Copy,
163 {
164 if let Some(lang_item) = AttrFlags::lang_item(db, item.into()) {
165 tracing::trace!("found lang item `{lang_item}`");
166 self.assign_lang_item(lang_item, item.into());
167 }
168 }
169}
170
171fn resolve_core_trait(
172 db: &dyn SourceDatabase,
173 core_def_map: &DefMap,
174 modules: &[Symbol],
175 name: Symbol,
176) -> Option<TraitId> {
177 let mut current = &core_def_map[core_def_map.root];
178 for module in modules {
179 let Some((ModuleDefId::ModuleId(cur), _)) =
180 current.scope.type_(&Name::new_symbol_root(module.clone()))
181 else {
182 return None;
183 };
184 if cur.krate(db) != core_def_map.krate() || cur.block(db) != core_def_map.block_id() {
185 return None;
186 }
187 current = &core_def_map[cur];
188 }
189 let Some((ModuleDefId::TraitId(trait_), _)) = current.scope.type_(&Name::new_symbol_root(name))
190 else {
191 return None;
192 };
193 Some(trait_)
194}
195
196fn resolve_core_macro(
197 db: &dyn SourceDatabase,
198 core_def_map: &DefMap,
199 modules: &[Symbol],
200 name: Symbol,
201) -> Option<MacroId> {
202 let mut current = &core_def_map[core_def_map.root];
203 for module in modules {
204 let Some((ModuleDefId::ModuleId(cur), _)) =
205 current.scope.type_(&Name::new_symbol_root(module.clone()))
206 else {
207 return None;
208 };
209 if cur.krate(db) != core_def_map.krate() || cur.block(db) != core_def_map.block_id() {
210 return None;
211 }
212 current = &core_def_map[cur];
213 }
214 current.scope.makro(&Name::new_symbol_root(name))
215}
216
217impl LangItems {
218 fn resolve_manually(&mut self, db: &dyn SourceDatabase) {
219 let parent_trait =
220 |lang_item: &mut Option<TraitId>, def: Option<FunctionId>| match def?.loc(db).container
221 {
222 ItemContainerId::TraitId(trait_) => {
223 *lang_item = Some(trait_);
224 Some(trait_)
225 }
226 _ => None,
227 };
228 let assoc_types =
229 |trait_: TraitId, assoc_types: &mut [(&mut Option<TypeAliasId>, Symbol)]| {
230 let trait_items = trait_.trait_items(db);
231 for (assoc_type, name) in assoc_types {
232 **assoc_type =
233 trait_items.associated_type_by_name(&Name::new_symbol_root(name.clone()));
234 }
235 };
236 let methods = |trait_: TraitId, assoc_types: &mut [(&mut Option<FunctionId>, Symbol)]| {
237 let trait_items = trait_.trait_items(db);
238 for (assoc_type, name) in assoc_types {
239 **assoc_type = trait_items.method_by_name(&Name::new_symbol_root(name.clone()));
240 }
241 };
242 (|| {
243 let into_future = parent_trait(&mut self.IntoFuture, self.IntoFutureIntoFuture)?;
244 assoc_types(into_future, &mut [(&mut self.IntoFutureOutput, sym::Output)]);
245 Some(())
246 })();
247
248 (|| {
249 let into_iterator = parent_trait(&mut self.IntoIterator, self.IntoIterIntoIter)?;
250 assoc_types(
251 into_iterator,
252 &mut [
253 (&mut self.IntoIteratorItem, sym::Item),
254 (&mut self.IntoIterIntoIterType, sym::IntoIter),
255 ],
256 );
257 Some(())
258 })();
259
260 (|| {
261 assoc_types(self.Iterator?, &mut [(&mut self.IteratorItem, sym::Item)]);
262 Some(())
263 })();
264
265 (|| {
266 assoc_types(self.AsyncIterator?, &mut [(&mut self.AsyncIteratorItem, sym::Item)]);
267 Some(())
268 })();
269
270 for (op_trait, op_method, op_method_name) in [
271 (self.Fn, &mut self.Fn_call, sym::call),
272 (self.FnMut, &mut self.FnMut_call_mut, sym::call_mut),
273 (self.FnOnce, &mut self.FnOnce_call_once, sym::call_once),
274 (self.AsyncFn, &mut self.AsyncFn_async_call, sym::async_call),
275 (self.AsyncFnMut, &mut self.AsyncFnMut_async_call_mut, sym::async_call_mut),
276 (self.AsyncFnOnce, &mut self.AsyncFnOnce_async_call_once, sym::async_call_once),
277 (self.Not, &mut self.Not_not, sym::not),
278 (self.Neg, &mut self.Neg_neg, sym::neg),
279 (self.Add, &mut self.Add_add, sym::add),
280 (self.Mul, &mut self.Mul_mul, sym::mul),
281 (self.Sub, &mut self.Sub_sub, sym::sub),
282 (self.Div, &mut self.Div_div, sym::div),
283 (self.Rem, &mut self.Rem_rem, sym::rem),
284 (self.Shl, &mut self.Shl_shl, sym::shl),
285 (self.Shr, &mut self.Shr_shr, sym::shr),
286 (self.BitXor, &mut self.BitXor_bitxor, sym::bitxor),
287 (self.BitOr, &mut self.BitOr_bitor, sym::bitor),
288 (self.BitAnd, &mut self.BitAnd_bitand, sym::bitand),
289 (self.AddAssign, &mut self.AddAssign_add_assign, sym::add_assign),
290 (self.MulAssign, &mut self.MulAssign_mul_assign, sym::mul_assign),
291 (self.SubAssign, &mut self.SubAssign_sub_assign, sym::sub_assign),
292 (self.DivAssign, &mut self.DivAssign_div_assign, sym::div_assign),
293 (self.RemAssign, &mut self.RemAssign_rem_assign, sym::rem_assign),
294 (self.ShlAssign, &mut self.ShlAssign_shl_assign, sym::shl_assign),
295 (self.ShrAssign, &mut self.ShrAssign_shr_assign, sym::shr_assign),
296 (self.BitXorAssign, &mut self.BitXorAssign_bitxor_assign, sym::bitxor_assign),
297 (self.BitOrAssign, &mut self.BitOrAssign_bitor_assign, sym::bitor_assign),
298 (self.BitAndAssign, &mut self.BitAndAssign_bitand_assign, sym::bitand_assign),
299 (self.Debug, &mut self.Debug_fmt, sym::fmt),
300 (self.Deref, &mut self.Deref_deref, sym::deref),
301 (self.DerefMut, &mut self.DerefMut_deref_mut, sym::deref_mut),
302 (self.Index, &mut self.Index_index, sym::index),
303 (self.IndexMut, &mut self.IndexMut_index_mut, sym::index_mut),
304 ] {
305 (|| {
306 methods(op_trait?, &mut [(op_method, op_method_name)]);
307 Some(())
308 })();
309 }
310 (|| {
311 methods(
312 self.PartialEq?,
313 &mut [(&mut self.PartialEq_eq, sym::eq), (&mut self.PartialEq_ne, sym::ne)],
314 );
315 Some(())
316 })();
317 (|| {
318 methods(
319 self.PartialOrd?,
320 &mut [
321 (&mut self.PartialOrd_le, sym::le),
322 (&mut self.PartialOrd_lt, sym::lt),
323 (&mut self.PartialOrd_ge, sym::ge),
324 (&mut self.PartialOrd_gt, sym::gt),
325 ],
326 );
327 Some(())
328 })();
329 (|| {
330 methods(
331 self.Drop?,
332 &mut [(&mut self.Drop_drop, sym::drop), (&mut self.Drop_pin_drop, sym::pin_drop)],
333 );
334 Some(())
335 })();
336 }
337
338 #[inline]
339 pub fn get_solver_trait(&self, lang_item: SolverTraitLangItem) -> Option<TraitId> {
340 self.solver_trait[lang_item as usize]
341 }
342
343 #[inline]
344 pub fn get_solver_projection(
345 &self,
346 lang_item: SolverProjectionLangItem,
347 ) -> Option<TypeAliasId> {
348 self.solver_projection[lang_item as usize]
349 }
350
351 #[inline]
352 pub fn get_solver_adt(&self, lang_item: SolverAdtLangItem) -> Option<AdtId> {
353 self.solver_adt[lang_item as usize]
354 }
355
356 #[inline]
357 pub fn get_reverse_solver_trait(&self, trait_: TraitId) -> Option<SolverTraitLangItem> {
358 self.reverse_solver_trait.get(&trait_).copied()
359 }
360
361 #[inline]
362 pub fn get_reverse_solver_adt(&self, adt: AdtId) -> Option<SolverAdtLangItem> {
363 self.reverse_solver_adt.get(&adt).copied()
364 }
365
366 #[inline]
367 pub fn get_reverse_solver_projection(
368 &self,
369 projection: TypeAliasId,
370 ) -> Option<SolverProjectionLangItem> {
371 self.reverse_solver_projection.get(&projection).copied()
372 }
373
374 fn shrink_to_fit(&mut self) {
375 let Self { reverse_solver_adt, reverse_solver_projection, reverse_solver_trait, .. } = self;
376 reverse_solver_adt.shrink_to_fit();
377 reverse_solver_projection.shrink_to_fit();
378 reverse_solver_trait.shrink_to_fit();
379 }
380
381 fn assign_solver_trait(&mut self, lang_item: SolverTraitLangItem, def: TraitId) {
382 self.solver_trait[lang_item as usize] = Some(def);
383 self.reverse_solver_trait.insert(def, lang_item);
384 }
385
386 fn assign_solver_projection(&mut self, lang_item: SolverProjectionLangItem, def: TypeAliasId) {
387 self.solver_projection[lang_item as usize] = Some(def);
388 self.reverse_solver_projection.insert(def, lang_item);
389 }
390
391 fn assign_solver_adt(&mut self, lang_item: SolverAdtLangItem, def: impl Into<AdtId>) {
392 let def = def.into();
393 self.solver_adt[lang_item as usize] = Some(def);
394 self.reverse_solver_adt.insert(def, lang_item);
395 }
396}
397
398#[salsa::tracked(returns(as_deref))]
399pub fn crate_notable_traits(db: &dyn SourceDatabase, krate: Crate) -> Option<Box<[TraitId]>> {
400 let mut traits = Vec::new();
401
402 let crate_def_map = crate_def_map(db, krate);
403
404 for (_, module_data) in crate_def_map.modules() {
405 for def in module_data.scope.declarations() {
406 if let ModuleDefId::TraitId(trait_) = def
407 && AttrFlags::query(db, trait_.into()).contains(AttrFlags::IS_DOC_NOTABLE_TRAIT)
408 {
409 traits.push(trait_);
410 }
411 }
412 }
413
414 if traits.is_empty() { None } else { Some(traits.into_iter().collect()) }
415}
416
417macro_rules! assign_solver {
418 ( $self:ident, $def:ident, $lang_item:ident, TraitId, solver ) => {
419 $self.assign_solver_trait(SolverTraitLangItem::$lang_item, $def);
420 };
421 ( $self:ident, $def:ident, $lang_item:ident, TypeAliasId, solver ) => {
422 $self.assign_solver_projection(SolverProjectionLangItem::$lang_item, $def);
423 };
424 ( $self:ident, $def:ident, $lang_item:ident, StructId, solver ) => {
425 $self.assign_solver_adt(SolverAdtLangItem::$lang_item, $def);
426 };
427 ( $self:ident, $def:ident, $lang_item:ident, EnumId, solver ) => {
428 $self.assign_solver_adt(SolverAdtLangItem::$lang_item, $def);
429 };
430 ( $self:ident, $def:ident, $lang_item:ident, UnionId, solver ) => {
431 $self.assign_solver_adt(SolverAdtLangItem::$lang_item, $def);
432 };
433 ( $self:ident, $def:ident, $lang_item:ident, $ty:ident ) => {};
434}
435
436macro_rules! solver_exhaustiveness_check {
437 (
438 $dollar:tt, $solver_ty:ident, $id_ty:ident,
439 [ $($id_tys:ident),* ]
440
441 $( $lang_item:ident, $target:ident $(, $solver:ident)?; )*
442 ) => {
443 const _: () = {
444 #[expect(unreachable_patterns, dead_code)]
445 fn exhaustiveness_check(lang_item: $solver_ty) {
446 macro_rules! one_variant {
447 $(
448 (
449 $dollar lang_item:ident, $id_tys, solver
450 ) => {
451 ($solver_ty::$dollar lang_item, true)
452 };
453 )*
454 ( $dollar($t:tt)* ) => {
455 (_, false)
456 };
457 }
458
459 match (lang_item, true) {
460 $(
461 one_variant!( $lang_item, $target $(, $solver )? ) => {}
462 )*
463 }
464 }
465 };
466 };
467}
468
469macro_rules! get_solver_count {
470 (
471 $dollar:tt, $solver_ty:ident,
472 [ $($id_tys:ident),* ]
473
474 $( $lang_item:ident, $target:ident $(, $solver:ident)?; )*
475 ) => {{
476 let mut max_discriminant = 0;
477 macro_rules! one_variant {
478 $(
479 (
480 $dollar lang_item:ident, $id_tys, solver
481 ) => {
482 if $solver_ty::$dollar lang_item as usize > max_discriminant {
483 max_discriminant = $solver_ty::$dollar lang_item as usize;
484 }
485 };
486 )*
487 ( $dollar($t:tt)* ) => {};
488 }
489 $(
490 one_variant!($lang_item, $target $(, $solver)?);
491 )*
492 max_discriminant + 1
493 }};
494}
495
496fn merge_array_prefer_other<T: Copy, const N: usize>(
497 this: &mut [Option<T>; N],
498 other: &[Option<T>; N],
499) {
500 for (this, other) in std::iter::zip(this, other) {
501 *this = other.or(*this);
502 }
503}
504
505macro_rules! language_item_table {
506 (
507 $dollar:tt
508 $LangItems:ident =>
509 $( $lang_item:ident, $module:ident :: $name:ident, $target:ident $(, $solver:ident)?; )*
510
511 @non_lang_core_traits:
512
513 $( core::$($non_lang_trait_module:ident)::*, $non_lang_trait:ident; )*
514
515 @non_lang_core_macros:
516
517 $( core::$($non_lang_macro_module:ident)::*, $non_lang_macro:ident, $non_lang_macro_field:ident; )*
518
519 @resolve_manually:
520
521 $( $resolve_manually:ident, $resolve_manually_type:ident; )*
522 ) => {
523 const SOLVER_TRAITS_LEN: usize = get_solver_count! {
524 $dollar, SolverTraitLangItem,
525 [ TraitId ]
526
527 $( $lang_item, $target $(, $solver)?; )*
528 };
529 const SOLVER_PROJECTIONS_LEN: usize = get_solver_count! {
530 $dollar, SolverProjectionLangItem,
531 [ TypeAliasId ]
532
533 $( $lang_item, $target $(, $solver)?; )*
534 };
535 const SOLVER_ADTS_LEN: usize = get_solver_count! {
536 $dollar, SolverAdtLangItem,
537 [ StructId, EnumId, UnionId ]
538
539 $( $lang_item, $target $(, $solver)?; )*
540 };
541
542 #[allow(non_snake_case)] #[derive(Default, Clone)]
544 pub struct $LangItems {
545 $(
546 pub $lang_item: Option<$target>,
547 )*
548 $(
549 pub $non_lang_trait: Option<TraitId>,
550 )*
551 $(
552 pub $non_lang_macro_field: Option<MacroId>,
553 )*
554 $(
555 pub $resolve_manually: Option<$resolve_manually_type>,
556 )*
557
558 solver_trait: [Option<TraitId>; SOLVER_TRAITS_LEN],
559 solver_adt: [Option<AdtId>; SOLVER_ADTS_LEN],
560 solver_projection: [Option<TypeAliasId>; SOLVER_PROJECTIONS_LEN],
561
562 reverse_solver_trait: FxHashMap<TraitId, SolverTraitLangItem>,
563 reverse_solver_adt: FxHashMap<AdtId, SolverAdtLangItem>,
564 reverse_solver_projection: FxHashMap<TypeAliasId, SolverProjectionLangItem>,
565 }
566
567 impl std::fmt::Debug for $LangItems {
568 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
569 let mut debug = f.debug_struct(stringify!($LangItems));
570 let Self {
571 $( $lang_item, )*
572 $( $non_lang_trait, )*
573 $( $non_lang_macro_field, )*
574 $( $resolve_manually, )*
575
576 solver_trait: _,
577 solver_adt: _,
578 solver_projection: _,
579 reverse_solver_trait: _,
580 reverse_solver_adt: _,
581 reverse_solver_projection: _,
582 } = self;
583 $(
584 if let Some(it) = $lang_item {
585 debug.field(stringify!($lang_item), it);
586 }
587 )*
588 $(
589 if let Some(it) = $non_lang_trait {
590 debug.field(stringify!($non_lang_trait), it);
591 }
592 )*
593 $(
594 if let Some(it) = $non_lang_macro_field {
595 debug.field(stringify!($non_lang_macro_field), it);
596 }
597 )*
598 $(
599 if let Some(it) = $resolve_manually {
600 debug.field(stringify!($resolve_manually), it);
601 }
602 )*
603 debug.finish()
604 }
605 }
606
607 impl PartialEq for $LangItems {
608 fn eq(&self, other: &Self) -> bool {
609 let Self {
610 $( $lang_item, )*
611 $( $non_lang_trait, )*
612 $( $non_lang_macro_field, )*
613 $( $resolve_manually, )*
614
615 solver_trait: _,
616 solver_adt: _,
617 solver_projection: _,
618 reverse_solver_trait: _,
619 reverse_solver_adt: _,
620 reverse_solver_projection: _,
621 } = *self;
622
623 true
624 $( && $lang_item == other.$lang_item )*
625 $( && $non_lang_trait == other.$non_lang_trait )*
626 $( && $non_lang_macro_field == other.$non_lang_macro_field )*
627 $( && $resolve_manually == other.$resolve_manually )*
628 }
629 }
630
631 impl Eq for $LangItems {}
632
633 impl LangItems {
634 fn is_empty(&self) -> bool {
635 let Self {
636 $( $lang_item, )*
637 $( $non_lang_trait, )*
638 $( $non_lang_macro_field, )*
639 $( $resolve_manually, )*
640
641 solver_trait: _,
642 solver_adt: _,
643 solver_projection: _,
644 reverse_solver_trait: _,
645 reverse_solver_adt: _,
646 reverse_solver_projection: _,
647 } = *self;
648
649 true
650 $( && $lang_item.is_none() )*
651 $( && $non_lang_trait.is_none() )*
652 $( && $non_lang_macro_field.is_none() )*
653 $( && $resolve_manually.is_none() )*
654 }
655
656 fn merge_prefer_other(&mut self, other: &Self) {
658 $( self.$lang_item = other.$lang_item.or(self.$lang_item); )*
659 $( self.$non_lang_trait = other.$non_lang_trait.or(self.$non_lang_trait); )*
660 $( self.$non_lang_macro_field = other.$non_lang_macro_field.or(self.$non_lang_macro_field); )*
661 $( self.$resolve_manually = other.$resolve_manually.or(self.$resolve_manually); )*
662
663 merge_array_prefer_other(&mut self.solver_trait, &other.solver_trait);
664 merge_array_prefer_other(&mut self.solver_adt, &other.solver_adt);
665 merge_array_prefer_other(&mut self.solver_projection, &other.solver_projection);
666
667 self.reverse_solver_trait.extend(&other.reverse_solver_trait);
668 self.reverse_solver_adt.extend(&other.reverse_solver_adt);
669 self.reverse_solver_projection.extend(&other.reverse_solver_projection);
670 }
671
672 fn assign_lang_item(&mut self, name: Symbol, target: LangItemTarget) {
673 match name {
674 $(
675 _ if name == $module::$name => {
676 if let LangItemTarget::$target(target) = target {
677 self.$lang_item = Some(target);
678
679 assign_solver!(self, target, $lang_item, $target $(, $solver)? );
680 }
681 }
682 )*
683 _ => {}
684 }
685 }
686
687 fn fill_non_lang_core_items(&mut self, db: &dyn SourceDatabase, core_def_map: &DefMap) {
688 $( self.$non_lang_trait = resolve_core_trait(db, core_def_map, &[ $(sym::$non_lang_trait_module),* ], sym::$non_lang_trait); )*
689 $( self.$non_lang_macro_field = resolve_core_macro(db, core_def_map, &[ $(sym::$non_lang_macro_module),* ], sym::$non_lang_macro); )*
690 }
691 }
692
693 solver_exhaustiveness_check! {
694 $dollar, SolverTraitLangItem, TraitId,
695 [ TraitId ]
696
697 $( $lang_item, $target $(, $solver)?; )*
698 }
699
700 solver_exhaustiveness_check! {
701 $dollar, SolverProjectionLangItem, TypeAliasId,
702 [ TypeAliasId ]
703
704 $( $lang_item, $target $(, $solver)?; )*
705 }
706
707 solver_exhaustiveness_check! {
708 $dollar, SolverAdtLangItem, AdtId,
709 [ StructId, EnumId, UnionId ]
710
711 $( $lang_item, $target $(, $solver)?; )*
712 }
713
714 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
715 #[allow(non_camel_case_types)]
716 pub enum LangItemEnum {
717 $(
718 $lang_item,
719 )*
720 $( $non_lang_trait, )*
721 $( $non_lang_macro_field, )*
722 $( $resolve_manually, )*
723 }
724
725 impl LangItemEnum {
726 #[inline]
727 pub fn from_lang_items(self, lang_items: &LangItems) -> Option<LangItemTarget> {
728 match self {
729 $( LangItemEnum::$lang_item => lang_items.$lang_item.map(Into::into), )*
730 $( LangItemEnum::$non_lang_trait => lang_items.$non_lang_trait.map(Into::into), )*
731 $( LangItemEnum::$non_lang_macro_field => lang_items.$non_lang_macro_field.map(Into::into), )*
732 $( LangItemEnum::$resolve_manually => lang_items.$resolve_manually.map(Into::into), )*
733 }
734 }
735
736 #[inline]
737 pub fn from_symbol(symbol: &Symbol) -> Option<Self> {
738 match symbol {
739 $( _ if *symbol == $module::$name => Some(Self::$lang_item), )*
740 _ => None,
741 }
742 }
743 }
744 }
745}
746
747language_item_table! { $ LangItems =>
748Sized, sym::sized, TraitId, solver;
750 MetaSized, sym::meta_sized, TraitId, solver;
751 PointeeSized, sym::pointee_sized, TraitId, solver;
752 Unsize, sym::unsize, TraitId, solver;
753 StructuralPeq, sym::structural_peq, TraitId;
755 StructuralTeq, sym::structural_teq, TraitId;
757 Copy, sym::copy, TraitId, solver;
758 UseCloned, sym::use_cloned, TraitId;
759 Clone, sym::clone, TraitId, solver;
760 TrivialClone, sym::trivial_clone, TraitId, solver;
761 Sync, sym::sync, TraitId;
762 DiscriminantKind, sym::discriminant_kind, TraitId, solver;
763 Discriminant, sym::discriminant_type, TypeAliasId;
765
766 PointeeTrait, sym::pointee_trait, TraitId, solver;
767 Metadata, sym::metadata_type, TypeAliasId, solver;
768 DynMetadata, sym::dyn_metadata, StructId, solver;
769
770 Freeze, sym::freeze, TraitId;
771
772 NonNull, sym::non_null, StructId;
773
774 FnPtrTrait, sym::fn_ptr_trait, TraitId, solver;
775 FnPtrAsPtr, sym::fn_ptr_as_ptr, FunctionId;
776 FnPtrFromPtr, sym::fn_ptr_from_ptr, FunctionId;
777
778 Drop, sym::drop, TraitId, solver;
779 Destruct, sym::destruct, TraitId, solver;
780 BikeshedGuaranteedNoDrop,sym::bikeshed_guaranteed_no_drop, TraitId, solver;
781
782 CoerceUnsized, sym::coerce_unsized, TraitId;
783 DispatchFromDyn, sym::dispatch_from_dyn, TraitId;
784 Reborrow, sym::reborrow, TraitId;
785 CoerceShared, sym::coerce_shared, TraitId;
786
787 TransmuteOpts, sym::transmute_opts, StructId;
789 TransmuteTrait, sym::transmute_trait, TraitId, solver;
790
791 Add, sym::add, TraitId;
792 Sub, sym::sub, TraitId;
793 Mul, sym::mul, TraitId;
794 Div, sym::div, TraitId;
795 Rem, sym::rem, TraitId;
796 Neg, sym::neg, TraitId;
797 Not, sym::not, TraitId;
798 BitXor, sym::bitxor, TraitId;
799 BitAnd, sym::bitand, TraitId;
800 BitOr, sym::bitor, TraitId;
801 Shl, sym::shl, TraitId;
802 Shr, sym::shr, TraitId;
803 AddAssign, sym::add_assign, TraitId;
804 SubAssign, sym::sub_assign, TraitId;
805 MulAssign, sym::mul_assign, TraitId;
806 DivAssign, sym::div_assign, TraitId;
807 RemAssign, sym::rem_assign, TraitId;
808 BitXorAssign, sym::bitxor_assign, TraitId;
809 BitAndAssign, sym::bitand_assign, TraitId;
810 BitOrAssign, sym::bitor_assign, TraitId;
811 ShlAssign, sym::shl_assign, TraitId;
812 ShrAssign, sym::shr_assign, TraitId;
813 Index, sym::index, TraitId;
814 IndexMut, sym::index_mut, TraitId;
815
816 UnsafeCell, sym::unsafe_cell, StructId;
817 UnsafePinned, sym::unsafe_pinned, StructId;
818 VaList, sym::va_list, StructId;
819
820 Deref, sym::deref, TraitId;
821 DerefMut, sym::deref_mut, TraitId;
822 DerefPure, sym::deref_pure, TraitId;
823 DerefTarget, sym::deref_target, TypeAliasId;
824 Receiver, sym::receiver, TraitId;
825 ReceiverTarget, sym::receiver_target, TypeAliasId;
826
827 Fn, sym::fn_, TraitId, solver;
828 FnMut, sym::fn_mut, TraitId, solver;
829 FnOnce, sym::fn_once, TraitId, solver;
830 AsyncFn, sym::async_fn, TraitId, solver;
831 AsyncFnMut, sym::async_fn_mut, TraitId, solver;
832 AsyncFnOnce, sym::async_fn_once, TraitId, solver;
833 AsyncFnKindHelper, sym::async_fn_kind_helper,TraitId, solver;
834 AsyncFnKindUpvars, sym::async_fn_kind_upvars,TypeAliasId, solver;
835
836 CallRefFuture, sym::call_ref_future, TypeAliasId, solver;
837 CallOnceFuture, sym::call_once_future, TypeAliasId, solver;
838 AsyncFnOnceOutput, sym::async_fn_once_output, TypeAliasId, solver;
839
840 FnOnceOutput, sym::fn_once_output, TypeAliasId;
841
842 Future, sym::future_trait, TraitId, solver;
843 AsyncIterator, sym::async_iterator, TraitId, solver;
844 CoroutineState, sym::coroutine_state, EnumId;
845 Coroutine, sym::coroutine, TraitId, solver;
846 CoroutineReturn, sym::coroutine_return, TypeAliasId, solver;
847 CoroutineYield, sym::coroutine_yield, TypeAliasId, solver;
848 Unpin, sym::unpin, TraitId, solver;
849 Pin, sym::pin, StructId;
850
851 AsyncGenReady, sym::AsyncGenReady, FunctionId;
852
853 PartialEq, sym::eq, TraitId;
854 PartialOrd, sym::partial_ord, TraitId;
855 CVoid, sym::c_void, EnumId;
856
857 Panic, sym::panic, FunctionId;
865 PanicNounwind, sym::panic_nounwind, FunctionId;
866 PanicFmt, sym::panic_fmt, FunctionId;
867 PanicDisplay, sym::panic_display, FunctionId;
868 ConstPanicFmt, sym::const_panic_fmt, FunctionId;
869 PanicBoundsCheck, sym::panic_bounds_check, FunctionId;
870 PanicMisalignedPointerDereference, sym::panic_misaligned_pointer_dereference, FunctionId;
871 PanicInfo, sym::panic_info, StructId;
872 PanicLocation, sym::panic_location, StructId;
873 PanicImpl, sym::panic_impl, FunctionId;
874 PanicCannotUnwind, sym::panic_cannot_unwind, FunctionId;
875 PanicNullPointerDereference, sym::panic_null_pointer_dereference, FunctionId;
876 BeginPanic, sym::begin_panic, FunctionId;
878
879 FormatAlignment, sym::format_alignment, EnumId;
881 FormatArgument, sym::format_argument, StructId;
882 FormatArguments, sym::format_arguments, StructId;
883 FormatCount, sym::format_count, EnumId;
884 FormatPlaceholder, sym::format_placeholder, StructId;
885 FormatUnsafeArg, sym::format_unsafe_arg, StructId;
886
887 ExchangeMalloc, sym::exchange_malloc, FunctionId;
888 BoxFree, sym::box_free, FunctionId;
889 DropInPlace, sym::drop_in_place, FunctionId;
890 AllocLayout, sym::alloc_layout, StructId;
891
892 Start, sym::start, FunctionId;
893
894 EhPersonality, sym::eh_personality, FunctionId;
895 EhCatchTypeinfo, sym::eh_catch_typeinfo, StaticId;
896
897 OwnedBox, sym::owned_box, StructId;
898
899 PhantomData, sym::phantom_data, StructId;
900
901 ManuallyDrop, sym::manually_drop, StructId;
902
903 MaybeUninit, sym::maybe_uninit, UnionId;
904
905 AlignOffset, sym::align_offset, FunctionId;
907
908 Termination, sym::termination, TraitId;
909
910 Try, sym::Try, TraitId;
911
912 Tuple, sym::tuple_trait, TraitId, solver;
913
914 SliceLen, sym::slice_len_fn, FunctionId;
915
916 TryTraitFromResidual, sym::from_residual, FunctionId;
918 TryTraitFromOutput, sym::from_output, FunctionId;
919 TryTraitBranch, sym::branch, FunctionId;
920 TryTraitFromYeet, sym::from_yeet, FunctionId;
921 ResidualIntoTryType, sym::into_try_type, FunctionId;
922
923 PointerLike, sym::pointer_like, TraitId;
924
925 ConstParamTy, sym::const_param_ty, TraitId;
926
927 Poll, sym::Poll, EnumId, solver;
928 PollReady, sym::Ready, EnumVariantId;
929 PollPending, sym::Pending, EnumVariantId;
930
931 ResumeTy, sym::ResumeTy, StructId;
934 GetContext, sym::get_context, FunctionId;
935
936 Context, sym::Context, StructId;
937 FuturePoll, sym::poll, FunctionId;
938 FutureOutput, sym::future_output, TypeAliasId, solver;
939
940 Option, sym::Option, EnumId, solver;
941 OptionSome, sym::Some, EnumVariantId;
942 OptionNone, sym::None, EnumVariantId;
943
944 ResultOk, sym::Ok, EnumVariantId;
945 ResultErr, sym::Err, EnumVariantId;
946
947 ControlFlowContinue, sym::Continue, EnumVariantId;
948 ControlFlowBreak, sym::Break, EnumVariantId;
949
950 IntoFutureIntoFuture, sym::into_future, FunctionId;
951 IntoIterIntoIter, sym::into_iter, FunctionId;
952 IteratorNext, sym::next, FunctionId;
953 Iterator, sym::iterator, TraitId, solver;
954 FusedIterator, sym::fused_iterator, TraitId, solver;
955
956 PinNewUnchecked, sym::new_unchecked, FunctionId;
957
958 RangeFrom, sym::RangeFrom, StructId;
959 RangeFull, sym::RangeFull, StructId;
960 RangeInclusiveStruct, sym::RangeInclusive, StructId;
961 RangeInclusiveNew, sym::range_inclusive_new, FunctionId;
962 Range, sym::Range, StructId;
963 RangeToInclusive, sym::RangeToInclusive, StructId;
964 RangeTo, sym::RangeTo, StructId;
965
966 RangeFromCopy, sym::RangeFromCopy, StructId;
967 RangeInclusiveCopy, sym::RangeInclusiveCopy, StructId;
968 RangeCopy, sym::RangeCopy, StructId;
969 RangeToInclusiveCopy, sym::RangeToInclusiveCopy, StructId;
970
971 String, sym::String, StructId;
972 CStr, sym::CStr, StructId;
973 Ordering, sym::Ordering, EnumId;
974
975 Field, sym::field, TraitId, solver;
976 FieldBase, sym::field_base, TypeAliasId, solver;
977 FieldType, sym::field_type, TypeAliasId, solver;
978
979 RangeMin, sym::RangeMin, ConstId;
980 RangeMax, sym::RangeMax, ConstId;
981 RangeSub, sym::RangeSub, FunctionId;
982
983 @non_lang_core_traits:
984 core::default, Default;
985 core::fmt, Debug;
986 core::hash, Hash;
987 core::cmp, Ord;
988 core::cmp, Eq;
989
990 @non_lang_core_macros:
991 core::default, Default, DefaultDerive;
992 core::fmt, Debug, DebugDerive;
993 core::hash, Hash, HashDerive;
994 core::cmp, PartialOrd, PartialOrdDerive;
995 core::cmp, Ord, OrdDerive;
996 core::cmp, PartialEq, PartialEqDerive;
997 core::cmp, Eq, EqDerive;
998 core::marker, CoercePointee, CoercePointeeDerive;
999 core::marker, CoerceShared, CoerceSharedDerive;
1000 core::marker, Copy, CopyDerive;
1001 core::marker, Reborrow, ReborrowDerive;
1002 core::clone, Clone, CloneDerive;
1003
1004 @resolve_manually:
1005
1006 IntoFuture, TraitId;
1007 IntoFutureOutput, TypeAliasId;
1008 IntoIterator, TraitId;
1009 IntoIteratorItem, TypeAliasId;
1010 IntoIterIntoIterType, TypeAliasId;
1011 IteratorItem, TypeAliasId;
1012 AsyncIteratorItem, TypeAliasId;
1013
1014 Fn_call, FunctionId;
1015 FnMut_call_mut, FunctionId;
1016 FnOnce_call_once, FunctionId;
1017 AsyncFn_async_call, FunctionId;
1018 AsyncFnMut_async_call_mut, FunctionId;
1019 AsyncFnOnce_async_call_once, FunctionId;
1020 Not_not, FunctionId;
1021 Neg_neg, FunctionId;
1022 Add_add, FunctionId;
1023 Mul_mul, FunctionId;
1024 Sub_sub, FunctionId;
1025 Div_div, FunctionId;
1026 Rem_rem, FunctionId;
1027 Shl_shl, FunctionId;
1028 Shr_shr, FunctionId;
1029 BitXor_bitxor, FunctionId;
1030 BitOr_bitor, FunctionId;
1031 BitAnd_bitand, FunctionId;
1032 AddAssign_add_assign, FunctionId;
1033 MulAssign_mul_assign, FunctionId;
1034 SubAssign_sub_assign, FunctionId;
1035 DivAssign_div_assign, FunctionId;
1036 RemAssign_rem_assign, FunctionId;
1037 ShlAssign_shl_assign, FunctionId;
1038 ShrAssign_shr_assign, FunctionId;
1039 BitXorAssign_bitxor_assign, FunctionId;
1040 BitOrAssign_bitor_assign, FunctionId;
1041 BitAndAssign_bitand_assign, FunctionId;
1042 PartialEq_eq, FunctionId;
1043 PartialEq_ne, FunctionId;
1044 PartialOrd_le, FunctionId;
1045 PartialOrd_lt, FunctionId;
1046 PartialOrd_ge, FunctionId;
1047 PartialOrd_gt, FunctionId;
1048 Drop_drop, FunctionId;
1049 Drop_pin_drop, FunctionId;
1050 Debug_fmt, FunctionId;
1051 Deref_deref, FunctionId;
1052 DerefMut_deref_mut, FunctionId;
1053 Index_index, FunctionId;
1054 IndexMut_index_mut, FunctionId;
1055}