@@ -10,6 +10,14 @@ import std::option::some;
10
10
import std:: option:: none;
11
11
import std:: option:: is_none;
12
12
13
+ // This is not an alias-analyser (though it would merit from becoming one, or
14
+ // at getting input from one, to be more precise). It is a pass that checks
15
+ // whether aliases are used in a safe way. Beyond that, though it doesn't have
16
+ // a lot to do with aliases, it also checks whether assignments are valid
17
+ // (using an lval, which is actually mutable), since it already has all the
18
+ // information needed to do that (and the typechecker, which would be a
19
+ // logical place for such a check, doesn't).
20
+
13
21
tag valid {
14
22
valid;
15
23
overwritten ( span, ast:: path) ;
@@ -318,6 +326,7 @@ fn check_var(&ctx cx, &@ast::expr ex, &ast::path p, ast::ann ann, bool assign,
318
326
}
319
327
}
320
328
329
+ // FIXME does not catch assigning to immutable object fields yet
321
330
fn check_assign ( & @ctx cx , & @ast:: expr dest, & @ast:: expr src,
322
331
& scope sc, & vt[ scope] v ) {
323
332
visit_expr ( cx, src, sc, v) ;
@@ -339,6 +348,18 @@ fn check_assign(&@ctx cx, &@ast::expr dest, &@ast::expr src,
339
348
check_var ( * cx, dest, p, ann, true , sc) ;
340
349
}
341
350
case ( _) {
351
+ auto root = expr_root ( * cx, dest, false ) ;
352
+ if ( vec:: len ( root. ds ) == 0 u) {
353
+ cx. tcx . sess . span_err ( dest. span , "assignment to non-lvalue" ) ;
354
+ } else if ( !root. ds . ( 0 ) . mut ) {
355
+ auto name = alt ( root. ds . ( 0 ) . kind ) {
356
+ case ( unbox) { "box" }
357
+ case ( field) { "field" }
358
+ case ( index) { "vec content" }
359
+ } ;
360
+ cx. tcx . sess . span_err
361
+ ( dest. span , "assignment to immutable " + name) ;
362
+ }
342
363
visit_expr ( cx, dest, sc, v) ;
343
364
}
344
365
}
@@ -391,7 +412,7 @@ fn deps(&scope sc, vec[def_num] roots) -> vec[uint] {
391
412
392
413
tag deref_t {
393
414
unbox;
394
- field ( ident ) ;
415
+ field;
395
416
index;
396
417
}
397
418
type deref = rec ( bool mut, deref_t kind, ty:: t outer_t ) ;
@@ -446,7 +467,7 @@ fn expr_root(&ctx cx, @ast::expr ex, bool autoderef)
446
467
case ( ty:: ty_obj ( _) ) { }
447
468
}
448
469
vec:: push ( ds, rec ( mut=mut,
449
- kind=field ( ident ) ,
470
+ kind=field,
450
471
outer_t=auto_unbox. t ) ) ;
451
472
maybe_push_auto_unbox ( auto_unbox. d , ds) ;
452
473
ex = base;
0 commit comments