diff --git a/src/libextra/dlist.rs b/src/libextra/dlist.rs
index 9eacddd90028b..35600df4f9dd0 100644
--- a/src/libextra/dlist.rs
+++ b/src/libextra/dlist.rs
@@ -173,11 +173,11 @@ impl<T> Deque<T> for DList<T> {
                 let tail_own = match tail.prev.resolve() {
                     None => {
                         self.list_tail = Rawlink::none();
-                        self.list_head.swap_unwrap()
+                        self.list_head.take_unwrap()
                     },
                     Some(tail_prev) => {
                         self.list_tail = tail.prev;
-                        tail_prev.next.swap_unwrap()
+                        tail_prev.next.take_unwrap()
                     }
                 };
                 Some(tail_own.value)
@@ -465,7 +465,7 @@ impl<'self, A> ListInsertion<A> for MutDListIterator<'self, A> {
                     Some(prev) => prev,
                 };
                 let mut ins_node = ~Node{value: elt, next: None, prev: Rawlink::none()};
-                let node_own = prev_node.next.swap_unwrap();
+                let node_own = prev_node.next.take_unwrap();
                 ins_node.next = link_with_prev(node_own, Rawlink::some(ins_node));
                 prev_node.next = link_with_prev(ins_node, Rawlink::some(prev_node));
                 self.list.length += 1;
diff --git a/src/libextra/net/ip.rs b/src/libextra/net/ip.rs
index 6876b3510b6ca..11e3106e4b5a9 100644
--- a/src/libextra/net/ip.rs
+++ b/src/libextra/net/ip.rs
@@ -116,7 +116,7 @@ pub fn get_addr(node: &str, iotask: &iotask)
     let (output_po, output_ch) = stream();
     let mut output_ch = Some(SharedChan::new(output_ch));
     do str::as_buf(node) |node_ptr, len| {
-        let output_ch = output_ch.swap_unwrap();
+        let output_ch = output_ch.take_unwrap();
         debug!("slice len %?", len);
         let handle = create_uv_getaddrinfo_t();
         let handle_ptr: *uv_getaddrinfo_t = &handle;
diff --git a/src/libextra/smallintmap.rs b/src/libextra/smallintmap.rs
index 27e9f8cd60f33..200e824209450 100644
--- a/src/libextra/smallintmap.rs
+++ b/src/libextra/smallintmap.rs
@@ -161,8 +161,8 @@ impl<V> SmallIntMap<V> {
     /// Visit all key-value pairs in reverse order
     pub fn each_reverse<'a>(&'a self, it: &fn(uint, &'a V) -> bool) -> bool {
         for uint::range_rev(self.v.len(), 0) |i| {
-            match self.v[i - 1] {
-              Some(ref elt) => if !it(i - 1, elt) { return false; },
+            match self.v[i] {
+              Some(ref elt) => if !it(i, elt) { return false; },
               None => ()
             }
         }
diff --git a/src/libextra/sync.rs b/src/libextra/sync.rs
index b9d25451a8a95..632f5d7827d4c 100644
--- a/src/libextra/sync.rs
+++ b/src/libextra/sync.rs
@@ -260,7 +260,7 @@ impl<'self> Condvar<'self> {
                             signal_waitqueue(&state.waiters);
                         }
                         // Enqueue ourself to be woken up by a signaller.
-                        let SignalEnd = SignalEnd.swap_unwrap();
+                        let SignalEnd = SignalEnd.take_unwrap();
                         state.blocked[condvar_id].tail.send(SignalEnd);
                     } else {
                         out_of_bounds = Some(state.blocked.len());
@@ -281,7 +281,7 @@ impl<'self> Condvar<'self> {
             // Unconditionally "block". (Might not actually block if a
             // signaller already sent -- I mean 'unconditionally' in contrast
             // with acquire().)
-            let _ = comm::recv_one(WaitEnd.swap_unwrap());
+            let _ = comm::recv_one(WaitEnd.take_unwrap());
         }
 
         // This is needed for a failing condition variable to reacquire the
@@ -353,7 +353,7 @@ impl<'self> Condvar<'self> {
                 }
             }
             do check_cvar_bounds(out_of_bounds, condvar_id, "cond.signal_on()") {
-                let queue = queue.swap_unwrap();
+                let queue = queue.take_unwrap();
                 broadcast_waitqueue(&queue)
             }
         }
@@ -1436,7 +1436,7 @@ mod tests {
         do x.write_downgrade |xwrite| {
             let mut xopt = Some(xwrite);
             do y.write_downgrade |_ywrite| {
-                y.downgrade(xopt.swap_unwrap());
+                y.downgrade(xopt.take_unwrap());
                 error!("oops, y.downgrade(x) should have failed!");
             }
         }
diff --git a/src/libextra/treemap.rs b/src/libextra/treemap.rs
index f1fe7acb00f83..bd13c8619be1d 100644
--- a/src/libextra/treemap.rs
+++ b/src/libextra/treemap.rs
@@ -552,7 +552,7 @@ fn mutate_values<'r, K: TotalOrd, V>(node: &'r mut Option<~TreeNode<K, V>>,
 // Remove left horizontal link by rotating right
 fn skew<K: TotalOrd, V>(node: &mut ~TreeNode<K, V>) {
     if node.left.map_default(false, |x| x.level == node.level) {
-        let mut save = node.left.swap_unwrap();
+        let mut save = node.left.take_unwrap();
         swap(&mut node.left, &mut save.right); // save.right now None
         swap(node, &mut save);
         node.right = Some(save);
@@ -564,7 +564,7 @@ fn skew<K: TotalOrd, V>(node: &mut ~TreeNode<K, V>) {
 fn split<K: TotalOrd, V>(node: &mut ~TreeNode<K, V>) {
     if node.right.map_default(false,
       |x| x.right.map_default(false, |y| y.level == node.level)) {
-        let mut save = node.right.swap_unwrap();
+        let mut save = node.right.take_unwrap();
         swap(&mut node.right, &mut save.left); // save.left now None
         save.level += 1;
         swap(node, &mut save);
@@ -643,7 +643,7 @@ fn remove<K: TotalOrd, V>(node: &mut Option<~TreeNode<K, V>>,
           Equal => {
             if save.left.is_some() {
                 if save.right.is_some() {
-                    let mut left = save.left.swap_unwrap();
+                    let mut left = save.left.take_unwrap();
                     if left.right.is_some() {
                         heir_swap(save, &mut left.right);
                     } else {
@@ -653,13 +653,13 @@ fn remove<K: TotalOrd, V>(node: &mut Option<~TreeNode<K, V>>,
                     save.left = Some(left);
                     (remove(&mut save.left, key), true)
                 } else {
-                    let new = save.left.swap_unwrap();
+                    let new = save.left.take_unwrap();
                     let ~TreeNode{value, _} = replace(save, new);
-                    *save = save.left.swap_unwrap();
+                    *save = save.left.take_unwrap();
                     (Some(value), true)
                 }
             } else if save.right.is_some() {
-                let new = save.right.swap_unwrap();
+                let new = save.right.take_unwrap();
                 let ~TreeNode{value, _} = replace(save, new);
                 (Some(value), true)
             } else {
diff --git a/src/librustc/middle/borrowck/check_loans.rs b/src/librustc/middle/borrowck/check_loans.rs
index a455bdc436cad..4fe9f15c7c889 100644
--- a/src/librustc/middle/borrowck/check_loans.rs
+++ b/src/librustc/middle/borrowck/check_loans.rs
@@ -639,15 +639,14 @@ fn check_loans_in_fn<'a>(fk: &visit::fn_kind,
                                 span: span) {
         let cap_vars = this.bccx.capture_map.get(&closure_id);
         for cap_vars.iter().advance |cap_var| {
+            let var_id = ast_util::def_id_of_def(cap_var.def).node;
+            let var_path = @LpVar(var_id);
+            this.check_if_path_is_moved(closure_id, span,
+                                        MovedInCapture, var_path);
             match cap_var.mode {
-                moves::CapRef | moves::CapCopy => {
-                    let var_id = ast_util::def_id_of_def(cap_var.def).node;
-                    let lp = @LpVar(var_id);
-                    this.check_if_path_is_moved(closure_id, span,
-                                                MovedInCapture, lp);
-                }
+                moves::CapRef | moves::CapCopy => {}
                 moves::CapMove => {
-                    check_by_move_capture(this, closure_id, cap_var);
+                    check_by_move_capture(this, closure_id, cap_var, var_path);
                 }
             }
         }
@@ -655,9 +654,8 @@ fn check_loans_in_fn<'a>(fk: &visit::fn_kind,
 
         fn check_by_move_capture(this: @mut CheckLoanCtxt,
                                  closure_id: ast::node_id,
-                                 cap_var: &moves::CaptureVar) {
-            let var_id = ast_util::def_id_of_def(cap_var.def).node;
-            let move_path = @LpVar(var_id);
+                                 cap_var: &moves::CaptureVar,
+                                 move_path: @LoanPath) {
             let move_err = this.analyze_move_out_from(closure_id, move_path);
             match move_err {
                 MoveOk => {}
diff --git a/src/librustc/middle/const_eval.rs b/src/librustc/middle/const_eval.rs
index af39dea6d79e1..2cf99e07dc9f1 100644
--- a/src/librustc/middle/const_eval.rs
+++ b/src/librustc/middle/const_eval.rs
@@ -165,10 +165,58 @@ pub fn classify(e: &expr,
 pub fn lookup_const(tcx: ty::ctxt, e: &expr) -> Option<@expr> {
     match tcx.def_map.find(&e.id) {
         Some(&ast::def_static(def_id, false)) => lookup_const_by_id(tcx, def_id),
+        Some(&ast::def_variant(enum_def, variant_def)) => lookup_variant_by_id(tcx,
+                                                                               enum_def,
+                                                                               variant_def),
         _ => None
     }
 }
 
+pub fn lookup_variant_by_id(tcx: ty::ctxt,
+                            enum_def: ast::def_id,
+                            variant_def: ast::def_id)
+                       -> Option<@expr> {
+    fn variant_expr(variants: &[ast::variant], id: ast::node_id) -> Option<@expr> {
+        for variants.iter().advance |variant| {
+            if variant.node.id == id {
+                return variant.node.disr_expr;
+            }
+        }
+        None
+    }
+
+    if ast_util::is_local(enum_def) {
+        match tcx.items.find(&enum_def.node) {
+            None => None,
+            Some(&ast_map::node_item(it, _)) => match it.node {
+                item_enum(ast::enum_def { variants: ref variants }, _) => {
+                    variant_expr(*variants, variant_def.node)
+                }
+                _ => None
+            },
+            Some(_) => None
+        }
+    } else {
+        let maps = astencode::Maps {
+            root_map: @mut HashMap::new(),
+            method_map: @mut HashMap::new(),
+            vtable_map: @mut HashMap::new(),
+            write_guard_map: @mut HashSet::new(),
+            capture_map: @mut HashMap::new()
+        };
+        match csearch::maybe_get_item_ast(tcx, enum_def,
+            |a, b, c, d| astencode::decode_inlined_item(a, b, maps, /*bar*/ copy c, d)) {
+            csearch::found(ast::ii_item(item)) => match item.node {
+                item_enum(ast::enum_def { variants: ref variants }, _) => {
+                    variant_expr(*variants, variant_def.node)
+                }
+                _ => None
+            },
+            _ => None
+        }
+    }
+}
+
 pub fn lookup_const_by_id(tcx: ty::ctxt,
                           def_id: ast::def_id)
                        -> Option<@expr> {
@@ -237,13 +285,13 @@ pub enum const_val {
 }
 
 pub fn eval_const_expr(tcx: middle::ty::ctxt, e: &expr) -> const_val {
-    match eval_const_expr_partial(tcx, e) {
+    match eval_const_expr_partial(&tcx, e) {
         Ok(r) => r,
         Err(s) => tcx.sess.span_fatal(e.span, s)
     }
 }
 
-pub fn eval_const_expr_partial(tcx: middle::ty::ctxt, e: &expr)
+pub fn eval_const_expr_partial<T: ty::ExprTyProvider>(tcx: &T, e: &expr)
                             -> Result<const_val, ~str> {
     use middle::ty;
     fn fromb(b: bool) -> Result<const_val, ~str> { Ok(const_int(b as i64)) }
@@ -360,7 +408,7 @@ pub fn eval_const_expr_partial(tcx: middle::ty::ctxt, e: &expr)
         }
       }
       expr_cast(base, _) => {
-        let ety = ty::expr_ty(tcx, e);
+        let ety = tcx.expr_ty(e);
         let base = eval_const_expr_partial(tcx, base);
         match /*bad*/copy base {
             Err(_) => base,
@@ -390,8 +438,8 @@ pub fn eval_const_expr_partial(tcx: middle::ty::ctxt, e: &expr)
         }
       }
       expr_path(_) => {
-          match lookup_const(tcx, e) {
-              Some(actual_e) => eval_const_expr_partial(tcx, actual_e),
+          match lookup_const(tcx.ty_ctxt(), e) {
+              Some(actual_e) => eval_const_expr_partial(&tcx.ty_ctxt(), actual_e),
               None => Err(~"Non-constant path in constant expr")
           }
       }
diff --git a/src/librustc/middle/kind.rs b/src/librustc/middle/kind.rs
index 9a75601a08288..cce5a9d85f59f 100644
--- a/src/librustc/middle/kind.rs
+++ b/src/librustc/middle/kind.rs
@@ -309,7 +309,7 @@ pub fn check_expr(e: @expr, (cx, v): (Context, visit::vt<Context>)) {
                        "explicit copy requires a copyable argument");
         }
         expr_repeat(element, count_expr, _) => {
-            let count = ty::eval_repeat_count(cx.tcx, count_expr);
+            let count = ty::eval_repeat_count(&cx.tcx, count_expr);
             if count > 1 {
                 let element_ty = ty::expr_ty(cx.tcx, element);
                 check_copy(cx, element_ty, element.span,
diff --git a/src/librustc/middle/trans/tvec.rs b/src/librustc/middle/trans/tvec.rs
index 2a16b13677428..be840f6a295dc 100644
--- a/src/librustc/middle/trans/tvec.rs
+++ b/src/librustc/middle/trans/tvec.rs
@@ -420,7 +420,7 @@ pub fn write_content(bcx: block,
                     return expr::trans_into(bcx, element, Ignore);
                 }
                 SaveIn(lldest) => {
-                    let count = ty::eval_repeat_count(bcx.tcx(), count_expr);
+                    let count = ty::eval_repeat_count(&bcx.tcx(), count_expr);
                     if count == 0 {
                         return bcx;
                     }
@@ -512,7 +512,7 @@ pub fn elements_required(bcx: block, content_expr: &ast::expr) -> uint {
         },
         ast::expr_vec(ref es, _) => es.len(),
         ast::expr_repeat(_, count_expr, _) => {
-            ty::eval_repeat_count(bcx.tcx(), count_expr)
+            ty::eval_repeat_count(&bcx.tcx(), count_expr)
         }
         _ => bcx.tcx().sess.span_bug(content_expr.span,
                                      "Unexpected evec content")
diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs
index c9bf94776c0e2..5e118b25a5fdd 100644
--- a/src/librustc/middle/ty.rs
+++ b/src/librustc/middle/ty.rs
@@ -4232,42 +4232,57 @@ pub fn normalize_ty(cx: ctxt, t: t) -> t {
     return t_norm;
 }
 
+pub trait ExprTyProvider {
+    pub fn expr_ty(&self, ex: &ast::expr) -> t;
+    pub fn ty_ctxt(&self) -> ctxt;
+}
+
+impl ExprTyProvider for ctxt {
+    pub fn expr_ty(&self, ex: &ast::expr) -> t {
+        expr_ty(*self, ex)
+    }
+
+    pub fn ty_ctxt(&self) -> ctxt {
+        *self
+    }
+}
+
 // Returns the repeat count for a repeating vector expression.
-pub fn eval_repeat_count(tcx: ctxt, count_expr: &ast::expr) -> uint {
+pub fn eval_repeat_count<T: ExprTyProvider>(tcx: &T, count_expr: &ast::expr) -> uint {
     match const_eval::eval_const_expr_partial(tcx, count_expr) {
       Ok(ref const_val) => match *const_val {
         const_eval::const_int(count) => if count < 0 {
-            tcx.sess.span_err(count_expr.span,
-                              "expected positive integer for \
-                               repeat count but found negative integer");
+            tcx.ty_ctxt().sess.span_err(count_expr.span,
+                                        "expected positive integer for \
+                                         repeat count but found negative integer");
             return 0;
         } else {
             return count as uint
         },
         const_eval::const_uint(count) => return count as uint,
         const_eval::const_float(count) => {
-            tcx.sess.span_err(count_expr.span,
-                              "expected positive integer for \
-                               repeat count but found float");
+            tcx.ty_ctxt().sess.span_err(count_expr.span,
+                                        "expected positive integer for \
+                                         repeat count but found float");
             return count as uint;
         }
         const_eval::const_str(_) => {
-            tcx.sess.span_err(count_expr.span,
-                              "expected positive integer for \
-                               repeat count but found string");
+            tcx.ty_ctxt().sess.span_err(count_expr.span,
+                                        "expected positive integer for \
+                                         repeat count but found string");
             return 0;
         }
         const_eval::const_bool(_) => {
-            tcx.sess.span_err(count_expr.span,
-                              "expected positive integer for \
-                               repeat count but found boolean");
+            tcx.ty_ctxt().sess.span_err(count_expr.span,
+                                        "expected positive integer for \
+                                         repeat count but found boolean");
             return 0;
         }
       },
       Err(*) => {
-        tcx.sess.span_err(count_expr.span,
-                          "expected constant integer for repeat count \
-                           but found variable");
+        tcx.ty_ctxt().sess.span_err(count_expr.span,
+                                    "expected constant integer for repeat count \
+                                     but found variable");
         return 0;
       }
     }
diff --git a/src/librustc/middle/typeck/astconv.rs b/src/librustc/middle/typeck/astconv.rs
index d0e793160fedc..e9297b12ed0fd 100644
--- a/src/librustc/middle/typeck/astconv.rs
+++ b/src/librustc/middle/typeck/astconv.rs
@@ -479,7 +479,7 @@ pub fn ast_ty_to_ty<AC:AstConv, RS:region_scope + Copy + 'static>(
         }
       }
       ast::ty_fixed_length_vec(ref a_mt, e) => {
-        match const_eval::eval_const_expr_partial(tcx, e) {
+        match const_eval::eval_const_expr_partial(&tcx, e) {
           Ok(ref r) => {
             match *r {
               const_eval::const_int(i) =>
diff --git a/src/librustc/middle/typeck/check/mod.rs b/src/librustc/middle/typeck/check/mod.rs
index 8ffff56a9c485..87d45294967a2 100644
--- a/src/librustc/middle/typeck/check/mod.rs
+++ b/src/librustc/middle/typeck/check/mod.rs
@@ -83,7 +83,7 @@ use middle::pat_util;
 use middle::lint::unreachable_code;
 use middle::ty::{FnSig, VariantInfo_};
 use middle::ty::{ty_param_bounds_and_ty, ty_param_substs_and_ty};
-use middle::ty::{substs, param_ty};
+use middle::ty::{substs, param_ty, ExprTyProvider};
 use middle::ty;
 use middle::typeck::astconv::AstConv;
 use middle::typeck::astconv::{ast_region_to_region, ast_ty_to_ty};
@@ -290,6 +290,16 @@ pub fn blank_fn_ctxt(ccx: @mut CrateCtxt,
     }
 }
 
+impl ExprTyProvider for FnCtxt {
+    pub fn expr_ty(&self, ex: &ast::expr) -> ty::t {
+        self.expr_ty(ex)
+    }
+
+    pub fn ty_ctxt(&self) -> ty::ctxt {
+        self.ccx.tcx
+    }
+}
+
 pub fn check_item_types(ccx: @mut CrateCtxt, crate: &ast::crate) {
     let visit = visit::mk_simple_visitor(@visit::SimpleVisitor {
         visit_item: |a| check_item(ccx, a),
@@ -797,7 +807,7 @@ impl FnCtxt {
         pat.repr(self.tcx())
     }
 
-    pub fn expr_ty(&self, ex: @ast::expr) -> ty::t {
+    pub fn expr_ty(&self, ex: &ast::expr) -> ty::t {
         match self.inh.node_types.find(&ex.id) {
             Some(&t) => t,
             None => {
@@ -2250,8 +2260,8 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt,
             }
           }
           ast::expr_repeat(element, count_expr, mutbl) => {
-            let _ = ty::eval_repeat_count(tcx, count_expr);
             check_expr_with_hint(fcx, count_expr, ty::mk_uint());
+            let _ = ty::eval_repeat_count(fcx, count_expr);
             let tt = ast_expr_vstore_to_vstore(fcx, ev, vst);
             let mutability = match vst {
                 ast::expr_vstore_mut_box | ast::expr_vstore_mut_slice => {
@@ -2730,8 +2740,8 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt,
         fcx.write_ty(id, typ);
       }
       ast::expr_repeat(element, count_expr, mutbl) => {
-        let count = ty::eval_repeat_count(tcx, count_expr);
         check_expr_with_hint(fcx, count_expr, ty::mk_uint());
+        let count = ty::eval_repeat_count(fcx, count_expr);
         let t: ty::t = fcx.infcx().next_ty_var();
         check_expr_has_type(fcx, element, t);
         let element_ty = fcx.expr_ty(element);
@@ -3126,7 +3136,7 @@ pub fn check_enum_variants(ccx: @mut CrateCtxt,
                 // that the expression is in an form that eval_const_expr can
                 // handle, so we may still get an internal compiler error
 
-                match const_eval::eval_const_expr_partial(ccx.tcx, e) {
+                match const_eval::eval_const_expr_partial(&ccx.tcx, e) {
                   Ok(const_eval::const_int(val)) => {
                     *disr_val = val as int;
                   }
diff --git a/src/librustc/middle/typeck/infer/region_inference/mod.rs b/src/librustc/middle/typeck/infer/region_inference/mod.rs
index c3b35aba5181b..2342b60ace05b 100644
--- a/src/librustc/middle/typeck/infer/region_inference/mod.rs
+++ b/src/librustc/middle/typeck/infer/region_inference/mod.rs
@@ -385,7 +385,6 @@ impl RegionVarBindings {
 
     pub fn tainted(&mut self, snapshot: uint, r0: Region) -> ~[Region] {
         /*!
-         *
          * Computes all regions that have been related to `r0` in any
          * way since the snapshot `snapshot` was taken---`r0` itself
          * will be the first entry. This is used when checking whether
diff --git a/src/libstd/num/int_macros.rs b/src/libstd/num/int_macros.rs
index 75e0bbcb71b04..cef32b5c7e445 100644
--- a/src/libstd/num/int_macros.rs
+++ b/src/libstd/num/int_macros.rs
@@ -29,28 +29,38 @@ pub static bytes : uint = ($bits / 8);
 pub static min_value: $T = (-1 as $T) << (bits - 1);
 pub static max_value: $T = min_value - 1 as $T;
 
+enum Range { Closed, HalfOpen }
+
+#[inline]
 ///
-/// Iterate over the range [`lo`..`hi`)
+/// Iterate through a range with a given step value.
 ///
-/// # Arguments
+/// Let `term` denote the closed interval `[stop-step,stop]` if `r` is Closed;
+/// otherwise `term` denotes the half-open interval `[stop-step,stop)`.
+/// Iterates through the range `[x_0, x_1, ..., x_n]` where
+/// `x_j == start + step*j`, and `x_n` lies in the interval `term`.
 ///
-/// * `lo` - lower bound, inclusive
-/// * `hi` - higher bound, exclusive
-///
-/// # Examples
-/// ~~~
-/// let mut sum = 0;
-/// for int::range(1, 5) |i| {
-///     sum += i;
-/// }
-/// assert!(sum == 10);
-/// ~~~
+/// If no such nonnegative integer `n` exists, then the iteration range
+/// is empty.
 ///
-#[inline]
-pub fn range_step(start: $T, stop: $T, step: $T, it: &fn($T) -> bool) -> bool {
+fn range_step_core(start: $T, stop: $T, step: $T, r: Range, it: &fn($T) -> bool) -> bool {
     let mut i = start;
     if step == 0 {
         fail!(~"range_step called with step == 0");
+    } else if step == (1 as $T) { // elide bounds check to tighten loop
+        while i < stop {
+            if !it(i) { return false; }
+            // no need for overflow check;
+            // cannot have i + 1 > max_value because i < stop <= max_value
+            i += (1 as $T);
+        }
+    } else if step == (-1 as $T) { // elide bounds check to tighten loop
+        while i > stop {
+            if !it(i) { return false; }
+            // no need for underflow check;
+            // cannot have i - 1 < min_value because i > stop >= min_value
+            i -= (1 as $T);
+        }
     } else if step > 0 { // ascending
         while i < stop {
             if !it(i) { return false; }
@@ -66,9 +76,55 @@ pub fn range_step(start: $T, stop: $T, step: $T, it: &fn($T) -> bool) -> bool {
             i += step;
         }
     }
-    return true;
+    match r {
+        HalfOpen => return true,
+        Closed => return (i != stop || it(i))
+    }
+}
+
+#[inline]
+///
+/// Iterate through the range [`start`..`stop`) with a given step value.
+///
+/// Iterates through the range `[x_0, x_1, ..., x_n]` where
+/// * `x_i == start + step*i`, and
+/// * `n` is the greatest nonnegative integer such that `x_n < stop`
+///
+/// (If no such `n` exists, then the iteration range is empty.)
+///
+/// # Arguments
+///
+/// * `start` - lower bound, inclusive
+/// * `stop` - higher bound, exclusive
+///
+/// # Examples
+/// ~~~
+/// let mut sum = 0;
+/// for int::range(1, 5) |i| {
+///     sum += i;
+/// }
+/// assert!(sum == 10);
+/// ~~~
+///
+pub fn range_step(start: $T, stop: $T, step: $T, it: &fn($T) -> bool) -> bool {
+    range_step_core(start, stop, step, HalfOpen, it)
+}
+
+#[inline]
+///
+/// Iterate through a range with a given step value.
+///
+/// Iterates through the range `[x_0, x_1, ..., x_n]` where
+/// `x_i == start + step*i` and `x_n <= last < step + x_n`.
+///
+/// (If no such nonnegative integer `n` exists, then the iteration
+///  range is empty.)
+///
+pub fn range_step_inclusive(start: $T, last: $T, step: $T, it: &fn($T) -> bool) -> bool {
+    range_step_core(start, last, step, Closed, it)
 }
 
+
 #[inline]
 /// Iterate over the range [`lo`..`hi`)
 pub fn range(lo: $T, hi: $T, it: &fn($T) -> bool) -> bool {
@@ -76,9 +132,10 @@ pub fn range(lo: $T, hi: $T, it: &fn($T) -> bool) -> bool {
 }
 
 #[inline]
-/// Iterate over the range [`hi`..`lo`)
+/// Iterate over the range (`hi`..`lo`]
 pub fn range_rev(hi: $T, lo: $T, it: &fn($T) -> bool) -> bool {
-    range_step(hi, lo, -1 as $T, it)
+    if hi == min_value { return true; }
+    range_step_inclusive(hi-1, lo, -1 as $T, it)
 }
 
 impl Num for $T {}
@@ -841,7 +898,7 @@ mod tests {
         for range(0,3) |i| {
             l.push(i);
         }
-        for range_rev(13,10) |i| {
+        for range_rev(14,11) |i| {
             l.push(i);
         }
         for range_step(20,26,2) |i| {
diff --git a/src/libstd/num/uint_macros.rs b/src/libstd/num/uint_macros.rs
index de1b997b14b52..54c1327fa9303 100644
--- a/src/libstd/num/uint_macros.rs
+++ b/src/libstd/num/uint_macros.rs
@@ -30,32 +30,46 @@ pub static bytes : uint = ($bits / 8);
 pub static min_value: $T = 0 as $T;
 pub static max_value: $T = 0 as $T - 1 as $T;
 
+enum Range { Closed, HalfOpen }
+
 #[inline]
-/**
- * Iterate through a range with a given step value.
- *
- * # Examples
- * ~~~ {.rust}
- * let nums = [1,2,3,4,5,6,7];
- *
- * for uint::range_step(0, nums.len() - 1, 2) |i| {
- *     println(fmt!("%d & %d", nums[i], nums[i+1]));
- * }
- * ~~~
- */
-pub fn range_step(start: $T, stop: $T, step: $T_SIGNED, it: &fn($T) -> bool) -> bool {
+///
+/// Iterate through a range with a given step value.
+///
+/// Let `term` denote the closed interval `[stop-step,stop]` if `r` is Closed;
+/// otherwise `term` denotes the half-open interval `[stop-step,stop)`.
+/// Iterates through the range `[x_0, x_1, ..., x_n]` where
+/// `x_j == start + step*j`, and `x_n` lies in the interval `term`.
+///
+/// If no such nonnegative integer `n` exists, then the iteration range
+/// is empty.
+///
+fn range_step_core(start: $T, stop: $T, step: $T_SIGNED, r: Range, it: &fn($T) -> bool) -> bool {
     let mut i = start;
     if step == 0 {
         fail!("range_step called with step == 0");
-    }
-    if step >= 0 {
+    } else if step == (1 as $T_SIGNED) { // elide bounds check to tighten loop
+        while i < stop {
+            if !it(i) { return false; }
+            // no need for overflow check;
+            // cannot have i + 1 > max_value because i < stop <= max_value
+            i += (1 as $T);
+        }
+    } else if step == (-1 as $T_SIGNED) { // elide bounds check to tighten loop
+        while i > stop {
+            if !it(i) { return false; }
+            // no need for underflow check;
+            // cannot have i - 1 < min_value because i > stop >= min_value
+            i -= (1 as $T);
+        }
+    } else if step > 0 { // ascending
         while i < stop {
             if !it(i) { return false; }
             // avoiding overflow. break if i + step > max_value
             if i > max_value - (step as $T) { return true; }
             i += step as $T;
         }
-    } else {
+    } else { // descending
         while i > stop {
             if !it(i) { return false; }
             // avoiding underflow. break if i + step < min_value
@@ -63,7 +77,52 @@ pub fn range_step(start: $T, stop: $T, step: $T_SIGNED, it: &fn($T) -> bool) ->
             i -= -step as $T;
         }
     }
-    return true;
+    match r {
+        HalfOpen => return true,
+        Closed => return (i != stop || it(i))
+    }
+}
+
+#[inline]
+///
+/// Iterate through the range [`start`..`stop`) with a given step value.
+///
+/// Iterates through the range `[x_0, x_1, ..., x_n]` where
+/// - `x_i == start + step*i`, and
+/// - `n` is the greatest nonnegative integer such that `x_n < stop`
+///
+/// (If no such `n` exists, then the iteration range is empty.)
+///
+/// # Arguments
+///
+/// * `start` - lower bound, inclusive
+/// * `stop` - higher bound, exclusive
+///
+/// # Examples
+/// ~~~ {.rust}
+/// let nums = [1,2,3,4,5,6,7];
+///
+/// for uint::range_step(0, nums.len() - 1, 2) |i| {
+///     println(fmt!("%d & %d", nums[i], nums[i+1]));
+/// }
+/// ~~~
+///
+pub fn range_step(start: $T, stop: $T, step: $T_SIGNED, it: &fn($T) -> bool) -> bool {
+    range_step_core(start, stop, step, HalfOpen, it)
+}
+
+#[inline]
+///
+/// Iterate through a range with a given step value.
+///
+/// Iterates through the range `[x_0, x_1, ..., x_n]` where
+/// `x_i == start + step*i` and `x_n <= last < step + x_n`.
+///
+/// (If no such nonnegative integer `n` exists, then the iteration
+///  range is empty.)
+///
+pub fn range_step_inclusive(start: $T, last: $T, step: $T_SIGNED, it: &fn($T) -> bool) -> bool {
+    range_step_core(start, last, step, Closed, it)
 }
 
 #[inline]
@@ -73,9 +132,10 @@ pub fn range(lo: $T, hi: $T, it: &fn($T) -> bool) -> bool {
 }
 
 #[inline]
-/// Iterate over the range [`hi`..`lo`)
+/// Iterate over the range (`hi`..`lo`]
 pub fn range_rev(hi: $T, lo: $T, it: &fn($T) -> bool) -> bool {
-    range_step(hi, lo, -1 as $T_SIGNED, it)
+    if hi == min_value { return true; }
+    range_step_inclusive(hi-1, lo, -1 as $T_SIGNED, it)
 }
 
 impl Num for $T {}
@@ -603,7 +663,7 @@ mod tests {
         for range(0,3) |i| {
             l.push(i);
         }
-        for range_rev(13,10) |i| {
+        for range_rev(14,11) |i| {
             l.push(i);
         }
         for range_step(20,26,2) |i| {
diff --git a/src/libstd/option.rs b/src/libstd/option.rs
index 222952a6dc143..b0811674a7bfa 100644
--- a/src/libstd/option.rs
+++ b/src/libstd/option.rs
@@ -203,14 +203,14 @@ impl<T> Option<T> {
     /// Apply a function to the contained value or do nothing
     pub fn mutate(&mut self, f: &fn(T) -> T) {
         if self.is_some() {
-            *self = Some(f(self.swap_unwrap()));
+            *self = Some(f(self.take_unwrap()));
         }
     }
 
     /// Apply a function to the contained value or set it to a default
     pub fn mutate_default(&mut self, def: T, f: &fn(T) -> T) {
         if self.is_some() {
-            *self = Some(f(self.swap_unwrap()));
+            *self = Some(f(self.take_unwrap()));
         } else {
             *self = Some(def);
         }
@@ -293,8 +293,8 @@ impl<T> Option<T> {
      * Fails if the value equals `None`.
      */
     #[inline]
-    pub fn swap_unwrap(&mut self) -> T {
-        if self.is_none() { fail!("option::swap_unwrap none") }
+    pub fn take_unwrap(&mut self) -> T {
+        if self.is_none() { fail!("option::take_unwrap none") }
         util::replace(self, None).unwrap()
     }
 
@@ -460,7 +460,7 @@ fn test_option_dance() {
     let mut y = Some(5);
     let mut y2 = 0;
     for x.iter().advance |_x| {
-        y2 = y.swap_unwrap();
+        y2 = y.take_unwrap();
     }
     assert_eq!(y2, 5);
     assert!(y.is_none());
@@ -468,8 +468,8 @@ fn test_option_dance() {
 #[test] #[should_fail] #[ignore(cfg(windows))]
 fn test_option_too_much_dance() {
     let mut y = Some(util::NonCopyable);
-    let _y2 = y.swap_unwrap();
-    let _y3 = y.swap_unwrap();
+    let _y2 = y.take_unwrap();
+    let _y3 = y.take_unwrap();
 }
 
 #[test]
diff --git a/src/libstd/rt/sched.rs b/src/libstd/rt/sched.rs
index 6e9aef7773051..4e4145ddc161f 100644
--- a/src/libstd/rt/sched.rs
+++ b/src/libstd/rt/sched.rs
@@ -328,7 +328,7 @@ impl Scheduler {
     /// Given an input Coroutine sends it back to its home scheduler.
     fn send_task_home(task: ~Task) {
         let mut task = task;
-        let mut home = task.home.swap_unwrap();
+        let mut home = task.home.take_unwrap();
         match home {
             Sched(ref mut home_handle) => {
                 home_handle.send(PinnedTask(task));
@@ -418,7 +418,7 @@ impl Scheduler {
 
         do self.deschedule_running_task_and_then |sched, dead_task| {
             let mut dead_task = dead_task;
-            let coroutine = dead_task.coroutine.swap_unwrap();
+            let coroutine = dead_task.coroutine.take_unwrap();
             coroutine.recycle(&mut sched.stack_pool);
         }
 
@@ -506,7 +506,7 @@ impl Scheduler {
         this.metrics.context_switches_task_to_sched += 1;
 
         unsafe {
-            let blocked_task = this.current_task.swap_unwrap();
+            let blocked_task = this.current_task.take_unwrap();
             let f_fake_region = transmute::<&fn(&mut Scheduler, ~Task),
                                             &fn(&mut Scheduler, ~Task)>(f);
             let f_opaque = ClosureConverter::from_fn(f_fake_region);
@@ -538,7 +538,7 @@ impl Scheduler {
         rtdebug!("switching tasks");
         this.metrics.context_switches_task_to_task += 1;
 
-        let old_running_task = this.current_task.swap_unwrap();
+        let old_running_task = this.current_task.take_unwrap();
         let f_fake_region = unsafe {
             transmute::<&fn(&mut Scheduler, ~Task),
                         &fn(&mut Scheduler, ~Task)>(f)
@@ -576,7 +576,7 @@ impl Scheduler {
 
         assert!(self.cleanup_job.is_some());
 
-        let cleanup_job = self.cleanup_job.swap_unwrap();
+        let cleanup_job = self.cleanup_job.take_unwrap();
         match cleanup_job {
             DoNothing => { }
             GiveTask(task, f) => (f.to_fn())(self, task)
diff --git a/src/libstd/rt/task.rs b/src/libstd/rt/task.rs
index 17d0d59660f1b..449438b920551 100644
--- a/src/libstd/rt/task.rs
+++ b/src/libstd/rt/task.rs
@@ -127,7 +127,7 @@ impl Task {
 
         // Wait for children. Possibly report the exit status.
         let local_success = !self.unwinder.unwinding;
-        let join_latch = self.join_latch.swap_unwrap();
+        let join_latch = self.join_latch.take_unwrap();
         match self.on_exit {
             Some(ref on_exit) => {
                 let success = join_latch.wait(local_success);
diff --git a/src/libstd/rt/tube.rs b/src/libstd/rt/tube.rs
index 013eb438c3657..f61eee8859b1a 100644
--- a/src/libstd/rt/tube.rs
+++ b/src/libstd/rt/tube.rs
@@ -53,7 +53,7 @@ impl<T> Tube<T> {
             if (*state).blocked_task.is_some() {
                 // There's a waiting task. Wake it up
                 rtdebug!("waking blocked tube");
-                let task = (*state).blocked_task.swap_unwrap();
+                let task = (*state).blocked_task.take_unwrap();
                 let sched = Local::take::<Scheduler>();
                 sched.resume_task_immediately(task);
             }
diff --git a/src/libstd/rt/uv/async.rs b/src/libstd/rt/uv/async.rs
index f3d1024024ff8..81428509e33e5 100644
--- a/src/libstd/rt/uv/async.rs
+++ b/src/libstd/rt/uv/async.rs
@@ -62,7 +62,7 @@ impl AsyncWatcher {
             let mut watcher: AsyncWatcher = NativeHandle::from_native_handle(handle);
             {
                 let data = watcher.get_watcher_data();
-                data.close_cb.swap_unwrap()();
+                data.close_cb.take_unwrap()();
             }
             watcher.drop_watcher_data();
             unsafe { uvll::free_handle(handle as *c_void); }
diff --git a/src/libstd/rt/uv/idle.rs b/src/libstd/rt/uv/idle.rs
index a3630c9b9bf8d..28b101f686d4c 100644
--- a/src/libstd/rt/uv/idle.rs
+++ b/src/libstd/rt/uv/idle.rs
@@ -73,7 +73,7 @@ impl IdleWatcher {
                 let mut idle_watcher: IdleWatcher = NativeHandle::from_native_handle(handle);
                 {
                     let data = idle_watcher.get_watcher_data();
-                    data.close_cb.swap_unwrap()();
+                    data.close_cb.take_unwrap()();
                 }
                 idle_watcher.drop_watcher_data();
                 uvll::idle_delete(handle);
diff --git a/src/libstd/rt/uv/net.rs b/src/libstd/rt/uv/net.rs
index 6d096f9885a7d..09c748ec04782 100644
--- a/src/libstd/rt/uv/net.rs
+++ b/src/libstd/rt/uv/net.rs
@@ -209,7 +209,7 @@ impl StreamWatcher {
             let write_request: WriteRequest = NativeHandle::from_native_handle(req);
             let mut stream_watcher = write_request.stream();
             write_request.delete();
-            let cb = stream_watcher.get_watcher_data().write_cb.swap_unwrap();
+            let cb = stream_watcher.get_watcher_data().write_cb.take_unwrap();
             let status = status_to_maybe_uv_error(stream_watcher.native_handle(), status);
             cb(stream_watcher, status);
         }
@@ -233,7 +233,7 @@ impl StreamWatcher {
 
         extern fn close_cb(handle: *uvll::uv_stream_t) {
             let mut stream_watcher: StreamWatcher = NativeHandle::from_native_handle(handle);
-            stream_watcher.get_watcher_data().close_cb.swap_unwrap()();
+            stream_watcher.get_watcher_data().close_cb.take_unwrap()();
             stream_watcher.drop_watcher_data();
             unsafe { free_handle(handle as *c_void) }
         }
@@ -301,7 +301,7 @@ impl TcpWatcher {
                 let connect_request: ConnectRequest = NativeHandle::from_native_handle(req);
                 let mut stream_watcher = connect_request.stream();
                 connect_request.delete();
-                let cb = stream_watcher.get_watcher_data().connect_cb.swap_unwrap();
+                let cb = stream_watcher.get_watcher_data().connect_cb.take_unwrap();
                 let status = status_to_maybe_uv_error(stream_watcher.native_handle(), status);
                 cb(stream_watcher, status);
             }
@@ -438,7 +438,7 @@ impl UdpWatcher {
             let send_request: UdpSendRequest = NativeHandle::from_native_handle(req);
             let mut udp_watcher = send_request.handle();
             send_request.delete();
-            let cb = udp_watcher.get_watcher_data().udp_send_cb.swap_unwrap();
+            let cb = udp_watcher.get_watcher_data().udp_send_cb.take_unwrap();
             let status = status_to_maybe_uv_error(udp_watcher.native_handle(), status);
             cb(udp_watcher, status);
         }
@@ -456,7 +456,7 @@ impl UdpWatcher {
 
         extern fn close_cb(handle: *uvll::uv_udp_t) {
             let mut udp_watcher: UdpWatcher = NativeHandle::from_native_handle(handle);
-            udp_watcher.get_watcher_data().close_cb.swap_unwrap()();
+            udp_watcher.get_watcher_data().close_cb.take_unwrap()();
             udp_watcher.drop_watcher_data();
             unsafe { free_handle(handle as *c_void) }
         }
diff --git a/src/libstd/rt/uv/timer.rs b/src/libstd/rt/uv/timer.rs
index 14465eb7dfd3a..bc5399327a032 100644
--- a/src/libstd/rt/uv/timer.rs
+++ b/src/libstd/rt/uv/timer.rs
@@ -70,7 +70,7 @@ impl TimerWatcher {
             let mut watcher: TimerWatcher = NativeHandle::from_native_handle(handle);
             {
                 let data = watcher.get_watcher_data();
-                data.close_cb.swap_unwrap()();
+                data.close_cb.take_unwrap()();
             }
             watcher.drop_watcher_data();
             unsafe {
diff --git a/src/libstd/run.rs b/src/libstd/run.rs
index 17dc604a17858..883870db1e673 100644
--- a/src/libstd/run.rs
+++ b/src/libstd/run.rs
@@ -669,7 +669,7 @@ fn spawn_process_os(prog: &str, args: &[~str],
             fail!("failure in dup3(err_fd, 2): %s", os::last_os_error());
         }
         // close all other fds
-        for int::range_rev(getdtablesize() as int - 1, 2) |fd| {
+        for int::range_rev(getdtablesize() as int, 3) |fd| {
             close(fd as c_int);
         }
 
diff --git a/src/libstd/task/spawn.rs b/src/libstd/task/spawn.rs
index 206d19e175fe9..bf09a533ebe12 100644
--- a/src/libstd/task/spawn.rs
+++ b/src/libstd/task/spawn.rs
@@ -302,7 +302,7 @@ fn each_ancestor(list:        &mut AncestorList,
         fn with_parent_tg<U>(parent_group: &mut Option<TaskGroupArc>,
                              blk: &fn(TaskGroupInner) -> U) -> U {
             // If this trips, more likely the problem is 'blk' failed inside.
-            let tmp_arc = parent_group.swap_unwrap();
+            let tmp_arc = parent_group.take_unwrap();
             let result = do access_group(&tmp_arc) |tg_opt| { blk(tg_opt) };
             *parent_group = Some(tmp_arc);
             result
@@ -609,7 +609,7 @@ fn spawn_raw_newsched(mut opts: TaskOpts, f: ~fn()) {
     };
 
     if opts.notify_chan.is_some() {
-        let notify_chan = opts.notify_chan.swap_unwrap();
+        let notify_chan = opts.notify_chan.take_unwrap();
         let notify_chan = Cell::new(notify_chan);
         let on_exit: ~fn(bool) = |success| {
             notify_chan.take().send(
@@ -647,7 +647,7 @@ fn spawn_raw_oldsched(mut opts: TaskOpts, f: ~fn()) {
             let notify_chan = if opts.notify_chan.is_none() {
                 None
             } else {
-                Some(opts.notify_chan.swap_unwrap())
+                Some(opts.notify_chan.take_unwrap())
             };
 
             let child_wrapper = make_child_wrapper(new_task, child_tg,
diff --git a/src/libstd/trie.rs b/src/libstd/trie.rs
index 3882ab0de6333..396fdaf2e6a55 100644
--- a/src/libstd/trie.rs
+++ b/src/libstd/trie.rs
@@ -287,7 +287,7 @@ impl<T> TrieNode<T> {
 
     fn each_reverse<'a>(&'a self, f: &fn(&uint, &'a T) -> bool) -> bool {
         for uint::range_rev(self.children.len(), 0) |idx| {
-            match self.children[idx - 1] {
+            match self.children[idx] {
                 Internal(ref x) => if !x.each_reverse(|i,t| f(i,t)) { return false },
                 External(k, ref v) => if !f(&k, v) { return false },
                 Nothing => ()
@@ -488,7 +488,7 @@ mod test_map {
             m.insert(x, x / 2);
         }
 
-        let mut n = uint::max_value - 9999;
+        let mut n = uint::max_value - 10000;
         for m.each |k, v| {
             if n == uint::max_value - 5000 { break }
             assert!(n < uint::max_value - 5000);
@@ -525,7 +525,7 @@ mod test_map {
             m.insert(x, x / 2);
         }
 
-        let mut n = uint::max_value;
+        let mut n = uint::max_value - 1;
         for m.each_reverse |k, v| {
             if n == uint::max_value - 5000 { break }
             assert!(n > uint::max_value - 5000);
diff --git a/src/test/bench/msgsend-ring-mutex-arcs.rs b/src/test/bench/msgsend-ring-mutex-arcs.rs
index 2bd53f81b0581..0bf492ae55f0c 100644
--- a/src/test/bench/msgsend-ring-mutex-arcs.rs
+++ b/src/test/bench/msgsend-ring-mutex-arcs.rs
@@ -60,8 +60,8 @@ fn thread_ring(i: uint, count: uint, num_chan: pipe, num_port: pipe) {
     // Send/Receive lots of messages.
     for uint::range(0u, count) |j| {
         //error!("task %?, iter %?", i, j);
-        let mut num_chan2 = num_chan.swap_unwrap();
-        let mut num_port2 = num_port.swap_unwrap();
+        let mut num_chan2 = num_chan.take_unwrap();
+        let mut num_port2 = num_port.take_unwrap();
         send(&num_chan2, i * j);
         num_chan = Some(num_chan2);
         let _n = recv(&num_port2);
diff --git a/src/test/bench/msgsend-ring-rw-arcs.rs b/src/test/bench/msgsend-ring-rw-arcs.rs
index b5b5b685d87c4..a5f96b35999e2 100644
--- a/src/test/bench/msgsend-ring-rw-arcs.rs
+++ b/src/test/bench/msgsend-ring-rw-arcs.rs
@@ -56,8 +56,8 @@ fn thread_ring(i: uint, count: uint, num_chan: pipe, num_port: pipe) {
     // Send/Receive lots of messages.
     for uint::range(0u, count) |j| {
         //error!("task %?, iter %?", i, j);
-        let mut num_chan2 = num_chan.swap_unwrap();
-        let mut num_port2 = num_port.swap_unwrap();
+        let mut num_chan2 = num_chan.take_unwrap();
+        let mut num_port2 = num_port.take_unwrap();
         send(&num_chan2, i * j);
         num_chan = Some(num_chan2);
         let _n = recv(&num_port2);
diff --git a/src/test/codegen/iterate-over-array.cc b/src/test/codegen/iterate-over-array.cc
new file mode 100644
index 0000000000000..7eca21b13d70b
--- /dev/null
+++ b/src/test/codegen/iterate-over-array.cc
@@ -0,0 +1,17 @@
+#include <stdlib.h>
+#include <assert.h>
+
+struct slice {
+  int const *p;
+  size_t len;
+};
+
+extern "C"
+size_t test(slice s) {
+  size_t y = 0;
+  for (int i = 0; i < s.len; ++i) {
+	assert(i < s.len);
+	y += s.p[i];
+  }
+  return y;
+}
diff --git a/src/test/codegen/iterate-over-array.rs b/src/test/codegen/iterate-over-array.rs
new file mode 100644
index 0000000000000..cf54e6eafbaf1
--- /dev/null
+++ b/src/test/codegen/iterate-over-array.rs
@@ -0,0 +1,10 @@
+#[no_mangle]
+fn test(x: &[int]) -> int {
+    let mut y = 0;
+    let mut i = 0;
+    while (i < x.len()) {
+        y += x[i];
+        i += 1;
+    }
+    y
+}
diff --git a/src/test/codegen/scalar-function-call.cc b/src/test/codegen/scalar-function-call.cc
new file mode 100644
index 0000000000000..91ed882f68a9f
--- /dev/null
+++ b/src/test/codegen/scalar-function-call.cc
@@ -0,0 +1,10 @@
+#include <stdlib.h>
+
+size_t foo(size_t x) {
+    return x * x;
+}
+
+extern "C"
+void test() {
+    size_t x = foo(10);
+}
diff --git a/src/test/codegen/scalar-function-call.rs b/src/test/codegen/scalar-function-call.rs
new file mode 100644
index 0000000000000..7e4a566749ba6
--- /dev/null
+++ b/src/test/codegen/scalar-function-call.rs
@@ -0,0 +1,8 @@
+fn foo(x: int) -> int {
+    x * x
+}
+
+#[no_mangle]
+fn test() {
+    let x = foo(10);
+}
diff --git a/src/test/codegen/small-dense-int-switch.cc b/src/test/codegen/small-dense-int-switch.cc
new file mode 100644
index 0000000000000..87bc5bf852eb4
--- /dev/null
+++ b/src/test/codegen/small-dense-int-switch.cc
@@ -0,0 +1,11 @@
+#include <stdlib.h>
+
+extern "C"
+size_t test(size_t x, size_t y) {
+  switch (x) {
+  case 1: return y;
+  case 2: return y*2;
+  case 4: return y*3;
+  default: return 11;
+  }
+}
diff --git a/src/test/codegen/small-dense-int-switch.rs b/src/test/codegen/small-dense-int-switch.rs
new file mode 100644
index 0000000000000..6840dc7411b34
--- /dev/null
+++ b/src/test/codegen/small-dense-int-switch.rs
@@ -0,0 +1,9 @@
+#[no_mangle]
+fn test(x: int, y: int) -> int {
+    match x {
+        1 => y,
+        2 => y*2,
+        4 => y*3,
+        _ => 11
+    }
+}
diff --git a/src/test/codegen/hello.cc b/src/test/codegen/stack-alloc-string-slice.cc
similarity index 100%
rename from src/test/codegen/hello.cc
rename to src/test/codegen/stack-alloc-string-slice.cc
diff --git a/src/test/codegen/hello.rs b/src/test/codegen/stack-alloc-string-slice.rs
similarity index 100%
rename from src/test/codegen/hello.rs
rename to src/test/codegen/stack-alloc-string-slice.rs
diff --git a/src/test/compile-fail/borrowck-move-by-capture.rs b/src/test/compile-fail/borrowck-move-by-capture.rs
index 4ee824d1d49ad..ecb18993d9300 100644
--- a/src/test/compile-fail/borrowck-move-by-capture.rs
+++ b/src/test/compile-fail/borrowck-move-by-capture.rs
@@ -4,8 +4,10 @@ pub fn main() {
     let _f: @fn() -> int = || *foo + 5;
     //~^ ERROR cannot move `foo`
 
+    // FIXME(#2202) - Due to the way that borrowck treats closures,
+    // you get two error reports here.
     let bar = ~3;
     let _g = || { //~ ERROR capture of moved value
-        let _h: @fn() -> int = || *bar;
+        let _h: @fn() -> int = || *bar; //~ ERROR capture of moved value
     };
 }
diff --git a/src/test/compile-fail/borrowck-move-moved-value-into-closure.rs b/src/test/compile-fail/borrowck-move-moved-value-into-closure.rs
new file mode 100644
index 0000000000000..5e789e99c0559
--- /dev/null
+++ b/src/test/compile-fail/borrowck-move-moved-value-into-closure.rs
@@ -0,0 +1,10 @@
+fn call_f(f: ~fn:Send() -> int) -> int {
+    f()
+}
+
+fn main() {
+    let t = ~3;
+
+    call_f(|| { *t + 1 });
+    call_f(|| { *t + 1 }); //~ ERROR capture of moved value
+}
diff --git a/src/test/run-pass/borrowck-move-by-capture-ok.rs b/src/test/run-pass/borrowck-move-by-capture-ok.rs
new file mode 100644
index 0000000000000..095e2ba6fea4b
--- /dev/null
+++ b/src/test/run-pass/borrowck-move-by-capture-ok.rs
@@ -0,0 +1,5 @@
+pub fn main() {
+    let bar = ~3;
+    let h: @fn() -> int = || *bar;
+    assert_eq!(h(), 3);
+}
diff --git a/src/test/run-pass/enum-vec-initializer.rs b/src/test/run-pass/enum-vec-initializer.rs
new file mode 100644
index 0000000000000..ae590ad7d1f71
--- /dev/null
+++ b/src/test/run-pass/enum-vec-initializer.rs
@@ -0,0 +1,24 @@
+// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+enum Flopsy {
+    Bunny = 2
+}
+
+static BAR:uint = Bunny as uint;
+static BAR2:uint = BAR;
+
+fn main() {
+    let v = [0, .. Bunny as uint];
+    let v = [0, .. BAR];
+    let v = [0, .. BAR2];
+    static BAR3:uint = BAR2;
+    let v = [0, .. BAR3];
+}
\ No newline at end of file
diff --git a/src/test/run-pass/num-range-rev.rs b/src/test/run-pass/num-range-rev.rs
new file mode 100644
index 0000000000000..7262339e431d9
--- /dev/null
+++ b/src/test/run-pass/num-range-rev.rs
@@ -0,0 +1,114 @@
+// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use std::int;
+use std::uint;
+
+fn uint_range(lo: uint, hi: uint, it: &fn(uint) -> bool) -> bool {
+    uint::range(lo, hi, it)
+}
+
+fn int_range(lo: int,  hi: int, it: &fn(int) -> bool) -> bool {
+    int::range(lo, hi, it)
+}
+
+fn uint_range_rev(hi: uint, lo: uint, it: &fn(uint) -> bool) -> bool {
+    uint::range_rev(hi, lo, it)
+}
+
+fn int_range_rev(hi: int,  lo: int, it: &fn(int) -> bool) -> bool {
+    int::range_rev(hi, lo, it)
+}
+
+fn int_range_step(a: int, b: int, step: int, it: &fn(int) -> bool) -> bool {
+    int::range_step(a, b, step, it)
+}
+
+fn uint_range_step(a: uint, b: uint, step: int, it: &fn(uint) -> bool) -> bool {
+    uint::range_step(a, b, step, it)
+}
+
+
+pub fn main() {
+    // int and uint have same result for
+    //   Sum{100 > i >= 2} == (Sum{1 <= i <= 99} - 1) == n*(n+1)/2 - 1 for n=99
+    let mut sum = 0u;
+    for uint_range_rev(100, 2) |i| {
+        sum += i;
+    }
+    assert_eq!(sum, 4949);
+
+    let mut sum = 0i;
+    for int_range_rev(100, 2) |i| {
+        sum += i;
+    }
+    assert_eq!(sum, 4949);
+
+
+    // elements are visited in correct order
+    let primes = [2,3,5,7,11];
+    let mut prod = 1i;
+    for uint_range_rev(5, 0) |i| {
+        println(fmt!("uint 4 downto 0: %u", i));
+        prod *= int::pow(primes[i], i);
+    }
+    assert_eq!(prod, 11*11*11*11*7*7*7*5*5*3*1);
+    let mut prod = 1i;
+    for int_range_rev(5, 0) |i| {
+        println(fmt!("int 4 downto 0: %d", i));
+        prod *= int::pow(primes[i], i as uint);
+    }
+    assert_eq!(prod, 11*11*11*11*7*7*7*5*5*3*1);
+
+
+    // range and range_rev are symmetric.
+    let mut sum_up = 0u;
+    for uint_range(10, 30) |i| {
+        sum_up += i;
+    }
+    let mut sum_down = 0u;
+    for uint_range_rev(30, 10) |i| {
+        sum_down += i;
+    }
+    assert_eq!(sum_up, sum_down);
+
+    let mut sum_up = 0;
+    for int_range(-20, 10) |i| {
+        sum_up += i;
+    }
+    let mut sum_down = 0;
+    for int_range_rev(10, -20) |i| {
+        sum_down += i;
+    }
+    assert_eq!(sum_up, sum_down);
+
+
+    // empty ranges
+    for int_range_rev(10, 10) |_| {
+        fail!("range should be empty when start == stop");
+    }
+
+    for uint_range_rev(0, 1) |_| {
+        fail!("range should be empty when start-1 underflows");
+    }
+
+    // range iterations do not wrap/underflow
+    let mut uflo_loop_visited = ~[];
+    for int_range_step(int::min_value+15, int::min_value, -4) |x| {
+        uflo_loop_visited.push(x - int::min_value);
+    }
+    assert_eq!(uflo_loop_visited, ~[15, 11, 7, 3]);
+
+    let mut uflo_loop_visited = ~[];
+    for uint_range_step(uint::min_value+15, uint::min_value, -4) |x| {
+        uflo_loop_visited.push(x - uint::min_value);
+    }
+    assert_eq!(uflo_loop_visited, ~[15, 11, 7, 3]);
+}
diff --git a/src/test/run-pass/num-range.rs b/src/test/run-pass/num-range.rs
new file mode 100644
index 0000000000000..7c1f905a049b6
--- /dev/null
+++ b/src/test/run-pass/num-range.rs
@@ -0,0 +1,119 @@
+// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use std::int;
+use std::uint;
+
+fn uint_range(lo: uint, hi: uint, it: &fn(uint) -> bool) -> bool {
+    uint::range(lo, hi, it)
+}
+
+fn int_range(lo: int, hi: int, it: &fn(int) -> bool) -> bool {
+    int::range(lo, hi, it)
+}
+
+fn int_range_step(a: int, b: int, step: int, it: &fn(int) -> bool) -> bool {
+    int::range_step(a, b, step, it)
+}
+
+fn uint_range_step(a: uint, b: uint, s: int, it: &fn(uint) -> bool) -> bool {
+    uint::range_step(a, b, s, it)
+}
+
+pub fn main() {
+    println(fmt!("num-range start"));
+    // int and uint have same result for
+    //   Sum{2 <= i < 100} == (Sum{1 <= i <= 99} - 1) == n*(n+1)/2 - 1 for n=99
+    let mut sum = 0u;
+    for uint_range(2, 100) |i| {
+        sum += i;
+    }
+    assert_eq!(sum, 4949);
+
+    let mut sum = 0i;
+    for int_range(2, 100) |i| {
+        sum += i;
+    }
+    assert_eq!(sum, 4949);
+
+
+    // elements are visited in correct order
+    let primes = [2,3,5,7];
+    let mut prod = 1i;
+    for uint_range(0, 4) |i| {
+        prod *= int::pow(primes[i], i);
+    }
+    assert_eq!(prod, 1*3*5*5*7*7*7);
+    let mut prod = 1i;
+    for int_range(0, 4) |i| {
+        prod *= int::pow(primes[i], i as uint);
+    }
+    assert_eq!(prod, 1*3*5*5*7*7*7);
+
+
+    // empty ranges
+    for int_range(10, 10) |_| {
+        fail!("range should be empty when start == stop");
+    }
+
+    for uint_range(10, 10) |_| {
+        fail!("range should be empty when start == stop");
+    }
+
+
+    // range iterations do not wrap/overflow
+    let mut oflo_loop_visited = ~[];
+    for uint_range_step(uint::max_value-15, uint::max_value, 4) |x| {
+        oflo_loop_visited.push(uint::max_value - x);
+    }
+    assert_eq!(oflo_loop_visited, ~[15, 11, 7, 3]);
+
+    let mut oflo_loop_visited = ~[];
+    for int_range_step(int::max_value-15, int::max_value, 4) |x| {
+        oflo_loop_visited.push(int::max_value - x);
+    }
+    assert_eq!(oflo_loop_visited, ~[15, 11, 7, 3]);
+
+
+    // range_step never passes nor visits the stop element
+    for int_range_step(0, 21, 3) |x| {
+        assert!(x < 21);
+    }
+
+    // range_step_inclusive will never pass stop element, and may skip it.
+    let mut saw21 = false;
+    for uint::range_step_inclusive(0, 21, 4) |x| {
+        assert!(x <= 21);
+        if x == 21 { saw21 = true; }
+    }
+    assert!(!saw21);
+    let mut saw21 = false;
+    for int::range_step_inclusive(0, 21, 4) |x| {
+        assert!(x <= 21);
+        if x == 21 { saw21 = true; }
+    }
+    assert!(!saw21);
+
+    // range_step_inclusive will never pass stop element, but may visit it.
+    let mut saw21 = false;
+    for uint::range_step_inclusive(0, 21, 3) |x| {
+        assert!(x <= 21);
+        println(fmt!("saw: %u", x));
+        if x == 21 { saw21 = true; }
+    }
+    assert!(saw21);
+    let mut saw21 = false;
+    for int::range_step_inclusive(0, 21, 3) |x| {
+        assert!(x <= 21);
+        if x == 21 { saw21 = true; }
+    }
+    assert!(saw21);
+
+}