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) {
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 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 pub fn binds_anything(&self) -> bool {
166 !self.params.is_empty()
167 }
168
169 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 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 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 *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 let mut outer_params = self.params;
265
266 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 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 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 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 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 pub fn has_explicits(&self) -> bool {
398 !self.regions.is_empty() || !self.types.is_empty() || !self.const_generics.is_empty()
399 }
400 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 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 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 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 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 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 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 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 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#[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 pub fn under_binder_of(self, item_id: ItemId) -> T {
610 self.assert_item_id(item_id);
611 self.val
612 }
613
614 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#[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 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 pub fn is_unit(&self) -> bool {
666 match self.as_tuple() {
667 Some(tys) => tys.is_empty(),
668 None => false,
669 }
670 }
671
672 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 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 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 PtrMetadata::InheritFrom(ty) => {
722 let ty = ty.clone().substitute(&ty_ref.generics);
723 ty.get_ptr_metadata(translated)
724 }
725 meta => meta.clone().substitute(&ty_ref.generics),
727 }
728 }
729 TypeId::Tuple => {
731 match ty_ref.generics.types.iter().last() {
732 None => PtrMetadata::None,
734 Some(ty) => ty.get_ptr_metadata(translated),
736 }
737 }
738 TypeId::Builtin(BuiltinTy::Box) => PtrMetadata::None,
740 TypeId::Builtin(BuiltinTy::Array) => PtrMetadata::None,
742 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 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
805impl std::ops::Deref for Ty {
807 type Target = TyKind;
808
809 fn deref(&self) -> &Self::Target {
810 self.kind()
811 }
812}
813unsafe 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 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 pub fn renamed_name(&self) -> Option<&str> {
877 self.attr_info.rename.as_deref().or(self.name.as_deref())
878 }
879
880 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 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 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 pub fn vtable_ref(&self, translated: &TranslatedCrate) -> Option<TypeDeclRef> {
914 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 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 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 let binder = &self.binder;
947
948 let trait_ref = binder.params.trait_clauses[0].trait_.clone().erase();
952 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 generics.types.remove_and_shift_ids(TypeVarId::ZERO);
960 generics = generics.move_from_under_binder().unwrap();
962
963 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 for (trait_id, assoc_name) in assoc_tys {
984 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 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 generics.types.push(assoc_ty);
1007 }
1008
1009 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
1023pub 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#[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 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 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
1095pub trait TyVisitable: Sized + AstVisitable {
1097 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 fn move_under_binder(self) -> Self {
1187 self.move_under_binders(DeBruijnId::one())
1188 }
1189
1190 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 fn move_from_under_binder(self) -> Option<Self> {
1203 self.move_from_under_binders(DeBruijnId::one())
1204 }
1205
1206 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 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 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 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);