charon_lib/ast/
types_utils.rs

1//! This file groups everything which is linked to implementations about [crate::types]
2use crate::ast::*;
3use crate::formatter::IntoFormatter;
4use crate::ids::Vector;
5use crate::pretty::FmtWithCtx;
6use derive_generic_visitor::*;
7use itertools::Itertools;
8use std::collections::HashSet;
9use std::convert::Infallible;
10use std::fmt::Debug;
11use std::iter::Iterator;
12use std::mem;
13
14impl TraitParam {
15    /// Constructs the trait ref that refers to this clause.
16    pub fn identity_tref(&self) -> TraitRef {
17        self.identity_tref_at_depth(DeBruijnId::zero())
18    }
19
20    /// Like `identity_tref` but uses variables bound at the given depth.
21    pub fn identity_tref_at_depth(&self, depth: DeBruijnId) -> TraitRef {
22        TraitRef {
23            kind: TraitRefKind::Clause(DeBruijnVar::bound(depth, self.clause_id)),
24            trait_decl_ref: self.trait_.clone().move_under_binders(depth),
25        }
26    }
27}
28
29impl GenericParams {
30    pub fn empty() -> Self {
31        Self::default()
32    }
33
34    pub fn is_empty(&self) -> bool {
35        self.len() == 0
36    }
37    /// Whether this has any explicit arguments (types, regions or const generics).
38    pub fn has_explicits(&self) -> bool {
39        !self.regions.is_empty() || !self.types.is_empty() || !self.const_generics.is_empty()
40    }
41    /// Whether this has any implicit arguments (trait clauses, outlives relations, associated type
42    /// equality constraints).
43    pub fn has_predicates(&self) -> bool {
44        !self.trait_clauses.is_empty()
45            || !self.types_outlive.is_empty()
46            || !self.regions_outlive.is_empty()
47            || !self.trait_type_constraints.is_empty()
48    }
49
50    /// Run some sanity checks.
51    pub fn check_consistency(&self) {
52        // Sanity check: check the clause ids are consistent.
53        assert!(
54            self.trait_clauses
55                .iter()
56                .enumerate()
57                .all(|(i, c)| c.clause_id.index() == i)
58        );
59
60        // Sanity check: region names are pairwise distinct (this caused trouble when generating
61        // names for the backward functions in Aeneas): at some point, Rustc introduced names equal
62        // to `Some("'_")` for the anonymous regions, instead of using `None` (we now check in
63        // [translate_region_name] and ignore names equal to "'_").
64        let mut s = HashSet::new();
65        for r in &self.regions {
66            if let Some(name) = &r.name {
67                assert!(
68                    !s.contains(name),
69                    "Name \"{}\" reused for two different lifetimes",
70                    name
71                );
72                s.insert(name);
73            }
74        }
75    }
76
77    pub fn len(&self) -> usize {
78        let GenericParams {
79            regions,
80            types,
81            const_generics,
82            trait_clauses,
83            regions_outlive,
84            types_outlive,
85            trait_type_constraints,
86        } = self;
87        regions.elem_count()
88            + types.elem_count()
89            + const_generics.elem_count()
90            + trait_clauses.elem_count()
91            + regions_outlive.len()
92            + types_outlive.len()
93            + trait_type_constraints.elem_count()
94    }
95
96    /// Construct a set of generic arguments in the scope of `self` that matches `self` and feeds
97    /// each required parameter with itself. E.g. given parameters for `<T, U> where U:
98    /// PartialEq<T>`, the arguments would be `<T, U>[@TraitClause0]`.
99    pub fn identity_args(&self) -> GenericArgs {
100        self.identity_args_at_depth(DeBruijnId::zero())
101    }
102
103    /// Like `identity_args` but uses variables bound at the given depth.
104    pub fn identity_args_at_depth(&self, depth: DeBruijnId) -> GenericArgs {
105        GenericArgs {
106            regions: self
107                .regions
108                .map_ref_indexed(|id, _| Region::Var(DeBruijnVar::bound(depth, id))),
109            types: self
110                .types
111                .map_ref_indexed(|id, _| TyKind::TypeVar(DeBruijnVar::bound(depth, id)).into_ty()),
112            const_generics: self
113                .const_generics
114                .map_ref_indexed(|id, _| ConstGeneric::Var(DeBruijnVar::bound(depth, id))),
115            trait_refs: self
116                .trait_clauses
117                .map_ref(|clause| clause.identity_tref_at_depth(depth)),
118        }
119    }
120
121    /// Take the predicates from the another `GenericParams`.
122    pub fn take_predicates_from(&mut self, other: GenericParams) {
123        assert!(!other.has_explicits());
124        let GenericParams {
125            regions: _,
126            types: _,
127            const_generics: _,
128            trait_clauses,
129            regions_outlive,
130            types_outlive,
131            trait_type_constraints,
132        } = other;
133        let num_clauses = self.trait_clauses.slot_count();
134        self.trait_clauses
135            .extend(trait_clauses.into_iter().update(|clause| {
136                clause.clause_id += num_clauses;
137            }));
138        self.regions_outlive.extend(regions_outlive);
139        self.types_outlive.extend(types_outlive);
140        self.trait_type_constraints.extend(trait_type_constraints);
141    }
142}
143
144impl<T> Binder<T> {
145    /// Wrap the value in an empty binder, shifting variables appropriately.
146    pub fn empty(kind: BinderKind, x: T) -> Self
147    where
148        T: TyVisitable,
149    {
150        Binder {
151            params: Default::default(),
152            skip_binder: x.move_under_binder(),
153            kind,
154        }
155    }
156    pub fn new(kind: BinderKind, params: GenericParams, skip_binder: T) -> Self {
157        Self {
158            params,
159            skip_binder,
160            kind,
161        }
162    }
163
164    /// Whether this binder binds any variables.
165    pub fn binds_anything(&self) -> bool {
166        !self.params.is_empty()
167    }
168
169    /// Retreive the contents of this binder if the binder binds no variables. This is the invers
170    /// of `Binder::empty`.
171    pub fn get_if_binds_nothing(&self) -> Option<T>
172    where
173        T: TyVisitable + Clone,
174    {
175        self.params
176            .is_empty()
177            .then(|| self.skip_binder.clone().move_from_under_binder().unwrap())
178    }
179
180    pub fn map<U>(self, f: impl FnOnce(T) -> U) -> Binder<U> {
181        Binder {
182            params: self.params,
183            skip_binder: f(self.skip_binder),
184            kind: self.kind.clone(),
185        }
186    }
187
188    pub fn map_ref<U>(&self, f: impl FnOnce(&T) -> U) -> Binder<U> {
189        Binder {
190            params: self.params.clone(),
191            skip_binder: f(&self.skip_binder),
192            kind: self.kind.clone(),
193        }
194    }
195
196    /// Substitute the provided arguments for the variables bound in this binder and return the
197    /// substituted inner value.
198    pub fn apply(self, args: &GenericArgs) -> T
199    where
200        T: TyVisitable,
201    {
202        self.skip_binder.substitute(args)
203    }
204}
205
206impl<T: AstVisitable> Binder<Binder<T>> {
207    /// Flatten two levels of binders into a single one.
208    pub fn flatten(self) -> Binder<T> {
209        #[derive(Visitor)]
210        struct FlattenVisitor<'a> {
211            shift_by: &'a GenericParams,
212            binder_depth: DeBruijnId,
213        }
214        impl VisitorWithBinderDepth for FlattenVisitor<'_> {
215            fn binder_depth_mut(&mut self) -> &mut DeBruijnId {
216                &mut self.binder_depth
217            }
218        }
219        impl VisitAstMut for FlattenVisitor<'_> {
220            fn visit<'a, T: AstVisitable>(&'a mut self, x: &mut T) -> ControlFlow<Self::Break> {
221                VisitWithBinderDepth::new(self).visit(x)
222            }
223
224            fn enter_de_bruijn_id(&mut self, db_id: &mut DeBruijnId) {
225                if *db_id > self.binder_depth {
226                    // We started visiting at the inner binder, so in this branch we're either
227                    // mentioning the outer binder or a binder further beyond. Either way we
228                    // decrease the depth; variables that point to the outer binder don't have to
229                    // be shifted.
230                    *db_id = db_id.decr();
231                }
232            }
233            fn enter_region(&mut self, x: &mut Region) {
234                if let Region::Var(var) = x
235                    && let Some(id) = var.bound_at_depth_mut(self.binder_depth)
236                {
237                    *id += self.shift_by.regions.slot_count();
238                }
239            }
240            fn enter_ty_kind(&mut self, x: &mut TyKind) {
241                if let TyKind::TypeVar(var) = x
242                    && let Some(id) = var.bound_at_depth_mut(self.binder_depth)
243                {
244                    *id += self.shift_by.types.slot_count();
245                }
246            }
247            fn enter_const_generic(&mut self, x: &mut ConstGeneric) {
248                if let ConstGeneric::Var(var) = x
249                    && let Some(id) = var.bound_at_depth_mut(self.binder_depth)
250                {
251                    *id += self.shift_by.const_generics.slot_count();
252                }
253            }
254            fn enter_trait_ref_kind(&mut self, x: &mut TraitRefKind) {
255                if let TraitRefKind::Clause(var) = x
256                    && let Some(id) = var.bound_at_depth_mut(self.binder_depth)
257                {
258                    *id += self.shift_by.trait_clauses.slot_count();
259                }
260            }
261        }
262
263        // We will concatenate both sets of params.
264        let mut outer_params = self.params;
265
266        // The inner value needs to change:
267        // - at binder level 0 we shift all variable ids to match the concatenated params;
268        // - at binder level > 0 we decrease binding level because there's one fewer binder.
269        let mut bound_value = self.skip_binder.skip_binder;
270        let _ = bound_value.drive_mut(&mut FlattenVisitor {
271            shift_by: &outer_params,
272            binder_depth: Default::default(),
273        });
274
275        // The inner params must also be updated, as they can refer to themselves and the outer
276        // one.
277        let mut inner_params = self.skip_binder.params;
278        let _ = inner_params.drive_mut(&mut FlattenVisitor {
279            shift_by: &outer_params,
280            binder_depth: Default::default(),
281        });
282        inner_params
283            .regions
284            .iter_mut()
285            .for_each(|v| v.index += outer_params.regions.slot_count());
286        inner_params
287            .types
288            .iter_mut()
289            .for_each(|v| v.index += outer_params.types.slot_count());
290        inner_params
291            .const_generics
292            .iter_mut()
293            .for_each(|v| v.index += outer_params.const_generics.slot_count());
294        inner_params
295            .trait_clauses
296            .iter_mut()
297            .for_each(|v| v.clause_id += outer_params.trait_clauses.slot_count());
298
299        let GenericParams {
300            regions,
301            types,
302            const_generics,
303            trait_clauses,
304            regions_outlive,
305            types_outlive,
306            trait_type_constraints,
307        } = &inner_params;
308        outer_params.regions.extend_from_slice(regions);
309        outer_params.types.extend_from_slice(types);
310        outer_params
311            .const_generics
312            .extend_from_slice(const_generics);
313        outer_params.trait_clauses.extend_from_slice(trait_clauses);
314        outer_params
315            .regions_outlive
316            .extend_from_slice(regions_outlive);
317        outer_params.types_outlive.extend_from_slice(types_outlive);
318        outer_params
319            .trait_type_constraints
320            .extend_from_slice(trait_type_constraints);
321
322        Binder {
323            params: outer_params,
324            skip_binder: bound_value,
325            kind: BinderKind::Other,
326        }
327    }
328}
329
330impl<T> RegionBinder<T> {
331    /// Wrap the value in an empty region binder, shifting variables appropriately.
332    pub fn empty(x: T) -> Self
333    where
334        T: TyVisitable,
335    {
336        RegionBinder {
337            regions: Default::default(),
338            skip_binder: x.move_under_binder(),
339        }
340    }
341
342    pub fn map<U>(self, f: impl FnOnce(T) -> U) -> RegionBinder<U> {
343        RegionBinder {
344            regions: self.regions,
345            skip_binder: f(self.skip_binder),
346        }
347    }
348
349    pub fn map_ref<U>(&self, f: impl FnOnce(&T) -> U) -> RegionBinder<U> {
350        RegionBinder {
351            regions: self.regions.clone(),
352            skip_binder: f(&self.skip_binder),
353        }
354    }
355
356    /// Substitute the bound variables with the given lifetimes.
357    pub fn apply(self, regions: Vector<RegionId, Region>) -> T
358    where
359        T: AstVisitable,
360    {
361        assert_eq!(regions.slot_count(), self.regions.slot_count());
362        let args = GenericArgs {
363            regions,
364            ..GenericArgs::empty()
365        };
366        self.skip_binder.substitute(&args)
367    }
368
369    /// Substitute the bound variables with erased lifetimes.
370    pub fn erase(self) -> T
371    where
372        T: AstVisitable,
373    {
374        let regions = self.regions.map_ref_indexed(|_, _| Region::Erased);
375        self.apply(regions)
376    }
377}
378
379impl GenericArgs {
380    pub fn len(&self) -> usize {
381        let GenericArgs {
382            regions,
383            types,
384            const_generics,
385            trait_refs,
386        } = self;
387        regions.elem_count()
388            + types.elem_count()
389            + const_generics.elem_count()
390            + trait_refs.elem_count()
391    }
392
393    pub fn is_empty(&self) -> bool {
394        self.len() == 0
395    }
396    /// Whether this has any explicit arguments (types, regions or const generics).
397    pub fn has_explicits(&self) -> bool {
398        !self.regions.is_empty() || !self.types.is_empty() || !self.const_generics.is_empty()
399    }
400    /// Whether this has any implicit arguments (trait refs).
401    pub fn has_implicits(&self) -> bool {
402        !self.trait_refs.is_empty()
403    }
404
405    pub fn empty() -> Self {
406        GenericArgs {
407            regions: Default::default(),
408            types: Default::default(),
409            const_generics: Default::default(),
410            trait_refs: Default::default(),
411        }
412    }
413
414    pub fn new_for_builtin(types: Vector<TypeVarId, Ty>) -> Self {
415        GenericArgs {
416            types,
417            ..Self::empty()
418        }
419    }
420
421    pub fn new(
422        regions: Vector<RegionId, Region>,
423        types: Vector<TypeVarId, Ty>,
424        const_generics: Vector<ConstGenericVarId, ConstGeneric>,
425        trait_refs: Vector<TraitClauseId, TraitRef>,
426    ) -> Self {
427        Self {
428            regions,
429            types,
430            const_generics,
431            trait_refs,
432        }
433    }
434
435    pub fn new_types(types: Vector<TypeVarId, Ty>) -> Self {
436        Self {
437            types,
438            ..Self::empty()
439        }
440    }
441
442    /// Check whether this matches the given `GenericParams`.
443    /// TODO: check more things, e.g. that the trait refs use the correct trait and generics.
444    pub fn matches(&self, params: &GenericParams) -> bool {
445        params.regions.elem_count() == self.regions.elem_count()
446            && params.types.elem_count() == self.types.elem_count()
447            && params.const_generics.elem_count() == self.const_generics.elem_count()
448            && params.trait_clauses.elem_count() == self.trait_refs.elem_count()
449    }
450
451    /// Return the same generics, but where we pop the first type arguments.
452    /// This is useful for trait references (for pretty printing for instance),
453    /// because the first type argument is the type for which the trait is
454    /// implemented.
455    pub fn pop_first_type_arg(&self) -> (Ty, Self) {
456        let mut generics = self.clone();
457        let mut it = mem::take(&mut generics.types).into_iter();
458        let ty = it.next().unwrap();
459        generics.types = it.collect();
460        (ty, generics)
461    }
462
463    /// Concatenate this set of arguments with another one. Use with care, you must manage the
464    /// order of arguments correctly.
465    pub fn concat(mut self, other: &Self) -> Self {
466        let Self {
467            regions,
468            types,
469            const_generics,
470            trait_refs,
471        } = other;
472        self.regions.extend_from_slice(regions);
473        self.types.extend_from_slice(types);
474        self.const_generics.extend_from_slice(const_generics);
475        self.trait_refs.extend_from_slice(trait_refs);
476        self
477    }
478}
479
480impl IntTy {
481    /// Important: this returns the target byte count for the types.
482    /// Must not be used for host types from rustc.
483    pub fn target_size(&self, ptr_size: ByteCount) -> usize {
484        match self {
485            IntTy::Isize => ptr_size as usize,
486            IntTy::I8 => size_of::<i8>(),
487            IntTy::I16 => size_of::<i16>(),
488            IntTy::I32 => size_of::<i32>(),
489            IntTy::I64 => size_of::<i64>(),
490            IntTy::I128 => size_of::<i128>(),
491        }
492    }
493}
494impl UIntTy {
495    /// Important: this returns the target byte count for the types.
496    /// Must not be used for host types from rustc.
497    pub fn target_size(&self, ptr_size: ByteCount) -> usize {
498        match self {
499            UIntTy::Usize => ptr_size as usize,
500            UIntTy::U8 => size_of::<u8>(),
501            UIntTy::U16 => size_of::<u16>(),
502            UIntTy::U32 => size_of::<u32>(),
503            UIntTy::U64 => size_of::<u64>(),
504            UIntTy::U128 => size_of::<u128>(),
505        }
506    }
507}
508impl FloatTy {
509    /// Important: this returns the target byte count for the types.
510    /// Must not be used for host types from rustc.
511    pub fn target_size(&self) -> usize {
512        match self {
513            FloatTy::F16 => size_of::<u16>(),
514            FloatTy::F32 => size_of::<u32>(),
515            FloatTy::F64 => size_of::<u64>(),
516            FloatTy::F128 => size_of::<u128>(),
517        }
518    }
519}
520
521impl IntegerTy {
522    pub fn to_unsigned(&self) -> Self {
523        match self {
524            IntegerTy::Signed(IntTy::Isize) => IntegerTy::Unsigned(UIntTy::Usize),
525            IntegerTy::Signed(IntTy::I8) => IntegerTy::Unsigned(UIntTy::U8),
526            IntegerTy::Signed(IntTy::I16) => IntegerTy::Unsigned(UIntTy::U16),
527            IntegerTy::Signed(IntTy::I32) => IntegerTy::Unsigned(UIntTy::U32),
528            IntegerTy::Signed(IntTy::I64) => IntegerTy::Unsigned(UIntTy::U64),
529            IntegerTy::Signed(IntTy::I128) => IntegerTy::Unsigned(UIntTy::U128),
530            _ => *self,
531        }
532    }
533
534    /// Important: this returns the target byte count for the types.
535    /// Must not be used for host types from rustc.
536    pub fn target_size(&self, ptr_size: ByteCount) -> usize {
537        match self {
538            IntegerTy::Signed(ty) => ty.target_size(ptr_size),
539            IntegerTy::Unsigned(ty) => ty.target_size(ptr_size),
540        }
541    }
542}
543
544impl LiteralTy {
545    pub fn to_integer_ty(&self) -> Option<IntegerTy> {
546        match self {
547            Self::Int(int_ty) => Some(IntegerTy::Signed(*int_ty)),
548            Self::UInt(uint_ty) => Some(IntegerTy::Unsigned(*uint_ty)),
549            _ => None,
550        }
551    }
552
553    /// Important: this returns the target byte count for the types.
554    /// Must not be used for host types from rustc.
555    pub fn target_size(&self, ptr_size: ByteCount) -> usize {
556        match self {
557            LiteralTy::Int(int_ty) => int_ty.target_size(ptr_size),
558            LiteralTy::UInt(uint_ty) => uint_ty.target_size(ptr_size),
559            LiteralTy::Float(float_ty) => float_ty.target_size(),
560            LiteralTy::Char => 4,
561            LiteralTy::Bool => 1,
562        }
563    }
564}
565
566/// A value of type `T` bound by the generic parameters of item
567/// `item`. Used when dealing with multiple items at a time, to
568/// ensure we don't mix up generics.
569///
570/// To get the value, use `under_binder_of` or `subst_for`.
571#[derive(Debug, Clone, Copy)]
572pub struct ItemBinder<ItemId, T> {
573    pub item_id: ItemId,
574    val: T,
575}
576
577impl<ItemId, T> ItemBinder<ItemId, T>
578where
579    ItemId: Debug + Copy + PartialEq,
580{
581    pub fn new(item_id: ItemId, val: T) -> Self {
582        Self { item_id, val }
583    }
584
585    pub fn as_ref(&self) -> ItemBinder<ItemId, &T> {
586        ItemBinder {
587            item_id: self.item_id,
588            val: &self.val,
589        }
590    }
591
592    pub fn map_bound<U>(self, f: impl FnOnce(T) -> U) -> ItemBinder<ItemId, U> {
593        ItemBinder {
594            item_id: self.item_id,
595            val: f(self.val),
596        }
597    }
598
599    fn assert_item_id(&self, item_id: ItemId) {
600        assert_eq!(
601            self.item_id, item_id,
602            "Trying to use item bound for {:?} as if it belonged to {:?}",
603            self.item_id, item_id
604        );
605    }
606
607    /// Assert that the value is bound for item `item_id`, and returns it. This is used when we
608    /// plan to store the returned value inside that item.
609    pub fn under_binder_of(self, item_id: ItemId) -> T {
610        self.assert_item_id(item_id);
611        self.val
612    }
613
614    /// Given generic args for `item_id`, assert that the value is bound for `item_id` and
615    /// substitute it with the provided generic arguments. Because the arguments are bound in the
616    /// context of another item, so it the resulting substituted value.
617    pub fn substitute<OtherItem: Debug + Copy + PartialEq>(
618        self,
619        args: ItemBinder<OtherItem, &GenericArgs>,
620    ) -> ItemBinder<OtherItem, T>
621    where
622        ItemId: Into<ItemId>,
623        T: TyVisitable,
624    {
625        args.map_bound(|args| self.val.substitute(args))
626    }
627}
628
629/// Dummy item identifier that represents the current item when not ambiguous.
630#[derive(Debug, Clone, Copy, PartialEq, Eq)]
631pub struct CurrentItem;
632
633impl<T> ItemBinder<CurrentItem, T> {
634    pub fn under_current_binder(self) -> T {
635        self.val
636    }
637}
638
639impl Ty {
640    /// Return the unit type
641    pub fn mk_unit() -> Ty {
642        Self::mk_tuple(vec![])
643    }
644
645    pub fn mk_usize() -> Ty {
646        TyKind::Literal(LiteralTy::UInt(UIntTy::Usize)).into()
647    }
648
649    pub fn mk_tuple(tys: Vec<Ty>) -> Ty {
650        TyKind::Adt(TypeDeclRef {
651            id: TypeId::Tuple,
652            generics: Box::new(GenericArgs::new_for_builtin(tys.into())),
653        })
654        .into_ty()
655    }
656
657    pub fn mk_slice(ty: Ty) -> Ty {
658        TyKind::Adt(TypeDeclRef {
659            id: TypeId::Builtin(BuiltinTy::Slice),
660            generics: Box::new(GenericArgs::new_for_builtin(vec![ty].into())),
661        })
662        .into_ty()
663    }
664    /// Return true if it is actually unit (i.e.: 0-tuple)
665    pub fn is_unit(&self) -> bool {
666        match self.as_tuple() {
667            Some(tys) => tys.is_empty(),
668            None => false,
669        }
670    }
671
672    /// Return true if this is a scalar type
673    pub fn is_scalar(&self) -> bool {
674        match self.kind() {
675            TyKind::Literal(kind) => kind.is_int() || kind.is_uint(),
676            _ => false,
677        }
678    }
679
680    pub fn is_unsigned_scalar(&self) -> bool {
681        matches!(self.kind(), TyKind::Literal(LiteralTy::UInt(_)))
682    }
683
684    pub fn is_signed_scalar(&self) -> bool {
685        matches!(self.kind(), TyKind::Literal(LiteralTy::Int(_)))
686    }
687
688    /// Return true if the type is Box
689    pub fn is_box(&self) -> bool {
690        match self.kind() {
691            TyKind::Adt(ty_ref) if let TypeId::Builtin(BuiltinTy::Box) = ty_ref.id => true,
692            _ => false,
693        }
694    }
695
696    pub fn as_box(&self) -> Option<&Ty> {
697        match self.kind() {
698            TyKind::Adt(ty_ref) if let TypeId::Builtin(BuiltinTy::Box) = ty_ref.id => {
699                Some(&ty_ref.generics.types[0])
700            }
701            _ => None,
702        }
703    }
704
705    pub fn get_ptr_metadata(&self, translated: &TranslatedCrate) -> PtrMetadata {
706        let ref ty_decls = translated.type_decls;
707        match self.kind() {
708            TyKind::Adt(ty_ref) => {
709                // there are two cases:
710                // 1. if the declared type has a fixed metadata, just returns it
711                // 2. if it depends on some other types or the generic itself
712                match ty_ref.id {
713                    TypeId::Adt(type_decl_id) => {
714                        let Some(decl) = ty_decls.get(type_decl_id) else {
715                            return PtrMetadata::InheritFrom(Ty::new(TyKind::Error(format!(
716                                "Internal Error: type decl id not found during getting metadata: {type_decl_id}"
717                            ))));
718                        };
719                        match &decl.ptr_metadata {
720                            // if it depends on some type, recursion with the binding env
721                            PtrMetadata::InheritFrom(ty) => {
722                                let ty = ty.clone().substitute(&ty_ref.generics);
723                                ty.get_ptr_metadata(translated)
724                            }
725                            // otherwise, simply returns it
726                            meta => meta.clone().substitute(&ty_ref.generics),
727                        }
728                    }
729                    // the metadata of a tuple is simply the last field
730                    TypeId::Tuple => {
731                        match ty_ref.generics.types.iter().last() {
732                            // `None` refers to the unit type `()`
733                            None => PtrMetadata::None,
734                            // Otherwise, simply recurse
735                            Some(ty) => ty.get_ptr_metadata(translated),
736                        }
737                    }
738                    // Box is a pointer like ref & raw ptr, hence no metadata
739                    TypeId::Builtin(BuiltinTy::Box) => PtrMetadata::None,
740                    // Array: `[T; N]` has no metadata
741                    TypeId::Builtin(BuiltinTy::Array) => PtrMetadata::None,
742                    // `[T]` & `str` all have metadata length
743                    TypeId::Builtin(BuiltinTy::Slice) => PtrMetadata::Length,
744                    TypeId::Builtin(BuiltinTy::Str) => PtrMetadata::Length,
745                }
746            }
747            TyKind::DynTrait(pred) => match pred.vtable_ref(translated) {
748                Some(vtable) => PtrMetadata::VTable(vtable),
749                None => PtrMetadata::InheritFrom(
750                    TyKind::Error(format!(
751                        "Vtable for dyn trait {} not found",
752                        pred.with_ctx(&translated.into_fmt())
753                    ))
754                    .into(),
755                ),
756            },
757            TyKind::TraitType(..) | TyKind::TypeVar(_) => PtrMetadata::InheritFrom(self.clone()),
758            TyKind::Literal(_)
759            | TyKind::Never
760            | TyKind::Ref(..)
761            | TyKind::RawPtr(..)
762            | TyKind::FnPtr(..)
763            | TyKind::FnDef(..)
764            | TyKind::Error(_) => PtrMetadata::None,
765            // The metadata itself must be Sized, hence must with `PtrMetadata::None`
766            TyKind::PtrMetadata(_) => PtrMetadata::None,
767        }
768    }
769
770    pub fn as_array_or_slice(&self) -> Option<&Ty> {
771        match self.kind() {
772            TyKind::Adt(ty_ref)
773                if let TypeId::Builtin(BuiltinTy::Array | BuiltinTy::Slice) = ty_ref.id =>
774            {
775                Some(&ty_ref.generics.types[0])
776            }
777            _ => None,
778        }
779    }
780
781    pub fn as_tuple(&self) -> Option<&Vector<TypeVarId, Ty>> {
782        match self.kind() {
783            TyKind::Adt(ty_ref) if let TypeId::Tuple = ty_ref.id => Some(&ty_ref.generics.types),
784            _ => None,
785        }
786    }
787
788    pub fn as_adt(&self) -> Option<&TypeDeclRef> {
789        self.kind().as_adt()
790    }
791}
792
793impl TyKind {
794    pub fn into_ty(self) -> Ty {
795        Ty::new(self)
796    }
797}
798
799impl From<TyKind> for Ty {
800    fn from(kind: TyKind) -> Ty {
801        kind.into_ty()
802    }
803}
804
805/// Convenience for migration purposes.
806impl std::ops::Deref for Ty {
807    type Target = TyKind;
808
809    fn deref(&self) -> &Self::Target {
810        self.kind()
811    }
812}
813/// For deref patterns.
814unsafe impl std::ops::DerefPure for Ty {}
815
816impl TypeDeclRef {
817    pub fn new(id: TypeId, generics: GenericArgs) -> Self {
818        Self {
819            id,
820            generics: Box::new(generics),
821        }
822    }
823}
824
825impl TraitDeclRef {
826    pub fn self_ty<'a>(&'a self, krate: &'a TranslatedCrate) -> Option<&'a Ty> {
827        match self.generics.types.iter().next() {
828            Some(ty) => return Some(ty),
829            // TODO(mono): A monomorphized trait takes no arguments.
830            None => {
831                let name = krate.item_name(self.id)?;
832                let args = name.name.last()?.as_monomorphized()?;
833                args.types.iter().next()
834            }
835        }
836    }
837}
838
839impl TraitRef {
840    pub fn new_builtin(
841        trait_id: TraitDeclId,
842        ty: Ty,
843        parents: Vector<TraitClauseId, TraitRef>,
844    ) -> Self {
845        let trait_decl_ref = RegionBinder::empty(TraitDeclRef {
846            id: trait_id,
847            generics: Box::new(GenericArgs::new_types([ty].into())),
848        });
849        TraitRef {
850            kind: TraitRefKind::BuiltinOrAuto {
851                parent_trait_refs: parents,
852                types: Default::default(),
853            },
854            trait_decl_ref,
855        }
856    }
857}
858
859impl PtrMetadata {
860    pub fn into_type(self) -> Ty {
861        match self {
862            PtrMetadata::None => Ty::mk_unit(),
863            PtrMetadata::Length => Ty::mk_usize(),
864            PtrMetadata::VTable(type_decl_ref) => Ty::new(TyKind::Ref(
865                Region::Static,
866                Ty::new(TyKind::Adt(type_decl_ref)),
867                RefKind::Shared,
868            )),
869            PtrMetadata::InheritFrom(ty) => Ty::new(TyKind::PtrMetadata(ty)),
870        }
871    }
872}
873
874impl Field {
875    /// The new name for this field, as suggested by the `#[charon::rename]` attribute.
876    pub fn renamed_name(&self) -> Option<&str> {
877        self.attr_info.rename.as_deref().or(self.name.as_deref())
878    }
879
880    /// Whether this field has a `#[charon::opaque]` annotation.
881    pub fn is_opaque(&self) -> bool {
882        self.attr_info
883            .attributes
884            .iter()
885            .any(|attr| attr.is_opaque())
886    }
887}
888
889impl Variant {
890    /// The new name for this variant, as suggested by the `#[charon::rename]` and
891    /// `#[charon::variants_prefix]` attributes.
892    pub fn renamed_name(&self) -> &str {
893        self.attr_info
894            .rename
895            .as_deref()
896            .unwrap_or(self.name.as_ref())
897    }
898
899    /// Whether this variant has a `#[charon::opaque]` annotation.
900    pub fn is_opaque(&self) -> bool {
901        self.attr_info
902            .attributes
903            .iter()
904            .any(|attr| attr.is_opaque())
905    }
906}
907
908impl DynPredicate {
909    /// Get the vtable declaration reference with current generics applied.
910    /// Matches associated types from the vtable's generics with the dyn predicates's constraints.
911    ///
912    /// Rustc guarantees all associated types are specified in a `dyn Trait` type.
913    pub fn vtable_ref(&self, translated: &TranslatedCrate) -> Option<TypeDeclRef> {
914        // Get vtable_ref's ID with trait-ref's generics from dyn-self applied.
915        // Add associated types in correct order following the vtable's generics.
916
917        // 0. Prepare trait name for debug/error messages
918        let trait_name = self.binder.params.trait_clauses[0]
919            .trait_
920            .skip_binder
921            .id
922            .with_ctx(&translated.into_fmt())
923            .to_string();
924
925        // 1. Get vtable ref from trait declaration
926        //    Provides: 1) final return ID, 2) correct order of associated types
927        // Firstly, get the trait declaration for the vtable ref it stores.
928        let Some(trait_decl) = translated
929            .trait_decls
930            .get(self.binder.params.trait_clauses[0].trait_.skip_binder.id)
931        else {
932            return None;
933        };
934
935        // Get vtable ref from definition for correct ID.
936        // Generics in vtable ref are placeholders but provide correct order of the associated types.
937        let Some(vtable_ref) = &trait_decl.vtable else {
938            panic!(
939                "Vtable for trait {} is None, meaning the trait is non-dyn-compatible!",
940                trait_name
941            );
942        };
943
944        // 2. Get correct generics for vtable ref from `dyn_self_ty`
945        //    The binder contains all target generics info.
946        let binder = &self.binder;
947
948        // 3. Prepare "basic part" of generics from trait ref (without associated types)
949        // The trait ref `dyn Trait<_dyn, Arg1, ..., ArgN>`, no associated types.
950        // First trait clause is the target one for vtable, guaranteed by `DynPredicate`.
951        let trait_ref = binder.params.trait_clauses[0].trait_.clone().erase();
952        // Type vars (except `_dyn`) are one level deeper, move out after removing `_dyn`.
953        trace!(
954            "Getting vtable ref with trait-decl-ref {}.",
955            trait_ref.with_ctx(&translated.into_fmt())
956        );
957        let mut generics = trait_ref.generics.clone();
958        // Remove the first `_dyn` type argument
959        generics.types.remove_and_shift_ids(TypeVarId::ZERO);
960        // Move out of predicate binder for `_dyn`
961        generics = generics.move_from_under_binder().unwrap();
962
963        // 4. Prepare associated types part in same order as vtable's generics
964        // Utilise the vtable ref form:
965        // `{vtable}<TraitArg1, ..., SuperTrait::Assoc1, ..., Self::AssocN>`
966        //
967        // Use trait ID + assoc name (`Trait::AssocTy`) to uniquely identify
968        let assoc_tys = vtable_ref
969            .generics
970            .types
971            .iter()
972            .filter_map(|ty| {
973                if let TyKind::TraitType(tref, name) = &ty.kind() {
974                    Some((tref.trait_decl_ref.skip_binder.id, name.clone()))
975                } else {
976                    None
977                }
978            })
979            .collect_vec();
980
981        // Find correct type argument from dyn trait's constraints for each assoc type.
982        // TODO: use proper normalization here instead of doing it by hand
983        for (trait_id, assoc_name) in assoc_tys {
984            // Find it
985            let Some(assoc_ty) = binder.params.trait_type_constraints.iter().find_map(|c| {
986                let c = c.clone().erase();
987                if c.trait_ref.trait_decl_ref.skip_binder.id == trait_id
988                    && c.type_name == assoc_name
989                {
990                    // Move potentially bounded type out of `_dyn` binder
991                    Some(c.ty.clone().move_from_under_binder().unwrap())
992                } else {
993                    None
994                }
995            }) else {
996                let dyn_self_ty = Ty::new(TyKind::DynTrait(self.clone()));
997                panic!(
998                    "Could not find associated type {}::{} for vtable of trait {} in dyn Trait type: {}",
999                    trait_id.with_ctx(&translated.into_fmt()),
1000                    assoc_name,
1001                    trait_name,
1002                    dyn_self_ty.with_ctx(&translated.into_fmt())
1003                );
1004            };
1005            // Push it
1006            generics.types.push(assoc_ty);
1007        }
1008
1009        // 5. Return vtable ref's ID with correct generics
1010        Some(TypeDeclRef {
1011            id: vtable_ref.id,
1012            generics,
1013        })
1014    }
1015}
1016
1017impl RefKind {
1018    pub fn mutable(x: bool) -> Self {
1019        if x { Self::Mut } else { Self::Shared }
1020    }
1021}
1022
1023/// Visitor for type-level variables. Used to visit the variables contained in a value, as seen
1024/// from the outside of the value. This means that any variable bound inside the value will be
1025/// skipped, and all the seen De Bruijn indices will count from the outside of the value. The
1026/// returned value, if any, will be put in place of the variable.
1027pub trait VarsVisitor {
1028    fn visit_region_var(&mut self, _v: RegionDbVar) -> Option<Region> {
1029        None
1030    }
1031    fn visit_type_var(&mut self, _v: TypeDbVar) -> Option<Ty> {
1032        None
1033    }
1034    fn visit_const_generic_var(&mut self, _v: ConstGenericDbVar) -> Option<ConstGeneric> {
1035        None
1036    }
1037    fn visit_clause_var(&mut self, _v: ClauseDbVar) -> Option<TraitRefKind> {
1038        None
1039    }
1040    fn visit_self_clause(&mut self) -> Option<TraitRefKind> {
1041        None
1042    }
1043}
1044
1045/// Visitor for the [TyVisitable::substitute] function.
1046/// This substitutes variables bound at the level where we start to substitute (level 0).
1047#[derive(Visitor)]
1048pub(crate) struct SubstVisitor<'a> {
1049    generics: &'a GenericArgs,
1050    self_ref: &'a TraitRefKind,
1051}
1052impl<'a> SubstVisitor<'a> {
1053    pub(crate) fn new(generics: &'a GenericArgs, self_ref: &'a TraitRefKind) -> Self {
1054        Self { generics, self_ref }
1055    }
1056
1057    /// Returns the value for this variable, if any.
1058    fn process_var<Id, T>(&self, var: DeBruijnVar<Id>, get: impl Fn(Id) -> &'a T) -> Option<T>
1059    where
1060        Id: Copy,
1061        T: Clone + TyVisitable,
1062        DeBruijnVar<Id>: Into<T>,
1063    {
1064        match var {
1065            DeBruijnVar::Bound(dbid, varid) => {
1066                Some(if let Some(dbid) = dbid.sub(DeBruijnId::one()) {
1067                    // This is bound outside the binder we're substituting for.
1068                    DeBruijnVar::Bound(dbid, varid).into()
1069                } else {
1070                    get(varid).clone()
1071                })
1072            }
1073            DeBruijnVar::Free(..) => None,
1074        }
1075    }
1076}
1077impl VarsVisitor for SubstVisitor<'_> {
1078    fn visit_region_var(&mut self, v: RegionDbVar) -> Option<Region> {
1079        self.process_var(v, |id| &self.generics[id])
1080    }
1081    fn visit_type_var(&mut self, v: TypeDbVar) -> Option<Ty> {
1082        self.process_var(v, |id| &self.generics[id])
1083    }
1084    fn visit_const_generic_var(&mut self, v: ConstGenericDbVar) -> Option<ConstGeneric> {
1085        self.process_var(v, |id| &self.generics[id])
1086    }
1087    fn visit_clause_var(&mut self, v: ClauseDbVar) -> Option<TraitRefKind> {
1088        self.process_var(v, |id| &self.generics[id].kind)
1089    }
1090    fn visit_self_clause(&mut self) -> Option<TraitRefKind> {
1091        Some(self.self_ref.clone())
1092    }
1093}
1094
1095/// Types that are involved at the type-level and may be substituted around.
1096pub trait TyVisitable: Sized + AstVisitable {
1097    /// Visit the variables contained in `self`, as seen from the outside of `self`. This means
1098    /// that any variable bound inside `self` will be skipped, and all the seen De Bruijn indices
1099    /// will count from the outside of `self`.
1100    fn visit_vars(&mut self, v: &mut impl VarsVisitor) {
1101        #[derive(Visitor)]
1102        struct Wrap<'v, V> {
1103            v: &'v mut V,
1104            depth: DeBruijnId,
1105        }
1106        impl<V: VarsVisitor> VisitAstMut for Wrap<'_, V> {
1107            fn enter_region_binder<T: AstVisitable>(&mut self, _: &mut RegionBinder<T>) {
1108                self.depth = self.depth.incr()
1109            }
1110            fn exit_region_binder<T: AstVisitable>(&mut self, _: &mut RegionBinder<T>) {
1111                self.depth = self.depth.decr()
1112            }
1113            fn enter_binder<T: AstVisitable>(&mut self, _: &mut Binder<T>) {
1114                self.depth = self.depth.incr()
1115            }
1116            fn exit_binder<T: AstVisitable>(&mut self, _: &mut Binder<T>) {
1117                self.depth = self.depth.decr()
1118            }
1119
1120            fn exit_region(&mut self, r: &mut Region) {
1121                if let Region::Var(var) = r
1122                    && let Some(var) = var.move_out_from_depth(self.depth)
1123                    && let Some(new_r) = self.v.visit_region_var(var)
1124                {
1125                    *r = new_r.move_under_binders(self.depth);
1126                }
1127            }
1128            fn exit_ty(&mut self, ty: &mut Ty) {
1129                if let TyKind::TypeVar(var) = ty.kind()
1130                    && let Some(var) = var.move_out_from_depth(self.depth)
1131                    && let Some(new_ty) = self.v.visit_type_var(var)
1132                {
1133                    *ty = new_ty.move_under_binders(self.depth);
1134                }
1135            }
1136            fn exit_const_generic(&mut self, cg: &mut ConstGeneric) {
1137                if let ConstGeneric::Var(var) = cg
1138                    && let Some(var) = var.move_out_from_depth(self.depth)
1139                    && let Some(new_cg) = self.v.visit_const_generic_var(var)
1140                {
1141                    *cg = new_cg.move_under_binders(self.depth);
1142                }
1143            }
1144            fn exit_constant_expr(&mut self, ce: &mut ConstantExpr) {
1145                if let ConstantExprKind::Var(var) = &mut ce.kind
1146                    && let Some(var) = var.move_out_from_depth(self.depth)
1147                    && let Some(new_cg) = self.v.visit_const_generic_var(var)
1148                {
1149                    ce.kind = new_cg.move_under_binders(self.depth).into();
1150                }
1151            }
1152            fn exit_trait_ref_kind(&mut self, kind: &mut TraitRefKind) {
1153                match kind {
1154                    TraitRefKind::SelfId => {
1155                        if let Some(new_kind) = self.v.visit_self_clause() {
1156                            *kind = new_kind.move_under_binders(self.depth);
1157                        }
1158                    }
1159                    TraitRefKind::Clause(var) => {
1160                        if let Some(var) = var.move_out_from_depth(self.depth)
1161                            && let Some(new_kind) = self.v.visit_clause_var(var)
1162                        {
1163                            *kind = new_kind.move_under_binders(self.depth);
1164                        }
1165                    }
1166                    _ => {}
1167                }
1168            }
1169        }
1170        let _ = self.drive_mut(&mut Wrap {
1171            v,
1172            depth: DeBruijnId::zero(),
1173        });
1174    }
1175
1176    fn substitute(self, generics: &GenericArgs) -> Self {
1177        self.substitute_with_self(generics, &TraitRefKind::SelfId)
1178    }
1179
1180    fn substitute_with_self(mut self, generics: &GenericArgs, self_ref: &TraitRefKind) -> Self {
1181        let _ = self.visit_vars(&mut SubstVisitor::new(generics, self_ref));
1182        self
1183    }
1184
1185    /// Move under one binder.
1186    fn move_under_binder(self) -> Self {
1187        self.move_under_binders(DeBruijnId::one())
1188    }
1189
1190    /// Move under `depth` binders.
1191    fn move_under_binders(mut self, depth: DeBruijnId) -> Self {
1192        if !depth.is_zero() {
1193            let Continue(()) = self.visit_db_id::<Infallible>(|id| {
1194                *id = id.plus(depth);
1195                Continue(())
1196            });
1197        }
1198        self
1199    }
1200
1201    /// Move from under one binder.
1202    fn move_from_under_binder(self) -> Option<Self> {
1203        self.move_from_under_binders(DeBruijnId::one())
1204    }
1205
1206    /// Move the value out of `depth` binders. Returns `None` if it contains a variable bound in
1207    /// one of these `depth` binders.
1208    fn move_from_under_binders(mut self, depth: DeBruijnId) -> Option<Self> {
1209        self.visit_db_id::<()>(|id| match id.sub(depth) {
1210            Some(sub) => {
1211                *id = sub;
1212                Continue(())
1213            }
1214            None => Break(()),
1215        })
1216        .is_continue()
1217        .then_some(self)
1218    }
1219
1220    /// Visit the de Bruijn ids contained in `self`, as seen from the outside of `self`. This means
1221    /// that any variable bound inside `self` will be skipped, and all the seen indices will count
1222    /// from the outside of self.
1223    fn visit_db_id<B>(
1224        &mut self,
1225        f: impl FnMut(&mut DeBruijnId) -> ControlFlow<B>,
1226    ) -> ControlFlow<B> {
1227        struct Wrap<F> {
1228            f: F,
1229            depth: DeBruijnId,
1230        }
1231        impl<B, F> Visitor for Wrap<F>
1232        where
1233            F: FnMut(&mut DeBruijnId) -> ControlFlow<B>,
1234        {
1235            type Break = B;
1236        }
1237        impl<B, F> VisitAstMut for Wrap<F>
1238        where
1239            F: FnMut(&mut DeBruijnId) -> ControlFlow<B>,
1240        {
1241            fn enter_region_binder<T: AstVisitable>(&mut self, _: &mut RegionBinder<T>) {
1242                self.depth = self.depth.incr()
1243            }
1244            fn exit_region_binder<T: AstVisitable>(&mut self, _: &mut RegionBinder<T>) {
1245                self.depth = self.depth.decr()
1246            }
1247            fn enter_binder<T: AstVisitable>(&mut self, _: &mut Binder<T>) {
1248                self.depth = self.depth.incr()
1249            }
1250            fn exit_binder<T: AstVisitable>(&mut self, _: &mut Binder<T>) {
1251                self.depth = self.depth.decr()
1252            }
1253
1254            fn visit_de_bruijn_id(&mut self, x: &mut DeBruijnId) -> ControlFlow<Self::Break> {
1255                if let Some(mut shifted) = x.sub(self.depth) {
1256                    (self.f)(&mut shifted)?;
1257                    *x = shifted.plus(self.depth)
1258                }
1259                Continue(())
1260            }
1261        }
1262        self.drive_mut(&mut Wrap {
1263            f,
1264            depth: DeBruijnId::zero(),
1265        })
1266    }
1267}
1268
1269impl TypeDecl {
1270    /// Looks up the variant corresponding to the tag (i.e. the in-memory bytes that represent the discriminant).
1271    /// Returns `None` for types that don't have a relevant discriminant (e.g. uninhabited types).
1272    ///
1273    /// If the `tag` does not correspond to any valid discriminant but there is a niche,
1274    /// the resulting `VariantId` will be for the untagged variant [`TagEncoding::Niche::untagged_variant`].
1275    pub fn get_variant_from_tag(&self, tag: ScalarValue) -> Option<VariantId> {
1276        let layout = self.layout.as_ref()?;
1277        if layout.uninhabited {
1278            return None;
1279        };
1280        let discr_layout = layout.discriminant_layout.as_ref()?;
1281
1282        let variant_for_tag =
1283            layout
1284                .variant_layouts
1285                .iter_indexed()
1286                .find_map(|(id, variant_layout)| {
1287                    if variant_layout.tag == Some(tag) {
1288                        Some(id)
1289                    } else {
1290                        None
1291                    }
1292                });
1293
1294        match &discr_layout.encoding {
1295            TagEncoding::Direct => {
1296                assert_eq!(tag.get_integer_ty(), discr_layout.tag_ty);
1297                variant_for_tag
1298            }
1299            TagEncoding::Niche { untagged_variant } => variant_for_tag.or(Some(*untagged_variant)),
1300        }
1301    }
1302
1303    pub fn is_c_repr(&self) -> bool {
1304        self.repr
1305            .as_ref()
1306            .is_some_and(|repr| repr.repr_algo == ReprAlgorithm::C)
1307    }
1308
1309    pub fn get_field_by_name(
1310        &self,
1311        variant: Option<VariantId>,
1312        field_name: &str,
1313    ) -> Option<(FieldId, &Field)> {
1314        let fields = match &self.kind {
1315            TypeDeclKind::Struct(fields) | TypeDeclKind::Union(fields) => fields,
1316            TypeDeclKind::Enum(variants) => &variants[variant.unwrap()].fields,
1317            _ => return None,
1318        };
1319        fields
1320            .iter_indexed()
1321            .find(|(_, field)| field.name.as_deref() == Some(field_name))
1322    }
1323}
1324
1325impl Layout {
1326    pub fn is_variant_uninhabited(&self, variant_id: VariantId) -> bool {
1327        if let Some(v) = self.variant_layouts.get(variant_id) {
1328            v.uninhabited
1329        } else {
1330            false
1331        }
1332    }
1333}
1334
1335impl ReprOptions {
1336    /// Whether this representation options guarantee a fixed
1337    /// field ordering for the type.
1338    ///
1339    /// Since we don't support `repr(simd)` or `repr(linear)` yet, this is
1340    /// the case if it's either `repr(C)` or an explicit discriminant type for
1341    /// an enum with fields (if it doesn't have fields, this obviously doesn't matter anyway).
1342    ///
1343    /// Cf. <https://doc.rust-lang.org/reference/type-layout.html#r-layout.repr.c.struct>
1344    /// and <https://doc.rust-lang.org/reference/type-layout.html#r-layout.repr.primitive.adt>.
1345    pub fn guarantees_fixed_field_order(&self) -> bool {
1346        self.repr_algo == ReprAlgorithm::C || self.explicit_discr_type
1347    }
1348}
1349
1350impl<T: AstVisitable> TyVisitable for T {}
1351
1352impl Eq for TraitParam {}
1353
1354mk_index_impls!(GenericArgs.regions[RegionId]: Region);
1355mk_index_impls!(GenericArgs.types[TypeVarId]: Ty);
1356mk_index_impls!(GenericArgs.const_generics[ConstGenericVarId]: ConstGeneric);
1357mk_index_impls!(GenericArgs.trait_refs[TraitClauseId]: TraitRef);
1358mk_index_impls!(GenericParams.regions[RegionId]: RegionParam);
1359mk_index_impls!(GenericParams.types[TypeVarId]: TypeParam);
1360mk_index_impls!(GenericParams.const_generics[ConstGenericVarId]: ConstGenericParam);
1361mk_index_impls!(GenericParams.trait_clauses[TraitClauseId]: TraitParam);