1use std::mem;
14use std::path::PathBuf;
15use std::{any::Any, hash::Hash};
16
17use crate::ast::*;
18use crate::ids::{Idx, IndexVec};
19use derive_generic_visitor::*;
20
21#[visitable_group(
40 visitor(drive(&VisitAst)),
42 visitor(drive_mut(&mut VisitAstMut)),
43 visitor(drive_two(&two ZipAst)),
44 skip((), String, PathBuf, bool),
46 drive(
48 Assert, AttrInfo, BinderKind, BinOp, BorrowckStatement, BorrowKind, BuiltinAssertKind, BuiltinFunId, BuiltinIndexOp, BuiltinTy,
49 Call, CastKind, ClosureInfo, ClosureKind, ConstGenericParam, ConstGenericVarId,
50 Disambiguator, DynPredicate, Field, FieldId, File, FloatTy, FloatValue,
51 FnOperand, FunId, FnPtrKind, FunSig, InlineAttr, IntegerTy, IntTy, UIntTy, Literal, LiteralTy,
52 llbc_ast::ExprBody, llbc_ast::StatementKind, llbc_ast::Switch,
53 Loc, Locals, NullOp, Operand, PathElem, PlaceKind, ConstantExprKind,
54 RawAttribute, RefKind, RegionId, RegionParam, ScalarValue, TraitItemName, TraitMethodId, AssocTypeId, AssocConstId, AssocItemId, MaybeAssocItemId,
55 TranslatedCrate, TypeDeclKind, TypeId, TypeParam, TypePattern, TypeVarId,
56 llbc_ast::BlockId, llbc_ast::StatementId,
57 ullbc_ast::BlockData, ullbc_ast::BlockId, ullbc_ast::ExprBody, ullbc_ast::StatementKind,
58 ullbc_ast::TerminatorKind, ullbc_ast::SwitchTargets,
59 UnOp, UnsizingMetadata, Local, Variant, VariantId, LocalId, Layout, VariantLayout, PtrMetadata,
60 SpanData,
61 ItemByVal, VTableField, AssocItemNames,
62 for<Id: AstVisitable> DeclRef<Id>, ItemId,
63 for<T: AstVisitable> Box<T>,
64 for<T: AstVisitable> Option<T>,
65 for<A: AstVisitable, B: AstVisitable> (A, B),
66 for<A: AstVisitable, B: AstVisitable, C: AstVisitable> (A, B, C),
67 for<A: AstVisitable, B: AstVisitable> Result<A, B>,
68 for<A: AstVisitable, B: AstVisitable> OutlivesPred<A, B>,
69 for<T: AstVisitable> Vec<T>,
70 for<T: AstVisitable + HashConsable> HashConsed<T>,
71 for<I: Idx, T: AstVisitable> IndexMap<I, T>,
72 for<I: Idx, T: AstVisitable> IndexVec<I, T>,
73 ),
74 override(
77 FunDeclId, GlobalDeclId, TypeDeclId, TraitDeclId, TraitImplId, FileId,
78 TypeDeclRef, FunDeclRef, GlobalDeclRef, TraitDeclRef, TraitImplRef, ImplElem,
79 FunDecl, GlobalDecl, TypeDecl, TraitDecl, TraitImpl,
80 ItemMeta, Name, Span, Attribute,
81 TypeSource, FunSource, GlobalSource, TraitDeclSource, TraitImplSource,
82 TraitAssocTy, TraitAssocConst, TraitMethod, TraitAssocTyImpl,
83 DeBruijnId, Ty, TyKind, Region, TraitRef, TraitRefContents, TraitRefKind,
84 GenericArgs, GenericParams, TraitParam, TraitClauseId, TraitTypeConstraint,
85 for<T: AstVisitable + Idx> DeBruijnVar<T>,
86 for<T: AstVisitable> RegionBinder<T>,
87 for<T: AstVisitable> Binder<T>,
88 llbc_block: llbc_ast::Block, llbc_statement: llbc_ast::Statement,
89 ullbc_statement: ullbc_ast::Statement, ullbc_terminator: ullbc_ast::Terminator,
90 AbortKind, AggregateKind, FnPtr,
91 ConstantExpr, Place, ProjectionElem, Rvalue, Body,
92 )
93)]
94pub trait AstVisitable: Any {
95 fn name(&self) -> &'static str {
97 std::any::type_name::<Self>()
98 }
99 fn dyn_visit<T: AstVisitable>(&self, f: impl FnMut(&T))
101 where
102 Self: Sized,
103 {
104 let _ = VisitAst::visit(&mut DynVisitor::new_shared::<T>(f), self);
105 }
106 fn dyn_visit_mut<T: AstVisitable>(&mut self, f: impl FnMut(&mut T))
108 where
109 Self: Sized,
110 {
111 let _ = VisitAstMut::visit(&mut DynVisitor::new_mut::<T>(f), self);
112 }
113}
114
115impl<K: AstVisitable + Hash + Eq, T: AstVisitable> AstVisitable for SeqHashMap<K, T> {
117 fn drive<V: VisitAst>(&self, v: &mut V) -> ControlFlow<V::Break> {
118 for (k, x) in self {
119 v.visit(k)?;
120 v.visit(x)?;
121 }
122 Continue(())
123 }
124 fn drive_mut<V: VisitAstMut>(&mut self, v: &mut V) -> ControlFlow<V::Break> {
125 for (mut k, mut x) in mem::take(self) {
126 v.visit(&mut k)?;
127 v.visit(&mut x)?;
128 self.insert(k, x);
129 }
130 Continue(())
131 }
132 fn drive_two<V: ZipAst>(&self, other: &Self, v: &mut V) -> ControlFlow<V::Break> {
133 if self.len() != other.len() {
134 return Break(Default::default());
135 }
136 for ((key, value), (other_key, other_value)) in self.iter().zip(other) {
137 v.visit(key, other_key)?;
138 v.visit(value, other_value)?;
139 }
140 Continue(())
141 }
142}
143impl<K: BodyVisitable + Hash + Eq, T: BodyVisitable> BodyVisitable for SeqHashMap<K, T> {
144 fn drive_body<V: VisitBody>(&self, v: &mut V) -> ControlFlow<V::Break> {
145 for (k, x) in self {
146 v.visit(k)?;
147 v.visit(x)?;
148 }
149 Continue(())
150 }
151 fn drive_body_mut<V: VisitBodyMut>(&mut self, v: &mut V) -> ControlFlow<V::Break> {
152 for (mut k, mut x) in mem::take(self) {
153 v.visit(&mut k)?;
154 v.visit(&mut x)?;
155 self.insert(k, x);
156 }
157 Continue(())
158 }
159}
160
161#[visitable_group(
174 visitor(drive_body(&VisitBody)),
176 visitor(drive_body_mut(&mut VisitBodyMut)),
177 skip(
179 AbortKind, BinOp, BorrowKind, BuiltinAssertKind, ConstantExpr, FieldId,
180 TypeDeclRef, FunDeclId, FunDeclRef, FnPtrKind, GenericArgs, GlobalDeclRef, IntegerTy, IntTy, UIntTy,
181 NullOp, RefKind, ScalarValue, Span, Ty, TypeDeclId, TypeId, UnOp, VariantId,
182 TraitRef, LiteralTy, Literal, Region, RegionId, (), String, PathBuf, bool,
183 ),
184 drive(
186 Assert, BorrowckStatement, PlaceKind,
187 llbc_ast::ExprBody, llbc_ast::StatementKind, llbc_ast::Switch,
188 ullbc_ast::BlockData, ullbc_ast::ExprBody, ullbc_ast::StatementKind,
189 ullbc_ast::TerminatorKind, ullbc_ast::SwitchTargets,
190 llbc_ast::BlockId, llbc_ast::StatementId,
191 Body, Local,
192 for<T: BodyVisitable> Box<T>,
193 for<T: BodyVisitable> Option<T>,
194 for<T: BodyVisitable, E: BodyVisitable> Result<T, E>,
195 for<A: BodyVisitable, B: BodyVisitable> (A, B),
196 for<A: BodyVisitable, B: BodyVisitable, C: BodyVisitable> (A, B, C),
197 for<T: BodyVisitable> Vec<T>,
198 for<I: Idx, T: BodyVisitable> IndexMap<I, T>,
199 for<I: Idx, T: BodyVisitable> IndexVec<I, T>,
200 ),
201 override(
204 AggregateKind, Call, FnOperand, FnPtr,
205 Operand, Place, ProjectionElem, Rvalue, Locals, LocalId,
206 llbc_block: llbc_ast::Block,
207 llbc_statement: llbc_ast::Statement,
208 ullbc_statement: ullbc_ast::Statement,
209 ullbc_terminator: ullbc_ast::Terminator,
210 ullbc_block_id: ullbc_ast::BlockId,
211 )
212)]
213pub trait BodyVisitable: Any {
214 fn dyn_visit_in_body<T: BodyVisitable>(&self, f: impl FnMut(&T))
216 where
217 Self: Sized,
218 {
219 let _ = VisitBody::visit(&mut DynVisitor::new_shared::<T>(f), self);
220 }
221
222 fn dyn_visit_in_body_mut<T: BodyVisitable>(&mut self, f: impl FnMut(&mut T))
224 where
225 Self: Sized,
226 {
227 let _ = VisitBodyMut::visit(&mut DynVisitor::new_mut::<T>(f), self);
228 }
229}
230
231#[derive(Visitor)]
234pub struct DynVisitor<F> {
235 enter: F,
236}
237impl DynVisitor<()> {
238 pub fn new_shared<T: Any>(mut f: impl FnMut(&T)) -> DynVisitor<impl FnMut(&dyn Any)> {
239 let enter = move |x: &dyn Any| {
240 if let Some(x) = x.downcast_ref::<T>() {
241 f(x);
242 }
243 };
244 DynVisitor { enter }
245 }
246 pub fn new_mut<T: Any>(mut f: impl FnMut(&mut T)) -> DynVisitor<impl FnMut(&mut dyn Any)> {
247 let enter = move |x: &mut dyn Any| {
248 if let Some(x) = x.downcast_mut::<T>() {
249 f(x);
250 }
251 };
252 DynVisitor { enter }
253 }
254}
255impl<F> VisitAst for DynVisitor<F>
256where
257 F: FnMut(&dyn Any),
258{
259 fn visit<T: AstVisitable>(&mut self, x: &T) -> ControlFlow<Self::Break> {
260 (self.enter)(x);
261 x.drive(self)?;
262 Continue(())
263 }
264}
265impl<F> VisitAstMut for DynVisitor<F>
266where
267 F: FnMut(&mut dyn Any),
268{
269 fn visit<T: AstVisitable>(&mut self, x: &mut T) -> ControlFlow<Self::Break> {
270 (self.enter)(x);
271 x.drive_mut(self)?;
272 Continue(())
273 }
274}
275impl<F> VisitBody for DynVisitor<F>
276where
277 F: FnMut(&dyn Any),
278{
279 fn visit<T: BodyVisitable>(&mut self, x: &T) -> ControlFlow<Self::Break> {
280 (self.enter)(x);
281 x.drive_body(self)?;
282 Continue(())
283 }
284}
285impl<F> VisitBodyMut for DynVisitor<F>
286where
287 F: FnMut(&mut dyn Any),
288{
289 fn visit<T: BodyVisitable>(&mut self, x: &mut T) -> ControlFlow<Self::Break> {
290 (self.enter)(x);
291 x.drive_body_mut(self)?;
292 Continue(())
293 }
294}
295
296pub use wrappers::*;
297mod wrappers {
298 use std::mem;
312
313 use crate::ast::*;
314 use derive_generic_visitor::*;
315
316 #[repr(transparent)]
322 pub struct DontLeakImplDetails<V>(V);
323
324 impl<V> DontLeakImplDetails<V> {
325 pub fn new(v: &mut V) -> &mut Self {
326 unsafe { std::mem::transmute(v) }
328 }
329 pub fn inner(&mut self) -> &mut V {
330 unsafe { std::mem::transmute(self) }
332 }
333 }
334
335 impl<V: Visitor> Visitor for DontLeakImplDetails<V> {
336 type Break = V::Break;
337 }
338 impl<V: VisitAst> VisitAst for DontLeakImplDetails<V> {
339 fn visit_inner<T>(&mut self, x: &T) -> ControlFlow<Self::Break>
341 where
342 T: AstVisitable,
343 {
344 x.drive(self.inner())
345 }
346 }
347 impl<V: VisitAstMut> VisitAstMut for DontLeakImplDetails<V> {
348 fn visit_inner<T>(&mut self, x: &mut T) -> ControlFlow<Self::Break>
350 where
351 T: AstVisitable,
352 {
353 x.drive_mut(self.inner())
354 }
355 }
356
357 #[repr(transparent)]
368 pub struct VisitWithBinderDepth<V>(V);
369
370 impl<V: VisitorWithBinderDepth> VisitWithBinderDepth<V> {
371 pub fn new(v: &mut V) -> &mut Self {
372 unsafe { std::mem::transmute(v) }
374 }
375 pub fn inner(&mut self) -> &mut V {
376 unsafe { std::mem::transmute(self) }
378 }
379 }
380
381 pub trait VisitorWithBinderDepth {
382 fn binder_depth_mut(&mut self) -> &mut DeBruijnId;
383 }
384
385 impl<V: Visitor> Visitor for VisitWithBinderDepth<V> {
386 type Break = V::Break;
387 }
388 impl<V: VisitAst + VisitorWithBinderDepth> VisitAst for VisitWithBinderDepth<V> {
389 fn visit_inner<T>(&mut self, x: &T) -> ControlFlow<Self::Break>
390 where
391 T: AstVisitable,
392 {
393 x.drive(self.inner())
394 }
395 fn enter_region_binder<T: AstVisitable>(&mut self, _: &RegionBinder<T>) {
396 let binder_depth = self.0.binder_depth_mut();
397 *binder_depth = binder_depth.incr()
398 }
399 fn exit_region_binder<T: AstVisitable>(&mut self, _: &RegionBinder<T>) {
400 let binder_depth = self.0.binder_depth_mut();
401 *binder_depth = binder_depth.decr()
402 }
403 fn enter_binder<T: AstVisitable>(&mut self, _: &Binder<T>) {
404 let binder_depth = self.0.binder_depth_mut();
405 *binder_depth = binder_depth.incr()
406 }
407 fn exit_binder<T: AstVisitable>(&mut self, _: &Binder<T>) {
408 let binder_depth = self.0.binder_depth_mut();
409 *binder_depth = binder_depth.decr()
410 }
411 }
412 impl<V: VisitAstMut + VisitorWithBinderDepth> VisitAstMut for VisitWithBinderDepth<V> {
413 fn visit_inner<T>(&mut self, x: &mut T) -> ControlFlow<Self::Break>
414 where
415 T: AstVisitable,
416 {
417 x.drive_mut(self.inner())
418 }
419 fn enter_region_binder<T: AstVisitable>(&mut self, _: &mut RegionBinder<T>) {
420 let binder_depth = self.0.binder_depth_mut();
421 *binder_depth = binder_depth.incr()
422 }
423 fn exit_region_binder<T: AstVisitable>(&mut self, _: &mut RegionBinder<T>) {
424 let binder_depth = self.0.binder_depth_mut();
425 *binder_depth = binder_depth.decr()
426 }
427 fn enter_binder<T: AstVisitable>(&mut self, _: &mut Binder<T>) {
428 let binder_depth = self.0.binder_depth_mut();
429 *binder_depth = binder_depth.incr()
430 }
431 fn exit_binder<T: AstVisitable>(&mut self, _: &mut Binder<T>) {
432 let binder_depth = self.0.binder_depth_mut();
433 *binder_depth = binder_depth.decr()
434 }
435 }
436
437 #[repr(transparent)]
439 pub struct VisitWithItem<V>(V);
440
441 impl<V> VisitWithItem<V> {
442 pub fn new(v: &mut V) -> &mut Self {
443 unsafe { std::mem::transmute(v) }
445 }
446 pub fn inner(&mut self) -> &mut V {
447 unsafe { std::mem::transmute(self) }
449 }
450 }
451
452 pub trait VisitorWithItem: VisitAst {
453 fn enter_item(&mut self, _item: ItemRef<'_>) {}
454 fn exit_item(&mut self, _item: ItemRef<'_>) {}
455 fn visit_item(&mut self, item: ItemRef<'_>) -> ControlFlow<Self::Break> {
456 self.enter_item(item);
457 item.drive(self)?;
458 self.exit_item(item);
459 Continue(())
460 }
461 }
462 pub trait VisitorWithItemMut: VisitAstMut {
463 fn enter_item(&mut self, _item: ItemRefMut<'_>) {}
464 fn exit_item(&mut self, _item: ItemRefMut<'_>) {}
465 fn visit_item(&mut self, mut item: ItemRefMut<'_>) -> ControlFlow<Self::Break> {
466 self.enter_item(item.reborrow());
467 item.drive_mut(self)?;
468 self.exit_item(item);
469 Continue(())
470 }
471 }
472
473 impl<V: Visitor> Visitor for VisitWithItem<V> {
474 type Break = V::Break;
475 }
476 impl<V: VisitAst + VisitorWithItem> VisitAst for VisitWithItem<V> {
477 fn visit_inner<T>(&mut self, x: &T) -> ControlFlow<Self::Break>
478 where
479 T: AstVisitable,
480 {
481 x.drive(self.inner())
482 }
483 fn visit_fun_decl(&mut self, x: &FunDecl) -> ControlFlow<Self::Break> {
484 self.0.visit_item(ItemRef::Fun(x))
485 }
486 fn visit_type_decl(&mut self, x: &TypeDecl) -> ControlFlow<Self::Break> {
487 self.0.visit_item(ItemRef::Type(x))
488 }
489 fn visit_global_decl(&mut self, x: &GlobalDecl) -> ControlFlow<Self::Break> {
490 self.0.visit_item(ItemRef::Global(x))
491 }
492 fn visit_trait_decl(&mut self, x: &TraitDecl) -> ControlFlow<Self::Break> {
493 self.0.visit_item(ItemRef::TraitDecl(x))
494 }
495 fn visit_trait_impl(&mut self, x: &TraitImpl) -> ControlFlow<Self::Break> {
496 self.0.visit_item(ItemRef::TraitImpl(x))
497 }
498 }
499 impl<V: VisitAstMut + VisitorWithItemMut> VisitAstMut for VisitWithItem<V> {
500 fn visit_inner<T>(&mut self, x: &mut T) -> ControlFlow<Self::Break>
501 where
502 T: AstVisitable,
503 {
504 x.drive_mut(self.inner())
505 }
506 fn visit_fun_decl(&mut self, x: &mut FunDecl) -> ControlFlow<Self::Break> {
507 self.0.visit_item(ItemRefMut::Fun(x))
508 }
509 fn visit_type_decl(&mut self, x: &mut TypeDecl) -> ControlFlow<Self::Break> {
510 self.0.visit_item(ItemRefMut::Type(x))
511 }
512 fn visit_global_decl(&mut self, x: &mut GlobalDecl) -> ControlFlow<Self::Break> {
513 self.0.visit_item(ItemRefMut::Global(x))
514 }
515 fn visit_trait_decl(&mut self, x: &mut TraitDecl) -> ControlFlow<Self::Break> {
516 self.0.visit_item(ItemRefMut::TraitDecl(x))
517 }
518 fn visit_trait_impl(&mut self, x: &mut TraitImpl) -> ControlFlow<Self::Break> {
519 self.0.visit_item(ItemRefMut::TraitImpl(x))
520 }
521 }
522
523 #[repr(transparent)]
525 pub struct VisitWithItemRef<V>(V);
526
527 impl<V> VisitWithItemRef<V> {
528 pub fn new(v: &mut V) -> &mut Self {
529 unsafe { std::mem::transmute(v) }
531 }
532 pub fn inner(&mut self) -> &mut V {
533 unsafe { std::mem::transmute(self) }
535 }
536 }
537
538 pub trait VisitorWithItemRef: VisitAst {
539 fn enter_item_ref(&mut self, _item_id: ItemId, _args: &GenericArgs) {}
540 fn exit_item_ref(&mut self, _item_id: ItemId, _args: &GenericArgs) {}
541 fn visit_item_ref(
542 &mut self,
543 item_id: ItemId,
544 args: &GenericArgs,
545 ) -> ControlFlow<Self::Break> {
546 self.enter_item_ref(item_id, args);
547 self.visit_inner(args)?;
548 self.exit_item_ref(item_id, args);
549 Continue(())
550 }
551 }
552 pub trait VisitorWithItemRefMut: VisitAstMut {
553 fn enter_item_ref(&mut self, _item_id: ItemId, _args: &mut GenericArgs) {}
554 fn exit_item_ref(&mut self, _item_id: ItemId, _args: &mut GenericArgs) {}
555 fn visit_item_ref(
556 &mut self,
557 item_id: ItemId,
558 args: &mut GenericArgs,
559 ) -> ControlFlow<Self::Break> {
560 self.enter_item_ref(item_id, args);
561 self.visit_inner(args)?;
562 self.exit_item_ref(item_id, args);
563 Continue(())
564 }
565 }
566
567 impl<V: Visitor> Visitor for VisitWithItemRef<V> {
568 type Break = V::Break;
569 }
570 impl<V: VisitAst + VisitorWithItemRef> VisitAst for VisitWithItemRef<V> {
571 fn visit_inner<T>(&mut self, x: &T) -> ControlFlow<Self::Break>
572 where
573 T: AstVisitable,
574 {
575 x.drive(self.inner())
576 }
577 fn visit_type_decl_ref(&mut self, x: &TypeDeclRef) -> ControlFlow<Self::Break> {
578 match x.as_adt() {
579 Some(id) => self.0.visit_item_ref(ItemId::Type(id), &x.generics),
580 None => self.visit_inner(x),
581 }
582 }
583 fn visit_fun_decl_ref(&mut self, x: &FunDeclRef) -> ControlFlow<Self::Break> {
584 self.0.visit_item_ref(ItemId::Fun(x.id), &x.generics)
585 }
586 fn visit_global_decl_ref(&mut self, x: &GlobalDeclRef) -> ControlFlow<Self::Break> {
587 self.0.visit_item_ref(ItemId::Global(x.id), &x.generics)
588 }
589 fn visit_trait_decl_ref(&mut self, x: &TraitDeclRef) -> ControlFlow<Self::Break> {
590 self.0.visit_item_ref(ItemId::TraitDecl(x.id), &x.generics)
591 }
592 fn visit_trait_impl_ref(&mut self, x: &TraitImplRef) -> ControlFlow<Self::Break> {
593 self.0.visit_item_ref(ItemId::TraitImpl(x.id), &x.generics)
594 }
595 fn visit_fn_ptr(&mut self, x: &FnPtr) -> ControlFlow<Self::Break> {
596 match x.kind.as_ref() {
597 FnPtrKind::Fun(FunId::Regular(id)) => {
598 self.0.visit_item_ref(ItemId::Fun(*id), &x.generics)
599 }
600 FnPtrKind::Fun(FunId::Builtin(_)) | FnPtrKind::Trait(..) => self.visit_inner(x),
601 }
602 }
603 }
604 impl<V: VisitAstMut + VisitorWithItemRefMut> VisitAstMut for VisitWithItemRef<V> {
605 fn visit_inner<T>(&mut self, x: &mut T) -> ControlFlow<Self::Break>
606 where
607 T: AstVisitable,
608 {
609 x.drive_mut(self.inner())
610 }
611 fn visit_type_decl_ref(&mut self, x: &mut TypeDeclRef) -> ControlFlow<Self::Break> {
612 match x.as_adt() {
613 Some(id) => self.0.visit_item_ref(ItemId::Type(id), &mut x.generics),
614 None => self.visit_inner(x),
615 }
616 }
617 fn visit_fun_decl_ref(&mut self, x: &mut FunDeclRef) -> ControlFlow<Self::Break> {
618 self.0.visit_item_ref(ItemId::Fun(x.id), &mut x.generics)
619 }
620 fn visit_global_decl_ref(&mut self, x: &mut GlobalDeclRef) -> ControlFlow<Self::Break> {
621 self.0.visit_item_ref(ItemId::Global(x.id), &mut x.generics)
622 }
623 fn visit_trait_decl_ref(&mut self, x: &mut TraitDeclRef) -> ControlFlow<Self::Break> {
624 self.0
625 .visit_item_ref(ItemId::TraitDecl(x.id), &mut x.generics)
626 }
627 fn visit_trait_impl_ref(&mut self, x: &mut TraitImplRef) -> ControlFlow<Self::Break> {
628 self.0
629 .visit_item_ref(ItemId::TraitImpl(x.id), &mut x.generics)
630 }
631 fn visit_fn_ptr(&mut self, x: &mut FnPtr) -> ControlFlow<Self::Break> {
632 match x.kind.as_ref() {
633 FnPtrKind::Fun(FunId::Regular(id)) => {
634 self.0.visit_item_ref(ItemId::Fun(*id), &mut x.generics)
635 }
636 FnPtrKind::Fun(FunId::Builtin(_)) | FnPtrKind::Trait(..) => self.visit_inner(x),
637 }
638 }
639 }
640
641 #[repr(transparent)]
643 pub struct VisitWithBinderStack<V>(V);
644
645 impl<V: VisitorWithBinderStack> VisitWithBinderStack<V> {
646 fn wrap(v: &mut V) -> &mut Self {
648 unsafe { std::mem::transmute(v) }
650 }
651 pub fn new(v: &mut V) -> &mut VisitWithItem<DontLeakImplDetails<Self>> {
652 VisitWithItem::new(DontLeakImplDetails::new(Self::wrap(v)))
656 }
657 pub fn inner(&mut self) -> &mut V {
658 unsafe { std::mem::transmute(self) }
660 }
661 }
662
663 pub trait VisitorWithBinderStack {
664 fn binder_stack_mut(&mut self) -> &mut BindingStack<GenericParams>;
665 }
666
667 impl<V: VisitAst + VisitorWithBinderStack> VisitorWithItem
668 for DontLeakImplDetails<VisitWithBinderStack<V>>
669 {
670 fn enter_item(&mut self, item: ItemRef<'_>) {
671 self.0
672 .0
673 .binder_stack_mut()
674 .push(item.generic_params().clone());
675 }
676 fn exit_item(&mut self, _item: ItemRef<'_>) {
677 self.0.0.binder_stack_mut().pop();
678 }
679 }
680 impl<V: VisitAstMut + VisitorWithBinderStack> VisitorWithItemMut
681 for DontLeakImplDetails<VisitWithBinderStack<V>>
682 {
683 fn enter_item(&mut self, item: ItemRefMut<'_>) {
684 self.0
685 .0
686 .binder_stack_mut()
687 .push(item.as_ref().generic_params().clone());
688 }
689 fn exit_item(&mut self, _item: ItemRefMut<'_>) {
690 self.0.0.binder_stack_mut().pop();
691 }
692 }
693
694 impl<V: Visitor> Visitor for VisitWithBinderStack<V> {
695 type Break = V::Break;
696 }
697 impl<V: VisitAst + VisitorWithBinderStack> VisitAst for VisitWithBinderStack<V> {
698 fn visit_inner<T>(&mut self, x: &T) -> ControlFlow<Self::Break>
699 where
700 T: AstVisitable,
701 {
702 x.drive(self.inner())
703 }
704 fn visit_binder<T: AstVisitable>(
705 &mut self,
706 binder: &Binder<T>,
707 ) -> ControlFlow<Self::Break> {
708 self.0.binder_stack_mut().push(binder.params.clone());
709 self.visit_inner(binder)?;
710 self.0.binder_stack_mut().pop();
711 Continue(())
712 }
713 fn visit_region_binder<T: AstVisitable>(
714 &mut self,
715 binder: &RegionBinder<T>,
716 ) -> ControlFlow<Self::Break> {
717 self.0.binder_stack_mut().push(GenericParams {
718 regions: binder.regions.clone(),
719 ..Default::default()
720 });
721 self.visit_inner(binder)?;
722 self.0.binder_stack_mut().pop();
723 Continue(())
724 }
725 }
726 impl<V: VisitAstMut + VisitorWithBinderStack> VisitAstMut for VisitWithBinderStack<V> {
727 fn visit_inner<T>(&mut self, x: &mut T) -> ControlFlow<Self::Break>
728 where
729 T: AstVisitable,
730 {
731 x.drive_mut(self.inner())
732 }
733 fn visit_binder<T: AstVisitable>(
734 &mut self,
735 binder: &mut Binder<T>,
736 ) -> ControlFlow<Self::Break> {
737 self.0.binder_stack_mut().push(binder.params.clone());
738 self.visit_inner(binder)?;
739 self.0.binder_stack_mut().pop();
740 Continue(())
741 }
742 fn visit_region_binder<T: AstVisitable>(
743 &mut self,
744 binder: &mut RegionBinder<T>,
745 ) -> ControlFlow<Self::Break> {
746 self.0.binder_stack_mut().push(GenericParams {
747 regions: binder.regions.clone(),
748 ..Default::default()
749 });
750 self.visit_inner(binder)?;
751 self.0.binder_stack_mut().pop();
752 Continue(())
753 }
754 }
755
756 #[repr(transparent)]
758 pub struct VisitWithSpan<V>(V);
759
760 impl<V: VisitorWithSpan> VisitWithSpan<V> {
761 fn wrap(v: &mut V) -> &mut Self {
763 unsafe { std::mem::transmute(v) }
765 }
766 pub fn new(v: &mut V) -> &mut VisitWithItem<DontLeakImplDetails<Self>> {
767 VisitWithItem::new(DontLeakImplDetails::new(Self::wrap(v)))
771 }
772 pub fn inner(&mut self) -> &mut V {
773 unsafe { std::mem::transmute(self) }
775 }
776 }
777
778 pub trait VisitorWithSpan {
779 fn current_span(&mut self) -> &mut Span;
780 }
781
782 impl<V: VisitAst + VisitorWithSpan> VisitorWithItem for DontLeakImplDetails<VisitWithSpan<V>> {
783 fn visit_item(&mut self, item: ItemRef<'_>) -> ControlFlow<Self::Break> {
784 let old_span = mem::replace(self.0.0.current_span(), item.item_meta().span);
785 item.drive(self)?;
786 *self.0.0.current_span() = old_span;
787 Continue(())
788 }
789 }
790 impl<V: VisitAstMut + VisitorWithSpan> VisitorWithItemMut
791 for DontLeakImplDetails<VisitWithSpan<V>>
792 {
793 fn visit_item(&mut self, mut item: ItemRefMut<'_>) -> ControlFlow<Self::Break> {
794 let span = item.as_ref().item_meta().span;
795 let old_span = mem::replace(self.0.0.current_span(), span);
796 item.drive_mut(self)?;
797 *self.0.0.current_span() = old_span;
798 Continue(())
799 }
800 }
801
802 impl<V: Visitor> Visitor for VisitWithSpan<V> {
803 type Break = V::Break;
804 }
805 impl<V: VisitAst + VisitorWithSpan> VisitWithSpan<V> {
806 fn visit_inner_track_span<T>(&mut self, x: &T, span: Span) -> ControlFlow<V::Break>
807 where
808 T: AstVisitable,
809 T: for<'s> derive_generic_visitor::Drive<'s, AstVisitableWrapper<Self>>,
810 {
811 let old_span = mem::replace(self.0.current_span(), span);
812 self.visit_inner(x)?;
813 *self.0.current_span() = old_span;
814 Continue(())
815 }
816 }
817 impl<V: VisitAstMut + VisitorWithSpan> VisitWithSpan<V> {
818 fn visit_inner_mut_track_span<T>(&mut self, x: &mut T, span: Span) -> ControlFlow<V::Break>
819 where
820 T: AstVisitable,
821 T: for<'s> derive_generic_visitor::DriveMut<'s, AstVisitableWrapper<Self>>,
822 {
823 let old_span = mem::replace(self.0.current_span(), span);
824 self.visit_inner(x)?;
825 *self.0.current_span() = old_span;
826 Continue(())
827 }
828 }
829 impl<V: VisitAst + VisitorWithSpan> VisitAst for VisitWithSpan<V> {
830 fn visit_inner<T>(&mut self, x: &T) -> ControlFlow<Self::Break>
831 where
832 T: AstVisitable,
833 {
834 x.drive(self.inner())
835 }
836 fn visit_trait_param(&mut self, x: &TraitParam) -> ControlFlow<Self::Break> {
837 match x.span {
838 Some(span) => self.visit_inner_track_span(x, span),
839 None => self.visit_inner(x),
840 }
841 }
842 fn visit_ullbc_statement(&mut self, x: &ullbc_ast::Statement) -> ControlFlow<Self::Break> {
843 self.visit_inner_track_span(x, x.span)
844 }
845 fn visit_ullbc_terminator(
846 &mut self,
847 x: &ullbc_ast::Terminator,
848 ) -> ControlFlow<Self::Break> {
849 self.visit_inner_track_span(x, x.span)
850 }
851 fn visit_llbc_statement(&mut self, x: &llbc_ast::Statement) -> ControlFlow<Self::Break> {
852 self.visit_inner_track_span(x, x.span)
853 }
854 fn visit_llbc_block(&mut self, x: &llbc_ast::Block) -> ControlFlow<Self::Break> {
855 self.visit_inner_track_span(x, x.span)
856 }
857 }
858 impl<V: VisitAstMut + VisitorWithSpan> VisitAstMut for VisitWithSpan<V> {
859 fn visit_inner<T>(&mut self, x: &mut T) -> ControlFlow<Self::Break>
860 where
861 T: AstVisitable,
862 {
863 x.drive_mut(self.inner())
864 }
865 fn visit_trait_param(&mut self, x: &mut TraitParam) -> ControlFlow<Self::Break> {
866 match x.span {
867 Some(span) => self.visit_inner_mut_track_span(x, span),
868 None => self.visit_inner(x),
869 }
870 }
871 fn visit_ullbc_statement(
872 &mut self,
873 x: &mut ullbc_ast::Statement,
874 ) -> ControlFlow<Self::Break> {
875 self.visit_inner_mut_track_span(x, x.span)
876 }
877 fn visit_ullbc_terminator(
878 &mut self,
879 x: &mut ullbc_ast::Terminator,
880 ) -> ControlFlow<Self::Break> {
881 self.visit_inner_mut_track_span(x, x.span)
882 }
883 fn visit_llbc_statement(
884 &mut self,
885 x: &mut llbc_ast::Statement,
886 ) -> ControlFlow<Self::Break> {
887 self.visit_inner_mut_track_span(x, x.span)
888 }
889 fn visit_llbc_block(&mut self, x: &mut llbc_ast::Block) -> ControlFlow<Self::Break> {
890 self.visit_inner_mut_track_span(x, x.span)
891 }
892 }
893
894 impl<V: VisitorWithSpan> VisitorWithSpan for VisitWithBinderStack<V> {
896 fn current_span(&mut self) -> &mut Span {
897 self.0.current_span()
898 }
899 }
900 impl<V: VisitorWithSpan> VisitorWithSpan for VisitWithItem<V> {
901 fn current_span(&mut self) -> &mut Span {
902 self.0.current_span()
903 }
904 }
905 impl<V: VisitorWithSpan> VisitorWithSpan for DontLeakImplDetails<V> {
906 fn current_span(&mut self) -> &mut Span {
907 self.0.current_span()
908 }
909 }
910 impl<V: VisitorWithBinderDepth> VisitorWithBinderDepth for VisitWithItemRef<V> {
911 fn binder_depth_mut(&mut self) -> &mut DeBruijnId {
912 self.0.binder_depth_mut()
913 }
914 }
915}