1use 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 pub fn identity_tref(&self) -> TraitRef {
17 self.identity_tref_at_depth(DeBruijnId::zero())
18 }
19
20 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 pub fn has_explicits(&self) -> bool {
39 !self.regions.is_empty() || !self.types.is_empty() || !self.const_generics.is_empty()
40 }
41 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 pub fn check_consistency(&self) {
52 assert!(
54 self.trait_clauses
55 .iter()
56 .enumerate()
57 .all(|(i, c)| c.clause_id.index() == i)
58 );
59
60 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 pub fn identity_args(&self) -> GenericArgs {
100 self.identity_args_at_depth(DeBruijnId::zero())
101 }
102
103 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 pub fn take_predicates_from(&mut self, other: GenericParams) {
124 assert!(!other.has_explicits());
125 let num_clauses = self.trait_clauses.slot_count();
126 let GenericParams {
127 regions: _,
128 types: _,
129 const_generics: _,
130 trait_clauses,
131 regions_outlive,
132 types_outlive,
133 trait_type_constraints,
134 } = other;
135 self.trait_clauses
136 .extend(trait_clauses.into_iter().update(|clause| {
137 clause.clause_id += num_clauses;
138 }));
139 self.regions_outlive.extend(regions_outlive);
140 self.types_outlive.extend(types_outlive);
141 self.trait_type_constraints.extend(trait_type_constraints);
142 }
143
144 pub fn merge_predicates_from(&mut self, mut other: GenericParams) {
148 other.types.clear();
150 other.regions.clear();
151 other.const_generics.clear();
152 struct ShiftClausesVisitor(usize);
154 impl VarsVisitor for ShiftClausesVisitor {
155 fn visit_clause_var(&mut self, v: ClauseDbVar) -> Option<TraitRefKind> {
156 if let DeBruijnVar::Bound(DeBruijnId::ZERO, clause_id) = v {
157 Some(TraitRefKind::Clause(DeBruijnVar::Bound(
159 DeBruijnId::ZERO,
160 clause_id + self.0,
161 )))
162 } else {
163 None
164 }
165 }
166 }
167 let num_clauses = self.trait_clauses.slot_count();
168 other.visit_vars(&mut ShiftClausesVisitor(num_clauses));
169 self.take_predicates_from(other);
170 }
171}
172
173impl<T> Binder<T> {
174 pub fn empty(kind: BinderKind, x: T) -> Self
176 where
177 T: TyVisitable,
178 {
179 Binder {
180 params: Default::default(),
181 skip_binder: x.move_under_binder(),
182 kind,
183 }
184 }
185 pub fn new(kind: BinderKind, params: GenericParams, skip_binder: T) -> Self {
186 Self {
187 params,
188 skip_binder,
189 kind,
190 }
191 }
192
193 pub fn binds_anything(&self) -> bool {
195 !self.params.is_empty()
196 }
197
198 pub fn get_if_binds_nothing(&self) -> Option<T>
201 where
202 T: TyVisitable + Clone,
203 {
204 self.params
205 .is_empty()
206 .then(|| self.skip_binder.clone().move_from_under_binder().unwrap())
207 }
208
209 pub fn map<U>(self, f: impl FnOnce(T) -> U) -> Binder<U> {
210 Binder {
211 params: self.params,
212 skip_binder: f(self.skip_binder),
213 kind: self.kind.clone(),
214 }
215 }
216
217 pub fn map_ref<U>(&self, f: impl FnOnce(&T) -> U) -> Binder<U> {
218 Binder {
219 params: self.params.clone(),
220 skip_binder: f(&self.skip_binder),
221 kind: self.kind.clone(),
222 }
223 }
224
225 pub fn apply(self, args: &GenericArgs) -> T
228 where
229 T: TyVisitable,
230 {
231 self.skip_binder.substitute(args)
232 }
233}
234
235impl<T: AstVisitable> Binder<Binder<T>> {
236 pub fn flatten(self) -> Binder<T> {
238 #[derive(Visitor)]
239 struct FlattenVisitor<'a> {
240 shift_by: &'a GenericParams,
241 binder_depth: DeBruijnId,
242 }
243 impl VisitorWithBinderDepth for FlattenVisitor<'_> {
244 fn binder_depth_mut(&mut self) -> &mut DeBruijnId {
245 &mut self.binder_depth
246 }
247 }
248 impl VisitAstMut for FlattenVisitor<'_> {
249 fn visit<'a, T: AstVisitable>(&'a mut self, x: &mut T) -> ControlFlow<Self::Break> {
250 VisitWithBinderDepth::new(self).visit(x)
251 }
252
253 fn enter_de_bruijn_id(&mut self, db_id: &mut DeBruijnId) {
254 if *db_id > self.binder_depth {
255 *db_id = db_id.decr();
260 }
261 }
262 fn enter_region(&mut self, x: &mut Region) {
263 if let Region::Var(var) = x
264 && let Some(id) = var.bound_at_depth_mut(self.binder_depth)
265 {
266 *id += self.shift_by.regions.slot_count();
267 }
268 }
269 fn enter_ty_kind(&mut self, x: &mut TyKind) {
270 if let TyKind::TypeVar(var) = x
271 && let Some(id) = var.bound_at_depth_mut(self.binder_depth)
272 {
273 *id += self.shift_by.types.slot_count();
274 }
275 }
276 fn enter_const_generic(&mut self, x: &mut ConstGeneric) {
277 if let ConstGeneric::Var(var) = x
278 && let Some(id) = var.bound_at_depth_mut(self.binder_depth)
279 {
280 *id += self.shift_by.const_generics.slot_count();
281 }
282 }
283 fn enter_trait_ref_kind(&mut self, x: &mut TraitRefKind) {
284 if let TraitRefKind::Clause(var) = x
285 && let Some(id) = var.bound_at_depth_mut(self.binder_depth)
286 {
287 *id += self.shift_by.trait_clauses.slot_count();
288 }
289 }
290 }
291
292 let mut outer_params = self.params;
294
295 let mut bound_value = self.skip_binder.skip_binder;
299 let _ = bound_value.drive_mut(&mut FlattenVisitor {
300 shift_by: &outer_params,
301 binder_depth: Default::default(),
302 });
303
304 let mut inner_params = self.skip_binder.params;
307 let _ = inner_params.drive_mut(&mut FlattenVisitor {
308 shift_by: &outer_params,
309 binder_depth: Default::default(),
310 });
311 inner_params
312 .regions
313 .iter_mut()
314 .for_each(|v| v.index += outer_params.regions.slot_count());
315 inner_params
316 .types
317 .iter_mut()
318 .for_each(|v| v.index += outer_params.types.slot_count());
319 inner_params
320 .const_generics
321 .iter_mut()
322 .for_each(|v| v.index += outer_params.const_generics.slot_count());
323 inner_params
324 .trait_clauses
325 .iter_mut()
326 .for_each(|v| v.clause_id += outer_params.trait_clauses.slot_count());
327
328 let GenericParams {
329 regions,
330 types,
331 const_generics,
332 trait_clauses,
333 regions_outlive,
334 types_outlive,
335 trait_type_constraints,
336 } = &inner_params;
337 outer_params.regions.extend_from_slice(regions);
338 outer_params.types.extend_from_slice(types);
339 outer_params
340 .const_generics
341 .extend_from_slice(const_generics);
342 outer_params.trait_clauses.extend_from_slice(trait_clauses);
343 outer_params
344 .regions_outlive
345 .extend_from_slice(regions_outlive);
346 outer_params.types_outlive.extend_from_slice(types_outlive);
347 outer_params
348 .trait_type_constraints
349 .extend_from_slice(trait_type_constraints);
350
351 Binder {
352 params: outer_params,
353 skip_binder: bound_value,
354 kind: BinderKind::Other,
355 }
356 }
357}
358
359impl<T> RegionBinder<T> {
360 pub fn empty(x: T) -> Self
362 where
363 T: TyVisitable,
364 {
365 RegionBinder {
366 regions: Default::default(),
367 skip_binder: x.move_under_binder(),
368 }
369 }
370
371 pub fn map<U>(self, f: impl FnOnce(T) -> U) -> RegionBinder<U> {
372 RegionBinder {
373 regions: self.regions,
374 skip_binder: f(self.skip_binder),
375 }
376 }
377
378 pub fn map_ref<U>(&self, f: impl FnOnce(&T) -> U) -> RegionBinder<U> {
379 RegionBinder {
380 regions: self.regions.clone(),
381 skip_binder: f(&self.skip_binder),
382 }
383 }
384
385 pub fn apply(self, regions: Vector<RegionId, Region>) -> T
387 where
388 T: AstVisitable,
389 {
390 assert_eq!(regions.slot_count(), self.regions.slot_count());
391 let args = GenericArgs {
392 regions,
393 ..GenericArgs::empty()
394 };
395 self.skip_binder.substitute(&args)
396 }
397
398 pub fn erase(self) -> T
400 where
401 T: AstVisitable,
402 {
403 let regions = self.regions.map_ref_indexed(|_, _| Region::Erased);
404 self.apply(regions)
405 }
406}
407
408impl GenericArgs {
409 pub fn len(&self) -> usize {
410 let GenericArgs {
411 regions,
412 types,
413 const_generics,
414 trait_refs,
415 } = self;
416 regions.elem_count()
417 + types.elem_count()
418 + const_generics.elem_count()
419 + trait_refs.elem_count()
420 }
421
422 pub fn is_empty(&self) -> bool {
423 self.len() == 0
424 }
425 pub fn has_explicits(&self) -> bool {
427 !self.regions.is_empty() || !self.types.is_empty() || !self.const_generics.is_empty()
428 }
429 pub fn has_implicits(&self) -> bool {
431 !self.trait_refs.is_empty()
432 }
433
434 pub fn empty() -> Self {
435 GenericArgs {
436 regions: Default::default(),
437 types: Default::default(),
438 const_generics: Default::default(),
439 trait_refs: Default::default(),
440 }
441 }
442
443 pub fn new_for_builtin(types: Vector<TypeVarId, Ty>) -> Self {
444 GenericArgs {
445 types,
446 ..Self::empty()
447 }
448 }
449
450 pub fn new(
451 regions: Vector<RegionId, Region>,
452 types: Vector<TypeVarId, Ty>,
453 const_generics: Vector<ConstGenericVarId, ConstGeneric>,
454 trait_refs: Vector<TraitClauseId, TraitRef>,
455 ) -> Self {
456 Self {
457 regions,
458 types,
459 const_generics,
460 trait_refs,
461 }
462 }
463
464 pub fn new_types(types: Vector<TypeVarId, Ty>) -> Self {
465 Self {
466 types,
467 ..Self::empty()
468 }
469 }
470
471 pub fn matches(&self, params: &GenericParams) -> bool {
474 params.regions.elem_count() == self.regions.elem_count()
475 && params.types.elem_count() == self.types.elem_count()
476 && params.const_generics.elem_count() == self.const_generics.elem_count()
477 && params.trait_clauses.elem_count() == self.trait_refs.elem_count()
478 }
479
480 pub fn pop_first_type_arg(&self) -> (Ty, Self) {
485 let mut generics = self.clone();
486 let mut it = mem::take(&mut generics.types).into_iter();
487 let ty = it.next().unwrap();
488 generics.types = it.collect();
489 (ty, generics)
490 }
491
492 pub fn concat(mut self, other: &Self) -> Self {
495 let Self {
496 regions,
497 types,
498 const_generics,
499 trait_refs,
500 } = other;
501 self.regions.extend_from_slice(regions);
502 self.types.extend_from_slice(types);
503 self.const_generics.extend_from_slice(const_generics);
504 self.trait_refs.extend_from_slice(trait_refs);
505 self
506 }
507}
508
509impl IntTy {
510 pub fn target_size(&self, ptr_size: ByteCount) -> usize {
513 match self {
514 IntTy::Isize => ptr_size as usize,
515 IntTy::I8 => size_of::<i8>(),
516 IntTy::I16 => size_of::<i16>(),
517 IntTy::I32 => size_of::<i32>(),
518 IntTy::I64 => size_of::<i64>(),
519 IntTy::I128 => size_of::<i128>(),
520 }
521 }
522}
523impl UIntTy {
524 pub fn target_size(&self, ptr_size: ByteCount) -> usize {
527 match self {
528 UIntTy::Usize => ptr_size as usize,
529 UIntTy::U8 => size_of::<u8>(),
530 UIntTy::U16 => size_of::<u16>(),
531 UIntTy::U32 => size_of::<u32>(),
532 UIntTy::U64 => size_of::<u64>(),
533 UIntTy::U128 => size_of::<u128>(),
534 }
535 }
536}
537impl FloatTy {
538 pub fn target_size(&self) -> usize {
541 match self {
542 FloatTy::F16 => size_of::<u16>(),
543 FloatTy::F32 => size_of::<u32>(),
544 FloatTy::F64 => size_of::<u64>(),
545 FloatTy::F128 => size_of::<u128>(),
546 }
547 }
548}
549
550impl IntegerTy {
551 pub fn to_unsigned(&self) -> Self {
552 match self {
553 IntegerTy::Signed(IntTy::Isize) => IntegerTy::Unsigned(UIntTy::Usize),
554 IntegerTy::Signed(IntTy::I8) => IntegerTy::Unsigned(UIntTy::U8),
555 IntegerTy::Signed(IntTy::I16) => IntegerTy::Unsigned(UIntTy::U16),
556 IntegerTy::Signed(IntTy::I32) => IntegerTy::Unsigned(UIntTy::U32),
557 IntegerTy::Signed(IntTy::I64) => IntegerTy::Unsigned(UIntTy::U64),
558 IntegerTy::Signed(IntTy::I128) => IntegerTy::Unsigned(UIntTy::U128),
559 _ => *self,
560 }
561 }
562
563 pub fn target_size(&self, ptr_size: ByteCount) -> usize {
566 match self {
567 IntegerTy::Signed(ty) => ty.target_size(ptr_size),
568 IntegerTy::Unsigned(ty) => ty.target_size(ptr_size),
569 }
570 }
571}
572
573impl LiteralTy {
574 pub fn to_integer_ty(&self) -> Option<IntegerTy> {
575 match self {
576 Self::Int(int_ty) => Some(IntegerTy::Signed(*int_ty)),
577 Self::UInt(uint_ty) => Some(IntegerTy::Unsigned(*uint_ty)),
578 _ => None,
579 }
580 }
581
582 pub fn target_size(&self, ptr_size: ByteCount) -> usize {
585 match self {
586 LiteralTy::Int(int_ty) => int_ty.target_size(ptr_size),
587 LiteralTy::UInt(uint_ty) => uint_ty.target_size(ptr_size),
588 LiteralTy::Float(float_ty) => float_ty.target_size(),
589 LiteralTy::Char => 4,
590 LiteralTy::Bool => 1,
591 }
592 }
593}
594
595#[derive(Debug, Clone, Copy)]
601pub struct ItemBinder<ItemId, T> {
602 pub item_id: ItemId,
603 val: T,
604}
605
606impl<ItemId, T> ItemBinder<ItemId, T>
607where
608 ItemId: Debug + Copy + PartialEq,
609{
610 pub fn new(item_id: ItemId, val: T) -> Self {
611 Self { item_id, val }
612 }
613
614 pub fn as_ref(&self) -> ItemBinder<ItemId, &T> {
615 ItemBinder {
616 item_id: self.item_id,
617 val: &self.val,
618 }
619 }
620
621 pub fn map_bound<U>(self, f: impl FnOnce(T) -> U) -> ItemBinder<ItemId, U> {
622 ItemBinder {
623 item_id: self.item_id,
624 val: f(self.val),
625 }
626 }
627
628 fn assert_item_id(&self, item_id: ItemId) {
629 assert_eq!(
630 self.item_id, item_id,
631 "Trying to use item bound for {:?} as if it belonged to {:?}",
632 self.item_id, item_id
633 );
634 }
635
636 pub fn under_binder_of(self, item_id: ItemId) -> T {
639 self.assert_item_id(item_id);
640 self.val
641 }
642
643 pub fn substitute<OtherItem: Debug + Copy + PartialEq>(
647 self,
648 args: ItemBinder<OtherItem, &GenericArgs>,
649 ) -> ItemBinder<OtherItem, T>
650 where
651 ItemId: Into<ItemId>,
652 T: TyVisitable,
653 {
654 args.map_bound(|args| self.val.substitute(args))
655 }
656}
657
658#[derive(Debug, Clone, Copy, PartialEq, Eq)]
660pub struct CurrentItem;
661
662impl<T> ItemBinder<CurrentItem, T> {
663 pub fn under_current_binder(self) -> T {
664 self.val
665 }
666}
667
668impl Ty {
669 pub fn mk_unit() -> Ty {
671 Self::mk_tuple(vec![])
672 }
673
674 pub fn mk_usize() -> Ty {
675 TyKind::Literal(LiteralTy::UInt(UIntTy::Usize)).into()
676 }
677
678 pub fn mk_tuple(tys: Vec<Ty>) -> Ty {
679 TyKind::Adt(TypeDeclRef {
680 id: TypeId::Tuple,
681 generics: Box::new(GenericArgs::new_for_builtin(tys.into())),
682 })
683 .into_ty()
684 }
685
686 pub fn mk_slice(ty: Ty) -> Ty {
687 TyKind::Adt(TypeDeclRef {
688 id: TypeId::Builtin(BuiltinTy::Slice),
689 generics: Box::new(GenericArgs::new_for_builtin(vec![ty].into())),
690 })
691 .into_ty()
692 }
693 pub fn is_unit(&self) -> bool {
695 match self.as_tuple() {
696 Some(tys) => tys.is_empty(),
697 None => false,
698 }
699 }
700
701 pub fn is_scalar(&self) -> bool {
703 match self.kind() {
704 TyKind::Literal(kind) => kind.is_int() || kind.is_uint(),
705 _ => false,
706 }
707 }
708
709 pub fn is_unsigned_scalar(&self) -> bool {
710 matches!(self.kind(), TyKind::Literal(LiteralTy::UInt(_)))
711 }
712
713 pub fn is_signed_scalar(&self) -> bool {
714 matches!(self.kind(), TyKind::Literal(LiteralTy::Int(_)))
715 }
716
717 pub fn is_box(&self) -> bool {
719 match self.kind() {
720 TyKind::Adt(ty_ref) if let TypeId::Builtin(BuiltinTy::Box) = ty_ref.id => true,
721 _ => false,
722 }
723 }
724
725 pub fn as_box(&self) -> Option<&Ty> {
726 match self.kind() {
727 TyKind::Adt(ty_ref) if let TypeId::Builtin(BuiltinTy::Box) = ty_ref.id => {
728 Some(&ty_ref.generics.types[0])
729 }
730 _ => None,
731 }
732 }
733
734 pub fn get_ptr_metadata(&self, translated: &TranslatedCrate) -> PtrMetadata {
735 let ref ty_decls = translated.type_decls;
736 match self.kind() {
737 TyKind::Adt(ty_ref) => {
738 match ty_ref.id {
742 TypeId::Adt(type_decl_id) => {
743 let Some(decl) = ty_decls.get(type_decl_id) else {
744 return PtrMetadata::InheritFrom(Ty::new(TyKind::Error(format!(
745 "Internal Error: type decl id not found during getting metadata: {type_decl_id}"
746 ))));
747 };
748 match &decl.ptr_metadata {
749 PtrMetadata::InheritFrom(ty) => {
751 let ty = ty.clone().substitute(&ty_ref.generics);
752 ty.get_ptr_metadata(translated)
753 }
754 meta => meta.clone().substitute(&ty_ref.generics),
756 }
757 }
758 TypeId::Tuple => {
760 match ty_ref.generics.types.iter().last() {
761 None => PtrMetadata::None,
763 Some(ty) => ty.get_ptr_metadata(translated),
765 }
766 }
767 TypeId::Builtin(BuiltinTy::Box) => PtrMetadata::None,
769 TypeId::Builtin(BuiltinTy::Array) => PtrMetadata::None,
771 TypeId::Builtin(BuiltinTy::Slice) => PtrMetadata::Length,
773 TypeId::Builtin(BuiltinTy::Str) => PtrMetadata::Length,
774 }
775 }
776 TyKind::DynTrait(pred) => match pred.vtable_ref(translated) {
777 Some(vtable) => PtrMetadata::VTable(vtable),
778 None => PtrMetadata::InheritFrom(
779 TyKind::Error(format!(
780 "Vtable for dyn trait {} not found",
781 pred.with_ctx(&translated.into_fmt())
782 ))
783 .into(),
784 ),
785 },
786 TyKind::TraitType(..) | TyKind::TypeVar(_) => PtrMetadata::InheritFrom(self.clone()),
787 TyKind::Literal(_)
788 | TyKind::Never
789 | TyKind::Ref(..)
790 | TyKind::RawPtr(..)
791 | TyKind::FnPtr(..)
792 | TyKind::FnDef(..)
793 | TyKind::Error(_) => PtrMetadata::None,
794 TyKind::PtrMetadata(_) => PtrMetadata::None,
796 }
797 }
798
799 pub fn as_array_or_slice(&self) -> Option<&Ty> {
800 match self.kind() {
801 TyKind::Adt(ty_ref)
802 if let TypeId::Builtin(BuiltinTy::Array | BuiltinTy::Slice) = ty_ref.id =>
803 {
804 Some(&ty_ref.generics.types[0])
805 }
806 _ => None,
807 }
808 }
809
810 pub fn as_tuple(&self) -> Option<&Vector<TypeVarId, Ty>> {
811 match self.kind() {
812 TyKind::Adt(ty_ref) if let TypeId::Tuple = ty_ref.id => Some(&ty_ref.generics.types),
813 _ => None,
814 }
815 }
816
817 pub fn as_adt(&self) -> Option<&TypeDeclRef> {
818 self.kind().as_adt()
819 }
820}
821
822impl TyKind {
823 pub fn into_ty(self) -> Ty {
824 Ty::new(self)
825 }
826}
827
828impl From<TyKind> for Ty {
829 fn from(kind: TyKind) -> Ty {
830 kind.into_ty()
831 }
832}
833
834impl std::ops::Deref for Ty {
836 type Target = TyKind;
837
838 fn deref(&self) -> &Self::Target {
839 self.kind()
840 }
841}
842unsafe impl std::ops::DerefPure for Ty {}
844
845impl TypeDeclRef {
846 pub fn new(id: TypeId, generics: GenericArgs) -> Self {
847 Self {
848 id,
849 generics: Box::new(generics),
850 }
851 }
852}
853
854impl TraitDeclRef {
855 pub fn self_ty<'a>(&'a self, krate: &'a TranslatedCrate) -> Option<&'a Ty> {
856 match self.generics.types.iter().next() {
857 Some(ty) => return Some(ty),
858 None => {
860 let name = krate.item_name(self.id)?;
861 let args = name.name.last()?.as_monomorphized()?;
862 args.types.iter().next()
863 }
864 }
865 }
866}
867
868impl TraitRef {
869 pub fn new_builtin(
870 trait_id: TraitDeclId,
871 ty: Ty,
872 parents: Vector<TraitClauseId, TraitRef>,
873 ) -> Self {
874 let trait_decl_ref = RegionBinder::empty(TraitDeclRef {
875 id: trait_id,
876 generics: Box::new(GenericArgs::new_types([ty].into())),
877 });
878 TraitRef {
879 kind: TraitRefKind::BuiltinOrAuto {
880 parent_trait_refs: parents,
881 types: Default::default(),
882 },
883 trait_decl_ref,
884 }
885 }
886}
887
888impl PtrMetadata {
889 pub fn into_type(self) -> Ty {
890 match self {
891 PtrMetadata::None => Ty::mk_unit(),
892 PtrMetadata::Length => Ty::mk_usize(),
893 PtrMetadata::VTable(type_decl_ref) => Ty::new(TyKind::Ref(
894 Region::Static,
895 Ty::new(TyKind::Adt(type_decl_ref)),
896 RefKind::Shared,
897 )),
898 PtrMetadata::InheritFrom(ty) => Ty::new(TyKind::PtrMetadata(ty)),
899 }
900 }
901}
902
903impl Field {
904 pub fn renamed_name(&self) -> Option<&str> {
906 self.attr_info.rename.as_deref().or(self.name.as_deref())
907 }
908
909 pub fn is_opaque(&self) -> bool {
911 self.attr_info
912 .attributes
913 .iter()
914 .any(|attr| attr.is_opaque())
915 }
916}
917
918impl Variant {
919 pub fn renamed_name(&self) -> &str {
922 self.attr_info
923 .rename
924 .as_deref()
925 .unwrap_or(self.name.as_ref())
926 }
927
928 pub fn is_opaque(&self) -> bool {
930 self.attr_info
931 .attributes
932 .iter()
933 .any(|attr| attr.is_opaque())
934 }
935}
936
937impl DynPredicate {
938 pub fn vtable_ref(&self, translated: &TranslatedCrate) -> Option<TypeDeclRef> {
943 let trait_name = self.binder.params.trait_clauses[0]
948 .trait_
949 .skip_binder
950 .id
951 .with_ctx(&translated.into_fmt())
952 .to_string();
953
954 let Some(trait_decl) = translated
958 .trait_decls
959 .get(self.binder.params.trait_clauses[0].trait_.skip_binder.id)
960 else {
961 return None;
962 };
963
964 let Some(vtable_ref) = &trait_decl.vtable else {
967 panic!(
968 "Vtable for trait {} is None, meaning the trait is non-dyn-compatible!",
969 trait_name
970 );
971 };
972
973 let binder = &self.binder;
976
977 let trait_ref = binder.params.trait_clauses[0].trait_.clone().erase();
981 trace!(
983 "Getting vtable ref with trait-decl-ref {}.",
984 trait_ref.with_ctx(&translated.into_fmt())
985 );
986 let mut generics = trait_ref.generics.clone();
987 generics.types.remove_and_shift_ids(TypeVarId::ZERO);
989 generics = generics.move_from_under_binder().unwrap();
991
992 let assoc_tys = vtable_ref
998 .generics
999 .types
1000 .iter()
1001 .filter_map(|ty| {
1002 if let TyKind::TraitType(tref, name) = &ty.kind() {
1003 Some((tref.trait_decl_ref.skip_binder.id, name.clone()))
1004 } else {
1005 None
1006 }
1007 })
1008 .collect_vec();
1009
1010 for (trait_id, assoc_name) in assoc_tys {
1013 let Some(assoc_ty) = binder.params.trait_type_constraints.iter().find_map(|c| {
1015 let c = c.clone().erase();
1016 if c.trait_ref.trait_decl_ref.skip_binder.id == trait_id
1017 && c.type_name == assoc_name
1018 {
1019 Some(c.ty.clone().move_from_under_binder().unwrap())
1021 } else {
1022 None
1023 }
1024 }) else {
1025 let dyn_self_ty = Ty::new(TyKind::DynTrait(self.clone()));
1026 panic!(
1027 "Could not find associated type {}::{} for vtable of trait {} in dyn Trait type: {}",
1028 trait_id.with_ctx(&translated.into_fmt()),
1029 assoc_name,
1030 trait_name,
1031 dyn_self_ty.with_ctx(&translated.into_fmt())
1032 );
1033 };
1034 generics.types.push(assoc_ty);
1036 }
1037
1038 Some(TypeDeclRef {
1040 id: vtable_ref.id,
1041 generics,
1042 })
1043 }
1044}
1045
1046impl RefKind {
1047 pub fn mutable(x: bool) -> Self {
1048 if x { Self::Mut } else { Self::Shared }
1049 }
1050}
1051
1052pub trait VarsVisitor {
1057 fn visit_region_var(&mut self, _v: RegionDbVar) -> Option<Region> {
1058 None
1059 }
1060 fn visit_type_var(&mut self, _v: TypeDbVar) -> Option<Ty> {
1061 None
1062 }
1063 fn visit_const_generic_var(&mut self, _v: ConstGenericDbVar) -> Option<ConstGeneric> {
1064 None
1065 }
1066 fn visit_clause_var(&mut self, _v: ClauseDbVar) -> Option<TraitRefKind> {
1067 None
1068 }
1069 fn visit_self_clause(&mut self) -> Option<TraitRefKind> {
1070 None
1071 }
1072}
1073
1074#[derive(Visitor)]
1077pub(crate) struct SubstVisitor<'a> {
1078 generics: &'a GenericArgs,
1079 self_ref: &'a TraitRefKind,
1080 explicits_only: bool,
1082}
1083impl<'a> SubstVisitor<'a> {
1084 pub(crate) fn new(
1085 generics: &'a GenericArgs,
1086 self_ref: &'a TraitRefKind,
1087 explicits_only: bool,
1088 ) -> Self {
1089 Self {
1090 generics,
1091 self_ref,
1092 explicits_only,
1093 }
1094 }
1095
1096 fn process_var<Id, T>(&self, var: DeBruijnVar<Id>, get: impl Fn(Id) -> &'a T) -> Option<T>
1098 where
1099 Id: Copy,
1100 T: Clone + TyVisitable,
1101 DeBruijnVar<Id>: Into<T>,
1102 {
1103 match var {
1104 DeBruijnVar::Bound(dbid, varid) => {
1105 Some(if let Some(dbid) = dbid.sub(DeBruijnId::one()) {
1106 DeBruijnVar::Bound(dbid, varid).into()
1108 } else {
1109 get(varid).clone()
1110 })
1111 }
1112 DeBruijnVar::Free(..) => None,
1113 }
1114 }
1115}
1116impl VarsVisitor for SubstVisitor<'_> {
1117 fn visit_region_var(&mut self, v: RegionDbVar) -> Option<Region> {
1118 self.process_var(v, |id| &self.generics[id])
1119 }
1120 fn visit_type_var(&mut self, v: TypeDbVar) -> Option<Ty> {
1121 self.process_var(v, |id| &self.generics[id])
1122 }
1123 fn visit_const_generic_var(&mut self, v: ConstGenericDbVar) -> Option<ConstGeneric> {
1124 self.process_var(v, |id| &self.generics[id])
1125 }
1126 fn visit_clause_var(&mut self, v: ClauseDbVar) -> Option<TraitRefKind> {
1127 if self.explicits_only {
1128 None
1129 } else {
1130 self.process_var(v, |id| &self.generics[id].kind)
1131 }
1132 }
1133 fn visit_self_clause(&mut self) -> Option<TraitRefKind> {
1134 Some(self.self_ref.clone())
1135 }
1136}
1137
1138pub trait TyVisitable: Sized + AstVisitable {
1140 fn visit_vars(&mut self, v: &mut impl VarsVisitor) {
1144 #[derive(Visitor)]
1145 struct Wrap<'v, V> {
1146 v: &'v mut V,
1147 depth: DeBruijnId,
1148 }
1149 impl<V: VarsVisitor> VisitAstMut for Wrap<'_, V> {
1150 fn enter_region_binder<T: AstVisitable>(&mut self, _: &mut RegionBinder<T>) {
1151 self.depth = self.depth.incr()
1152 }
1153 fn exit_region_binder<T: AstVisitable>(&mut self, _: &mut RegionBinder<T>) {
1154 self.depth = self.depth.decr()
1155 }
1156 fn enter_binder<T: AstVisitable>(&mut self, _: &mut Binder<T>) {
1157 self.depth = self.depth.incr()
1158 }
1159 fn exit_binder<T: AstVisitable>(&mut self, _: &mut Binder<T>) {
1160 self.depth = self.depth.decr()
1161 }
1162
1163 fn exit_region(&mut self, r: &mut Region) {
1164 if let Region::Var(var) = r
1165 && let Some(var) = var.move_out_from_depth(self.depth)
1166 && let Some(new_r) = self.v.visit_region_var(var)
1167 {
1168 *r = new_r.move_under_binders(self.depth);
1169 }
1170 }
1171 fn exit_ty(&mut self, ty: &mut Ty) {
1172 if let TyKind::TypeVar(var) = ty.kind()
1173 && let Some(var) = var.move_out_from_depth(self.depth)
1174 && let Some(new_ty) = self.v.visit_type_var(var)
1175 {
1176 *ty = new_ty.move_under_binders(self.depth);
1177 }
1178 }
1179 fn exit_const_generic(&mut self, cg: &mut ConstGeneric) {
1180 if let ConstGeneric::Var(var) = cg
1181 && let Some(var) = var.move_out_from_depth(self.depth)
1182 && let Some(new_cg) = self.v.visit_const_generic_var(var)
1183 {
1184 *cg = new_cg.move_under_binders(self.depth);
1185 }
1186 }
1187 fn exit_constant_expr(&mut self, ce: &mut ConstantExpr) {
1188 if let ConstantExprKind::Var(var) = &mut ce.kind
1189 && let Some(var) = var.move_out_from_depth(self.depth)
1190 && let Some(new_cg) = self.v.visit_const_generic_var(var)
1191 {
1192 ce.kind = new_cg.move_under_binders(self.depth).into();
1193 }
1194 }
1195 fn exit_trait_ref_kind(&mut self, kind: &mut TraitRefKind) {
1196 match kind {
1197 TraitRefKind::SelfId => {
1198 if let Some(new_kind) = self.v.visit_self_clause() {
1199 *kind = new_kind.move_under_binders(self.depth);
1200 }
1201 }
1202 TraitRefKind::Clause(var) => {
1203 if let Some(var) = var.move_out_from_depth(self.depth)
1204 && let Some(new_kind) = self.v.visit_clause_var(var)
1205 {
1206 *kind = new_kind.move_under_binders(self.depth);
1207 }
1208 }
1209 _ => {}
1210 }
1211 }
1212 }
1213 let _ = self.drive_mut(&mut Wrap {
1214 v,
1215 depth: DeBruijnId::zero(),
1216 });
1217 }
1218
1219 fn substitute(self, generics: &GenericArgs) -> Self {
1223 self.substitute_with_self(generics, &TraitRefKind::SelfId)
1224 }
1225 fn substitute_explicits(mut self, generics: &GenericArgs) -> Self {
1227 let _ = self.visit_vars(&mut SubstVisitor::new(
1228 generics,
1229 &TraitRefKind::SelfId,
1230 true,
1231 ));
1232 self
1233 }
1234 fn substitute_with_self(mut self, generics: &GenericArgs, self_ref: &TraitRefKind) -> Self {
1236 let _ = self.visit_vars(&mut SubstVisitor::new(generics, self_ref, false));
1237 self
1238 }
1239
1240 fn move_under_binder(self) -> Self {
1242 self.move_under_binders(DeBruijnId::one())
1243 }
1244
1245 fn move_under_binders(mut self, depth: DeBruijnId) -> Self {
1247 if !depth.is_zero() {
1248 let Continue(()) = self.visit_db_id::<Infallible>(|id| {
1249 *id = id.plus(depth);
1250 Continue(())
1251 });
1252 }
1253 self
1254 }
1255
1256 fn move_from_under_binder(self) -> Option<Self> {
1258 self.move_from_under_binders(DeBruijnId::one())
1259 }
1260
1261 fn move_from_under_binders(mut self, depth: DeBruijnId) -> Option<Self> {
1264 self.visit_db_id::<()>(|id| match id.sub(depth) {
1265 Some(sub) => {
1266 *id = sub;
1267 Continue(())
1268 }
1269 None => Break(()),
1270 })
1271 .is_continue()
1272 .then_some(self)
1273 }
1274
1275 fn visit_db_id<B>(
1279 &mut self,
1280 f: impl FnMut(&mut DeBruijnId) -> ControlFlow<B>,
1281 ) -> ControlFlow<B> {
1282 struct Wrap<F> {
1283 f: F,
1284 depth: DeBruijnId,
1285 }
1286 impl<B, F> Visitor for Wrap<F>
1287 where
1288 F: FnMut(&mut DeBruijnId) -> ControlFlow<B>,
1289 {
1290 type Break = B;
1291 }
1292 impl<B, F> VisitAstMut for Wrap<F>
1293 where
1294 F: FnMut(&mut DeBruijnId) -> ControlFlow<B>,
1295 {
1296 fn enter_region_binder<T: AstVisitable>(&mut self, _: &mut RegionBinder<T>) {
1297 self.depth = self.depth.incr()
1298 }
1299 fn exit_region_binder<T: AstVisitable>(&mut self, _: &mut RegionBinder<T>) {
1300 self.depth = self.depth.decr()
1301 }
1302 fn enter_binder<T: AstVisitable>(&mut self, _: &mut Binder<T>) {
1303 self.depth = self.depth.incr()
1304 }
1305 fn exit_binder<T: AstVisitable>(&mut self, _: &mut Binder<T>) {
1306 self.depth = self.depth.decr()
1307 }
1308
1309 fn visit_de_bruijn_id(&mut self, x: &mut DeBruijnId) -> ControlFlow<Self::Break> {
1310 if let Some(mut shifted) = x.sub(self.depth) {
1311 (self.f)(&mut shifted)?;
1312 *x = shifted.plus(self.depth)
1313 }
1314 Continue(())
1315 }
1316 }
1317 self.drive_mut(&mut Wrap {
1318 f,
1319 depth: DeBruijnId::zero(),
1320 })
1321 }
1322}
1323
1324impl TypeDecl {
1325 pub fn get_variant_from_tag(&self, tag: ScalarValue) -> Option<VariantId> {
1331 let layout = self.layout.as_ref()?;
1332 if layout.uninhabited {
1333 return None;
1334 };
1335 let discr_layout = layout.discriminant_layout.as_ref()?;
1336
1337 let variant_for_tag =
1338 layout
1339 .variant_layouts
1340 .iter_indexed()
1341 .find_map(|(id, variant_layout)| {
1342 if variant_layout.tag == Some(tag) {
1343 Some(id)
1344 } else {
1345 None
1346 }
1347 });
1348
1349 match &discr_layout.encoding {
1350 TagEncoding::Direct => {
1351 assert_eq!(tag.get_integer_ty(), discr_layout.tag_ty);
1352 variant_for_tag
1353 }
1354 TagEncoding::Niche { untagged_variant } => variant_for_tag.or(Some(*untagged_variant)),
1355 }
1356 }
1357
1358 pub fn is_c_repr(&self) -> bool {
1359 self.repr
1360 .as_ref()
1361 .is_some_and(|repr| repr.repr_algo == ReprAlgorithm::C)
1362 }
1363
1364 pub fn get_field_by_name(
1365 &self,
1366 variant: Option<VariantId>,
1367 field_name: &str,
1368 ) -> Option<(FieldId, &Field)> {
1369 let fields = match &self.kind {
1370 TypeDeclKind::Struct(fields) | TypeDeclKind::Union(fields) => fields,
1371 TypeDeclKind::Enum(variants) => &variants[variant.unwrap()].fields,
1372 _ => return None,
1373 };
1374 fields
1375 .iter_indexed()
1376 .find(|(_, field)| field.name.as_deref() == Some(field_name))
1377 }
1378}
1379
1380impl Layout {
1381 pub fn is_variant_uninhabited(&self, variant_id: VariantId) -> bool {
1382 if let Some(v) = self.variant_layouts.get(variant_id) {
1383 v.uninhabited
1384 } else {
1385 false
1386 }
1387 }
1388}
1389
1390impl ReprOptions {
1391 pub fn guarantees_fixed_field_order(&self) -> bool {
1401 self.repr_algo == ReprAlgorithm::C || self.explicit_discr_type
1402 }
1403}
1404
1405impl<T: AstVisitable> TyVisitable for T {}
1406
1407impl Eq for TraitParam {}
1408
1409mk_index_impls!(GenericArgs.regions[RegionId]: Region);
1410mk_index_impls!(GenericArgs.types[TypeVarId]: Ty);
1411mk_index_impls!(GenericArgs.const_generics[ConstGenericVarId]: ConstGeneric);
1412mk_index_impls!(GenericArgs.trait_refs[TraitClauseId]: TraitRef);
1413mk_index_impls!(GenericParams.regions[RegionId]: RegionParam);
1414mk_index_impls!(GenericParams.types[TypeVarId]: TypeParam);
1415mk_index_impls!(GenericParams.const_generics[ConstGenericVarId]: ConstGenericParam);
1416mk_index_impls!(GenericParams.trait_clauses[TraitClauseId]: TraitParam);