@@ -15,25 +15,30 @@ import std::option::{some, none, is_none};
15
15
tag valid { valid; overwritten ( span, ast:: path) ; val_taken ( span, ast:: path) ; }
16
16
tag copied { not_allowed; copied; not_copied; }
17
17
18
- type restrict = @{ node_id: node_id,
19
- span: span,
20
- local_id: uint,
21
- root_var: option:: t<node_id>,
22
- unsafe_tys: [ ty:: t] ,
23
- mutable ok: valid,
24
- mutable copied: copied} ;
25
-
26
- type scope = [ restrict ] ;
18
+ type binding = @{ node_id: node_id,
19
+ span: span,
20
+ local_id: uint,
21
+ root_var: option:: t<node_id>,
22
+ unsafe_tys: [ ty:: t] ,
23
+ mutable ok: valid,
24
+ mutable copied: copied} ;
25
+ type scope = [ binding ] ; // {bs: [binding], ret_style: ast::ret_style}
26
+
27
+ fn mk_binding ( cx : ctx , id : node_id , span : span , root_var : option:: t < node_id > ,
28
+ unsafe : [ ty:: t ] ) -> binding {
29
+ ret @{ node_id : id, span : span, local_id : cx. next_local ,
30
+ root_var : root_var, unsafe_tys : unsafe ,
31
+ mutable ok: valid, mutable copied: not_copied} ;
32
+ }
27
33
28
34
tag local_info { local( uint) ; }
29
35
30
36
type copy_map = std:: map:: hashmap < node_id , ( ) > ;
31
37
32
- type ctx =
33
- { tcx : ty:: ctxt ,
34
- local_map : std:: map:: hashmap < node_id , local_info > ,
35
- mutable next_local: uint ,
36
- copy_map : copy_map } ;
38
+ type ctx = { tcx : ty:: ctxt ,
39
+ local_map : std:: map:: hashmap < node_id , local_info > ,
40
+ mutable next_local: uint ,
41
+ copy_map : copy_map } ;
37
42
38
43
fn check_crate ( tcx : ty:: ctxt , crate : @ast:: crate ) -> copy_map {
39
44
// Stores information about object fields and function
@@ -105,6 +110,10 @@ fn visit_expr(cx: @ctx, ex: @ast::expr, sc: scope, v: vt<scope>) {
105
110
ast:: expr_assign ( dest, src) | ast:: expr_assign_op ( _, dest, src) {
106
111
check_assign ( cx, dest, src, sc, v) ;
107
112
}
113
+ ast:: expr_ret ( oexpr) {
114
+
115
+ handled = false ;
116
+ }
108
117
_ { handled = false ; }
109
118
}
110
119
if !handled { visit:: visit_expr ( ex, sc, v) ; }
@@ -137,30 +146,30 @@ fn visit_decl(cx: @ctx, d: @ast::decl, sc: scope, v: vt<scope>) {
137
146
}
138
147
}
139
148
140
- fn cant_copy ( cx : ctx , r : restrict ) -> bool {
141
- alt r . copied {
149
+ fn cant_copy ( cx : ctx , b : binding ) -> bool {
150
+ alt b . copied {
142
151
not_allowed. { ret true ; }
143
152
copied. { ret false ; }
144
153
not_copied. { }
145
154
}
146
- let ty = ty:: node_id_to_type ( cx. tcx , r . node_id ) ;
155
+ let ty = ty:: node_id_to_type ( cx. tcx , b . node_id ) ;
147
156
if ty:: type_allows_implicit_copy ( cx. tcx , ty) {
148
- r . copied = copied;
149
- cx. copy_map . insert ( r . node_id , ( ) ) ;
157
+ b . copied = copied;
158
+ cx. copy_map . insert ( b . node_id , ( ) ) ;
150
159
if copy_is_expensive ( cx. tcx , ty) {
151
- cx. tcx . sess . span_warn ( r . span ,
160
+ cx. tcx . sess . span_warn ( b . span ,
152
161
"inserting an implicit copy for type " +
153
162
util:: ppaux:: ty_to_str ( cx. tcx , ty) ) ;
154
163
}
155
164
ret false;
156
165
} else { ret true ; }
157
166
}
158
167
159
- fn check_call ( cx : ctx , f : @ast:: expr , args : [ @ast:: expr ] ) -> [ restrict ] {
168
+ fn check_call ( cx : ctx , f : @ast:: expr , args : [ @ast:: expr ] ) -> [ binding ] {
160
169
let fty = ty:: type_autoderef ( cx. tcx , ty:: expr_ty ( cx. tcx , f) ) ;
161
170
let arg_ts = ty:: ty_fn_args ( cx. tcx , fty) ;
162
171
let mut_roots: [ { arg : uint , node : node_id } ] = [ ] ;
163
- let restricts = [ ] ;
172
+ let bindings = [ ] ;
164
173
let i = 0 u;
165
174
for arg_t: ty:: arg in arg_ts {
166
175
let arg = args[ i] ;
@@ -175,17 +184,14 @@ fn check_call(cx: ctx, f: @ast::expr, args: [@ast::expr]) -> [restrict] {
175
184
}
176
185
}
177
186
let root_var = path_def_id ( cx, root. ex ) ;
178
- restricts += [ @{ node_id: arg. id ,
179
- span: arg. span ,
180
- local_id: cx. next_local ,
181
- root_var: root_var,
182
- unsafe_tys: inner_mut ( root. ds ) ,
183
- mutable ok: valid,
184
- mutable copied: alt arg_t. mode {
185
- ast:: by_move. { copied }
186
- ast:: by_ref. { not_copied }
187
- ast:: by_mut_ref. { not_allowed }
188
- } } ] ;
187
+ let new_bnd = mk_binding ( cx, arg. id , arg. span , root_var,
188
+ inner_mut ( root. ds ) ) ;
189
+ new_bnd. copied = alt arg_t. mode {
190
+ ast:: by_move. { copied }
191
+ ast:: by_ref. { not_copied }
192
+ ast:: by_mut_ref. { not_allowed }
193
+ } ;
194
+ bindings += [ new_bnd] ;
189
195
i += 1 u;
190
196
}
191
197
let f_may_close =
@@ -195,8 +201,8 @@ fn check_call(cx: ctx, f: @ast::expr, args: [@ast::expr]) -> [restrict] {
195
201
} ;
196
202
if f_may_close {
197
203
let i = 0 u;
198
- for r in restricts {
199
- if vec:: len ( r . unsafe_tys ) > 0 u && cant_copy ( cx, r ) {
204
+ for b in bindings {
205
+ if vec:: len ( b . unsafe_tys ) > 0 u && cant_copy ( cx, b ) {
200
206
cx. tcx . sess . span_err ( f. span ,
201
207
#fmt[ "function may alias with argument \
202
208
%u, which is not immutably rooted",
@@ -206,14 +212,14 @@ fn check_call(cx: ctx, f: @ast::expr, args: [@ast::expr]) -> [restrict] {
206
212
}
207
213
}
208
214
let j = 0 u;
209
- for r in restricts {
210
- for ty in r . unsafe_tys {
215
+ for b in bindings {
216
+ for ty in b . unsafe_tys {
211
217
let i = 0 u;
212
218
for arg_t: ty:: arg in arg_ts {
213
219
let mut_alias = arg_t. mode == ast:: by_mut_ref;
214
220
if i != j &&
215
221
ty_can_unsafely_include ( cx, ty, arg_t. ty , mut_alias) &&
216
- cant_copy ( cx, r ) {
222
+ cant_copy ( cx, b ) {
217
223
cx. tcx . sess . span_err
218
224
( args[ i] . span ,
219
225
#fmt[ "argument %u may alias with argument %u, \
@@ -229,11 +235,11 @@ fn check_call(cx: ctx, f: @ast::expr, args: [@ast::expr]) -> [restrict] {
229
235
230
236
for { node: node, arg: arg} in mut_roots {
231
237
let i = 0 u;
232
- for r in restricts {
238
+ for b in bindings {
233
239
if i != arg {
234
- alt r . root_var {
240
+ alt b . root_var {
235
241
some ( root) {
236
- if node == root && cant_copy ( cx, r ) {
242
+ if node == root && cant_copy ( cx, b ) {
237
243
cx. tcx . sess . span_err
238
244
( args[ arg] . span ,
239
245
"passing a mutable reference to a \
@@ -247,7 +253,7 @@ fn check_call(cx: ctx, f: @ast::expr, args: [@ast::expr]) -> [restrict] {
247
253
i += 1 u;
248
254
}
249
255
}
250
- ret restricts ;
256
+ ret bindings ;
251
257
}
252
258
253
259
fn check_alt ( cx : ctx , input : @ast:: expr , arms : [ ast:: arm ] , sc : scope ,
@@ -277,13 +283,8 @@ fn check_alt(cx: ctx, input: @ast::expr, arms: [ast::arm], sc: scope,
277
283
}
278
284
}
279
285
for info in binding_info {
280
- new_sc += [ @{ node_id: info. id ,
281
- span: info. span ,
282
- local_id: cx. next_local ,
283
- root_var: root_var,
284
- unsafe_tys: info. unsafe ,
285
- mutable ok: valid,
286
- mutable copied: not_copied} ] ;
286
+ new_sc += [ mk_binding ( cx, info. id , info. span , root_var,
287
+ info. unsafe ) ] ;
287
288
}
288
289
register_locals ( cx, a. pats [ 0 ] ) ;
289
290
visit:: visit_arm ( a, new_sc, v) ;
@@ -297,13 +298,8 @@ fn check_for_each(cx: ctx, local: @ast::local, call: @ast::expr,
297
298
ast:: expr_call ( f, args) {
298
299
let new_sc = sc + check_call ( cx, f, args) ;
299
300
for proot in * pattern_roots ( cx. tcx , [ ] , local. node . pat ) {
300
- new_sc += [ @{ node_id: proot. id ,
301
- span: proot. span ,
302
- local_id: cx. next_local ,
303
- root_var : none:: < node_id > ,
304
- unsafe_tys: inner_mut ( proot. ds ) ,
305
- mutable ok: valid,
306
- mutable copied: not_copied} ] ;
301
+ new_sc += [ mk_binding ( cx, proot. id , proot. span , none,
302
+ inner_mut ( proot. ds ) ) ] ;
307
303
}
308
304
register_locals ( cx, local. node . pat ) ;
309
305
visit:: visit_block ( blk, new_sc, v) ;
@@ -330,13 +326,8 @@ fn check_for(cx: ctx, local: @ast::local, seq: @ast::expr, blk: ast::blk,
330
326
let root_var = path_def_id ( cx, root. ex ) ;
331
327
let new_sc = sc;
332
328
for proot in * pattern_roots ( cx. tcx , ext_ds, local. node . pat ) {
333
- new_sc += [ @{ node_id: proot. id ,
334
- span: proot. span ,
335
- local_id: cx. next_local ,
336
- root_var: root_var,
337
- unsafe_tys: inner_mut ( proot. ds ) ,
338
- mutable ok: valid,
339
- mutable copied: not_copied} ] ;
329
+ new_sc += [ mk_binding ( cx, proot. id , proot. span , root_var,
330
+ inner_mut ( proot. ds ) ) ] ;
340
331
}
341
332
register_locals ( cx, local. node . pat ) ;
342
333
visit:: visit_block ( blk, new_sc, v) ;
@@ -350,16 +341,16 @@ fn check_var(cx: ctx, ex: @ast::expr, p: ast::path, id: ast::node_id,
350
341
let my_local_id =
351
342
alt cx. local_map . find ( my_defnum) { some ( local ( id) ) { id } _ { 0 u } } ;
352
343
let var_t = ty:: expr_ty ( cx. tcx , ex) ;
353
- for r : restrict in sc {
344
+ for b in sc {
354
345
// excludes variables introduced since the alias was made
355
- if my_local_id < r . local_id {
356
- for ty in r . unsafe_tys {
346
+ if my_local_id < b . local_id {
347
+ for ty in b . unsafe_tys {
357
348
if ty_can_unsafely_include ( cx, ty, var_t, assign) {
358
- r . ok = val_taken ( ex. span , p) ;
349
+ b . ok = val_taken ( ex. span , p) ;
359
350
}
360
351
}
361
- } else if r . node_id == my_defnum {
362
- test_scope ( cx, sc, r , p) ;
352
+ } else if b . node_id == my_defnum {
353
+ test_scope ( cx, sc, b , p) ;
363
354
}
364
355
}
365
356
}
@@ -369,8 +360,8 @@ fn check_lval(cx: @ctx, dest: @ast::expr, sc: scope, v: vt<scope>) {
369
360
ast:: expr_path ( p) {
370
361
let def = cx. tcx . def_map . get ( dest. id ) ;
371
362
let dnum = ast_util:: def_id_of_def ( def) . node ;
372
- for r : restrict in sc {
373
- if r . root_var == some ( dnum) { r . ok = overwritten ( dest. span , p) ; }
363
+ for b in sc {
364
+ if b . root_var == some ( dnum) { b . ok = overwritten ( dest. span , p) ; }
374
365
}
375
366
}
376
367
_ { visit_expr( cx, dest, sc, v) ; }
@@ -383,9 +374,9 @@ fn check_assign(cx: @ctx, dest: @ast::expr, src: @ast::expr, sc: scope,
383
374
check_lval ( cx, dest, sc, v) ;
384
375
}
385
376
386
- fn test_scope ( cx : ctx , sc : scope , r : restrict , p : ast:: path ) {
387
- let prob = r . ok ;
388
- alt r . root_var {
377
+ fn test_scope ( cx : ctx , sc : scope , b : binding , p : ast:: path ) {
378
+ let prob = b . ok ;
379
+ alt b . root_var {
389
380
some ( dn) {
390
381
for other in sc {
391
382
if other. node_id == dn {
@@ -396,7 +387,7 @@ fn test_scope(cx: ctx, sc: scope, r: restrict, p: ast::path) {
396
387
}
397
388
_ { }
398
389
}
399
- if prob != valid && cant_copy ( cx, r ) {
390
+ if prob != valid && cant_copy ( cx, b ) {
400
391
let msg = alt prob {
401
392
overwritten( sp, wpt) {
402
393
{ span: sp, msg: "overwriting " + ast_util:: path_name ( wpt) }
0 commit comments