1use crate::ast::*;
3use crate::ids::Vector;
4use derive_generic_visitor::*;
5use std::collections::HashSet;
6use std::convert::Infallible;
7use std::fmt::Debug;
8use std::iter::Iterator;
9use std::mem;
10
11impl TraitClause {
12 pub fn identity_tref(&self) -> TraitRef {
14 self.identity_tref_at_depth(DeBruijnId::zero())
15 }
16
17 pub fn identity_tref_at_depth(&self, depth: DeBruijnId) -> TraitRef {
19 TraitRef {
20 kind: TraitRefKind::Clause(DeBruijnVar::bound(depth, self.clause_id)),
21 trait_decl_ref: self.trait_.clone().move_under_binders(depth),
22 }
23 }
24}
25
26impl GenericParams {
27 pub fn empty() -> Self {
28 Self::default()
29 }
30
31 pub fn is_empty(&self) -> bool {
32 self.len() == 0
33 }
34 pub fn has_explicits(&self) -> bool {
36 !self.regions.is_empty() || !self.types.is_empty() || !self.const_generics.is_empty()
37 }
38 pub fn has_predicates(&self) -> bool {
41 !self.trait_clauses.is_empty()
42 || !self.types_outlive.is_empty()
43 || !self.regions_outlive.is_empty()
44 || !self.trait_type_constraints.is_empty()
45 }
46
47 pub fn check_consistency(&self) {
49 assert!(
51 self.trait_clauses
52 .iter()
53 .enumerate()
54 .all(|(i, c)| c.clause_id.index() == i)
55 );
56
57 let mut s = HashSet::new();
62 for r in &self.regions {
63 if let Some(name) = &r.name {
64 assert!(
65 !s.contains(name),
66 "Name \"{}\" reused for two different lifetimes",
67 name
68 );
69 s.insert(name);
70 }
71 }
72 }
73
74 pub fn len(&self) -> usize {
75 let GenericParams {
76 regions,
77 types,
78 const_generics,
79 trait_clauses,
80 regions_outlive,
81 types_outlive,
82 trait_type_constraints,
83 } = self;
84 regions.elem_count()
85 + types.elem_count()
86 + const_generics.elem_count()
87 + trait_clauses.elem_count()
88 + regions_outlive.len()
89 + types_outlive.len()
90 + trait_type_constraints.elem_count()
91 }
92
93 pub fn identity_args(&self) -> GenericArgs {
97 self.identity_args_at_depth(DeBruijnId::zero())
98 }
99
100 pub fn identity_args_at_depth(&self, depth: DeBruijnId) -> GenericArgs {
102 GenericArgs {
103 regions: self
104 .regions
105 .map_ref_indexed(|id, _| Region::Var(DeBruijnVar::bound(depth, id))),
106 types: self
107 .types
108 .map_ref_indexed(|id, _| TyKind::TypeVar(DeBruijnVar::bound(depth, id)).into_ty()),
109 const_generics: self
110 .const_generics
111 .map_ref_indexed(|id, _| ConstGeneric::Var(DeBruijnVar::bound(depth, id))),
112 trait_refs: self
113 .trait_clauses
114 .map_ref(|clause| clause.identity_tref_at_depth(depth)),
115 }
116 }
117}
118
119impl<T> Binder<T> {
120 pub fn new(kind: BinderKind, params: GenericParams, skip_binder: T) -> Self {
121 Self {
122 params,
123 skip_binder,
124 kind,
125 }
126 }
127
128 pub fn apply(self, args: &GenericArgs) -> T
131 where
132 T: TyVisitable,
133 {
134 self.skip_binder.substitute(args)
135 }
136}
137
138impl<T: AstVisitable> Binder<Binder<T>> {
139 pub fn flatten(self) -> Binder<T> {
141 #[derive(Visitor)]
142 struct FlattenVisitor<'a> {
143 shift_by: &'a GenericParams,
144 binder_depth: DeBruijnId,
145 }
146 impl VisitAstMut for FlattenVisitor<'_> {
147 fn enter_region_binder<T: AstVisitable>(&mut self, _: &mut RegionBinder<T>) {
148 self.binder_depth = self.binder_depth.incr()
149 }
150 fn exit_region_binder<T: AstVisitable>(&mut self, _: &mut RegionBinder<T>) {
151 self.binder_depth = self.binder_depth.decr()
152 }
153 fn enter_binder<T: AstVisitable>(&mut self, _: &mut Binder<T>) {
154 self.binder_depth = self.binder_depth.incr()
155 }
156 fn exit_binder<T: AstVisitable>(&mut self, _: &mut Binder<T>) {
157 self.binder_depth = self.binder_depth.decr()
158 }
159 fn enter_de_bruijn_id(&mut self, db_id: &mut DeBruijnId) {
160 if *db_id > self.binder_depth {
161 *db_id = db_id.decr();
166 }
167 }
168 fn enter_region(&mut self, x: &mut Region) {
169 if let Region::Var(var) = x
170 && let Some(id) = var.bound_at_depth_mut(self.binder_depth)
171 {
172 *id += self.shift_by.regions.slot_count();
173 }
174 }
175 fn enter_ty_kind(&mut self, x: &mut TyKind) {
176 if let TyKind::TypeVar(var) = x
177 && let Some(id) = var.bound_at_depth_mut(self.binder_depth)
178 {
179 *id += self.shift_by.types.slot_count();
180 }
181 }
182 fn enter_const_generic(&mut self, x: &mut ConstGeneric) {
183 if let ConstGeneric::Var(var) = x
184 && let Some(id) = var.bound_at_depth_mut(self.binder_depth)
185 {
186 *id += self.shift_by.const_generics.slot_count();
187 }
188 }
189 fn enter_trait_ref_kind(&mut self, x: &mut TraitRefKind) {
190 if let TraitRefKind::Clause(var) = x
191 && let Some(id) = var.bound_at_depth_mut(self.binder_depth)
192 {
193 *id += self.shift_by.trait_clauses.slot_count();
194 }
195 }
196 }
197
198 let mut outer_params = self.params;
200
201 let mut bound_value = self.skip_binder.skip_binder;
205 let _ = bound_value.drive_mut(&mut FlattenVisitor {
206 shift_by: &outer_params,
207 binder_depth: Default::default(),
208 });
209
210 let mut inner_params = self.skip_binder.params;
213 let _ = inner_params.drive_mut(&mut FlattenVisitor {
214 shift_by: &outer_params,
215 binder_depth: Default::default(),
216 });
217 inner_params
218 .regions
219 .iter_mut()
220 .for_each(|v| v.index += outer_params.regions.slot_count());
221 inner_params
222 .types
223 .iter_mut()
224 .for_each(|v| v.index += outer_params.types.slot_count());
225 inner_params
226 .const_generics
227 .iter_mut()
228 .for_each(|v| v.index += outer_params.const_generics.slot_count());
229 inner_params
230 .trait_clauses
231 .iter_mut()
232 .for_each(|v| v.clause_id += outer_params.trait_clauses.slot_count());
233
234 let GenericParams {
235 regions,
236 types,
237 const_generics,
238 trait_clauses,
239 regions_outlive,
240 types_outlive,
241 trait_type_constraints,
242 } = &inner_params;
243 outer_params.regions.extend_from_slice(regions);
244 outer_params.types.extend_from_slice(types);
245 outer_params
246 .const_generics
247 .extend_from_slice(const_generics);
248 outer_params.trait_clauses.extend_from_slice(trait_clauses);
249 outer_params
250 .regions_outlive
251 .extend_from_slice(regions_outlive);
252 outer_params.types_outlive.extend_from_slice(types_outlive);
253 outer_params
254 .trait_type_constraints
255 .extend_from_slice(trait_type_constraints);
256
257 Binder {
258 params: outer_params,
259 skip_binder: bound_value,
260 kind: BinderKind::Other,
261 }
262 }
263}
264
265impl<T> RegionBinder<T> {
266 pub fn empty(x: T) -> Self
268 where
269 T: TyVisitable,
270 {
271 RegionBinder {
272 regions: Default::default(),
273 skip_binder: x.move_under_binder(),
274 }
275 }
276
277 pub fn map<U>(self, f: impl FnOnce(T) -> U) -> RegionBinder<U> {
278 RegionBinder {
279 regions: self.regions,
280 skip_binder: f(self.skip_binder),
281 }
282 }
283
284 pub fn map_ref<U>(&self, f: impl FnOnce(&T) -> U) -> RegionBinder<U> {
285 RegionBinder {
286 regions: self.regions.clone(),
287 skip_binder: f(&self.skip_binder),
288 }
289 }
290
291 pub fn apply(self, regions: Vector<RegionId, Region>) -> T
293 where
294 T: AstVisitable,
295 {
296 assert_eq!(regions.slot_count(), self.regions.slot_count());
297 let args = GenericArgs {
298 regions,
299 ..GenericArgs::empty()
300 };
301 self.skip_binder.substitute(&args)
302 }
303
304 pub fn erase(self) -> T
306 where
307 T: AstVisitable,
308 {
309 let regions = self.regions.map_ref_indexed(|_, _| Region::Erased);
310 self.apply(regions)
311 }
312}
313
314impl GenericArgs {
315 pub fn len(&self) -> usize {
316 let GenericArgs {
317 regions,
318 types,
319 const_generics,
320 trait_refs,
321 } = self;
322 regions.elem_count()
323 + types.elem_count()
324 + const_generics.elem_count()
325 + trait_refs.elem_count()
326 }
327
328 pub fn is_empty(&self) -> bool {
329 self.len() == 0
330 }
331 pub fn has_explicits(&self) -> bool {
333 !self.regions.is_empty() || !self.types.is_empty() || !self.const_generics.is_empty()
334 }
335 pub fn has_implicits(&self) -> bool {
337 !self.trait_refs.is_empty()
338 }
339
340 pub fn empty() -> Self {
341 GenericArgs {
342 regions: Default::default(),
343 types: Default::default(),
344 const_generics: Default::default(),
345 trait_refs: Default::default(),
346 }
347 }
348
349 pub fn new_for_builtin(types: Vector<TypeVarId, Ty>) -> Self {
350 GenericArgs {
351 types,
352 ..Self::empty()
353 }
354 }
355
356 pub fn new(
357 regions: Vector<RegionId, Region>,
358 types: Vector<TypeVarId, Ty>,
359 const_generics: Vector<ConstGenericVarId, ConstGeneric>,
360 trait_refs: Vector<TraitClauseId, TraitRef>,
361 ) -> Self {
362 Self {
363 regions,
364 types,
365 const_generics,
366 trait_refs,
367 }
368 }
369
370 pub fn new_types(types: Vector<TypeVarId, Ty>) -> Self {
371 Self {
372 types,
373 ..Self::empty()
374 }
375 }
376
377 pub fn matches(&self, params: &GenericParams) -> bool {
380 params.regions.elem_count() == self.regions.elem_count()
381 && params.types.elem_count() == self.types.elem_count()
382 && params.const_generics.elem_count() == self.const_generics.elem_count()
383 && params.trait_clauses.elem_count() == self.trait_refs.elem_count()
384 }
385
386 pub fn pop_first_type_arg(&self) -> (Ty, Self) {
391 let mut generics = self.clone();
392 let mut it = mem::take(&mut generics.types).into_iter();
393 let ty = it.next().unwrap();
394 generics.types = it.collect();
395 (ty, generics)
396 }
397
398 pub fn concat(mut self, other: &Self) -> Self {
401 let Self {
402 regions,
403 types,
404 const_generics,
405 trait_refs,
406 } = other;
407 self.regions.extend_from_slice(regions);
408 self.types.extend_from_slice(types);
409 self.const_generics.extend_from_slice(const_generics);
410 self.trait_refs.extend_from_slice(trait_refs);
411 self
412 }
413}
414
415impl IntegerTy {
416 pub fn is_signed(&self) -> bool {
417 matches!(
418 self,
419 IntegerTy::Isize
420 | IntegerTy::I8
421 | IntegerTy::I16
422 | IntegerTy::I32
423 | IntegerTy::I64
424 | IntegerTy::I128
425 )
426 }
427
428 pub fn is_unsigned(&self) -> bool {
429 !(self.is_signed())
430 }
431
432 pub fn to_unsigned(&self) -> Self {
433 match self {
434 IntegerTy::Isize => IntegerTy::Usize,
435 IntegerTy::I8 => IntegerTy::U8,
436 IntegerTy::I16 => IntegerTy::U16,
437 IntegerTy::I32 => IntegerTy::U32,
438 IntegerTy::I64 => IntegerTy::U64,
439 IntegerTy::I128 => IntegerTy::U128,
440 _ => *self,
441 }
442 }
443}
444
445#[derive(Debug, Clone, Copy)]
451pub struct ItemBinder<ItemId, T> {
452 pub item_id: ItemId,
453 val: T,
454}
455
456impl<ItemId, T> ItemBinder<ItemId, T>
457where
458 ItemId: Debug + Copy + PartialEq,
459{
460 pub fn new(item_id: ItemId, val: T) -> Self {
461 Self { item_id, val }
462 }
463
464 pub fn as_ref(&self) -> ItemBinder<ItemId, &T> {
465 ItemBinder {
466 item_id: self.item_id,
467 val: &self.val,
468 }
469 }
470
471 pub fn map_bound<U>(self, f: impl FnOnce(T) -> U) -> ItemBinder<ItemId, U> {
472 ItemBinder {
473 item_id: self.item_id,
474 val: f(self.val),
475 }
476 }
477
478 fn assert_item_id(&self, item_id: ItemId) {
479 assert_eq!(
480 self.item_id, item_id,
481 "Trying to use item bound for {:?} as if it belonged to {:?}",
482 self.item_id, item_id
483 );
484 }
485
486 pub fn under_binder_of(self, item_id: ItemId) -> T {
489 self.assert_item_id(item_id);
490 self.val
491 }
492
493 pub fn substitute<OtherItem: Debug + Copy + PartialEq>(
497 self,
498 args: ItemBinder<OtherItem, &GenericArgs>,
499 ) -> ItemBinder<OtherItem, T>
500 where
501 ItemId: Into<AnyTransId>,
502 T: TyVisitable,
503 {
504 args.map_bound(|args| self.val.substitute(args))
505 }
506}
507
508#[derive(Debug, Clone, Copy, PartialEq, Eq)]
510pub struct CurrentItem;
511
512impl<T> ItemBinder<CurrentItem, T> {
513 pub fn under_current_binder(self) -> T {
514 self.val
515 }
516}
517
518impl Ty {
519 pub fn mk_unit() -> Ty {
521 Self::mk_tuple(vec![])
522 }
523
524 pub fn mk_tuple(tys: Vec<Ty>) -> Ty {
525 TyKind::Adt(TypeDeclRef {
526 id: TypeId::Tuple,
527 generics: Box::new(GenericArgs::new_for_builtin(tys.into())),
528 })
529 .into_ty()
530 }
531
532 pub fn mk_slice(ty: Ty) -> Ty {
533 TyKind::Adt(TypeDeclRef {
534 id: TypeId::Builtin(BuiltinTy::Slice),
535 generics: Box::new(GenericArgs::new_for_builtin(vec![ty].into())),
536 })
537 .into_ty()
538 }
539 pub fn is_unit(&self) -> bool {
541 match self.as_tuple() {
542 Some(tys) => tys.is_empty(),
543 None => false,
544 }
545 }
546
547 pub fn is_scalar(&self) -> bool {
549 match self.kind() {
550 TyKind::Literal(kind) => kind.is_integer(),
551 _ => false,
552 }
553 }
554
555 pub fn is_unsigned_scalar(&self) -> bool {
556 match self.kind() {
557 TyKind::Literal(LiteralTy::Integer(kind)) => kind.is_unsigned(),
558 _ => false,
559 }
560 }
561
562 pub fn is_signed_scalar(&self) -> bool {
563 match self.kind() {
564 TyKind::Literal(LiteralTy::Integer(kind)) => kind.is_signed(),
565 _ => false,
566 }
567 }
568
569 pub fn is_box(&self) -> bool {
571 match self.kind() {
572 TyKind::Adt(ty_ref) if let TypeId::Builtin(BuiltinTy::Box) = ty_ref.id => true,
573 _ => false,
574 }
575 }
576
577 pub fn as_box(&self) -> Option<&Ty> {
578 match self.kind() {
579 TyKind::Adt(ty_ref) if let TypeId::Builtin(BuiltinTy::Box) = ty_ref.id => {
580 Some(&ty_ref.generics.types[0])
581 }
582 _ => None,
583 }
584 }
585
586 pub fn as_array_or_slice(&self) -> Option<&Ty> {
587 match self.kind() {
588 TyKind::Adt(ty_ref)
589 if let TypeId::Builtin(BuiltinTy::Array | BuiltinTy::Slice) = ty_ref.id =>
590 {
591 Some(&ty_ref.generics.types[0])
592 }
593 _ => None,
594 }
595 }
596
597 pub fn as_tuple(&self) -> Option<&Vector<TypeVarId, Ty>> {
598 match self.kind() {
599 TyKind::Adt(ty_ref) if let TypeId::Tuple = ty_ref.id => Some(&ty_ref.generics.types),
600 _ => None,
601 }
602 }
603
604 pub fn as_adt(&self) -> Option<&TypeDeclRef> {
605 self.kind().as_adt()
606 }
607}
608
609impl TyKind {
610 pub fn into_ty(self) -> Ty {
611 Ty::new(self)
612 }
613}
614
615impl From<TyKind> for Ty {
616 fn from(kind: TyKind) -> Ty {
617 kind.into_ty()
618 }
619}
620
621impl std::ops::Deref for Ty {
623 type Target = TyKind;
624
625 fn deref(&self) -> &Self::Target {
626 self.kind()
627 }
628}
629unsafe impl std::ops::DerefPure for Ty {}
631
632impl TypeDeclRef {
633 pub fn new(id: TypeId, generics: GenericArgs) -> Self {
634 Self {
635 id,
636 generics: Box::new(generics),
637 }
638 }
639}
640
641impl TraitRef {
642 pub fn new_builtin(
643 trait_id: TraitDeclId,
644 ty: Ty,
645 parents: Vector<TraitClauseId, TraitRef>,
646 ) -> Self {
647 let trait_decl_ref = RegionBinder::empty(TraitDeclRef {
648 id: trait_id,
649 generics: Box::new(GenericArgs::new_types([ty].into())),
650 });
651 TraitRef {
652 kind: TraitRefKind::BuiltinOrAuto {
653 trait_decl_ref: trait_decl_ref.clone(),
654 parent_trait_refs: parents,
655 types: Default::default(),
656 },
657 trait_decl_ref,
658 }
659 }
660}
661
662impl Field {
663 pub fn renamed_name(&self) -> Option<&str> {
665 self.attr_info.rename.as_deref().or(self.name.as_deref())
666 }
667
668 pub fn is_opaque(&self) -> bool {
670 self.attr_info
671 .attributes
672 .iter()
673 .any(|attr| attr.is_opaque())
674 }
675}
676
677impl Variant {
678 pub fn renamed_name(&self) -> &str {
681 self.attr_info
682 .rename
683 .as_deref()
684 .unwrap_or(self.name.as_ref())
685 }
686
687 pub fn is_opaque(&self) -> bool {
689 self.attr_info
690 .attributes
691 .iter()
692 .any(|attr| attr.is_opaque())
693 }
694}
695
696impl RefKind {
697 pub fn mutable(x: bool) -> Self {
698 if x { Self::Mut } else { Self::Shared }
699 }
700}
701
702pub trait VarsVisitor {
707 fn visit_region_var(&mut self, _v: RegionDbVar) -> Option<Region> {
708 None
709 }
710 fn visit_type_var(&mut self, _v: TypeDbVar) -> Option<Ty> {
711 None
712 }
713 fn visit_const_generic_var(&mut self, _v: ConstGenericDbVar) -> Option<ConstGeneric> {
714 None
715 }
716 fn visit_clause_var(&mut self, _v: ClauseDbVar) -> Option<TraitRefKind> {
717 None
718 }
719 fn visit_self_clause(&mut self) -> Option<TraitRefKind> {
720 None
721 }
722}
723
724#[derive(Visitor)]
727pub(crate) struct SubstVisitor<'a> {
728 generics: &'a GenericArgs,
729 self_ref: &'a TraitRefKind,
730}
731impl<'a> SubstVisitor<'a> {
732 pub(crate) fn new(generics: &'a GenericArgs, self_ref: &'a TraitRefKind) -> Self {
733 Self { generics, self_ref }
734 }
735
736 fn process_var<Id, T>(&self, var: DeBruijnVar<Id>, get: impl Fn(Id) -> &'a T) -> Option<T>
738 where
739 Id: Copy,
740 T: Clone + TyVisitable,
741 DeBruijnVar<Id>: Into<T>,
742 {
743 match var {
744 DeBruijnVar::Bound(dbid, varid) => {
745 Some(if let Some(dbid) = dbid.sub(DeBruijnId::one()) {
746 DeBruijnVar::Bound(dbid, varid).into()
748 } else {
749 get(varid).clone()
750 })
751 }
752 DeBruijnVar::Free(..) => None,
753 }
754 }
755}
756impl VarsVisitor for SubstVisitor<'_> {
757 fn visit_region_var(&mut self, v: RegionDbVar) -> Option<Region> {
758 self.process_var(v, |id| &self.generics[id])
759 }
760 fn visit_type_var(&mut self, v: TypeDbVar) -> Option<Ty> {
761 self.process_var(v, |id| &self.generics[id])
762 }
763 fn visit_const_generic_var(&mut self, v: ConstGenericDbVar) -> Option<ConstGeneric> {
764 self.process_var(v, |id| &self.generics[id])
765 }
766 fn visit_clause_var(&mut self, v: ClauseDbVar) -> Option<TraitRefKind> {
767 self.process_var(v, |id| &self.generics[id].kind)
768 }
769 fn visit_self_clause(&mut self) -> Option<TraitRefKind> {
770 Some(self.self_ref.clone())
771 }
772}
773
774pub trait TyVisitable: Sized + AstVisitable {
776 fn visit_vars(&mut self, v: &mut impl VarsVisitor) {
780 #[derive(Visitor)]
781 struct Wrap<'v, V> {
782 v: &'v mut V,
783 depth: DeBruijnId,
784 }
785 impl<V: VarsVisitor> VisitAstMut for Wrap<'_, V> {
786 fn enter_region_binder<T: AstVisitable>(&mut self, _: &mut RegionBinder<T>) {
787 self.depth = self.depth.incr()
788 }
789 fn exit_region_binder<T: AstVisitable>(&mut self, _: &mut RegionBinder<T>) {
790 self.depth = self.depth.decr()
791 }
792 fn enter_binder<T: AstVisitable>(&mut self, _: &mut Binder<T>) {
793 self.depth = self.depth.incr()
794 }
795 fn exit_binder<T: AstVisitable>(&mut self, _: &mut Binder<T>) {
796 self.depth = self.depth.decr()
797 }
798
799 fn exit_region(&mut self, r: &mut Region) {
800 if let Region::Var(var) = r
801 && let Some(var) = var.move_out_from_depth(self.depth)
802 && let Some(new_r) = self.v.visit_region_var(var)
803 {
804 *r = new_r.move_under_binders(self.depth);
805 }
806 }
807 fn exit_ty(&mut self, ty: &mut Ty) {
808 if let TyKind::TypeVar(var) = ty.kind()
809 && let Some(var) = var.move_out_from_depth(self.depth)
810 && let Some(new_ty) = self.v.visit_type_var(var)
811 {
812 *ty = new_ty.move_under_binders(self.depth);
813 }
814 }
815 fn exit_const_generic(&mut self, cg: &mut ConstGeneric) {
816 if let ConstGeneric::Var(var) = cg
817 && let Some(var) = var.move_out_from_depth(self.depth)
818 && let Some(new_cg) = self.v.visit_const_generic_var(var)
819 {
820 *cg = new_cg.move_under_binders(self.depth);
821 }
822 }
823 fn exit_constant_expr(&mut self, ce: &mut ConstantExpr) {
824 if let RawConstantExpr::Var(var) = &mut ce.value
825 && let Some(var) = var.move_out_from_depth(self.depth)
826 && let Some(new_cg) = self.v.visit_const_generic_var(var)
827 {
828 ce.value = new_cg.move_under_binders(self.depth).into();
829 }
830 }
831 fn exit_trait_ref_kind(&mut self, kind: &mut TraitRefKind) {
832 match kind {
833 TraitRefKind::SelfId => {
834 if let Some(new_kind) = self.v.visit_self_clause() {
835 *kind = new_kind.move_under_binders(self.depth);
836 }
837 }
838 TraitRefKind::Clause(var) => {
839 if let Some(var) = var.move_out_from_depth(self.depth)
840 && let Some(new_kind) = self.v.visit_clause_var(var)
841 {
842 *kind = new_kind.move_under_binders(self.depth);
843 }
844 }
845 _ => {}
846 }
847 }
848 }
849 let _ = self.drive_mut(&mut Wrap {
850 v,
851 depth: DeBruijnId::zero(),
852 });
853 }
854
855 fn substitute(self, generics: &GenericArgs) -> Self {
856 self.substitute_with_self(generics, &TraitRefKind::SelfId)
857 }
858
859 fn substitute_with_self(mut self, generics: &GenericArgs, self_ref: &TraitRefKind) -> Self {
860 let _ = self.visit_vars(&mut SubstVisitor::new(generics, self_ref));
861 self
862 }
863
864 fn move_under_binder(self) -> Self {
866 self.move_under_binders(DeBruijnId::one())
867 }
868
869 fn move_under_binders(mut self, depth: DeBruijnId) -> Self {
871 if !depth.is_zero() {
872 let Continue(()) = self.visit_db_id::<Infallible>(|id| {
873 *id = id.plus(depth);
874 Continue(())
875 });
876 }
877 self
878 }
879
880 fn move_from_under_binder(self) -> Option<Self> {
882 self.move_from_under_binders(DeBruijnId::one())
883 }
884
885 fn move_from_under_binders(mut self, depth: DeBruijnId) -> Option<Self> {
888 self.visit_db_id::<()>(|id| match id.sub(depth) {
889 Some(sub) => {
890 *id = sub;
891 Continue(())
892 }
893 None => Break(()),
894 })
895 .is_continue()
896 .then_some(self)
897 }
898
899 fn visit_db_id<B>(
903 &mut self,
904 f: impl FnMut(&mut DeBruijnId) -> ControlFlow<B>,
905 ) -> ControlFlow<B> {
906 struct Wrap<F> {
907 f: F,
908 depth: DeBruijnId,
909 }
910 impl<B, F> Visitor for Wrap<F>
911 where
912 F: FnMut(&mut DeBruijnId) -> ControlFlow<B>,
913 {
914 type Break = B;
915 }
916 impl<B, F> VisitAstMut for Wrap<F>
917 where
918 F: FnMut(&mut DeBruijnId) -> ControlFlow<B>,
919 {
920 fn enter_region_binder<T: AstVisitable>(&mut self, _: &mut RegionBinder<T>) {
921 self.depth = self.depth.incr()
922 }
923 fn exit_region_binder<T: AstVisitable>(&mut self, _: &mut RegionBinder<T>) {
924 self.depth = self.depth.decr()
925 }
926 fn enter_binder<T: AstVisitable>(&mut self, _: &mut Binder<T>) {
927 self.depth = self.depth.incr()
928 }
929 fn exit_binder<T: AstVisitable>(&mut self, _: &mut Binder<T>) {
930 self.depth = self.depth.decr()
931 }
932
933 fn visit_de_bruijn_id(&mut self, x: &mut DeBruijnId) -> ControlFlow<Self::Break> {
934 if let Some(mut shifted) = x.sub(self.depth) {
935 (self.f)(&mut shifted)?;
936 *x = shifted.plus(self.depth)
937 }
938 Continue(())
939 }
940 }
941 self.drive_mut(&mut Wrap {
942 f,
943 depth: DeBruijnId::zero(),
944 })
945 }
946}
947
948impl TypeDecl {
949 pub fn get_variant_from_tag(&self, tag: ScalarValue) -> Option<VariantId> {
955 let layout = self.layout.as_ref()?;
956 if layout.uninhabited {
957 return None;
958 };
959 let discr_layout = layout.discriminant_layout.as_ref()?;
960
961 let variant_for_tag =
962 layout
963 .variant_layouts
964 .iter_indexed()
965 .find_map(|(id, variant_layout)| {
966 if variant_layout.tag == Some(tag) {
967 Some(id)
968 } else {
969 None
970 }
971 });
972
973 match &discr_layout.encoding {
974 TagEncoding::Direct => {
975 assert_eq!(tag.get_integer_ty(), discr_layout.tag_ty);
976 variant_for_tag
977 }
978 TagEncoding::Niche { untagged_variant } => variant_for_tag.or(Some(*untagged_variant)),
979 }
980 }
981}
982
983impl Layout {
984 pub fn is_variant_uninhabited(&self, variant_id: VariantId) -> bool {
985 if let Some(v) = self.variant_layouts.get(variant_id) {
986 v.uninhabited
987 } else {
988 false
989 }
990 }
991}
992
993impl<T: AstVisitable> TyVisitable for T {}
994
995impl Eq for TraitClause {}
996
997mk_index_impls!(GenericArgs.regions[RegionId]: Region);
998mk_index_impls!(GenericArgs.types[TypeVarId]: Ty);
999mk_index_impls!(GenericArgs.const_generics[ConstGenericVarId]: ConstGeneric);
1000mk_index_impls!(GenericArgs.trait_refs[TraitClauseId]: TraitRef);
1001mk_index_impls!(GenericParams.regions[RegionId]: RegionVar);
1002mk_index_impls!(GenericParams.types[TypeVarId]: TypeVar);
1003mk_index_impls!(GenericParams.const_generics[ConstGenericVarId]: ConstGenericVar);
1004mk_index_impls!(GenericParams.trait_clauses[TraitClauseId]: TraitClause);