charon_lib/ast/
krate.rs

1use std::cmp::{Ord, PartialOrd};
2use std::fmt;
3
4use derive_generic_visitor::{ControlFlow, Drive, DriveMut};
5use index_vec::Idx;
6use serde::{Deserialize, Serialize};
7use serde_state::{DeserializeState, SerializeState};
8
9use crate::ast::*;
10use crate::common::serialize_map_to_array::SeqHashMapToArray;
11use crate::formatter::{FmtCtx, IntoFormatter};
12use crate::ids::{IndexMap, IndexVec};
13use crate::pretty::FmtWithCtx;
14use macros::{EnumAsGetters, EnumIsA, VariantIndexArity, VariantName};
15
16generate_index_type!(FunDeclId, "Fun");
17generate_index_type!(TypeDeclId, "Adt");
18generate_index_type!(GlobalDeclId, "Global");
19generate_index_type!(TraitDeclId, "TraitDecl");
20generate_index_type!(TraitImplId, "TraitImpl");
21
22/// The id of a translated item.
23#[derive(
24    Copy,
25    Clone,
26    Debug,
27    PartialOrd,
28    Ord,
29    PartialEq,
30    Eq,
31    Hash,
32    EnumIsA,
33    EnumAsGetters,
34    VariantName,
35    VariantIndexArity,
36    Serialize,
37    Deserialize,
38    SerializeState,
39    DeserializeState,
40    Drive,
41    DriveMut,
42)]
43#[charon::variants_prefix("Id")]
44#[serde_state(stateless)]
45pub enum ItemId {
46    Type(TypeDeclId),
47    Fun(FunDeclId),
48    Global(GlobalDeclId),
49    TraitDecl(TraitDeclId),
50    TraitImpl(TraitImplId),
51}
52
53/// Implement `TryFrom`  and `From` to convert between an enum and its variants.
54macro_rules! wrap_unwrap_enum {
55    ($enum:ident::$variant:ident($variant_ty:ident)) => {
56        impl TryFrom<$enum> for $variant_ty {
57            type Error = ();
58            fn try_from(x: $enum) -> Result<Self, Self::Error> {
59                match x {
60                    $enum::$variant(x) => Ok(x),
61                    _ => Err(()),
62                }
63            }
64        }
65
66        impl From<$variant_ty> for $enum {
67            fn from(x: $variant_ty) -> Self {
68                $enum::$variant(x)
69            }
70        }
71    };
72}
73
74wrap_unwrap_enum!(ItemId::Fun(FunDeclId));
75wrap_unwrap_enum!(ItemId::Global(GlobalDeclId));
76wrap_unwrap_enum!(ItemId::Type(TypeDeclId));
77wrap_unwrap_enum!(ItemId::TraitDecl(TraitDeclId));
78wrap_unwrap_enum!(ItemId::TraitImpl(TraitImplId));
79impl TryFrom<ItemId> for TypeId {
80    type Error = ();
81    fn try_from(x: ItemId) -> Result<Self, Self::Error> {
82        Ok(TypeId::Adt(x.try_into()?))
83    }
84}
85impl TryFrom<ItemId> for FunId {
86    type Error = ();
87    fn try_from(x: ItemId) -> Result<Self, Self::Error> {
88        Ok(FunId::Regular(x.try_into()?))
89    }
90}
91
92/// A translated item.
93#[derive(Debug, EnumIsA, EnumAsGetters, VariantName, VariantIndexArity, Drive, DriveMut)]
94pub enum ItemByVal {
95    Type(TypeDecl),
96    Fun(FunDecl),
97    Global(GlobalDecl),
98    TraitDecl(TraitDecl),
99    TraitImpl(TraitImpl),
100}
101
102/// A reference to a translated item.
103#[derive(
104    Debug, Clone, Copy, EnumIsA, EnumAsGetters, VariantName, VariantIndexArity, Drive, DriveMut,
105)]
106pub enum ItemRef<'ctx> {
107    Type(&'ctx TypeDecl),
108    Fun(&'ctx FunDecl),
109    Global(&'ctx GlobalDecl),
110    TraitDecl(&'ctx TraitDecl),
111    TraitImpl(&'ctx TraitImpl),
112}
113
114/// A mutable reference to a translated item.
115#[derive(Debug, EnumIsA, EnumAsGetters, VariantName, VariantIndexArity, Drive, DriveMut)]
116pub enum ItemRefMut<'ctx> {
117    Type(&'ctx mut TypeDecl),
118    Fun(&'ctx mut FunDecl),
119    Global(&'ctx mut GlobalDecl),
120    TraitDecl(&'ctx mut TraitDecl),
121    TraitImpl(&'ctx mut TraitImpl),
122}
123
124/// A (group of) top-level declaration(s), properly reordered.
125/// "G" stands for "generic"
126#[derive(
127    Debug, Clone, VariantIndexArity, VariantName, EnumAsGetters, EnumIsA, Serialize, Deserialize,
128)]
129#[charon::variants_suffix("Group")]
130pub enum GDeclarationGroup<Id> {
131    /// A non-recursive declaration
132    NonRec(Id),
133    /// A (group of mutually) recursive declaration(s)
134    Rec(Vec<Id>),
135}
136
137/// A (group of) top-level declaration(s), properly reordered.
138#[derive(
139    Debug, Clone, VariantIndexArity, VariantName, EnumAsGetters, EnumIsA, Serialize, Deserialize,
140)]
141#[charon::variants_suffix("Group")]
142pub enum DeclarationGroup {
143    /// A type declaration group
144    Type(GDeclarationGroup<TypeDeclId>),
145    /// A function declaration group
146    Fun(GDeclarationGroup<FunDeclId>),
147    /// A global declaration group
148    Global(GDeclarationGroup<GlobalDeclId>),
149    ///
150    TraitDecl(GDeclarationGroup<TraitDeclId>),
151    ///
152    TraitImpl(GDeclarationGroup<TraitImplId>),
153    /// Anything that doesn't fit into these categories.
154    Mixed(GDeclarationGroup<ItemId>),
155}
156
157pub type DeclarationsGroups = Vec<DeclarationGroup>;
158
159#[derive(Default, Clone, Drive, DriveMut, Serialize, Deserialize)]
160pub struct TargetInfo {
161    /// The pointer size of the target in bytes.
162    pub target_pointer_size: types::ByteCount,
163    /// Whether the target platform uses little endian byte order.
164    pub is_little_endian: bool,
165}
166
167/// The data of a translated crate.
168#[derive(Default, Clone, Drive, DriveMut, SerializeState, DeserializeState)]
169#[serde_state(state_implements = HashConsSerializerState)]
170pub struct TranslatedCrate {
171    /// The name of the crate.
172    #[drive(skip)]
173    pub crate_name: String,
174
175    /// The options used when calling Charon. It is useful for the applications
176    /// which consumed the serialized code, to check that Charon was called with
177    /// the proper options.
178    #[drive(skip)]
179    #[serde_state(stateless)]
180    pub options: crate::options::CliOpts,
181
182    /// Information about the target platform for which rustc is called on for the crate.
183    #[drive(skip)]
184    #[serde_state(stateless)]
185    pub target_information: TargetInfo,
186
187    /// The names of all registered items. Available so we can know the names even of items that
188    /// failed to translate.
189    /// Invariant: after translation, any existing `ItemId` must have an associated name, even
190    /// if the corresponding item wasn't translated.
191    #[serde(with = "SeqHashMapToArray::<ItemId, Name>")]
192    pub item_names: SeqHashMap<ItemId, Name>,
193    /// Short names, for items whose last PathElem is unique.
194    #[serde(with = "SeqHashMapToArray::<ItemId, Name>")]
195    pub short_names: SeqHashMap<ItemId, Name>,
196
197    /// The translated files.
198    #[drive(skip)]
199    #[serde_state(stateless)]
200    pub files: IndexVec<FileId, File>,
201    /// The translated type definitions
202    pub type_decls: IndexMap<TypeDeclId, TypeDecl>,
203    /// The translated function definitions
204    pub fun_decls: IndexMap<FunDeclId, FunDecl>,
205    /// The translated global definitions
206    pub global_decls: IndexMap<GlobalDeclId, GlobalDecl>,
207    /// The translated trait declarations
208    pub trait_decls: IndexMap<TraitDeclId, TraitDecl>,
209    /// The translated trait declarations
210    pub trait_impls: IndexMap<TraitImplId, TraitImpl>,
211    /// A `const UNIT: () = ();` used whenever we make a thin pointer/reference to avoid creating a
212    /// local `let unit = ();` variable. It is always `Some`.
213    pub unit_metadata: Option<GlobalDeclRef>,
214    /// The re-ordered groups of declarations, initialized as empty.
215    #[drive(skip)]
216    #[serde_state(stateless)]
217    pub ordered_decls: Option<DeclarationsGroups>,
218}
219
220impl TranslatedCrate {
221    pub fn item_name(&self, id: impl Into<ItemId>) -> Option<&Name> {
222        self.item_names.get(&id.into())
223    }
224
225    pub fn item_short_name(&self, id: impl Into<ItemId>) -> Option<&Name> {
226        let id = id.into();
227        self.short_names.get(&id).or_else(|| self.item_name(id))
228    }
229
230    pub fn get_item(&self, trans_id: impl Into<ItemId>) -> Option<ItemRef<'_>> {
231        match trans_id.into() {
232            ItemId::Type(id) => self.type_decls.get(id).map(ItemRef::Type),
233            ItemId::Fun(id) => self.fun_decls.get(id).map(ItemRef::Fun),
234            ItemId::Global(id) => self.global_decls.get(id).map(ItemRef::Global),
235            ItemId::TraitDecl(id) => self.trait_decls.get(id).map(ItemRef::TraitDecl),
236            ItemId::TraitImpl(id) => self.trait_impls.get(id).map(ItemRef::TraitImpl),
237        }
238    }
239    pub fn get_item_mut(&mut self, trans_id: ItemId) -> Option<ItemRefMut<'_>> {
240        match trans_id {
241            ItemId::Type(id) => self.type_decls.get_mut(id).map(ItemRefMut::Type),
242            ItemId::Fun(id) => self.fun_decls.get_mut(id).map(ItemRefMut::Fun),
243            ItemId::Global(id) => self.global_decls.get_mut(id).map(ItemRefMut::Global),
244            ItemId::TraitDecl(id) => self.trait_decls.get_mut(id).map(ItemRefMut::TraitDecl),
245            ItemId::TraitImpl(id) => self.trait_impls.get_mut(id).map(ItemRefMut::TraitImpl),
246        }
247    }
248    pub fn remove_item(&mut self, trans_id: ItemId) -> Option<ItemByVal> {
249        match trans_id {
250            ItemId::Type(id) => self.type_decls.remove(id).map(ItemByVal::Type),
251            ItemId::Fun(id) => self.fun_decls.remove(id).map(ItemByVal::Fun),
252            ItemId::Global(id) => self.global_decls.remove(id).map(ItemByVal::Global),
253            ItemId::TraitDecl(id) => self.trait_decls.remove(id).map(ItemByVal::TraitDecl),
254            ItemId::TraitImpl(id) => self.trait_impls.remove(id).map(ItemByVal::TraitImpl),
255        }
256    }
257    pub fn set_item_slot(&mut self, id: ItemId, item: ItemByVal) {
258        match item {
259            ItemByVal::Type(decl) => self.type_decls.set_slot(*id.as_type().unwrap(), decl),
260            ItemByVal::Fun(decl) => self.fun_decls.set_slot(*id.as_fun().unwrap(), decl),
261            ItemByVal::Global(decl) => self.global_decls.set_slot(*id.as_global().unwrap(), decl),
262            ItemByVal::TraitDecl(decl) => self
263                .trait_decls
264                .set_slot(*id.as_trait_decl().unwrap(), decl),
265            ItemByVal::TraitImpl(decl) => self
266                .trait_impls
267                .set_slot(*id.as_trait_impl().unwrap(), decl),
268        }
269    }
270
271    pub fn all_ids(&self) -> impl Iterator<Item = ItemId> + use<> {
272        self.type_decls
273            .all_indices()
274            .map(ItemId::Type)
275            .chain(self.trait_decls.all_indices().map(ItemId::TraitDecl))
276            .chain(self.trait_impls.all_indices().map(ItemId::TraitImpl))
277            .chain(self.global_decls.all_indices().map(ItemId::Global))
278            .chain(self.fun_decls.all_indices().map(ItemId::Fun))
279    }
280    pub fn all_items(&self) -> impl Iterator<Item = ItemRef<'_>> {
281        self.type_decls
282            .iter()
283            .map(ItemRef::Type)
284            .chain(self.trait_decls.iter().map(ItemRef::TraitDecl))
285            .chain(self.trait_impls.iter().map(ItemRef::TraitImpl))
286            .chain(self.global_decls.iter().map(ItemRef::Global))
287            .chain(self.fun_decls.iter().map(ItemRef::Fun))
288    }
289    pub fn all_items_mut(&mut self) -> impl Iterator<Item = ItemRefMut<'_>> {
290        self.type_decls
291            .iter_mut()
292            .map(ItemRefMut::Type)
293            .chain(self.trait_impls.iter_mut().map(ItemRefMut::TraitImpl))
294            .chain(self.trait_decls.iter_mut().map(ItemRefMut::TraitDecl))
295            .chain(self.fun_decls.iter_mut().map(ItemRefMut::Fun))
296            .chain(self.global_decls.iter_mut().map(ItemRefMut::Global))
297    }
298    pub fn all_items_with_ids(&self) -> impl Iterator<Item = (ItemId, ItemRef<'_>)> {
299        self.all_items().map(|item| (item.id(), item))
300    }
301}
302
303impl ItemByVal {
304    pub fn as_ref(&self) -> ItemRef<'_> {
305        match self {
306            Self::Type(d) => ItemRef::Type(d),
307            Self::Fun(d) => ItemRef::Fun(d),
308            Self::Global(d) => ItemRef::Global(d),
309            Self::TraitDecl(d) => ItemRef::TraitDecl(d),
310            Self::TraitImpl(d) => ItemRef::TraitImpl(d),
311        }
312    }
313    pub fn as_mut(&mut self) -> ItemRefMut<'_> {
314        match self {
315            Self::Type(d) => ItemRefMut::Type(d),
316            Self::Fun(d) => ItemRefMut::Fun(d),
317            Self::Global(d) => ItemRefMut::Global(d),
318            Self::TraitDecl(d) => ItemRefMut::TraitDecl(d),
319            Self::TraitImpl(d) => ItemRefMut::TraitImpl(d),
320        }
321    }
322}
323
324impl<'ctx> ItemRef<'ctx> {
325    pub fn id(&self) -> ItemId {
326        match self {
327            ItemRef::Type(d) => d.def_id.into(),
328            ItemRef::Fun(d) => d.def_id.into(),
329            ItemRef::Global(d) => d.def_id.into(),
330            ItemRef::TraitDecl(d) => d.def_id.into(),
331            ItemRef::TraitImpl(d) => d.def_id.into(),
332        }
333    }
334
335    pub fn clone(&self) -> ItemByVal {
336        match *self {
337            Self::Type(d) => ItemByVal::Type(d.clone()),
338            Self::Fun(d) => ItemByVal::Fun(d.clone()),
339            Self::Global(d) => ItemByVal::Global(d.clone()),
340            Self::TraitDecl(d) => ItemByVal::TraitDecl(d.clone()),
341            Self::TraitImpl(d) => ItemByVal::TraitImpl(d.clone()),
342        }
343    }
344
345    pub fn item_meta(&self) -> &'ctx ItemMeta {
346        match self {
347            Self::Type(d) => &d.item_meta,
348            Self::Fun(d) => &d.item_meta,
349            Self::Global(d) => &d.item_meta,
350            Self::TraitDecl(d) => &d.item_meta,
351            Self::TraitImpl(d) => &d.item_meta,
352        }
353    }
354    /// The generic parameters of this item.
355    pub fn generic_params(&self) -> &'ctx GenericParams {
356        match self {
357            ItemRef::Type(d) => &d.generics,
358            ItemRef::Fun(d) => &d.signature.generics,
359            ItemRef::Global(d) => &d.generics,
360            ItemRef::TraitDecl(d) => &d.generics,
361            ItemRef::TraitImpl(d) => &d.generics,
362        }
363    }
364
365    /// Get information about the parent of this item, if any.
366    pub fn parent_info(&self) -> &'ctx ItemSource {
367        match self {
368            ItemRef::Fun(d) => &d.src,
369            ItemRef::Global(d) => &d.src,
370            ItemRef::Type(_) | ItemRef::TraitDecl(_) | ItemRef::TraitImpl(_) => {
371                &ItemSource::TopLevel
372            }
373        }
374    }
375
376    /// See [`GenericParams::identity_args`].
377    pub fn identity_args(&self) -> GenericArgs {
378        self.generic_params().identity_args()
379    }
380
381    /// We can't implement `AstVisitable` because of the `'static` constraint, but it's ok because
382    /// `ItemRef` isn't contained in any of our types.
383    pub fn drive<V: VisitAst>(&self, visitor: &mut V) -> ControlFlow<V::Break> {
384        match *self {
385            ItemRef::Type(d) => visitor.visit(d),
386            ItemRef::Fun(d) => visitor.visit(d),
387            ItemRef::Global(d) => visitor.visit(d),
388            ItemRef::TraitDecl(d) => visitor.visit(d),
389            ItemRef::TraitImpl(d) => visitor.visit(d),
390        }
391    }
392
393    /// Visit all occurrences of that type inside `self`, in pre-order traversal.
394    pub fn dyn_visit<T: AstVisitable>(&self, f: impl FnMut(&T)) {
395        match *self {
396            ItemRef::Type(d) => d.dyn_visit(f),
397            ItemRef::Fun(d) => d.dyn_visit(f),
398            ItemRef::Global(d) => d.dyn_visit(f),
399            ItemRef::TraitDecl(d) => d.dyn_visit(f),
400            ItemRef::TraitImpl(d) => d.dyn_visit(f),
401        }
402    }
403}
404
405impl<'ctx> ItemRefMut<'ctx> {
406    pub fn as_ref(&self) -> ItemRef<'_> {
407        match self {
408            ItemRefMut::Type(d) => ItemRef::Type(d),
409            ItemRefMut::Fun(d) => ItemRef::Fun(d),
410            ItemRefMut::Global(d) => ItemRef::Global(d),
411            ItemRefMut::TraitDecl(d) => ItemRef::TraitDecl(d),
412            ItemRefMut::TraitImpl(d) => ItemRef::TraitImpl(d),
413        }
414    }
415    pub fn reborrow(&mut self) -> ItemRefMut<'_> {
416        match self {
417            ItemRefMut::Type(d) => ItemRefMut::Type(d),
418            ItemRefMut::Fun(d) => ItemRefMut::Fun(d),
419            ItemRefMut::Global(d) => ItemRefMut::Global(d),
420            ItemRefMut::TraitDecl(d) => ItemRefMut::TraitDecl(d),
421            ItemRefMut::TraitImpl(d) => ItemRefMut::TraitImpl(d),
422        }
423    }
424
425    pub fn set_id(&mut self, id: ItemId) {
426        match (self, id) {
427            (Self::Type(d), ItemId::Type(id)) => d.def_id = id,
428            (Self::Fun(d), ItemId::Fun(id)) => d.def_id = id,
429            (Self::Global(d), ItemId::Global(id)) => d.def_id = id,
430            (Self::TraitDecl(d), ItemId::TraitDecl(id)) => d.def_id = id,
431            (Self::TraitImpl(d), ItemId::TraitImpl(id)) => d.def_id = id,
432            _ => unreachable!(),
433        }
434    }
435
436    pub fn item_meta(&mut self) -> &mut ItemMeta {
437        match self {
438            Self::Type(d) => &mut d.item_meta,
439            Self::Fun(d) => &mut d.item_meta,
440            Self::Global(d) => &mut d.item_meta,
441            Self::TraitDecl(d) => &mut d.item_meta,
442            Self::TraitImpl(d) => &mut d.item_meta,
443        }
444    }
445    /// The generic parameters of this item.
446    pub fn generic_params(&mut self) -> &mut GenericParams {
447        match self {
448            ItemRefMut::Type(d) => &mut d.generics,
449            ItemRefMut::Fun(d) => &mut d.signature.generics,
450            ItemRefMut::Global(d) => &mut d.generics,
451            ItemRefMut::TraitDecl(d) => &mut d.generics,
452            ItemRefMut::TraitImpl(d) => &mut d.generics,
453        }
454    }
455
456    /// We can't implement `AstVisitable` because of the `'static` constraint, but it's ok because
457    /// `ItemRefMut` isn't contained in any of our types.
458    pub fn drive_mut<V: VisitAstMut>(&mut self, visitor: &mut V) -> ControlFlow<V::Break> {
459        match self {
460            ItemRefMut::Type(d) => visitor.visit(*d),
461            ItemRefMut::Fun(d) => visitor.visit(*d),
462            ItemRefMut::Global(d) => visitor.visit(*d),
463            ItemRefMut::TraitDecl(d) => visitor.visit(*d),
464            ItemRefMut::TraitImpl(d) => visitor.visit(*d),
465        }
466    }
467
468    /// Visit all occurrences of that type inside `self`, in pre-order traversal.
469    pub fn dyn_visit_mut<T: AstVisitable>(&mut self, f: impl FnMut(&mut T)) {
470        match self {
471            ItemRefMut::Type(d) => d.dyn_visit_mut(f),
472            ItemRefMut::Fun(d) => d.dyn_visit_mut(f),
473            ItemRefMut::Global(d) => d.dyn_visit_mut(f),
474            ItemRefMut::TraitDecl(d) => d.dyn_visit_mut(f),
475            ItemRefMut::TraitImpl(d) => d.dyn_visit_mut(f),
476        }
477    }
478}
479
480impl fmt::Display for TranslatedCrate {
481    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
482        let fmt: &FmtCtx = &self.into_fmt();
483        match &self.ordered_decls {
484            None => {
485                // We do simple: types, globals, traits, functions
486                for d in &self.type_decls {
487                    writeln!(f, "{}\n", d.with_ctx(fmt))?
488                }
489                for d in &self.global_decls {
490                    writeln!(f, "{}\n", d.with_ctx(fmt))?
491                }
492                for d in &self.trait_decls {
493                    writeln!(f, "{}\n", d.with_ctx(fmt))?
494                }
495                for d in &self.trait_impls {
496                    writeln!(f, "{}\n", d.with_ctx(fmt))?
497                }
498                for d in &self.fun_decls {
499                    writeln!(f, "{}\n", d.with_ctx(fmt))?
500                }
501            }
502            Some(ordered_decls) => {
503                for gr in ordered_decls {
504                    for id in gr.get_ids() {
505                        writeln!(f, "{}\n", fmt.format_decl_id(id))?
506                    }
507                }
508            }
509        }
510        fmt::Result::Ok(())
511    }
512}
513
514impl<'tcx, 'ctx, 'a> IntoFormatter for &'a TranslatedCrate {
515    type C = FmtCtx<'a>;
516
517    fn into_fmt(self) -> Self::C {
518        FmtCtx {
519            translated: Some(self),
520            ..Default::default()
521        }
522    }
523}
524
525pub trait HasIdxMapOf<Id: Idx>: std::ops::Index<Id, Output: Sized> {
526    fn get_idx_map(&self) -> &IndexMap<Id, Self::Output>;
527    fn get_idx_map_mut(&mut self) -> &mut IndexMap<Id, Self::Output>;
528}
529
530/// Delegate `Index` implementations to subfields.
531macro_rules! mk_index_impls {
532    ($ty:ident.$field:ident[$idx:ty]: $output:ty) => {
533        impl std::ops::Index<$idx> for $ty {
534            type Output = $output;
535            fn index(&self, index: $idx) -> &Self::Output {
536                &self.$field[index]
537            }
538        }
539        impl std::ops::IndexMut<$idx> for $ty {
540            fn index_mut(&mut self, index: $idx) -> &mut Self::Output {
541                &mut self.$field[index]
542            }
543        }
544        impl HasIdxMapOf<$idx> for $ty {
545            fn get_idx_map(&self) -> &IndexMap<$idx, Self::Output> {
546                &self.$field
547            }
548            fn get_idx_map_mut(&mut self) -> &mut IndexMap<$idx, Self::Output> {
549                &mut self.$field
550            }
551        }
552    };
553}
554pub(crate) use mk_index_impls;
555
556mk_index_impls!(TranslatedCrate.type_decls[TypeDeclId]: TypeDecl);
557mk_index_impls!(TranslatedCrate.fun_decls[FunDeclId]: FunDecl);
558mk_index_impls!(TranslatedCrate.global_decls[GlobalDeclId]: GlobalDecl);
559mk_index_impls!(TranslatedCrate.trait_decls[TraitDeclId]: TraitDecl);
560mk_index_impls!(TranslatedCrate.trait_impls[TraitImplId]: TraitImpl);