about summary refs log tree commit diff
diff options
context:
space:
mode:
authorDaniel Micay <danielmicay@gmail.com>2013-08-03 23:51:29 -0400
committerDaniel Micay <danielmicay@gmail.com>2013-08-04 00:39:48 -0400
commite7bb33aed889aebae1b141cdcc2aeeebab1724ee (patch)
tree528ad739b0c54febc5ee5aaa9baf42f89dca8112
parent10089455287dcc3652b984ab4bfd6971e1b5f302 (diff)
downloadrust-e7bb33aed889aebae1b141cdcc2aeeebab1724ee.tar.gz
rust-e7bb33aed889aebae1b141cdcc2aeeebab1724ee.zip
rm obsolete `for` support from the compiler
-rw-r--r--src/librustc/middle/cfg/construct.rs1
-rw-r--r--src/librustc/middle/check_loop.rs8
-rw-r--r--src/librustc/middle/dataflow.rs47
-rw-r--r--src/librustc/middle/liveness.rs5
-rw-r--r--src/librustc/middle/mem_categorization.rs2
-rw-r--r--src/librustc/middle/moves.rs1
-rw-r--r--src/librustc/middle/trans/asm.rs3
-rw-r--r--src/librustc/middle/trans/callee.rs80
-rw-r--r--src/librustc/middle/trans/expr.rs21
-rw-r--r--src/librustc/middle/trans/meth.rs1
-rw-r--r--src/librustc/middle/trans/type_use.rs2
-rw-r--r--src/librustc/middle/ty.rs1
-rw-r--r--src/librustc/middle/typeck/check/mod.rs144
-rw-r--r--src/librustc/middle/typeck/check/regionck.rs5
-rw-r--r--src/librustc/util/common.rs3
-rw-r--r--src/libsyntax/ast.rs5
-rw-r--r--src/libsyntax/fold.rs1
-rw-r--r--src/libsyntax/oldvisit.rs2
-rw-r--r--src/libsyntax/print/pprust.rs5
-rw-r--r--src/libsyntax/visit.rs1
20 files changed, 15 insertions, 323 deletions
diff --git a/src/librustc/middle/cfg/construct.rs b/src/librustc/middle/cfg/construct.rs
index f1d8502ff5f..f34b28e1642 100644
--- a/src/librustc/middle/cfg/construct.rs
+++ b/src/librustc/middle/cfg/construct.rs
@@ -396,7 +396,6 @@ impl CFGBuilder {
             }
 
             ast::expr_addr_of(_, e) |
-            ast::expr_loop_body(e) |
             ast::expr_do_body(e) |
             ast::expr_cast(e, _) |
             ast::expr_unary(_, _, e) |
diff --git a/src/librustc/middle/check_loop.rs b/src/librustc/middle/check_loop.rs
index 0dabb304fbc..fb12f97c50c 100644
--- a/src/librustc/middle/check_loop.rs
+++ b/src/librustc/middle/check_loop.rs
@@ -45,14 +45,6 @@ pub fn check_crate(tcx: ty::ctxt, crate: &Crate) {
                                          can_ret: false
                                       }, v));
               }
-              expr_loop_body(@expr {node: expr_fn_block(_, ref b), _}) => {
-                let sigil = ty::ty_closure_sigil(ty::expr_ty(tcx, e));
-                let blk = (sigil == BorrowedSigil);
-                (v.visit_block)(b, (Context {
-                                         in_loop: true,
-                                         can_ret: blk
-                                     }, v));
-              }
               expr_break(_) => {
                 if !cx.in_loop {
                     tcx.sess.span_err(e.span, "`break` outside of loop");
diff --git a/src/librustc/middle/dataflow.rs b/src/librustc/middle/dataflow.rs
index d2808b01e5b..008add975d4 100644
--- a/src/librustc/middle/dataflow.rs
+++ b/src/librustc/middle/dataflow.rs
@@ -82,19 +82,8 @@ struct PropagationContext<'self, O> {
     changed: bool
 }
 
-#[deriving(Eq)]
-enum LoopKind {
-    /// A `while` or `loop` loop
-    TrueLoop,
-
-    /// A `for` "loop" (i.e., really a func call where `break`, `return`,
-    /// and `loop` all essentially perform an early return from the closure)
-    ForLoop
-}
-
 struct LoopScope<'self> {
     loop_id: ast::NodeId,
-    loop_kind: LoopKind,
     break_bits: ~[uint]
 }
 
