1use std::cmp::{Ord, PartialOrd};
2use std::fmt;
3
4use derive_generic_visitor::{ControlFlow, Drive, DriveMut};
5use index_vec::Idx;
6use itertools::Itertools;
7use serde::{Deserialize, Serialize};
8use serde_state::{DeserializeState, SerializeState};
9
10use crate::ast::*;
11use crate::common::serialize_map_to_array::SeqHashMapToArray;
12use crate::formatter::{FmtCtx, IntoFormatter};
13use crate::ids::{IndexMap, IndexVec};
14use crate::pretty::FmtWithCtx;
15use macros::{EnumAsGetters, EnumIsA, VariantIndexArity, VariantName};
16
17generate_index_type!(FunDeclId, "Fun");
18generate_index_type!(TypeDeclId, "Adt");
19generate_index_type!(GlobalDeclId, "Global");
20generate_index_type!(TraitDeclId, "TraitDecl");
21generate_index_type!(TraitImplId, "TraitImpl");
22
23#[derive(
25 Copy,
26 Clone,
27 Debug,
28 PartialOrd,
29 Ord,
30 PartialEq,
31 Eq,
32 Hash,
33 EnumIsA,
34 EnumAsGetters,
35 VariantName,
36 VariantIndexArity,
37 Serialize,
38 Deserialize,
39 SerializeState,
40 DeserializeState,
41 Drive,
42 DriveMut,
43)]
44#[cfg_attr(feature = "charon_on_charon", charon::variants_prefix("Id"))]
45#[serde_state(stateless)]
46pub enum ItemId {
47 Type(TypeDeclId),
48 TraitDecl(TraitDeclId),
49 TraitImpl(TraitImplId),
50 Fun(FunDeclId),
51 Global(GlobalDeclId),
52}
53
54#[derive(
55 Copy,
56 Clone,
57 Debug,
58 PartialOrd,
59 Ord,
60 PartialEq,
61 Eq,
62 Hash,
63 EnumIsA,
64 EnumAsGetters,
65 VariantName,
66 VariantIndexArity,
67 Serialize,
68 Deserialize,
69 SerializeState,
70 DeserializeState,
71 Drive,
72 DriveMut,
73)]
74#[cfg_attr(feature = "charon_on_charon", charon::variants_prefix("AssocId"))]
75#[serde_state(stateless)]
76pub enum AssocItemId {
77 Type(AssocTypeId),
78 Method(TraitMethodId),
79 Const(AssocConstId),
80}
81
82macro_rules! wrap_unwrap_enum {
84 ($enum:ident::$variant:ident($variant_ty:ident)) => {
85 impl TryFrom<$enum> for $variant_ty {
86 type Error = ();
87 fn try_from(x: $enum) -> Result<Self, Self::Error> {
88 match x {
89 $enum::$variant(x) => Ok(x),
90 _ => Err(()),
91 }
92 }
93 }
94
95 impl From<$variant_ty> for $enum {
96 fn from(x: $variant_ty) -> Self {
97 $enum::$variant(x)
98 }
99 }
100 };
101}
102
103wrap_unwrap_enum!(ItemId::Fun(FunDeclId));
104wrap_unwrap_enum!(ItemId::Global(GlobalDeclId));
105wrap_unwrap_enum!(ItemId::Type(TypeDeclId));
106wrap_unwrap_enum!(ItemId::TraitDecl(TraitDeclId));
107wrap_unwrap_enum!(ItemId::TraitImpl(TraitImplId));
108impl TryFrom<ItemId> for TypeId {
109 type Error = ();
110 fn try_from(x: ItemId) -> Result<Self, Self::Error> {
111 Ok(TypeId::Adt(x.try_into()?))
112 }
113}
114impl TryFrom<ItemId> for FunId {
115 type Error = ();
116 fn try_from(x: ItemId) -> Result<Self, Self::Error> {
117 Ok(FunId::Regular(x.try_into()?))
118 }
119}
120
121wrap_unwrap_enum!(AssocItemId::Type(AssocTypeId));
122wrap_unwrap_enum!(AssocItemId::Method(TraitMethodId));
123wrap_unwrap_enum!(AssocItemId::Const(AssocConstId));
124
125#[derive(
127 Debug, PartialEq, Eq, EnumIsA, EnumAsGetters, VariantName, VariantIndexArity, Drive, DriveMut,
128)]
129pub enum ItemByVal {
130 Type(TypeDecl),
131 Fun(FunDecl),
132 Global(GlobalDecl),
133 TraitDecl(TraitDecl),
134 TraitImpl(TraitImpl),
135}
136
137#[derive(
139 Debug, Clone, Copy, EnumIsA, EnumAsGetters, VariantName, VariantIndexArity, Drive, DriveMut,
140)]
141pub enum ItemRef<'ctx> {
142 Type(&'ctx TypeDecl),
143 Fun(&'ctx FunDecl),
144 Global(&'ctx GlobalDecl),
145 TraitDecl(&'ctx TraitDecl),
146 TraitImpl(&'ctx TraitImpl),
147}
148
149#[derive(
151 Debug, PartialEq, Eq, EnumIsA, EnumAsGetters, VariantName, VariantIndexArity, Drive, DriveMut,
152)]
153pub enum ItemRefMut<'ctx> {
154 Type(&'ctx mut TypeDecl),
155 Fun(&'ctx mut FunDecl),
156 Global(&'ctx mut GlobalDecl),
157 TraitDecl(&'ctx mut TraitDecl),
158 TraitImpl(&'ctx mut TraitImpl),
159}
160
161#[derive(
164 Debug, Clone, VariantIndexArity, VariantName, EnumAsGetters, EnumIsA, Serialize, Deserialize,
165)]
166#[cfg_attr(feature = "charon_on_charon", charon::variants_suffix("Group"))]
167pub enum GDeclarationGroup<Id> {
168 NonRec(Id),
170 Rec(Vec<Id>),
172}
173
174#[derive(
176 Debug, Clone, VariantIndexArity, VariantName, EnumAsGetters, EnumIsA, Serialize, Deserialize,
177)]
178#[cfg_attr(feature = "charon_on_charon", charon::variants_suffix("Group"))]
179pub enum DeclarationGroup {
180 Type(GDeclarationGroup<TypeDeclId>),
182 Fun(GDeclarationGroup<FunDeclId>),
184 Global(GDeclarationGroup<GlobalDeclId>),
186 TraitDecl(GDeclarationGroup<TraitDeclId>),
187 TraitImpl(GDeclarationGroup<TraitImplId>),
188 Mixed(GDeclarationGroup<ItemId>),
190}
191
192pub type DeclarationsGroups = Vec<DeclarationGroup>;
193
194pub type TargetTriple = String;
196
197#[derive(Clone, Drive, DriveMut, SerializeState, DeserializeState)]
198#[serde_state(stateless)]
199pub struct TargetInfo {
200 pub target_pointer_size: types::ByteCount,
202 pub is_little_endian: bool,
204}
205
206#[derive(Default, Clone, Drive, DriveMut, SerializeState, DeserializeState)]
207pub struct AssocItemNames {
208 pub types: IndexVec<AssocTypeId, TraitItemName>,
209 pub methods: IndexVec<TraitMethodId, TraitItemName>,
210 pub consts: IndexVec<AssocConstId, TraitItemName>,
211}
212
213#[derive(Default, Clone, Drive, DriveMut, SerializeState, DeserializeState)]
229#[serde_state(state_implements = HashConsSerializerState)]
230pub struct TranslatedCrate {
231 #[drive(skip)]
233 pub crate_name: String,
234
235 #[drive(skip)]
238 #[serde_state(stateless)]
239 pub options: crate::options::CliOpts,
240
241 #[drive(skip)]
245 #[serde(with = "SeqHashMapToArray::<TargetTriple, TargetInfo>")]
246 pub target_information: SeqHashMap<TargetTriple, TargetInfo>,
247
248 #[serde_state(stateless)]
253 pub files: IndexVec<FileId, File>,
254
255 #[serde(with = "SeqHashMapToArray::<ItemId, Name>")]
260 pub item_names: SeqHashMap<ItemId, Name>,
261 pub assoc_item_names: IndexMap<TraitDeclId, AssocItemNames>,
266 #[serde(with = "SeqHashMapToArray::<ItemId, Name>")]
268 pub short_names: SeqHashMap<ItemId, Name>,
269
270 pub type_decls: IndexMap<TypeDeclId, TypeDecl>,
272 pub fun_decls: IndexMap<FunDeclId, FunDecl>,
277 pub global_decls: IndexMap<GlobalDeclId, GlobalDecl>,
279 pub trait_decls: IndexMap<TraitDeclId, TraitDecl>,
281 pub trait_impls: IndexMap<TraitImplId, TraitImpl>,
283 #[drive(skip)]
295 #[serde_state(stateless)]
296 pub ordered_decls: Option<DeclarationsGroups>,
297}
298
299impl TranslatedCrate {
300 pub fn item_name(&self, id: impl Into<ItemId>) -> &Name {
301 self.item_names.get(&id.into()).unwrap()
304 }
305 pub fn assoc_item_name(
306 &self,
307 trait_id: TraitDeclId,
308 id: impl Into<AssocItemId>,
309 ) -> TraitItemName {
310 let names = &self.assoc_item_names[trait_id];
311 match id.into() {
312 AssocItemId::Type(id) => names.types[id],
313 AssocItemId::Method(id) => names.methods[id],
314 AssocItemId::Const(id) => names.consts[id],
315 }
316 }
317
318 pub fn item_short_name(&self, id: impl Into<ItemId>) -> &Name {
319 let id = id.into();
320 self.short_names
321 .get(&id)
322 .unwrap_or_else(|| self.item_name(id))
323 }
324
325 pub fn get_item(&self, trans_id: impl Into<ItemId>) -> Option<ItemRef<'_>> {
326 match trans_id.into() {
327 ItemId::Type(id) => self.type_decls.get(id).map(ItemRef::Type),
328 ItemId::Fun(id) => self.fun_decls.get(id).map(ItemRef::Fun),
329 ItemId::Global(id) => self.global_decls.get(id).map(ItemRef::Global),
330 ItemId::TraitDecl(id) => self.trait_decls.get(id).map(ItemRef::TraitDecl),
331 ItemId::TraitImpl(id) => self.trait_impls.get(id).map(ItemRef::TraitImpl),
332 }
333 }
334 pub fn get_item_mut(&mut self, trans_id: ItemId) -> Option<ItemRefMut<'_>> {
335 match trans_id {
336 ItemId::Type(id) => self.type_decls.get_mut(id).map(ItemRefMut::Type),
337 ItemId::Fun(id) => self.fun_decls.get_mut(id).map(ItemRefMut::Fun),
338 ItemId::Global(id) => self.global_decls.get_mut(id).map(ItemRefMut::Global),
339 ItemId::TraitDecl(id) => self.trait_decls.get_mut(id).map(ItemRefMut::TraitDecl),
340 ItemId::TraitImpl(id) => self.trait_impls.get_mut(id).map(ItemRefMut::TraitImpl),
341 }
342 }
343
344 pub fn remove_item(&mut self, trans_id: ItemId) -> Option<ItemByVal> {
348 self.short_names.swap_remove(&trans_id);
349 self.item_names.swap_remove(&trans_id);
350 self.remove_item_temporarily(trans_id)
351 }
352 pub fn set_new_item_slot(&mut self, id: ItemId, item: impl Into<ItemByVal>) {
354 let item = item.into();
355 self.item_names
356 .insert(id, item.as_ref().item_meta().name.clone());
357 self.put_item_back(id, item);
358 }
359 pub fn remove_item_temporarily(&mut self, trans_id: ItemId) -> Option<ItemByVal> {
365 match trans_id {
366 ItemId::Type(id) => self.type_decls.remove(id).map(ItemByVal::Type),
367 ItemId::Fun(id) => self.fun_decls.remove(id).map(ItemByVal::Fun),
368 ItemId::Global(id) => self.global_decls.remove(id).map(ItemByVal::Global),
369 ItemId::TraitDecl(id) => self.trait_decls.remove(id).map(ItemByVal::TraitDecl),
370 ItemId::TraitImpl(id) => self.trait_impls.remove(id).map(ItemByVal::TraitImpl),
371 }
372 }
373 pub fn put_item_back(&mut self, id: ItemId, item: impl Into<ItemByVal>) {
377 match item.into() {
378 ItemByVal::Type(decl) => self.type_decls.set_slot(*id.as_type().unwrap(), decl),
379 ItemByVal::Fun(decl) => self.fun_decls.set_slot(*id.as_fun().unwrap(), decl),
380 ItemByVal::Global(decl) => self.global_decls.set_slot(*id.as_global().unwrap(), decl),
381 ItemByVal::TraitDecl(decl) => self
382 .trait_decls
383 .set_slot(*id.as_trait_decl().unwrap(), decl),
384 ItemByVal::TraitImpl(decl) => self
385 .trait_impls
386 .set_slot(*id.as_trait_impl().unwrap(), decl),
387 }
388 }
389
390 pub fn all_ids(&self) -> impl Iterator<Item = ItemId> + use<> {
391 self.type_decls
392 .all_indices()
393 .map(ItemId::Type)
394 .chain(self.trait_decls.all_indices().map(ItemId::TraitDecl))
395 .chain(self.trait_impls.all_indices().map(ItemId::TraitImpl))
396 .chain(self.global_decls.all_indices().map(ItemId::Global))
397 .chain(self.fun_decls.all_indices().map(ItemId::Fun))
398 }
399 pub fn all_items(&self) -> impl Iterator<Item = ItemRef<'_>> {
400 self.type_decls
401 .iter()
402 .map(ItemRef::Type)
403 .chain(self.trait_decls.iter().map(ItemRef::TraitDecl))
404 .chain(self.trait_impls.iter().map(ItemRef::TraitImpl))
405 .chain(self.global_decls.iter().map(ItemRef::Global))
406 .chain(self.fun_decls.iter().map(ItemRef::Fun))
407 }
408 pub fn all_items_mut(&mut self) -> impl Iterator<Item = ItemRefMut<'_>> {
409 self.type_decls
410 .iter_mut()
411 .map(ItemRefMut::Type)
412 .chain(self.trait_impls.iter_mut().map(ItemRefMut::TraitImpl))
413 .chain(self.trait_decls.iter_mut().map(ItemRefMut::TraitDecl))
414 .chain(self.fun_decls.iter_mut().map(ItemRefMut::Fun))
415 .chain(self.global_decls.iter_mut().map(ItemRefMut::Global))
416 }
417 pub fn all_items_with_ids(&self) -> impl Iterator<Item = (ItemId, ItemRef<'_>)> {
418 self.all_items().map(|item| (item.id(), item))
419 }
420
421 pub fn the_target_information(&self) -> &TargetInfo {
425 self.target_information
426 .values()
427 .exactly_one()
428 .ok()
429 .expect("called `the_target_information` on a multi-target crate")
430 }
431}
432
433impl ItemByVal {
434 pub fn as_ref(&self) -> ItemRef<'_> {
435 match self {
436 Self::Type(d) => ItemRef::Type(d),
437 Self::Fun(d) => ItemRef::Fun(d),
438 Self::Global(d) => ItemRef::Global(d),
439 Self::TraitDecl(d) => ItemRef::TraitDecl(d),
440 Self::TraitImpl(d) => ItemRef::TraitImpl(d),
441 }
442 }
443 pub fn as_mut(&mut self) -> ItemRefMut<'_> {
444 match self {
445 Self::Type(d) => ItemRefMut::Type(d),
446 Self::Fun(d) => ItemRefMut::Fun(d),
447 Self::Global(d) => ItemRefMut::Global(d),
448 Self::TraitDecl(d) => ItemRefMut::TraitDecl(d),
449 Self::TraitImpl(d) => ItemRefMut::TraitImpl(d),
450 }
451 }
452}
453
454impl<'ctx> ItemRef<'ctx> {
455 pub fn id(&self) -> ItemId {
456 match self {
457 ItemRef::Type(d) => d.def_id.into(),
458 ItemRef::Fun(d) => d.def_id.into(),
459 ItemRef::Global(d) => d.def_id.into(),
460 ItemRef::TraitDecl(d) => d.def_id.into(),
461 ItemRef::TraitImpl(d) => d.def_id.into(),
462 }
463 }
464
465 pub fn to_owned(&self) -> ItemByVal {
466 match *self {
467 Self::Type(d) => ItemByVal::Type(d.clone()),
468 Self::Fun(d) => ItemByVal::Fun(d.clone()),
469 Self::Global(d) => ItemByVal::Global(d.clone()),
470 Self::TraitDecl(d) => ItemByVal::TraitDecl(d.clone()),
471 Self::TraitImpl(d) => ItemByVal::TraitImpl(d.clone()),
472 }
473 }
474
475 pub fn item_meta(&self) -> &'ctx ItemMeta {
476 match self {
477 Self::Type(d) => &d.item_meta,
478 Self::Fun(d) => &d.item_meta,
479 Self::Global(d) => &d.item_meta,
480 Self::TraitDecl(d) => &d.item_meta,
481 Self::TraitImpl(d) => &d.item_meta,
482 }
483 }
484 pub fn generic_params(&self) -> &'ctx GenericParams {
486 match self {
487 ItemRef::Type(d) => &d.generics,
488 ItemRef::Fun(d) => &d.generics,
489 ItemRef::Global(d) => &d.generics,
490 ItemRef::TraitDecl(d) => &d.generics,
491 ItemRef::TraitImpl(d) => &d.generics,
492 }
493 }
494
495 pub fn parent_info(&self) -> &'ctx ItemSource {
497 match self {
498 ItemRef::Fun(d) => &d.src,
499 ItemRef::Global(d) => &d.src,
500 ItemRef::Type(_) | ItemRef::TraitDecl(_) | ItemRef::TraitImpl(_) => {
501 &ItemSource::TopLevel
502 }
503 }
504 }
505
506 pub fn identity_args(&self) -> GenericArgs {
508 self.generic_params().identity_args()
509 }
510
511 pub fn drive<V: VisitAst>(&self, visitor: &mut V) -> ControlFlow<V::Break> {
514 match *self {
515 ItemRef::Type(d) => visitor.visit(d),
516 ItemRef::Fun(d) => visitor.visit(d),
517 ItemRef::Global(d) => visitor.visit(d),
518 ItemRef::TraitDecl(d) => visitor.visit(d),
519 ItemRef::TraitImpl(d) => visitor.visit(d),
520 }
521 }
522
523 pub fn dyn_visit<T: AstVisitable>(&self, f: impl FnMut(&T)) {
525 match *self {
526 ItemRef::Type(d) => d.dyn_visit(f),
527 ItemRef::Fun(d) => d.dyn_visit(f),
528 ItemRef::Global(d) => d.dyn_visit(f),
529 ItemRef::TraitDecl(d) => d.dyn_visit(f),
530 ItemRef::TraitImpl(d) => d.dyn_visit(f),
531 }
532 }
533}
534
535impl<'ctx> ItemRefMut<'ctx> {
536 pub fn as_ref(&self) -> ItemRef<'_> {
537 match self {
538 ItemRefMut::Type(d) => ItemRef::Type(d),
539 ItemRefMut::Fun(d) => ItemRef::Fun(d),
540 ItemRefMut::Global(d) => ItemRef::Global(d),
541 ItemRefMut::TraitDecl(d) => ItemRef::TraitDecl(d),
542 ItemRefMut::TraitImpl(d) => ItemRef::TraitImpl(d),
543 }
544 }
545 pub fn reborrow(&mut self) -> ItemRefMut<'_> {
546 match self {
547 ItemRefMut::Type(d) => ItemRefMut::Type(d),
548 ItemRefMut::Fun(d) => ItemRefMut::Fun(d),
549 ItemRefMut::Global(d) => ItemRefMut::Global(d),
550 ItemRefMut::TraitDecl(d) => ItemRefMut::TraitDecl(d),
551 ItemRefMut::TraitImpl(d) => ItemRefMut::TraitImpl(d),
552 }
553 }
554
555 pub fn set_id(&mut self, id: ItemId) {
556 match (self, id) {
557 (Self::Type(d), ItemId::Type(id)) => d.def_id = id,
558 (Self::Fun(d), ItemId::Fun(id)) => d.def_id = id,
559 (Self::Global(d), ItemId::Global(id)) => d.def_id = id,
560 (Self::TraitDecl(d), ItemId::TraitDecl(id)) => d.def_id = id,
561 (Self::TraitImpl(d), ItemId::TraitImpl(id)) => d.def_id = id,
562 _ => unreachable!(),
563 }
564 }
565
566 pub fn item_meta(&mut self) -> &mut ItemMeta {
567 match self {
568 Self::Type(d) => &mut d.item_meta,
569 Self::Fun(d) => &mut d.item_meta,
570 Self::Global(d) => &mut d.item_meta,
571 Self::TraitDecl(d) => &mut d.item_meta,
572 Self::TraitImpl(d) => &mut d.item_meta,
573 }
574 }
575 pub fn generic_params(&mut self) -> &mut GenericParams {
577 match self {
578 ItemRefMut::Type(d) => &mut d.generics,
579 ItemRefMut::Fun(d) => &mut d.generics,
580 ItemRefMut::Global(d) => &mut d.generics,
581 ItemRefMut::TraitDecl(d) => &mut d.generics,
582 ItemRefMut::TraitImpl(d) => &mut d.generics,
583 }
584 }
585
586 pub fn drive_mut<V: VisitAstMut>(&mut self, visitor: &mut V) -> ControlFlow<V::Break> {
589 match self {
590 ItemRefMut::Type(d) => visitor.visit(*d),
591 ItemRefMut::Fun(d) => visitor.visit(*d),
592 ItemRefMut::Global(d) => visitor.visit(*d),
593 ItemRefMut::TraitDecl(d) => visitor.visit(*d),
594 ItemRefMut::TraitImpl(d) => visitor.visit(*d),
595 }
596 }
597
598 pub fn dyn_visit_mut<T: AstVisitable>(&mut self, f: impl FnMut(&mut T)) {
600 match self {
601 ItemRefMut::Type(d) => d.dyn_visit_mut(f),
602 ItemRefMut::Fun(d) => d.dyn_visit_mut(f),
603 ItemRefMut::Global(d) => d.dyn_visit_mut(f),
604 ItemRefMut::TraitDecl(d) => d.dyn_visit_mut(f),
605 ItemRefMut::TraitImpl(d) => d.dyn_visit_mut(f),
606 }
607 }
608}
609
610impl fmt::Display for TranslatedCrate {
611 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
612 let fmt: &FmtCtx = &self.into_fmt();
613 match &self.ordered_decls {
614 None => {
615 for d in &self.type_decls {
617 writeln!(f, "{}\n", d.with_ctx(fmt))?
618 }
619 for d in &self.global_decls {
620 writeln!(f, "{}\n", d.with_ctx(fmt))?
621 }
622 for d in &self.trait_decls {
623 writeln!(f, "{}\n", d.with_ctx(fmt))?
624 }
625 for d in &self.trait_impls {
626 writeln!(f, "{}\n", d.with_ctx(fmt))?
627 }
628 for d in &self.fun_decls {
629 writeln!(f, "{}\n", d.with_ctx(fmt))?
630 }
631 }
632 Some(ordered_decls) => {
633 for gr in ordered_decls {
634 for id in gr.get_ids() {
635 writeln!(f, "{}\n", fmt.format_decl_id(id))?
636 }
637 }
638 }
639 }
640 fmt::Result::Ok(())
641 }
642}
643
644impl<'a> IntoFormatter for &'a TranslatedCrate {
645 type C = FmtCtx<'a>;
646
647 fn into_fmt(self) -> Self::C {
648 FmtCtx {
649 translated: Some(self),
650 ..Default::default()
651 }
652 }
653}
654
655pub trait HasIdxMapOf<Id: Idx>: std::ops::Index<Id, Output: Sized> {
656 fn get_idx_map(&self) -> &IndexMap<Id, Self::Output>;
657 fn get_idx_map_mut(&mut self) -> &mut IndexMap<Id, Self::Output>;
658}
659
660macro_rules! mk_index_impls {
662 ($ty:ident.$field:ident[$idx:ty]: $output:ty) => {
663 impl std::ops::Index<$idx> for $ty {
664 type Output = $output;
665 fn index(&self, index: $idx) -> &Self::Output {
666 &self.$field[index]
667 }
668 }
669 impl std::ops::IndexMut<$idx> for $ty {
670 fn index_mut(&mut self, index: $idx) -> &mut Self::Output {
671 &mut self.$field[index]
672 }
673 }
674 impl HasIdxMapOf<$idx> for $ty {
675 fn get_idx_map(&self) -> &IndexMap<$idx, Self::Output> {
676 &self.$field
677 }
678 fn get_idx_map_mut(&mut self) -> &mut IndexMap<$idx, Self::Output> {
679 &mut self.$field
680 }
681 }
682 };
683}
684mk_index_impls!(TranslatedCrate.type_decls[TypeDeclId]: TypeDecl);
685mk_index_impls!(TranslatedCrate.fun_decls[FunDeclId]: FunDecl);
686mk_index_impls!(TranslatedCrate.global_decls[GlobalDeclId]: GlobalDecl);
687mk_index_impls!(TranslatedCrate.trait_decls[TraitDeclId]: TraitDecl);
688mk_index_impls!(TranslatedCrate.trait_impls[TraitImplId]: TraitImpl);