@@ -20,6 +20,7 @@ type restrict = @rec(vec[def_num] root_vars,
20
20
def_num block_defnum ,
21
21
vec[ def_num] bindings ,
22
22
vec[ ty:: t ] tys ,
23
+ vec[ uint] depends_on ,
23
24
mutable valid ok) ;
24
25
25
26
type scope = vec[ restrict ] ;
@@ -182,6 +183,7 @@ fn check_alt(&ctx cx, &@ast::expr input, &vec[ast::arm] arms,
182
183
block_defnum=dnums. ( 0 ) ,
183
184
bindings=dnums,
184
185
tys=forbidden_tp,
186
+ depends_on=deps( sc, roots) ,
185
187
mutable ok=valid) ) ;
186
188
}
187
189
visit:: visit_arm( a, new_sc, v) ;
@@ -221,6 +223,7 @@ fn check_for_each(&ctx cx, &@ast::decl decl, &@ast::expr call,
221
223
block_defnum=defnum,
222
224
bindings=[ defnum] ,
223
225
tys=data. unsafe_ts,
226
+ depends_on=deps( sc, data. root_vars) ,
224
227
mutable ok=valid) ;
225
228
visit:: visit_block( block, sc + [ new_sc] , v) ;
226
229
}
@@ -256,6 +259,7 @@ fn check_for(&ctx cx, &@ast::decl decl, &@ast::expr seq,
256
259
block_defnum=defnum,
257
260
bindings=[ defnum] ,
258
261
tys=unsafe ,
262
+ depends_on=deps( sc, root_def) ,
259
263
mutable ok=valid) ;
260
264
visit:: visit_block( block, sc + [ new_sc] , v) ;
261
265
}
@@ -274,24 +278,8 @@ fn check_var(&ctx cx, &@ast::expr ex, &ast::path p, ast::ann ann, bool assign,
274
278
r. ok = val_taken ( ex. span , p) ;
275
279
}
276
280
}
277
- } else if ( r. ok != valid && vec:: member ( my_defnum , r. bindings ) ) {
278
- fail_alias ( cx, r. ok , p) ;
279
- }
280
- }
281
- }
282
-
283
- fn fail_alias ( & ctx cx, valid issue, & ast:: path pt) {
284
- auto base = " will invalidate alias " + ast:: path_name ( pt) +
285
- ", which is still used" ;
286
- alt ( issue) {
287
- case ( overwritten ( ?sp, ?wpt) ) {
288
- cx. tcx . sess . span_err
289
- ( sp, "overwriting " + ast:: path_name ( wpt) + base) ;
290
- }
291
- case ( val_taken ( ?sp, ?vpt) ) {
292
- cx. tcx . sess . span_err
293
- ( sp, "taking the value of " + ast:: path_name ( vpt) +
294
- base) ;
281
+ } else if ( vec:: member ( my_defnum , r. bindings ) ) {
282
+ test_scope ( cx, sc, r, p) ;
295
283
}
296
284
}
297
285
}
@@ -316,6 +304,41 @@ fn check_assign(&@ctx cx, &@ast::expr dest, &@ast::expr src,
316
304
}
317
305
}
318
306
307
+ fn test_scope ( & ctx cx, & scope sc, & restrict r, & ast:: path p) {
308
+ auto prob = r. ok ;
309
+ for ( uint dep in r. depends_on) {
310
+ if ( prob != valid) { break ; }
311
+ prob = sc. ( dep) . ok ;
312
+ }
313
+ if ( prob != valid) {
314
+ auto msg = alt ( prob) {
315
+ case ( overwritten ( ?sp, ?wpt) ) {
316
+ tup ( sp, "overwriting " + ast:: path_name ( wpt) )
317
+ }
318
+ case ( val_taken ( ?sp, ?vpt) ) {
319
+ tup ( sp, "taking the value of " + ast:: path_name ( vpt) )
320
+ }
321
+ } ;
322
+ cx. tcx . sess . span_err
323
+ ( msg. _0 , msg. _1 + " will invalidate alias " +
324
+ ast:: path_name ( p) + ", which is still used" ) ;
325
+ }
326
+ }
327
+
328
+ fn deps ( & scope sc, vec[ def_num] roots ) -> vec[ uint ] {
329
+ auto i = 0 u;
330
+ auto result = [ ] ;
331
+ for ( restrict r in sc) {
332
+ for ( def_num dn in roots) {
333
+ if ( vec:: member ( dn, r. bindings ) ) {
334
+ vec:: push ( result, i) ;
335
+ }
336
+ }
337
+ i += 1 u;
338
+ }
339
+ ret result;
340
+ }
341
+
319
342
fn expr_root ( & ctx cx, @ast:: expr ex, bool autoderef )
320
343
-> rec ( @ast:: expr ex, option:: t[ ty:: t ] inner_mut , bool mut_in_box ) {
321
344
let option:: t[ ty:: t] mut = none;
0 commit comments