1use std::mem;
14use std::path::PathBuf;
15use std::{any::Any, hash::Hash};
16
17use crate::ast::from_rustc;
18use crate::ast::from_rustc::{
19 AttributeKind, DeprecatedSince, Deprecation, Ident, LangItem, OptimizeAttr,
20};
21use crate::ast::*;
22use crate::ids::{Idx, IndexVec};
23use derive_generic_visitor::*;
24
25#[visitable_group(
44 visitor(drive(&VisitAst)),
46 visitor(drive_mut(&mut VisitAstMut)),
47 visitor(drive_two(&two ZipAst)),
48 skip_but_eq(
50 (),
51 Abi,
52 AsmKind,
53 AsmOperandId,
54 AsmOptions,
55 AsmRegister,
56 BranchId,
57 BuiltinImplData,
58 BuiltinPathElem,
59 CallSafety,
60 DeprecatedSince,
61 DropKind,
62 Error,
63 FieldPredecessor,
64 FileName,
65 GlobalKind,
66 ItemOpacity,
67 LangItem,
68 LifetimeMutability,
69 OptimizeAttr,
70 OverflowMode,
71 PathBuf,
72 ReprOptions,
73 RuntimeChecks,
74 String,
75 Variance,
76 WithRetag,
77 bool,
78 char,
79 crate::options::CliOpts,
80 from_rustc::Linkage,
81 i128,
82 std::ops::RangeInclusive<IntegerValue>,
83 u128,
84 u32,
85 u64,
86 u8,
87 ullbc_ast::UnwindKind,
88 usize,
89 ustr::Ustr,
90 ),
91 skip(
93 DeclarationGroup,
94 ImplementsMarkerTraits,
95 PredicateOrigin,
96 TargetInfo,
97 TypeInfo,
98 llbc_ast::BlockId,
99 llbc_ast::StatementId,
100 ),
101 drive(
103 AsmOperand,
104 AsmTemplatePiece,
105 Assert,
106 AssocConstId,
107 AssocItemId,
108 AssocItemNames,
109 AssocTypeId,
110 AttributeKind,
111 BinOp,
112 BinderKind,
113 BorrowKind,
114 BorrowckStatement,
115 BuiltinAdt,
116 BuiltinAssertKind,
117 Byte,
118 Call,
119 CastKind,
120 ClosureInfo,
121 ClosureKind,
122 ConstGenericParam,
123 ConstGenericVarId,
124 ConstProjectionElem,
125 Deprecation,
126 Disambiguator,
127 Discriminator,
128 DynPredicate,
129 Field,
130 FieldId,
131 File,
132 FloatTy,
133 FloatValue,
134 FnOperand,
135 FnPtrKind,
136 GlobalPlaceKind,
137 GlobalProvenance,
138 Ident,
139 InlineAsm,
140 InlineAttr,
141 IntTy,
142 IntegerTy,
143 IntegerValue,
144 ItemByVal,
145 ItemId,
146 Loc,
147 Local,
148 LocalId,
149 Locals,
150 MaybeAssocItemId,
151 NullOp,
152 OffsetExpr,
153 OffsetGuarantee,
154 Operand,
155 PathElem,
156 PlaceKind,
157 PtrMetadata,
158 RawAttribute,
159 RefKind,
160 RegionArgs,
161 RegionId,
162 ScalarTy,
163 SerializedSpan,
164 Size,
165 SpanData,
166 SwitchData,
167 SwitchScrutinee,
168 TraitItemName,
169 TraitMethodId,
170 TranslatedCrate,
171 TypeDeclKind,
172 TypeParam,
173 TypePattern,
174 TypeVarId,
175 UIntTy,
176 UnOp,
177 UnsizingMetadata,
178 VTableDecl,
179 VTableField,
180 Variant,
181 VariantId,
182 VariantLayout,
183 from_rustc::InlineAttr,
184 llbc_ast::ExprBody,
185 llbc_ast::StatementKind,
186 ullbc_ast::BlockData,
187 ullbc_ast::BlockId,
188 ullbc_ast::ExprBody,
189 ullbc_ast::StatementKind,
190 ullbc_ast::TerminatorKind,
191 for<A: AstVisitable, B: AstVisitable, C: AstVisitable> (A, B, C),
192 for<A: AstVisitable, B: AstVisitable> (A, B),
193 for<A: AstVisitable, B: AstVisitable> OutlivesPred<A, B>,
194 for<A: AstVisitable, B: AstVisitable> Result<A, B>,
195 for<I: Idx, T: AstVisitable> IndexMap<I, T>,
196 for<I: Idx, T: AstVisitable> IndexVec<I, T>,
197 for<Id: AstVisitable> DeclRef<Id>,
198 for<T: AstVisitable + HashConsable> HashConsed<T>,
199 for<T: AstVisitable> Box<T>,
200 for<T: AstVisitable> Option<T>,
201 for<T: AstVisitable> Vec<T>,
202 ),
203 override(
206 AbortKind,
207 AggregateKind,
208 AttrInfo,
209 Attribute,
210 Body,
211 ConstantExpr,
212 ConstantExprKind,
213 DeBruijnId,
214 FileId,
215 FnPtr,
216 FunDecl,
217 FunDeclId,
218 FunDeclRef,
219 FunSig,
220 FunSource,
221 GenericArgs,
222 GenericParams,
223 GlobalDecl,
224 GlobalDeclId,
225 GlobalDeclRef,
226 GlobalPlace,
227 GlobalSource,
228 ImplElem,
229 InhabitedPredicate,
230 InhabitedPredicateKind,
231 ItemMeta,
232 Layout,
233 MetadataValue,
234 Name,
235 Place,
236 PolyTraitRef,
237 ProjectionElem,
238 Region,
239 RegionParam,
240 Rvalue,
241 SizeExpr,
242 SizeExprKind,
243 Span,
244 TraitAssocConst,
245 TraitAssocTy,
246 TraitAssocTyImpl,
247 TraitClauseId,
248 TraitDecl,
249 TraitDeclId,
250 TraitDeclRef,
251 TraitDeclSource,
252 TraitImpl,
253 TraitImplId,
254 TraitImplRef,
255 TraitImplSource,
256 TraitMethod,
257 TraitParam,
258 TraitRef,
259 TraitRefContents,
260 TraitRefKind,
261 TraitTypeConstraint,
262 Ty,
263 TyKind,
264 TypeDecl,
265 TypeDeclId,
266 TypeDeclRef,
267 TypeSource,
268 llbc_block: llbc_ast::Block,
269 llbc_statement: llbc_ast::Statement,
270 ullbc_statement: ullbc_ast::Statement,
271 ullbc_terminator: ullbc_ast::Terminator,
272 for<T: AstVisitable + Idx> DeBruijnVar<T>,
273 for<T: AstVisitable> Binder<T>,
274 for<T: AstVisitable> RegionBinder<T>,
275 for<T: AstVisitable> WithCachedTypeInfo<T>,
276 )
277)]
278pub trait AstVisitable: Any {
279 fn name(&self) -> &'static str {
281 std::any::type_name::<Self>()
282 }
283 fn dyn_visit<T: AstVisitable>(&self, f: impl FnMut(&T))
285 where
286 Self: Sized,
287 {
288 let _ = VisitAst::visit(&mut DynVisitor::new_shared::<T>(f), self);
289 }
290 fn dyn_visit_mut<T: AstVisitable>(&mut self, f: impl FnMut(&mut T))
292 where
293 Self: Sized,
294 {
295 let _ = VisitAstMut::visit(&mut DynVisitor::new_mut::<T>(f), self);
296 }
297}
298
299impl<K: AstVisitable + Hash + Eq, T: AstVisitable> AstVisitable for SeqHashMap<K, T> {
301 fn drive<V: VisitAst>(&self, v: &mut V) -> ControlFlow<V::Break> {
302 for (k, x) in self {
303 v.visit(k)?;
304 v.visit(x)?;
305 }
306 Continue(())
307 }
308 fn drive_mut<V: VisitAstMut>(&mut self, v: &mut V) -> ControlFlow<V::Break> {
309 for (mut k, mut x) in mem::take(self) {
310 v.visit(&mut k)?;
311 v.visit(&mut x)?;
312 self.insert(k, x);
313 }
314 Continue(())
315 }
316 fn drive_two<V: ZipAst>(&self, other: &Self, v: &mut V) -> ControlFlow<V::Break> {
317 if self.len() != other.len() {
318 return Break(Default::default());
319 }
320 for ((key, value), (other_key, other_value)) in self.iter().zip(other) {
321 v.visit(key, other_key)?;
322 v.visit(value, other_value)?;
323 }
324 Continue(())
325 }
326}
327impl<K: BodyVisitable + Hash + Eq, T: BodyVisitable> BodyVisitable for SeqHashMap<K, T> {
328 fn drive_body<V: VisitBody>(&self, v: &mut V) -> ControlFlow<V::Break> {
329 for (k, x) in self {
330 v.visit(k)?;
331 v.visit(x)?;
332 }
333 Continue(())
334 }
335 fn drive_body_mut<V: VisitBodyMut>(&mut self, v: &mut V) -> ControlFlow<V::Break> {
336 for (mut k, mut x) in mem::take(self) {
337 v.visit(&mut k)?;
338 v.visit(&mut x)?;
339 self.insert(k, x);
340 }
341 Continue(())
342 }
343}
344
345#[visitable_group(
358 visitor(drive_body(&VisitBody)),
360 visitor(drive_body_mut(&mut VisitBodyMut)),
361 skip(
363 (),
364 AbortKind,
365 AsmKind,
366 AsmOperandId,
367 AsmOptions,
368 AsmRegister,
369 AsmTemplatePiece,
370 BinOp,
371 BorrowKind,
372 BranchId,
373 BuiltinAdt,
374 BuiltinPathElem,
375 CallSafety,
376 ConstantExpr,
377 DropKind,
378 Error,
379 FieldId,
380 FnPtrKind,
381 FunDeclId,
382 FunDeclRef,
383 GenericArgs,
384 GlobalDeclRef,
385 IntTy,
386 IntegerTy,
387 IntegerValue,
388 Name,
389 NullOp,
390 PathBuf,
391 PolyTraitRef,
392 RefKind,
393 Region,
394 RegionArgs,
395 RegionId,
396 ScalarTy,
397 Span,
398 String,
399 TraitRef,
400 Ty,
401 TypeDeclId,
402 TypeDeclRef,
403 UIntTy,
404 UnOp,
405 Variance,
406 VariantId,
407 WithRetag,
408 bool,
409 llbc_ast::BlockId,
410 llbc_ast::StatementId,
411 u32,
412 ullbc_ast::UnwindKind,
413 usize,
414 ),
415 drive(
417 Assert,
418 BorrowckStatement,
419 BuiltinAssertKind,
420 InlineAsm,
421 PlaceKind,
422 SwitchData,
423 SwitchScrutinee,
424 llbc_ast::StatementKind,
425 ullbc_ast::StatementKind,
426 ullbc_ast::TerminatorKind,
427 for<A: BodyVisitable, B: BodyVisitable, C: BodyVisitable> (A, B, C),
428 for<A: BodyVisitable, B: BodyVisitable> (A, B),
429 for<I: Idx, T: BodyVisitable> IndexMap<I, T>,
430 for<I: Idx, T: BodyVisitable> IndexVec<I, T>,
431 for<T: BodyVisitable, E: BodyVisitable> Result<T, E>,
432 for<T: BodyVisitable> Box<T>,
433 for<T: BodyVisitable> GExprBody<T>,
434 for<T: BodyVisitable> Option<T>,
435 for<T: BodyVisitable> Vec<T>,
436 ),
437 override(
440 AggregateKind,
441 AsmOperand,
442 Body,
443 Call,
444 FnOperand,
445 FnPtr,
446 Local,
447 LocalId,
448 Locals,
449 Operand,
450 Place,
451 ProjectionElem,
452 Rvalue,
453 llbc_block: llbc_ast::Block,
454 llbc_statement: llbc_ast::Statement,
455 ullbc_block: ullbc_ast::BlockData,
456 ullbc_block_id: ullbc_ast::BlockId,
457 ullbc_statement: ullbc_ast::Statement,
458 ullbc_terminator: ullbc_ast::Terminator,
459 )
460)]
461pub trait BodyVisitable: Any {
462 fn dyn_visit_in_body<T: BodyVisitable>(&self, f: impl FnMut(&T))
464 where
465 Self: Sized,
466 {
467 let _ = VisitBody::visit(&mut DynVisitor::new_shared::<T>(f), self);
468 }
469
470 fn dyn_visit_in_body_mut<T: BodyVisitable>(&mut self, f: impl FnMut(&mut T))
472 where
473 Self: Sized,
474 {
475 let _ = VisitBodyMut::visit(&mut DynVisitor::new_mut::<T>(f), self);
476 }
477}
478
479#[derive(Visitor)]
482pub struct DynVisitor<F> {
483 enter: F,
484}
485impl DynVisitor<()> {
486 pub fn new_shared<T: Any>(mut f: impl FnMut(&T)) -> DynVisitor<impl FnMut(&dyn Any)> {
487 let enter = move |x: &dyn Any| {
488 if let Some(x) = x.downcast_ref::<T>() {
489 f(x);
490 }
491 };
492 DynVisitor { enter }
493 }
494 pub fn new_mut<T: Any>(mut f: impl FnMut(&mut T)) -> DynVisitor<impl FnMut(&mut dyn Any)> {
495 let enter = move |x: &mut dyn Any| {
496 if let Some(x) = x.downcast_mut::<T>() {
497 f(x);
498 }
499 };
500 DynVisitor { enter }
501 }
502}
503impl<F> VisitAst for DynVisitor<F>
504where
505 F: FnMut(&dyn Any),
506{
507 fn visit<T: AstVisitable>(&mut self, x: &T) -> ControlFlow<Self::Break> {
508 (self.enter)(x);
509 x.drive(self)?;
510 Continue(())
511 }
512}
513impl<F> VisitAstMut for DynVisitor<F>
514where
515 F: FnMut(&mut dyn Any),
516{
517 fn visit<T: AstVisitable>(&mut self, x: &mut T) -> ControlFlow<Self::Break> {
518 (self.enter)(x);
519 x.drive_mut(self)?;
520 Continue(())
521 }
522}
523impl<F> VisitBody for DynVisitor<F>
524where
525 F: FnMut(&dyn Any),
526{
527 fn visit<T: BodyVisitable>(&mut self, x: &T) -> ControlFlow<Self::Break> {
528 (self.enter)(x);
529 x.drive_body(self)?;
530 Continue(())
531 }
532}
533impl<F> VisitBodyMut for DynVisitor<F>
534where
535 F: FnMut(&mut dyn Any),
536{
537 fn visit<T: BodyVisitable>(&mut self, x: &mut T) -> ControlFlow<Self::Break> {
538 (self.enter)(x);
539 x.drive_body_mut(self)?;
540 Continue(())
541 }
542}
543
544pub use wrappers::*;
545mod wrappers {
546 use std::mem;
560
561 use crate::ast::*;
562 use derive_generic_visitor::*;
563
564 #[repr(transparent)]
570 pub struct DontLeakImplDetails<V>(V);
571
572 impl<V> DontLeakImplDetails<V> {
573 pub fn new(v: &mut V) -> &mut Self {
574 unsafe { std::mem::transmute(v) }
576 }
577 pub fn inner(&mut self) -> &mut V {
578 unsafe { std::mem::transmute(self) }
580 }
581 }
582
583 impl<V: Visitor> Visitor for DontLeakImplDetails<V> {
584 type Break = V::Break;
585 }
586 impl<V: VisitAst> VisitAst for DontLeakImplDetails<V> {
587 fn visit_inner<T>(&mut self, x: &T) -> ControlFlow<Self::Break>
589 where
590 T: AstVisitable,
591 {
592 x.drive(self.inner())
593 }
594 }
595 impl<V: VisitAstMut> VisitAstMut for DontLeakImplDetails<V> {
596 fn visit_inner<T>(&mut self, x: &mut T) -> ControlFlow<Self::Break>
598 where
599 T: AstVisitable,
600 {
601 x.drive_mut(self.inner())
602 }
603 }
604
605 #[repr(transparent)]
616 pub struct VisitWithBinderDepth<V>(V);
617
618 impl<V: VisitorWithBinderDepth> VisitWithBinderDepth<V> {
619 pub fn new(v: &mut V) -> &mut Self {
620 unsafe { std::mem::transmute(v) }
622 }
623 pub fn inner(&mut self) -> &mut V {
624 unsafe { std::mem::transmute(self) }
626 }
627 }
628
629 pub trait VisitorWithBinderDepth {
630 fn binder_depth_mut(&mut self) -> &mut DeBruijnId;
631 }
632
633 impl<V: Visitor> Visitor for VisitWithBinderDepth<V> {
634 type Break = V::Break;
635 }
636 impl<V: VisitAst + VisitorWithBinderDepth> VisitAst for VisitWithBinderDepth<V> {
637 fn visit_inner<T>(&mut self, x: &T) -> ControlFlow<Self::Break>
638 where
639 T: AstVisitable,
640 {
641 x.drive(self.inner())
642 }
643 fn enter_region_binder<T: AstVisitable>(&mut self, _: &RegionBinder<T>) {
644 let binder_depth = self.0.binder_depth_mut();
645 *binder_depth = binder_depth.incr()
646 }
647 fn exit_region_binder<T: AstVisitable>(&mut self, _: &RegionBinder<T>) {
648 let binder_depth = self.0.binder_depth_mut();
649 *binder_depth = binder_depth.decr()
650 }
651 fn enter_binder<T: AstVisitable>(&mut self, _: &Binder<T>) {
652 let binder_depth = self.0.binder_depth_mut();
653 *binder_depth = binder_depth.incr()
654 }
655 fn exit_binder<T: AstVisitable>(&mut self, _: &Binder<T>) {
656 let binder_depth = self.0.binder_depth_mut();
657 *binder_depth = binder_depth.decr()
658 }
659 }
660 impl<V: VisitAstMut + VisitorWithBinderDepth> VisitAstMut for VisitWithBinderDepth<V> {
661 fn visit_inner<T>(&mut self, x: &mut T) -> ControlFlow<Self::Break>
662 where
663 T: AstVisitable,
664 {
665 x.drive_mut(self.inner())
666 }
667 fn enter_region_binder<T: AstVisitable>(&mut self, _: &mut RegionBinder<T>) {
668 let binder_depth = self.0.binder_depth_mut();
669 *binder_depth = binder_depth.incr()
670 }
671 fn exit_region_binder<T: AstVisitable>(&mut self, _: &mut RegionBinder<T>) {
672 let binder_depth = self.0.binder_depth_mut();
673 *binder_depth = binder_depth.decr()
674 }
675 fn enter_binder<T: AstVisitable>(&mut self, _: &mut Binder<T>) {
676 let binder_depth = self.0.binder_depth_mut();
677 *binder_depth = binder_depth.incr()
678 }
679 fn exit_binder<T: AstVisitable>(&mut self, _: &mut Binder<T>) {
680 let binder_depth = self.0.binder_depth_mut();
681 *binder_depth = binder_depth.decr()
682 }
683 }
684
685 pub struct VisitWithVariance<'a, 'ctx, V> {
688 inner: &'a mut V,
689 krate: &'ctx TranslatedCrate,
690 }
691
692 impl<'a, 'ctx, V: VisitorWithVariance> VisitWithVariance<'a, 'ctx, V> {
693 pub fn new(inner: &'a mut V, krate: &'ctx TranslatedCrate) -> Self {
694 Self { inner, krate }
695 }
696 }
697
698 pub trait VisitorWithVariance {
699 fn ambient_variance_mut(&mut self) -> &mut Variance;
700 }
701
702 impl<V: Visitor> Visitor for VisitWithVariance<'_, '_, V> {
703 type Break = V::Break;
704 }
705
706 impl<V: VisitAst + VisitorWithVariance> VisitWithVariance<'_, '_, V> {
707 fn with(
708 &mut self,
709 variance: Variance,
710 f: impl FnOnce(&mut Self) -> ControlFlow<V::Break>,
711 ) -> ControlFlow<V::Break> {
712 let old = *self.inner.ambient_variance_mut();
713 *self.inner.ambient_variance_mut() = Variance::compose(old, variance);
714 let result = f(self);
715 *self.inner.ambient_variance_mut() = old;
716 result
717 }
718
719 fn visit_with<T: AstVisitable>(
720 &mut self,
721 variance: Variance,
722 value: &T,
723 ) -> ControlFlow<V::Break> {
724 self.with(variance, |this| this.visit(value))
725 }
726
727 fn visit_inner_with(&mut self, variance: Variance, ty: &Ty) -> ControlFlow<V::Break> {
728 self.with(variance, |this| this.visit_inner(ty))
729 }
730 }
731
732 impl<V: VisitAst + VisitorWithVariance> VisitAst for VisitWithVariance<'_, '_, V> {
733 fn visit_inner<T: AstVisitable>(&mut self, value: &T) -> ControlFlow<Self::Break> {
734 value.drive(self.inner)
735 }
736
737 fn visit_ty(&mut self, ty: &Ty) -> ControlFlow<Self::Break> {
738 match ty.kind() {
739 TyKind::Ref(region, inner, kind) => {
740 self.visit(region)?;
741 match kind {
742 RefKind::Shared => self.visit(inner)?,
743 RefKind::Mut => self.visit_with(Variance::Invariant, inner)?,
744 }
745 }
746 TyKind::RawPtr(inner, RefKind::Shared) => self.visit(inner)?,
747 TyKind::RawPtr(inner, RefKind::Mut) => {
748 self.visit_with(Variance::Invariant, inner)?;
749 }
750 TyKind::FnPtr(..)
751 | TyKind::Adt(..)
752 | TyKind::Array(..)
753 | TyKind::Slice(..)
754 | TyKind::Pattern(..) => {
755 self.visit_inner(ty)?;
756 }
757 TyKind::TraitType(..)
758 | TyKind::DynTrait(..)
759 | TyKind::FnDef(..)
760 | TyKind::PtrMetadata(..) => {
761 self.visit_inner_with(Variance::Invariant, ty)?;
762 }
763 TyKind::TypeVar(..) | TyKind::Scalar(..) | TyKind::Never | TyKind::Error(..) => {}
764 }
765 Continue(())
766 }
767
768 fn visit_fun_sig(&mut self, sig: &FunSig) -> ControlFlow<Self::Break> {
769 for input in &sig.inputs {
770 self.visit_with(Variance::Contravariant, input)?;
771 }
772 self.visit(&sig.output)?;
773 Continue(())
774 }
775
776 fn visit_type_decl_ref(&mut self, type_ref: &TypeDeclRef) -> ControlFlow<Self::Break> {
777 if let Some(decl) = self.krate.type_decls.get(type_ref.id) {
778 let params = &decl.generics;
779 for (param, region) in params.regions.iter().zip(&type_ref.generics.regions) {
780 self.visit_with(param.variance, region)?;
781 }
782 for (param, ty) in params.types.iter().zip(&type_ref.generics.types) {
783 self.visit_with(param.variance, ty)?;
784 }
785 } else {
786 self.visit_with(Variance::Covariant, &type_ref.generics.regions)?;
787 self.visit_with(Variance::Covariant, &type_ref.generics.types)?;
788 }
789 Continue(())
790 }
791 }
792
793 #[repr(transparent)]
795 pub struct VisitWithItem<V>(V);
796
797 impl<V> VisitWithItem<V> {
798 pub fn new(v: &mut V) -> &mut Self {
799 unsafe { std::mem::transmute(v) }
801 }
802 pub fn inner(&mut self) -> &mut V {
803 unsafe { std::mem::transmute(self) }
805 }
806 }
807
808 pub trait VisitorWithItem: VisitAst {
809 fn enter_item(&mut self, _item: ItemRef<'_>) {}
810 fn exit_item(&mut self, _item: ItemRef<'_>) {}
811 fn visit_item(&mut self, item: ItemRef<'_>) -> ControlFlow<Self::Break> {
812 self.enter_item(item);
813 item.drive(self)?;
814 self.exit_item(item);
815 Continue(())
816 }
817 }
818 pub trait VisitorWithItemMut: VisitAstMut {
819 fn enter_item(&mut self, _item: ItemRefMut<'_>) {}
820 fn exit_item(&mut self, _item: ItemRefMut<'_>) {}
821 fn visit_item(&mut self, mut item: ItemRefMut<'_>) -> ControlFlow<Self::Break> {
822 self.enter_item(item.reborrow());
823 item.drive_mut(self)?;
824 self.exit_item(item);
825 Continue(())
826 }
827 }
828
829 impl<V: Visitor> Visitor for VisitWithItem<V> {
830 type Break = V::Break;
831 }
832 impl<V: VisitAst + VisitorWithItem> VisitAst for VisitWithItem<V> {
833 fn visit_inner<T>(&mut self, x: &T) -> ControlFlow<Self::Break>
834 where
835 T: AstVisitable,
836 {
837 x.drive(self.inner())
838 }
839 fn visit_fun_decl(&mut self, x: &FunDecl) -> ControlFlow<Self::Break> {
840 self.0.visit_item(ItemRef::Fun(x))
841 }
842 fn visit_type_decl(&mut self, x: &TypeDecl) -> ControlFlow<Self::Break> {
843 self.0.visit_item(ItemRef::Type(x))
844 }
845 fn visit_global_decl(&mut self, x: &GlobalDecl) -> ControlFlow<Self::Break> {
846 self.0.visit_item(ItemRef::Global(x))
847 }
848 fn visit_trait_decl(&mut self, x: &TraitDecl) -> ControlFlow<Self::Break> {
849 self.0.visit_item(ItemRef::TraitDecl(x))
850 }
851 fn visit_trait_impl(&mut self, x: &TraitImpl) -> ControlFlow<Self::Break> {
852 self.0.visit_item(ItemRef::TraitImpl(x))
853 }
854 }
855 impl<V: VisitAstMut + VisitorWithItemMut> VisitAstMut for VisitWithItem<V> {
856 fn visit_inner<T>(&mut self, x: &mut T) -> ControlFlow<Self::Break>
857 where
858 T: AstVisitable,
859 {
860 x.drive_mut(self.inner())
861 }
862 fn visit_fun_decl(&mut self, x: &mut FunDecl) -> ControlFlow<Self::Break> {
863 self.0.visit_item(ItemRefMut::Fun(x))
864 }
865 fn visit_type_decl(&mut self, x: &mut TypeDecl) -> ControlFlow<Self::Break> {
866 self.0.visit_item(ItemRefMut::Type(x))
867 }
868 fn visit_global_decl(&mut self, x: &mut GlobalDecl) -> ControlFlow<Self::Break> {
869 self.0.visit_item(ItemRefMut::Global(x))
870 }
871 fn visit_trait_decl(&mut self, x: &mut TraitDecl) -> ControlFlow<Self::Break> {
872 self.0.visit_item(ItemRefMut::TraitDecl(x))
873 }
874 fn visit_trait_impl(&mut self, x: &mut TraitImpl) -> ControlFlow<Self::Break> {
875 self.0.visit_item(ItemRefMut::TraitImpl(x))
876 }
877 }
878
879 #[repr(transparent)]
881 pub struct VisitWithItemRef<V>(V);
882
883 impl<V> VisitWithItemRef<V> {
884 pub fn new(v: &mut V) -> &mut Self {
885 unsafe { std::mem::transmute(v) }
887 }
888 pub fn inner(&mut self) -> &mut V {
889 unsafe { std::mem::transmute(self) }
891 }
892 }
893
894 pub trait VisitorWithItemRef: VisitAst {
895 fn enter_item_ref(&mut self, _item_id: ItemId, _args: &GenericArgs) {}
896 fn exit_item_ref(&mut self, _item_id: ItemId, _args: &GenericArgs) {}
897 fn visit_item_ref(
898 &mut self,
899 item_id: ItemId,
900 args: &GenericArgs,
901 ) -> ControlFlow<Self::Break> {
902 self.enter_item_ref(item_id, args);
903 self.visit_inner(args)?;
904 self.exit_item_ref(item_id, args);
905 Continue(())
906 }
907 }
908 pub trait VisitorWithItemRefMut: VisitAstMut {
909 fn enter_item_ref(&mut self, _item_id: ItemId, _args: &mut GenericArgs) {}
910 fn exit_item_ref(&mut self, _item_id: ItemId, _args: &mut GenericArgs) {}
911 fn visit_item_ref(
912 &mut self,
913 item_id: ItemId,
914 args: &mut GenericArgs,
915 ) -> ControlFlow<Self::Break> {
916 self.enter_item_ref(item_id, args);
917 self.visit_inner(args)?;
918 self.exit_item_ref(item_id, args);
919 Continue(())
920 }
921 }
922
923 impl<V: Visitor> Visitor for VisitWithItemRef<V> {
924 type Break = V::Break;
925 }
926 impl<V: VisitAst + VisitorWithItemRef> VisitAst for VisitWithItemRef<V> {
927 fn visit_inner<T>(&mut self, x: &T) -> ControlFlow<Self::Break>
928 where
929 T: AstVisitable,
930 {
931 x.drive(self.inner())
932 }
933 fn visit_type_decl_ref(&mut self, x: &TypeDeclRef) -> ControlFlow<Self::Break> {
934 self.0.visit_item_ref(ItemId::Type(x.id), &x.generics)
935 }
936 fn visit_fun_decl_ref(&mut self, x: &FunDeclRef) -> ControlFlow<Self::Break> {
937 self.0.visit_item_ref(ItemId::Fun(x.id), &x.generics)
938 }
939 fn visit_global_decl_ref(&mut self, x: &GlobalDeclRef) -> ControlFlow<Self::Break> {
940 self.0.visit_item_ref(ItemId::Global(x.id), &x.generics)
941 }
942 fn visit_trait_decl_ref(&mut self, x: &TraitDeclRef) -> ControlFlow<Self::Break> {
943 self.0.visit_item_ref(ItemId::TraitDecl(x.id), &x.generics)
944 }
945 fn visit_trait_impl_ref(&mut self, x: &TraitImplRef) -> ControlFlow<Self::Break> {
946 self.0.visit_item_ref(ItemId::TraitImpl(x.id), &x.generics)
947 }
948 fn visit_fn_ptr(&mut self, x: &FnPtr) -> ControlFlow<Self::Break> {
949 match x.kind.as_ref() {
950 FnPtrKind::Fun(id) => self.0.visit_item_ref(ItemId::Fun(*id), &x.generics),
951 FnPtrKind::Trait(..) => self.visit_inner(x),
952 }
953 }
954 }
955 impl<V: VisitAstMut + VisitorWithItemRefMut> VisitAstMut for VisitWithItemRef<V> {
956 fn visit_inner<T>(&mut self, x: &mut T) -> ControlFlow<Self::Break>
957 where
958 T: AstVisitable,
959 {
960 x.drive_mut(self.inner())
961 }
962 fn visit_type_decl_ref(&mut self, x: &mut TypeDeclRef) -> ControlFlow<Self::Break> {
963 self.0.visit_item_ref(ItemId::Type(x.id), &mut x.generics)
964 }
965 fn visit_fun_decl_ref(&mut self, x: &mut FunDeclRef) -> ControlFlow<Self::Break> {
966 self.0.visit_item_ref(ItemId::Fun(x.id), &mut x.generics)
967 }
968 fn visit_global_decl_ref(&mut self, x: &mut GlobalDeclRef) -> ControlFlow<Self::Break> {
969 self.0.visit_item_ref(ItemId::Global(x.id), &mut x.generics)
970 }
971 fn visit_trait_decl_ref(&mut self, x: &mut TraitDeclRef) -> ControlFlow<Self::Break> {
972 self.0
973 .visit_item_ref(ItemId::TraitDecl(x.id), &mut x.generics)
974 }
975 fn visit_trait_impl_ref(&mut self, x: &mut TraitImplRef) -> ControlFlow<Self::Break> {
976 self.0
977 .visit_item_ref(ItemId::TraitImpl(x.id), &mut x.generics)
978 }
979 fn visit_fn_ptr(&mut self, x: &mut FnPtr) -> ControlFlow<Self::Break> {
980 match x.kind.as_ref() {
981 FnPtrKind::Fun(id) => self.0.visit_item_ref(ItemId::Fun(*id), &mut x.generics),
982 FnPtrKind::Trait(..) => self.visit_inner(x),
983 }
984 }
985 }
986
987 #[repr(transparent)]
989 pub struct VisitWithBinderStack<V>(V);
990
991 impl<V: VisitorWithBinderStack> VisitWithBinderStack<V> {
992 fn wrap(v: &mut V) -> &mut Self {
994 unsafe { std::mem::transmute(v) }
996 }
997 pub fn new(v: &mut V) -> &mut VisitWithItem<DontLeakImplDetails<Self>> {
998 VisitWithItem::new(DontLeakImplDetails::new(Self::wrap(v)))
1002 }
1003 pub fn inner(&mut self) -> &mut V {
1004 unsafe { std::mem::transmute(self) }
1006 }
1007 }
1008
1009 pub trait VisitorWithBinderStack {
1010 fn binder_stack_mut(&mut self) -> &mut BindingStack<GenericParams>;
1011 }
1012
1013 impl<V: VisitAst + VisitorWithBinderStack> VisitorWithItem
1014 for DontLeakImplDetails<VisitWithBinderStack<V>>
1015 {
1016 fn enter_item(&mut self, item: ItemRef<'_>) {
1017 self.0
1018 .0
1019 .binder_stack_mut()
1020 .push(item.generic_params().clone());
1021 }
1022 fn exit_item(&mut self, _item: ItemRef<'_>) {
1023 self.0.0.binder_stack_mut().pop();
1024 }
1025 }
1026 impl<V: VisitAstMut + VisitorWithBinderStack> VisitorWithItemMut
1027 for DontLeakImplDetails<VisitWithBinderStack<V>>
1028 {
1029 fn enter_item(&mut self, item: ItemRefMut<'_>) {
1030 self.0
1031 .0
1032 .binder_stack_mut()
1033 .push(item.as_ref().generic_params().clone());
1034 }
1035 fn exit_item(&mut self, _item: ItemRefMut<'_>) {
1036 self.0.0.binder_stack_mut().pop();
1037 }
1038 }
1039
1040 impl<V: Visitor> Visitor for VisitWithBinderStack<V> {
1041 type Break = V::Break;
1042 }
1043 impl<V: VisitAst + VisitorWithBinderStack> VisitAst for VisitWithBinderStack<V> {
1044 fn visit_inner<T>(&mut self, x: &T) -> ControlFlow<Self::Break>
1045 where
1046 T: AstVisitable,
1047 {
1048 x.drive(self.inner())
1049 }
1050 fn visit_binder<T: AstVisitable>(
1051 &mut self,
1052 binder: &Binder<T>,
1053 ) -> ControlFlow<Self::Break> {
1054 self.0.binder_stack_mut().push(binder.params.clone());
1055 self.visit_inner(binder)?;
1056 self.0.binder_stack_mut().pop();
1057 Continue(())
1058 }
1059 fn visit_region_binder<T: AstVisitable>(
1060 &mut self,
1061 binder: &RegionBinder<T>,
1062 ) -> ControlFlow<Self::Break> {
1063 self.0.binder_stack_mut().push(binder.to_params());
1064 self.visit_inner(binder)?;
1065 self.0.binder_stack_mut().pop();
1066 Continue(())
1067 }
1068 }
1069 impl<V: VisitAstMut + VisitorWithBinderStack> VisitAstMut for VisitWithBinderStack<V> {
1070 fn visit_inner<T>(&mut self, x: &mut T) -> ControlFlow<Self::Break>
1071 where
1072 T: AstVisitable,
1073 {
1074 x.drive_mut(self.inner())
1075 }
1076 fn visit_binder<T: AstVisitable>(
1077 &mut self,
1078 binder: &mut Binder<T>,
1079 ) -> ControlFlow<Self::Break> {
1080 self.0.binder_stack_mut().push(binder.params.clone());
1081 self.visit_inner(binder)?;
1082 self.0.binder_stack_mut().pop();
1083 Continue(())
1084 }
1085 fn visit_region_binder<T: AstVisitable>(
1086 &mut self,
1087 binder: &mut RegionBinder<T>,
1088 ) -> ControlFlow<Self::Break> {
1089 self.0.binder_stack_mut().push(binder.to_params());
1090 self.visit_inner(binder)?;
1091 self.0.binder_stack_mut().pop();
1092 Continue(())
1093 }
1094 }
1095
1096 #[repr(transparent)]
1098 pub struct VisitWithSpan<V>(V);
1099
1100 impl<V: VisitorWithSpan> VisitWithSpan<V> {
1101 fn wrap(v: &mut V) -> &mut Self {
1103 unsafe { std::mem::transmute(v) }
1105 }
1106 pub fn new(v: &mut V) -> &mut VisitWithItem<DontLeakImplDetails<Self>> {
1107 VisitWithItem::new(DontLeakImplDetails::new(Self::wrap(v)))
1111 }
1112 pub fn inner(&mut self) -> &mut V {
1113 unsafe { std::mem::transmute(self) }
1115 }
1116 }
1117
1118 pub trait VisitorWithSpan {
1119 fn current_span(&mut self) -> &mut Span;
1120 }
1121
1122 impl<V: VisitAst + VisitorWithSpan> VisitorWithItem for DontLeakImplDetails<VisitWithSpan<V>> {
1123 fn visit_item(&mut self, item: ItemRef<'_>) -> ControlFlow<Self::Break> {
1124 let old_span = mem::replace(self.0.0.current_span(), item.item_meta().span);
1125 item.drive(self)?;
1126 *self.0.0.current_span() = old_span;
1127 Continue(())
1128 }
1129 }
1130 impl<V: VisitAstMut + VisitorWithSpan> VisitorWithItemMut
1131 for DontLeakImplDetails<VisitWithSpan<V>>
1132 {
1133 fn visit_item(&mut self, mut item: ItemRefMut<'_>) -> ControlFlow<Self::Break> {
1134 let span = item.as_ref().item_meta().span;
1135 let old_span = mem::replace(self.0.0.current_span(), span);
1136 item.drive_mut(self)?;
1137 *self.0.0.current_span() = old_span;
1138 Continue(())
1139 }
1140 }
1141
1142 impl<V: Visitor> Visitor for VisitWithSpan<V> {
1143 type Break = V::Break;
1144 }
1145 impl<V: VisitAst + VisitorWithSpan> VisitWithSpan<V> {
1146 fn visit_inner_track_span<T>(&mut self, x: &T, span: Span) -> ControlFlow<V::Break>
1147 where
1148 T: AstVisitable,
1149 T: for<'s> derive_generic_visitor::Drive<'s, AstVisitableWrapper<Self>>,
1150 {
1151 let old_span = mem::replace(self.0.current_span(), span);
1152 self.visit_inner(x)?;
1153 *self.0.current_span() = old_span;
1154 Continue(())
1155 }
1156 }
1157 impl<V: VisitAstMut + VisitorWithSpan> VisitWithSpan<V> {
1158 fn visit_inner_mut_track_span<T>(&mut self, x: &mut T, span: Span) -> ControlFlow<V::Break>
1159 where
1160 T: AstVisitable,
1161 T: for<'s> derive_generic_visitor::DriveMut<'s, AstVisitableWrapper<Self>>,
1162 {
1163 let old_span = mem::replace(self.0.current_span(), span);
1164 self.visit_inner(x)?;
1165 *self.0.current_span() = old_span;
1166 Continue(())
1167 }
1168 }
1169 impl<V: VisitAst + VisitorWithSpan> VisitAst for VisitWithSpan<V> {
1170 fn visit_inner<T>(&mut self, x: &T) -> ControlFlow<Self::Break>
1171 where
1172 T: AstVisitable,
1173 {
1174 x.drive(self.inner())
1175 }
1176 fn visit_trait_param(&mut self, x: &TraitParam) -> ControlFlow<Self::Break> {
1177 match x.span {
1178 Some(span) => self.visit_inner_track_span(x, span),
1179 None => self.visit_inner(x),
1180 }
1181 }
1182 fn visit_ullbc_statement(&mut self, x: &ullbc_ast::Statement) -> ControlFlow<Self::Break> {
1183 self.visit_inner_track_span(x, x.span)
1184 }
1185 fn visit_ullbc_terminator(
1186 &mut self,
1187 x: &ullbc_ast::Terminator,
1188 ) -> ControlFlow<Self::Break> {
1189 self.visit_inner_track_span(x, x.span)
1190 }
1191 fn visit_llbc_statement(&mut self, x: &llbc_ast::Statement) -> ControlFlow<Self::Break> {
1192 self.visit_inner_track_span(x, x.span)
1193 }
1194 fn visit_llbc_block(&mut self, x: &llbc_ast::Block) -> ControlFlow<Self::Break> {
1195 self.visit_inner_track_span(x, x.span)
1196 }
1197 }
1198 impl<V: VisitAstMut + VisitorWithSpan> VisitAstMut for VisitWithSpan<V> {
1199 fn visit_inner<T>(&mut self, x: &mut T) -> ControlFlow<Self::Break>
1200 where
1201 T: AstVisitable,
1202 {
1203 x.drive_mut(self.inner())
1204 }
1205 fn visit_trait_param(&mut self, x: &mut TraitParam) -> ControlFlow<Self::Break> {
1206 match x.span {
1207 Some(span) => self.visit_inner_mut_track_span(x, span),
1208 None => self.visit_inner(x),
1209 }
1210 }
1211 fn visit_ullbc_statement(
1212 &mut self,
1213 x: &mut ullbc_ast::Statement,
1214 ) -> ControlFlow<Self::Break> {
1215 self.visit_inner_mut_track_span(x, x.span)
1216 }
1217 fn visit_ullbc_terminator(
1218 &mut self,
1219 x: &mut ullbc_ast::Terminator,
1220 ) -> ControlFlow<Self::Break> {
1221 self.visit_inner_mut_track_span(x, x.span)
1222 }
1223 fn visit_llbc_statement(
1224 &mut self,
1225 x: &mut llbc_ast::Statement,
1226 ) -> ControlFlow<Self::Break> {
1227 self.visit_inner_mut_track_span(x, x.span)
1228 }
1229 fn visit_llbc_block(&mut self, x: &mut llbc_ast::Block) -> ControlFlow<Self::Break> {
1230 self.visit_inner_mut_track_span(x, x.span)
1231 }
1232 }
1233
1234 impl<V: VisitorWithSpan> VisitorWithSpan for VisitWithBinderStack<V> {
1236 fn current_span(&mut self) -> &mut Span {
1237 self.0.current_span()
1238 }
1239 }
1240 impl<V: VisitorWithSpan> VisitorWithSpan for VisitWithItem<V> {
1241 fn current_span(&mut self) -> &mut Span {
1242 self.0.current_span()
1243 }
1244 }
1245 impl<V: VisitorWithSpan> VisitorWithSpan for DontLeakImplDetails<V> {
1246 fn current_span(&mut self) -> &mut Span {
1247 self.0.current_span()
1248 }
1249 }
1250 impl<V: VisitorWithBinderDepth> VisitorWithBinderDepth for VisitWithItemRef<V> {
1251 fn binder_depth_mut(&mut self) -> &mut DeBruijnId {
1252 self.0.binder_depth_mut()
1253 }
1254 }
1255}