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