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 (), String, PathBuf, bool, char, i128, u8, u32, u64, u128, usize, ustr::Ustr,
51 crate::options::CliOpts,
52 Abi, BuiltinImplData, Byte, DeprecatedSince, DropKind, Error, FileName,
53 GlobalKind, ItemOpacity, LangItem, LifetimeMutability, OptimizeAttr, OverflowMode,
54 ReprOptions, Variance, FieldPredecessor,
55 std::ops::RangeInclusive<IntegerValue>,
56 WithRetag, BuiltinPathElem, BranchId, AsmOperandId, AsmKind, AsmRegister, AsmOptions, CallSafety,
57 ),
58 skip(
60 DeclarationGroup, PredicateOrigin, TargetInfo, TypeInfo, ImplementsMarkerTraits,
61 llbc_ast::BlockId, llbc_ast::StatementId,
62 ),
63 drive(
65 Assert, AttributeKind, BinderKind, BinOp, BorrowckStatement, BorrowKind, BuiltinAdt, BuiltinAssertKind,
66 Call, InlineAsm, AsmTemplatePiece, AsmOperand, CastKind, ClosureInfo, ClosureKind, ConstGenericParam, ConstGenericVarId,
67 Deprecation, Disambiguator, DynPredicate, Field, FieldId, File, FloatTy, FloatValue,
68 FnOperand, FnPtrKind, InlineAttr, IntegerTy, IntTy, UIntTy, ScalarTy,
69 Ident, from_rustc::InlineAttr,
70 llbc_ast::ExprBody, llbc_ast::StatementKind,
71 Loc, Locals, NullOp, Operand, PathElem, PlaceKind,
72 RawAttribute, RefKind, RegionId, RegionParam, IntegerValue, TraitItemName, TraitMethodId, AssocTypeId, AssocConstId, AssocItemId, MaybeAssocItemId,
73 TranslatedCrate, TypeDeclKind, TypeParam, TypePattern, TypeVarId,
74 ullbc_ast::BlockData, ullbc_ast::BlockId, ullbc_ast::ExprBody, ullbc_ast::StatementKind,
75 ullbc_ast::TerminatorKind, SwitchData, SwitchScrutinee,
76 UnOp, UnsizingMetadata, Local, Variant, VariantId, LocalId, VariantLayout,
77 Discriminator,
78 Size, OffsetExpr, OffsetGuarantee,
79 PtrMetadata,
80 SpanData, SerializedSpan,
81 ItemByVal, VTableField, VTableDecl, AssocItemNames,
82 for<Id: AstVisitable> DeclRef<Id>, ItemId,
83 for<T: AstVisitable> Box<T>,
84 for<T: AstVisitable> Option<T>,
85 for<A: AstVisitable, B: AstVisitable> (A, B),
86 for<A: AstVisitable, B: AstVisitable, C: AstVisitable> (A, B, C),
87 for<A: AstVisitable, B: AstVisitable> Result<A, B>,
88 for<A: AstVisitable, B: AstVisitable> OutlivesPred<A, B>,
89 for<T: AstVisitable> Vec<T>,
90 for<T: AstVisitable + HashConsable> HashConsed<T>,
91 for<I: Idx, T: AstVisitable> IndexMap<I, T>,
92 for<I: Idx, T: AstVisitable> IndexVec<I, T>,
93 ),
94 override(
97 FunDeclId, GlobalDeclId, TypeDeclId, TraitDeclId, TraitImplId, FileId,
98 TypeDeclRef, FunDeclRef, GlobalDeclRef, TraitDeclRef, TraitImplRef, ImplElem,
99 FunDecl, GlobalDecl, TypeDecl, TraitDecl, TraitImpl,
100 ItemMeta, Name, Span, Attribute, AttrInfo,
101 TypeSource, FunSource, GlobalSource, TraitDeclSource, TraitImplSource,
102 TraitAssocTy, TraitAssocConst, TraitMethod, TraitAssocTyImpl,
103 DeBruijnId, Ty, TyKind, Region, TraitRef, TraitRefContents, TraitRefKind,
104 GenericArgs, GenericParams, TraitParam, TraitClauseId, TraitTypeConstraint,
105 for<T: AstVisitable + Idx> DeBruijnVar<T>,
106 for<T: AstVisitable> WithCachedTypeInfo<T>,
107 for<T: AstVisitable> RegionBinder<T>,
108 for<T: AstVisitable> Binder<T>,
109 llbc_block: llbc_ast::Block, llbc_statement: llbc_ast::Statement,
110 ullbc_statement: ullbc_ast::Statement, ullbc_terminator: ullbc_ast::Terminator,
111 AbortKind, AggregateKind, FnPtr, FunSig,
112 ConstantExpr, ConstantExprKind, Layout, InhabitedPredicate, InhabitedPredicateKind, SizeExpr,
113 SizeExprKind, MetadataValue, Place, ProjectionElem, Rvalue, Body,
114 )
115)]
116pub trait AstVisitable: Any {
117 fn name(&self) -> &'static str {
119 std::any::type_name::<Self>()
120 }
121 fn dyn_visit<T: AstVisitable>(&self, f: impl FnMut(&T))
123 where
124 Self: Sized,
125 {
126 let _ = VisitAst::visit(&mut DynVisitor::new_shared::<T>(f), self);
127 }
128 fn dyn_visit_mut<T: AstVisitable>(&mut self, f: impl FnMut(&mut T))
130 where
131 Self: Sized,
132 {
133 let _ = VisitAstMut::visit(&mut DynVisitor::new_mut::<T>(f), self);
134 }
135}
136
137impl<K: AstVisitable + Hash + Eq, T: AstVisitable> AstVisitable for SeqHashMap<K, T> {
139 fn drive<V: VisitAst>(&self, v: &mut V) -> ControlFlow<V::Break> {
140 for (k, x) in self {
141 v.visit(k)?;
142 v.visit(x)?;
143 }
144 Continue(())
145 }
146 fn drive_mut<V: VisitAstMut>(&mut self, v: &mut V) -> ControlFlow<V::Break> {
147 for (mut k, mut x) in mem::take(self) {
148 v.visit(&mut k)?;
149 v.visit(&mut x)?;
150 self.insert(k, x);
151 }
152 Continue(())
153 }
154 fn drive_two<V: ZipAst>(&self, other: &Self, v: &mut V) -> ControlFlow<V::Break> {
155 if self.len() != other.len() {
156 return Break(Default::default());
157 }
158 for ((key, value), (other_key, other_value)) in self.iter().zip(other) {
159 v.visit(key, other_key)?;
160 v.visit(value, other_value)?;
161 }
162 Continue(())
163 }
164}
165impl<K: BodyVisitable + Hash + Eq, T: BodyVisitable> BodyVisitable for SeqHashMap<K, T> {
166 fn drive_body<V: VisitBody>(&self, v: &mut V) -> ControlFlow<V::Break> {
167 for (k, x) in self {
168 v.visit(k)?;
169 v.visit(x)?;
170 }
171 Continue(())
172 }
173 fn drive_body_mut<V: VisitBodyMut>(&mut self, v: &mut V) -> ControlFlow<V::Break> {
174 for (mut k, mut x) in mem::take(self) {
175 v.visit(&mut k)?;
176 v.visit(&mut x)?;
177 self.insert(k, x);
178 }
179 Continue(())
180 }
181}
182
183#[visitable_group(
196 visitor(drive_body(&VisitBody)),
198 visitor(drive_body_mut(&mut VisitBodyMut)),
199 skip(
201 AbortKind, BinOp, BorrowKind, BranchId, AsmOperandId, AsmTemplatePiece, BuiltinAssertKind, ConstantExpr, FieldId,
202 TypeDeclRef, FunDeclId, FunDeclRef, FnPtrKind, GenericArgs, GlobalDeclRef, IntegerTy, IntTy, UIntTy,
203 Name, NullOp, RefKind, IntegerValue, Span, Ty, TypeDeclId, UnOp, VariantId,
204 TraitRef, ScalarTy, Region, RegionId, (), String, PathBuf, bool, u32, usize,
205 DropKind, Error, Variance, WithRetag, BuiltinAdt, BuiltinPathElem, AsmKind, AsmRegister, AsmOptions, CallSafety,
206 llbc_ast::BlockId, llbc_ast::StatementId,
207 ),
208 drive(
210 Assert, InlineAsm, BorrowckStatement, PlaceKind,
211 llbc_ast::StatementKind, ullbc_ast::StatementKind,
212 ullbc_ast::TerminatorKind, SwitchData, SwitchScrutinee,
213 for<T: BodyVisitable> GExprBody<T>,
214 for<T: BodyVisitable> Box<T>,
215 for<T: BodyVisitable> Option<T>,
216 for<T: BodyVisitable, E: BodyVisitable> Result<T, E>,
217 for<A: BodyVisitable, B: BodyVisitable> (A, B),
218 for<A: BodyVisitable, B: BodyVisitable, C: BodyVisitable> (A, B, C),
219 for<T: BodyVisitable> Vec<T>,
220 for<I: Idx, T: BodyVisitable> IndexMap<I, T>,
221 for<I: Idx, T: BodyVisitable> IndexVec<I, T>,
222 ),
223 override(
226 Body, Locals, Local, LocalId,
227 AggregateKind, AsmOperand, Call, FnOperand, FnPtr,
228 Operand, Place, ProjectionElem, Rvalue,
229 llbc_block: llbc_ast::Block,
230 llbc_statement: llbc_ast::Statement,
231 ullbc_block: ullbc_ast::BlockData,
232 ullbc_statement: ullbc_ast::Statement,
233 ullbc_terminator: ullbc_ast::Terminator,
234 ullbc_block_id: ullbc_ast::BlockId,
235 )
236)]
237pub trait BodyVisitable: Any {
238 fn dyn_visit_in_body<T: BodyVisitable>(&self, f: impl FnMut(&T))
240 where
241 Self: Sized,
242 {
243 let _ = VisitBody::visit(&mut DynVisitor::new_shared::<T>(f), self);
244 }
245
246 fn dyn_visit_in_body_mut<T: BodyVisitable>(&mut self, f: impl FnMut(&mut T))
248 where
249 Self: Sized,
250 {
251 let _ = VisitBodyMut::visit(&mut DynVisitor::new_mut::<T>(f), self);
252 }
253}
254
255#[derive(Visitor)]
258pub struct DynVisitor<F> {
259 enter: F,
260}
261impl DynVisitor<()> {
262 pub fn new_shared<T: Any>(mut f: impl FnMut(&T)) -> DynVisitor<impl FnMut(&dyn Any)> {
263 let enter = move |x: &dyn Any| {
264 if let Some(x) = x.downcast_ref::<T>() {
265 f(x);
266 }
267 };
268 DynVisitor { enter }
269 }
270 pub fn new_mut<T: Any>(mut f: impl FnMut(&mut T)) -> DynVisitor<impl FnMut(&mut dyn Any)> {
271 let enter = move |x: &mut dyn Any| {
272 if let Some(x) = x.downcast_mut::<T>() {
273 f(x);
274 }
275 };
276 DynVisitor { enter }
277 }
278}
279impl<F> VisitAst for DynVisitor<F>
280where
281 F: FnMut(&dyn Any),
282{
283 fn visit<T: AstVisitable>(&mut self, x: &T) -> ControlFlow<Self::Break> {
284 (self.enter)(x);
285 x.drive(self)?;
286 Continue(())
287 }
288}
289impl<F> VisitAstMut for DynVisitor<F>
290where
291 F: FnMut(&mut dyn Any),
292{
293 fn visit<T: AstVisitable>(&mut self, x: &mut T) -> ControlFlow<Self::Break> {
294 (self.enter)(x);
295 x.drive_mut(self)?;
296 Continue(())
297 }
298}
299impl<F> VisitBody for DynVisitor<F>
300where
301 F: FnMut(&dyn Any),
302{
303 fn visit<T: BodyVisitable>(&mut self, x: &T) -> ControlFlow<Self::Break> {
304 (self.enter)(x);
305 x.drive_body(self)?;
306 Continue(())
307 }
308}
309impl<F> VisitBodyMut for DynVisitor<F>
310where
311 F: FnMut(&mut dyn Any),
312{
313 fn visit<T: BodyVisitable>(&mut self, x: &mut T) -> ControlFlow<Self::Break> {
314 (self.enter)(x);
315 x.drive_body_mut(self)?;
316 Continue(())
317 }
318}
319
320pub use wrappers::*;
321mod wrappers {
322 use std::mem;
336
337 use crate::ast::*;
338 use derive_generic_visitor::*;
339
340 #[repr(transparent)]
346 pub struct DontLeakImplDetails<V>(V);
347
348 impl<V> DontLeakImplDetails<V> {
349 pub fn new(v: &mut V) -> &mut Self {
350 unsafe { std::mem::transmute(v) }
352 }
353 pub fn inner(&mut self) -> &mut V {
354 unsafe { std::mem::transmute(self) }
356 }
357 }
358
359 impl<V: Visitor> Visitor for DontLeakImplDetails<V> {
360 type Break = V::Break;
361 }
362 impl<V: VisitAst> VisitAst for DontLeakImplDetails<V> {
363 fn visit_inner<T>(&mut self, x: &T) -> ControlFlow<Self::Break>
365 where
366 T: AstVisitable,
367 {
368 x.drive(self.inner())
369 }
370 }
371 impl<V: VisitAstMut> VisitAstMut for DontLeakImplDetails<V> {
372 fn visit_inner<T>(&mut self, x: &mut T) -> ControlFlow<Self::Break>
374 where
375 T: AstVisitable,
376 {
377 x.drive_mut(self.inner())
378 }
379 }
380
381 #[repr(transparent)]
392 pub struct VisitWithBinderDepth<V>(V);
393
394 impl<V: VisitorWithBinderDepth> VisitWithBinderDepth<V> {
395 pub fn new(v: &mut V) -> &mut Self {
396 unsafe { std::mem::transmute(v) }
398 }
399 pub fn inner(&mut self) -> &mut V {
400 unsafe { std::mem::transmute(self) }
402 }
403 }
404
405 pub trait VisitorWithBinderDepth {
406 fn binder_depth_mut(&mut self) -> &mut DeBruijnId;
407 }
408
409 impl<V: Visitor> Visitor for VisitWithBinderDepth<V> {
410 type Break = V::Break;
411 }
412 impl<V: VisitAst + VisitorWithBinderDepth> VisitAst for VisitWithBinderDepth<V> {
413 fn visit_inner<T>(&mut self, x: &T) -> ControlFlow<Self::Break>
414 where
415 T: AstVisitable,
416 {
417 x.drive(self.inner())
418 }
419 fn enter_region_binder<T: AstVisitable>(&mut self, _: &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, _: &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, _: &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, _: &Binder<T>) {
432 let binder_depth = self.0.binder_depth_mut();
433 *binder_depth = binder_depth.decr()
434 }
435 }
436 impl<V: VisitAstMut + VisitorWithBinderDepth> VisitAstMut for VisitWithBinderDepth<V> {
437 fn visit_inner<T>(&mut self, x: &mut T) -> ControlFlow<Self::Break>
438 where
439 T: AstVisitable,
440 {
441 x.drive_mut(self.inner())
442 }
443 fn enter_region_binder<T: AstVisitable>(&mut self, _: &mut RegionBinder<T>) {
444 let binder_depth = self.0.binder_depth_mut();
445 *binder_depth = binder_depth.incr()
446 }
447 fn exit_region_binder<T: AstVisitable>(&mut self, _: &mut RegionBinder<T>) {
448 let binder_depth = self.0.binder_depth_mut();
449 *binder_depth = binder_depth.decr()
450 }
451 fn enter_binder<T: AstVisitable>(&mut self, _: &mut Binder<T>) {
452 let binder_depth = self.0.binder_depth_mut();
453 *binder_depth = binder_depth.incr()
454 }
455 fn exit_binder<T: AstVisitable>(&mut self, _: &mut Binder<T>) {
456 let binder_depth = self.0.binder_depth_mut();
457 *binder_depth = binder_depth.decr()
458 }
459 }
460
461 pub struct VisitWithVariance<'a, 'ctx, V> {
464 inner: &'a mut V,
465 krate: &'ctx TranslatedCrate,
466 }
467
468 impl<'a, 'ctx, V: VisitorWithVariance> VisitWithVariance<'a, 'ctx, V> {
469 pub fn new(inner: &'a mut V, krate: &'ctx TranslatedCrate) -> Self {
470 Self { inner, krate }
471 }
472
473 fn compose(outer: Variance, inner: Variance) -> Variance {
474 match (outer, inner) {
475 (Variance::Unknown, _) | (_, Variance::Unknown) => Variance::Unknown,
476 (Variance::Bivariant, _) | (_, Variance::Bivariant) => Variance::Bivariant,
477 (Variance::Invariant, _) | (_, Variance::Invariant) => Variance::Invariant,
478 (Variance::Covariant, variance) => variance,
479 (Variance::Contravariant, Variance::Covariant) => Variance::Contravariant,
480 (Variance::Contravariant, Variance::Contravariant) => Variance::Covariant,
481 }
482 }
483 }
484
485 pub trait VisitorWithVariance {
486 fn ambient_variance_mut(&mut self) -> &mut Variance;
487 }
488
489 impl<V: Visitor> Visitor for VisitWithVariance<'_, '_, V> {
490 type Break = V::Break;
491 }
492
493 impl<V: VisitAst + VisitorWithVariance> VisitWithVariance<'_, '_, V> {
494 fn with(
495 &mut self,
496 variance: Variance,
497 f: impl FnOnce(&mut Self) -> ControlFlow<V::Break>,
498 ) -> ControlFlow<V::Break> {
499 let old = *self.inner.ambient_variance_mut();
500 *self.inner.ambient_variance_mut() = Self::compose(old, variance);
501 let result = f(self);
502 *self.inner.ambient_variance_mut() = old;
503 result
504 }
505
506 fn visit_with<T: AstVisitable>(
507 &mut self,
508 variance: Variance,
509 value: &T,
510 ) -> ControlFlow<V::Break> {
511 self.with(variance, |this| this.visit(value))
512 }
513
514 fn visit_inner_with(&mut self, variance: Variance, ty: &Ty) -> ControlFlow<V::Break> {
515 self.with(variance, |this| this.visit_inner(ty))
516 }
517 }
518
519 impl<V: VisitAst + VisitorWithVariance> VisitAst for VisitWithVariance<'_, '_, V> {
520 fn visit_inner<T: AstVisitable>(&mut self, value: &T) -> ControlFlow<Self::Break> {
521 value.drive(self.inner)
522 }
523
524 fn visit_ty(&mut self, ty: &Ty) -> ControlFlow<Self::Break> {
525 match ty.kind() {
526 TyKind::Ref(region, inner, kind) => {
527 self.visit(region)?;
528 match kind {
529 RefKind::Shared => self.visit(inner)?,
530 RefKind::Mut => self.visit_with(Variance::Invariant, inner)?,
531 }
532 }
533 TyKind::RawPtr(inner, RefKind::Shared) => self.visit(inner)?,
534 TyKind::RawPtr(inner, RefKind::Mut) => {
535 self.visit_with(Variance::Invariant, inner)?;
536 }
537 TyKind::FnPtr(..)
538 | TyKind::Adt(..)
539 | TyKind::Array(..)
540 | TyKind::Slice(..)
541 | TyKind::Pattern(..) => {
542 self.visit_inner(ty)?;
543 }
544 TyKind::TraitType(..)
545 | TyKind::DynTrait(..)
546 | TyKind::FnDef(..)
547 | TyKind::PtrMetadata(..) => {
548 self.visit_inner_with(Variance::Invariant, ty)?;
549 }
550 TyKind::TypeVar(..) | TyKind::Scalar(..) | TyKind::Never | TyKind::Error(..) => {}
551 }
552 Continue(())
553 }
554
555 fn visit_fun_sig(&mut self, sig: &FunSig) -> ControlFlow<Self::Break> {
556 for input in &sig.inputs {
557 self.visit_with(Variance::Contravariant, input)?;
558 }
559 self.visit(&sig.output)?;
560 Continue(())
561 }
562
563 fn visit_type_decl_ref(&mut self, type_ref: &TypeDeclRef) -> ControlFlow<Self::Break> {
564 if let Some(decl) = self.krate.type_decls.get(type_ref.id) {
565 let params = &decl.generics;
566 for (param, region) in params.regions.iter().zip(&type_ref.generics.regions) {
567 self.visit_with(param.variance, region)?;
568 }
569 for (param, ty) in params.types.iter().zip(&type_ref.generics.types) {
570 self.visit_with(param.variance, ty)?;
571 }
572 } else {
573 self.visit_with(Variance::Covariant, &type_ref.generics.regions)?;
574 self.visit_with(Variance::Covariant, &type_ref.generics.types)?;
575 }
576 Continue(())
577 }
578 }
579
580 #[repr(transparent)]
582 pub struct VisitWithItem<V>(V);
583
584 impl<V> VisitWithItem<V> {
585 pub fn new(v: &mut V) -> &mut Self {
586 unsafe { std::mem::transmute(v) }
588 }
589 pub fn inner(&mut self) -> &mut V {
590 unsafe { std::mem::transmute(self) }
592 }
593 }
594
595 pub trait VisitorWithItem: VisitAst {
596 fn enter_item(&mut self, _item: ItemRef<'_>) {}
597 fn exit_item(&mut self, _item: ItemRef<'_>) {}
598 fn visit_item(&mut self, item: ItemRef<'_>) -> ControlFlow<Self::Break> {
599 self.enter_item(item);
600 item.drive(self)?;
601 self.exit_item(item);
602 Continue(())
603 }
604 }
605 pub trait VisitorWithItemMut: VisitAstMut {
606 fn enter_item(&mut self, _item: ItemRefMut<'_>) {}
607 fn exit_item(&mut self, _item: ItemRefMut<'_>) {}
608 fn visit_item(&mut self, mut item: ItemRefMut<'_>) -> ControlFlow<Self::Break> {
609 self.enter_item(item.reborrow());
610 item.drive_mut(self)?;
611 self.exit_item(item);
612 Continue(())
613 }
614 }
615
616 impl<V: Visitor> Visitor for VisitWithItem<V> {
617 type Break = V::Break;
618 }
619 impl<V: VisitAst + VisitorWithItem> VisitAst for VisitWithItem<V> {
620 fn visit_inner<T>(&mut self, x: &T) -> ControlFlow<Self::Break>
621 where
622 T: AstVisitable,
623 {
624 x.drive(self.inner())
625 }
626 fn visit_fun_decl(&mut self, x: &FunDecl) -> ControlFlow<Self::Break> {
627 self.0.visit_item(ItemRef::Fun(x))
628 }
629 fn visit_type_decl(&mut self, x: &TypeDecl) -> ControlFlow<Self::Break> {
630 self.0.visit_item(ItemRef::Type(x))
631 }
632 fn visit_global_decl(&mut self, x: &GlobalDecl) -> ControlFlow<Self::Break> {
633 self.0.visit_item(ItemRef::Global(x))
634 }
635 fn visit_trait_decl(&mut self, x: &TraitDecl) -> ControlFlow<Self::Break> {
636 self.0.visit_item(ItemRef::TraitDecl(x))
637 }
638 fn visit_trait_impl(&mut self, x: &TraitImpl) -> ControlFlow<Self::Break> {
639 self.0.visit_item(ItemRef::TraitImpl(x))
640 }
641 }
642 impl<V: VisitAstMut + VisitorWithItemMut> VisitAstMut for VisitWithItem<V> {
643 fn visit_inner<T>(&mut self, x: &mut T) -> ControlFlow<Self::Break>
644 where
645 T: AstVisitable,
646 {
647 x.drive_mut(self.inner())
648 }
649 fn visit_fun_decl(&mut self, x: &mut FunDecl) -> ControlFlow<Self::Break> {
650 self.0.visit_item(ItemRefMut::Fun(x))
651 }
652 fn visit_type_decl(&mut self, x: &mut TypeDecl) -> ControlFlow<Self::Break> {
653 self.0.visit_item(ItemRefMut::Type(x))
654 }
655 fn visit_global_decl(&mut self, x: &mut GlobalDecl) -> ControlFlow<Self::Break> {
656 self.0.visit_item(ItemRefMut::Global(x))
657 }
658 fn visit_trait_decl(&mut self, x: &mut TraitDecl) -> ControlFlow<Self::Break> {
659 self.0.visit_item(ItemRefMut::TraitDecl(x))
660 }
661 fn visit_trait_impl(&mut self, x: &mut TraitImpl) -> ControlFlow<Self::Break> {
662 self.0.visit_item(ItemRefMut::TraitImpl(x))
663 }
664 }
665
666 #[repr(transparent)]
668 pub struct VisitWithItemRef<V>(V);
669
670 impl<V> VisitWithItemRef<V> {
671 pub fn new(v: &mut V) -> &mut Self {
672 unsafe { std::mem::transmute(v) }
674 }
675 pub fn inner(&mut self) -> &mut V {
676 unsafe { std::mem::transmute(self) }
678 }
679 }
680
681 pub trait VisitorWithItemRef: VisitAst {
682 fn enter_item_ref(&mut self, _item_id: ItemId, _args: &GenericArgs) {}
683 fn exit_item_ref(&mut self, _item_id: ItemId, _args: &GenericArgs) {}
684 fn visit_item_ref(
685 &mut self,
686 item_id: ItemId,
687 args: &GenericArgs,
688 ) -> ControlFlow<Self::Break> {
689 self.enter_item_ref(item_id, args);
690 self.visit_inner(args)?;
691 self.exit_item_ref(item_id, args);
692 Continue(())
693 }
694 }
695 pub trait VisitorWithItemRefMut: VisitAstMut {
696 fn enter_item_ref(&mut self, _item_id: ItemId, _args: &mut GenericArgs) {}
697 fn exit_item_ref(&mut self, _item_id: ItemId, _args: &mut GenericArgs) {}
698 fn visit_item_ref(
699 &mut self,
700 item_id: ItemId,
701 args: &mut GenericArgs,
702 ) -> ControlFlow<Self::Break> {
703 self.enter_item_ref(item_id, args);
704 self.visit_inner(args)?;
705 self.exit_item_ref(item_id, args);
706 Continue(())
707 }
708 }
709
710 impl<V: Visitor> Visitor for VisitWithItemRef<V> {
711 type Break = V::Break;
712 }
713 impl<V: VisitAst + VisitorWithItemRef> VisitAst for VisitWithItemRef<V> {
714 fn visit_inner<T>(&mut self, x: &T) -> ControlFlow<Self::Break>
715 where
716 T: AstVisitable,
717 {
718 x.drive(self.inner())
719 }
720 fn visit_type_decl_ref(&mut self, x: &TypeDeclRef) -> ControlFlow<Self::Break> {
721 self.0.visit_item_ref(ItemId::Type(x.id), &x.generics)
722 }
723 fn visit_fun_decl_ref(&mut self, x: &FunDeclRef) -> ControlFlow<Self::Break> {
724 self.0.visit_item_ref(ItemId::Fun(x.id), &x.generics)
725 }
726 fn visit_global_decl_ref(&mut self, x: &GlobalDeclRef) -> ControlFlow<Self::Break> {
727 self.0.visit_item_ref(ItemId::Global(x.id), &x.generics)
728 }
729 fn visit_trait_decl_ref(&mut self, x: &TraitDeclRef) -> ControlFlow<Self::Break> {
730 self.0.visit_item_ref(ItemId::TraitDecl(x.id), &x.generics)
731 }
732 fn visit_trait_impl_ref(&mut self, x: &TraitImplRef) -> ControlFlow<Self::Break> {
733 self.0.visit_item_ref(ItemId::TraitImpl(x.id), &x.generics)
734 }
735 fn visit_fn_ptr(&mut self, x: &FnPtr) -> ControlFlow<Self::Break> {
736 match x.kind.as_ref() {
737 FnPtrKind::Fun(id) => self.0.visit_item_ref(ItemId::Fun(*id), &x.generics),
738 FnPtrKind::Trait(..) => self.visit_inner(x),
739 }
740 }
741 }
742 impl<V: VisitAstMut + VisitorWithItemRefMut> VisitAstMut for VisitWithItemRef<V> {
743 fn visit_inner<T>(&mut self, x: &mut T) -> ControlFlow<Self::Break>
744 where
745 T: AstVisitable,
746 {
747 x.drive_mut(self.inner())
748 }
749 fn visit_type_decl_ref(&mut self, x: &mut TypeDeclRef) -> ControlFlow<Self::Break> {
750 self.0.visit_item_ref(ItemId::Type(x.id), &mut x.generics)
751 }
752 fn visit_fun_decl_ref(&mut self, x: &mut FunDeclRef) -> ControlFlow<Self::Break> {
753 self.0.visit_item_ref(ItemId::Fun(x.id), &mut x.generics)
754 }
755 fn visit_global_decl_ref(&mut self, x: &mut GlobalDeclRef) -> ControlFlow<Self::Break> {
756 self.0.visit_item_ref(ItemId::Global(x.id), &mut x.generics)
757 }
758 fn visit_trait_decl_ref(&mut self, x: &mut TraitDeclRef) -> ControlFlow<Self::Break> {
759 self.0
760 .visit_item_ref(ItemId::TraitDecl(x.id), &mut x.generics)
761 }
762 fn visit_trait_impl_ref(&mut self, x: &mut TraitImplRef) -> ControlFlow<Self::Break> {
763 self.0
764 .visit_item_ref(ItemId::TraitImpl(x.id), &mut x.generics)
765 }
766 fn visit_fn_ptr(&mut self, x: &mut FnPtr) -> ControlFlow<Self::Break> {
767 match x.kind.as_ref() {
768 FnPtrKind::Fun(id) => self.0.visit_item_ref(ItemId::Fun(*id), &mut x.generics),
769 FnPtrKind::Trait(..) => self.visit_inner(x),
770 }
771 }
772 }
773
774 #[repr(transparent)]
776 pub struct VisitWithBinderStack<V>(V);
777
778 impl<V: VisitorWithBinderStack> VisitWithBinderStack<V> {
779 fn wrap(v: &mut V) -> &mut Self {
781 unsafe { std::mem::transmute(v) }
783 }
784 pub fn new(v: &mut V) -> &mut VisitWithItem<DontLeakImplDetails<Self>> {
785 VisitWithItem::new(DontLeakImplDetails::new(Self::wrap(v)))
789 }
790 pub fn inner(&mut self) -> &mut V {
791 unsafe { std::mem::transmute(self) }
793 }
794 }
795
796 pub trait VisitorWithBinderStack {
797 fn binder_stack_mut(&mut self) -> &mut BindingStack<GenericParams>;
798 }
799
800 impl<V: VisitAst + VisitorWithBinderStack> VisitorWithItem
801 for DontLeakImplDetails<VisitWithBinderStack<V>>
802 {
803 fn enter_item(&mut self, item: ItemRef<'_>) {
804 self.0
805 .0
806 .binder_stack_mut()
807 .push(item.generic_params().clone());
808 }
809 fn exit_item(&mut self, _item: ItemRef<'_>) {
810 self.0.0.binder_stack_mut().pop();
811 }
812 }
813 impl<V: VisitAstMut + VisitorWithBinderStack> VisitorWithItemMut
814 for DontLeakImplDetails<VisitWithBinderStack<V>>
815 {
816 fn enter_item(&mut self, item: ItemRefMut<'_>) {
817 self.0
818 .0
819 .binder_stack_mut()
820 .push(item.as_ref().generic_params().clone());
821 }
822 fn exit_item(&mut self, _item: ItemRefMut<'_>) {
823 self.0.0.binder_stack_mut().pop();
824 }
825 }
826
827 impl<V: Visitor> Visitor for VisitWithBinderStack<V> {
828 type Break = V::Break;
829 }
830 impl<V: VisitAst + VisitorWithBinderStack> VisitAst for VisitWithBinderStack<V> {
831 fn visit_inner<T>(&mut self, x: &T) -> ControlFlow<Self::Break>
832 where
833 T: AstVisitable,
834 {
835 x.drive(self.inner())
836 }
837 fn visit_binder<T: AstVisitable>(
838 &mut self,
839 binder: &Binder<T>,
840 ) -> ControlFlow<Self::Break> {
841 self.0.binder_stack_mut().push(binder.params.clone());
842 self.visit_inner(binder)?;
843 self.0.binder_stack_mut().pop();
844 Continue(())
845 }
846 fn visit_region_binder<T: AstVisitable>(
847 &mut self,
848 binder: &RegionBinder<T>,
849 ) -> ControlFlow<Self::Break> {
850 self.0.binder_stack_mut().push(GenericParams {
851 regions: binder.regions.clone(),
852 ..Default::default()
853 });
854 self.visit_inner(binder)?;
855 self.0.binder_stack_mut().pop();
856 Continue(())
857 }
858 }
859 impl<V: VisitAstMut + VisitorWithBinderStack> VisitAstMut for VisitWithBinderStack<V> {
860 fn visit_inner<T>(&mut self, x: &mut T) -> ControlFlow<Self::Break>
861 where
862 T: AstVisitable,
863 {
864 x.drive_mut(self.inner())
865 }
866 fn visit_binder<T: AstVisitable>(
867 &mut self,
868 binder: &mut Binder<T>,
869 ) -> ControlFlow<Self::Break> {
870 self.0.binder_stack_mut().push(binder.params.clone());
871 self.visit_inner(binder)?;
872 self.0.binder_stack_mut().pop();
873 Continue(())
874 }
875 fn visit_region_binder<T: AstVisitable>(
876 &mut self,
877 binder: &mut RegionBinder<T>,
878 ) -> ControlFlow<Self::Break> {
879 self.0.binder_stack_mut().push(GenericParams {
880 regions: binder.regions.clone(),
881 ..Default::default()
882 });
883 self.visit_inner(binder)?;
884 self.0.binder_stack_mut().pop();
885 Continue(())
886 }
887 }
888
889 #[repr(transparent)]
891 pub struct VisitWithSpan<V>(V);
892
893 impl<V: VisitorWithSpan> VisitWithSpan<V> {
894 fn wrap(v: &mut V) -> &mut Self {
896 unsafe { std::mem::transmute(v) }
898 }
899 pub fn new(v: &mut V) -> &mut VisitWithItem<DontLeakImplDetails<Self>> {
900 VisitWithItem::new(DontLeakImplDetails::new(Self::wrap(v)))
904 }
905 pub fn inner(&mut self) -> &mut V {
906 unsafe { std::mem::transmute(self) }
908 }
909 }
910
911 pub trait VisitorWithSpan {
912 fn current_span(&mut self) -> &mut Span;
913 }
914
915 impl<V: VisitAst + VisitorWithSpan> VisitorWithItem for DontLeakImplDetails<VisitWithSpan<V>> {
916 fn visit_item(&mut self, item: ItemRef<'_>) -> ControlFlow<Self::Break> {
917 let old_span = mem::replace(self.0.0.current_span(), item.item_meta().span);
918 item.drive(self)?;
919 *self.0.0.current_span() = old_span;
920 Continue(())
921 }
922 }
923 impl<V: VisitAstMut + VisitorWithSpan> VisitorWithItemMut
924 for DontLeakImplDetails<VisitWithSpan<V>>
925 {
926 fn visit_item(&mut self, mut item: ItemRefMut<'_>) -> ControlFlow<Self::Break> {
927 let span = item.as_ref().item_meta().span;
928 let old_span = mem::replace(self.0.0.current_span(), span);
929 item.drive_mut(self)?;
930 *self.0.0.current_span() = old_span;
931 Continue(())
932 }
933 }
934
935 impl<V: Visitor> Visitor for VisitWithSpan<V> {
936 type Break = V::Break;
937 }
938 impl<V: VisitAst + VisitorWithSpan> VisitWithSpan<V> {
939 fn visit_inner_track_span<T>(&mut self, x: &T, span: Span) -> ControlFlow<V::Break>
940 where
941 T: AstVisitable,
942 T: for<'s> derive_generic_visitor::Drive<'s, AstVisitableWrapper<Self>>,
943 {
944 let old_span = mem::replace(self.0.current_span(), span);
945 self.visit_inner(x)?;
946 *self.0.current_span() = old_span;
947 Continue(())
948 }
949 }
950 impl<V: VisitAstMut + VisitorWithSpan> VisitWithSpan<V> {
951 fn visit_inner_mut_track_span<T>(&mut self, x: &mut T, span: Span) -> ControlFlow<V::Break>
952 where
953 T: AstVisitable,
954 T: for<'s> derive_generic_visitor::DriveMut<'s, AstVisitableWrapper<Self>>,
955 {
956 let old_span = mem::replace(self.0.current_span(), span);
957 self.visit_inner(x)?;
958 *self.0.current_span() = old_span;
959 Continue(())
960 }
961 }
962 impl<V: VisitAst + VisitorWithSpan> VisitAst for VisitWithSpan<V> {
963 fn visit_inner<T>(&mut self, x: &T) -> ControlFlow<Self::Break>
964 where
965 T: AstVisitable,
966 {
967 x.drive(self.inner())
968 }
969 fn visit_trait_param(&mut self, x: &TraitParam) -> ControlFlow<Self::Break> {
970 match x.span {
971 Some(span) => self.visit_inner_track_span(x, span),
972 None => self.visit_inner(x),
973 }
974 }
975 fn visit_ullbc_statement(&mut self, x: &ullbc_ast::Statement) -> ControlFlow<Self::Break> {
976 self.visit_inner_track_span(x, x.span)
977 }
978 fn visit_ullbc_terminator(
979 &mut self,
980 x: &ullbc_ast::Terminator,
981 ) -> ControlFlow<Self::Break> {
982 self.visit_inner_track_span(x, x.span)
983 }
984 fn visit_llbc_statement(&mut self, x: &llbc_ast::Statement) -> ControlFlow<Self::Break> {
985 self.visit_inner_track_span(x, x.span)
986 }
987 fn visit_llbc_block(&mut self, x: &llbc_ast::Block) -> ControlFlow<Self::Break> {
988 self.visit_inner_track_span(x, x.span)
989 }
990 }
991 impl<V: VisitAstMut + VisitorWithSpan> VisitAstMut for VisitWithSpan<V> {
992 fn visit_inner<T>(&mut self, x: &mut T) -> ControlFlow<Self::Break>
993 where
994 T: AstVisitable,
995 {
996 x.drive_mut(self.inner())
997 }
998 fn visit_trait_param(&mut self, x: &mut TraitParam) -> ControlFlow<Self::Break> {
999 match x.span {
1000 Some(span) => self.visit_inner_mut_track_span(x, span),
1001 None => self.visit_inner(x),
1002 }
1003 }
1004 fn visit_ullbc_statement(
1005 &mut self,
1006 x: &mut ullbc_ast::Statement,
1007 ) -> ControlFlow<Self::Break> {
1008 self.visit_inner_mut_track_span(x, x.span)
1009 }
1010 fn visit_ullbc_terminator(
1011 &mut self,
1012 x: &mut ullbc_ast::Terminator,
1013 ) -> ControlFlow<Self::Break> {
1014 self.visit_inner_mut_track_span(x, x.span)
1015 }
1016 fn visit_llbc_statement(
1017 &mut self,
1018 x: &mut llbc_ast::Statement,
1019 ) -> ControlFlow<Self::Break> {
1020 self.visit_inner_mut_track_span(x, x.span)
1021 }
1022 fn visit_llbc_block(&mut self, x: &mut llbc_ast::Block) -> ControlFlow<Self::Break> {
1023 self.visit_inner_mut_track_span(x, x.span)
1024 }
1025 }
1026
1027 impl<V: VisitorWithSpan> VisitorWithSpan for VisitWithBinderStack<V> {
1029 fn current_span(&mut self) -> &mut Span {
1030 self.0.current_span()
1031 }
1032 }
1033 impl<V: VisitorWithSpan> VisitorWithSpan for VisitWithItem<V> {
1034 fn current_span(&mut self) -> &mut Span {
1035 self.0.current_span()
1036 }
1037 }
1038 impl<V: VisitorWithSpan> VisitorWithSpan for DontLeakImplDetails<V> {
1039 fn current_span(&mut self) -> &mut Span {
1040 self.0.current_span()
1041 }
1042 }
1043 impl<V: VisitorWithBinderDepth> VisitorWithBinderDepth for VisitWithItemRef<V> {
1044 fn binder_depth_mut(&mut self) -> &mut DeBruijnId {
1045 self.0.binder_depth_mut()
1046 }
1047 }
1048}