summary refs log tree commit diff
path: root/src/libsyntax
diff options
context:
space:
mode:
authorAlex Crichton <alex@alexcrichton.com>2013-05-27 22:21:29 -0500
committerAlex Crichton <alex@alexcrichton.com>2013-05-27 22:22:09 -0500
commitae7df57c5aa40a247306c887159d466922f9be7e (patch)
treebe5d3b47e33f95d774a0d9267591cc6a982bf8cc /src/libsyntax
parente6a838d05100baec0df9ae8b16b2127470a593b8 (diff)
downloadrust-ae7df57c5aa40a247306c887159d466922f9be7e.tar.gz
rust-ae7df57c5aa40a247306c887159d466922f9be7e.zip
Prevent refcount cycles during linting
Shaves off ~600MB of memory while compiling rustc
Diffstat (limited to 'src/libsyntax')
-rw-r--r--src/libsyntax/ast_util.rs109
1 files changed, 66 insertions, 43 deletions
diff --git a/src/libsyntax/ast_util.rs b/src/libsyntax/ast_util.rs
index 59743b6e892..8d5af682d62 100644
--- a/src/libsyntax/ast_util.rs
+++ b/src/libsyntax/ast_util.rs
@@ -386,82 +386,103 @@ pub impl id_range {
     }
 }
 
-pub fn id_visitor(vfn: @fn(node_id)) -> visit::vt<()> {
-    let visit_generics: @fn(&Generics) = |generics| {
+pub fn id_visitor<T: Copy>(vfn: @fn(node_id, T)) -> visit::vt<T> {
+    let visit_generics: @fn(&Generics, T) = |generics, t| {
         for generics.ty_params.each |p| {
-            vfn(p.id);
+            vfn(p.id, t);
         }
         for generics.lifetimes.each |p| {
-            vfn(p.id);
+            vfn(p.id, t);
         }
     };
-    visit::mk_simple_visitor(@visit::SimpleVisitor {
-        visit_mod: |_m, _sp, id| vfn(id),
+    visit::mk_vt(@visit::Visitor {
+        visit_mod: |m, sp, id, t, vt| {
+            vfn(id, t);
+            visit::visit_mod(m, sp, id, t, vt);
+        },
 
-        visit_view_item: |vi| {
+        visit_view_item: |vi, t, vt| {
             match vi.node {
-              view_item_extern_mod(_, _, id) => vfn(id),
+              view_item_extern_mod(_, _, id) => vfn(id, t),
               view_item_use(ref vps) => {
                   for vps.each |vp| {
                       match vp.node {
-                          view_path_simple(_, _, id) => vfn(id),
-                          view_path_glob(_, id) => vfn(id),
+                          view_path_simple(_, _, id) => vfn(id, t),
+                          view_path_glob(_, id) => vfn(id, t),
                           view_path_list(_, ref paths, id) => {
-                              vfn(id);
+                              vfn(id, t);
                               for paths.each |p| {
-                                  vfn(p.node.id);
+                                  vfn(p.node.id, t);
                               }
                           }
                       }
                   }
               }
             }
+            visit::visit_view_item(vi, t, vt);
         },
 
-        visit_foreign_item: |ni| vfn(ni.id),
+        visit_foreign_item: |ni, t, vt| {
+            vfn(ni.id, t);
+            visit::visit_foreign_item(ni, t, vt);
+        },
 
-        visit_item: |i| {
-            vfn(i.id);
+        visit_item: |i, t, vt| {
+            vfn(i.id, t);
             match i.node {
               item_enum(ref enum_definition, _) =>
-                for (*enum_definition).variants.each |v| { vfn(v.node.id); },
+                for (*enum_definition).variants.each |v| { vfn(v.node.id, t); },
               _ => ()
             }
+            visit::visit_item(i, t, vt);
         },
 
-        visit_local: |l| vfn(l.node.id),
-        visit_block: |b| vfn(b.node.id),
-        visit_stmt: |s| vfn(ast_util::stmt_id(s)),
-        visit_arm: |_| {},
-        visit_pat: |p| vfn(p.id),
-        visit_decl: |_| {},
-
-        visit_expr: |e| {
-            vfn(e.callee_id);
-            vfn(e.id);
+        visit_local: |l, t, vt| {
+            vfn(l.node.id, t);
+            visit::visit_local(l, t, vt);
+        },
+        visit_block: |b, t, vt| {
+            vfn(b.node.id, t);
+            visit::visit_block(b, t, vt);
+        },
+        visit_stmt: |s, t, vt| {
+            vfn(ast_util::stmt_id(s), t);
+            visit::visit_stmt(s, t, vt);
+        },
+        visit_pat: |p, t, vt| {
+            vfn(p.id, t);
+            visit::visit_pat(p, t, vt);
         },
 
-        visit_expr_post: |_| {},
+        visit_expr: |e, t, vt| {
+            vfn(e.callee_id, t);
+            vfn(e.id, t);
+            visit::visit_expr(e, t, vt);
+        },
 
-        visit_ty: |t| {
-            match t.node {
-              ty_path(_, id) => vfn(id),
+        visit_ty: |ty, t, vt| {
+            match ty.node {
+              ty_path(_, id) => vfn(id, t),
               _ => { /* fall through */ }
             }
+            visit::visit_ty(ty, t, vt);
         },
 
-        visit_generics: visit_generics,
+        visit_generics: |generics, t, vt| {
+            visit_generics(generics, t);
+            visit::visit_generics(generics, t, vt);
+        },
 
-        visit_fn: |fk, d, _, _, id| {
-            vfn(id);
+        visit_fn: |fk, d, a, b, id, t, vt| {
+            vfn(id, t);
 
             match *fk {
                 visit::fk_item_fn(_, generics, _, _) => {
-                    visit_generics(generics);
+                    visit_generics(generics, t);
                 }
                 visit::fk_method(_, generics, m) => {
-                    vfn(m.self_id);
-                    visit_generics(generics);
+                    vfn(m.self_id, t);
+                    visit_generics(generics, t);
                 }
                 visit::fk_anon(_) |
                 visit::fk_fn_block => {
@@ -469,20 +490,22 @@ pub fn id_visitor(vfn: @fn(node_id)) -> visit::vt<()> {
             }
 
             for d.inputs.each |arg| {
-                vfn(arg.id)
+                vfn(arg.id, t)
             }
+            visit::visit_fn(fk, d, a, b, id, t, vt);
+        },
+
+        visit_struct_field: |f, t, vt| {
+            vfn(f.node.id, t);
+            visit::visit_struct_field(f, t, vt);
         },
 
-        visit_ty_method: |_| {},
-        visit_trait_method: |_| {},
-        visit_struct_def: |_, _, _, _| {},
-        visit_struct_field: |f| vfn(f.node.id),
-        visit_struct_method: |_| {}
+        .. *visit::default_visitor()
     })
 }
 
 pub fn visit_ids_for_inlined_item(item: &inlined_item, vfn: @fn(node_id)) {
-    item.accept((), id_visitor(vfn));
+    item.accept((), id_visitor(|id, ()| vfn(id)));
 }
 
 pub fn compute_id_range(visit_ids_fn: &fn(@fn(node_id))) -> id_range {