@@ -28,72 +28,69 @@ use util::ppaux::Repr;
28
28
29
29
#[ deriving( Clone ) ]
30
30
struct Context {
31
- tcx : ty:: ctxt ,
32
31
safe_stack : bool
33
32
}
34
33
35
- struct StackCheckVisitor ;
34
+ struct StackCheckVisitor {
35
+ tcx : ty:: ctxt ,
36
+ }
36
37
37
38
impl Visitor < Context > for StackCheckVisitor {
38
39
fn visit_item ( & mut self , i : @ast:: item , e : Context ) {
39
- stack_check_item ( * self , i, e) ;
40
+ stack_check_item ( self , i, e) ;
40
41
}
41
42
fn visit_fn ( & mut self , fk : & visit:: fn_kind , fd : & ast:: fn_decl ,
42
43
b : & ast:: Block , s : Span , n : ast:: NodeId , e : Context ) {
43
- stack_check_fn ( * self , fk, fd, b, s, n, e) ;
44
+ stack_check_fn ( self , fk, fd, b, s, n, e) ;
44
45
}
45
46
fn visit_expr ( & mut self , ex : @ast:: Expr , e : Context ) {
46
- stack_check_expr ( * self , ex, e) ;
47
+ stack_check_expr ( self , ex, e) ;
47
48
}
48
49
}
49
50
50
51
pub fn stack_check_crate ( tcx : ty:: ctxt ,
51
52
crate : & ast:: Crate ) {
52
- let new_cx = Context {
53
- tcx : tcx,
54
- safe_stack : false
55
- } ;
56
- let mut visitor = StackCheckVisitor ;
53
+ let new_cx = Context { safe_stack : false } ;
54
+ let mut visitor = StackCheckVisitor { tcx : tcx } ;
57
55
visit:: walk_crate ( & mut visitor, crate , new_cx) ;
58
56
}
59
57
60
- fn stack_check_item ( v : StackCheckVisitor ,
58
+ fn stack_check_item ( v : & mut StackCheckVisitor ,
61
59
item : @ast:: item ,
62
60
in_cx : Context ) {
63
- let mut v = v;
64
61
match item. node {
65
62
ast:: item_fn( _, ast:: extern_fn, _, _, _) => {
66
63
// an extern fn is already being called from C code...
67
- let new_cx = Context { safe_stack : true , ..in_cx } ;
68
- visit:: walk_item ( & mut v, item, new_cx) ;
64
+ let new_cx = Context { safe_stack : true } ;
65
+ visit:: walk_item ( v, item, new_cx) ;
69
66
}
70
67
ast:: item_fn( * ) => {
71
68
let safe_stack = fixed_stack_segment ( item. attrs ) ;
72
- let new_cx = Context { safe_stack : safe_stack, ..in_cx } ;
73
- visit:: walk_item ( & mut v, item, new_cx) ;
69
+ let new_cx = Context { safe_stack : safe_stack} ;
70
+ visit:: walk_item ( v, item, new_cx) ;
74
71
}
75
72
ast:: item_impl( _, _, _, ref methods) => {
76
73
// visit_method() would make this nicer
77
74
for & method in methods. iter ( ) {
78
75
let safe_stack = fixed_stack_segment ( method. attrs ) ;
79
- let new_cx = Context { safe_stack : safe_stack, ..in_cx } ;
80
- visit:: walk_method_helper ( & mut v, method, new_cx) ;
76
+ let new_cx = Context { safe_stack : safe_stack} ;
77
+ visit:: walk_method_helper ( v, method, new_cx) ;
81
78
}
82
79
}
83
80
ast:: item_trait( _, _, ref methods) => {
84
81
for method in methods. iter ( ) {
85
82
match * method {
86
83
ast:: provided( @ref method) => {
87
84
let safe_stack = fixed_stack_segment ( method. attrs ) ;
88
- let new_cx = Context { safe_stack : safe_stack, ..in_cx } ;
89
- visit:: walk_method_helper ( & mut v, method, new_cx) ;
85
+ let new_cx = Context { safe_stack : safe_stack} ;
86
+ visit:: walk_method_helper ( v, method, new_cx) ;
90
87
}
91
88
ast:: required( * ) => ( )
92
89
}
93
90
}
94
91
}
95
92
_ => {
96
- visit:: walk_item ( & mut v, item, in_cx) ;
93
+ visit:: walk_item ( v, item, in_cx) ;
97
94
}
98
95
}
99
96
@@ -102,7 +99,7 @@ fn stack_check_item(v: StackCheckVisitor,
102
99
}
103
100
}
104
101
105
- fn stack_check_fn < ' a > ( v : StackCheckVisitor ,
102
+ fn stack_check_fn < ' a > ( v : & mut StackCheckVisitor ,
106
103
fk : & visit:: fn_kind ,
107
104
decl : & ast:: fn_decl ,
108
105
body : & ast:: Block ,
@@ -114,7 +111,7 @@ fn stack_check_fn<'a>(v: StackCheckVisitor,
114
111
in_cx. safe_stack // see stack_check_item above
115
112
}
116
113
visit:: fk_anon( * ) | visit:: fk_fn_block => {
117
- match ty:: get ( ty:: node_id_to_type ( in_cx . tcx , id) ) . sty {
114
+ match ty:: get ( ty:: node_id_to_type ( v . tcx , id) ) . sty {
118
115
ty:: ty_bare_fn( * ) |
119
116
ty:: ty_closure( ty:: ClosureTy { sigil : ast:: OwnedSigil , _} ) => {
120
117
false
@@ -125,26 +122,25 @@ fn stack_check_fn<'a>(v: StackCheckVisitor,
125
122
}
126
123
}
127
124
} ;
128
- let new_cx = Context { safe_stack : safe_stack, ..in_cx } ;
125
+ let new_cx = Context { safe_stack : safe_stack} ;
129
126
debug ! ( "stack_check_fn(safe_stack=%b, id=%?)" , safe_stack, id) ;
130
- let mut v = v;
131
- visit:: walk_fn ( & mut v, fk, decl, body, sp, id, new_cx) ;
127
+ visit:: walk_fn ( v, fk, decl, body, sp, id, new_cx) ;
132
128
}
133
129
134
- fn stack_check_expr < ' a > ( v : StackCheckVisitor ,
130
+ fn stack_check_expr < ' a > ( v : & mut StackCheckVisitor ,
135
131
expr : @ast:: Expr ,
136
132
cx : Context ) {
137
133
debug ! ( "stack_check_expr(safe_stack=%b, expr=%s)" ,
138
- cx. safe_stack, expr. repr( cx . tcx) ) ;
134
+ cx. safe_stack, expr. repr( v . tcx) ) ;
139
135
if !cx. safe_stack {
140
136
match expr. node {
141
137
ast:: ExprCall ( callee, _, _) => {
142
- let callee_ty = ty:: expr_ty ( cx . tcx , callee) ;
143
- debug ! ( "callee_ty=%s" , callee_ty. repr( cx . tcx) ) ;
138
+ let callee_ty = ty:: expr_ty ( v . tcx , callee) ;
139
+ debug ! ( "callee_ty=%s" , callee_ty. repr( v . tcx) ) ;
144
140
match ty:: get ( callee_ty) . sty {
145
141
ty:: ty_bare_fn( ref fty) => {
146
142
if !fty. abis . is_rust ( ) && !fty. abis . is_intrinsic ( ) {
147
- call_to_extern_fn ( cx , callee) ;
143
+ call_to_extern_fn ( v , callee) ;
148
144
}
149
145
}
150
146
_ => { }
@@ -153,18 +149,17 @@ fn stack_check_expr<'a>(v: StackCheckVisitor,
153
149
_ => { }
154
150
}
155
151
}
156
- let mut v = v;
157
- visit:: walk_expr ( & mut v, expr, cx) ;
152
+ visit:: walk_expr ( v, expr, cx) ;
158
153
}
159
154
160
- fn call_to_extern_fn ( cx : Context , callee : @ast:: Expr ) {
155
+ fn call_to_extern_fn ( v : & mut StackCheckVisitor , callee : @ast:: Expr ) {
161
156
// Permit direct calls to extern fns that are annotated with
162
157
// #[rust_stack]. This is naturally a horrible pain to achieve.
163
158
match callee. node {
164
159
ast:: ExprPath ( * ) => {
165
- match cx . tcx . def_map . find ( & callee. id ) {
160
+ match v . tcx . def_map . find ( & callee. id ) {
166
161
Some ( & ast:: DefFn ( id, _) ) if id. crate == ast:: LOCAL_CRATE => {
167
- match cx . tcx . items . find ( & id. node ) {
162
+ match v . tcx . items . find ( & id. node ) {
168
163
Some ( & ast_map:: node_foreign_item( item, _, _, _) ) => {
169
164
if attr:: contains_name ( item. attrs , "rust_stack" ) {
170
165
return ;
@@ -179,7 +174,7 @@ fn call_to_extern_fn(cx: Context, callee: @ast::Expr) {
179
174
_ => { }
180
175
}
181
176
182
- cx . tcx . sess . add_lint ( lint:: cstack,
177
+ v . tcx . sess . add_lint ( lint:: cstack,
183
178
callee. id ,
184
179
callee. span ,
185
180
fmt ! ( "invoking non-Rust fn in fn without \
0 commit comments