Skip to content

Commit b97cc95

Browse files
committed
Ported effect checker from oldvisit to <V:Visitor> trait API.
1 parent 635d917 commit b97cc95

File tree

1 file changed

+65
-50
lines changed

1 file changed

+65
-50
lines changed

src/librustc/middle/effect.rs

Lines changed: 65 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,10 @@ use syntax::ast::{deref, expr_call, expr_inline_asm, expr_method_call};
2020
use syntax::ast::{expr_unary, unsafe_fn, expr_path};
2121
use syntax::ast;
2222
use syntax::codemap::span;
23-
use syntax::oldvisit::{fk_item_fn, fk_method};
24-
use syntax::oldvisit;
23+
use syntax::visit::{fk_item_fn, fk_method};
24+
use syntax::visit;
25+
use syntax::visit::{Visitor,fn_kind};
26+
use syntax::ast::{fn_decl,Block,NodeId,expr};
2527

2628
#[deriving(Eq)]
2729
enum UnsafeContext {
@@ -45,120 +47,133 @@ fn type_is_unsafe_function(ty: ty::t) -> bool {
4547
}
4648
}
4749

48-
pub fn check_crate(tcx: ty::ctxt,
49-
method_map: method_map,
50-
crate: &ast::Crate) {
51-
let context = @mut Context {
52-
method_map: method_map,
53-
unsafe_context: SafeContext,
54-
};
50+
struct EffectCheckVisitor {
51+
tcx: ty::ctxt,
52+
context: @mut Context,
53+
}
5554

56-
let require_unsafe: @fn(span: span,
57-
description: &str) = |span, description| {
58-
match context.unsafe_context {
55+
impl EffectCheckVisitor {
56+
fn require_unsafe(&mut self, span: span, description: &str) {
57+
match self.context.unsafe_context {
5958
SafeContext => {
6059
// Report an error.
61-
tcx.sess.span_err(span,
60+
self.tcx.sess.span_err(span,
6261
fmt!("%s requires unsafe function or block",
6362
description))
6463
}
6564
UnsafeBlock(block_id) => {
6665
// OK, but record this.
6766
debug!("effect: recording unsafe block as used: %?", block_id);
68-
let _ = tcx.used_unsafe.insert(block_id);
67+
let _ = self.tcx.used_unsafe.insert(block_id);
6968
}
7069
UnsafeFn => {}
7170
}
72-
};
71+
}
72+
}
73+
74+
impl Visitor<()> for EffectCheckVisitor {
75+
fn visit_fn(&mut self, fn_kind:&fn_kind, fn_decl:&fn_decl,
76+
block:&Block, span:span, node_id:NodeId, _:()) {
7377

74-
let visitor = oldvisit::mk_vt(@oldvisit::Visitor {
75-
visit_fn: |fn_kind, fn_decl, block, span, node_id, (_, visitor)| {
7678
let (is_item_fn, is_unsafe_fn) = match *fn_kind {
7779
fk_item_fn(_, _, purity, _) => (true, purity == unsafe_fn),
7880
fk_method(_, _, method) => (true, method.purity == unsafe_fn),
7981
_ => (false, false),
8082
};
8183

82-
let old_unsafe_context = context.unsafe_context;
84+
let old_unsafe_context = self.context.unsafe_context;
8385
if is_unsafe_fn {
84-
context.unsafe_context = UnsafeFn
86+
self.context.unsafe_context = UnsafeFn
8587
} else if is_item_fn {
86-
context.unsafe_context = SafeContext
88+
self.context.unsafe_context = SafeContext
8789
}
8890

89-
oldvisit::visit_fn(fn_kind,
91+
visit::walk_fn(self,
92+
fn_kind,
9093
fn_decl,
9194
block,
9295
span,
9396
node_id,
94-
((),
95-
visitor));
97+
());
98+
99+
self.context.unsafe_context = old_unsafe_context
100+
}
96101

97-
context.unsafe_context = old_unsafe_context
98-
},
102+
fn visit_block(&mut self, block:&Block, _:()) {
99103

100-
visit_block: |block, (_, visitor)| {
101-
let old_unsafe_context = context.unsafe_context;
104+
let old_unsafe_context = self.context.unsafe_context;
102105
if block.rules == ast::UnsafeBlock &&
103-
context.unsafe_context == SafeContext {
104-
context.unsafe_context = UnsafeBlock(block.id)
106+
self.context.unsafe_context == SafeContext {
107+
self.context.unsafe_context = UnsafeBlock(block.id)
105108
}
106109

107-
oldvisit::visit_block(block, ((), visitor));
110+
visit::walk_block(self, block, ());
108111

109-
context.unsafe_context = old_unsafe_context
110-
},
112+
self.context.unsafe_context = old_unsafe_context
113+
}
114+
115+
fn visit_expr(&mut self, expr:@expr, _:()) {
111116

112-
visit_expr: |expr, (_, visitor)| {
113117
match expr.node {
114118
expr_method_call(callee_id, _, _, _, _, _) => {
115-
let base_type = ty::node_id_to_type(tcx, callee_id);
119+
let base_type = ty::node_id_to_type(self.tcx, callee_id);
116120
debug!("effect: method call case, base type is %s",
117-
ppaux::ty_to_str(tcx, base_type));
121+
ppaux::ty_to_str(self.tcx, base_type));
118122
if type_is_unsafe_function(base_type) {
119-
require_unsafe(expr.span,
123+
self.require_unsafe(expr.span,
120124
"invocation of unsafe method")
121125
}
122126
}
123127
expr_call(base, _, _) => {
124-
let base_type = ty::node_id_to_type(tcx, base.id);
128+
let base_type = ty::node_id_to_type(self.tcx, base.id);
125129
debug!("effect: call case, base type is %s",
126-
ppaux::ty_to_str(tcx, base_type));
130+
ppaux::ty_to_str(self.tcx, base_type));
127131
if type_is_unsafe_function(base_type) {
128-
require_unsafe(expr.span, "call to unsafe function")
132+
self.require_unsafe(expr.span, "call to unsafe function")
129133
}
130134
}
131135
expr_unary(_, deref, base) => {
132-
let base_type = ty::node_id_to_type(tcx, base.id);
136+
let base_type = ty::node_id_to_type(self.tcx, base.id);
133137
debug!("effect: unary case, base type is %s",
134-
ppaux::ty_to_str(tcx, base_type));
138+
ppaux::ty_to_str(self.tcx, base_type));
135139
match ty::get(base_type).sty {
136140
ty_ptr(_) => {
137-
require_unsafe(expr.span,
141+
self.require_unsafe(expr.span,
138142
"dereference of unsafe pointer")
139143
}
140144
_ => {}
141145
}
142146
}
143147
expr_inline_asm(*) => {
144-
require_unsafe(expr.span, "use of inline assembly")
148+
self.require_unsafe(expr.span, "use of inline assembly")
145149
}
146150
expr_path(*) => {
147-
match ty::resolve_expr(tcx, expr) {
151+
match ty::resolve_expr(self.tcx, expr) {
148152
ast::def_static(_, true) => {
149-
require_unsafe(expr.span, "use of mutable static")
153+
self.require_unsafe(expr.span, "use of mutable static")
150154
}
151155
_ => {}
152156
}
153157
}
154158
_ => {}
155159
}
156160

157-
oldvisit::visit_expr(expr, ((), visitor))
158-
},
161+
visit::walk_expr(self, expr, ());
162+
}
163+
}
159164

160-
.. *oldvisit::default_visitor()
161-
});
165+
pub fn check_crate(tcx: ty::ctxt,
166+
method_map: method_map,
167+
crate: &ast::Crate) {
168+
let context = @mut Context {
169+
method_map: method_map,
170+
unsafe_context: SafeContext,
171+
};
172+
173+
let mut visitor = EffectCheckVisitor {
174+
tcx: tcx,
175+
context: context,
176+
};
162177

163-
oldvisit::visit_crate(crate, ((), visitor))
178+
visit::walk_crate(&mut visitor, crate, ());
164179
}

0 commit comments

Comments
 (0)