about summary refs log tree commit diff
path: root/src/comp
diff options
context:
space:
mode:
authorGraydon Hoare <graydon@mozilla.com>2011-01-20 15:54:38 -0800
committerGraydon Hoare <graydon@mozilla.com>2011-01-20 15:54:38 -0800
commit45fd05ac4293e9cb9bbcf0ec89539f54d0de6059 (patch)
treea74a737b9469f0996e1bfd3afdeacb41d6e4a73d /src/comp
parent61379af1a979aa7813aa9470e2558953eef166b6 (diff)
downloadrust-45fd05ac4293e9cb9bbcf0ec89539f54d0de6059.tar.gz
rust-45fd05ac4293e9cb9bbcf0ec89539f54d0de6059.zip
Teach ty and typeck about linear for loops.
Diffstat (limited to 'src/comp')
-rw-r--r--src/comp/middle/ty.rs1
-rw-r--r--src/comp/middle/typeck.rs85
2 files changed, 56 insertions, 30 deletions
diff --git a/src/comp/middle/ty.rs b/src/comp/middle/ty.rs
index 182e25219c3..f27595a157c 100644
--- a/src/comp/middle/ty.rs
+++ b/src/comp/middle/ty.rs
@@ -646,6 +646,7 @@ fn expr_ty(@ast.expr expr) -> @t {
         case (ast.expr_lit(_, ?ann))          { ret ann_to_type(ann); }
         case (ast.expr_cast(_, _, ?ann))      { ret ann_to_type(ann); }
         case (ast.expr_if(_, _, _, ?ann))     { ret ann_to_type(ann); }
+        case (ast.expr_for(_, _, _, ?ann))    { ret ann_to_type(ann); }
         case (ast.expr_while(_, _, ?ann))     { ret ann_to_type(ann); }
         case (ast.expr_do_while(_, _, ?ann))  { ret ann_to_type(ann); }
         case (ast.expr_alt(_, _, ?ann))       { ret ann_to_type(ann); }
diff --git a/src/comp/middle/typeck.rs b/src/comp/middle/typeck.rs
index d159c76f3ff..02e6eaaac50 100644
--- a/src/comp/middle/typeck.rs
+++ b/src/comp/middle/typeck.rs
@@ -721,6 +721,10 @@ fn demand_expr(&@fn_ctxt fcx, @ty.t expected, @ast.expr e) -> @ast.expr {
             }
             e_1 = ast.expr_if(cond, then_1, else_1, ast.ann_type(t));
         }
+        case (ast.expr_for(?decl, ?seq, ?bloc, ?ann)) {
+            auto t = demand(fcx, e.span, expected, ann_to_type(ann));
+            e_1 = ast.expr_for(decl, seq, bloc, ast.ann_type(t));
+        }
         case (ast.expr_while(?cond, ?bloc, ?ann)) {
             auto t = demand(fcx, e.span, expected, ann_to_type(ann));
             e_1 = ast.expr_while(cond, bloc, ast.ann_type(t));
@@ -1055,6 +1059,20 @@ fn check_expr(&@fn_ctxt fcx, @ast.expr expr) -> @ast.expr {
                                                     ast.ann_type(elsopt_t)));
         }
 
+        case (ast.expr_for(?decl, ?seq, ?body, _)) {
+            auto decl_1 = check_decl_local(fcx, decl);
+            auto seq_1 = check_expr(fcx, seq);
+            auto body_1 = check_block(fcx, body);
+
+            // FIXME: enforce that the type of the decl is the element type
+            // of the seq.
+
+            auto ann = ast.ann_type(plain_ty(ty.ty_nil));
+            ret @fold.respan[ast.expr_](expr.span,
+                                        ast.expr_for(decl_1, seq_1,
+                                                     body_1, ann));
+        }
+
         case (ast.expr_while(?cond, ?body, _)) {
             auto cond_0 = check_expr(fcx, cond);
             auto cond_1 = demand_expr(fcx, plain_ty(ty.ty_bool), cond_0);
@@ -1413,40 +1431,47 @@ fn next_ty_var(@crate_ctxt ccx) -> @ty.t {
     ret t;
 }
 
+fn check_decl_local(&@fn_ctxt fcx, &@ast.decl decl) -> @ast.decl {
+    alt (decl.node) {
+        case (ast.decl_local(?local)) {
+
+            auto local_ty;
+            alt (local.ty) {
+                case (none[@ast.ty]) {
+                    // Auto slot. Assign a ty_var.
+                    local_ty = next_ty_var(fcx.ccx);
+                }
+
+                case (some[@ast.ty](?ast_ty)) {
+                    local_ty = ast_ty_to_ty_crate(fcx.ccx, ast_ty);
+                }
+            }
+            fcx.locals.insert(local.id, local_ty);
+
+            auto rhs_ty = local_ty;
+            auto init = local.init;
+            alt (local.init) {
+                case (some[@ast.expr](?expr)) {
+                    auto expr_0 = check_expr(fcx, expr);
+                    auto lty = plain_ty(ty.ty_local(local.id));
+                    auto expr_1 = demand_expr(fcx, lty, expr_0);
+                    init = some[@ast.expr](expr_1);
+                }
+                case (_) { /* fall through */  }
+            }
+            auto local_1 = @rec(init = init with *local);
+            ret @rec(node=ast.decl_local(local_1)
+                     with *decl);
+        }
+    }
+}
+
 fn check_stmt(&@fn_ctxt fcx, &@ast.stmt stmt) -> @ast.stmt {
     alt (stmt.node) {
         case (ast.stmt_decl(?decl)) {
             alt (decl.node) {
-                case (ast.decl_local(?local)) {
-
-                    auto local_ty;
-                    alt (local.ty) {
-                        case (none[@ast.ty]) {
-                            // Auto slot. Assign a ty_var.
-                            local_ty = next_ty_var(fcx.ccx);
-                        }
-
-                        case (some[@ast.ty](?ast_ty)) {
-                            local_ty = ast_ty_to_ty_crate(fcx.ccx, ast_ty);
-                        }
-                    }
-                    fcx.locals.insert(local.id, local_ty);
-
-                    auto rhs_ty = local_ty;
-                    auto init = local.init;
-                    alt (local.init) {
-                        case (some[@ast.expr](?expr)) {
-                            auto expr_0 = check_expr(fcx, expr);
-                            auto lty = plain_ty(ty.ty_local(local.id));
-                            auto expr_1 = demand_expr(fcx, lty, expr_0);
-                            init = some[@ast.expr](expr_1);
-                        }
-                        case (_) { /* fall through */  }
-                    }
-
-                    auto local_1 = @rec(init = init with *local);
-                    auto decl_1 = @rec(node=ast.decl_local(local_1)
-                                       with *decl);
+                case (ast.decl_local(_)) {
+                    auto decl_1 = check_decl_local(fcx, decl);
                     ret @fold.respan[ast.stmt_](stmt.span,
                                                 ast.stmt_decl(decl_1));
                 }