about summary refs log tree commit diff
diff options
context:
space:
mode:
authorPatrick Walton <pcwalton@mimiga.net>2012-11-13 14:07:26 -0800
committerPatrick Walton <pcwalton@mimiga.net>2012-11-14 11:26:00 -0800
commit3e14ada4f6782f1379abe498b2b2d9681f489e26 (patch)
treee6975e425555e16dd60349c76511608b89ad86fa
parentbad62dcb04d78c53911dc464663c04b47c5215ac (diff)
downloadrust-3e14ada4f6782f1379abe498b2b2d9681f489e26.tar.gz
rust-3e14ada4f6782f1379abe498b2b2d9681f489e26.zip
rustc: Implement let assignability. r=nmatsakis
-rw-r--r--src/librustc/middle/typeck/check.rs32
-rw-r--r--src/test/run-pass/let-assignability.rs18
2 files changed, 39 insertions, 11 deletions
diff --git a/src/librustc/middle/typeck/check.rs b/src/librustc/middle/typeck/check.rs
index 970f0670e86..3d56ad3595d 100644
--- a/src/librustc/middle/typeck/check.rs
+++ b/src/librustc/middle/typeck/check.rs
@@ -868,6 +868,16 @@ fn check_expr_with(fcx: @fn_ctxt, expr: @ast::expr, expected: ty::t) -> bool {
     check_expr(fcx, expr, Some(expected))
 }
 
+fn check_expr_with_assignability(fcx: @fn_ctxt,
+                                 expr: @ast::expr,
+                                 expected: ty::t)
+                              -> bool {
+    do check_expr_with_unifier(fcx, expr, Some(expected)) {
+        demand::assign(fcx, expr.span, expected, expr)
+    }
+}
+
+
 fn check_expr(fcx: @fn_ctxt, expr: @ast::expr,
               expected: Option<ty::t>) -> bool {
     return do check_expr_with_unifier(fcx, expr, expected) {
@@ -1072,11 +1082,7 @@ fn check_expr_with_unifier(fcx: @fn_ctxt,
                         DontDerefArgs => {}
                     }
 
-                    bot |= check_expr_with_unifier(
-                        fcx, *arg, Some(formal_ty),
-                        || demand::assign(fcx, arg.span,
-                                           formal_ty, *arg)
-                    );
+                    bot |= check_expr_with_assignability(fcx, *arg, formal_ty);
                     fcx.write_ty(arg.id, fcx.expr_ty(*arg));
 
                 }
@@ -1087,10 +1093,14 @@ fn check_expr_with_unifier(fcx: @fn_ctxt,
     }
 
     // A generic function for checking assignment expressions
-    fn check_assignment(fcx: @fn_ctxt, _sp: span, lhs: @ast::expr,
-                        rhs: @ast::expr, id: ast::node_id) -> bool {
+    fn check_assignment(fcx: @fn_ctxt,
+                        lhs: @ast::expr,
+                        rhs: @ast::expr,
+                        id: ast::node_id)
+                     -> bool {
         let mut bot = check_expr(fcx, lhs, None);
-        bot |= check_expr_with(fcx, rhs, fcx.expr_ty(lhs));
+        let lhs_type = fcx.expr_ty(lhs);
+        bot |= check_expr_with_assignability(fcx, rhs, lhs_type);
         fcx.write_ty(id, ty::mk_nil(fcx.ccx.tcx));
         return bot;
     }
@@ -1908,10 +1918,10 @@ fn check_expr_with_unifier(fcx: @fn_ctxt,
         };
       }
       ast::expr_assign(lhs, rhs) => {
-        bot = check_assignment(fcx, expr.span, lhs, rhs, id);
+        bot = check_assignment(fcx, lhs, rhs, id);
       }
       ast::expr_swap(lhs, rhs) => {
-        bot = check_assignment(fcx, expr.span, lhs, rhs, id);
+        bot = check_assignment(fcx, lhs, rhs, id);
       }
       ast::expr_if(cond, thn, elsopt) => {
         bot = check_expr_with(fcx, cond, ty::mk_bool(tcx)) |
@@ -2246,7 +2256,7 @@ fn require_integral(fcx: @fn_ctxt, sp: span, t: ty::t) {
 fn check_decl_initializer(fcx: @fn_ctxt, nid: ast::node_id,
                           init: @ast::expr) -> bool {
     let lty = ty::mk_var(fcx.ccx.tcx, lookup_local(fcx, init.span, nid));
-    return check_expr_with(fcx, init, lty);
+    return check_expr_with_assignability(fcx, init, lty);
 }
 
 fn check_decl_local(fcx: @fn_ctxt, local: @ast::local) -> bool {
diff --git a/src/test/run-pass/let-assignability.rs b/src/test/run-pass/let-assignability.rs
new file mode 100644
index 00000000000..750ebbfac02
--- /dev/null
+++ b/src/test/run-pass/let-assignability.rs
@@ -0,0 +1,18 @@
+fn f() {
+    let a = ~"hello";
+    let b: &str = a;
+    io::println(b);
+}
+
+fn g() {
+    let c = ~"world";
+    let d: &str;
+    d = c;
+    io::println(d);
+}
+
+fn main() {
+    f();
+    g();
+}
+