1use crate::ast::*;
3use crate::ids::IndexVec;
4use derive_generic_visitor::*;
5use index_vec::Idx;
6use itertools::Itertools;
7use std::borrow::Cow;
8use std::collections::HashSet;
9use std::convert::Infallible;
10use std::fmt::Debug;
11use std::iter::Iterator;
12use std::mem;
13
14impl TraitParam {
15 pub fn identity_tref(&self) -> TraitRef {
17 self.identity_tref_at_depth(DeBruijnId::zero())
18 }
19
20 pub fn identity_tref_at_depth(&self, depth: DeBruijnId) -> TraitRef {
22 TraitRef::new(
23 TraitRefKind::Clause(DeBruijnVar::bound(depth, self.clause_id)),
24 self.trait_.clone().move_under_binders(depth),
25 )
26 }
27}
28
29impl GenericParams {
30 pub fn empty() -> Self {
31 Self::default()
32 }
33
34 pub fn is_empty(&self) -> bool {
35 self.len() == 0
36 }
37 pub fn has_explicits(&self) -> bool {
39 !self.regions.is_empty() || !self.types.is_empty() || !self.const_generics.is_empty()
40 }
41 pub fn has_predicates(&self) -> bool {
44 !self.trait_clauses.is_empty()
45 || !self.types_outlive.is_empty()
46 || !self.regions_outlive.is_empty()
47 || !self.trait_type_constraints.is_empty()
48 }
49
50 pub fn check_consistency(&self) {
52 assert!(
54 self.trait_clauses
55 .iter()
56 .enumerate()
57 .all(|(i, c)| c.clause_id.index() == i)
58 );
59
60 let mut s = HashSet::new();
65 for r in &self.regions {
66 if let Some(name) = &r.name {
67 assert!(
68 !s.contains(name),
69 "Name \"{}\" reused for two different lifetimes",
70 name
71 );
72 s.insert(name);
73 }
74 }
75 }
76
77 pub fn len(&self) -> usize {
78 let GenericParams {
79 regions,
80 types,
81 const_generics,
82 trait_clauses,
83 regions_outlive,
84 types_outlive,
85 trait_type_constraints,
86 } = self;
87 regions.len()
88 + types.len()
89 + const_generics.len()
90 + trait_clauses.len()
91 + regions_outlive.len()
92 + types_outlive.len()
93 + trait_type_constraints.len()
94 }
95
96 pub fn identity_args(&self) -> GenericArgs {
100 self.identity_args_at_depth(DeBruijnId::zero())
101 }
102
103 pub fn identity_args_at_depth(&self, depth: DeBruijnId) -> GenericArgs {
105 GenericArgs {
106 regions: self
107 .regions
108 .map_ref_indexed(|id, _| Region::Var(DeBruijnVar::bound(depth, id))),
109 types: self
110 .types
111 .map_ref_indexed(|id, _| TyKind::TypeVar(DeBruijnVar::bound(depth, id)).into_ty()),
112 const_generics: self.const_generics.map_ref_indexed(|id, c| ConstantExpr {
113 ty: c.ty.clone(),
114 kind: ConstantExprKind::Var(DeBruijnVar::bound(depth, id)),
115 }),
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.len();
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.len();
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,
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<T: AstVisitable>(&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.len();
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.len();
275 }
276 }
277 fn enter_constant_expr(&mut self, x: &mut ConstantExpr) {
278 if let ConstantExprKind::Var(ref mut var) = x.kind
279 && let Some(id) = var.bound_at_depth_mut(self.binder_depth)
280 {
281 *id += self.shift_by.const_generics.len();
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.len();
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.len());
316 inner_params
317 .types
318 .iter_mut()
319 .for_each(|v| v.index += outer_params.types.len());
320 inner_params
321 .const_generics
322 .iter_mut()
323 .for_each(|v| v.index += outer_params.const_generics.len());
324 inner_params
325 .trait_clauses
326 .iter_mut()
327 .for_each(|v| v.clause_id += outer_params.trait_clauses.len());
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.clone_extend_from_other(regions);
339 outer_params.types.clone_extend_from_other(types);
340 outer_params
341 .const_generics
342 .clone_extend_from_other(const_generics);
343 outer_params
344 .trait_clauses
345 .clone_extend_from_other(trait_clauses);
346 outer_params
347 .regions_outlive
348 .extend_from_slice(regions_outlive);
349 outer_params.types_outlive.extend_from_slice(types_outlive);
350 outer_params
351 .trait_type_constraints
352 .clone_extend_from_other(trait_type_constraints);
353
354 Binder {
355 params: outer_params,
356 skip_binder: bound_value,
357 kind: BinderKind::Other,
358 }
359 }
360}
361
362impl<T> RegionBinder<T> {
363 pub fn empty(x: T) -> Self
365 where
366 T: TyVisitable,
367 {
368 RegionBinder {
369 regions: Default::default(),
370 skip_binder: x.move_under_binder(),
371 }
372 }
373
374 pub fn map<U>(self, f: impl FnOnce(T) -> U) -> RegionBinder<U> {
375 RegionBinder {
376 regions: self.regions,
377 skip_binder: f(self.skip_binder),
378 }
379 }
380
381 pub fn map_ref<U>(&self, f: impl FnOnce(&T) -> U) -> RegionBinder<U> {
382 RegionBinder {
383 regions: self.regions.clone(),
384 skip_binder: f(&self.skip_binder),
385 }
386 }
387
388 pub fn apply(self, regions: IndexVec<RegionId, Region>) -> T
390 where
391 T: TyVisitable,
392 {
393 assert_eq!(regions.len(), self.regions.len());
394 let args = GenericArgs {
395 regions,
396 ..GenericArgs::empty()
397 };
398 self.skip_binder.substitute_inner_binder(&args)
399 }
400
401 pub fn erase(self) -> T
403 where
404 T: TyVisitable,
405 {
406 let regions = self.regions.map_ref_indexed(|_, _| Region::Erased);
407 self.apply(regions)
408 }
409}
410
411impl GenericArgs {
412 pub fn len(&self) -> usize {
413 let GenericArgs {
414 regions,
415 types,
416 const_generics,
417 trait_refs,
418 } = self;
419 regions.len() + types.len() + const_generics.len() + trait_refs.len()
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(
444 regions: IndexVec<RegionId, Region>,
445 types: IndexVec<TypeVarId, Ty>,
446 const_generics: IndexVec<ConstGenericVarId, ConstantExpr>,
447 trait_refs: IndexVec<TraitClauseId, TraitRef>,
448 ) -> Self {
449 Self {
450 regions,
451 types,
452 const_generics,
453 trait_refs,
454 }
455 }
456 pub fn new_types(types: IndexVec<TypeVarId, Ty>) -> Self {
457 Self {
458 types,
459 ..Self::empty()
460 }
461 }
462 pub fn new_lifetimes(regions: IndexVec<RegionId, Region>) -> Self {
463 Self {
464 regions,
465 ..Self::empty()
466 }
467 }
468
469 pub fn matches(&self, params: &GenericParams) -> bool {
472 params.regions.len() == self.regions.len()
473 && params.types.len() == self.types.len()
474 && params.const_generics.len() == self.const_generics.len()
475 && params.trait_clauses.len() == self.trait_refs.len()
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.clone_extend_from_other(regions);
500 self.types.clone_extend_from_other(types);
501 self.const_generics.clone_extend_from_other(const_generics);
502 self.trait_refs.clone_extend_from_other(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_bool() -> Ty {
691 TyKind::Literal(LiteralTy::Bool).into()
692 }
693
694 pub fn mk_usize() -> Ty {
695 TyKind::Literal(LiteralTy::UInt(UIntTy::Usize)).into()
696 }
697
698 pub fn mk_tuple(tys: Vec<Ty>) -> Ty {
699 TyKind::Adt(TypeDeclRef {
700 id: TypeId::Tuple,
701 generics: Box::new(GenericArgs::new_types(tys.into())),
702 })
703 .into_ty()
704 }
705
706 pub fn mk_array(ty: Ty, len: ConstantExpr) -> Ty {
707 TyKind::Array(ty, Box::new(len)).into_ty()
708 }
709
710 pub fn mk_slice(ty: Ty) -> Ty {
711 TyKind::Slice(ty).into_ty()
712 }
713 pub fn is_unit(&self) -> bool {
715 match self.as_tuple() {
716 Some(tys) => tys.is_empty(),
717 None => false,
718 }
719 }
720
721 pub fn is_scalar(&self) -> bool {
723 match self.kind() {
724 TyKind::Literal(kind) => kind.is_int() || kind.is_uint(),
725 TyKind::Pattern(ty, _) => ty.is_scalar(),
726 _ => false,
727 }
728 }
729
730 pub fn is_unsigned_scalar(&self) -> bool {
731 match self.kind() {
732 TyKind::Literal(LiteralTy::UInt(_)) => true,
733 TyKind::Pattern(ty, _) => ty.is_unsigned_scalar(),
734 _ => false,
735 }
736 }
737
738 pub fn is_signed_scalar(&self) -> bool {
739 match self.kind() {
740 TyKind::Literal(LiteralTy::Int(_)) => true,
741 TyKind::Pattern(ty, _) => ty.is_signed_scalar(),
742 _ => false,
743 }
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_box(&self) -> bool {
755 match self.kind() {
756 TyKind::Adt(ty_ref) if let TypeId::Builtin(BuiltinTy::Box) = ty_ref.id => true,
757 _ => false,
758 }
759 }
760
761 pub fn as_box(&self) -> Option<&Ty> {
762 match self.kind() {
763 TyKind::Adt(ty_ref) if let TypeId::Builtin(BuiltinTy::Box) = ty_ref.id => {
764 Some(&ty_ref.generics.types[0])
765 }
766 _ => None,
767 }
768 }
769
770 pub fn as_adt_id(&self) -> Option<TypeDeclId> {
771 self.kind().as_adt().and_then(|a| a.id.as_adt().cloned())
772 }
773
774 pub fn get_ptr_metadata(&self, translated: &TranslatedCrate) -> PtrMetadata {
775 let ty_decls = &translated.type_decls;
776 match self.kind() {
777 TyKind::Pattern(ty, _) => ty.get_ptr_metadata(translated),
778 TyKind::Adt(ty_ref) => {
779 match ty_ref.id {
783 TypeId::Adt(type_decl_id) => {
784 let Some(decl) = ty_decls.get(type_decl_id) else {
785 return PtrMetadata::InheritFrom(self.clone());
786 };
787 match decl.ptr_metadata.clone().substitute(&ty_ref.generics) {
788 PtrMetadata::InheritFrom(ty) => ty.get_ptr_metadata(translated),
790 meta => meta,
792 }
793 }
794 TypeId::Tuple => {
796 match ty_ref.generics.types.iter().last() {
797 None => PtrMetadata::None,
799 Some(ty) => ty.get_ptr_metadata(translated),
801 }
802 }
803 TypeId::Builtin(BuiltinTy::Box) => PtrMetadata::None,
805 TypeId::Builtin(BuiltinTy::Str) => PtrMetadata::Length,
807 }
808 }
809 TyKind::DynTrait(pred) => match pred.vtable_ref(translated) {
810 Some(vtable) => PtrMetadata::VTable(vtable),
811 None => PtrMetadata::InheritFrom(self.clone()),
812 },
813 TyKind::Slice(..) => PtrMetadata::Length,
815 TyKind::TraitType(..) | TyKind::TypeVar(_) => PtrMetadata::InheritFrom(self.clone()),
816 TyKind::Literal(_)
817 | TyKind::Never
818 | TyKind::Ref(..)
819 | TyKind::RawPtr(..)
820 | TyKind::FnPtr(..)
821 | TyKind::FnDef(..)
822 | TyKind::Array(..)
823 | TyKind::Error(_) => PtrMetadata::None,
824 TyKind::PtrMetadata(_) => PtrMetadata::None,
826 }
827 }
828
829 pub fn as_ref_or_ptr(&self) -> Option<&Ty> {
830 match self.kind() {
831 TyKind::RawPtr(ty, _) | TyKind::Ref(_, ty, _) => Some(ty),
832 _ => None,
833 }
834 }
835
836 pub fn as_array_or_slice(&self) -> Option<&Ty> {
837 match self.kind() {
838 TyKind::Slice(ty) | TyKind::Array(ty, _) => Some(ty),
839 _ => None,
840 }
841 }
842
843 pub fn as_tuple(&self) -> Option<&IndexVec<TypeVarId, Ty>> {
844 match self.kind() {
845 TyKind::Adt(ty_ref) if let TypeId::Tuple = ty_ref.id => Some(&ty_ref.generics.types),
846 _ => None,
847 }
848 }
849
850 pub fn as_adt(&self) -> Option<&TypeDeclRef> {
851 self.kind().as_adt()
852 }
853}
854
855impl TyKind {
856 pub fn into_ty(self) -> Ty {
857 Ty::new(self)
858 }
859}
860
861impl From<TyKind> for Ty {
862 fn from(kind: TyKind) -> Ty {
863 kind.into_ty()
864 }
865}
866
867impl std::ops::Deref for Ty {
869 type Target = TyKind;
870
871 fn deref(&self) -> &Self::Target {
872 self.kind()
873 }
874}
875
876impl TypeDeclRef {
877 pub fn new(id: TypeId, generics: GenericArgs) -> Self {
878 Self {
879 id,
880 generics: Box::new(generics),
881 }
882 }
883}
884
885impl TraitDeclRef {
886 pub fn self_ty<'a>(&'a self, krate: &'a TranslatedCrate) -> Option<&'a Ty> {
887 match self.generics.types.iter().next() {
888 Some(ty) => Some(ty),
889 None => {
891 let name = krate.item_name(self.id);
892 let args = name.name.last()?.as_monomorphized()?;
893 args.types.iter().next()
894 }
895 }
896 }
897}
898
899impl TraitRef {
900 pub fn new(kind: TraitRefKind, trait_decl_ref: PolyTraitDeclRef) -> Self {
901 TraitRefContents {
902 kind,
903 trait_decl_ref,
904 }
905 .intern()
906 }
907
908 pub fn new_builtin(
909 trait_id: TraitDeclId,
910 ty: Ty,
911 parents: IndexVec<TraitClauseId, TraitRef>,
912 builtin_data: BuiltinImplData,
913 ) -> Self {
914 let trait_decl_ref = RegionBinder::empty(TraitDeclRef {
915 id: trait_id,
916 generics: Box::new(GenericArgs::new_types([ty].into())),
917 });
918 Self::new(
919 TraitRefKind::BuiltinOrAuto {
920 builtin_data,
921 parent_trait_refs: parents,
922 types: Default::default(),
923 },
924 trait_decl_ref,
925 )
926 }
927
928 pub fn trait_id(&self) -> TraitDeclId {
929 self.trait_decl_ref.skip_binder.id
930 }
931
932 pub fn with_contents_mut<R>(&mut self, f: impl FnOnce(&mut TraitRefContents) -> R) -> R {
935 self.0.with_inner_mut(f)
936 }
937}
938impl TraitRefContents {
939 pub fn intern(self) -> TraitRef {
940 TraitRef(HashConsed::new(self))
941 }
942}
943
944impl std::ops::Deref for TraitRef {
945 type Target = TraitRefContents;
946 fn deref(&self) -> &Self::Target {
947 &self.0
948 }
949}
950
951impl BuiltinImplData {
952 pub fn as_closure_kind(&self) -> Option<ClosureKind> {
953 match self {
954 BuiltinImplData::FnOnce => Some(ClosureKind::FnOnce),
955 BuiltinImplData::FnMut => Some(ClosureKind::FnMut),
956 BuiltinImplData::Fn => Some(ClosureKind::Fn),
957 _ => None,
958 }
959 }
960}
961
962impl PtrMetadata {
963 pub fn into_type(self) -> Ty {
964 match self {
965 PtrMetadata::None => Ty::mk_unit(),
966 PtrMetadata::Length => Ty::mk_usize(),
967 PtrMetadata::VTable(type_decl_ref) => Ty::new(TyKind::Ref(
968 Region::Static,
969 Ty::new(TyKind::Adt(type_decl_ref)),
970 RefKind::Shared,
971 )),
972 PtrMetadata::InheritFrom(ty) => Ty::new(TyKind::PtrMetadata(ty)),
973 }
974 }
975}
976
977impl Field {
978 pub fn renamed_name(&self) -> Option<&str> {
980 self.attr_info.rename.as_deref().or(self.name.as_deref())
981 }
982
983 pub fn is_opaque(&self) -> bool {
985 self.attr_info
986 .attributes
987 .iter()
988 .any(|attr| attr.is_opaque())
989 }
990}
991
992impl Variant {
993 pub fn renamed_name(&self) -> &str {
996 self.attr_info
997 .rename
998 .as_deref()
999 .unwrap_or(self.name.as_ref())
1000 }
1001
1002 pub fn is_opaque(&self) -> bool {
1004 self.attr_info
1005 .attributes
1006 .iter()
1007 .any(|attr| attr.is_opaque())
1008 }
1009}
1010
1011impl DynPredicate {
1012 pub fn vtable_ref(&self, translated: &TranslatedCrate) -> Option<TypeDeclRef> {
1014 let dyn_ty = TyKind::DynTrait(self.clone()).into_ty();
1015 let relevant_tref = self.binder.params.trait_clauses[0]
1018 .trait_
1019 .clone()
1020 .erase()
1021 .substitute(&GenericArgs::new_types([dyn_ty].into_iter().collect()));
1022
1023 let trait_decl = translated.trait_decls.get(relevant_tref.id)?;
1025 let vtable_ref = trait_decl
1026 .vtable
1027 .clone()?
1028 .substitute_with_self(&relevant_tref.generics, &TraitRefKind::Dyn);
1029 Some(vtable_ref)
1030 }
1031}
1032
1033impl RefKind {
1034 pub fn mutable(x: bool) -> Self {
1035 if x { Self::Mut } else { Self::Shared }
1036 }
1037}
1038
1039pub trait VarsVisitor {
1044 fn visit_erased_region(&mut self) -> Option<Region> {
1045 None
1046 }
1047 fn visit_region_var(&mut self, _v: RegionDbVar) -> Option<Region> {
1048 None
1049 }
1050 fn visit_type_var(&mut self, _v: TypeDbVar) -> Option<Ty> {
1051 None
1052 }
1053 fn visit_const_generic_var(&mut self, _v: ConstGenericDbVar) -> Option<ConstantExprKind> {
1054 None
1055 }
1056 fn visit_clause_var(&mut self, _v: ClauseDbVar) -> Option<TraitRefKind> {
1057 None
1058 }
1059 fn visit_self_clause(&mut self) -> Option<TraitRefKind> {
1060 None
1061 }
1062}
1063
1064#[derive(Visitor)]
1067pub(crate) struct SubstVisitor<'a> {
1068 generics: &'a GenericArgs,
1069 self_ref: Option<&'a TraitRefKind>,
1070 explicits_only: bool,
1072 had_error: bool,
1073}
1074impl<'a> SubstVisitor<'a> {
1075 pub(crate) fn new(
1076 generics: &'a GenericArgs,
1077 self_ref: Option<&'a TraitRefKind>,
1078 explicits_only: bool,
1079 ) -> Self {
1080 Self {
1081 generics,
1082 self_ref,
1083 explicits_only,
1084 had_error: false,
1085 }
1086 }
1087
1088 pub fn visit<T: TyVisitable>(mut self, mut x: T) -> Result<T, GenericsMismatch> {
1089 x.visit_vars(&mut self);
1090 if self.had_error {
1091 Err(GenericsMismatch)
1092 } else {
1093 Ok(x)
1094 }
1095 }
1096
1097 fn process_var<Id, T>(
1099 &mut self,
1100 var: DeBruijnVar<Id>,
1101 get: impl Fn(Id) -> Option<&'a T>,
1102 ) -> Option<T>
1103 where
1104 Id: Copy,
1105 T: Clone + TyVisitable,
1106 DeBruijnVar<Id>: Into<T>,
1107 {
1108 match var {
1109 DeBruijnVar::Bound(dbid, varid) => {
1110 Some(if let Some(dbid) = dbid.sub(DeBruijnId::one()) {
1111 DeBruijnVar::Bound(dbid, varid).into()
1113 } else {
1114 match get(varid) {
1115 Some(v) => v.clone(),
1116 None => {
1117 self.had_error = true;
1118 return None;
1119 }
1120 }
1121 })
1122 }
1123 DeBruijnVar::Free(..) => None,
1124 }
1125 }
1126}
1127impl VarsVisitor for SubstVisitor<'_> {
1128 fn visit_region_var(&mut self, v: RegionDbVar) -> Option<Region> {
1129 self.process_var(v, |id| self.generics.regions.get(id))
1130 }
1131 fn visit_type_var(&mut self, v: TypeDbVar) -> Option<Ty> {
1132 self.process_var(v, |id| self.generics.types.get(id))
1133 }
1134 fn visit_const_generic_var(&mut self, v: ConstGenericDbVar) -> Option<ConstantExprKind> {
1135 self.process_var(v, |id| {
1136 self.generics.const_generics.get(id).map(|c| &c.kind)
1137 })
1138 }
1139 fn visit_clause_var(&mut self, v: ClauseDbVar) -> Option<TraitRefKind> {
1140 if self.explicits_only {
1141 None
1142 } else {
1143 self.process_var(v, |id| Some(&self.generics.trait_refs.get(id)?.kind))
1144 }
1145 }
1146 fn visit_self_clause(&mut self) -> Option<TraitRefKind> {
1147 Some(self.self_ref.cloned().expect(
1148 "used `substitute` on an item coming from a trait; \
1149 use `substitute_with_self` or `substitute_inner_binder` instead.",
1150 ))
1151 }
1152}
1153
1154#[derive(Debug)]
1155pub struct GenericsMismatch;
1156
1157pub trait TyVisitable: Sized + AstVisitable {
1159 fn visit_vars(&mut self, v: &mut impl VarsVisitor) {
1163 #[derive(Visitor)]
1164 struct Wrap<'v, V> {
1165 v: &'v mut V,
1166 depth: DeBruijnId,
1167 }
1168 impl<V> VisitorWithBinderDepth for Wrap<'_, V> {
1169 fn binder_depth_mut(&mut self) -> &mut DeBruijnId {
1170 &mut self.depth
1171 }
1172 }
1173 impl<V: VarsVisitor> VisitAstMut for Wrap<'_, V> {
1174 fn visit<T: AstVisitable>(&mut self, x: &mut T) -> ControlFlow<Self::Break> {
1175 VisitWithBinderDepth::new(self).visit(x)
1176 }
1177
1178 fn exit_region(&mut self, r: &mut Region) {
1179 match r {
1180 Region::Var(var)
1181 if let Some(var) = var.move_out_from_depth(self.depth)
1182 && let Some(new_r) = self.v.visit_region_var(var) =>
1183 {
1184 *r = new_r.move_under_binders(self.depth);
1185 }
1186 Region::Erased | Region::Body(..)
1187 if let Some(new_r) = self.v.visit_erased_region() =>
1188 {
1189 *r = new_r.move_under_binders(self.depth);
1190 }
1191 _ => (),
1192 }
1193 }
1194 fn exit_ty(&mut self, ty: &mut Ty) {
1195 if let TyKind::TypeVar(var) = ty.kind()
1196 && let Some(var) = var.move_out_from_depth(self.depth)
1197 && let Some(new_ty) = self.v.visit_type_var(var)
1198 {
1199 *ty = new_ty.move_under_binders(self.depth);
1200 }
1201 }
1202 fn exit_constant_expr(&mut self, ce: &mut ConstantExpr) {
1203 if let ConstantExprKind::Var(var) = &mut ce.kind
1204 && let Some(var) = var.move_out_from_depth(self.depth)
1205 && let Some(new_cg) = self.v.visit_const_generic_var(var)
1206 {
1207 ce.kind = new_cg.move_under_binders(self.depth);
1208 }
1209 }
1210 fn exit_trait_ref_kind(&mut self, kind: &mut TraitRefKind) {
1211 match kind {
1212 TraitRefKind::SelfId => {
1213 if let Some(new_kind) = self.v.visit_self_clause() {
1214 *kind = new_kind.move_under_binders(self.depth);
1215 }
1216 }
1217 TraitRefKind::Clause(var) => {
1218 if let Some(var) = var.move_out_from_depth(self.depth)
1219 && let Some(new_kind) = self.v.visit_clause_var(var)
1220 {
1221 *kind = new_kind.move_under_binders(self.depth);
1222 }
1223 }
1224 _ => {}
1225 }
1226 }
1227 }
1228 Wrap {
1229 v,
1230 depth: DeBruijnId::zero(),
1231 }
1232 .visit(self);
1233 }
1234
1235 fn substitute(self, generics: &GenericArgs) -> Self {
1239 SubstVisitor::new(generics, None, false)
1240 .visit(self)
1241 .unwrap()
1242 }
1243 fn substitute_inner_binder(self, generics: &GenericArgs) -> Self {
1246 self.substitute_with_self(generics, &TraitRefKind::SelfId)
1247 }
1248 fn substitute_explicits(self, generics: &GenericArgs) -> Self {
1250 SubstVisitor::new(generics, None, true).visit(self).unwrap()
1251 }
1252 fn substitute_with_self(self, generics: &GenericArgs, self_ref: &TraitRefKind) -> Self {
1254 self.try_substitute_with_self(generics, self_ref).unwrap()
1255 }
1256 fn substitute_with_tref(self, tref: &TraitRef) -> Self {
1258 let pred = tref.trait_decl_ref.clone().erase();
1259 self.substitute_with_self(&pred.generics, &tref.kind)
1260 }
1261 fn try_substitute_with_tref(self, tref: &TraitRef) -> Result<Self, GenericsMismatch> {
1263 let pred = tref.trait_decl_ref.clone().erase();
1264 self.try_substitute_with_self(&pred.generics, &tref.kind)
1265 }
1266
1267 fn try_substitute(self, generics: &GenericArgs) -> Result<Self, GenericsMismatch> {
1268 SubstVisitor::new(generics, None, false).visit(self)
1269 }
1270 fn try_substitute_with_self(
1271 self,
1272 generics: &GenericArgs,
1273 self_ref: &TraitRefKind,
1274 ) -> Result<Self, GenericsMismatch> {
1275 SubstVisitor::new(generics, Some(self_ref), false).visit(self)
1276 }
1277
1278 fn move_under_binder(self) -> Self {
1280 self.move_under_binders(DeBruijnId::one())
1281 }
1282
1283 fn move_under_binders(mut self, depth: DeBruijnId) -> Self {
1285 if !depth.is_zero() {
1286 let Continue(()) = self.visit_db_id::<Infallible>(|id| {
1287 *id = id.plus(depth);
1288 Continue(())
1289 });
1290 }
1291 self
1292 }
1293
1294 fn move_from_under_binder(self) -> Option<Self> {
1296 self.move_from_under_binders(DeBruijnId::one())
1297 }
1298
1299 fn move_from_under_binders(mut self, depth: DeBruijnId) -> Option<Self> {
1302 self.visit_db_id::<()>(|id| match id.sub(depth) {
1303 Some(sub) => {
1304 *id = sub;
1305 Continue(())
1306 }
1307 None => Break(()),
1308 })
1309 .is_continue()
1310 .then_some(self)
1311 }
1312
1313 fn visit_db_id<B>(
1317 &mut self,
1318 f: impl FnMut(&mut DeBruijnId) -> ControlFlow<B>,
1319 ) -> ControlFlow<B> {
1320 struct Wrap<F> {
1321 f: F,
1322 depth: DeBruijnId,
1323 }
1324 impl<B, F> Visitor for Wrap<F>
1325 where
1326 F: FnMut(&mut DeBruijnId) -> ControlFlow<B>,
1327 {
1328 type Break = B;
1329 }
1330 impl<B, F> VisitAstMut for Wrap<F>
1331 where
1332 F: FnMut(&mut DeBruijnId) -> ControlFlow<B>,
1333 {
1334 fn enter_region_binder<T: AstVisitable>(&mut self, _: &mut RegionBinder<T>) {
1335 self.depth = self.depth.incr()
1336 }
1337 fn exit_region_binder<T: AstVisitable>(&mut self, _: &mut RegionBinder<T>) {
1338 self.depth = self.depth.decr()
1339 }
1340 fn enter_binder<T: AstVisitable>(&mut self, _: &mut Binder<T>) {
1341 self.depth = self.depth.incr()
1342 }
1343 fn exit_binder<T: AstVisitable>(&mut self, _: &mut Binder<T>) {
1344 self.depth = self.depth.decr()
1345 }
1346
1347 fn visit_de_bruijn_id(&mut self, x: &mut DeBruijnId) -> ControlFlow<Self::Break> {
1348 if let Some(mut shifted) = x.sub(self.depth) {
1349 (self.f)(&mut shifted)?;
1350 *x = shifted.plus(self.depth)
1351 }
1352 Continue(())
1353 }
1354 }
1355 self.drive_mut(&mut Wrap {
1356 f,
1357 depth: DeBruijnId::zero(),
1358 })
1359 }
1360
1361 fn replace_erased_regions(mut self, f: impl FnMut() -> Region) -> Self {
1364 #[derive(Visitor)]
1365 struct RefreshErasedRegions<F>(F);
1366 impl<F: FnMut() -> Region> VarsVisitor for RefreshErasedRegions<F> {
1367 fn visit_erased_region(&mut self) -> Option<Region> {
1368 Some((self.0)())
1369 }
1370 }
1371 self.visit_vars(&mut RefreshErasedRegions(f));
1372 self
1373 }
1374}
1375
1376#[derive(Debug, Clone)]
1379pub struct Substituted<'a, T> {
1380 pub val: &'a T,
1381 pub generics: Cow<'a, GenericArgs>,
1382 pub trait_self: Option<&'a TraitRefKind>,
1383}
1384
1385impl<'a, T> Substituted<'a, T> {
1386 pub fn new(val: &'a T, generics: &'a GenericArgs) -> Self {
1387 Self {
1388 val,
1389 generics: Cow::Borrowed(generics),
1390 trait_self: None,
1391 }
1392 }
1393 pub fn new_for_trait(
1394 val: &'a T,
1395 generics: &'a GenericArgs,
1396 trait_self: &'a TraitRefKind,
1397 ) -> Self {
1398 Self {
1399 val,
1400 generics: Cow::Borrowed(generics),
1401 trait_self: Some(trait_self),
1402 }
1403 }
1404 pub fn new_for_trait_ref(val: &'a T, tref: &'a TraitRef) -> Self {
1405 Self {
1406 val,
1407 generics: Cow::Owned(*tref.trait_decl_ref.clone().erase().generics),
1408 trait_self: Some(&tref.kind),
1409 }
1410 }
1411
1412 pub fn rebind<U>(&self, val: &'a U) -> Substituted<'a, U> {
1413 Substituted {
1414 val,
1415 generics: self.generics.clone(),
1416 trait_self: self.trait_self,
1417 }
1418 }
1419
1420 pub fn substitute(&self) -> T
1421 where
1422 T: TyVisitable + Clone,
1423 {
1424 self.try_substitute().unwrap()
1425 }
1426 pub fn try_substitute(&self) -> Result<T, GenericsMismatch>
1427 where
1428 T: TyVisitable + Clone,
1429 {
1430 match self.trait_self {
1431 None => self.val.clone().try_substitute(&self.generics),
1432 Some(trait_self) => self
1433 .val
1434 .clone()
1435 .try_substitute_with_self(&self.generics, trait_self),
1436 }
1437 }
1438
1439 pub fn iter<Item: 'a>(&self) -> impl Iterator<Item = Substituted<'a, Item>>
1440 where
1441 &'a T: IntoIterator<Item = &'a Item>,
1442 {
1443 self.val.into_iter().map(move |x| self.rebind(x))
1444 }
1445}
1446
1447impl TypeDecl {
1448 pub fn get_field(&self, variant: Option<VariantId>, field: FieldId) -> Option<&Field> {
1449 let fields = match &self.kind {
1450 TypeDeclKind::Struct(fields) | TypeDeclKind::Union(fields) => fields,
1451 TypeDeclKind::Enum(variants) => &variants[variant.unwrap()].fields,
1452 _ => return None,
1453 };
1454 fields.get(field)
1455 }
1456
1457 pub fn get_field_by_name(
1458 &self,
1459 variant: Option<VariantId>,
1460 field_name: &str,
1461 ) -> Option<(FieldId, &Field)> {
1462 let fields = match &self.kind {
1463 TypeDeclKind::Struct(fields) | TypeDeclKind::Union(fields) => fields,
1464 TypeDeclKind::Enum(variants) => &variants[variant.unwrap()].fields,
1465 _ => return None,
1466 };
1467 fields
1468 .iter_enumerated()
1469 .find(|(_, field)| field.name.as_deref() == Some(field_name))
1470 }
1471}
1472
1473#[derive(Debug, PartialEq, Eq)]
1474pub enum DiscriminantReadError {
1475 UninitByte,
1477 InvalidDiscriminant,
1479}
1480
1481impl Discriminator {
1482 pub fn trivial(variant_id: VariantId) -> Self {
1484 Self::Known(variant_id)
1485 }
1486
1487 pub fn read_discriminant(
1491 &self,
1492 read: impl Fn(ByteCount, IntegerTy) -> Result<ScalarValue, DiscriminantReadError> + Copy,
1493 ) -> Result<VariantId, DiscriminantReadError> {
1494 match self {
1495 Discriminator::Known(id) => Ok(*id),
1496 Discriminator::Invalid => Err(DiscriminantReadError::InvalidDiscriminant),
1497 Discriminator::Branch {
1498 offset,
1499 int_ty,
1500 fallback,
1501 children,
1502 } => {
1503 let val = read(*offset, *int_ty)?;
1504 for (range, child) in children {
1505 if range.contains(&val) {
1506 return child.read_discriminant(read);
1507 }
1508 }
1509 fallback.read_discriminant(read)
1510 }
1511 }
1512 }
1513}
1514
1515impl Layout {
1516 pub fn is_variant_uninhabited(&self, variant_id: VariantId) -> bool {
1517 self.variant_layouts[variant_id]
1518 .as_ref()
1519 .is_none_or(|v| v.uninhabited)
1520 }
1521
1522 pub fn is_c_repr(&self) -> bool {
1523 self.repr.repr_algo == ReprAlgorithm::C
1524 }
1525}
1526
1527impl ReprOptions {
1528 pub fn guarantees_fixed_field_order(&self) -> bool {
1538 self.repr_algo == ReprAlgorithm::C || self.explicit_discr_type
1539 }
1540}
1541
1542impl<T: AstVisitable> TyVisitable for T {}
1543
1544impl Eq for TraitParam {}
1545
1546pub trait HasIdxVecOf<Id: Idx>: std::ops::Index<Id, Output: Sized> {
1547 fn get_idx_vec(&self) -> &IndexVec<Id, Self::Output>;
1548 fn get_idx_vec_mut(&mut self) -> &mut IndexVec<Id, Self::Output>;
1549}
1550
1551macro_rules! mk_index_impls {
1553 ($ty:ident.$field:ident[$idx:ty]: $output:ty) => {
1554 impl std::ops::Index<$idx> for $ty {
1555 type Output = $output;
1556 fn index(&self, index: $idx) -> &Self::Output {
1557 &self.$field[index]
1558 }
1559 }
1560 impl std::ops::IndexMut<$idx> for $ty {
1561 fn index_mut(&mut self, index: $idx) -> &mut Self::Output {
1562 &mut self.$field[index]
1563 }
1564 }
1565 impl HasIdxVecOf<$idx> for $ty {
1566 fn get_idx_vec(&self) -> &IndexVec<$idx, Self::Output> {
1567 &self.$field
1568 }
1569 fn get_idx_vec_mut(&mut self) -> &mut IndexVec<$idx, Self::Output> {
1570 &mut self.$field
1571 }
1572 }
1573 };
1574}
1575mk_index_impls!(GenericArgs.regions[RegionId]: Region);
1576mk_index_impls!(GenericArgs.types[TypeVarId]: Ty);
1577mk_index_impls!(GenericArgs.const_generics[ConstGenericVarId]: ConstantExpr);
1578mk_index_impls!(GenericArgs.trait_refs[TraitClauseId]: TraitRef);
1579mk_index_impls!(GenericParams.regions[RegionId]: RegionParam);
1580mk_index_impls!(GenericParams.types[TypeVarId]: TypeParam);
1581mk_index_impls!(GenericParams.const_generics[ConstGenericVarId]: ConstGenericParam);
1582mk_index_impls!(GenericParams.trait_clauses[TraitClauseId]: TraitParam);