diff --git a/src/comp/front/ast.rs b/src/comp/front/ast.rs
index 5999388ee12ce..59a928be88a86 100644
--- a/src/comp/front/ast.rs
+++ b/src/comp/front/ast.rs
@@ -223,7 +223,7 @@ tag expr_ {
     expr_unary(unop, @expr, ann);
     expr_lit(@lit, ann);
     expr_cast(@expr, @ty, ann);
-    expr_if(@expr, block, vec[tup(@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_for_each(@decl, @expr, block, ann);
diff --git a/src/comp/front/eval.rs b/src/comp/front/eval.rs
index efa9aa0d92802..21a764df06141 100644
--- a/src/comp/front/eval.rs
+++ b/src/comp/front/eval.rs
@@ -289,7 +289,7 @@ impure fn eval_crate_directive_expr(parser p,
 
     alt (x.node) {
 
-        case (ast.expr_if(?cond, ?thn, ?elifs, ?elopt, _)) {
+        case (ast.expr_if(?cond, ?thn, ?elopt, _)) {
             auto cv = eval_expr(sess, e, cond);
             if (!val_is_bool(cv)) {
                 sess.span_err(x.span, "bad cond type in 'if'");
@@ -301,24 +301,11 @@ impure fn eval_crate_directive_expr(parser p,
                                                index);
             }
 
-            for (tup(@ast.expr, ast.block) elif in elifs) {
-                auto cv = eval_expr(sess, e, elif._0);
-                if (!val_is_bool(cv)) {
-                    sess.span_err(x.span, "bad cond type in 'else if'");
-                }
-
-                if (val_as_bool(cv)) {
-                    ret eval_crate_directive_block(p, e, elif._1, prefix,
-                                                   view_items, items,
-                                                   index);
-                }
-            }
-
             alt (elopt) {
-                case (some[ast.block](?els)) {
-                    ret eval_crate_directive_block(p, e, els, prefix,
-                                                   view_items, items,
-                                                   index);
+                case (some[@ast.expr](?els)) {
+                    ret eval_crate_directive_expr(p, e, els, prefix,
+                                                  view_items, items,
+                                                  index);
                 }
                 case (_) {
                     // Absent-else is ok.
@@ -353,6 +340,12 @@ impure fn eval_crate_directive_expr(parser p,
             sess.span_err(x.span, "no cases matched in 'alt'");
         }
 
+        case (ast.expr_block(?block, _)) {
+            ret eval_crate_directive_block(p, e, block, prefix,
+                                           view_items, items,
+                                           index);
+        }
+
         case (_) {
             sess.span_err(x.span, "unsupported expr type");
         }
diff --git a/src/comp/front/parser.rs b/src/comp/front/parser.rs
index 45cec0c0d2337..653e45a1ebf07 100644
--- a/src/comp/front/parser.rs
+++ b/src/comp/front/parser.rs
@@ -1094,40 +1094,32 @@ 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.expr] els = none[@ast.expr];
     hi = thn.span;
-
-    let vec[tup(@ast.expr, ast.block)] elifs = vec();
-    let option.t[ast.block] els = none[ast.block];
-    let bool parsing_elses = true;
-    while (parsing_elses) {
-        alt (p.peek()) {
-            case (token.ELSE) {
-                expect(p, token.ELSE);
-                alt (p.peek()) {
-                    case (token.IF) {
-                        expect(p, token.IF);
-                        expect(p, token.LPAREN);
-                        auto elifcond = parse_expr(p);
-                        expect(p, token.RPAREN);
-                        auto elifthn = parse_block(p);
-                        elifs += tup(elifcond, elifthn);
-                        hi = elifthn.span;
-                    }
-                    case (_) {
-                        auto eblk = parse_block(p);
-                        els = some(eblk);
-                        hi = eblk.span;
-                        parsing_elses = false;
-                    }
-                }
-            }
-            case (_) {
-                parsing_elses = false;
-            }
+    alt (p.peek()) {
+        case (token.ELSE) {
+            auto elexpr = parse_else_expr(p);
+            els = some(elexpr);
+            hi = elexpr.span;
         }
+        case (_) { /* fall through */ }
     }
 
-    ret @spanned(lo, hi, ast.expr_if(cond, thn, elifs, els, ast.ann_none));
+    ret @spanned(lo, hi, ast.expr_if(cond, thn, els, ast.ann_none));
+}
+
+impure fn parse_else_expr(parser p) -> @ast.expr {
+    expect(p, token.ELSE);
+    alt (p.peek()) {
+        case (token.IF) {
+            ret parse_if_expr(p);
+        }
+        case (_) {
+            auto blk = parse_block(p);
+            ret @spanned(blk.span, blk.span,
+                         ast.expr_block(blk, ast.ann_none));
+        }
+    }
 }
 
 impure fn parse_head_local(parser p) -> @ast.decl {
@@ -1530,7 +1522,7 @@ fn stmt_ends_with_semi(@ast.stmt stmt) -> bool {
                 case (ast.expr_unary(_,_,_))    { ret true; }
                 case (ast.expr_lit(_,_))        { ret true; }
                 case (ast.expr_cast(_,_,_))     { ret true; }
-                case (ast.expr_if(_,_,_,_,_))   { ret false; }
+                case (ast.expr_if(_,_,_,_))     { ret false; }
                 case (ast.expr_for(_,_,_,_))    { ret false; }
                 case (ast.expr_for_each(_,_,_,_))
                     { ret false; }
diff --git a/src/comp/middle/fold.rs b/src/comp/middle/fold.rs
index 17a2a2ca37424..bbe6f84172bcd 100644
--- a/src/comp/middle/fold.rs
+++ b/src/comp/middle/fold.rs
@@ -105,8 +105,7 @@ type ast_fold[ENV] =
 
      (fn(&ENV e, &span sp,
          @expr cond, &block thn,
-         &vec[tup(@expr, block)] elifs,
-         &option.t[block] els,
+         &option.t[@expr] els,
          ann a) -> @expr)                         fold_expr_if,
 
      (fn(&ENV e, &span sp,
@@ -565,27 +564,17 @@ fn fold_expr[ENV](&ENV env, ast_fold[ENV] fld, &@expr e) -> @expr {
             ret fld.fold_expr_cast(env_, e.span, ee, tt, at);
         }
 
-        case (ast.expr_if(?cnd, ?thn, ?elifs, ?els, ?t)) {
+        case (ast.expr_if(?cnd, ?thn, ?els, ?t)) {
             auto ccnd = fold_expr(env_, fld, cnd);
             auto tthn = fold_block(env_, fld, thn);
-
-            let vec[tup(@ast.expr, ast.block)] eelifs = vec();
-            for (tup(@expr, block) elif in elifs) {
-                auto elifcnd = elif._0;
-                auto elifthn = elif._1;
-                auto elifccnd = fold_expr(env_, fld, elifcnd);
-                auto eliftthn = fold_block(env_, fld, elifthn);
-                eelifs += tup(elifccnd, eliftthn);
-            }
-
-            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 */  }
             }
-            ret fld.fold_expr_if(env_, e.span, ccnd, tthn, eelifs, eels, t);
+            ret fld.fold_expr_if(env_, e.span, ccnd, tthn, eels, t);
         }
 
         case (ast.expr_for(?decl, ?seq, ?body, ?t)) {
@@ -1137,9 +1126,8 @@ 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,
-                              &vec[tup(@expr, block)] elifs,
-                              &option.t[block] els, ann a) -> @expr {
-    ret @respan(sp, ast.expr_if(cond, thn, elifs, els, a));
+                              &option.t[@expr] els, ann a) -> @expr {
+    ret @respan(sp, ast.expr_if(cond, thn, els, a));
 }
 
 fn identity_fold_expr_for[ENV](&ENV env, &span sp,
@@ -1483,7 +1471,7 @@ fn new_identity_fold[ENV]() -> ast_fold[ENV] {
          fold_expr_unary  = bind identity_fold_expr_unary[ENV](_,_,_,_,_),
          fold_expr_lit    = bind identity_fold_expr_lit[ENV](_,_,_,_),
          fold_expr_cast   = bind identity_fold_expr_cast[ENV](_,_,_,_,_),
-         fold_expr_if     = bind identity_fold_expr_if[ENV](_,_,_,_,_,_,_),
+         fold_expr_if     = bind identity_fold_expr_if[ENV](_,_,_,_,_,_),
          fold_expr_for    = bind identity_fold_expr_for[ENV](_,_,_,_,_,_),
          fold_expr_for_each
              = bind identity_fold_expr_for_each[ENV](_,_,_,_,_,_),
diff --git a/src/comp/middle/trans.rs b/src/comp/middle/trans.rs
index 6485054231711..6dcfb5c0a04fd 100644
--- a/src/comp/middle/trans.rs
+++ b/src/comp/middle/trans.rs
@@ -2833,9 +2833,8 @@ fn join_results(@block_ctxt parent_cx,
     ret res(join_cx, phi);
 }
 
-fn trans_if(@block_ctxt cx, @ast.expr cond, &ast.block thn,
-            &vec[tup(@ast.expr, ast.block)] elifs,
-            &option.t[ast.block] els) -> result {
+fn trans_if(@block_ctxt cx, @ast.expr cond,
+            &ast.block thn, &option.t[@ast.expr] els) -> result {
 
     auto cond_res = trans_expr(cx, cond);
 
@@ -2845,25 +2844,11 @@ fn trans_if(@block_ctxt cx, @ast.expr cond, &ast.block thn,
     auto else_cx = new_scope_block_ctxt(cx, "else");
     auto else_res = res(else_cx, C_nil());
 
-    auto num_elifs = _vec.len[tup(@ast.expr, ast.block)](elifs);
-    if (num_elifs > 0u) {
-        auto next_elif = elifs.(0u);
-        auto next_elifthn = next_elif._0;
-        auto next_elifcnd = next_elif._1;
-        auto rest_elifs = _vec.shift[tup(@ast.expr, ast.block)](elifs);
-        else_res = trans_if(else_cx, next_elifthn, next_elifcnd,
-                            rest_elifs, els);
-    }
-
-    /* else: FIXME: rustboot has a problem here
-       with preconditions inside an else block */
-    if (num_elifs == 0u)  {
-        alt (els) {
-            case (some[ast.block](?eblk)) {
-                else_res = trans_block(else_cx, eblk);
-            }
-            case (_) { /* fall through */ }
+    alt (els) {
+        case (some[@ast.expr](?elexpr)) {
+            else_res = trans_expr(else_cx, elexpr);
         }
+        case (_) { /* fall through */ }
     }
 
     cond_res.bcx.build.CondBr(cond_res.val,
@@ -4303,8 +4288,8 @@ fn trans_expr(@block_ctxt cx, @ast.expr e) -> result {
             ret trans_binary(cx, op, x, y);
         }
 
-        case (ast.expr_if(?cond, ?thn, ?elifs, ?els, _)) {
-            ret trans_if(cx, cond, thn, elifs, els);
+        case (ast.expr_if(?cond, ?thn, ?els, _)) {
+            ret trans_if(cx, cond, thn, els);
         }
 
         case (ast.expr_for(?decl, ?seq, ?body, _)) {
@@ -4328,14 +4313,7 @@ fn trans_expr(@block_ctxt cx, @ast.expr e) -> result {
         }
 
         case (ast.expr_block(?blk, _)) {
-            auto sub_cx = new_scope_block_ctxt(cx, "block-expr body");
-            auto next_cx = new_sub_block_ctxt(cx, "next");
-            auto sub = trans_block(sub_cx, blk);
-
-            cx.build.Br(sub_cx.llbb);
-            sub.bcx.build.Br(next_cx.llbb);
-
-            ret res(next_cx, sub.val);
+            ret trans_block(cx, blk);
         }
 
         case (ast.expr_assign(?dst, ?src, ?ann)) {
diff --git a/src/comp/middle/ty.rs b/src/comp/middle/ty.rs
index bd3e3263820b8..0a161810e0203 100644
--- a/src/comp/middle/ty.rs
+++ b/src/comp/middle/ty.rs
@@ -702,7 +702,7 @@ fn expr_ty(@ast.expr expr) -> @t {
         case (ast.expr_unary(_, _, ?ann))     { ret ann_to_type(ann); }
         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_if(_, _, _, ?ann))     { ret ann_to_type(ann); }
         case (ast.expr_for(_, _, _, ?ann))    { ret ann_to_type(ann); }
         case (ast.expr_for_each(_, _, _, ?ann))
                                               { ret ann_to_type(ann); }
diff --git a/src/comp/middle/typeck.rs b/src/comp/middle/typeck.rs
index 7dfe918c065be..b2f371c5f9e27 100644
--- a/src/comp/middle/typeck.rs
+++ b/src/comp/middle/typeck.rs
@@ -1263,28 +1263,20 @@ fn demand_expr_full(&@fn_ctxt fcx, @ty.t expected, @ast.expr e,
             e_1 = ast.expr_cast(sube, ast_ty,
                                 ast.ann_type(t, none[vec[@ty.t]]));
         }
-        case (ast.expr_if(?cond, ?then_0, ?elifs_0, ?else_0, ?ann)) {
+        case (ast.expr_if(?cond, ?then_0, ?else_0, ?ann)) {
             auto t = demand_full(fcx, e.span, expected,
                                  ann_to_type(ann), adk);
             auto then_1 = demand_block(fcx, expected, then_0);
 
-            let vec[tup(@ast.expr, ast.block)] elifs_1 = vec();
-            for (tup(@ast.expr, ast.block) elif in elifs_0) {
-                auto elifcond = elif._0;
-                auto elifthn_0 = elif._1;
-                auto elifthn_1 = demand_block(fcx, expected, elifthn_0);
-                elifs_1 += tup(elifcond, elifthn_1);
-            }
-
             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, elifs_1, else_1,
+            e_1 = ast.expr_if(cond, then_1, else_1,
                               ast.ann_type(t, none[vec[@ty.t]]));
         }
         case (ast.expr_for(?decl, ?seq, ?bloc, ?ann)) {
@@ -1795,39 +1787,24 @@ fn check_expr(&@fn_ctxt fcx, @ast.expr expr) -> @ast.expr {
                                                            ann));
         }
 
-        case (ast.expr_if(?cond, ?thn, ?elifs, ?elsopt, _)) {
+        case (ast.expr_if(?cond, ?thn, ?elsopt, _)) {
             auto cond_0 = check_expr(fcx, cond);
             auto cond_1 = demand_expr(fcx, plain_ty(ty.ty_bool), cond_0);
 
             auto thn_0 = check_block(fcx, thn);
             auto thn_t = block_ty(thn_0);
 
-            auto num_elifs = _vec.len[tup(@ast.expr, ast.block)](elifs);
-            let vec[tup(@ast.expr, ast.block)] elifs_1 = vec();
-            for each (uint i in _uint.range(0u, num_elifs)) {
-                auto elif = elifs.(i);
-                auto elifcond = elif._0;
-                auto elifcond_0 = check_expr(fcx, cond);
-                auto elifcond_1 = demand_expr(fcx,
-                                              plain_ty(ty.ty_bool),
-                                              elifcond_0);
-                auto elifthn = elif._1;
-                auto elifthn_0 = check_block(fcx, elifthn);
-                auto elifthn_1 = demand_block(fcx, thn_t, elifthn_0);
-                elifs_1 += tup(elifcond_1, elifthn_1);
-            }
-
             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);
                 }
             }
@@ -1837,7 +1814,7 @@ fn check_expr(&@fn_ctxt fcx, @ast.expr expr) -> @ast.expr {
             auto ann = ast.ann_type(elsopt_t, none[vec[@ty.t]]);
             ret @fold.respan[ast.expr_](expr.span,
                                         ast.expr_if(cond_1, thn_1,
-                                                    elifs_1, elsopt_1, ann));
+                                                    elsopt_1, ann));
         }
 
         case (ast.expr_for(?decl, ?seq, ?body, _)) {
diff --git a/src/comp/pretty/pprust.rs b/src/comp/pretty/pprust.rs
index 9ef9bb1614127..2b64b8e41696e 100644
--- a/src/comp/pretty/pprust.rs
+++ b/src/comp/pretty/pprust.rs
@@ -366,26 +366,18 @@ impure fn print_expr(ps s, @ast.expr expr) {
       wrd1(s, "as");
       print_type(s, ty);
     }
-    case (ast.expr_if(?test,?block,?clauses,?_else,_)) {
-      impure fn print_clause(ps s, @ast.expr test, ast.block blk) {
-        wrd1(s, "if");
-        popen(s);
-        print_expr(s, test);
-        pclose(s);
-        space(s);
-        print_block(s, blk);
-      }
-      print_clause(s, test, block);
-      for (tup(@ast.expr, ast.block) clause in clauses) {
-        space(s);
-        wrd1(s, "else");
-        print_clause(s, clause._0, clause._1);
-      }
-      alt (_else) {
-        case (option.some[ast.block](?blk)) {
+    case (ast.expr_if(?test,?block,?elseopt,_)) {
+      wrd1(s, "if");
+      popen(s);
+      print_expr(s, test);
+      pclose(s);
+      space(s);
+      print_block(s, block);
+      alt (elseopt) {
+        case (option.some[@ast.expr](?_else)) {
           space(s);
           wrd1(s, "else");
-          print_block(s, blk);
+          print_expr(s, _else);
         }
         case (_) { /* fall through */ }
       }