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