diff options
| author | Patrick Walton <pcwalton@mimiga.net> | 2013-08-29 19:01:19 -0700 |
|---|---|---|
| committer | Patrick Walton <pcwalton@mimiga.net> | 2013-09-23 18:23:20 -0700 |
| commit | 6ecbd75843a2187027d09649c9046189d1d4a446 (patch) | |
| tree | 01a6b507157208617145378be4f4c1bc0d034057 | |
| parent | 37c32e249505f103f9bcad0bdd83f49f0efec9ef (diff) | |
| download | rust-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.rs | 47 | ||||
| -rw-r--r-- | src/librustc/middle/lint.rs | 22 | ||||
| -rw-r--r-- | src/librustc/rustc.rs | 2 | ||||
| -rw-r--r-- | src/libsyntax/ast_util.rs | 77 |
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 } |
