about summary refs log tree commit diff
diff options
context:
space:
mode:
authorPatrick Walton <pcwalton@mimiga.net>2013-08-29 19:01:19 -0700
committerPatrick Walton <pcwalton@mimiga.net>2013-09-23 18:23:20 -0700
commit6ecbd75843a2187027d09649c9046189d1d4a446 (patch)
tree01a6b507157208617145378be4f4c1bc0d034057
parent37c32e249505f103f9bcad0bdd83f49f0efec9ef (diff)
downloadrust-6ecbd75843a2187027d09649c9046189d1d4a446.tar.gz
rust-6ecbd75843a2187027d09649c9046189d1d4a446.zip
librustc: Change the ID visitor to use traits instead of garbage-collected functions.
-rw-r--r--src/librustc/middle/astencode.rs47
-rw-r--r--src/librustc/middle/lint.rs22
-rw-r--r--src/librustc/rustc.rs2
-rw-r--r--src/libsyntax/ast_util.rs77
4 files changed, 94 insertions, 54 deletions
diff --git a/src/librustc/middle/astencode.rs b/src/librustc/middle/astencode.rs
index 6521b4bb3cc..683fbba09cc 100644
--- a/src/librustc/middle/astencode.rs
+++ b/src/librustc/middle/astencode.rs
@@ -24,6 +24,7 @@ use middle;
 use util::ppaux::ty_to_str;
 
 use std::at_vec;
+use std::libc;
 use extra::ebml::reader;
 use extra::ebml;
 use extra::serialize;
@@ -849,6 +850,26 @@ impl write_tag_and_id for writer::Encoder {
     }
 }
 
