about summary refs log tree commit diff
diff options
context:
space:
mode:
authorBrian Anderson <andersrb@gmail.com>2011-01-31 23:06:02 -0500
committerBrian Anderson <andersrb@gmail.com>2011-02-01 00:08:47 -0500
commit3fedb18c0af0bd9fa5e4973936003c0b57e4d3e8 (patch)
tree69adf95963fda1fedd3338d30f095f73d1c37c77
parentc848ed1e9862a527e0a6f16ef235b41f98baa419 (diff)
downloadrust-3fedb18c0af0bd9fa5e4973936003c0b57e4d3e8.tar.gz
rust-3fedb18c0af0bd9fa5e4973936003c0b57e4d3e8.zip
Allow the else part of an expr_if to be either expr_if or expr_block
-rw-r--r--src/comp/front/ast.rs2
-rw-r--r--src/comp/front/parser.rs19
-rw-r--r--src/comp/middle/fold.rs10
-rw-r--r--src/comp/middle/trans.rs17
-rw-r--r--src/comp/middle/typeck.rs37
5 files changed, 55 insertions, 30 deletions
diff --git a/src/comp/front/ast.rs b/src/comp/front/ast.rs
index 10bcd5c4562..fb068dba4aa 100644
--- a/src/comp/front/ast.rs
+++ b/src/comp/front/ast.rs
@@ -149,7 +149,7 @@ tag expr_ {
     expr_unary(unop, @expr, ann);
     expr_lit(@lit, ann);
     expr_cast(@expr, @ty, ann);
-    expr_if(@expr, block, option.t[block], ann);
+    expr_if(@expr, block, option.t[@expr], ann);
     expr_while(@expr, block, ann);
     expr_for(@decl, @expr, block, ann);
     expr_do_while(block, @expr, ann);
diff --git a/src/comp/front/parser.rs b/src/comp/front/parser.rs
index fbed877fbd8..e629683c2f8 100644
--- a/src/comp/front/parser.rs
+++ b/src/comp/front/parser.rs
@@ -891,30 +891,29 @@ impure fn parse_if_expr(parser p) -> @ast.expr {
     auto cond = parse_expr(p);
     expect(p, token.RPAREN);
     auto thn = parse_block(p);
-    let option.t[ast.block] els = none[ast.block];
+    let option.t[@ast.expr] els = none[@ast.expr];
     hi = thn.span;
     alt (p.peek()) {
         case (token.ELSE) {
-            auto eblk = parse_else_block(p);
-            els = some(eblk);
-            hi = eblk.span;
+            auto elexpr = parse_else_expr(p);
+            els = some(elexpr);
+            hi = elexpr.span;
         }
         case (_) { /* fall through */ }
     }
     ret @spanned(lo, hi, ast.expr_if(cond, thn, els, ast.ann_none));
 }
 
-impure fn parse_else_block(parser p) -> ast.block {
+impure fn parse_else_expr(parser p) -> @ast.expr {
     expect(p, token.ELSE);
     alt (p.peek()) {
         case (token.IF) {
-            let vec[@ast.stmt] stmts = vec();
-            auto ifexpr = parse_if_expr(p);
-            auto bloc = index_block(stmts, some(ifexpr));
-            ret spanned(ifexpr.span, ifexpr.span, bloc);
+            ret parse_if_expr(p);
         }
         case (_) {
-            ret parse_block(p);
+            auto blk = parse_block(p);
+            ret @spanned(blk.span, blk.span,
+                         ast.expr_block(blk, ast.ann_none));
         }
     }
 }
diff --git a/src/comp/middle/fold.rs b/src/comp/middle/fold.rs
index 67c260140b7..ca10e79fe2d 100644
--- a/src/comp/middle/fold.rs
+++ b/src/comp/middle/fold.rs
@@ -100,7 +100,7 @@ type ast_fold[ENV] =
 
      (fn(&ENV e, &span sp,
          @expr cond, &block thn,
-         &option.t[block] els,
+         &option.t[@expr] els,
          ann a) -> @expr)                         fold_expr_if,
 
      (fn(&ENV e, &span sp,
@@ -504,10 +504,10 @@ fn fold_expr[ENV](&ENV env, ast_fold[ENV] fld, &@expr e) -> @expr {
         case (ast.expr_if(?cnd, ?thn, ?els, ?t)) {
             auto ccnd = fold_expr(env_, fld, cnd);
             auto tthn = fold_block(env_, fld, thn);
-            auto eels = none[block];
+            auto eels = none[@expr];
             alt (els) {
-                case (some[block](?b)) {
-                    eels = some(fold_block(env_, fld, b));
+                case (some[@expr](?e)) {
+                    eels = some(fold_expr(env_, fld, e));
                 }
                 case (_) { /* fall through */  }
             }
@@ -961,7 +961,7 @@ fn identity_fold_expr_cast[ENV](&ENV env, &span sp, @ast.expr e,
 
 fn identity_fold_expr_if[ENV](&ENV env, &span sp,
                               @expr cond, &block thn,
-                              &option.t[block] els, ann a) -> @expr {
+                              &option.t[@expr] els, ann a) -> @expr {
     ret @respan(sp, ast.expr_if(cond, thn, els, a));
 }
 
diff --git a/src/comp/middle/trans.rs b/src/comp/middle/trans.rs
index 8eb614e5da3..c2b0ae48bbc 100644
--- a/src/comp/middle/trans.rs
+++ b/src/comp/middle/trans.rs
@@ -1931,7 +1931,7 @@ fn join_results(@block_ctxt parent_cx,
 }
 
 fn trans_if(@block_ctxt cx, @ast.expr cond,
-            &ast.block thn, &option.t[ast.block] els) -> result {
+            &ast.block thn, &option.t[@ast.expr] els) -> result {
 
     auto cond_res = trans_expr(cx, cond);
 
@@ -1942,8 +1942,19 @@ fn trans_if(@block_ctxt cx, @ast.expr cond,
     auto else_res = res(else_cx, C_nil());
 
     alt (els) {
-        case (some[ast.block](?eblk)) {
-            else_res = trans_block(else_cx, eblk);
+        case (some[@ast.expr](?elexpr)) {
+            // FIXME: Shouldn't need to unwrap the block here,
+            // instead just use 'else_res = trans_expr(else_cx, elexpr)',
+            // but either a) trans_expr doesn't handle expr_block
+            // correctly or b) I have no idea what I'm doing...
+            alt (elexpr.node) {
+                case (ast.expr_if(_, _, _, _)) {
+                    else_res = trans_expr(else_cx, elexpr);
+                }
+                case (ast.expr_block(?b, _)) {
+                    else_res = trans_block(else_cx, b);
+                }
+            }
         }
         case (_) { /* fall through */ }
     }
diff --git a/src/comp/middle/typeck.rs b/src/comp/middle/typeck.rs
index ea9002aeccb..d778ffa96d0 100644
--- a/src/comp/middle/typeck.rs
+++ b/src/comp/middle/typeck.rs
@@ -870,10 +870,10 @@ fn demand_expr_full(&@fn_ctxt fcx, @ty.t expected, @ast.expr e,
             auto then_1 = demand_block(fcx, expected, then_0);
             auto else_1;
             alt (else_0) {
-                case (none[ast.block]) { else_1 = none[ast.block]; }
-                case (some[ast.block](?b_0)) {
-                    auto b_1 = demand_block(fcx, expected, b_0);
-                    else_1 = some[ast.block](b_1);
+                case (none[@ast.expr]) { else_1 = none[@ast.expr]; }
+                case (some[@ast.expr](?e_0)) {
+                    auto e_1 = demand_expr(fcx, expected, e_0);
+                    else_1 = some[@ast.expr](e_1);
                 }
             }
             e_1 = ast.expr_if(cond, then_1, else_1, ast.ann_type(t));
@@ -1205,14 +1205,14 @@ fn check_expr(&@fn_ctxt fcx, @ast.expr expr) -> @ast.expr {
             auto elsopt_1;
             auto elsopt_t;
             alt (elsopt) {
-                case (some[ast.block](?els)) {
-                    auto els_0 = check_block(fcx, els);
-                    auto els_1 = demand_block(fcx, thn_t, els_0);
-                    elsopt_1 = some[ast.block](els_1);
-                    elsopt_t = block_ty(els_1);
+                case (some[@ast.expr](?els)) {
+                    auto els_0 = check_expr(fcx, els);
+                    auto els_1 = demand_expr(fcx, thn_t, els_0);
+                    elsopt_1 = some[@ast.expr](els_1);
+                    elsopt_t = expr_ty(els_1);
                 }
-                case (none[ast.block]) {
-                    elsopt_1 = none[ast.block];
+                case (none[@ast.expr]) {
+                    elsopt_1 = none[@ast.expr];
                     elsopt_t = plain_ty(ty.ty_nil);
                 }
             }
@@ -1308,6 +1308,21 @@ fn check_expr(&@fn_ctxt fcx, @ast.expr expr) -> @ast.expr {
                                         ast.expr_alt(expr_1, arms_1, ann));
         }
 
+        case (ast.expr_block(?b, _)) {
+            auto b_0 = check_block(fcx, b);
+            auto ann;
+            alt (b_0.node.expr) {
+                case (some[@ast.expr](?expr)) {
+                    ann = ast.ann_type(expr_ty(expr));
+                }
+                case (none[@ast.expr]) {
+                    ann = ast.ann_type(plain_ty(ty.ty_nil));
+                }
+            }
+            ret @fold.respan[ast.expr_](expr.span,
+                                        ast.expr_block(b_0, ann));
+        }
+
         case (ast.expr_bind(?f, ?args, _)) {
             auto f_0 = check_expr(fcx, f);
             auto t_0 = expr_ty(f_0);