@@ -41,14 +41,12 @@ type ctx = {tcx: ty::ctxt, local_map: std::map::hashmap[node_id, local_info]};
41
41
fn check_crate ( tcx: ty:: ctxt, crate : & @ast:: crate) {
42
42
// Stores information about object fields and function
43
43
// arguments that's otherwise not easily available.
44
- let cx =
45
- @{ tcx: tcx, local_map: std:: map:: new_int_hash ( ) } ;
46
- let v =
47
- @{ visit_fn: bind visit_fn ( cx, _, _, _, _, _, _, _) ,
48
- visit_item: bind visit_item ( cx, _, _, _) ,
49
- visit_expr: bind visit_expr ( cx, _, _, _) ,
50
- visit_decl: bind visit_decl ( cx, _, _, _)
51
- with * visit:: default_visitor[ scope] ( ) } ;
44
+ let cx = @{ tcx: tcx, local_map: std:: map:: new_int_hash ( ) } ;
45
+ let v = @{ visit_fn: bind visit_fn ( cx, _, _, _, _, _, _, _) ,
46
+ visit_item: bind visit_item ( cx, _, _, _) ,
47
+ visit_expr: bind visit_expr ( cx, _, _, _) ,
48
+ visit_decl: bind visit_decl ( cx, _, _, _)
49
+ with * visit:: default_visitor[ scope] ( ) } ;
52
50
visit:: visit_crate ( * crate , @~[ ] , visit:: mk_vt ( v) ) ;
53
51
tcx. sess . abort_if_errors ( ) ;
54
52
}
@@ -158,12 +156,29 @@ fn check_call(cx: &ctx, f: &@ast::expr, args: &(@ast::expr)[], sc: &scope) ->
158
156
let arg = args. ( i) ;
159
157
let root = expr_root ( cx, arg, false ) ;
160
158
if arg_t. mode == ty:: mo_alias ( true ) {
161
- alt path_def_id ( cx, arg) {
162
- some ( did) { mut_roots += ~[ { arg: i, node: did. node } ] ; }
159
+ alt path_def ( cx, arg) {
160
+ some ( def) {
161
+ let dnum = ast:: def_id_of_def ( def) . node ;
162
+ if def_is_local ( def, true ) {
163
+ if is_immutable_alias ( cx, sc, dnum) {
164
+ cx. tcx . sess . span_err
165
+ ( arg. span , "passing an immutable alias \
166
+ by mutable alias") ;
167
+ } else if is_immutable_objfield ( cx, dnum) {
168
+ cx. tcx . sess . span_err
169
+ ( arg. span , "passing an immutable object \
170
+ field by mutable alias") ;
171
+ }
172
+ } else {
173
+ cx. tcx . sess . span_err
174
+ ( arg. span ,
175
+ "passing a static item by mutable alias" ) ;
176
+ }
177
+ mut_roots += ~[ { arg: i, node: dnum} ] ;
178
+ }
163
179
_ {
164
180
if !mut_field( root. ds ) {
165
- let m =
166
- "passing a temporary value or \
181
+ let m = "passing a temporary value or \
167
182
immutable field by mutable alias";
168
183
cx. tcx . sess . span_err ( arg. span , m) ;
169
184
}
@@ -391,13 +406,13 @@ fn check_lval(cx: &@ctx, dest: &@ast::expr, sc: &scope, v: &vt[scope]) {
391
406
alt dest. node {
392
407
ast:: expr_path ( p) {
393
408
let dnum = ast:: def_id_of_def ( cx. tcx . def_map . get ( dest. id ) ) . node ;
394
- if is_immutable_alias ( cx, sc, dnum) {
409
+ if is_immutable_alias ( * cx, sc, dnum) {
395
410
cx. tcx . sess . span_err ( dest. span , "assigning to immutable alias" ) ;
396
- } else if ( is_immutable_objfield ( cx, dnum) ) {
411
+ } else if ( is_immutable_objfield ( * cx, dnum) ) {
397
412
cx. tcx . sess . span_err ( dest. span ,
398
413
"assigning to immutable obj field" ) ;
399
414
}
400
- for r: restrict in * sc {
415
+ for r: restrict in * sc {
401
416
if ivec:: member ( dnum, r. root_vars ) {
402
417
r. ok = overwritten ( dest. span , p) ;
403
418
}
@@ -452,7 +467,7 @@ fn check_assign(cx: &@ctx, dest: &@ast::expr, src: &@ast::expr, sc: &scope,
452
467
}
453
468
454
469
455
- fn is_immutable_alias ( cx : & @ ctx , sc : & scope , dnum : node_id ) -> bool {
470
+ fn is_immutable_alias ( cx : & ctx , sc : & scope , dnum : node_id ) -> bool {
456
471
alt cx. local_map . find ( dnum) {
457
472
some ( arg ( ast:: alias ( false ) ) ) { ret true ; }
458
473
_ { }
@@ -463,7 +478,7 @@ fn is_immutable_alias(cx: &@ctx, sc: &scope, dnum: node_id) -> bool {
463
478
ret false;
464
479
}
465
480
466
- fn is_immutable_objfield ( cx : & @ ctx , dnum : node_id ) -> bool {
481
+ fn is_immutable_objfield ( cx : & ctx , dnum : node_id ) -> bool {
467
482
ret cx. local_map . find ( dnum) == some ( objfield ( ast:: imm) ) ;
468
483
}
469
484
@@ -614,6 +629,13 @@ fn inner_mut(ds: &@deref[]) -> option::t[ty::t] {
614
629
ret none;
615
630
}
616
631
632
+ fn path_def ( cx : & ctx , ex : & @ast:: expr ) -> option:: t [ ast:: def ] {
633
+ ret alt ex. node {
634
+ ast:: expr_path ( _) { some ( cx. tcx . def_map . get ( ex. id ) ) }
635
+ _ { none }
636
+ }
637
+ }
638
+
617
639
fn path_def_id ( cx : & ctx , ex : & @ast:: expr ) -> option:: t [ ast:: def_id ] {
618
640
alt ex. node {
619
641
ast:: expr_path ( _) {
0 commit comments