aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGraydon Hoare <[email protected]>2011-01-20 15:54:38 -0800
committerGraydon Hoare <[email protected]>2011-01-20 15:54:38 -0800
commit45fd05ac4293e9cb9bbcf0ec89539f54d0de6059 (patch)
treea74a737b9469f0996e1bfd3afdeacb41d6e4a73d /src
parentFix typo in fold. (diff)
downloadrust-45fd05ac4293e9cb9bbcf0ec89539f54d0de6059.tar.xz
rust-45fd05ac4293e9cb9bbcf0ec89539f54d0de6059.zip
Teach ty and typeck about linear for loops.
Diffstat (limited to 'src')
-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 182e2521..f27595a1 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 d159c76f..02e6eaaa 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));
}