1use crate::ast::*;
3use crate::common::hash_consing::HashConsed;
4use crate::formatter::IntoFormatter;
5use crate::ids::Vector;
6use crate::pretty::FmtWithCtx;
7use derive_generic_visitor::*;
8use itertools::Itertools;
9use std::collections::HashSet;
10use std::convert::Infallible;
11use std::fmt::Debug;
12use std::iter::Iterator;
13use std::mem;
14
15impl TraitParam {
16 pub fn identity_tref(&self) -> TraitRef {
18 self.identity_tref_at_depth(DeBruijnId::zero())
19 }
20
21 pub fn identity_tref_at_depth(&self, depth: DeBruijnId) -> TraitRef {
23 TraitRef::new(
24 TraitRefKind::Clause(DeBruijnVar::bound(depth, self.clause_id)),
25 self.trait_.clone().move_under_binders(depth),
26 )
27 }
28}
29
30impl GenericParams {
31 pub fn empty() -> Self {
32 Self::default()
33 }
34
35 pub fn is_empty(&self) -> bool {
36 self.len() == 0
37 }
38 pub fn has_explicits(&self) -> bool {
40 !self.regions.is_empty() || !self.types.is_empty() || !self.const_generics.is_empty()
41 }
42 pub fn has_predicates(&self) -> bool {
45 !self.trait_clauses.is_empty()
46 || !self.types_outlive.is_empty()
47 || !self.regions_outlive.is_empty()
48 || !self.trait_type_constraints.is_empty()
49 }
50
51 pub fn check_consistency(&self) {
53 assert!(
55 self.trait_clauses
56 .iter()
57 .enumerate()
58 .all(|(i, c)| c.clause_id.index() == i)
59 );
60
61 let mut s = HashSet::new();
66 for r in &self.regions {
67 if let Some(name) = &r.name {
68 assert!(
69 !s.contains(name),
70 "Name \"{}\" reused for two different lifetimes",
71 name
72 );
73 s.insert(name);
74 }
75 }
76 }
77
78 pub fn len(&self) -> usize {
79 let GenericParams {
80 regions,
81 types,
82 const_generics,
83 trait_clauses,
84 regions_outlive,
85 types_outlive,
86 trait_type_constraints,
87 } = self;
88 regions.elem_count()
89 + types.elem_count()
90 + const_generics.elem_count()
91 + trait_clauses.elem_count()
92 + regions_outlive.len()
93 + types_outlive.len()
94 + trait_type_constraints.elem_count()
95 }
96
97 pub fn identity_args(&self) -> GenericArgs {
101 self.identity_args_at_depth(DeBruijnId::zero())
102 }
103
104 pub fn identity_args_at_depth(&self, depth: DeBruijnId) -> GenericArgs {
106 GenericArgs {
107 regions: self
108 .regions
109 .map_ref_indexed(|id, _| Region::Var(DeBruijnVar::bound(depth, id))),
110 types: self
111 .types
112 .map_ref_indexed(|id, _| TyKind::TypeVar(DeBruijnVar::bound(depth, id)).into_ty()),
113 const_generics: self
114 .const_generics
115 .map_ref_indexed(|id, _| ConstGeneric::Var(DeBruijnVar::bound(depth, id))),
116 trait_refs: self
117 .trait_clauses
118 .map_ref(|clause| clause.identity_tref_at_depth(depth)),
119 }
120 }
121
122 pub fn take_predicates_from(&mut self, other: GenericParams) {
125 assert!(!other.has_explicits());
126 let num_clauses = self.trait_clauses.slot_count();
127 let GenericParams {
128 regions: _,
129 types: _,
130 const_generics: _,
131 trait_clauses,
132 regions_outlive,
133 types_outlive,
134 trait_type_constraints,
135 } = other;
136 self.trait_clauses
137 .extend(trait_clauses.into_iter().update(|clause| {
138 clause.clause_id += num_clauses;
139 }));
140 self.regions_outlive.extend(regions_outlive);
141 self.types_outlive.extend(types_outlive);
142 self.trait_type_constraints.extend(trait_type_constraints);
143 }
144
145 pub fn merge_predicates_from(&mut self, mut other: GenericParams) {
149 other.types.clear();
151 other.regions.clear();
152 other.const_generics.clear();
153 struct ShiftClausesVisitor(usize);
155 impl VarsVisitor for ShiftClausesVisitor {
156 fn visit_clause_var(&mut self, v: ClauseDbVar) -> Option<TraitRefKind> {
157 if let DeBruijnVar::Bound(DeBruijnId::ZERO, clause_id) = v {
158 Some(TraitRefKind::Clause(DeBruijnVar::Bound(
160 DeBruijnId::ZERO,
161 clause_id + self.0,
162 )))
163 } else {
164 None
165 }
166 }
167 }
168 let num_clauses = self.trait_clauses.slot_count();
169 other.visit_vars(&mut ShiftClausesVisitor(num_clauses));
170 self.take_predicates_from(other);
171 }
172}
173
174impl<T> Binder<T> {
175 pub fn empty(kind: BinderKind, x: T) -> Self
177 where
178 T: TyVisitable,
179 {
180 Binder {
181 params: Default::default(),
182 skip_binder: x.move_under_binder(),
183 kind,
184 }
185 }
186 pub fn new(kind: BinderKind, params: GenericParams, skip_binder: T) -> Self {
187 Self {
188 params,
189 skip_binder,
190 kind,
191 }
192 }
193
194 pub fn binds_anything(&self) -> bool {
196 !self.params.is_empty()
197 }
198
199 pub fn get_if_binds_nothing(&self) -> Option<T>
202 where
203 T: TyVisitable + Clone,
204 {
205 self.params
206 .is_empty()
207 .then(|| self.skip_binder.clone().move_from_under_binder().unwrap())
208 }
209
210 pub fn map<U>(self, f: impl FnOnce(T) -> U) -> Binder<U> {
211 Binder {
212 params: self.params,
213 skip_binder: f(self.skip_binder),
214 kind: self.kind.clone(),
215 }
216 }
217
218 pub fn map_ref<U>(&self, f: impl FnOnce(&T) -> U) -> Binder<U> {
219 Binder {
220 params: self.params.clone(),
221 skip_binder: f(&self.skip_binder),
222 kind: self.kind.clone(),
223 }
224 }
225
226 pub fn apply(self, args: &GenericArgs) -> T
229 where
230 T: TyVisitable,
231 {
232 self.skip_binder.substitute(args)
233 }
234}
235
236impl<T: AstVisitable> Binder<Binder<T>> {
237 pub fn flatten(self) -> Binder<T> {
239 #[derive(Visitor)]
240 struct FlattenVisitor<'a> {
241 shift_by: &'a GenericParams,
242 binder_depth: DeBruijnId,
243 }
244 impl VisitorWithBinderDepth for FlattenVisitor<'_> {
245 fn binder_depth_mut(&mut self) -> &mut DeBruijnId {
246 &mut self.binder_depth
247 }
248 }
249 impl VisitAstMut for FlattenVisitor<'_> {
250 fn visit<'a, T: AstVisitable>(&'a mut self, x: &mut T) -> ControlFlow<Self::Break> {
251 VisitWithBinderDepth::new(self).visit(x)
252 }
253
254 fn enter_de_bruijn_id(&mut self, db_id: &mut DeBruijnId) {
255 if *db_id > self.binder_depth {
256 *db_id = db_id.decr();
261 }
262 }
263 fn enter_region(&mut self, x: &mut Region) {
264 if let Region::Var(var) = x
265 && let Some(id) = var.bound_at_depth_mut(self.binder_depth)
266 {
267 *id += self.shift_by.regions.slot_count();
268 }
269 }
270 fn enter_ty_kind(&mut self, x: &mut TyKind) {
271 if let TyKind::TypeVar(var) = x
272 && let Some(id) = var.bound_at_depth_mut(self.binder_depth)
273 {
274 *id += self.shift_by.types.slot_count();
275 }
276 }
277 fn enter_const_generic(&mut self, x: &mut ConstGeneric) {
278 if let ConstGeneric::Var(var) = x
279 && let Some(id) = var.bound_at_depth_mut(self.binder_depth)
280 {
281 *id += self.shift_by.const_generics.slot_count();
282 }
283 }
284 fn enter_trait_ref_kind(&mut self, x: &mut TraitRefKind) {
285 if let TraitRefKind::Clause(var) = x
286 && let Some(id) = var.bound_at_depth_mut(self.binder_depth)
287 {
288 *id += self.shift_by.trait_clauses.slot_count();
289 }
290 }
291 }
292
293 let mut outer_params = self.params;
295
296 let mut bound_value = self.skip_binder.skip_binder;
300 let _ = bound_value.drive_mut(&mut FlattenVisitor {
301 shift_by: &outer_params,
302 binder_depth: Default::default(),
303 });
304
305 let mut inner_params = self.skip_binder.params;
308 let _ = inner_params.drive_mut(&mut FlattenVisitor {
309 shift_by: &outer_params,
310 binder_depth: Default::default(),
311 });
312 inner_params
313 .regions
314 .iter_mut()
315 .for_each(|v| v.index += outer_params.regions.slot_count());
316 inner_params
317 .types
318 .iter_mut()
319 .for_each(|v| v.index += outer_params.types.slot_count());
320 inner_params
321 .const_generics
322 .iter_mut()
323 .for_each(|v| v.index += outer_params.const_generics.slot_count());
324 inner_params
325 .trait_clauses
326 .iter_mut()
327 .for_each(|v| v.clause_id += outer_params.trait_clauses.slot_count());
328
329 let GenericParams {
330 regions,
331 types,
332 const_generics,
333 trait_clauses,
334 regions_outlive,
335 types_outlive,
336 trait_type_constraints,
337 } = &inner_params;
338 outer_params.regions.extend_from_slice(regions);
339 outer_params.types.extend_from_slice(types);
340 outer_params
341 .const_generics
342 .extend_from_slice(const_generics);
343 outer_params.trait_clauses.extend_from_slice(trait_clauses);
344 outer_params
345 .regions_outlive
346 .extend_from_slice(regions_outlive);
347 outer_params.types_outlive.extend_from_slice(types_outlive);
348 outer_params
349 .trait_type_constraints
350 .extend_from_slice(trait_type_constraints);
351
352 Binder {
353 params: outer_params,
354 skip_binder: bound_value,
355 kind: BinderKind::Other,
356 }
357 }
358}
359
360impl<T> RegionBinder<T> {
361 pub fn empty(x: T) -> Self
363 where
364 T: TyVisitable,
365 {
366 RegionBinder {
367 regions: Default::default(),
368 skip_binder: x.move_under_binder(),
369 }
370 }
371
372 pub fn map<U>(self, f: impl FnOnce(T) -> U) -> RegionBinder<U> {
373 RegionBinder {
374 regions: self.regions,
375 skip_binder: f(self.skip_binder),
376 }
377 }
378
379 pub fn map_ref<U>(&self, f: impl FnOnce(&T) -> U) -> RegionBinder<U> {
380 RegionBinder {
381 regions: self.regions.clone(),
382 skip_binder: f(&self.skip_binder),
383 }
384 }
385
386 pub fn apply(self, regions: Vector<RegionId, Region>) -> T
388 where
389 T: AstVisitable,
390 {
391 assert_eq!(regions.slot_count(), self.regions.slot_count());
392 let args = GenericArgs {
393 regions,
394 ..GenericArgs::empty()
395 };
396 self.skip_binder.substitute(&args)
397 }
398
399 pub fn erase(self) -> T
401 where
402 T: AstVisitable,
403 {
404 let regions = self.regions.map_ref_indexed(|_, _| Region::Erased);
405 self.apply(regions)
406 }
407}
408
409impl GenericArgs {
410 pub fn len(&self) -> usize {
411 let GenericArgs {
412 regions,
413 types,
414 const_generics,
415 trait_refs,
416 } = self;
417 regions.elem_count()
418 + types.elem_count()
419 + const_generics.elem_count()
420 + trait_refs.elem_count()
421 }
422
423 pub fn is_empty(&self) -> bool {
424 self.len() == 0
425 }
426 pub fn has_explicits(&self) -> bool {
428 !self.regions.is_empty() || !self.types.is_empty() || !self.const_generics.is_empty()
429 }
430 pub fn has_implicits(&self) -> bool {
432 !self.trait_refs.is_empty()
433 }
434
435 pub fn empty() -> Self {
436 GenericArgs {
437 regions: Default::default(),
438 types: Default::default(),
439 const_generics: Default::default(),
440 trait_refs: Default::default(),
441 }
442 }
443
444 pub fn new_for_builtin(types: Vector<TypeVarId, Ty>) -> Self {
445 GenericArgs {
446 types,
447 ..Self::empty()
448 }
449 }
450
451 pub fn new(
452 regions: Vector<RegionId, Region>,
453 types: Vector<TypeVarId, Ty>,
454 const_generics: Vector<ConstGenericVarId, ConstGeneric>,
455 trait_refs: Vector<TraitClauseId, TraitRef>,
456 ) -> Self {
457 Self {
458 regions,
459 types,
460 const_generics,
461 trait_refs,
462 }
463 }
464
465 pub fn new_types(types: Vector<TypeVarId, Ty>) -> Self {
466 Self {
467 types,
468 ..Self::empty()
469 }
470 }
471
472 pub fn matches(&self, params: &GenericParams) -> bool {
475 params.regions.elem_count() == self.regions.elem_count()
476 && params.types.elem_count() == self.types.elem_count()
477 && params.const_generics.elem_count() == self.const_generics.elem_count()
478 && params.trait_clauses.elem_count() == self.trait_refs.elem_count()
479 }
480
481 pub fn pop_first_type_arg(&self) -> (Ty, Self) {
486 let mut generics = self.clone();
487 let mut it = mem::take(&mut generics.types).into_iter();
488 let ty = it.next().unwrap();
489 generics.types = it.collect();
490 (ty, generics)
491 }
492
493 pub fn concat(mut self, other: &Self) -> Self {
496 let Self {
497 regions,
498 types,
499 const_generics,
500 trait_refs,
501 } = other;
502 self.regions.extend_from_slice(regions);
503 self.types.extend_from_slice(types);
504 self.const_generics.extend_from_slice(const_generics);
505 self.trait_refs.extend_from_slice(trait_refs);
506 self
507 }
508}
509
510impl IntTy {
511 pub fn target_size(&self, ptr_size: ByteCount) -> usize {
514 match self {
515 IntTy::Isize => ptr_size as usize,
516 IntTy::I8 => size_of::<i8>(),
517 IntTy::I16 => size_of::<i16>(),
518 IntTy::I32 => size_of::<i32>(),
519 IntTy::I64 => size_of::<i64>(),
520 IntTy::I128 => size_of::<i128>(),
521 }
522 }
523}
524impl UIntTy {
525 pub fn target_size(&self, ptr_size: ByteCount) -> usize {
528 match self {
529 UIntTy::Usize => ptr_size as usize,
530 UIntTy::U8 => size_of::<u8>(),
531 UIntTy::U16 => size_of::<u16>(),
532 UIntTy::U32 => size_of::<u32>(),
533 UIntTy::U64 => size_of::<u64>(),
534 UIntTy::U128 => size_of::<u128>(),
535 }
536 }
537}
538impl FloatTy {
539 pub fn target_size(&self) -> usize {
542 match self {
543 FloatTy::F16 => size_of::<u16>(),
544 FloatTy::F32 => size_of::<u32>(),
545 FloatTy::F64 => size_of::<u64>(),
546 FloatTy::F128 => size_of::<u128>(),
547 }
548 }
549}
550
551impl IntegerTy {
552 pub fn to_unsigned(&self) -> Self {
553 match self {
554 IntegerTy::Signed(IntTy::Isize) => IntegerTy::Unsigned(UIntTy::Usize),
555 IntegerTy::Signed(IntTy::I8) => IntegerTy::Unsigned(UIntTy::U8),
556 IntegerTy::Signed(IntTy::I16) => IntegerTy::Unsigned(UIntTy::U16),
557 IntegerTy::Signed(IntTy::I32) => IntegerTy::Unsigned(UIntTy::U32),
558 IntegerTy::Signed(IntTy::I64) => IntegerTy::Unsigned(UIntTy::U64),
559 IntegerTy::Signed(IntTy::I128) => IntegerTy::Unsigned(UIntTy::U128),
560 _ => *self,
561 }
562 }
563
564 pub fn target_size(&self, ptr_size: ByteCount) -> usize {
567 match self {
568 IntegerTy::Signed(ty) => ty.target_size(ptr_size),
569 IntegerTy::Unsigned(ty) => ty.target_size(ptr_size),
570 }
571 }
572}
573
574impl LiteralTy {
575 pub fn to_integer_ty(&self) -> Option<IntegerTy> {
576 match self {
577 Self::Int(int_ty) => Some(IntegerTy::Signed(*int_ty)),
578 Self::UInt(uint_ty) => Some(IntegerTy::Unsigned(*uint_ty)),
579 _ => None,
580 }
581 }
582
583 pub fn target_size(&self, ptr_size: ByteCount) -> usize {
586 match self {
587 LiteralTy::Int(int_ty) => int_ty.target_size(ptr_size),
588 LiteralTy::UInt(uint_ty) => uint_ty.target_size(ptr_size),
589 LiteralTy::Float(float_ty) => float_ty.target_size(),
590 LiteralTy::Char => 4,
591 LiteralTy::Bool => 1,
592 }
593 }
594}
595
596#[derive(Debug, Clone, Copy)]
602pub struct ItemBinder<ItemId, T> {
603 pub item_id: ItemId,
604 val: T,
605}
606
607impl<ItemId, T> ItemBinder<ItemId, T>
608where
609 ItemId: Debug + Copy + PartialEq,
610{
611 pub fn new(item_id: ItemId, val: T) -> Self {
612 Self { item_id, val }
613 }
614
615 pub fn as_ref(&self) -> ItemBinder<ItemId, &T> {
616 ItemBinder {
617 item_id: self.item_id,
618 val: &self.val,
619 }
620 }
621
622 pub fn map_bound<U>(self, f: impl FnOnce(T) -> U) -> ItemBinder<ItemId, U> {
623 ItemBinder {
624 item_id: self.item_id,
625 val: f(self.val),
626 }
627 }
628
629 fn assert_item_id(&self, item_id: ItemId) {
630 assert_eq!(
631 self.item_id, item_id,
632 "Trying to use item bound for {:?} as if it belonged to {:?}",
633 self.item_id, item_id
634 );
635 }
636
637 pub fn under_binder_of(self, item_id: ItemId) -> T {
640 self.assert_item_id(item_id);
641 self.val
642 }
643
644 pub fn substitute<OtherItem: Debug + Copy + PartialEq>(
648 self,
649 args: ItemBinder<OtherItem, &GenericArgs>,
650 ) -> ItemBinder<OtherItem, T>
651 where
652 ItemId: Into<ItemId>,
653 T: TyVisitable,
654 {
655 args.map_bound(|args| self.val.substitute(args))
656 }
657}
658
659#[derive(Debug, Clone, Copy, PartialEq, Eq)]
661pub struct CurrentItem;
662
663impl<T> ItemBinder<CurrentItem, T> {
664 pub fn under_current_binder(self) -> T {
665 self.val
666 }
667}
668
669impl Ty {
670 pub fn new(kind: TyKind) -> Self {
671 Ty(HashConsed::new(kind))
672 }
673
674 pub fn kind(&self) -> &TyKind {
675 self.0.inner()
676 }
677
678 pub fn with_kind_mut<R>(&mut self, f: impl FnOnce(&mut TyKind) -> R) -> R {
679 self.0.with_inner_mut(f)
680 }
681
682 pub fn mk_unit() -> Ty {
684 Self::mk_tuple(vec![])
685 }
686
687 pub fn mk_usize() -> Ty {
688 TyKind::Literal(LiteralTy::UInt(UIntTy::Usize)).into()
689 }
690
691 pub fn mk_tuple(tys: Vec<Ty>) -> Ty {
692 TyKind::Adt(TypeDeclRef {
693 id: TypeId::Tuple,
694 generics: Box::new(GenericArgs::new_for_builtin(tys.into())),
695 })
696 .into_ty()
697 }
698
699 pub fn mk_slice(ty: Ty) -> Ty {
700 TyKind::Adt(TypeDeclRef {
701 id: TypeId::Builtin(BuiltinTy::Slice),
702 generics: Box::new(GenericArgs::new_for_builtin(vec![ty].into())),
703 })
704 .into_ty()
705 }
706 pub fn is_unit(&self) -> bool {
708 match self.as_tuple() {
709 Some(tys) => tys.is_empty(),
710 None => false,
711 }
712 }
713
714 pub fn is_scalar(&self) -> bool {
716 match self.kind() {
717 TyKind::Literal(kind) => kind.is_int() || kind.is_uint(),
718 _ => false,
719 }
720 }
721
722 pub fn is_unsigned_scalar(&self) -> bool {
723 matches!(self.kind(), TyKind::Literal(LiteralTy::UInt(_)))
724 }
725
726 pub fn is_signed_scalar(&self) -> bool {
727 matches!(self.kind(), TyKind::Literal(LiteralTy::Int(_)))
728 }
729
730 pub fn is_box(&self) -> bool {
732 match self.kind() {
733 TyKind::Adt(ty_ref) if let TypeId::Builtin(BuiltinTy::Box) = ty_ref.id => true,
734 _ => false,
735 }
736 }
737
738 pub fn as_box(&self) -> Option<&Ty> {
739 match self.kind() {
740 TyKind::Adt(ty_ref) if let TypeId::Builtin(BuiltinTy::Box) = ty_ref.id => {
741 Some(&ty_ref.generics.types[0])
742 }
743 _ => None,
744 }
745 }
746
747 pub fn get_ptr_metadata(&self, translated: &TranslatedCrate) -> PtrMetadata {
748 let ref ty_decls = translated.type_decls;
749 match self.kind() {
750 TyKind::Adt(ty_ref) => {
751 match ty_ref.id {
755 TypeId::Adt(type_decl_id) => {
756 let Some(decl) = ty_decls.get(type_decl_id) else {
757 return PtrMetadata::InheritFrom(Ty::new(TyKind::Error(format!(
758 "Internal Error: type decl id not found during getting metadata: {type_decl_id}"
759 ))));
760 };
761 match &decl.ptr_metadata {
762 PtrMetadata::InheritFrom(ty) => {
764 let ty = ty.clone().substitute(&ty_ref.generics);
765 ty.get_ptr_metadata(translated)
766 }
767 meta => meta.clone().substitute(&ty_ref.generics),
769 }
770 }
771 TypeId::Tuple => {
773 match ty_ref.generics.types.iter().last() {
774 None => PtrMetadata::None,
776 Some(ty) => ty.get_ptr_metadata(translated),
778 }
779 }
780 TypeId::Builtin(BuiltinTy::Box) => PtrMetadata::None,
782 TypeId::Builtin(BuiltinTy::Array) => PtrMetadata::None,
784 TypeId::Builtin(BuiltinTy::Slice) => PtrMetadata::Length,
786 TypeId::Builtin(BuiltinTy::Str) => PtrMetadata::Length,
787 }
788 }
789 TyKind::DynTrait(pred) => match pred.vtable_ref(translated) {
790 Some(vtable) => PtrMetadata::VTable(vtable),
791 None => PtrMetadata::InheritFrom(
792 TyKind::Error(format!(
793 "Vtable for dyn trait {} not found",
794 pred.with_ctx(&translated.into_fmt())
795 ))
796 .into(),
797 ),
798 },
799 TyKind::TraitType(..) | TyKind::TypeVar(_) => PtrMetadata::InheritFrom(self.clone()),
800 TyKind::Literal(_)
801 | TyKind::Never
802 | TyKind::Ref(..)
803 | TyKind::RawPtr(..)
804 | TyKind::FnPtr(..)
805 | TyKind::FnDef(..)
806 | TyKind::Error(_) => PtrMetadata::None,
807 TyKind::PtrMetadata(_) => PtrMetadata::None,
809 }
810 }
811
812 pub fn as_array_or_slice(&self) -> Option<&Ty> {
813 match self.kind() {
814 TyKind::Adt(ty_ref)
815 if let TypeId::Builtin(BuiltinTy::Array | BuiltinTy::Slice) = ty_ref.id =>
816 {
817 Some(&ty_ref.generics.types[0])
818 }
819 _ => None,
820 }
821 }
822
823 pub fn as_tuple(&self) -> Option<&Vector<TypeVarId, Ty>> {
824 match self.kind() {
825 TyKind::Adt(ty_ref) if let TypeId::Tuple = ty_ref.id => Some(&ty_ref.generics.types),
826 _ => None,
827 }
828 }
829
830 pub fn as_adt(&self) -> Option<&TypeDeclRef> {
831 self.kind().as_adt()
832 }
833}
834
835impl TyKind {
836 pub fn into_ty(self) -> Ty {
837 Ty::new(self)
838 }
839}
840
841impl From<TyKind> for Ty {
842 fn from(kind: TyKind) -> Ty {
843 kind.into_ty()
844 }
845}
846
847impl std::ops::Deref for Ty {
849 type Target = TyKind;
850
851 fn deref(&self) -> &Self::Target {
852 self.kind()
853 }
854}
855unsafe impl std::ops::DerefPure for Ty {}
857
858impl TypeDeclRef {
859 pub fn new(id: TypeId, generics: GenericArgs) -> Self {
860 Self {
861 id,
862 generics: Box::new(generics),
863 }
864 }
865}
866
867impl TraitDeclRef {
868 pub fn self_ty<'a>(&'a self, krate: &'a TranslatedCrate) -> Option<&'a Ty> {
869 match self.generics.types.iter().next() {
870 Some(ty) => return Some(ty),
871 None => {
873 let name = krate.item_name(self.id)?;
874 let args = name.name.last()?.as_monomorphized()?;
875 args.types.iter().next()
876 }
877 }
878 }
879}
880
881impl TraitRef {
882 pub fn new(kind: TraitRefKind, trait_decl_ref: PolyTraitDeclRef) -> Self {
883 TraitRefContents {
884 kind,
885 trait_decl_ref,
886 }
887 .intern()
888 }
889
890 pub fn new_builtin(
891 trait_id: TraitDeclId,
892 ty: Ty,
893 parents: Vector<TraitClauseId, TraitRef>,
894 builtin_data: BuiltinImplData,
895 ) -> Self {
896 let trait_decl_ref = RegionBinder::empty(TraitDeclRef {
897 id: trait_id,
898 generics: Box::new(GenericArgs::new_types([ty].into())),
899 });
900 Self::new(
901 TraitRefKind::BuiltinOrAuto {
902 builtin_data,
903 parent_trait_refs: parents,
904 types: Default::default(),
905 },
906 trait_decl_ref,
907 )
908 }
909
910 pub fn with_contents_mut<R>(&mut self, f: impl FnOnce(&mut TraitRefContents) -> R) -> R {
913 self.0.with_inner_mut(f)
914 }
915}
916impl TraitRefContents {
917 pub fn intern(self) -> TraitRef {
918 TraitRef(HashConsed::new(self))
919 }
920}
921
922impl std::ops::Deref for TraitRef {
923 type Target = TraitRefContents;
924 fn deref(&self) -> &Self::Target {
925 &self.0
926 }
927}
928
929impl BuiltinImplData {
930 pub fn as_closure_kind(&self) -> Option<ClosureKind> {
931 match self {
932 BuiltinImplData::FnOnce => Some(ClosureKind::FnOnce),
933 BuiltinImplData::FnMut => Some(ClosureKind::FnMut),
934 BuiltinImplData::Fn => Some(ClosureKind::Fn),
935 _ => None,
936 }
937 }
938}
939
940impl PtrMetadata {
941 pub fn into_type(self) -> Ty {
942 match self {
943 PtrMetadata::None => Ty::mk_unit(),
944 PtrMetadata::Length => Ty::mk_usize(),
945 PtrMetadata::VTable(type_decl_ref) => Ty::new(TyKind::Ref(
946 Region::Static,
947 Ty::new(TyKind::Adt(type_decl_ref)),
948 RefKind::Shared,
949 )),
950 PtrMetadata::InheritFrom(ty) => Ty::new(TyKind::PtrMetadata(ty)),
951 }
952 }
953}
954
955impl Field {
956 pub fn renamed_name(&self) -> Option<&str> {
958 self.attr_info.rename.as_deref().or(self.name.as_deref())
959 }
960
961 pub fn is_opaque(&self) -> bool {
963 self.attr_info
964 .attributes
965 .iter()
966 .any(|attr| attr.is_opaque())
967 }
968}
969
970impl Variant {
971 pub fn renamed_name(&self) -> &str {
974 self.attr_info
975 .rename
976 .as_deref()
977 .unwrap_or(self.name.as_ref())
978 }
979
980 pub fn is_opaque(&self) -> bool {
982 self.attr_info
983 .attributes
984 .iter()
985 .any(|attr| attr.is_opaque())
986 }
987}
988
989impl DynPredicate {
990 pub fn vtable_ref(&self, translated: &TranslatedCrate) -> Option<TypeDeclRef> {
995 let trait_name = self.binder.params.trait_clauses[0]
1000 .trait_
1001 .skip_binder
1002 .id
1003 .with_ctx(&translated.into_fmt())
1004 .to_string();
1005
1006 let Some(trait_decl) = translated
1010 .trait_decls
1011 .get(self.binder.params.trait_clauses[0].trait_.skip_binder.id)
1012 else {
1013 return None;
1014 };
1015
1016 let Some(vtable_ref) = &trait_decl.vtable else {
1019 panic!(
1020 "Vtable for trait {} is None, meaning the trait is non-dyn-compatible!",
1021 trait_name
1022 );
1023 };
1024
1025 let binder = &self.binder;
1028
1029 let trait_ref = binder.params.trait_clauses[0].trait_.clone().erase();
1033 trace!(
1035 "Getting vtable ref with trait-decl-ref {}.",
1036 trait_ref.with_ctx(&translated.into_fmt())
1037 );
1038 let mut generics = trait_ref.generics.clone();
1039 generics.types.remove_and_shift_ids(TypeVarId::ZERO);
1041 generics = generics.move_from_under_binder().unwrap();
1043
1044 let assoc_tys = vtable_ref
1050 .generics
1051 .types
1052 .iter()
1053 .filter_map(|ty| {
1054 if let TyKind::TraitType(tref, name) = &ty.kind() {
1055 Some((tref.trait_decl_ref.skip_binder.id, name.clone()))
1056 } else {
1057 None
1058 }
1059 })
1060 .collect_vec();
1061
1062 for (trait_id, assoc_name) in assoc_tys {
1065 let Some(assoc_ty) = binder.params.trait_type_constraints.iter().find_map(|c| {
1067 let c = c.clone().erase();
1068 if c.trait_ref.trait_decl_ref.skip_binder.id == trait_id
1069 && c.type_name == assoc_name
1070 {
1071 Some(c.ty.clone().move_from_under_binder().unwrap())
1073 } else {
1074 None
1075 }
1076 }) else {
1077 let dyn_self_ty = Ty::new(TyKind::DynTrait(self.clone()));
1078 panic!(
1079 "Could not find associated type {}::{} for vtable of trait {} in dyn Trait type: {}",
1080 trait_id.with_ctx(&translated.into_fmt()),
1081 assoc_name,
1082 trait_name,
1083 dyn_self_ty.with_ctx(&translated.into_fmt())
1084 );
1085 };
1086 generics.types.push(assoc_ty);
1088 }
1089
1090 Some(TypeDeclRef {
1092 id: vtable_ref.id,
1093 generics,
1094 })
1095 }
1096}
1097
1098impl RefKind {
1099 pub fn mutable(x: bool) -> Self {
1100 if x { Self::Mut } else { Self::Shared }
1101 }
1102}
1103
1104pub trait VarsVisitor {
1109 fn visit_region_var(&mut self, _v: RegionDbVar) -> Option<Region> {
1110 None
1111 }
1112 fn visit_type_var(&mut self, _v: TypeDbVar) -> Option<Ty> {
1113 None
1114 }
1115 fn visit_const_generic_var(&mut self, _v: ConstGenericDbVar) -> Option<ConstGeneric> {
1116 None
1117 }
1118 fn visit_clause_var(&mut self, _v: ClauseDbVar) -> Option<TraitRefKind> {
1119 None
1120 }
1121 fn visit_self_clause(&mut self) -> Option<TraitRefKind> {
1122 None
1123 }
1124}
1125
1126#[derive(Visitor)]
1129pub(crate) struct SubstVisitor<'a> {
1130 generics: &'a GenericArgs,
1131 self_ref: &'a TraitRefKind,
1132 explicits_only: bool,
1134}
1135impl<'a> SubstVisitor<'a> {
1136 pub(crate) fn new(
1137 generics: &'a GenericArgs,
1138 self_ref: &'a TraitRefKind,
1139 explicits_only: bool,
1140 ) -> Self {
1141 Self {
1142 generics,
1143 self_ref,
1144 explicits_only,
1145 }
1146 }
1147
1148 fn process_var<Id, T>(&self, var: DeBruijnVar<Id>, get: impl Fn(Id) -> &'a T) -> Option<T>
1150 where
1151 Id: Copy,
1152 T: Clone + TyVisitable,
1153 DeBruijnVar<Id>: Into<T>,
1154 {
1155 match var {
1156 DeBruijnVar::Bound(dbid, varid) => {
1157 Some(if let Some(dbid) = dbid.sub(DeBruijnId::one()) {
1158 DeBruijnVar::Bound(dbid, varid).into()
1160 } else {
1161 get(varid).clone()
1162 })
1163 }
1164 DeBruijnVar::Free(..) => None,
1165 }
1166 }
1167}
1168impl VarsVisitor for SubstVisitor<'_> {
1169 fn visit_region_var(&mut self, v: RegionDbVar) -> Option<Region> {
1170 self.process_var(v, |id| &self.generics[id])
1171 }
1172 fn visit_type_var(&mut self, v: TypeDbVar) -> Option<Ty> {
1173 self.process_var(v, |id| &self.generics[id])
1174 }
1175 fn visit_const_generic_var(&mut self, v: ConstGenericDbVar) -> Option<ConstGeneric> {
1176 self.process_var(v, |id| &self.generics[id])
1177 }
1178 fn visit_clause_var(&mut self, v: ClauseDbVar) -> Option<TraitRefKind> {
1179 if self.explicits_only {
1180 None
1181 } else {
1182 self.process_var(v, |id| &self.generics[id].kind)
1183 }
1184 }
1185 fn visit_self_clause(&mut self) -> Option<TraitRefKind> {
1186 Some(self.self_ref.clone())
1187 }
1188}
1189
1190pub trait TyVisitable: Sized + AstVisitable {
1192 fn visit_vars(&mut self, v: &mut impl VarsVisitor) {
1196 #[derive(Visitor)]
1197 struct Wrap<'v, V> {
1198 v: &'v mut V,
1199 depth: DeBruijnId,
1200 }
1201 impl<V: VarsVisitor> VisitAstMut for Wrap<'_, V> {
1202 fn enter_region_binder<T: AstVisitable>(&mut self, _: &mut RegionBinder<T>) {
1203 self.depth = self.depth.incr()
1204 }
1205 fn exit_region_binder<T: AstVisitable>(&mut self, _: &mut RegionBinder<T>) {
1206 self.depth = self.depth.decr()
1207 }
1208 fn enter_binder<T: AstVisitable>(&mut self, _: &mut Binder<T>) {
1209 self.depth = self.depth.incr()
1210 }
1211 fn exit_binder<T: AstVisitable>(&mut self, _: &mut Binder<T>) {
1212 self.depth = self.depth.decr()
1213 }
1214
1215 fn exit_region(&mut self, r: &mut Region) {
1216 if let Region::Var(var) = r
1217 && let Some(var) = var.move_out_from_depth(self.depth)
1218 && let Some(new_r) = self.v.visit_region_var(var)
1219 {
1220 *r = new_r.move_under_binders(self.depth);
1221 }
1222 }
1223 fn exit_ty(&mut self, ty: &mut Ty) {
1224 if let TyKind::TypeVar(var) = ty.kind()
1225 && let Some(var) = var.move_out_from_depth(self.depth)
1226 && let Some(new_ty) = self.v.visit_type_var(var)
1227 {
1228 *ty = new_ty.move_under_binders(self.depth);
1229 }
1230 }
1231 fn exit_const_generic(&mut self, cg: &mut ConstGeneric) {
1232 if let ConstGeneric::Var(var) = cg
1233 && let Some(var) = var.move_out_from_depth(self.depth)
1234 && let Some(new_cg) = self.v.visit_const_generic_var(var)
1235 {
1236 *cg = new_cg.move_under_binders(self.depth);
1237 }
1238 }
1239 fn exit_constant_expr(&mut self, ce: &mut ConstantExpr) {
1240 if let ConstantExprKind::Var(var) = &mut ce.kind
1241 && let Some(var) = var.move_out_from_depth(self.depth)
1242 && let Some(new_cg) = self.v.visit_const_generic_var(var)
1243 {
1244 ce.kind = new_cg.move_under_binders(self.depth).into();
1245 }
1246 }
1247 fn exit_trait_ref_kind(&mut self, kind: &mut TraitRefKind) {
1248 match kind {
1249 TraitRefKind::SelfId => {
1250 if let Some(new_kind) = self.v.visit_self_clause() {
1251 *kind = new_kind.move_under_binders(self.depth);
1252 }
1253 }
1254 TraitRefKind::Clause(var) => {
1255 if let Some(var) = var.move_out_from_depth(self.depth)
1256 && let Some(new_kind) = self.v.visit_clause_var(var)
1257 {
1258 *kind = new_kind.move_under_binders(self.depth);
1259 }
1260 }
1261 _ => {}
1262 }
1263 }
1264 }
1265 let _ = self.drive_mut(&mut Wrap {
1266 v,
1267 depth: DeBruijnId::zero(),
1268 });
1269 }
1270
1271 fn substitute(self, generics: &GenericArgs) -> Self {
1275 self.substitute_with_self(generics, &TraitRefKind::SelfId)
1276 }
1277 fn substitute_explicits(mut self, generics: &GenericArgs) -> Self {
1279 let _ = self.visit_vars(&mut SubstVisitor::new(
1280 generics,
1281 &TraitRefKind::SelfId,
1282 true,
1283 ));
1284 self
1285 }
1286 fn substitute_with_self(mut self, generics: &GenericArgs, self_ref: &TraitRefKind) -> Self {
1288 let _ = self.visit_vars(&mut SubstVisitor::new(generics, self_ref, false));
1289 self
1290 }
1291
1292 fn move_under_binder(self) -> Self {
1294 self.move_under_binders(DeBruijnId::one())
1295 }
1296
1297 fn move_under_binders(mut self, depth: DeBruijnId) -> Self {
1299 if !depth.is_zero() {
1300 let Continue(()) = self.visit_db_id::<Infallible>(|id| {
1301 *id = id.plus(depth);
1302 Continue(())
1303 });
1304 }
1305 self
1306 }
1307
1308 fn move_from_under_binder(self) -> Option<Self> {
1310 self.move_from_under_binders(DeBruijnId::one())
1311 }
1312
1313 fn move_from_under_binders(mut self, depth: DeBruijnId) -> Option<Self> {
1316 self.visit_db_id::<()>(|id| match id.sub(depth) {
1317 Some(sub) => {
1318 *id = sub;
1319 Continue(())
1320 }
1321 None => Break(()),
1322 })
1323 .is_continue()
1324 .then_some(self)
1325 }
1326
1327 fn visit_db_id<B>(
1331 &mut self,
1332 f: impl FnMut(&mut DeBruijnId) -> ControlFlow<B>,
1333 ) -> ControlFlow<B> {
1334 struct Wrap<F> {
1335 f: F,
1336 depth: DeBruijnId,
1337 }
1338 impl<B, F> Visitor for Wrap<F>
1339 where
1340 F: FnMut(&mut DeBruijnId) -> ControlFlow<B>,
1341 {
1342 type Break = B;
1343 }
1344 impl<B, F> VisitAstMut for Wrap<F>
1345 where
1346 F: FnMut(&mut DeBruijnId) -> ControlFlow<B>,
1347 {
1348 fn enter_region_binder<T: AstVisitable>(&mut self, _: &mut RegionBinder<T>) {
1349 self.depth = self.depth.incr()
1350 }
1351 fn exit_region_binder<T: AstVisitable>(&mut self, _: &mut RegionBinder<T>) {
1352 self.depth = self.depth.decr()
1353 }
1354 fn enter_binder<T: AstVisitable>(&mut self, _: &mut Binder<T>) {
1355 self.depth = self.depth.incr()
1356 }
1357 fn exit_binder<T: AstVisitable>(&mut self, _: &mut Binder<T>) {
1358 self.depth = self.depth.decr()
1359 }
1360
1361 fn visit_de_bruijn_id(&mut self, x: &mut DeBruijnId) -> ControlFlow<Self::Break> {
1362 if let Some(mut shifted) = x.sub(self.depth) {
1363 (self.f)(&mut shifted)?;
1364 *x = shifted.plus(self.depth)
1365 }
1366 Continue(())
1367 }
1368 }
1369 self.drive_mut(&mut Wrap {
1370 f,
1371 depth: DeBruijnId::zero(),
1372 })
1373 }
1374}
1375
1376impl TypeDecl {
1377 pub fn get_variant_from_tag(&self, tag: ScalarValue) -> Option<VariantId> {
1383 let layout = self.layout.as_ref()?;
1384 if layout.uninhabited {
1385 return None;
1386 };
1387 let discr_layout = layout.discriminant_layout.as_ref()?;
1388
1389 let variant_for_tag =
1390 layout
1391 .variant_layouts
1392 .iter_indexed()
1393 .find_map(|(id, variant_layout)| {
1394 if variant_layout.tag == Some(tag) {
1395 Some(id)
1396 } else {
1397 None
1398 }
1399 });
1400
1401 match &discr_layout.encoding {
1402 TagEncoding::Direct => {
1403 assert_eq!(tag.get_integer_ty(), discr_layout.tag_ty);
1404 variant_for_tag
1405 }
1406 TagEncoding::Niche { untagged_variant } => variant_for_tag.or(Some(*untagged_variant)),
1407 }
1408 }
1409
1410 pub fn is_c_repr(&self) -> bool {
1411 self.repr
1412 .as_ref()
1413 .is_some_and(|repr| repr.repr_algo == ReprAlgorithm::C)
1414 }
1415
1416 pub fn get_field_by_name(
1417 &self,
1418 variant: Option<VariantId>,
1419 field_name: &str,
1420 ) -> Option<(FieldId, &Field)> {
1421 let fields = match &self.kind {
1422 TypeDeclKind::Struct(fields) | TypeDeclKind::Union(fields) => fields,
1423 TypeDeclKind::Enum(variants) => &variants[variant.unwrap()].fields,
1424 _ => return None,
1425 };
1426 fields
1427 .iter_indexed()
1428 .find(|(_, field)| field.name.as_deref() == Some(field_name))
1429 }
1430}
1431
1432impl Layout {
1433 pub fn is_variant_uninhabited(&self, variant_id: VariantId) -> bool {
1434 if let Some(v) = self.variant_layouts.get(variant_id) {
1435 v.uninhabited
1436 } else {
1437 false
1438 }
1439 }
1440}
1441
1442impl ReprOptions {
1443 pub fn guarantees_fixed_field_order(&self) -> bool {
1453 self.repr_algo == ReprAlgorithm::C || self.explicit_discr_type
1454 }
1455}
1456
1457impl<T: AstVisitable> TyVisitable for T {}
1458
1459impl Eq for TraitParam {}
1460
1461mk_index_impls!(GenericArgs.regions[RegionId]: Region);
1462mk_index_impls!(GenericArgs.types[TypeVarId]: Ty);
1463mk_index_impls!(GenericArgs.const_generics[ConstGenericVarId]: ConstGeneric);
1464mk_index_impls!(GenericArgs.trait_refs[TraitClauseId]: TraitRef);
1465mk_index_impls!(GenericParams.regions[RegionId]: RegionParam);
1466mk_index_impls!(GenericParams.types[TypeVarId]: TypeParam);
1467mk_index_impls!(GenericParams.const_generics[ConstGenericVarId]: ConstGenericParam);
1468mk_index_impls!(GenericParams.trait_clauses[TraitClauseId]: TraitParam);