+struct SideTableEncodingIdVisitor {
+    ecx_ptr: *libc::c_void,
+    new_ebml_w: writer::Encoder,
+    maps: Maps,
+}
+
+impl ast_util::IdVisitingOperation for SideTableEncodingIdVisitor {
+    fn visit_id(&self, id: ast::NodeId) {
+        // Note: this will cause a copy of ebml_w, which is bad as
+        // it is mutable. But I believe it's harmless since we generate
+        // balanced EBML.
+        let mut new_ebml_w = self.new_ebml_w.clone();
+        // See above
+        let ecx: &e::EncodeContext = unsafe {
+            cast::transmute(self.ecx_ptr)
+        };
+        encode_side_tables_for_id(ecx, self.maps, &mut new_ebml_w, id)
+    }
+}
+
 fn encode_side_tables_for_ii(ecx: &e::EncodeContext,
                              maps: Maps,
                              ebml_w: &mut writer::Encoder,
@@ -856,22 +877,16 @@ fn encode_side_tables_for_ii(ecx: &e::EncodeContext,
     ebml_w.start_tag(c::tag_table as uint);
     let new_ebml_w = (*ebml_w).clone();
 
-    // Because the ast visitor uses @fn, I can't pass in
-    // ecx directly, but /I/ know that it'll be fine since
-    // the lifetime is tied to the CrateContext that
-    // lives this entire section.
-    let ecx_ptr : *() = unsafe { cast::transmute(ecx) };
-    ast_util::visit_ids_for_inlined_item(
-        ii,
-        |id: ast::NodeId| {
-            // Note: this will cause a copy of ebml_w, which is bad as
-            // it is mutable. But I believe it's harmless since we generate
-            // balanced EBML.
-            let mut new_ebml_w = new_ebml_w.clone();
-            // See above
-            let ecx : &e::EncodeContext = unsafe { cast::transmute(ecx_ptr) };
-            encode_side_tables_for_id(ecx, maps, &mut new_ebml_w, id)
-        });
+    // Because the ast visitor uses @IdVisitingOperation, I can't pass in
+    // ecx directly, but /I/ know that it'll be fine since the lifetime is
+    // tied to the CrateContext that lives throughout this entire section.
+    ast_util::visit_ids_for_inlined_item(ii, @SideTableEncodingIdVisitor {
+        ecx_ptr: unsafe {
+            cast::transmute(ecx)
+        },
+        new_ebml_w: new_ebml_w,
+        maps: maps,
+    } as @ast_util::IdVisitingOperation);
     ebml_w.end_tag();
 }
 
diff --git a/src/librustc/middle/lint.rs b/src/librustc/middle/lint.rs
index da181ff2eb6..c29a5159e81 100644
--- a/src/librustc/middle/lint.rs
+++ b/src/librustc/middle/lint.rs
@@ -1228,17 +1228,27 @@ fn lint_unused_mut() -> @mut OuterLint {
     @mut UnusedMutLintVisitor{ stopping_on_items: false } as @mut OuterLint
 }
 
-fn lint_session(cx: @mut Context) -> @mut visit::Visitor<()> {
-    ast_util::id_visitor(|id| {
-        match cx.tcx.sess.lints.pop(&id) {
-            None => {},
+struct LintReportingIdVisitor {
+    cx: @mut Context,
+}
+
+impl ast_util::IdVisitingOperation for LintReportingIdVisitor {
+    fn visit_id(&self, id: ast::NodeId) {
+        match self.cx.tcx.sess.lints.pop(&id) {
+            None => {}
             Some(l) => {
                 for (lint, span, msg) in l.move_iter() {
-                    cx.span_lint(lint, span, msg)
+                    self.cx.span_lint(lint, span, msg)
                 }
             }
         }
-    }, false)
+    }
+}
+
+fn lint_session(cx: @mut Context) -> @mut visit::Visitor<()> {
+    ast_util::id_visitor(@LintReportingIdVisitor {
+        cx: cx,
+    } as @ast_util::IdVisitingOperation, false)
 }
 
 struct UnnecessaryAllocationLintVisitor { stopping_on_items: bool }
diff --git a/src/librustc/rustc.rs b/src/librustc/rustc.rs
index 9fadaf82a98..f1f7a7bf2d6 100644
--- a/src/librustc/rustc.rs
+++ b/src/librustc/rustc.rs
@@ -299,7 +299,7 @@ struct RustcEmitter {
 
 impl diagnostic::Emitter for RustcEmitter {
     fn emit(&self,
-            cmsp: Option<(@codemap::CodeMap, codemap::span)>,
+            cmsp: Option<(@codemap::CodeMap, codemap::Span)>,
             msg: &str,
             lvl: diagnostic::level) {
         if lvl == diagnostic::fatal {
diff --git a/src/libsyntax/ast_util.rs b/src/libsyntax/ast_util.rs
index 2e47050ad6a..ac88fc835d5 100644
--- a/src/libsyntax/ast_util.rs
+++ b/src/libsyntax/ast_util.rs
@@ -397,18 +397,22 @@ impl id_range {
     }
 }
 
-pub fn id_visitor(vfn: @fn(NodeId), pass_through_items: bool)
+pub fn id_visitor(operation: @IdVisitingOperation, pass_through_items: bool)
                   -> @mut Visitor<()> {
     let visitor = @mut IdVisitor {
-        visit_callback: vfn,
+        operation: operation,
         pass_through_items: pass_through_items,
         visited_outermost: false,
     };
     visitor as @mut Visitor<()>
 }
 
+pub trait IdVisitingOperation {
+    fn visit_id(&self, node_id: NodeId);
+}
+
 pub struct IdVisitor {
-    visit_callback: @fn(NodeId),
+    operation: @IdVisitingOperation,
     pass_through_items: bool,
     visited_outermost: bool,
 }
@@ -416,10 +420,10 @@ pub struct IdVisitor {
 impl IdVisitor {
     fn visit_generics_helper(&self, generics: &Generics) {
         for type_parameter in generics.ty_params.iter() {
-            (self.visit_callback)(type_parameter.id)
+            self.operation.visit_id(type_parameter.id)
         }
         for lifetime in generics.lifetimes.iter() {
-            (self.visit_callback)(lifetime.id)
+            self.operation.visit_id(lifetime.id)
         }
     }
 }
@@ -430,26 +434,26 @@ impl Visitor<()> for IdVisitor {
                  _: Span,
                  node_id: NodeId,
                  env: ()) {
-        (self.visit_callback)(node_id);
+        self.operation.visit_id(node_id);
         visit::walk_mod(self, module, env)
     }
 
     fn visit_view_item(&mut self, view_item: &view_item, env: ()) {
         match view_item.node {
             view_item_extern_mod(_, _, _, node_id) => {
-                (self.visit_callback)(node_id)
+                self.operation.visit_id(node_id)
             }
             view_item_use(ref view_paths) => {
                 for view_path in view_paths.iter() {
                     match view_path.node {
                         view_path_simple(_, _, node_id) |
                         view_path_glob(_, node_id) => {
-                            (self.visit_callback)(node_id)
+                            self.operation.visit_id(node_id)
                         }
                         view_path_list(_, ref paths, node_id) => {
-                            (self.visit_callback)(node_id);
+                            self.operation.visit_id(node_id);
                             for path in paths.iter() {
-                                (self.visit_callback)(path.node.id)
+                                self.operation.visit_id(path.node.id)
                             }
                         }
                     }
@@ -460,7 +464,7 @@ impl Visitor<()> for IdVisitor {
     }
 
     fn visit_foreign_item(&mut self, foreign_item: @foreign_item, env: ()) {
-        (self.visit_callback)(foreign_item.id);
+        self.operation.visit_id(foreign_item.id);
         visit::walk_foreign_item(self, foreign_item, env)
     }
 
@@ -473,11 +477,11 @@ impl Visitor<()> for IdVisitor {
             }
         }
 
-        (self.visit_callback)(item.id);
+        self.operation.visit_id(item.id);
         match item.node {
             item_enum(ref enum_definition, _) => {
                 for variant in enum_definition.variants.iter() {
-                    (self.visit_callback)(variant.node.id)
+                    self.operation.visit_id(variant.node.id)
                 }
             }
             _ => {}
@@ -489,22 +493,22 @@ impl Visitor<()> for IdVisitor {
     }
 
     fn visit_local(&mut self, local: @Local, env: ()) {
-        (self.visit_callback)(local.id);
+        self.operation.visit_id(local.id);
         visit::walk_local(self, local, env)
     }
 
     fn visit_block(&mut self, block: &Block, env: ()) {
-        (self.visit_callback)(block.id);
+        self.operation.visit_id(block.id);
         visit::walk_block(self, block, env)
     }
 
     fn visit_stmt(&mut self, statement: @Stmt, env: ()) {
-        (self.visit_callback)(ast_util::stmt_id(statement));
+        self.operation.visit_id(ast_util::stmt_id(statement));
         visit::walk_stmt(self, statement, env)
     }
 
     fn visit_pat(&mut self, pattern: @Pat, env: ()) {
-        (self.visit_callback)(pattern.id);
+        self.operation.visit_id(pattern.id);
         visit::walk_pat(self, pattern, env)
     }
 
@@ -513,17 +517,17 @@ impl Visitor<()> for IdVisitor {
         {
             let optional_callee_id = expression.get_callee_id();
             for callee_id in optional_callee_id.iter() {
-                (self.visit_callback)(*callee_id)
+                self.operation.visit_id(*callee_id)
             }
         }
-        (self.visit_callback)(expression.id);
+        self.operation.visit_id(expression.id);
         visit::walk_expr(self, expression, env)
     }
 
     fn visit_ty(&mut self, typ: &Ty, env: ()) {
-        (self.visit_callback)(typ.id);
+        self.operation.visit_id(typ.id);
         match typ.node {
-            ty_path(_, _, id) => (self.visit_callback)(id),
+            ty_path(_, _, id) => self.operation.visit_id(id),
             _ => {}
         }
         visit::walk_ty(self, typ, env)
@@ -549,21 +553,21 @@ impl Visitor<()> for IdVisitor {
             }
         }
 
-        (self.visit_callback)(node_id);
+        self.operation.visit_id(node_id);
 
         match *function_kind {
             visit::fk_item_fn(_, generics, _, _) => {
                 self.visit_generics_helper(generics)
             }
             visit::fk_method(_, generics, method) => {
-                (self.visit_callback)(method.self_id);
+                self.operation.visit_id(method.self_id);
                 self.visit_generics_helper(generics)
             }
             visit::fk_anon(_) | visit::fk_fn_block => {}
         }
 
         for argument in function_declaration.inputs.iter() {
-            (self.visit_callback)(argument.id)
+            self.operation.visit_id(argument.id)
         }
 
         visit::walk_fn(self,
@@ -583,25 +587,36 @@ impl Visitor<()> for IdVisitor {
     }
 
     fn visit_struct_field(&mut self, struct_field: @struct_field, env: ()) {
-        (self.visit_callback)(struct_field.node.id);
+        self.operation.visit_id(struct_field.node.id);
         visit::walk_struct_field(self, struct_field, env)
     }
 }
 
-pub fn visit_ids_for_inlined_item(item: &inlined_item, vfn: @fn(NodeId)) {
+pub fn visit_ids_for_inlined_item(item: &inlined_item,
+                                  operation: @IdVisitingOperation) {
     let mut id_visitor = IdVisitor {
-        visit_callback: vfn,
+        operation: operation,
         pass_through_items: true,
         visited_outermost: false,
     };
     item.accept((), &mut id_visitor);
 }
 
-pub fn compute_id_range(visit_ids_fn: &fn(@fn(NodeId))) -> id_range {
-    let result = @mut id_range::max();
-    do visit_ids_fn |id| {
-        result.add(id);
+struct IdRangeComputingVisitor {
+    result: @mut id_range,
+}
+
+impl IdVisitingOperation for IdRangeComputingVisitor {
+    fn visit_id(&self, id: NodeId) {
+        self.result.add(id)
     }
+}
+
+pub fn compute_id_range(visit_ids_fn: &fn(@IdVisitingOperation)) -> id_range {
+    let result = @mut id_range::max();
+    visit_ids_fn(@IdRangeComputingVisitor {
+        result: result,
+    } as @IdVisitingOperation);
     *result
 }