@@ -509,7 +498,6 @@ impl<'self, O:DataFlowOperator> PropagationContext<'self, O> {
 
                     loop_scopes.push(LoopScope {
                         loop_id: expr.id,
-                        loop_kind: ForLoop,
                         break_bits: reslice(in_out).to_owned()
                     });
                     for input in decl.inputs.iter() {
@@ -574,7 +562,6 @@ impl<'self, O:DataFlowOperator> PropagationContext<'self, O> {
                 let mut body_bits = reslice(in_out).to_owned();
                 loop_scopes.push(LoopScope {
                     loop_id: expr.id,
-                    loop_kind: TrueLoop,
                     break_bits: reslice(in_out).to_owned()
                 });
                 self.walk_block(blk, body_bits, loop_scopes);
@@ -599,7 +586,6 @@ impl<'self, O:DataFlowOperator> PropagationContext<'self, O> {
                 self.reset(in_out);
                 loop_scopes.push(LoopScope {
                     loop_id: expr.id,
-                    loop_kind: TrueLoop,
                     break_bits: reslice(in_out).to_owned()
                 });
                 self.walk_block(blk, body_bits, loop_scopes);
@@ -646,20 +632,6 @@ impl<'self, O:DataFlowOperator> PropagationContext<'self, O> {
 
             ast::expr_ret(o_e) => {
                 self.walk_opt_expr(o_e, in_out, loop_scopes);
-
-                // is this a return from a `for`-loop closure?
-                match loop_scopes.iter().position(|s| s.loop_kind == ForLoop) {
-                    Some(i) => {
-                        // if so, add the in_out bits to the state
-                        // upon exit. Remember that we cannot count
-                        // upon the `for` loop function not to invoke
-                        // the closure again etc.
-                        self.break_from_to(expr, &mut loop_scopes[i], in_out);
-                    }
-
-                    None => {}
-                }
-
                 self.reset(in_out);
             }
 
@@ -671,22 +643,8 @@ impl<'self, O:DataFlowOperator> PropagationContext<'self, O> {
 
             ast::expr_again(label) => {
                 let scope = self.find_scope(expr, label, loop_scopes);
-
-                match scope.loop_kind {
-                    TrueLoop => {
-                        self.pop_scopes(expr, scope, in_out);
-                        self.add_to_entry_set(scope.loop_id, reslice(in_out));
-                    }
-
-                    ForLoop => {
-                        // If this `loop` construct is looping back to a `for`
-                        // loop, then `loop` is really just a return from the
-                        // closure. Therefore, we treat it the same as `break`.
-                        // See case for `expr_fn_block` for more details.
-                        self.break_from_to(expr, scope, in_out);
-                    }
-                }
-
+                self.pop_scopes(expr, scope, in_out);
+                self.add_to_entry_set(scope.loop_id, reslice(in_out));
                 self.reset(in_out);
             }
 
@@ -756,7 +714,6 @@ impl<'self, O:DataFlowOperator> PropagationContext<'self, O> {
             }
 
             ast::expr_addr_of(_, e) |
-            ast::expr_loop_body(e) |
             ast::expr_do_body(e) |
             ast::expr_cast(e, _) |
             ast::expr_unary(_, _, e) |
diff --git a/src/librustc/middle/liveness.rs b/src/librustc/middle/liveness.rs
index f4a3c2d1f39..0387f344796 100644
--- a/src/librustc/middle/liveness.rs
+++ b/src/librustc/middle/liveness.rs
@@ -512,7 +512,7 @@ fn visit_expr(expr: @expr, (this, vt): (@mut IrMaps, vt<@mut IrMaps>)) {
       // otherwise, live nodes are not required:
       expr_index(*) | expr_field(*) | expr_vstore(*) | expr_vec(*) |
       expr_call(*) | expr_method_call(*) | expr_tup(*) | expr_log(*) |
-      expr_binary(*) | expr_addr_of(*) | expr_loop_body(*) |
+      expr_binary(*) | expr_addr_of(*) |
       expr_do_body(*) | expr_cast(*) | expr_unary(*) | expr_break(_) |
       expr_again(_) | expr_lit(_) | expr_ret(*) | expr_block(*) |
       expr_assign(*) | expr_assign_op(*) | expr_mac(*) |
@@ -1209,7 +1209,6 @@ impl Liveness {
           }
 
           expr_addr_of(_, e) |
-          expr_loop_body(e) |
           expr_do_body(e) |
           expr_cast(e, _) |
           expr_unary(_, _, e) |
@@ -1483,7 +1482,7 @@ fn check_expr(expr: @expr, (this, vt): (@Liveness, vt<@Liveness>)) {
       expr_call(*) | expr_method_call(*) | expr_if(*) | expr_match(*) |
       expr_while(*) | expr_loop(*) | expr_index(*) | expr_field(*) |
       expr_vstore(*) | expr_vec(*) | expr_tup(*) | expr_log(*) |
-      expr_binary(*) | expr_loop_body(*) | expr_do_body(*) |
+      expr_binary(*) | expr_do_body(*) |
       expr_cast(*) | expr_unary(*) | expr_ret(*) | expr_break(*) |
       expr_again(*) | expr_lit(_) | expr_block(*) |
       expr_mac(*) | expr_addr_of(*) | expr_struct(*) | expr_repeat(*) |
diff --git a/src/librustc/middle/mem_categorization.rs b/src/librustc/middle/mem_categorization.rs
index 9e133972ada..6c5209cf504 100644
--- a/src/librustc/middle/mem_categorization.rs
+++ b/src/librustc/middle/mem_categorization.rs
@@ -423,7 +423,7 @@ impl mem_categorization_ctxt {
 
           ast::expr_addr_of(*) | ast::expr_call(*) |
           ast::expr_assign(*) | ast::expr_assign_op(*) |
-          ast::expr_fn_block(*) | ast::expr_ret(*) | ast::expr_loop_body(*) |
+          ast::expr_fn_block(*) | ast::expr_ret(*) |
           ast::expr_do_body(*) | ast::expr_unary(*) |
           ast::expr_method_call(*) | ast::expr_cast(*) | ast::expr_vstore(*) |
           ast::expr_vec(*) | ast::expr_tup(*) | ast::expr_if(*) |
diff --git a/src/librustc/middle/moves.rs b/src/librustc/middle/moves.rs
index b151f313b96..0c553843cd1 100644
--- a/src/librustc/middle/moves.rs
+++ b/src/librustc/middle/moves.rs
@@ -541,7 +541,6 @@ impl VisitContext {
                 self.consume_expr(count, visitor);
             }
 
-            expr_loop_body(base) |
             expr_do_body(base) => {
                 self.use_expr(base, comp_mode, visitor);
             }
diff --git a/src/librustc/middle/trans/asm.rs b/src/librustc/middle/trans/asm.rs
index 0b64defd78a..e54724b02ad 100644
--- a/src/librustc/middle/trans/asm.rs
+++ b/src/librustc/middle/trans/asm.rs
@@ -41,7 +41,6 @@ pub fn trans_inline_asm(bcx: @mut Block, ia: &ast::inline_asm) -> @mut Block {
                                    ty::ByCopy,
                                    out,
                                    &mut cleanups,
-                                   None,
                                    callee::DontAutorefArg)
         }));
 
@@ -56,7 +55,6 @@ pub fn trans_inline_asm(bcx: @mut Block, ia: &ast::inline_asm) -> @mut Block {
                                    ty::ByCopy,
                                    e,
                                    &mut cleanups,
-                                   None,
                                    callee::DontAutorefArg)
         })
 
@@ -77,7 +75,6 @@ pub fn trans_inline_asm(bcx: @mut Block, ia: &ast::inline_asm) -> @mut Block {
                                    ty::ByCopy,
                                    input,
                                    &mut cleanups,
-                                   None,
                                    callee::DontAutorefArg)
         })
 
diff --git a/src/librustc/middle/trans/callee.rs b/src/librustc/middle/trans/callee.rs
index 577c4fa021b..581ffa5252c 100644
--- a/src/librustc/middle/trans/callee.rs
+++ b/src/librustc/middle/trans/callee.rs
@@ -27,7 +27,6 @@ use middle::trans::base;
 use middle::trans::base::*;
 use middle::trans::build::*;
 use middle::trans::callee;
-use middle::trans::closure;
 use middle::trans::common;
 use middle::trans::common::*;
 use middle::trans::datum::*;
@@ -556,29 +555,9 @@ pub fn trans_call_inner(in_cx: @mut Block,
                         autoref_arg: AutorefArg)
                         -> Result {
     do base::with_scope_result(in_cx, call_info, "call") |cx| {
-        let ret_in_loop = match args {
-          ArgExprs(args) => {
-            args.len() > 0u && match args.last().node {
-              ast::expr_loop_body(@ast::expr {
-                node: ast::expr_fn_block(_, ref body),
-                _
-              }) =>  body_contains_ret(body),
-              _ => false
-            }
-          }
-          _ => false
-        };
-
         let callee = get_callee(cx);
         let mut bcx = callee.bcx;
         let ccx = cx.ccx();
-        let ret_flag = if ret_in_loop {
-            let flag = alloca(bcx, Type::bool(), "__ret_flag");
-            Store(bcx, C_bool(false), flag);
-            Some(flag)
-        } else {
-            None
-        };
 
         let (llfn, llenv) = unsafe {
             match callee.data {
@@ -611,9 +590,7 @@ pub fn trans_call_inner(in_cx: @mut Block,
         }
 
         llargs.push(llenv);
-        bcx = trans_args(bcx, args, fn_expr_ty,
-                         ret_flag, autoref_arg, &mut llargs);
-
+        bcx = trans_args(bcx, args, fn_expr_ty, autoref_arg, &mut llargs);
 
         // Now that the arguments have finished evaluating, we need to revoke
         // the cleanup for the self argument
@@ -667,20 +644,6 @@ pub fn trans_call_inner(in_cx: @mut Block,
 
         if ty::type_is_bot(ret_ty) {
             Unreachable(bcx);
-        } else if ret_in_loop {
-            let ret_flag_result = bool_to_i1(bcx, Load(bcx, ret_flag.get()));
-            bcx = do with_cond(bcx, ret_flag_result) |bcx| {
-                {
-                    let r = bcx.fcx.loop_ret;
-                    for &(flagptr, _) in r.iter() {
-                        Store(bcx, C_bool(true), flagptr);
-                        Store(bcx, C_bool(false), bcx.fcx.llretptr.get());
-                    }
-                }
-                base::cleanup_and_leave(bcx, None, Some(bcx.fcx.get_llreturn()));
-                Unreachable(bcx);
-                bcx
-            }
         }
         rslt(bcx, llresult)
     }
@@ -713,7 +676,6 @@ pub fn trans_ret_slot(bcx: @mut Block, fn_ty: ty::t, dest: Option<expr::Dest>)
 pub fn trans_args(cx: @mut Block,
                   args: CallArgs,
                   fn_ty: ty::t,
-                  ret_flag: Option<ValueRef>,
                   autoref_arg: AutorefArg,
                   llargs: &mut ~[ValueRef]) -> @mut Block
 {
@@ -728,7 +690,6 @@ pub fn trans_args(cx: @mut Block,
     // to cast her view of the arguments to the caller's view.
     match args {
       ArgExprs(arg_exprs) => {
-        let last = arg_exprs.len() - 1u;
         for (i, arg_expr) in arg_exprs.iter().enumerate() {
             let arg_val = unpack_result!(bcx, {
                 trans_arg_expr(bcx,
@@ -736,7 +697,6 @@ pub fn trans_args(cx: @mut Block,
                                ty::ByCopy,
                                *arg_expr,
                                &mut temp_cleanups,
-                               if i == last { ret_flag } else { None },
                                autoref_arg)
             });
             llargs.push(arg_val);
@@ -769,49 +729,17 @@ pub fn trans_arg_expr(bcx: @mut Block,
                       self_mode: ty::SelfMode,
                       arg_expr: @ast::expr,
                       temp_cleanups: &mut ~[ValueRef],
-                      ret_flag: Option<ValueRef>,
                       autoref_arg: AutorefArg) -> Result {
     let _icx = push_ctxt("trans_arg_expr");
     let ccx = bcx.ccx();
 
-    debug!("trans_arg_expr(formal_arg_ty=(%s), self_mode=%?, arg_expr=%s, \
-            ret_flag=%?)",
+    debug!("trans_arg_expr(formal_arg_ty=(%s), self_mode=%?, arg_expr=%s)",
            formal_arg_ty.repr(bcx.tcx()),
            self_mode,
-           arg_expr.repr(bcx.tcx()),
-           ret_flag.map(|v| bcx.val_to_str(*v)));
+           arg_expr.repr(bcx.tcx()));
 
     // translate the arg expr to a datum
-    let arg_datumblock = match ret_flag {
-        None => expr::trans_to_datum(bcx, arg_expr),
-
-        // If there is a ret_flag, this *must* be a loop body
-        Some(_) => {
-            match arg_expr.node {
-                ast::expr_loop_body(
-                    blk @ @ast::expr {
-                        node: ast::expr_fn_block(ref decl, ref body),
-                        _
-                    }) => {
-                    let scratch_ty = expr_ty(bcx, arg_expr);
-                    let scratch = alloc_ty(bcx, scratch_ty, "__ret_flag");
-                    let arg_ty = expr_ty(bcx, arg_expr);
-                    let sigil = ty::ty_closure_sigil(arg_ty);
-                    let bcx = closure::trans_expr_fn(
-                        bcx, sigil, decl, body, arg_expr.id,
-                        blk.id, Some(ret_flag), expr::SaveIn(scratch));
-                    DatumBlock {bcx: bcx,
-                                datum: Datum {val: scratch,
-                                              ty: scratch_ty,
-                                              mode: ByRef(RevokeClean)}}
-                }
-                _ => {
-                    bcx.sess().impossible_case(
-                        arg_expr.span, "ret_flag with non-loop-body expr");
-                }
-            }
-        }
-    };
+    let arg_datumblock = expr::trans_to_datum(bcx, arg_expr);
     let arg_datum = arg_datumblock.datum;
     let bcx = arg_datumblock.bcx;
 
diff --git a/src/librustc/middle/trans/expr.rs b/src/librustc/middle/trans/expr.rs
index 8cdbd943af7..a44f9321488 100644
--- a/src/librustc/middle/trans/expr.rs
+++ b/src/librustc/middle/trans/expr.rs
@@ -605,27 +605,6 @@ fn trans_rvalue_dps_unadjusted(bcx: @mut Block, expr: @ast::expr,
                                           expr.id, expr.id,
                                           None, dest);
         }
-        ast::expr_loop_body(blk) => {
-            let expr_ty = expr_ty(bcx, expr);
-            let sigil = ty::ty_closure_sigil(expr_ty);
-            match blk.node {
-                ast::expr_fn_block(ref decl, ref body) => {
-                    return closure::trans_expr_fn(bcx,
-                                                  sigil,
-                                                  decl,
-                                                  body,
-                                                  expr.id,
-                                                  blk.id,
-                                                  Some(None),
-                                                  dest);
-                }
-                _ => {
-                    bcx.sess().impossible_case(
-                        expr.span,
-                        "loop_body has the wrong kind of contents")
-                }
-            }
-        }
         ast::expr_do_body(blk) => {
             return trans_into(bcx, blk, dest);
         }
diff --git a/src/librustc/middle/trans/meth.rs b/src/librustc/middle/trans/meth.rs
index ade41151f34..b67d88c07e1 100644
--- a/src/librustc/middle/trans/meth.rs
+++ b/src/librustc/middle/trans/meth.rs
@@ -137,7 +137,6 @@ pub fn trans_self_arg(bcx: @mut Block,
                    mentry.self_mode,
                    base,
                    temp_cleanups,
-                   None,
                    DontAutorefArg)
 }
 
diff --git a/src/librustc/middle/trans/type_use.rs b/src/librustc/middle/trans/type_use.rs
index 5a722e8e695..42d5527ee43 100644
--- a/src/librustc/middle/trans/type_use.rs
+++ b/src/librustc/middle/trans/type_use.rs
@@ -400,7 +400,7 @@ pub fn mark_for_expr(cx: &Context, e: &expr) {
       expr_match(*) | expr_block(_) | expr_if(*) | expr_while(*) |
       expr_break(_) | expr_again(_) | expr_unary(*) | expr_lit(_) |
       expr_mac(_) | expr_addr_of(*) | expr_ret(_) | expr_loop(*) |
-      expr_loop_body(_) | expr_do_body(_) => (),
+      expr_do_body(_) => (),
 
       expr_for_loop(*) => fail!("non-desugared expr_for_loop")
     }
diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs
index 0e90452fdfa..29b975cdf99 100644
--- a/src/librustc/middle/ty.rs
+++ b/src/librustc/middle/ty.rs
@@ -3192,7 +3192,6 @@ pub fn expr_kind(tcx: ctxt,
         ast::expr_if(*) |
         ast::expr_match(*) |
         ast::expr_fn_block(*) |
-        ast::expr_loop_body(*) |
         ast::expr_do_body(*) |
         ast::expr_block(*) |
         ast::expr_repeat(*) |
diff --git a/src/librustc/middle/typeck/check/mod.rs b/src/librustc/middle/typeck/check/mod.rs
index 4ab79ac1c8f..7f486f77447 100644
--- a/src/librustc/middle/typeck/check/mod.rs
+++ b/src/librustc/middle/typeck/check/mod.rs
@@ -170,10 +170,6 @@ pub struct inherited {
 
 #[deriving(Clone)]
 pub enum FnKind {
-    // This is a for-closure.  The ty::t is the return type of the
-    // enclosing function.
-    ForLoop(ty::t),
-
     // A do-closure.
     DoBlock,
 
@@ -230,8 +226,6 @@ pub struct FnCtxt {
     err_count_on_creation: uint,
 
     ret_ty: ty::t,
-    // Used by loop bodies that return from the outer function
-    indirect_ret_ty: Option<ty::t>,
     ps: PurityState,
 
     // Sometimes we generate region pointers where the precise region
@@ -283,7 +277,6 @@ pub fn blank_fn_ctxt(ccx: @mut CrateCtxt,
     @mut FnCtxt {
         err_count_on_creation: ccx.tcx.sess.err_count(),
         ret_ty: rty,
-        indirect_ret_ty: None,
         ps: PurityState::function(ast::impure_fn, 0),
         region_lb: region_bnd,
         in_scope_regions: @Nil,
@@ -390,17 +383,9 @@ pub fn check_fn(ccx: @mut CrateCtxt,
     // Create the function context.  This is either derived from scratch or,
     // in the case of function expressions, based on the outer context.
     let fcx: @mut FnCtxt = {
-        // In a for-loop, you have an 'indirect return' because return
-        // does not return out of the directly enclosing fn
-        let indirect_ret_ty = match fn_kind {
-            ForLoop(t) => Some(t),
-            DoBlock | Vanilla => None
-        };
-
         @mut FnCtxt {
             err_count_on_creation: err_count_on_creation,
             ret_ty: ret_ty,
-            indirect_ret_ty: indirect_ret_ty,
             ps: PurityState::function(purity, id),
             region_lb: body.id,
             in_scope_regions: isr,
@@ -958,11 +943,6 @@ impl FnCtxt {
             return;
         }
         match self.fn_kind {
-            ForLoop(_) if !ty::type_is_bool(e) && !ty::type_is_nil(a) =>
-                    self.tcx().sess.span_err(sp, fmt!("A for-loop body must \
-                        return (), but it returns %s here. \
-                        Perhaps you meant to write a `do`-block?",
-                                            ppaux::ty_to_str(self.tcx(), a))),
             DoBlock if ty::type_is_bool(e) && ty::type_is_nil(a) =>
                 // If we expected bool and got ()...
                     self.tcx().sess.span_err(sp, fmt!("Do-block body must \
@@ -1274,7 +1254,7 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt,
 
             for (i, arg) in args.iter().enumerate() {
                 let is_block = match arg.node {
-                    ast::expr_fn_block(*) | ast::expr_loop_body(*) |
+                    ast::expr_fn_block(*) |
                     ast::expr_do_body(*) => true,
                     _ => false
                 };
@@ -2126,121 +2106,6 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt,
         fcx.write_ty(id, enum_type);
     }
 
-    fn check_loop_body(fcx: @mut FnCtxt,
-                       expr: @ast::expr,
-                       expected: Option<ty::t>,
-                       loop_body: @ast::expr) {
-        // a loop body is the special argument to a `for` loop.  We know that
-        // there will be an expected type in this context because it can only
-        // appear in the context of a call, so we get the expected type of the
-        // parameter. The catch here is that we need to validate two things:
-        // 1. a closure that returns a bool is expected
-        // 2. the closure that was given returns unit
-        let tcx = fcx.tcx();
-        let mut err_happened = false;
-        let expected_sty = unpack_expected(fcx,
-                                           expected,
-                                           |x| Some((*x).clone()));
-        let inner_ty = match expected_sty {
-            Some(ty::ty_closure(ref fty)) => {
-                match fcx.mk_subty(false, infer::Misc(expr.span),
-                                   fty.sig.output, ty::mk_bool()) {
-                    result::Ok(_) => {
-                        ty::mk_closure(tcx, ty::ClosureTy {
-                            sig: FnSig {
-                                output: ty::mk_nil(),
-                                ..fty.sig.clone()
-                            },
-                            ..(*fty).clone()
-                        })
-                    }
-                    result::Err(_) => {
-                        fcx.type_error_message(
-                            expr.span,
-                            |actual| {
-                                let did_you_mean = {
-                                    if ty::type_is_nil(fty.sig.output) {
-                                        "\nDid you mean to use \
-                                             `do` instead of `for`?"
-                                     } else {
-                                         ""
-                                     }
-                                };
-                                fmt!("A `for` loop iterator should expect a \
-                                      closure that returns `bool`. This \
-                                      iterator expects a closure that \
-                                      returns `%s`.%s",
-                                     actual, did_you_mean)
-                            },
-                            fty.sig.output,
-                            None);
-                        err_happened = true;
-                        fcx.write_error(expr.id);
-                        ty::mk_err()
-                    }
-                }
-            }
-            _ => {
-                match expected {
-                    Some(expected_t) => {
-                        fcx.type_error_message(
-                            expr.span,
-                            |actual| {
-                                fmt!("last argument in `for` call \
-                                      has non-closure type: %s",
-                                     actual)
-                            },
-                            expected_t, None);
-                        let err_ty = ty::mk_err();
-                        fcx.write_error(expr.id);
-                        err_happened = true;
-                        err_ty
-                    }
-                    None => fcx.tcx().sess.impossible_case(
-                        expr.span,
-                        "loop body must have an expected type")
-                }
-            }
-        };
-
-        match loop_body.node {
-            ast::expr_fn_block(ref decl, ref body) => {
-                // If an error occurred, we pretend this isn't a for
-                // loop, so as to assign types to all nodes while also
-                // propagating ty_err throughout so as to suppress
-                // derived errors. If we passed in ForLoop in the
-                // error case, we'd potentially emit a spurious error
-                // message because of the indirect_ret_ty.
-                let fn_kind = if err_happened {
-                    Vanilla
-                } else {
-                    let indirect_ret_ty =
-                        fcx.indirect_ret_ty.get_or_default(fcx.ret_ty);
-                    ForLoop(indirect_ret_ty)
-                };
-                check_expr_fn(fcx, loop_body, None,
-                              decl, body, fn_kind, Some(inner_ty));
-                demand::suptype(fcx, loop_body.span,
-                                inner_ty, fcx.expr_ty(loop_body));
-            }
-            ref n => {
-                fail!("check_loop_body expected expr_fn_block, not %?", n)
-            }
-        }
-
-        let block_ty = structurally_resolved_type(
-            fcx, expr.span, fcx.node_ty(loop_body.id));
-        if err_happened {
-            fcx.write_error(expr.id);
-            fcx.write_error(loop_body.id);
-        } else {
-            let loop_body_ty =
-                ty::replace_closure_return_type(
-                    tcx, block_ty, ty::mk_bool());
-            fcx.write_ty(expr.id, loop_body_ty);
-        }
-    }
-
     let tcx = fcx.ccx.tcx;
     let id = expr.id;
     match expr.node {
@@ -2494,9 +2359,7 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt,
       ast::expr_break(_) => { fcx.write_bot(id); }
       ast::expr_again(_) => { fcx.write_bot(id); }
       ast::expr_ret(expr_opt) => {
-        let ret_ty = match fcx.indirect_ret_ty {
-          Some(t) =>  t, None => fcx.ret_ty
-        };
+        let ret_ty = fcx.ret_ty;
         match expr_opt {
           None => match fcx.mk_eqty(false, infer::Misc(expr.span),
                                     ret_ty, ty::mk_nil()) {
@@ -2581,9 +2444,6 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt,
         check_expr_fn(fcx, expr, None,
                       decl, body, Vanilla, expected);
       }
-      ast::expr_loop_body(loop_body) => {
-          check_loop_body(fcx, expr, expected, loop_body);
-      }
       ast::expr_do_body(b) => {
         let expected_sty = unpack_expected(fcx,
                                            expected,
diff --git a/src/librustc/middle/typeck/check/regionck.rs b/src/librustc/middle/typeck/check/regionck.rs
index 3da70668434..18e7295d61a 100644
--- a/src/librustc/middle/typeck/check/regionck.rs
+++ b/src/librustc/middle/typeck/check/regionck.rs
@@ -426,10 +426,6 @@ fn visit_expr(expr: @ast::expr, (rcx, v): (@mut Rcx, rvt)) {
             oldvisit::visit_expr(expr, (rcx, v));
         }
 
-        ast::expr_loop_body(subexpr) => {
-            check_expr_fn_block(rcx, subexpr, v, true);
-        }
-
         ast::expr_fn_block(*) => {
             check_expr_fn_block(rcx, expr, v, false);
         }
@@ -1031,7 +1027,6 @@ pub mod guarantor {
             ast::expr_if(*) |
             ast::expr_match(*) |
             ast::expr_fn_block(*) |
-            ast::expr_loop_body(*) |
             ast::expr_do_body(*) |
             ast::expr_block(*) |
             ast::expr_repeat(*) |
diff --git a/src/librustc/util/common.rs b/src/librustc/util/common.rs
index 7ed2d00e7c4..26c22eed08c 100644
--- a/src/librustc/util/common.rs
+++ b/src/librustc/util/common.rs
@@ -70,8 +70,7 @@ pub fn loop_query(b: &ast::Block, p: @fn(&ast::expr_) -> bool) -> bool {
         match e.node {
           // Skip inner loops, since a break in the inner loop isn't a
           // break inside the outer loop
-          ast::expr_loop(*) | ast::expr_while(*)
-          | ast::expr_loop_body(*) => {}
+          ast::expr_loop(*) | ast::expr_while(*) => {}
           _ => oldvisit::visit_expr(e, (flag, v))
         }
     };
diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs
index 11f2c7005bc..cf7a1e51798 100644
--- a/src/libsyntax/ast.rs
+++ b/src/libsyntax/ast.rs
@@ -472,11 +472,6 @@ pub enum expr_ {
     expr_loop(Block, Option<ident>),
     expr_match(@expr, ~[arm]),
     expr_fn_block(fn_decl, Block),
-    // Inner expr is always an expr_fn_block. We need the wrapping node to
-    // easily type this (a function returning nil on the inside but bool on
-    // the outside).
-    expr_loop_body(@expr),
-    // Like expr_loop_body but for 'do' blocks
     expr_do_body(@expr),
     expr_block(Block),
 
diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs
index 000f9c73797..7ffed13940e 100644
--- a/src/libsyntax/fold.rs
+++ b/src/libsyntax/fold.rs
@@ -541,7 +541,6 @@ pub fn noop_fold_expr(e: &expr_, fld: @ast_fold) -> expr_ {
                 fld.fold_expr(ohs)
             )
         }
-        expr_loop_body(f) => expr_loop_body(fld.fold_expr(f)),
         expr_do_body(f) => expr_do_body(fld.fold_expr(f)),
         expr_lit(_) => (*e).clone(),
         expr_cast(expr, ref ty) => {
diff --git a/src/libsyntax/oldvisit.rs b/src/libsyntax/oldvisit.rs
index d5296e60dd3..295003c6ef5 100644
--- a/src/libsyntax/oldvisit.rs
+++ b/src/libsyntax/oldvisit.rs
@@ -501,7 +501,7 @@ pub fn visit_expr<E:Clone>(ex: @expr, (e, v): (E, vt<E>)) {
             (v.visit_expr)(b, (e.clone(), v));
         }
         expr_addr_of(_, x) | expr_unary(_, _, x) |
-        expr_loop_body(x) | expr_do_body(x) => (v.visit_expr)(x, (e.clone(), v)),
+        expr_do_body(x) => (v.visit_expr)(x, (e.clone(), v)),
         expr_lit(_) => (),
         expr_cast(x, ref t) => {
             (v.visit_expr)(x, (e.clone(), v));
diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs
index c3fcacdf7b0..174b0f8e451 100644
--- a/src/libsyntax/print/pprust.rs
+++ b/src/libsyntax/print/pprust.rs
@@ -1087,7 +1087,7 @@ pub fn print_call_post(s: @ps,
         nbsp(s);
         match blk.get().node {
           // need to handle closures specifically
-          ast::expr_do_body(e) | ast::expr_loop_body(e) => {
+          ast::expr_do_body(e) => {
             end(s); // we close our head box; closure
                     // will create it's own.
             print_expr(s, e);
@@ -1338,9 +1338,6 @@ pub fn print_expr(s: @ps, expr: &ast::expr) {
         // empty box to satisfy the close.
         ibox(s, 0);
       }
-      ast::expr_loop_body(body) => {
-        print_expr(s, body);
-      }
       ast::expr_do_body(body) => {
         print_expr(s, body);
       }
diff --git a/src/libsyntax/visit.rs b/src/libsyntax/visit.rs
index 15864fab258..7aa52bc13e3 100644
--- a/src/libsyntax/visit.rs
+++ b/src/libsyntax/visit.rs
@@ -513,7 +513,6 @@ pub fn visit_expr<E:Clone>(visitor: @Visitor<E>, expression: @expr, env: E) {
         }
         expr_addr_of(_, subexpression) |
         expr_unary(_, _, subexpression) |
-        expr_loop_body(subexpression) |
         expr_do_body(subexpression) => {
             visitor.visit_expr(subexpression, env.clone())
         }