cl-ast: Finally figure out how visit and walk are supposed to work
				
					
				
			This commit is contained in:
		| @@ -2,7 +2,11 @@ | ||||
| //! with default implementations across the entire AST | ||||
|  | ||||
| pub mod fold; | ||||
|  | ||||
| pub mod visit; | ||||
| pub mod walk; | ||||
|  | ||||
| pub use fold::Fold; | ||||
|  | ||||
| pub use visit::Visit; | ||||
| pub use walk::Walk; | ||||
|   | ||||
| @@ -3,6 +3,8 @@ | ||||
| use crate::ast::*; | ||||
| use cl_structures::span::Span; | ||||
|  | ||||
| use super::walk::Walk; | ||||
|  | ||||
| /// Immutably walks the entire AST | ||||
| /// | ||||
| /// Each method acts as a customization point. | ||||
| @@ -13,517 +15,248 @@ use cl_structures::span::Span; | ||||
| /// | ||||
| /// For all other nodes, traversal is *explicit*. | ||||
| pub trait Visit<'a>: Sized { | ||||
|     fn visit_span(&mut self, _span: &'a Span) {} | ||||
|     fn visit_mutability(&mut self, _mutable: &'a Mutability) {} | ||||
|     fn visit_visibility(&mut self, _vis: &'a Visibility) {} | ||||
|     fn visit_sym(&mut self, _name: &'a Sym) {} | ||||
|     fn visit_literal(&mut self, l: &'a Literal) { | ||||
|         or_visit_literal(self, l) | ||||
|     /// Visits a [Walker](Walk) | ||||
|     #[inline] | ||||
|     fn visit<W: Walk>(&mut self, walker: &'a W) { | ||||
|         walker.visit_in(self) | ||||
|     } | ||||
|     fn visit_bool(&mut self, _b: &'a bool) {} | ||||
|     fn visit_char(&mut self, _c: &'a char) {} | ||||
|     fn visit_int(&mut self, _i: &'a u128) {} | ||||
|     fn visit_smuggled_float(&mut self, _f: &'a u64) {} | ||||
|     fn visit_string(&mut self, _s: &'a str) {} | ||||
|     fn visit_file(&mut self, f: &'a File) { | ||||
|         let File { name: _, items } = f; | ||||
|         items.iter().for_each(|i| self.visit_item(i)); | ||||
|     } | ||||
|     fn visit_attrs(&mut self, a: &'a Attrs) { | ||||
|         let Attrs { meta } = a; | ||||
|         meta.iter().for_each(|m| self.visit_meta(m)); | ||||
|     } | ||||
|     fn visit_meta(&mut self, m: &'a Meta) { | ||||
|         let Meta { name, kind } = m; | ||||
|         self.visit_sym(name); | ||||
|         self.visit_meta_kind(kind); | ||||
|     } | ||||
|     fn visit_meta_kind(&mut self, kind: &'a MetaKind) { | ||||
|         or_visit_meta_kind(self, kind) | ||||
|     } | ||||
|     fn visit_item(&mut self, i: &'a Item) { | ||||
|         let Item { span, attrs, vis, kind } = i; | ||||
|         self.visit_span(span); | ||||
|         self.visit_attrs(attrs); | ||||
|         self.visit_visibility(vis); | ||||
|         self.visit_item_kind(kind); | ||||
|     } | ||||
|     fn visit_item_kind(&mut self, kind: &'a ItemKind) { | ||||
|         or_visit_item_kind(self, kind) | ||||
|     } | ||||
|     fn visit_generics(&mut self, gens: &'a Generics) { | ||||
|         let Generics { vars } = gens; | ||||
|         vars.iter().for_each(|name| self.visit_sym(name)); | ||||
|     } | ||||
|     fn visit_alias(&mut self, a: &'a Alias) { | ||||
|         let Alias { name, from } = a; | ||||
|         self.visit_sym(name); | ||||
|         if let Some(t) = from { | ||||
|             self.visit_ty(t) | ||||
|         } | ||||
|     } | ||||
|     fn visit_const(&mut self, c: &'a Const) { | ||||
|         let Const { name, ty, init } = c; | ||||
|         self.visit_sym(name); | ||||
|         self.visit_ty(ty); | ||||
|         self.visit_expr(init); | ||||
|     } | ||||
|     fn visit_static(&mut self, s: &'a Static) { | ||||
|         let Static { mutable, name, ty, init } = s; | ||||
|         self.visit_mutability(mutable); | ||||
|         self.visit_sym(name); | ||||
|         self.visit_ty(ty); | ||||
|         self.visit_expr(init); | ||||
|     } | ||||
|     fn visit_module(&mut self, m: &'a Module) { | ||||
|         let Module { name, file } = m; | ||||
|         self.visit_sym(name); | ||||
|         if let Some(f) = file { | ||||
|             self.visit_file(f) | ||||
|         } | ||||
|     } | ||||
|     fn visit_function(&mut self, f: &'a Function) { | ||||
|         let Function { name, gens, sign, bind, body } = f; | ||||
|         self.visit_sym(name); | ||||
|         self.visit_generics(gens); | ||||
|         self.visit_ty_fn(sign); | ||||
|         self.visit_pattern(bind); | ||||
|         if let Some(b) = body { | ||||
|             self.visit_expr(b) | ||||
|         } | ||||
|     } | ||||
|     fn visit_struct(&mut self, s: &'a Struct) { | ||||
|         let Struct { name, gens, kind } = s; | ||||
|         self.visit_sym(name); | ||||
|         self.visit_generics(gens); | ||||
|         self.visit_struct_kind(kind); | ||||
|     } | ||||
|     fn visit_struct_kind(&mut self, kind: &'a StructKind) { | ||||
|         or_visit_struct_kind(self, kind) | ||||
|     } | ||||
|     fn visit_struct_member(&mut self, m: &'a StructMember) { | ||||
|         let StructMember { vis, name, ty } = m; | ||||
|         self.visit_visibility(vis); | ||||
|         self.visit_sym(name); | ||||
|         self.visit_ty(ty); | ||||
|     } | ||||
|     fn visit_enum(&mut self, e: &'a Enum) { | ||||
|         let Enum { name, gens, variants: kind } = e; | ||||
|         self.visit_sym(name); | ||||
|         self.visit_generics(gens); | ||||
|         if let Some(variants) = kind { | ||||
|             variants.iter().for_each(|v| self.visit_variant(v)) | ||||
|         } | ||||
|     } | ||||
|     fn visit_variant(&mut self, v: &'a Variant) { | ||||
|         let Variant { name, kind } = v; | ||||
|         self.visit_sym(name); | ||||
|         self.visit_variant_kind(kind); | ||||
|     } | ||||
|     fn visit_variant_kind(&mut self, kind: &'a VariantKind) { | ||||
|         or_visit_variant_kind(self, kind) | ||||
|     } | ||||
|     fn visit_impl(&mut self, i: &'a Impl) { | ||||
|         let Impl { target, body } = i; | ||||
|         self.visit_impl_kind(target); | ||||
|         self.visit_file(body); | ||||
|     } | ||||
|     fn visit_impl_kind(&mut self, target: &'a ImplKind) { | ||||
|         or_visit_impl_kind(self, target) | ||||
|     } | ||||
|     fn visit_use(&mut self, u: &'a Use) { | ||||
|         let Use { absolute: _, tree } = u; | ||||
|         self.visit_use_tree(tree); | ||||
|     } | ||||
|     fn visit_use_tree(&mut self, tree: &'a UseTree) { | ||||
|         or_visit_use_tree(self, tree) | ||||
|     } | ||||
|     fn visit_ty(&mut self, t: &'a Ty) { | ||||
|         let Ty { span, kind } = t; | ||||
|         self.visit_span(span); | ||||
|         self.visit_ty_kind(kind); | ||||
|     } | ||||
|     fn visit_ty_kind(&mut self, kind: &'a TyKind) { | ||||
|         or_visit_ty_kind(self, kind) | ||||
|     } | ||||
|     fn visit_ty_array(&mut self, a: &'a TyArray) { | ||||
|         let TyArray { ty, count: _ } = a; | ||||
|         self.visit_ty_kind(ty); | ||||
|     } | ||||
|     fn visit_ty_slice(&mut self, s: &'a TySlice) { | ||||
|         let TySlice { ty } = s; | ||||
|         self.visit_ty_kind(ty) | ||||
|     } | ||||
|     fn visit_ty_tuple(&mut self, t: &'a TyTuple) { | ||||
|         let TyTuple { types } = t; | ||||
|         types.iter().for_each(|kind| self.visit_ty_kind(kind)) | ||||
|     } | ||||
|     fn visit_ty_ref(&mut self, t: &'a TyRef) { | ||||
|         let TyRef { mutable, count: _, to } = t; | ||||
|         self.visit_mutability(mutable); | ||||
|         self.visit_ty(to); | ||||
|     } | ||||
|     fn visit_ty_fn(&mut self, t: &'a TyFn) { | ||||
|         let TyFn { args, rety } = t; | ||||
|         self.visit_ty_kind(args); | ||||
|         if let Some(rety) = rety { | ||||
|             self.visit_ty(rety); | ||||
|         } | ||||
|     } | ||||
|     fn visit_path(&mut self, p: &'a Path) { | ||||
|         let Path { absolute: _, parts } = p; | ||||
|         parts.iter().for_each(|p| self.visit_path_part(p)) | ||||
|     } | ||||
|     fn visit_path_part(&mut self, p: &'a PathPart) { | ||||
|         match p { | ||||
|             PathPart::SuperKw => {} | ||||
|             PathPart::SelfKw => {} | ||||
|             PathPart::SelfTy => {} | ||||
|             PathPart::Ident(i) => self.visit_sym(i), | ||||
|         } | ||||
|     } | ||||
|     fn visit_stmt(&mut self, s: &'a Stmt) { | ||||
|         let Stmt { span, kind, semi } = s; | ||||
|         self.visit_span(span); | ||||
|         self.visit_stmt_kind(kind); | ||||
|         self.visit_semi(semi); | ||||
|     } | ||||
|     fn visit_stmt_kind(&mut self, kind: &'a StmtKind) { | ||||
|         or_visit_stmt_kind(self, kind) | ||||
|     } | ||||
|     fn visit_semi(&mut self, _s: &'a Semi) {} | ||||
|     fn visit_expr(&mut self, e: &'a Expr) { | ||||
|         let Expr { span, kind } = e; | ||||
|         self.visit_span(span); | ||||
|         self.visit_expr_kind(kind) | ||||
|     } | ||||
|     fn visit_expr_kind(&mut self, e: &'a ExprKind) { | ||||
|         or_visit_expr_kind(self, e) | ||||
|     } | ||||
|     fn visit_let(&mut self, l: &'a Let) { | ||||
|         let Let { mutable, name, ty, init } = l; | ||||
|         self.visit_mutability(mutable); | ||||
|         self.visit_pattern(name); | ||||
|         if let Some(ty) = ty { | ||||
|             self.visit_ty(ty); | ||||
|         } | ||||
|         if let Some(init) = init { | ||||
|             self.visit_expr(init) | ||||
|         } | ||||
|     /// Visits the children of a [Walker](Walk) | ||||
|     fn visit_children<W: Walk>(&mut self, walker: &'a W) { | ||||
|         walker.children(self) | ||||
|     } | ||||
|  | ||||
|     fn visit_pattern(&mut self, p: &'a Pattern) { | ||||
|         match p { | ||||
|             Pattern::Name(name) => self.visit_sym(name), | ||||
|             Pattern::Literal(literal) => self.visit_literal(literal), | ||||
|             Pattern::Rest(Some(name)) => self.visit_pattern(name), | ||||
|             Pattern::Rest(None) => {} | ||||
|             Pattern::Ref(mutability, pattern) => { | ||||
|                 self.visit_mutability(mutability); | ||||
|                 self.visit_pattern(pattern); | ||||
|             } | ||||
|             Pattern::RangeExc(head, tail) => { | ||||
|                 self.visit_pattern(head); | ||||
|                 self.visit_pattern(tail); | ||||
|             } | ||||
|             Pattern::RangeInc(head, tail) => { | ||||
|                 self.visit_pattern(head); | ||||
|                 self.visit_pattern(tail); | ||||
|             } | ||||
|             Pattern::Tuple(patterns) => { | ||||
|                 patterns.iter().for_each(|p| self.visit_pattern(p)); | ||||
|             } | ||||
|             Pattern::Array(patterns) => { | ||||
|                 patterns.iter().for_each(|p| self.visit_pattern(p)); | ||||
|             } | ||||
|             Pattern::Struct(path, items) => { | ||||
|                 self.visit_path(path); | ||||
|                 items.iter().for_each(|(_name, bind)| { | ||||
|                     bind.as_ref().inspect(|bind| { | ||||
|                         self.visit_pattern(bind); | ||||
|                     }); | ||||
|                 }); | ||||
|             } | ||||
|             Pattern::TupleStruct(path, items) => { | ||||
|                 self.visit_path(path); | ||||
|                 items.iter().for_each(|bind| self.visit_pattern(bind)); | ||||
|             } | ||||
|         } | ||||
|     fn visit_span(&mut self, value: &'a Span) { | ||||
|         value.children(self) | ||||
|     } | ||||
|     fn visit_mutability(&mut self, value: &'a Mutability) { | ||||
|         value.children(self) | ||||
|     } | ||||
|     fn visit_visibility(&mut self, value: &'a Visibility) { | ||||
|         value.children(self) | ||||
|     } | ||||
|     fn visit_sym(&mut self, value: &'a Sym) { | ||||
|         value.children(self) | ||||
|     } | ||||
|     fn visit_literal(&mut self, value: &'a Literal) { | ||||
|         value.children(self) | ||||
|     } | ||||
|     fn visit_bool(&mut self, value: &'a bool) { | ||||
|         value.children(self) | ||||
|     } | ||||
|     fn visit_char(&mut self, value: &'a char) { | ||||
|         value.children(self) | ||||
|     } | ||||
|     fn visit_int(&mut self, value: &'a u128) { | ||||
|         value.children(self) | ||||
|     } | ||||
|     fn visit_smuggled_float(&mut self, value: &'a u64) { | ||||
|         value.children(self) | ||||
|     } | ||||
|     fn visit_string(&mut self, value: &'a str) { | ||||
|         value.children(self) | ||||
|     } | ||||
|     fn visit_file(&mut self, value: &'a File) { | ||||
|         value.children(self) | ||||
|     } | ||||
|     fn visit_attrs(&mut self, value: &'a Attrs) { | ||||
|         value.children(self) | ||||
|     } | ||||
|     fn visit_meta(&mut self, value: &'a Meta) { | ||||
|         value.children(self) | ||||
|     } | ||||
|     fn visit_meta_kind(&mut self, value: &'a MetaKind) { | ||||
|         value.children(self) | ||||
|     } | ||||
|     fn visit_item(&mut self, value: &'a Item) { | ||||
|         value.children(self) | ||||
|     } | ||||
|     fn visit_item_kind(&mut self, value: &'a ItemKind) { | ||||
|         value.children(self) | ||||
|     } | ||||
|     fn visit_generics(&mut self, value: &'a Generics) { | ||||
|         value.children(self) | ||||
|     } | ||||
|     fn visit_alias(&mut self, value: &'a Alias) { | ||||
|         value.children(self) | ||||
|     } | ||||
|     fn visit_const(&mut self, value: &'a Const) { | ||||
|         value.children(self) | ||||
|     } | ||||
|     fn visit_static(&mut self, value: &'a Static) { | ||||
|         value.children(self) | ||||
|     } | ||||
|     fn visit_module(&mut self, value: &'a Module) { | ||||
|         value.children(self) | ||||
|     } | ||||
|     fn visit_function(&mut self, value: &'a Function) { | ||||
|         value.children(self) | ||||
|     } | ||||
|     fn visit_struct(&mut self, value: &'a Struct) { | ||||
|         value.children(self) | ||||
|     } | ||||
|     fn visit_struct_kind(&mut self, value: &'a StructKind) { | ||||
|         value.children(self) | ||||
|     } | ||||
|     fn visit_struct_member(&mut self, value: &'a StructMember) { | ||||
|         value.children(self) | ||||
|     } | ||||
|     fn visit_enum(&mut self, value: &'a Enum) { | ||||
|         value.children(self) | ||||
|     } | ||||
|     fn visit_variant(&mut self, value: &'a Variant) { | ||||
|         value.children(self) | ||||
|     } | ||||
|     fn visit_variant_kind(&mut self, value: &'a VariantKind) { | ||||
|         value.children(self) | ||||
|     } | ||||
|     fn visit_impl(&mut self, value: &'a Impl) { | ||||
|         value.children(self) | ||||
|     } | ||||
|     fn visit_impl_kind(&mut self, value: &'a ImplKind) { | ||||
|         value.children(self) | ||||
|     } | ||||
|     fn visit_use(&mut self, value: &'a Use) { | ||||
|         value.children(self) | ||||
|     } | ||||
|     fn visit_use_tree(&mut self, value: &'a UseTree) { | ||||
|         value.children(self) | ||||
|     } | ||||
|     fn visit_ty(&mut self, value: &'a Ty) { | ||||
|         value.children(self) | ||||
|     } | ||||
|     fn visit_ty_kind(&mut self, value: &'a TyKind) { | ||||
|         value.children(self) | ||||
|     } | ||||
|     fn visit_ty_array(&mut self, value: &'a TyArray) { | ||||
|         value.children(self) | ||||
|     } | ||||
|     fn visit_ty_slice(&mut self, value: &'a TySlice) { | ||||
|         value.children(self) | ||||
|     } | ||||
|     fn visit_ty_tuple(&mut self, value: &'a TyTuple) { | ||||
|         value.children(self) | ||||
|     } | ||||
|     fn visit_ty_ref(&mut self, value: &'a TyRef) { | ||||
|         value.children(self) | ||||
|     } | ||||
|     fn visit_ty_fn(&mut self, value: &'a TyFn) { | ||||
|         value.children(self) | ||||
|     } | ||||
|     fn visit_path(&mut self, value: &'a Path) { | ||||
|         value.children(self) | ||||
|     } | ||||
|     fn visit_path_part(&mut self, value: &'a PathPart) { | ||||
|         value.children(self) | ||||
|     } | ||||
|     fn visit_stmt(&mut self, value: &'a Stmt) { | ||||
|         value.children(self) | ||||
|     } | ||||
|     fn visit_stmt_kind(&mut self, value: &'a StmtKind) { | ||||
|         value.children(self) | ||||
|     } | ||||
|     fn visit_semi(&mut self, value: &'a Semi) { | ||||
|         value.children(self) | ||||
|     } | ||||
|     fn visit_expr(&mut self, value: &'a Expr) { | ||||
|         value.children(self) | ||||
|     } | ||||
|     fn visit_expr_kind(&mut self, value: &'a ExprKind) { | ||||
|         value.children(self) | ||||
|     } | ||||
|     fn visit_quote(&mut self, value: &'a Quote) { | ||||
|         value.children(self) | ||||
|     } | ||||
|     fn visit_let(&mut self, value: &'a Let) { | ||||
|         value.children(self) | ||||
|     } | ||||
|  | ||||
|     fn visit_match(&mut self, m: &'a Match) { | ||||
|         let Match { scrutinee, arms } = m; | ||||
|         self.visit_expr(scrutinee); | ||||
|         arms.iter().for_each(|arm| self.visit_match_arm(arm)); | ||||
|     fn visit_pattern(&mut self, value: &'a Pattern) { | ||||
|         value.children(self) | ||||
|     } | ||||
|  | ||||
|     fn visit_match_arm(&mut self, a: &'a MatchArm) { | ||||
|         let MatchArm(pat, expr) = a; | ||||
|         self.visit_pattern(pat); | ||||
|         self.visit_expr(expr); | ||||
|     fn visit_match(&mut self, value: &'a Match) { | ||||
|         value.children(self) | ||||
|     } | ||||
|  | ||||
|     fn visit_assign(&mut self, a: &'a Assign) { | ||||
|         let Assign { parts } = a; | ||||
|         let (head, tail) = parts.as_ref(); | ||||
|         self.visit_expr(head); | ||||
|         self.visit_expr(tail); | ||||
|     fn visit_match_arm(&mut self, value: &'a MatchArm) { | ||||
|         value.children(self) | ||||
|     } | ||||
|     fn visit_modify(&mut self, m: &'a Modify) { | ||||
|         let Modify { kind, parts } = m; | ||||
|         let (head, tail) = parts.as_ref(); | ||||
|         self.visit_modify_kind(kind); | ||||
|         self.visit_expr(head); | ||||
|         self.visit_expr(tail); | ||||
|  | ||||
|     fn visit_assign(&mut self, value: &'a Assign) { | ||||
|         value.children(self) | ||||
|     } | ||||
|     fn visit_modify_kind(&mut self, _kind: &'a ModifyKind) {} | ||||
|     fn visit_binary(&mut self, b: &'a Binary) { | ||||
|         let Binary { kind, parts } = b; | ||||
|         let (head, tail) = parts.as_ref(); | ||||
|         self.visit_binary_kind(kind); | ||||
|         self.visit_expr(head); | ||||
|         self.visit_expr(tail); | ||||
|     fn visit_modify(&mut self, value: &'a Modify) { | ||||
|         value.children(self) | ||||
|     } | ||||
|     fn visit_binary_kind(&mut self, _kind: &'a BinaryKind) {} | ||||
|     fn visit_unary(&mut self, u: &'a Unary) { | ||||
|         let Unary { kind, tail } = u; | ||||
|         self.visit_unary_kind(kind); | ||||
|         self.visit_expr(tail); | ||||
|     fn visit_modify_kind(&mut self, value: &'a ModifyKind) { | ||||
|         value.children(self) | ||||
|     } | ||||
|     fn visit_unary_kind(&mut self, _kind: &'a UnaryKind) {} | ||||
|     fn visit_cast(&mut self, cast: &'a Cast) { | ||||
|         let Cast { head, ty } = cast; | ||||
|         self.visit_expr(head); | ||||
|         self.visit_ty(ty); | ||||
|     fn visit_binary(&mut self, value: &'a Binary) { | ||||
|         value.children(self) | ||||
|     } | ||||
|     fn visit_member(&mut self, m: &'a Member) { | ||||
|         let Member { head, kind } = m; | ||||
|         self.visit_expr(head); | ||||
|         self.visit_member_kind(kind); | ||||
|     fn visit_binary_kind(&mut self, value: &'a BinaryKind) { | ||||
|         value.children(self) | ||||
|     } | ||||
|     fn visit_member_kind(&mut self, kind: &'a MemberKind) { | ||||
|         or_visit_member_kind(self, kind) | ||||
|     fn visit_unary(&mut self, value: &'a Unary) { | ||||
|         value.children(self) | ||||
|     } | ||||
|     fn visit_index(&mut self, i: &'a Index) { | ||||
|         let Index { head, indices } = i; | ||||
|         self.visit_expr(head); | ||||
|         indices.iter().for_each(|e| self.visit_expr(e)); | ||||
|     fn visit_unary_kind(&mut self, value: &'a UnaryKind) { | ||||
|         value.children(self) | ||||
|     } | ||||
|     fn visit_structor(&mut self, s: &'a Structor) { | ||||
|         let Structor { to, init } = s; | ||||
|         self.visit_path(to); | ||||
|         init.iter().for_each(|e| self.visit_fielder(e)) | ||||
|  | ||||
|     fn visit_cast(&mut self, value: &'a Cast) { | ||||
|         value.children(self) | ||||
|     } | ||||
|     fn visit_fielder(&mut self, f: &'a Fielder) { | ||||
|         let Fielder { name, init } = f; | ||||
|         self.visit_sym(name); | ||||
|         if let Some(init) = init { | ||||
|             self.visit_expr(init); | ||||
|         } | ||||
|     fn visit_member(&mut self, value: &'a Member) { | ||||
|         value.children(self) | ||||
|     } | ||||
|     fn visit_array(&mut self, a: &'a Array) { | ||||
|         let Array { values } = a; | ||||
|         values.iter().for_each(|e| self.visit_expr(e)) | ||||
|     fn visit_member_kind(&mut self, value: &'a MemberKind) { | ||||
|         value.children(self) | ||||
|     } | ||||
|     fn visit_array_rep(&mut self, a: &'a ArrayRep) { | ||||
|         let ArrayRep { value, repeat: _ } = a; | ||||
|         self.visit_expr(value); | ||||
|     fn visit_index(&mut self, value: &'a Index) { | ||||
|         value.children(self) | ||||
|     } | ||||
|     fn visit_addrof(&mut self, a: &'a AddrOf) { | ||||
|         let AddrOf { mutable, expr } = a; | ||||
|         self.visit_mutability(mutable); | ||||
|         self.visit_expr(expr); | ||||
|     fn visit_structor(&mut self, value: &'a Structor) { | ||||
|         value.children(self) | ||||
|     } | ||||
|     fn visit_block(&mut self, b: &'a Block) { | ||||
|         let Block { stmts } = b; | ||||
|         stmts.iter().for_each(|s| self.visit_stmt(s)); | ||||
|     fn visit_fielder(&mut self, value: &'a Fielder) { | ||||
|         value.children(self) | ||||
|     } | ||||
|     fn visit_group(&mut self, g: &'a Group) { | ||||
|         let Group { expr } = g; | ||||
|         self.visit_expr(expr) | ||||
|     fn visit_array(&mut self, value: &'a Array) { | ||||
|         value.children(self) | ||||
|     } | ||||
|     fn visit_tuple(&mut self, t: &'a Tuple) { | ||||
|         let Tuple { exprs } = t; | ||||
|         exprs.iter().for_each(|e| self.visit_expr(e)) | ||||
|     fn visit_array_rep(&mut self, value: &'a ArrayRep) { | ||||
|         value.children(self) | ||||
|     } | ||||
|     fn visit_while(&mut self, w: &'a While) { | ||||
|         let While { cond, pass, fail } = w; | ||||
|         self.visit_expr(cond); | ||||
|         self.visit_block(pass); | ||||
|         self.visit_else(fail); | ||||
|     fn visit_addrof(&mut self, value: &'a AddrOf) { | ||||
|         value.children(self) | ||||
|     } | ||||
|     fn visit_if(&mut self, i: &'a If) { | ||||
|         let If { cond, pass, fail } = i; | ||||
|         self.visit_expr(cond); | ||||
|         self.visit_block(pass); | ||||
|         self.visit_else(fail); | ||||
|     fn visit_block(&mut self, value: &'a Block) { | ||||
|         value.children(self) | ||||
|     } | ||||
|     fn visit_for(&mut self, f: &'a For) { | ||||
|         let For { bind, cond, pass, fail } = f; | ||||
|         self.visit_pattern(bind); | ||||
|         self.visit_expr(cond); | ||||
|         self.visit_block(pass); | ||||
|         self.visit_else(fail); | ||||
|     fn visit_group(&mut self, value: &'a Group) { | ||||
|         value.children(self) | ||||
|     } | ||||
|     fn visit_else(&mut self, e: &'a Else) { | ||||
|         let Else { body } = e; | ||||
|         if let Some(body) = body { | ||||
|             self.visit_expr(body) | ||||
|         } | ||||
|     fn visit_tuple(&mut self, value: &'a Tuple) { | ||||
|         value.children(self) | ||||
|     } | ||||
|     fn visit_break(&mut self, b: &'a Break) { | ||||
|         let Break { body } = b; | ||||
|         if let Some(body) = body { | ||||
|             self.visit_expr(body) | ||||
|         } | ||||
|     fn visit_while(&mut self, value: &'a While) { | ||||
|         value.children(self) | ||||
|     } | ||||
|     fn visit_return(&mut self, r: &'a Return) { | ||||
|         let Return { body } = r; | ||||
|         if let Some(body) = body { | ||||
|             self.visit_expr(body) | ||||
|         } | ||||
|     fn visit_if(&mut self, value: &'a If) { | ||||
|         value.children(self) | ||||
|     } | ||||
|     fn visit_for(&mut self, value: &'a For) { | ||||
|         value.children(self) | ||||
|     } | ||||
|     fn visit_else(&mut self, value: &'a Else) { | ||||
|         value.children(self) | ||||
|     } | ||||
|     fn visit_break(&mut self, value: &'a Break) { | ||||
|         value.children(self) | ||||
|     } | ||||
|     fn visit_return(&mut self, value: &'a Return) { | ||||
|         value.children(self) | ||||
|     } | ||||
|     fn visit_continue(&mut self) {} | ||||
| } | ||||
|  | ||||
| pub fn or_visit_literal<'a, V: Visit<'a>>(visitor: &mut V, l: &'a Literal) { | ||||
|     match l { | ||||
|         Literal::Bool(b) => visitor.visit_bool(b), | ||||
|         Literal::Char(c) => visitor.visit_char(c), | ||||
|         Literal::Int(i) => visitor.visit_int(i), | ||||
|         Literal::Float(f) => visitor.visit_smuggled_float(f), | ||||
|         Literal::String(s) => visitor.visit_string(s), | ||||
|     } | ||||
| } | ||||
|  | ||||
| pub fn or_visit_meta_kind<'a, V: Visit<'a>>(visitor: &mut V, kind: &'a MetaKind) { | ||||
|     match kind { | ||||
|         MetaKind::Plain => {} | ||||
|         MetaKind::Equals(l) => visitor.visit_literal(l), | ||||
|         MetaKind::Func(lits) => lits.iter().for_each(|l| visitor.visit_literal(l)), | ||||
|     } | ||||
| } | ||||
|  | ||||
| pub fn or_visit_item_kind<'a, V: Visit<'a>>(visitor: &mut V, kind: &'a ItemKind) { | ||||
|     match kind { | ||||
|         ItemKind::Module(m) => visitor.visit_module(m), | ||||
|         ItemKind::Alias(a) => visitor.visit_alias(a), | ||||
|         ItemKind::Enum(e) => visitor.visit_enum(e), | ||||
|         ItemKind::Struct(s) => visitor.visit_struct(s), | ||||
|         ItemKind::Const(c) => visitor.visit_const(c), | ||||
|         ItemKind::Static(s) => visitor.visit_static(s), | ||||
|         ItemKind::Function(f) => visitor.visit_function(f), | ||||
|         ItemKind::Impl(i) => visitor.visit_impl(i), | ||||
|         ItemKind::Use(u) => visitor.visit_use(u), | ||||
|     } | ||||
| } | ||||
|  | ||||
| pub fn or_visit_struct_kind<'a, V: Visit<'a>>(visitor: &mut V, kind: &'a StructKind) { | ||||
|     match kind { | ||||
|         StructKind::Empty => {} | ||||
|         StructKind::Tuple(ty) => ty.iter().for_each(|t| visitor.visit_ty(t)), | ||||
|         StructKind::Struct(m) => m.iter().for_each(|m| visitor.visit_struct_member(m)), | ||||
|     } | ||||
| } | ||||
|  | ||||
| pub fn or_visit_variant_kind<'a, V: Visit<'a>>(visitor: &mut V, kind: &'a VariantKind) { | ||||
|     match kind { | ||||
|         VariantKind::Plain => {} | ||||
|         VariantKind::CLike(_) => {} | ||||
|         VariantKind::Tuple(t) => visitor.visit_ty(t), | ||||
|         VariantKind::Struct(m) => m.iter().for_each(|m| visitor.visit_struct_member(m)), | ||||
|     } | ||||
| } | ||||
|  | ||||
| pub fn or_visit_impl_kind<'a, V: Visit<'a>>(visitor: &mut V, target: &'a ImplKind) { | ||||
|     match target { | ||||
|         ImplKind::Type(t) => visitor.visit_ty(t), | ||||
|         ImplKind::Trait { impl_trait, for_type } => { | ||||
|             visitor.visit_path(impl_trait); | ||||
|             visitor.visit_ty(for_type) | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| pub fn or_visit_use_tree<'a, V: Visit<'a>>(visitor: &mut V, tree: &'a UseTree) { | ||||
|     match tree { | ||||
|         UseTree::Tree(tree) => { | ||||
|             tree.iter().for_each(|tree| visitor.visit_use_tree(tree)); | ||||
|         } | ||||
|         UseTree::Path(path, rest) => { | ||||
|             visitor.visit_path_part(path); | ||||
|             visitor.visit_use_tree(rest) | ||||
|         } | ||||
|         UseTree::Alias(path, name) => { | ||||
|             visitor.visit_sym(path); | ||||
|             visitor.visit_sym(name); | ||||
|         } | ||||
|         UseTree::Name(name) => { | ||||
|             visitor.visit_sym(name); | ||||
|         } | ||||
|         UseTree::Glob => {} | ||||
|     } | ||||
| } | ||||
|  | ||||
| pub fn or_visit_ty_kind<'a, V: Visit<'a>>(visitor: &mut V, kind: &'a TyKind) { | ||||
|     match kind { | ||||
|         TyKind::Never => {} | ||||
|         TyKind::Empty => {} | ||||
|         TyKind::Infer => {} | ||||
|         TyKind::Path(p) => visitor.visit_path(p), | ||||
|         TyKind::Array(t) => visitor.visit_ty_array(t), | ||||
|         TyKind::Slice(t) => visitor.visit_ty_slice(t), | ||||
|         TyKind::Tuple(t) => visitor.visit_ty_tuple(t), | ||||
|         TyKind::Ref(t) => visitor.visit_ty_ref(t), | ||||
|         TyKind::Fn(t) => visitor.visit_ty_fn(t), | ||||
|     } | ||||
| } | ||||
|  | ||||
| pub fn or_visit_stmt_kind<'a, V: Visit<'a>>(visitor: &mut V, kind: &'a StmtKind) { | ||||
|     match kind { | ||||
|         StmtKind::Empty => {} | ||||
|         StmtKind::Item(i) => visitor.visit_item(i), | ||||
|         StmtKind::Expr(e) => visitor.visit_expr(e), | ||||
|     } | ||||
| } | ||||
|  | ||||
| pub fn or_visit_expr_kind<'a, V: Visit<'a>>(visitor: &mut V, e: &'a ExprKind) { | ||||
|     match e { | ||||
|         ExprKind::Empty => {} | ||||
|         ExprKind::Quote(_q) => {} // Quoted expressions are left unvisited | ||||
|         ExprKind::Let(l) => visitor.visit_let(l), | ||||
|         ExprKind::Match(m) => visitor.visit_match(m), | ||||
|         ExprKind::Assign(a) => visitor.visit_assign(a), | ||||
|         ExprKind::Modify(m) => visitor.visit_modify(m), | ||||
|         ExprKind::Binary(b) => visitor.visit_binary(b), | ||||
|         ExprKind::Unary(u) => visitor.visit_unary(u), | ||||
|         ExprKind::Cast(c) => visitor.visit_cast(c), | ||||
|         ExprKind::Member(m) => visitor.visit_member(m), | ||||
|         ExprKind::Index(i) => visitor.visit_index(i), | ||||
|         ExprKind::Structor(s) => visitor.visit_structor(s), | ||||
|         ExprKind::Path(p) => visitor.visit_path(p), | ||||
|         ExprKind::Literal(l) => visitor.visit_literal(l), | ||||
|         ExprKind::Array(a) => visitor.visit_array(a), | ||||
|         ExprKind::ArrayRep(a) => visitor.visit_array_rep(a), | ||||
|         ExprKind::AddrOf(a) => visitor.visit_addrof(a), | ||||
|         ExprKind::Block(b) => visitor.visit_block(b), | ||||
|         ExprKind::Group(g) => visitor.visit_group(g), | ||||
|         ExprKind::Tuple(t) => visitor.visit_tuple(t), | ||||
|         ExprKind::While(w) => visitor.visit_while(w), | ||||
|         ExprKind::If(i) => visitor.visit_if(i), | ||||
|         ExprKind::For(f) => visitor.visit_for(f), | ||||
|         ExprKind::Break(b) => visitor.visit_break(b), | ||||
|         ExprKind::Return(r) => visitor.visit_return(r), | ||||
|         ExprKind::Continue => visitor.visit_continue(), | ||||
|     } | ||||
| } | ||||
| pub fn or_visit_member_kind<'a, V: Visit<'a>>(visitor: &mut V, kind: &'a MemberKind) { | ||||
|     match kind { | ||||
|         MemberKind::Call(field, args) => { | ||||
|             visitor.visit_sym(field); | ||||
|             visitor.visit_tuple(args); | ||||
|         } | ||||
|         MemberKind::Struct(field) => visitor.visit_sym(field), | ||||
|         MemberKind::Tuple(field) => visitor.visit_literal(field), | ||||
|     } | ||||
| } | ||||
|   | ||||
							
								
								
									
										953
									
								
								compiler/cl-ast/src/ast_visitor/walk.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										953
									
								
								compiler/cl-ast/src/ast_visitor/walk.rs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,953 @@ | ||||
| //! Accepts an AST Visitor. Walks the AST, calling the visitor on each step. | ||||
|  | ||||
| use super::visit::Visit; | ||||
| use crate::ast::*; | ||||
| use cl_structures::span::Span; | ||||
|  | ||||
| /// Helps a [Visitor](Visit) walk through `Self`. | ||||
| pub trait Walk { | ||||
|     /// Calls the respective `visit_*` function in V | ||||
|     fn visit_in<'a, V: Visit<'a>>(&'a self, v: &mut V); | ||||
|  | ||||
|     #[allow(unused)] | ||||
|     /// Walks the children of self, visiting them in V | ||||
|     fn children<'a, V: Visit<'a>>(&'a self, v: &mut V) {} | ||||
| } | ||||
|  | ||||
| impl Walk for Span { | ||||
|     #[inline] | ||||
|     fn visit_in<'a, V: Visit<'a>>(&'a self, v: &mut V) { | ||||
|         v.visit_span(self); | ||||
|     } | ||||
| } | ||||
| impl Walk for Sym { | ||||
|     #[inline] | ||||
|     fn visit_in<'a, V: Visit<'a>>(&'a self, v: &mut V) { | ||||
|         v.visit_sym(self); | ||||
|     } | ||||
| } | ||||
| impl Walk for Mutability { | ||||
|     #[inline] | ||||
|     fn visit_in<'a, V: Visit<'a>>(&'a self, v: &mut V) { | ||||
|         v.visit_mutability(self); | ||||
|     } | ||||
| } | ||||
| impl Walk for Visibility { | ||||
|     #[inline] | ||||
|     fn visit_in<'a, V: Visit<'a>>(&'a self, v: &mut V) { | ||||
|         v.visit_visibility(self); | ||||
|     } | ||||
| } | ||||
| impl Walk for bool { | ||||
|     #[inline] | ||||
|     fn visit_in<'a, V: Visit<'a>>(&'a self, v: &mut V) { | ||||
|         v.visit_bool(self); | ||||
|     } | ||||
| } | ||||
| impl Walk for char { | ||||
|     #[inline] | ||||
|     fn visit_in<'a, V: Visit<'a>>(&'a self, v: &mut V) { | ||||
|         v.visit_char(self); | ||||
|     } | ||||
| } | ||||
| impl Walk for u128 { | ||||
|     #[inline] | ||||
|     fn visit_in<'a, V: Visit<'a>>(&'a self, v: &mut V) { | ||||
|         v.visit_int(self); | ||||
|     } | ||||
| } | ||||
| impl Walk for u64 { | ||||
|     #[inline] | ||||
|     fn visit_in<'a, V: Visit<'a>>(&'a self, v: &mut V) { | ||||
|         v.visit_smuggled_float(self); | ||||
|     } | ||||
| } | ||||
| impl Walk for str { | ||||
|     #[inline] | ||||
|     fn visit_in<'a, V: Visit<'a>>(&'a self, v: &mut V) { | ||||
|         v.visit_string(self); | ||||
|     } | ||||
| } | ||||
| impl Walk for Literal { | ||||
|     #[inline] | ||||
|     fn visit_in<'a, V: Visit<'a>>(&'a self, v: &mut V) { | ||||
|         v.visit_literal(self); | ||||
|     } | ||||
|     fn children<'a, V: Visit<'a>>(&'a self, v: &mut V) { | ||||
|         match self { | ||||
|             Literal::Bool(value) => value.children(v), | ||||
|             Literal::Char(value) => value.children(v), | ||||
|             Literal::Int(value) => value.children(v), | ||||
|             Literal::Float(value) => value.children(v), | ||||
|             Literal::String(value) => value.children(v), | ||||
|         }; | ||||
|     } | ||||
| } | ||||
| impl Walk for File { | ||||
|     #[inline] | ||||
|     fn visit_in<'a, V: Visit<'a>>(&'a self, v: &mut V) { | ||||
|         v.visit_file(self); | ||||
|     } | ||||
|     fn children<'a, V: Visit<'a>>(&'a self, v: &mut V) { | ||||
|         let File { name: _, items } = self; | ||||
|         items.iter().for_each(|i| v.visit_item(i)); | ||||
|     } | ||||
| } | ||||
| impl Walk for Attrs { | ||||
|     #[inline] | ||||
|     fn visit_in<'a, V: Visit<'a>>(&'a self, v: &mut V) { | ||||
|         v.visit_attrs(self); | ||||
|     } | ||||
|     fn children<'a, V: Visit<'a>>(&'a self, v: &mut V) { | ||||
|         let Attrs { meta } = self; | ||||
|         meta.children(v); | ||||
|     } | ||||
| } | ||||
| impl Walk for Meta { | ||||
|     #[inline] | ||||
|     fn visit_in<'a, V: Visit<'a>>(&'a self, v: &mut V) { | ||||
|         v.visit_meta(self); | ||||
|     } | ||||
|     fn children<'a, V: Visit<'a>>(&'a self, v: &mut V) { | ||||
|         let Meta { name, kind } = self; | ||||
|         name.visit_in(v); | ||||
|         kind.visit_in(v); | ||||
|     } | ||||
| } | ||||
| impl Walk for MetaKind { | ||||
|     #[inline] | ||||
|     fn visit_in<'a, V: Visit<'a>>(&'a self, v: &mut V) { | ||||
|         v.visit_meta_kind(self); | ||||
|     } | ||||
|     fn children<'a, V: Visit<'a>>(&'a self, v: &mut V) { | ||||
|         match self { | ||||
|             MetaKind::Plain => {} | ||||
|             MetaKind::Equals(lit) => lit.visit_in(v), | ||||
|             MetaKind::Func(lits) => lits.visit_in(v), | ||||
|         } | ||||
|     } | ||||
| } | ||||
| impl Walk for Item { | ||||
|     #[inline] | ||||
|     fn visit_in<'a, V: Visit<'a>>(&'a self, v: &mut V) { | ||||
|         v.visit_item(self); | ||||
|     } | ||||
|     fn children<'a, V: Visit<'a>>(&'a self, v: &mut V) { | ||||
|         let Item { span, attrs, vis, kind } = self; | ||||
|         span.visit_in(v); | ||||
|         attrs.visit_in(v); | ||||
|         vis.visit_in(v); | ||||
|         kind.visit_in(v); | ||||
|     } | ||||
| } | ||||
| impl Walk for ItemKind { | ||||
|     #[inline] | ||||
|     fn visit_in<'a, V: Visit<'a>>(&'a self, v: &mut V) { | ||||
|         v.visit_item_kind(self); | ||||
|     } | ||||
|     fn children<'a, V: Visit<'a>>(&'a self, v: &mut V) { | ||||
|         match self { | ||||
|             ItemKind::Module(value) => value.visit_in(v), | ||||
|             ItemKind::Alias(value) => value.visit_in(v), | ||||
|             ItemKind::Enum(value) => value.visit_in(v), | ||||
|             ItemKind::Struct(value) => value.visit_in(v), | ||||
|             ItemKind::Const(value) => value.visit_in(v), | ||||
|             ItemKind::Static(value) => value.visit_in(v), | ||||
|             ItemKind::Function(value) => value.visit_in(v), | ||||
|             ItemKind::Impl(value) => value.visit_in(v), | ||||
|             ItemKind::Use(value) => value.visit_in(v), | ||||
|         } | ||||
|     } | ||||
| } | ||||
| impl Walk for Generics { | ||||
|     #[inline] | ||||
|     fn visit_in<'a, V: Visit<'a>>(&'a self, v: &mut V) { | ||||
|         v.visit_generics(self); | ||||
|     } | ||||
|     fn children<'a, V: Visit<'a>>(&'a self, v: &mut V) { | ||||
|         let Self { vars } = self; | ||||
|         vars.visit_in(v); | ||||
|     } | ||||
| } | ||||
| impl Walk for Module { | ||||
|     #[inline] | ||||
|     fn visit_in<'a, V: Visit<'a>>(&'a self, v: &mut V) { | ||||
|         v.visit_module(self); | ||||
|     } | ||||
|     fn children<'a, V: Visit<'a>>(&'a self, v: &mut V) { | ||||
|         let Module { name, file } = self; | ||||
|         name.visit_in(v); | ||||
|         file.visit_in(v); | ||||
|     } | ||||
| } | ||||
| impl Walk for Alias { | ||||
|     #[inline] | ||||
|     fn visit_in<'a, V: Visit<'a>>(&'a self, v: &mut V) { | ||||
|         v.visit_alias(self); | ||||
|     } | ||||
|     fn children<'a, V: Visit<'a>>(&'a self, v: &mut V) { | ||||
|         let Alias { name, from } = self; | ||||
|         name.visit_in(v); | ||||
|         from.visit_in(v); | ||||
|     } | ||||
| } | ||||
| impl Walk for Const { | ||||
|     #[inline] | ||||
|     fn visit_in<'a, V: Visit<'a>>(&'a self, v: &mut V) { | ||||
|         v.visit_const(self); | ||||
|     } | ||||
|     fn children<'a, V: Visit<'a>>(&'a self, v: &mut V) { | ||||
|         let Const { name, ty, init } = self; | ||||
|         name.visit_in(v); | ||||
|         ty.visit_in(v); | ||||
|         init.visit_in(v); | ||||
|     } | ||||
| } | ||||
| impl Walk for Static { | ||||
|     #[inline] | ||||
|     fn visit_in<'a, V: Visit<'a>>(&'a self, v: &mut V) { | ||||
|         v.visit_static(self); | ||||
|     } | ||||
|     fn children<'a, V: Visit<'a>>(&'a self, v: &mut V) { | ||||
|         let Static { mutable, name, ty, init } = self; | ||||
|         mutable.visit_in(v); | ||||
|         name.visit_in(v); | ||||
|         ty.visit_in(v); | ||||
|         init.visit_in(v); | ||||
|     } | ||||
| } | ||||
| impl Walk for Function { | ||||
|     #[inline] | ||||
|     fn visit_in<'a, V: Visit<'a>>(&'a self, v: &mut V) { | ||||
|         v.visit_function(self); | ||||
|     } | ||||
|     fn children<'a, V: Visit<'a>>(&'a self, v: &mut V) { | ||||
|         let Function { name, gens, sign, bind, body } = self; | ||||
|         name.visit_in(v); | ||||
|         gens.visit_in(v); | ||||
|         sign.visit_in(v); | ||||
|         bind.visit_in(v); | ||||
|         body.visit_in(v); | ||||
|     } | ||||
| } | ||||
| impl Walk for Struct { | ||||
|     #[inline] | ||||
|     fn visit_in<'a, V: Visit<'a>>(&'a self, v: &mut V) { | ||||
|         v.visit_struct(self); | ||||
|     } | ||||
|     fn children<'a, V: Visit<'a>>(&'a self, v: &mut V) { | ||||
|         let Struct { name, gens, kind } = self; | ||||
|         name.visit_in(v); | ||||
|         gens.visit_in(v); | ||||
|         kind.visit_in(v); | ||||
|     } | ||||
| } | ||||
| impl Walk for StructKind { | ||||
|     #[inline] | ||||
|     fn visit_in<'a, V: Visit<'a>>(&'a self, v: &mut V) { | ||||
|         v.visit_struct_kind(self); | ||||
|     } | ||||
|     fn children<'a, V: Visit<'a>>(&'a self, v: &mut V) { | ||||
|         match self { | ||||
|             StructKind::Empty => {} | ||||
|             StructKind::Tuple(tys) => tys.visit_in(v), | ||||
|             StructKind::Struct(ms) => ms.visit_in(v), | ||||
|         } | ||||
|     } | ||||
| } | ||||
| impl Walk for StructMember { | ||||
|     #[inline] | ||||
|     fn visit_in<'a, V: Visit<'a>>(&'a self, v: &mut V) { | ||||
|         v.visit_struct_member(self); | ||||
|     } | ||||
|     fn children<'a, V: Visit<'a>>(&'a self, v: &mut V) { | ||||
|         let StructMember { vis, name, ty } = self; | ||||
|         vis.visit_in(v); | ||||
|         name.visit_in(v); | ||||
|         ty.visit_in(v); | ||||
|     } | ||||
| } | ||||
| impl Walk for Enum { | ||||
|     #[inline] | ||||
|     fn visit_in<'a, V: Visit<'a>>(&'a self, v: &mut V) { | ||||
|         v.visit_enum(self); | ||||
|     } | ||||
|     fn children<'a, V: Visit<'a>>(&'a self, v: &mut V) { | ||||
|         let Enum { name, gens, variants } = self; | ||||
|         name.visit_in(v); | ||||
|         gens.visit_in(v); | ||||
|         if let Some(variants) = variants { | ||||
|             variants.visit_in(v); | ||||
|         } | ||||
|     } | ||||
| } | ||||
| impl Walk for Variant { | ||||
|     #[inline] | ||||
|     fn visit_in<'a, V: Visit<'a>>(&'a self, v: &mut V) { | ||||
|         v.visit_variant(self); | ||||
|     } | ||||
|     fn children<'a, V: Visit<'a>>(&'a self, v: &mut V) { | ||||
|         let Variant { name, kind } = self; | ||||
|         name.visit_in(v); | ||||
|         kind.visit_in(v); | ||||
|     } | ||||
| } | ||||
| impl Walk for VariantKind { | ||||
|     #[inline] | ||||
|     fn visit_in<'a, V: Visit<'a>>(&'a self, v: &mut V) { | ||||
|         v.visit_variant_kind(self); | ||||
|     } | ||||
|     fn children<'a, V: Visit<'a>>(&'a self, v: &mut V) { | ||||
|         match self { | ||||
|             VariantKind::Plain => {} | ||||
|             VariantKind::CLike(_) => {} | ||||
|             VariantKind::Tuple(t) => t.visit_in(v), | ||||
|             VariantKind::Struct(m) => m.visit_in(v), | ||||
|         } | ||||
|     } | ||||
| } | ||||
| impl Walk for Impl { | ||||
|     #[inline] | ||||
|     fn visit_in<'a, V: Visit<'a>>(&'a self, v: &mut V) { | ||||
|         v.visit_impl(self); | ||||
|     } | ||||
|     fn children<'a, V: Visit<'a>>(&'a self, v: &mut V) { | ||||
|         let Impl { target, body } = self; | ||||
|         target.visit_in(v); | ||||
|         body.visit_in(v); | ||||
|     } | ||||
| } | ||||
| impl Walk for ImplKind { | ||||
|     #[inline] | ||||
|     fn visit_in<'a, V: Visit<'a>>(&'a self, v: &mut V) { | ||||
|         v.visit_impl_kind(self); | ||||
|     } | ||||
|     fn children<'a, V: Visit<'a>>(&'a self, v: &mut V) { | ||||
|         match self { | ||||
|             ImplKind::Type(t) => t.visit_in(v), | ||||
|             ImplKind::Trait { impl_trait, for_type } => { | ||||
|                 impl_trait.visit_in(v); | ||||
|                 for_type.visit_in(v); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
| impl Walk for Use { | ||||
|     #[inline] | ||||
|     fn visit_in<'a, V: Visit<'a>>(&'a self, v: &mut V) { | ||||
|         v.visit_use(self); | ||||
|     } | ||||
|     fn children<'a, V: Visit<'a>>(&'a self, v: &mut V) { | ||||
|         let Use { absolute: _, tree } = self; | ||||
|         tree.visit_in(v); | ||||
|     } | ||||
| } | ||||
| impl Walk for UseTree { | ||||
|     #[inline] | ||||
|     fn visit_in<'a, V: Visit<'a>>(&'a self, v: &mut V) { | ||||
|         v.visit_use_tree(self); | ||||
|     } | ||||
|     fn children<'a, V: Visit<'a>>(&'a self, v: &mut V) { | ||||
|         match self { | ||||
|             UseTree::Tree(tree) => tree.iter().for_each(|t| t.visit_in(v)), | ||||
|             UseTree::Path(part, tree) => { | ||||
|                 part.visit_in(v); | ||||
|                 tree.visit_in(v); | ||||
|             } | ||||
|             UseTree::Alias(from, to) => { | ||||
|                 from.visit_in(v); | ||||
|                 to.visit_in(v); | ||||
|             } | ||||
|             UseTree::Name(name) => name.visit_in(v), | ||||
|             UseTree::Glob => {} | ||||
|         } | ||||
|     } | ||||
| } | ||||
| impl Walk for Ty { | ||||
|     #[inline] | ||||
|     fn visit_in<'a, V: Visit<'a>>(&'a self, v: &mut V) { | ||||
|         v.visit_ty(self); | ||||
|     } | ||||
|     fn children<'a, V: Visit<'a>>(&'a self, v: &mut V) { | ||||
|         let Ty { span, kind } = self; | ||||
|         span.visit_in(v); | ||||
|         kind.visit_in(v); | ||||
|     } | ||||
| } | ||||
| impl Walk for TyKind { | ||||
|     #[inline] | ||||
|     fn visit_in<'a, V: Visit<'a>>(&'a self, v: &mut V) { | ||||
|         v.visit_ty_kind(self); | ||||
|     } | ||||
|     fn children<'a, V: Visit<'a>>(&'a self, v: &mut V) { | ||||
|         match self { | ||||
|             TyKind::Never => {} | ||||
|             TyKind::Empty => {} | ||||
|             TyKind::Infer => {} | ||||
|             TyKind::Path(value) => value.visit_in(v), | ||||
|             TyKind::Array(value) => value.visit_in(v), | ||||
|             TyKind::Slice(value) => value.visit_in(v), | ||||
|             TyKind::Tuple(value) => value.visit_in(v), | ||||
|             TyKind::Ref(value) => value.visit_in(v), | ||||
|             TyKind::Fn(value) => value.visit_in(v), | ||||
|         } | ||||
|     } | ||||
| } | ||||
| impl Walk for TyArray { | ||||
|     #[inline] | ||||
|     fn visit_in<'a, V: Visit<'a>>(&'a self, v: &mut V) { | ||||
|         v.visit_ty_array(self); | ||||
|     } | ||||
|     fn children<'a, V: Visit<'a>>(&'a self, v: &mut V) { | ||||
|         let TyArray { ty, count: _ } = self; | ||||
|         ty.visit_in(v); | ||||
|         // count.walk(v); // not available | ||||
|     } | ||||
| } | ||||
| impl Walk for TySlice { | ||||
|     #[inline] | ||||
|     fn visit_in<'a, V: Visit<'a>>(&'a self, v: &mut V) { | ||||
|         v.visit_ty_slice(self); | ||||
|     } | ||||
|     fn children<'a, V: Visit<'a>>(&'a self, v: &mut V) { | ||||
|         let TySlice { ty } = self; | ||||
|         ty.visit_in(v); | ||||
|     } | ||||
| } | ||||
| impl Walk for TyTuple { | ||||
|     #[inline] | ||||
|     fn visit_in<'a, V: Visit<'a>>(&'a self, v: &mut V) { | ||||
|         v.visit_ty_tuple(self); | ||||
|     } | ||||
|     fn children<'a, V: Visit<'a>>(&'a self, v: &mut V) { | ||||
|         let TyTuple { types } = self; | ||||
|         types.visit_in(v); | ||||
|     } | ||||
| } | ||||
| impl Walk for TyRef { | ||||
|     #[inline] | ||||
|     fn visit_in<'a, V: Visit<'a>>(&'a self, v: &mut V) { | ||||
|         v.visit_ty_ref(self); | ||||
|     } | ||||
|     fn children<'a, V: Visit<'a>>(&'a self, v: &mut V) { | ||||
|         let TyRef { mutable, count: _, to } = self; | ||||
|         mutable.children(v); | ||||
|         to.children(v); | ||||
|     } | ||||
| } | ||||
| impl Walk for TyFn { | ||||
|     #[inline] | ||||
|     fn visit_in<'a, V: Visit<'a>>(&'a self, v: &mut V) { | ||||
|         v.visit_ty_fn(self); | ||||
|     } | ||||
|     fn children<'a, V: Visit<'a>>(&'a self, v: &mut V) { | ||||
|         let TyFn { args, rety } = self; | ||||
|         args.visit_in(v); | ||||
|         rety.visit_in(v); | ||||
|     } | ||||
| } | ||||
| impl Walk for Path { | ||||
|     #[inline] | ||||
|     fn visit_in<'a, V: Visit<'a>>(&'a self, v: &mut V) { | ||||
|         v.visit_path(self); | ||||
|     } | ||||
|     fn children<'a, V: Visit<'a>>(&'a self, v: &mut V) { | ||||
|         let Path { absolute: _, parts } = self; | ||||
|         parts.visit_in(v); | ||||
|     } | ||||
| } | ||||
| impl Walk for PathPart { | ||||
|     #[inline] | ||||
|     fn visit_in<'a, V: Visit<'a>>(&'a self, v: &mut V) { | ||||
|         v.visit_path_part(self); | ||||
|     } | ||||
|     fn children<'a, V: Visit<'a>>(&'a self, v: &mut V) { | ||||
|         match self { | ||||
|             PathPart::SuperKw => {} | ||||
|             PathPart::SelfKw => {} | ||||
|             PathPart::SelfTy => {} | ||||
|             PathPart::Ident(sym) => sym.visit_in(v), | ||||
|         } | ||||
|     } | ||||
| } | ||||
| impl Walk for Stmt { | ||||
|     #[inline] | ||||
|     fn visit_in<'a, V: Visit<'a>>(&'a self, v: &mut V) { | ||||
|         v.visit_stmt(self); | ||||
|     } | ||||
|     fn children<'a, V: Visit<'a>>(&'a self, v: &mut V) { | ||||
|         let Stmt { span, kind, semi } = self; | ||||
|         span.visit_in(v); | ||||
|         kind.visit_in(v); | ||||
|         semi.visit_in(v); | ||||
|     } | ||||
| } | ||||
| impl Walk for StmtKind { | ||||
|     #[inline] | ||||
|     fn visit_in<'a, V: Visit<'a>>(&'a self, v: &mut V) { | ||||
|         v.visit_stmt_kind(self); | ||||
|     } | ||||
|     fn children<'a, V: Visit<'a>>(&'a self, v: &mut V) { | ||||
|         match self { | ||||
|             StmtKind::Empty => {} | ||||
|             StmtKind::Item(value) => value.visit_in(v), | ||||
|             StmtKind::Expr(value) => value.visit_in(v), | ||||
|         } | ||||
|     } | ||||
| } | ||||
| impl Walk for Semi { | ||||
|     #[inline] | ||||
|     fn visit_in<'a, V: Visit<'a>>(&'a self, v: &mut V) { | ||||
|         v.visit_semi(self); | ||||
|     } | ||||
| } | ||||
| impl Walk for Expr { | ||||
|     #[inline] | ||||
|     fn visit_in<'a, V: Visit<'a>>(&'a self, v: &mut V) { | ||||
|         v.visit_expr(self); | ||||
|     } | ||||
|     fn children<'a, V: Visit<'a>>(&'a self, v: &mut V) { | ||||
|         let Expr { span, kind } = self; | ||||
|         span.visit_in(v); | ||||
|         kind.visit_in(v); | ||||
|     } | ||||
| } | ||||
| impl Walk for ExprKind { | ||||
|     #[inline] | ||||
|     fn visit_in<'a, V: Visit<'a>>(&'a self, v: &mut V) { | ||||
|         v.visit_expr_kind(self); | ||||
|     } | ||||
|     fn children<'a, V: Visit<'a>>(&'a self, v: &mut V) { | ||||
|         match self { | ||||
|             ExprKind::Empty => {} | ||||
|             ExprKind::Quote(value) => value.visit_in(v), | ||||
|             ExprKind::Let(value) => value.visit_in(v), | ||||
|             ExprKind::Match(value) => value.visit_in(v), | ||||
|             ExprKind::Assign(value) => value.visit_in(v), | ||||
|             ExprKind::Modify(value) => value.visit_in(v), | ||||
|             ExprKind::Binary(value) => value.visit_in(v), | ||||
|             ExprKind::Unary(value) => value.visit_in(v), | ||||
|             ExprKind::Cast(value) => value.visit_in(v), | ||||
|             ExprKind::Member(value) => value.visit_in(v), | ||||
|             ExprKind::Index(value) => value.visit_in(v), | ||||
|             ExprKind::Structor(value) => value.visit_in(v), | ||||
|             ExprKind::Path(value) => value.visit_in(v), | ||||
|             ExprKind::Literal(value) => value.visit_in(v), | ||||
|             ExprKind::Array(value) => value.visit_in(v), | ||||
|             ExprKind::ArrayRep(value) => value.visit_in(v), | ||||
|             ExprKind::AddrOf(value) => value.visit_in(v), | ||||
|             ExprKind::Block(value) => value.visit_in(v), | ||||
|             ExprKind::Group(value) => value.visit_in(v), | ||||
|             ExprKind::Tuple(value) => value.visit_in(v), | ||||
|             ExprKind::While(value) => value.visit_in(v), | ||||
|             ExprKind::If(value) => value.visit_in(v), | ||||
|             ExprKind::For(value) => value.visit_in(v), | ||||
|             ExprKind::Break(value) => value.visit_in(v), | ||||
|             ExprKind::Return(value) => value.visit_in(v), | ||||
|             ExprKind::Continue => v.visit_continue(), | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| impl Walk for Tuple { | ||||
|     #[inline] | ||||
|     fn visit_in<'a, V: Visit<'a>>(&'a self, v: &mut V) { | ||||
|         v.visit_tuple(self); | ||||
|     } | ||||
|     fn children<'a, V: Visit<'a>>(&'a self, v: &mut V) { | ||||
|         let Tuple { exprs } = self; | ||||
|         exprs.visit_in(v); | ||||
|     } | ||||
| } | ||||
| impl Walk for Structor { | ||||
|     #[inline] | ||||
|     fn visit_in<'a, V: Visit<'a>>(&'a self, v: &mut V) { | ||||
|         v.visit_structor(self); | ||||
|     } | ||||
|     fn children<'a, V: Visit<'a>>(&'a self, v: &mut V) { | ||||
|         let Structor { to, init } = self; | ||||
|         to.visit_in(v); | ||||
|         init.visit_in(v); | ||||
|     } | ||||
| } | ||||
| impl Walk for Fielder { | ||||
|     #[inline] | ||||
|     fn visit_in<'a, V: Visit<'a>>(&'a self, v: &mut V) { | ||||
|         v.visit_fielder(self); | ||||
|     } | ||||
|     fn children<'a, V: Visit<'a>>(&'a self, v: &mut V) { | ||||
|         let Fielder { name, init } = self; | ||||
|         name.visit_in(v); | ||||
|         init.visit_in(v); | ||||
|     } | ||||
| } | ||||
| impl Walk for Array { | ||||
|     #[inline] | ||||
|     fn visit_in<'a, V: Visit<'a>>(&'a self, v: &mut V) { | ||||
|         v.visit_array(self); | ||||
|     } | ||||
|     fn children<'a, V: Visit<'a>>(&'a self, v: &mut V) { | ||||
|         let Array { values } = self; | ||||
|         values.visit_in(v); | ||||
|     } | ||||
| } | ||||
| impl Walk for ArrayRep { | ||||
|     #[inline] | ||||
|     fn visit_in<'a, V: Visit<'a>>(&'a self, v: &mut V) { | ||||
|         v.visit_array_rep(self); | ||||
|     } | ||||
|     fn children<'a, V: Visit<'a>>(&'a self, v: &mut V) { | ||||
|         let ArrayRep { value, repeat: _ } = self; | ||||
|         value.visit_in(v); | ||||
|         // repeat.visit_in(v) // TODO | ||||
|     } | ||||
| } | ||||
| impl Walk for AddrOf { | ||||
|     #[inline] | ||||
|     fn visit_in<'a, V: Visit<'a>>(&'a self, v: &mut V) { | ||||
|         v.visit_addrof(self); | ||||
|     } | ||||
|     fn children<'a, V: Visit<'a>>(&'a self, v: &mut V) { | ||||
|         let AddrOf { mutable, expr } = self; | ||||
|         mutable.visit_in(v); | ||||
|         expr.visit_in(v); | ||||
|     } | ||||
| } | ||||
| impl Walk for Cast { | ||||
|     #[inline] | ||||
|     fn visit_in<'a, V: Visit<'a>>(&'a self, v: &mut V) { | ||||
|         v.visit_cast(self); | ||||
|     } | ||||
|     fn children<'a, V: Visit<'a>>(&'a self, v: &mut V) { | ||||
|         let Cast { head, ty } = self; | ||||
|         head.visit_in(v); | ||||
|         ty.visit_in(v); | ||||
|     } | ||||
| } | ||||
| impl Walk for Quote { | ||||
|     #[inline] | ||||
|     fn visit_in<'a, V: Visit<'a>>(&'a self, v: &mut V) { | ||||
|         v.visit_quote(self); | ||||
|     } | ||||
|     fn children<'a, V: Visit<'a>>(&'a self, v: &mut V) { | ||||
|         let Quote { quote } = self; | ||||
|         quote.visit_in(v); | ||||
|     } | ||||
| } | ||||
| impl Walk for Group { | ||||
|     #[inline] | ||||
|     fn visit_in<'a, V: Visit<'a>>(&'a self, v: &mut V) { | ||||
|         v.visit_group(self); | ||||
|     } | ||||
|     fn children<'a, V: Visit<'a>>(&'a self, v: &mut V) { | ||||
|         let Group { expr } = self; | ||||
|         expr.visit_in(v); | ||||
|     } | ||||
| } | ||||
| impl Walk for Block { | ||||
|     #[inline] | ||||
|     fn visit_in<'a, V: Visit<'a>>(&'a self, v: &mut V) { | ||||
|         v.visit_block(self); | ||||
|     } | ||||
|     fn children<'a, V: Visit<'a>>(&'a self, v: &mut V) { | ||||
|         let Block { stmts } = self; | ||||
|         stmts.visit_in(v); | ||||
|     } | ||||
| } | ||||
| impl Walk for Assign { | ||||
|     #[inline] | ||||
|     fn visit_in<'a, V: Visit<'a>>(&'a self, v: &mut V) { | ||||
|         v.visit_assign(self); | ||||
|     } | ||||
|     fn children<'a, V: Visit<'a>>(&'a self, v: &mut V) { | ||||
|         let Assign { parts } = self; | ||||
|         parts.visit_in(v); | ||||
|     } | ||||
| } | ||||
| impl Walk for Modify { | ||||
|     #[inline] | ||||
|     fn visit_in<'a, V: Visit<'a>>(&'a self, v: &mut V) { | ||||
|         v.visit_modify(self); | ||||
|     } | ||||
|     fn children<'a, V: Visit<'a>>(&'a self, v: &mut V) { | ||||
|         let Modify { kind, parts } = self; | ||||
|         kind.visit_in(v); | ||||
|         parts.visit_in(v); | ||||
|     } | ||||
| } | ||||
| impl Walk for ModifyKind { | ||||
|     #[inline] | ||||
|     fn visit_in<'a, V: Visit<'a>>(&'a self, v: &mut V) { | ||||
|         v.visit_modify_kind(self); | ||||
|     } | ||||
| } | ||||
| impl Walk for Binary { | ||||
|     #[inline] | ||||
|     fn visit_in<'a, V: Visit<'a>>(&'a self, v: &mut V) { | ||||
|         v.visit_binary(self); | ||||
|     } | ||||
|     fn children<'a, V: Visit<'a>>(&'a self, v: &mut V) { | ||||
|         let Binary { kind, parts } = self; | ||||
|         kind.visit_in(v); | ||||
|         parts.visit_in(v); | ||||
|     } | ||||
| } | ||||
| impl Walk for BinaryKind { | ||||
|     #[inline] | ||||
|     fn visit_in<'a, V: Visit<'a>>(&'a self, v: &mut V) { | ||||
|         v.visit_binary_kind(self); | ||||
|     } | ||||
| } | ||||
| impl Walk for Unary { | ||||
|     #[inline] | ||||
|     fn visit_in<'a, V: Visit<'a>>(&'a self, v: &mut V) { | ||||
|         v.visit_unary(self); | ||||
|     } | ||||
|     fn children<'a, V: Visit<'a>>(&'a self, v: &mut V) { | ||||
|         let Unary { kind, tail } = self; | ||||
|         kind.visit_in(v); | ||||
|         tail.visit_in(v); | ||||
|     } | ||||
| } | ||||
| impl Walk for UnaryKind { | ||||
|     #[inline] | ||||
|     fn visit_in<'a, V: Visit<'a>>(&'a self, v: &mut V) { | ||||
|         v.visit_unary_kind(self); | ||||
|     } | ||||
| } | ||||
| impl Walk for Member { | ||||
|     #[inline] | ||||
|     fn visit_in<'a, V: Visit<'a>>(&'a self, v: &mut V) { | ||||
|         v.visit_member(self); | ||||
|     } | ||||
|     fn children<'a, V: Visit<'a>>(&'a self, v: &mut V) { | ||||
|         let Member { head, kind } = self; | ||||
|         head.visit_in(v); | ||||
|         kind.visit_in(v); | ||||
|     } | ||||
| } | ||||
| impl Walk for MemberKind { | ||||
|     #[inline] | ||||
|     fn visit_in<'a, V: Visit<'a>>(&'a self, v: &mut V) { | ||||
|         v.visit_member_kind(self); | ||||
|     } | ||||
|     fn children<'a, V: Visit<'a>>(&'a self, v: &mut V) { | ||||
|         match self { | ||||
|             MemberKind::Call(sym, tuple) => { | ||||
|                 sym.visit_in(v); | ||||
|                 tuple.visit_in(v); | ||||
|             } | ||||
|             MemberKind::Struct(sym) => sym.visit_in(v), | ||||
|             MemberKind::Tuple(literal) => literal.visit_in(v), | ||||
|         } | ||||
|     } | ||||
| } | ||||
| impl Walk for Index { | ||||
|     #[inline] | ||||
|     fn visit_in<'a, V: Visit<'a>>(&'a self, v: &mut V) { | ||||
|         v.visit_index(self); | ||||
|     } | ||||
|     fn children<'a, V: Visit<'a>>(&'a self, v: &mut V) { | ||||
|         let Index { head, indices } = self; | ||||
|         head.visit_in(v); | ||||
|         indices.visit_in(v); | ||||
|     } | ||||
| } | ||||
| impl Walk for Let { | ||||
|     #[inline] | ||||
|     fn visit_in<'a, V: Visit<'a>>(&'a self, v: &mut V) { | ||||
|         v.visit_let(self); | ||||
|     } | ||||
|     fn children<'a, V: Visit<'a>>(&'a self, v: &mut V) { | ||||
|         let Let { mutable, name, ty, init } = self; | ||||
|         mutable.visit_in(v); | ||||
|         name.visit_in(v); | ||||
|         ty.visit_in(v); | ||||
|         init.visit_in(v); | ||||
|     } | ||||
| } | ||||
| impl Walk for Match { | ||||
|     #[inline] | ||||
|     fn visit_in<'a, V: Visit<'a>>(&'a self, v: &mut V) { | ||||
|         v.visit_match(self); | ||||
|     } | ||||
|     fn children<'a, V: Visit<'a>>(&'a self, v: &mut V) { | ||||
|         let Match { scrutinee, arms } = self; | ||||
|         scrutinee.visit_in(v); | ||||
|         arms.visit_in(v); | ||||
|     } | ||||
| } | ||||
| impl Walk for MatchArm { | ||||
|     #[inline] | ||||
|     fn visit_in<'a, V: Visit<'a>>(&'a self, v: &mut V) { | ||||
|         v.visit_match_arm(self); | ||||
|     } | ||||
|     fn children<'a, V: Visit<'a>>(&'a self, v: &mut V) { | ||||
|         let MatchArm(pat, expr) = self; | ||||
|         pat.visit_in(v); | ||||
|         expr.visit_in(v); | ||||
|     } | ||||
| } | ||||
| impl Walk for Pattern { | ||||
|     #[inline] | ||||
|     fn visit_in<'a, V: Visit<'a>>(&'a self, v: &mut V) { | ||||
|         v.visit_pattern(self); | ||||
|     } | ||||
|     fn children<'a, V: Visit<'a>>(&'a self, v: &mut V) { | ||||
|         match self { | ||||
|             Pattern::Name(sym) => sym.visit_in(v), | ||||
|             Pattern::Literal(literal) => literal.visit_in(v), | ||||
|             Pattern::Rest(pattern) => pattern.visit_in(v), | ||||
|             Pattern::Ref(mutability, pattern) => { | ||||
|                 mutability.visit_in(v); | ||||
|                 pattern.visit_in(v); | ||||
|             } | ||||
|             Pattern::RangeExc(from, to) => { | ||||
|                 from.visit_in(v); | ||||
|                 to.visit_in(v); | ||||
|             } | ||||
|             Pattern::RangeInc(from, to) => { | ||||
|                 from.visit_in(v); | ||||
|                 to.visit_in(v); | ||||
|             } | ||||
|             Pattern::Tuple(patterns) => patterns.visit_in(v), | ||||
|             Pattern::Array(patterns) => patterns.visit_in(v), | ||||
|             Pattern::Struct(path, items) => { | ||||
|                 path.visit_in(v); | ||||
|                 items.visit_in(v); | ||||
|             } | ||||
|             Pattern::TupleStruct(path, patterns) => { | ||||
|                 path.visit_in(v); | ||||
|                 patterns.visit_in(v); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
| impl Walk for While { | ||||
|     #[inline] | ||||
|     fn visit_in<'a, V: Visit<'a>>(&'a self, v: &mut V) { | ||||
|         v.visit_while(self); | ||||
|     } | ||||
|     fn children<'a, V: Visit<'a>>(&'a self, v: &mut V) { | ||||
|         let While { cond, pass, fail } = self; | ||||
|         cond.visit_in(v); | ||||
|         pass.visit_in(v); | ||||
|         fail.visit_in(v); | ||||
|     } | ||||
| } | ||||
| impl Walk for If { | ||||
|     #[inline] | ||||
|     fn visit_in<'a, V: Visit<'a>>(&'a self, v: &mut V) { | ||||
|         v.visit_if(self); | ||||
|     } | ||||
|     fn children<'a, V: Visit<'a>>(&'a self, v: &mut V) { | ||||
|         let If { cond, pass, fail } = self; | ||||
|         cond.visit_in(v); | ||||
|         pass.visit_in(v); | ||||
|         fail.visit_in(v); | ||||
|     } | ||||
| } | ||||
| impl Walk for For { | ||||
|     #[inline] | ||||
|     fn visit_in<'a, V: Visit<'a>>(&'a self, v: &mut V) { | ||||
|         v.visit_for(self); | ||||
|     } | ||||
|     fn children<'a, V: Visit<'a>>(&'a self, v: &mut V) { | ||||
|         let For { bind, cond, pass, fail } = self; | ||||
|         bind.visit_in(v); | ||||
|         cond.visit_in(v); | ||||
|         pass.visit_in(v); | ||||
|         fail.visit_in(v); | ||||
|     } | ||||
| } | ||||
| impl Walk for Else { | ||||
|     #[inline] | ||||
|     fn visit_in<'a, V: Visit<'a>>(&'a self, v: &mut V) { | ||||
|         v.visit_else(self); | ||||
|     } | ||||
|     fn children<'a, V: Visit<'a>>(&'a self, v: &mut V) { | ||||
|         let Else { body } = self; | ||||
|         body.visit_in(v); | ||||
|     } | ||||
| } | ||||
| impl Walk for Break { | ||||
|     #[inline] | ||||
|     fn visit_in<'a, V: Visit<'a>>(&'a self, v: &mut V) { | ||||
|         v.visit_break(self); | ||||
|     } | ||||
|     fn children<'a, V: Visit<'a>>(&'a self, v: &mut V) { | ||||
|         let Break { body } = self; | ||||
|         body.visit_in(v); | ||||
|     } | ||||
| } | ||||
| impl Walk for Return { | ||||
|     #[inline] | ||||
|     fn visit_in<'a, V: Visit<'a>>(&'a self, v: &mut V) { | ||||
|         v.visit_return(self); | ||||
|     } | ||||
|     fn children<'a, V: Visit<'a>>(&'a self, v: &mut V) { | ||||
|         let Return { body } = self; | ||||
|         body.visit_in(v); | ||||
|     } | ||||
| } | ||||
|  | ||||
| // --- BLANKET IMPLEMENTATIONS | ||||
|  | ||||
| impl<T: Walk> Walk for [T] { | ||||
|     #[inline] | ||||
|     fn visit_in<'a, V: Visit<'a>>(&'a self, v: &mut V) { | ||||
|         self.iter().for_each(|value| value.visit_in(v)); | ||||
|     } | ||||
|     fn children<'a, V: Visit<'a>>(&'a self, v: &mut V) { | ||||
|         self.iter().for_each(|value| value.children(v)); | ||||
|     } | ||||
| } | ||||
|  | ||||
| impl<T: Walk> Walk for Vec<T> { | ||||
|     #[inline] | ||||
|     fn visit_in<'a, V: Visit<'a>>(&'a self, v: &mut V) { | ||||
|         self.as_slice().visit_in(v); | ||||
|     } | ||||
|  | ||||
|     fn children<'a, V: Visit<'a>>(&'a self, v: &mut V) { | ||||
|         self.as_slice().children(v); | ||||
|     } | ||||
| } | ||||
|  | ||||
| impl<A: Walk, B: Walk> Walk for (A, B) { | ||||
|     #[inline] | ||||
|     fn visit_in<'a, V: Visit<'a>>(&'a self, v: &mut V) { | ||||
|         let (a, b) = self; | ||||
|         a.visit_in(v); | ||||
|         b.visit_in(v); | ||||
|     } | ||||
|     fn children<'a, V: Visit<'a>>(&'a self, v: &mut V) { | ||||
|         let (a, b) = self; | ||||
|         a.children(v); | ||||
|         b.children(v); | ||||
|     } | ||||
| } | ||||
|  | ||||
| impl<T: Walk> Walk for Option<T> { | ||||
|     #[inline] | ||||
|     fn visit_in<'a, V: Visit<'a>>(&'a self, v: &mut V) { | ||||
|         if let Some(value) = self.as_ref() { | ||||
|             value.visit_in(v) | ||||
|         } | ||||
|     } | ||||
|     fn children<'a, V: Visit<'a>>(&'a self, v: &mut V) { | ||||
|         if let Some(value) = self { | ||||
|             value.children(v) | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| impl<T: Walk> Walk for Box<T> { | ||||
|     #[inline] | ||||
|     fn visit_in<'a, V: Visit<'a>>(&'a self, v: &mut V) { | ||||
|         self.as_ref().visit_in(v) | ||||
|     } | ||||
|     fn children<'a, V: Visit<'a>>(&'a self, v: &mut V) { | ||||
|         self.as_ref().children(v) | ||||
|     } | ||||
| } | ||||
| @@ -1,6 +1,9 @@ | ||||
| //! Collects the "Upvars" of a function at the point of its creation, allowing variable capture | ||||
| use crate::{convalue::ConValue, env::Environment}; | ||||
| use cl_ast::{Function, Let, Path, PathPart, Pattern, Sym, ast_visitor::visit::*}; | ||||
| use cl_ast::{ | ||||
|     Function, Let, Path, PathPart, Pattern, Sym, | ||||
|     ast_visitor::{visit::*, walk::Walk}, | ||||
| }; | ||||
| use std::collections::{HashMap, HashSet}; | ||||
|  | ||||
| pub fn collect_upvars(f: &Function, env: &Environment) -> super::Upvars { | ||||
| @@ -43,8 +46,7 @@ impl<'a> Visit<'a> for CollectUpvars<'_> { | ||||
|         let blacklist = self.blacklist.clone(); | ||||
|  | ||||
|         // visit the block | ||||
|         let cl_ast::Block { stmts } = b; | ||||
|         stmts.iter().for_each(|s| self.visit_stmt(s)); | ||||
|         b.children(self); | ||||
|  | ||||
|         // restore the blacklist | ||||
|         self.blacklist = blacklist; | ||||
| @@ -53,13 +55,10 @@ impl<'a> Visit<'a> for CollectUpvars<'_> { | ||||
|     fn visit_let(&mut self, l: &'a cl_ast::Let) { | ||||
|         let Let { mutable, name, ty, init } = l; | ||||
|         self.visit_mutability(mutable); | ||||
|         if let Some(ty) = ty { | ||||
|             self.visit_ty(ty); | ||||
|         } | ||||
|  | ||||
|         ty.visit_in(self); | ||||
|         // visit the initializer, which may use the bound name | ||||
|         if let Some(init) = init { | ||||
|             self.visit_expr(init) | ||||
|         } | ||||
|         init.visit_in(self); | ||||
|         // a bound name can never be an upvar | ||||
|         self.visit_pattern(name); | ||||
|     } | ||||
| @@ -67,10 +66,8 @@ impl<'a> Visit<'a> for CollectUpvars<'_> { | ||||
|     fn visit_function(&mut self, f: &'a cl_ast::Function) { | ||||
|         let Function { name: _, gens: _, sign: _, bind, body } = f; | ||||
|         // parameters can never be upvars | ||||
|         self.visit_pattern(bind); | ||||
|         if let Some(body) = body { | ||||
|             self.visit_expr(body); | ||||
|         } | ||||
|         bind.visit_in(self); | ||||
|         body.visit_in(self); | ||||
|     } | ||||
|  | ||||
|     fn visit_for(&mut self, f: &'a cl_ast::For) { | ||||
| @@ -106,35 +103,8 @@ impl<'a> Visit<'a> for CollectUpvars<'_> { | ||||
|             Pattern::Name(name) => { | ||||
|                 self.bind_name(name); | ||||
|             } | ||||
|             Pattern::Literal(literal) => self.visit_literal(literal), | ||||
|             Pattern::Rest(Some(name)) => { | ||||
|                 self.visit_pattern(name); | ||||
|             } | ||||
|             Pattern::Rest(None) => {} | ||||
|             Pattern::Ref(mutability, pattern) => { | ||||
|                 self.visit_mutability(mutability); | ||||
|                 self.visit_pattern(pattern); | ||||
|             } | ||||
|             Pattern::RangeExc(_, _) => {} | ||||
|             Pattern::RangeInc(_, _) => {} | ||||
|             Pattern::Tuple(patterns) => { | ||||
|                 patterns.iter().for_each(|p| self.visit_pattern(p)); | ||||
|             } | ||||
|             Pattern::Array(patterns) => { | ||||
|                 patterns.iter().for_each(|p| self.visit_pattern(p)); | ||||
|             } | ||||
|             Pattern::Struct(path, items) => { | ||||
|                 self.visit_path(path); | ||||
|                 items.iter().for_each(|(_name, bind)| { | ||||
|                     bind.as_ref().inspect(|bind| { | ||||
|                         self.visit_pattern(bind); | ||||
|                     }); | ||||
|                 }); | ||||
|             } | ||||
|             Pattern::TupleStruct(path, items) => { | ||||
|                 self.visit_path(path); | ||||
|                 items.iter().for_each(|bind| self.visit_pattern(bind)); | ||||
|             } | ||||
|             Pattern::RangeExc(_, _) | Pattern::RangeInc(_, _) => {} | ||||
|             _ => p.children(self), | ||||
|         } | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -33,7 +33,7 @@ impl<'t, 'a> Populator<'t, 'a> { | ||||
|  | ||||
| impl<'a> Visit<'a> for Populator<'_, 'a> { | ||||
|     fn visit_item(&mut self, i: &'a cl_ast::Item) { | ||||
|         let cl_ast::Item { span, attrs, vis, kind } = i; | ||||
|         let cl_ast::Item { span, attrs, vis: _, kind } = i; | ||||
|         // TODO: this, better, better. | ||||
|         let entry_kind = match kind { | ||||
|             ItemKind::Alias(_) => NodeKind::Type, | ||||
| @@ -53,10 +53,7 @@ impl<'a> Visit<'a> for Populator<'_, 'a> { | ||||
|         entry.inner.set_span(*span); | ||||
|         entry.inner.set_meta(&attrs.meta); | ||||
|  | ||||
|         entry.visit_span(span); | ||||
|         entry.visit_attrs(attrs); | ||||
|         entry.visit_visibility(vis); | ||||
|         entry.visit_item_kind(kind); | ||||
|         entry.visit_children(i); | ||||
|  | ||||
|         if let (Some(name), child) = (entry.name, entry.inner.id()) { | ||||
|             self.inner.add_child(name, child); | ||||
| @@ -68,9 +65,7 @@ impl<'a> Visit<'a> for Populator<'_, 'a> { | ||||
|         self.inner.set_source(Source::Alias(a)); | ||||
|         self.set_name(*name); | ||||
|  | ||||
|         if let Some(t) = from { | ||||
|             self.visit_ty(t) | ||||
|         } | ||||
|         self.visit(from); | ||||
|     } | ||||
|  | ||||
|     fn visit_const(&mut self, c: &'a cl_ast::Const) { | ||||
| @@ -79,8 +74,8 @@ impl<'a> Visit<'a> for Populator<'_, 'a> { | ||||
|         self.inner.set_body(init); | ||||
|         self.set_name(*name); | ||||
|  | ||||
|         self.visit_ty(ty); | ||||
|         self.visit_expr(init); | ||||
|         self.visit(ty); | ||||
|         self.visit(init); | ||||
|     } | ||||
|  | ||||
|     fn visit_static(&mut self, s: &'a cl_ast::Static) { | ||||
| @@ -89,9 +84,9 @@ impl<'a> Visit<'a> for Populator<'_, 'a> { | ||||
|         self.inner.set_body(init); | ||||
|         self.set_name(*name); | ||||
|  | ||||
|         self.visit_mutability(mutable); | ||||
|         self.visit_ty(ty); | ||||
|         self.visit_expr(init); | ||||
|         self.visit(mutable); | ||||
|         self.visit(ty); | ||||
|         self.visit(init); | ||||
|     } | ||||
|  | ||||
|     fn visit_module(&mut self, m: &'a cl_ast::Module) { | ||||
| @@ -99,9 +94,7 @@ impl<'a> Visit<'a> for Populator<'_, 'a> { | ||||
|         self.inner.set_source(Source::Module(m)); | ||||
|         self.set_name(*name); | ||||
|  | ||||
|         if let Some(file) = file { | ||||
|             self.visit_file(file); | ||||
|         } | ||||
|         self.visit(file); | ||||
|     } | ||||
|  | ||||
|     fn visit_function(&mut self, f: &'a cl_ast::Function) { | ||||
| @@ -110,11 +103,12 @@ impl<'a> Visit<'a> for Populator<'_, 'a> { | ||||
|         self.inner.set_source(Source::Function(f)); | ||||
|         self.set_name(*name); | ||||
|  | ||||
|         self.visit_ty_fn(sign); | ||||
|         self.visit_pattern(bind); | ||||
|         self.visit(sign); | ||||
|         self.visit(bind); | ||||
|  | ||||
|         if let Some(b) = body { | ||||
|             self.inner.set_body(b); | ||||
|             self.visit_expr(b) | ||||
|             self.visit(b); | ||||
|         } | ||||
|     } | ||||
|  | ||||
| @@ -124,7 +118,7 @@ impl<'a> Visit<'a> for Populator<'_, 'a> { | ||||
|         self.inner.set_source(Source::Struct(s)); | ||||
|         self.set_name(*name); | ||||
|  | ||||
|         self.visit_struct_kind(kind); | ||||
|         self.visit(kind); | ||||
|     } | ||||
|  | ||||
|     fn visit_enum(&mut self, e: &'a cl_ast::Enum) { | ||||
| @@ -133,9 +127,7 @@ impl<'a> Visit<'a> for Populator<'_, 'a> { | ||||
|         self.inner.set_source(Source::Enum(e)); | ||||
|         self.set_name(*name); | ||||
|  | ||||
|         if let Some(variants) = variants { | ||||
|             variants.iter().for_each(|v| self.visit_variant(v)); | ||||
|         } | ||||
|         self.visit(variants); | ||||
|     } | ||||
|  | ||||
|     fn visit_impl(&mut self, i: &'a cl_ast::Impl) { | ||||
| @@ -143,8 +135,8 @@ impl<'a> Visit<'a> for Populator<'_, 'a> { | ||||
|         self.inner.set_source(Source::Impl(i)); | ||||
|         self.inner.mark_impl_item(); | ||||
|  | ||||
|         self.visit_impl_kind(target); | ||||
|         self.visit_file(body); | ||||
|         self.visit(target); | ||||
|         self.visit(body); | ||||
|     } | ||||
|  | ||||
|     fn visit_use(&mut self, u: &'a cl_ast::Use) { | ||||
| @@ -152,6 +144,6 @@ impl<'a> Visit<'a> for Populator<'_, 'a> { | ||||
|         self.inner.set_source(Source::Use(u)); | ||||
|         self.inner.mark_use_item(); | ||||
|  | ||||
|         self.visit_use_tree(tree); | ||||
|         self.visit(tree); | ||||
|     } | ||||
| } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user