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)]
215#[serde_state(state_implements = HashConsSerializerState)]
216pub struct TranslatedCrate {
217 #[drive(skip)]
219 pub crate_name: String,
220
221 #[drive(skip)]
225 #[serde_state(stateless)]
226 pub options: crate::options::CliOpts,
227
228 #[drive(skip)]
231 #[serde(with = "SeqHashMapToArray::<TargetTriple, TargetInfo>")]
232 pub target_information: SeqHashMap<TargetTriple, TargetInfo>,
233
234 #[serde_state(stateless)]
237 pub files: IndexVec<FileId, File>,
238
239 #[serde(with = "SeqHashMapToArray::<ItemId, Name>")]
244 pub item_names: SeqHashMap<ItemId, Name>,
245 pub assoc_item_names: IndexMap<TraitDeclId, AssocItemNames>,
250 #[serde(with = "SeqHashMapToArray::<ItemId, Name>")]
252 pub short_names: SeqHashMap<ItemId, Name>,
253
254 pub type_decls: IndexMap<TypeDeclId, TypeDecl>,
256 pub fun_decls: IndexMap<FunDeclId, FunDecl>,
258 pub global_decls: IndexMap<GlobalDeclId, GlobalDecl>,
260 pub trait_decls: IndexMap<TraitDeclId, TraitDecl>,
262 pub trait_impls: IndexMap<TraitImplId, TraitImpl>,
264 #[drive(skip)]
266 #[serde_state(stateless)]
267 pub ordered_decls: Option<DeclarationsGroups>,
268}
269
270impl TranslatedCrate {
271 pub fn item_name(&self, id: impl Into<ItemId>) -> &Name {
272 self.item_names.get(&id.into()).unwrap()
275 }
276 pub fn assoc_item_name(
277 &self,
278 trait_id: TraitDeclId,
279 id: impl Into<AssocItemId>,
280 ) -> TraitItemName {
281 let names = &self.assoc_item_names[trait_id];
282 match id.into() {
283 AssocItemId::Type(id) => names.types[id],
284 AssocItemId::Method(id) => names.methods[id],
285 AssocItemId::Const(id) => names.consts[id],
286 }
287 }
288
289 pub fn item_short_name(&self, id: impl Into<ItemId>) -> &Name {
290 let id = id.into();
291 self.short_names
292 .get(&id)
293 .unwrap_or_else(|| self.item_name(id))
294 }
295
296 pub fn get_item(&self, trans_id: impl Into<ItemId>) -> Option<ItemRef<'_>> {
297 match trans_id.into() {
298 ItemId::Type(id) => self.type_decls.get(id).map(ItemRef::Type),
299 ItemId::Fun(id) => self.fun_decls.get(id).map(ItemRef::Fun),
300 ItemId::Global(id) => self.global_decls.get(id).map(ItemRef::Global),
301 ItemId::TraitDecl(id) => self.trait_decls.get(id).map(ItemRef::TraitDecl),
302 ItemId::TraitImpl(id) => self.trait_impls.get(id).map(ItemRef::TraitImpl),
303 }
304 }
305 pub fn get_item_mut(&mut self, trans_id: ItemId) -> Option<ItemRefMut<'_>> {
306 match trans_id {
307 ItemId::Type(id) => self.type_decls.get_mut(id).map(ItemRefMut::Type),
308 ItemId::Fun(id) => self.fun_decls.get_mut(id).map(ItemRefMut::Fun),
309 ItemId::Global(id) => self.global_decls.get_mut(id).map(ItemRefMut::Global),
310 ItemId::TraitDecl(id) => self.trait_decls.get_mut(id).map(ItemRefMut::TraitDecl),
311 ItemId::TraitImpl(id) => self.trait_impls.get_mut(id).map(ItemRefMut::TraitImpl),
312 }
313 }
314 pub fn remove_item(&mut self, trans_id: ItemId) -> Option<ItemByVal> {
315 self.short_names.swap_remove(&trans_id);
316 self.item_names.swap_remove(&trans_id);
317 self.remove_item_temporarily(trans_id)
318 }
319 pub fn remove_item_temporarily(&mut self, trans_id: ItemId) -> Option<ItemByVal> {
321 match trans_id {
322 ItemId::Type(id) => self.type_decls.remove(id).map(ItemByVal::Type),
323 ItemId::Fun(id) => self.fun_decls.remove(id).map(ItemByVal::Fun),
324 ItemId::Global(id) => self.global_decls.remove(id).map(ItemByVal::Global),
325 ItemId::TraitDecl(id) => self.trait_decls.remove(id).map(ItemByVal::TraitDecl),
326 ItemId::TraitImpl(id) => self.trait_impls.remove(id).map(ItemByVal::TraitImpl),
327 }
328 }
329 pub fn set_new_item_slot(&mut self, id: ItemId, item: impl Into<ItemByVal>) {
331 let item = item.into();
332 self.item_names
333 .insert(id, item.as_ref().item_meta().name.clone());
334 self.set_item_slot(id, item);
335 }
336 pub fn set_item_slot(&mut self, id: ItemId, item: impl Into<ItemByVal>) {
338 match item.into() {
339 ItemByVal::Type(decl) => self.type_decls.set_slot(*id.as_type().unwrap(), decl),
340 ItemByVal::Fun(decl) => self.fun_decls.set_slot(*id.as_fun().unwrap(), decl),
341 ItemByVal::Global(decl) => self.global_decls.set_slot(*id.as_global().unwrap(), decl),
342 ItemByVal::TraitDecl(decl) => self
343 .trait_decls
344 .set_slot(*id.as_trait_decl().unwrap(), decl),
345 ItemByVal::TraitImpl(decl) => self
346 .trait_impls
347 .set_slot(*id.as_trait_impl().unwrap(), decl),
348 }
349 }
350
351 pub fn all_ids(&self) -> impl Iterator<Item = ItemId> + use<> {
352 self.type_decls
353 .all_indices()
354 .map(ItemId::Type)
355 .chain(self.trait_decls.all_indices().map(ItemId::TraitDecl))
356 .chain(self.trait_impls.all_indices().map(ItemId::TraitImpl))
357 .chain(self.global_decls.all_indices().map(ItemId::Global))
358 .chain(self.fun_decls.all_indices().map(ItemId::Fun))
359 }
360 pub fn all_items(&self) -> impl Iterator<Item = ItemRef<'_>> {
361 self.type_decls
362 .iter()
363 .map(ItemRef::Type)
364 .chain(self.trait_decls.iter().map(ItemRef::TraitDecl))
365 .chain(self.trait_impls.iter().map(ItemRef::TraitImpl))
366 .chain(self.global_decls.iter().map(ItemRef::Global))
367 .chain(self.fun_decls.iter().map(ItemRef::Fun))
368 }
369 pub fn all_items_mut(&mut self) -> impl Iterator<Item = ItemRefMut<'_>> {
370 self.type_decls
371 .iter_mut()
372 .map(ItemRefMut::Type)
373 .chain(self.trait_impls.iter_mut().map(ItemRefMut::TraitImpl))
374 .chain(self.trait_decls.iter_mut().map(ItemRefMut::TraitDecl))
375 .chain(self.fun_decls.iter_mut().map(ItemRefMut::Fun))
376 .chain(self.global_decls.iter_mut().map(ItemRefMut::Global))
377 }
378 pub fn all_items_with_ids(&self) -> impl Iterator<Item = (ItemId, ItemRef<'_>)> {
379 self.all_items().map(|item| (item.id(), item))
380 }
381
382 pub fn the_target_information(&self) -> &TargetInfo {
385 self.target_information
386 .values()
387 .exactly_one()
388 .ok()
389 .expect("called `the_target_information` on a multi-target crate")
390 }
391}
392
393impl ItemByVal {
394 pub fn as_ref(&self) -> ItemRef<'_> {
395 match self {
396 Self::Type(d) => ItemRef::Type(d),
397 Self::Fun(d) => ItemRef::Fun(d),
398 Self::Global(d) => ItemRef::Global(d),
399 Self::TraitDecl(d) => ItemRef::TraitDecl(d),
400 Self::TraitImpl(d) => ItemRef::TraitImpl(d),
401 }
402 }
403 pub fn as_mut(&mut self) -> ItemRefMut<'_> {
404 match self {
405 Self::Type(d) => ItemRefMut::Type(d),
406 Self::Fun(d) => ItemRefMut::Fun(d),
407 Self::Global(d) => ItemRefMut::Global(d),
408 Self::TraitDecl(d) => ItemRefMut::TraitDecl(d),
409 Self::TraitImpl(d) => ItemRefMut::TraitImpl(d),
410 }
411 }
412}
413
414impl<'ctx> ItemRef<'ctx> {
415 pub fn id(&self) -> ItemId {
416 match self {
417 ItemRef::Type(d) => d.def_id.into(),
418 ItemRef::Fun(d) => d.def_id.into(),
419 ItemRef::Global(d) => d.def_id.into(),
420 ItemRef::TraitDecl(d) => d.def_id.into(),
421 ItemRef::TraitImpl(d) => d.def_id.into(),
422 }
423 }
424
425 pub fn to_owned(&self) -> ItemByVal {
426 match *self {
427 Self::Type(d) => ItemByVal::Type(d.clone()),
428 Self::Fun(d) => ItemByVal::Fun(d.clone()),
429 Self::Global(d) => ItemByVal::Global(d.clone()),
430 Self::TraitDecl(d) => ItemByVal::TraitDecl(d.clone()),
431 Self::TraitImpl(d) => ItemByVal::TraitImpl(d.clone()),
432 }
433 }
434
435 pub fn item_meta(&self) -> &'ctx ItemMeta {
436 match self {
437 Self::Type(d) => &d.item_meta,
438 Self::Fun(d) => &d.item_meta,
439 Self::Global(d) => &d.item_meta,
440 Self::TraitDecl(d) => &d.item_meta,
441 Self::TraitImpl(d) => &d.item_meta,
442 }
443 }
444 pub fn generic_params(&self) -> &'ctx GenericParams {
446 match self {
447 ItemRef::Type(d) => &d.generics,
448 ItemRef::Fun(d) => &d.generics,
449 ItemRef::Global(d) => &d.generics,
450 ItemRef::TraitDecl(d) => &d.generics,
451 ItemRef::TraitImpl(d) => &d.generics,
452 }
453 }
454
455 pub fn parent_info(&self) -> &'ctx ItemSource {
457 match self {
458 ItemRef::Fun(d) => &d.src,
459 ItemRef::Global(d) => &d.src,
460 ItemRef::Type(_) | ItemRef::TraitDecl(_) | ItemRef::TraitImpl(_) => {
461 &ItemSource::TopLevel
462 }
463 }
464 }
465
466 pub fn identity_args(&self) -> GenericArgs {
468 self.generic_params().identity_args()
469 }
470
471 pub fn drive<V: VisitAst>(&self, visitor: &mut V) -> ControlFlow<V::Break> {
474 match *self {
475 ItemRef::Type(d) => visitor.visit(d),
476 ItemRef::Fun(d) => visitor.visit(d),
477 ItemRef::Global(d) => visitor.visit(d),
478 ItemRef::TraitDecl(d) => visitor.visit(d),
479 ItemRef::TraitImpl(d) => visitor.visit(d),
480 }
481 }
482
483 pub fn dyn_visit<T: AstVisitable>(&self, f: impl FnMut(&T)) {
485 match *self {
486 ItemRef::Type(d) => d.dyn_visit(f),
487 ItemRef::Fun(d) => d.dyn_visit(f),
488 ItemRef::Global(d) => d.dyn_visit(f),
489 ItemRef::TraitDecl(d) => d.dyn_visit(f),
490 ItemRef::TraitImpl(d) => d.dyn_visit(f),
491 }
492 }
493}
494
495impl<'ctx> ItemRefMut<'ctx> {
496 pub fn as_ref(&self) -> ItemRef<'_> {
497 match self {
498 ItemRefMut::Type(d) => ItemRef::Type(d),
499 ItemRefMut::Fun(d) => ItemRef::Fun(d),
500 ItemRefMut::Global(d) => ItemRef::Global(d),
501 ItemRefMut::TraitDecl(d) => ItemRef::TraitDecl(d),
502 ItemRefMut::TraitImpl(d) => ItemRef::TraitImpl(d),
503 }
504 }
505 pub fn reborrow(&mut self) -> ItemRefMut<'_> {
506 match self {
507 ItemRefMut::Type(d) => ItemRefMut::Type(d),
508 ItemRefMut::Fun(d) => ItemRefMut::Fun(d),
509 ItemRefMut::Global(d) => ItemRefMut::Global(d),
510 ItemRefMut::TraitDecl(d) => ItemRefMut::TraitDecl(d),
511 ItemRefMut::TraitImpl(d) => ItemRefMut::TraitImpl(d),
512 }
513 }
514
515 pub fn set_id(&mut self, id: ItemId) {
516 match (self, id) {
517 (Self::Type(d), ItemId::Type(id)) => d.def_id = id,
518 (Self::Fun(d), ItemId::Fun(id)) => d.def_id = id,
519 (Self::Global(d), ItemId::Global(id)) => d.def_id = id,
520 (Self::TraitDecl(d), ItemId::TraitDecl(id)) => d.def_id = id,
521 (Self::TraitImpl(d), ItemId::TraitImpl(id)) => d.def_id = id,
522 _ => unreachable!(),
523 }
524 }
525
526 pub fn item_meta(&mut self) -> &mut ItemMeta {
527 match self {
528 Self::Type(d) => &mut d.item_meta,
529 Self::Fun(d) => &mut d.item_meta,
530 Self::Global(d) => &mut d.item_meta,
531 Self::TraitDecl(d) => &mut d.item_meta,
532 Self::TraitImpl(d) => &mut d.item_meta,
533 }
534 }
535 pub fn generic_params(&mut self) -> &mut GenericParams {
537 match self {
538 ItemRefMut::Type(d) => &mut d.generics,
539 ItemRefMut::Fun(d) => &mut d.generics,
540 ItemRefMut::Global(d) => &mut d.generics,
541 ItemRefMut::TraitDecl(d) => &mut d.generics,
542 ItemRefMut::TraitImpl(d) => &mut d.generics,
543 }
544 }
545
546 pub fn drive_mut<V: VisitAstMut>(&mut self, visitor: &mut V) -> ControlFlow<V::Break> {
549 match self {
550 ItemRefMut::Type(d) => visitor.visit(*d),
551 ItemRefMut::Fun(d) => visitor.visit(*d),
552 ItemRefMut::Global(d) => visitor.visit(*d),
553 ItemRefMut::TraitDecl(d) => visitor.visit(*d),
554 ItemRefMut::TraitImpl(d) => visitor.visit(*d),
555 }
556 }
557
558 pub fn dyn_visit_mut<T: AstVisitable>(&mut self, f: impl FnMut(&mut T)) {
560 match self {
561 ItemRefMut::Type(d) => d.dyn_visit_mut(f),
562 ItemRefMut::Fun(d) => d.dyn_visit_mut(f),
563 ItemRefMut::Global(d) => d.dyn_visit_mut(f),
564 ItemRefMut::TraitDecl(d) => d.dyn_visit_mut(f),
565 ItemRefMut::TraitImpl(d) => d.dyn_visit_mut(f),
566 }
567 }
568}
569
570impl fmt::Display for TranslatedCrate {
571 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
572 let fmt: &FmtCtx = &self.into_fmt();
573 match &self.ordered_decls {
574 None => {
575 for d in &self.type_decls {
577 writeln!(f, "{}\n", d.with_ctx(fmt))?
578 }
579 for d in &self.global_decls {
580 writeln!(f, "{}\n", d.with_ctx(fmt))?
581 }
582 for d in &self.trait_decls {
583 writeln!(f, "{}\n", d.with_ctx(fmt))?
584 }
585 for d in &self.trait_impls {
586 writeln!(f, "{}\n", d.with_ctx(fmt))?
587 }
588 for d in &self.fun_decls {
589 writeln!(f, "{}\n", d.with_ctx(fmt))?
590 }
591 }
592 Some(ordered_decls) => {
593 for gr in ordered_decls {
594 for id in gr.get_ids() {
595 writeln!(f, "{}\n", fmt.format_decl_id(id))?
596 }
597 }
598 }
599 }
600 fmt::Result::Ok(())
601 }
602}
603
604impl<'a> IntoFormatter for &'a TranslatedCrate {
605 type C = FmtCtx<'a>;
606
607 fn into_fmt(self) -> Self::C {
608 FmtCtx {
609 translated: Some(self),
610 ..Default::default()
611 }
612 }
613}
614
615pub trait HasIdxMapOf<Id: Idx>: std::ops::Index<Id, Output: Sized> {
616 fn get_idx_map(&self) -> &IndexMap<Id, Self::Output>;
617 fn get_idx_map_mut(&mut self) -> &mut IndexMap<Id, Self::Output>;
618}
619
620macro_rules! mk_index_impls {
622 ($ty:ident.$field:ident[$idx:ty]: $output:ty) => {
623 impl std::ops::Index<$idx> for $ty {
624 type Output = $output;
625 fn index(&self, index: $idx) -> &Self::Output {
626 &self.$field[index]
627 }
628 }
629 impl std::ops::IndexMut<$idx> for $ty {
630 fn index_mut(&mut self, index: $idx) -> &mut Self::Output {
631 &mut self.$field[index]
632 }
633 }
634 impl HasIdxMapOf<$idx> for $ty {
635 fn get_idx_map(&self) -> &IndexMap<$idx, Self::Output> {
636 &self.$field
637 }
638 fn get_idx_map_mut(&mut self) -> &mut IndexMap<$idx, Self::Output> {
639 &mut self.$field
640 }
641 }
642 };
643}
644mk_index_impls!(TranslatedCrate.type_decls[TypeDeclId]: TypeDecl);
645mk_index_impls!(TranslatedCrate.fun_decls[FunDeclId]: FunDecl);
646mk_index_impls!(TranslatedCrate.global_decls[GlobalDeclId]: GlobalDecl);
647mk_index_impls!(TranslatedCrate.trait_decls[TraitDeclId]: TraitDecl);
648mk_index_impls!(TranslatedCrate.trait_impls[TraitImplId]: TraitImpl);