Skip to content

Commit 608ae11

Browse files
committed
librustc: Make effect checking use the new visitor
1 parent 2eabce7 commit 608ae11

File tree

1 file changed

+115
-110
lines changed

1 file changed

+115
-110
lines changed

src/librustc/middle/effect.rs

Lines changed: 115 additions & 110 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,8 @@ 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, Visitor};
24+
use syntax::visit;
2525

2626
#[deriving(Eq)]
2727
enum UnsafeContext {
@@ -31,134 +31,139 @@ enum UnsafeContext {
3131
}
3232

3333
struct Context {
34+
/// The type context.
35+
type_context: ty::ctxt,
3436
/// The method map.
3537
method_map: method_map,
3638
/// Whether we're in an unsafe context.
3739
unsafe_context: UnsafeContext,
3840
}
3941

40-
fn type_is_unsafe_function(ty: ty::t) -> bool {
41-
match ty::get(ty).sty {
42-
ty_bare_fn(ref f) => f.purity == unsafe_fn,
43-
ty_closure(ref f) => f.purity == unsafe_fn,
44-
_ => false,
45-
}
46-
}
47-
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-
};
55-
56-
let require_unsafe: @fn(span: span,
57-
description: &str) = |span, description| {
58-
match context.unsafe_context {
59-
SafeContext => {
60-
// Report an error.
61-
tcx.sess.span_err(span,
62-
fmt!("%s requires unsafe function or block",
63-
description))
64-
}
65-
UnsafeBlock(block_id) => {
66-
// OK, but record this.
67-
debug!("effect: recording unsafe block as used: %?", block_id);
68-
let _ = tcx.used_unsafe.insert(block_id);
69-
}
70-
UnsafeFn => {}
42+
impl Visitor<()> for Context {
43+
fn visit_fn(&mut self,
44+
fn_kind: &visit::fn_kind,
45+
fn_decl: &ast::fn_decl,
46+
block: &ast::Block,
47+
span: span,
48+
node_id: ast::NodeId,
49+
_: ()) {
50+
let (is_item_fn, is_unsafe_fn) = match *fn_kind {
51+
fk_item_fn(_, _, purity, _) => (true, purity == unsafe_fn),
52+
fk_method(_, _, method) => (true, method.purity == unsafe_fn),
53+
_ => (false, false),
54+
};
55+
56+
let old_unsafe_context = self.unsafe_context;
57+
if is_unsafe_fn {
58+
self.unsafe_context = UnsafeFn
59+
} else if is_item_fn {
60+
self.unsafe_context = SafeContext
7161
}
72-
};
7362

74-
let visitor = oldvisit::mk_vt(@oldvisit::Visitor {
75-
visit_fn: |fn_kind, fn_decl, block, span, node_id, (_, visitor)| {
76-
let (is_item_fn, is_unsafe_fn) = match *fn_kind {
77-
fk_item_fn(_, _, purity, _) => (true, purity == unsafe_fn),
78-
fk_method(_, _, method) => (true, method.purity == unsafe_fn),
79-
_ => (false, false),
80-
};
81-
82-
let old_unsafe_context = context.unsafe_context;
83-
if is_unsafe_fn {
84-
context.unsafe_context = UnsafeFn
85-
} else if is_item_fn {
86-
context.unsafe_context = SafeContext
87-
}
63+
visit::walk_fn(self, fn_kind, fn_decl, block, span, node_id, ());
8864

89-
oldvisit::visit_fn(fn_kind,
90-
fn_decl,
91-
block,
92-
span,
93-
node_id,
94-
((),
95-
visitor));
96-
97-
context.unsafe_context = old_unsafe_context
98-
},
99-
100-
visit_block: |block, (_, visitor)| {
101-
let old_unsafe_context = context.unsafe_context;
102-
if block.rules == ast::UnsafeBlock &&
103-
context.unsafe_context == SafeContext {
104-
context.unsafe_context = UnsafeBlock(block.id)
105-
}
65+
self.unsafe_context = old_unsafe_context
66+
}
10667

107-
oldvisit::visit_block(block, ((), visitor));
68+
fn visit_block(&mut self, block: &ast::Block, _: ()) {
69+
let old_unsafe_context = self.unsafe_context;
70+
if block.rules == ast::UnsafeBlock &&
71+
self.unsafe_context == SafeContext {
72+
self.unsafe_context = UnsafeBlock(block.id)
73+
}
10874

109-
context.unsafe_context = old_unsafe_context
110-
},
75+
visit::walk_block(self, block, ());
11176

112-
visit_expr: |expr, (_, visitor)| {
113-
match expr.node {
114-
expr_method_call(callee_id, _, _, _, _, _) => {
115-
let base_type = ty::node_id_to_type(tcx, callee_id);
116-
debug!("effect: method call case, base type is %s",
117-
ppaux::ty_to_str(tcx, base_type));
118-
if type_is_unsafe_function(base_type) {
119-
require_unsafe(expr.span,
120-
"invocation of unsafe method")
121-
}
77+
self.unsafe_context = old_unsafe_context
78+
}
79+
80+
fn visit_expr(&mut self, expr: @ast::expr, _: ()) {
81+
match expr.node {
82+
expr_method_call(callee_id, _, _, _, _, _) => {
83+
let base_type = ty::node_id_to_type(self.type_context,
84+
callee_id);
85+
debug!("effect: method call case, base type is %s",
86+
ppaux::ty_to_str(self.type_context, base_type));
87+
if type_is_unsafe_function(base_type) {
88+
self.require_unsafe(expr.span,
89+
"invocation of unsafe method")
12290
}
123-
expr_call(base, _, _) => {
124-
let base_type = ty::node_id_to_type(tcx, base.id);
125-
debug!("effect: call case, base type is %s",
126-
ppaux::ty_to_str(tcx, base_type));
127-
if type_is_unsafe_function(base_type) {
128-
require_unsafe(expr.span, "call to unsafe function")
129-
}
91+
}
92+
expr_call(base, _, _) => {
93+
let base_type = ty::node_id_to_type(self.type_context,
94+
base.id);
95+
debug!("effect: call case, base type is %s",
96+
ppaux::ty_to_str(self.type_context, base_type));
97+
if type_is_unsafe_function(base_type) {
98+
self.require_unsafe(expr.span, "call to unsafe function")
13099
}
131-
expr_unary(_, deref, base) => {
132-
let base_type = ty::node_id_to_type(tcx, base.id);
133-
debug!("effect: unary case, base type is %s",
134-
ppaux::ty_to_str(tcx, base_type));
135-
match ty::get(base_type).sty {
136-
ty_ptr(_) => {
137-
require_unsafe(expr.span,
138-
"dereference of unsafe pointer")
139-
}
140-
_ => {}
100+
}
101+
expr_unary(_, deref, base) => {
102+
let base_type = ty::node_id_to_type(self.type_context,
103+
base.id);
104+
debug!("effect: unary case, base type is %s",
105+
ppaux::ty_to_str(self.type_context, base_type));
106+
match ty::get(base_type).sty {
107+
ty_ptr(_) => {
108+
self.require_unsafe(expr.span,
109+
"dereference of unsafe pointer")
141110
}
111+
_ => {}
142112
}
143-
expr_inline_asm(*) => {
144-
require_unsafe(expr.span, "use of inline assembly")
145-
}
146-
expr_path(*) => {
147-
match ty::resolve_expr(tcx, expr) {
148-
ast::def_static(_, true) => {
149-
require_unsafe(expr.span, "use of mutable static")
150-
}
151-
_ => {}
113+
}
114+
expr_inline_asm(*) => {
115+
self.require_unsafe(expr.span, "use of inline assembly")
116+
}
117+
expr_path(*) => {
118+
match ty::resolve_expr(self.type_context, expr) {
119+
ast::def_static(_, true) => {
120+
self.require_unsafe(expr.span,
121+
"use of mutable static")
152122
}
123+
_ => {}
153124
}
154-
_ => {}
155125
}
126+
_ => {}
127+
}
156128

157-
oldvisit::visit_expr(expr, ((), visitor))
158-
},
129+
visit::walk_expr(self, expr, ());
130+
}
131+
}
132+
133+
impl Context {
134+
fn require_unsafe(&mut self, span: span, description: &str) {
135+
match self.unsafe_context {
136+
SafeContext => {
137+
// Report an error.
138+
self.type_context.sess.span_err(span,
139+
fmt!("%s requires unsafe function or block",
140+
description))
141+
}
142+
UnsafeBlock(block_id) => {
143+
// OK, but record this.
144+
debug!("effect: recording unsafe block as used: %?", block_id);
145+
let _ = self.type_context.used_unsafe.insert(block_id);
146+
}
147+
UnsafeFn => {}
148+
}
149+
}
150+
}
159151

160-
.. *oldvisit::default_visitor()
161-
});
152+
fn type_is_unsafe_function(ty: ty::t) -> bool {
153+
match ty::get(ty).sty {
154+
ty_bare_fn(ref f) => f.purity == unsafe_fn,
155+
ty_closure(ref f) => f.purity == unsafe_fn,
156+
_ => false,
157+
}
158+
}
162159

163-
oldvisit::visit_crate(crate, ((), visitor))
160+
pub fn check_crate(tcx: ty::ctxt,
161+
method_map: method_map,
162+
crate: &ast::Crate) {
163+
let mut context = Context {
164+
type_context: tcx,
165+
method_map: method_map,
166+
unsafe_context: SafeContext,
167+
};
168+
visit::walk_crate(&mut context, crate, ());
164169
}

0 commit comments

Comments
 (0)