From ea94a90488e6b4701581079339de3595389e5b15 Mon Sep 17 00:00:00 2001
From: Jorge Aparicio <japaricious@gmail.com>
Date: Tue, 30 Dec 2014 17:14:50 -0500
Subject: [PATCH 01/23] unicode: unbox closures used in function arguments

---
 src/libunicode/normalize.rs | 27 +++++++++++++++------------
 1 file changed, 15 insertions(+), 12 deletions(-)

diff --git a/src/libunicode/normalize.rs b/src/libunicode/normalize.rs
index 9e4aa0712470b..c6f86ccd9d412 100644
--- a/src/libunicode/normalize.rs
+++ b/src/libunicode/normalize.rs
@@ -11,6 +11,7 @@
 //! Functions for computing canonical and compatible decompositions for Unicode characters.
 
 use core::cmp::Ordering::{Equal, Less, Greater};
+use core::ops::FnMut;
 use core::option::Option;
 use core::option::Option::{Some, None};
 use core::slice::SliceExt;
@@ -32,14 +33,15 @@ fn bsearch_table<T>(c: char, r: &'static [(char, &'static [T])]) -> Option<&'sta
 }
 
 /// Compute canonical Unicode decomposition for character
-pub fn decompose_canonical(c: char, i: |char|) { d(c, i, false); }
+pub fn decompose_canonical<F>(c: char, mut i: F) where F: FnMut(char) { d(c, &mut i, false); }
 
 /// Compute canonical or compatible Unicode decomposition for character
-pub fn decompose_compatible(c: char, i: |char|) { d(c, i, true); }
+pub fn decompose_compatible<F>(c: char, mut i: F) where F: FnMut(char) { d(c, &mut i, true); }
 
-fn d(c: char, i: |char|, k: bool) {
+// FIXME(#19596) This is a workaround, we should use `F` instead of `&mut F`
+fn d<F>(c: char, i: &mut F, k: bool) where F: FnMut(char) {
     // 7-bit ASCII never decomposes
-    if c <= '\x7f' { i(c); return; }
+    if c <= '\x7f' { (*i)(c); return; }
 
     // Perform decomposition for Hangul
     if (c as u32) >= S_BASE && (c as u32) < (S_BASE + S_COUNT) {
@@ -51,7 +53,7 @@ fn d(c: char, i: |char|, k: bool) {
     match bsearch_table(c, canonical_table) {
         Some(canon) => {
             for x in canon.iter() {
-                d(*x, |b| i(b), k);
+                d(*x, i, k);
             }
             return;
         }
@@ -59,13 +61,13 @@ fn d(c: char, i: |char|, k: bool) {
     }
 
     // Bottom out if we're not doing compat.
-    if !k { i(c); return; }
+    if !k { (*i)(c); return; }
 
     // Then check the compatibility decompositions
     match bsearch_table(c, compatibility_table) {
         Some(compat) => {
             for x in compat.iter() {
-                d(*x, |b| i(b), k);
+                d(*x, i, k);
             }
             return;
         }
@@ -73,7 +75,7 @@ fn d(c: char, i: |char|, k: bool) {
     }
 
     // Finally bottom out.
-    i(c);
+    (*i)(c);
 }
 
 pub fn compose(a: char, b: char) -> Option<char> {
@@ -108,23 +110,24 @@ const T_COUNT: u32 = 28;
 const N_COUNT: u32 = (V_COUNT * T_COUNT);
 const S_COUNT: u32 = (L_COUNT * N_COUNT);
 
+// FIXME(#19596) This is a workaround, we should use `F` instead of `&mut F`
 // Decompose a precomposed Hangul syllable
 #[inline(always)]
-fn decompose_hangul(s: char, f: |char|) {
+fn decompose_hangul<F>(s: char, f: &mut F) where F: FnMut(char) {
     use core::mem::transmute;
 
     let si = s as u32 - S_BASE;
 
     let li = si / N_COUNT;
     unsafe {
-        f(transmute(L_BASE + li));
+        (*f)(transmute(L_BASE + li));
 
         let vi = (si % N_COUNT) / T_COUNT;
-        f(transmute(V_BASE + vi));
+        (*f)(transmute(V_BASE + vi));
 
         let ti = si % T_COUNT;
         if ti > 0 {
-            f(transmute(T_BASE + ti));
+            (*f)(transmute(T_BASE + ti));
         }
     }
 }

From a17c2b60e1c32e950b011296025a9f88f4d3c4e4 Mon Sep 17 00:00:00 2001
From: Jorge Aparicio <japaricious@gmail.com>
Date: Tue, 30 Dec 2014 17:16:58 -0500
Subject: [PATCH 02/23] collections: fix fallout

---
 src/libcollections/str.rs | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/libcollections/str.rs b/src/libcollections/str.rs
index 8d5d76f9598f4..e5aa377b27546 100644
--- a/src/libcollections/str.rs
+++ b/src/libcollections/str.rs
@@ -202,7 +202,7 @@ impl<'a> Iterator<char> for Decompositions<'a> {
                 let buffer = &mut self.buffer;
                 let sorted = &mut self.sorted;
                 {
-                    let callback = |d| {
+                    let callback = |&mut: d| {
                         let class =
                             unicode::char::canonical_combining_class(d);
                         if class == 0 && !*sorted {

From 371f04d4330f70cfab5fa2a5fdb65df7ccd0604c Mon Sep 17 00:00:00 2001
From: Jorge Aparicio <japaricious@gmail.com>
Date: Tue, 30 Dec 2014 18:05:17 -0500
Subject: [PATCH 03/23] std: unbox closures used in function arguments

---
 src/libstd/io/stdio.rs               | 2 +-
 src/libstd/rt/task.rs                | 2 +-
 src/libstd/sys/common/thread_info.rs | 4 ++--
 src/libstd/sys/windows/os.rs         | 4 +++-
 4 files changed, 7 insertions(+), 5 deletions(-)

diff --git a/src/libstd/io/stdio.rs b/src/libstd/io/stdio.rs
index 43d2e078035a6..b7d069eb19e58 100644
--- a/src/libstd/io/stdio.rs
+++ b/src/libstd/io/stdio.rs
@@ -334,7 +334,7 @@ pub fn set_stderr(stderr: Box<Writer + Send>) -> Option<Box<Writer + Send>> {
 //          // io1 aliases io2
 //      })
 //  })
-fn with_task_stdout(f: |&mut Writer| -> IoResult<()>) {
+fn with_task_stdout<F>(f: F) where F: FnOnce(&mut Writer) -> IoResult<()> {
     let mut my_stdout = LOCAL_STDOUT.with(|slot| {
         slot.borrow_mut().take()
     }).unwrap_or_else(|| {
diff --git a/src/libstd/rt/task.rs b/src/libstd/rt/task.rs
index 773322e4f57f1..41e91d1b6ef9b 100644
--- a/src/libstd/rt/task.rs
+++ b/src/libstd/rt/task.rs
@@ -174,7 +174,7 @@ impl Task {
     ///
     /// It is invalid to call this function with a thread that has been previously
     /// destroyed via a failed call to `run`.
-    pub fn run(mut self: Box<Task>, f: ||) -> Box<Task> {
+    pub fn run<F>(mut self: Box<Task>, f: F) -> Box<Task> where F: FnOnce() {
         assert!(!self.is_destroyed(), "cannot re-use a destroyed thread");
 
         // First, make sure that no one else is in TLS. This does not allow
diff --git a/src/libstd/sys/common/thread_info.rs b/src/libstd/sys/common/thread_info.rs
index dc21feb17a8e8..8c76eb1504db7 100644
--- a/src/libstd/sys/common/thread_info.rs
+++ b/src/libstd/sys/common/thread_info.rs
@@ -26,13 +26,13 @@ struct ThreadInfo {
 thread_local! { static THREAD_INFO: RefCell<Option<ThreadInfo>> = RefCell::new(None) }
 
 impl ThreadInfo {
-    fn with<R>(f: |&mut ThreadInfo| -> R) -> R {
+    fn with<R, F>(f: F) -> R where F: FnOnce(&mut ThreadInfo) -> R {
         if THREAD_INFO.destroyed() {
             panic!("Use of std::thread::Thread::current() is not possible after \
                     the thread's local data has been destroyed");
         }
 
-        THREAD_INFO.with(|c| {
+        THREAD_INFO.with(move |c| {
             if c.borrow().is_none() {
                 *c.borrow_mut() = Some(ThreadInfo {
                     stack_bounds: (0, 0),
diff --git a/src/libstd/sys/windows/os.rs b/src/libstd/sys/windows/os.rs
index e7194df7ac3cb..0f26e36a80fd6 100644
--- a/src/libstd/sys/windows/os.rs
+++ b/src/libstd/sys/windows/os.rs
@@ -124,7 +124,9 @@ pub unsafe fn pipe() -> IoResult<(FileDesc, FileDesc)> {
     }
 }
 
-pub fn fill_utf16_buf_and_decode(f: |*mut u16, DWORD| -> DWORD) -> Option<String> {
+pub fn fill_utf16_buf_and_decode<F>(mut f: F) -> Option<String> where
+    F: FnMut(*mut u16, DWORD) -> DWORD,
+{
     unsafe {
         let mut n = TMPBUF_SZ as DWORD;
         let mut res = None;

From 70ce68eed4f81ff90cf3710e3fdb7b04de71a388 Mon Sep 17 00:00:00 2001
From: Jorge Aparicio <japaricious@gmail.com>
Date: Tue, 30 Dec 2014 18:39:20 -0500
Subject: [PATCH 04/23] syntax: unbox closures used in function arguments

---
 src/libsyntax/ast_util.rs         | 54 +++++++++++++++++--------------
 src/libsyntax/ext/base.rs         |  6 ++--
 src/libsyntax/ext/deriving/mod.rs |  4 +--
 src/libsyntax/ext/expand.rs       |  2 +-
 4 files changed, 35 insertions(+), 31 deletions(-)

diff --git a/src/libsyntax/ast_util.rs b/src/libsyntax/ast_util.rs
index 9196055267f6f..a8393ed9d3977 100644
--- a/src/libsyntax/ast_util.rs
+++ b/src/libsyntax/ast_util.rs
@@ -618,34 +618,38 @@ pub fn compute_id_range_for_fn_body(fk: visit::FnKind,
     id_visitor.operation.result
 }
 
-// FIXME(#19596) unbox `it`
-pub fn walk_pat(pat: &Pat, it: |&Pat| -> bool) -> bool {
-    if !it(pat) {
-        return false;
-    }
-
-    match pat.node {
-        PatIdent(_, _, Some(ref p)) => walk_pat(&**p, it),
-        PatStruct(_, ref fields, _) => {
-            fields.iter().all(|field| walk_pat(&*field.node.pat, |p| it(p)))
-        }
-        PatEnum(_, Some(ref s)) | PatTup(ref s) => {
-            s.iter().all(|p| walk_pat(&**p, |p| it(p)))
+pub fn walk_pat<F>(pat: &Pat, mut it: F) -> bool where F: FnMut(&Pat) -> bool {
+    // FIXME(#19596) this is a workaround, but there should be a better way
+    fn walk_pat_<G>(pat: &Pat, it: &mut G) -> bool where G: FnMut(&Pat) -> bool {
+        if !(*it)(pat) {
+            return false;
         }
-        PatBox(ref s) | PatRegion(ref s) => {
-            walk_pat(&**s, it)
-        }
-        PatVec(ref before, ref slice, ref after) => {
-            before.iter().all(|p| walk_pat(&**p, |p| it(p))) &&
-            slice.iter().all(|p| walk_pat(&**p, |p| it(p))) &&
-            after.iter().all(|p| walk_pat(&**p, |p| it(p)))
-        }
-        PatMac(_) => panic!("attempted to analyze unexpanded pattern"),
-        PatWild(_) | PatLit(_) | PatRange(_, _) | PatIdent(_, _, _) |
-        PatEnum(_, _) => {
-            true
+
+        match pat.node {
+            PatIdent(_, _, Some(ref p)) => walk_pat_(&**p, it),
+            PatStruct(_, ref fields, _) => {
+                fields.iter().all(|field| walk_pat_(&*field.node.pat, it))
+            }
+            PatEnum(_, Some(ref s)) | PatTup(ref s) => {
+                s.iter().all(|p| walk_pat_(&**p, it))
+            }
+            PatBox(ref s) | PatRegion(ref s) => {
+                walk_pat_(&**s, it)
+            }
+            PatVec(ref before, ref slice, ref after) => {
+                before.iter().all(|p| walk_pat_(&**p, it)) &&
+                slice.iter().all(|p| walk_pat_(&**p, it)) &&
+                after.iter().all(|p| walk_pat_(&**p, it))
+            }
+            PatMac(_) => panic!("attempted to analyze unexpanded pattern"),
+            PatWild(_) | PatLit(_) | PatRange(_, _) | PatIdent(_, _, _) |
+            PatEnum(_, _) => {
+                true
+            }
         }
     }
+
+    walk_pat_(pat, &mut it)
 }
 
 pub trait EachViewItem {
diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs
index 8e69076a2c50e..5134897893f24 100644
--- a/src/libsyntax/ext/base.rs
+++ b/src/libsyntax/ext/base.rs
@@ -47,18 +47,18 @@ pub trait ItemDecorator {
               sp: Span,
               meta_item: &ast::MetaItem,
               item: &ast::Item,
-              push: |P<ast::Item>|);
+              push: Box<FnMut(P<ast::Item>)>);
 }
 
 impl<F> ItemDecorator for F
-    where F : Fn(&mut ExtCtxt, Span, &ast::MetaItem, &ast::Item, |P<ast::Item>|)
+    where F : Fn(&mut ExtCtxt, Span, &ast::MetaItem, &ast::Item, Box<FnMut(P<ast::Item>)>)
 {
     fn expand(&self,
               ecx: &mut ExtCtxt,
               sp: Span,
               meta_item: &ast::MetaItem,
               item: &ast::Item,
-              push: |P<ast::Item>|) {
+              push: Box<FnMut(P<ast::Item>)>) {
         (*self)(ecx, sp, meta_item, item, push)
     }
 }
diff --git a/src/libsyntax/ext/deriving/mod.rs b/src/libsyntax/ext/deriving/mod.rs
index edf29e670eb88..75f763b5c38ee 100644
--- a/src/libsyntax/ext/deriving/mod.rs
+++ b/src/libsyntax/ext/deriving/mod.rs
@@ -45,7 +45,7 @@ pub fn expand_meta_deriving(cx: &mut ExtCtxt,
                             _span: Span,
                             mitem: &MetaItem,
                             item: &Item,
-                            push: |P<Item>|) {
+                            mut push: Box<FnMut(P<Item>)>) {
     match mitem.node {
         MetaNameValue(_, ref l) => {
             cx.span_err(l.span, "unexpected value in `deriving`");
@@ -64,7 +64,7 @@ pub fn expand_meta_deriving(cx: &mut ExtCtxt,
                     MetaWord(ref tname) => {
                         macro_rules! expand(($func:path) => ($func(cx, titem.span,
                                                                    &**titem, item,
-                                                                   |i| push(i))));
+                                                                   |i| push.call_mut((i,)))));
                         match tname.get() {
                             "Clone" => expand!(clone::expand_deriving_clone),
 
diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs
index 9fcaf2210c194..f9bffcc897460 100644
--- a/src/libsyntax/ext/expand.rs
+++ b/src/libsyntax/ext/expand.rs
@@ -424,7 +424,7 @@ pub fn expand_item(it: P<ast::Item>, fld: &mut MacroExpander)
                     // but that double-mut-borrows fld
                     let mut items: SmallVector<P<ast::Item>> = SmallVector::zero();
                     dec.expand(fld.cx, attr.span, &*attr.node.value, &*it,
-                               |item| items.push(item));
+                               box |&mut : item| items.push(item));
                     decorator_items.extend(items.into_iter()
                         .flat_map(|item| expand_item(item, fld).into_iter()));
 

From 5de9f47e49200f1e9e367144d184446ddde9105b Mon Sep 17 00:00:00 2001
From: Jorge Aparicio <japaricious@gmail.com>
Date: Tue, 30 Dec 2014 19:59:09 -0500
Subject: [PATCH 05/23] rustc: unbox closures used in function arguments

---
 src/librustc/middle/mem_categorization.rs | 38 ++++++------
 src/librustc/middle/ty.rs                 | 74 ++++++++++++-----------
 2 files changed, 59 insertions(+), 53 deletions(-)

diff --git a/src/librustc/middle/mem_categorization.rs b/src/librustc/middle/mem_categorization.rs
index c15001af68d96..580b3a93d7397 100644
--- a/src/librustc/middle/mem_categorization.rs
+++ b/src/librustc/middle/mem_categorization.rs
@@ -1122,11 +1122,15 @@ impl<'t,'tcx,TYPER:Typer<'tcx>> MemCategorizationContext<'t,TYPER> {
         })
     }
 
-    // FIXME(#19596) unbox `op`
-    pub fn cat_pattern(&self,
-                       cmt: cmt<'tcx>,
-                       pat: &ast::Pat,
-                       op: |&MemCategorizationContext<'t, TYPER>, cmt<'tcx>, &ast::Pat|)
+    pub fn cat_pattern<F>(&self, cmt: cmt<'tcx>, pat: &ast::Pat, mut op: F) where
+        F: FnMut(&MemCategorizationContext<'t, TYPER>, cmt<'tcx>, &ast::Pat),
+    {
+        self.cat_pattern_(cmt, pat, &mut op)
+    }
+
+    // FIXME(#19596) This is a workaround, but there should be a better way to do this
+    fn cat_pattern_<F>(&self, cmt: cmt<'tcx>, pat: &ast::Pat, op: &mut F) where
+        F: FnMut(&MemCategorizationContext<'t, TYPER>, cmt<'tcx>, &ast::Pat),
     {
         // Here, `cmt` is the categorization for the value being
         // matched and pat is the pattern it is being matched against.
@@ -1177,7 +1181,7 @@ impl<'t,'tcx,TYPER:Typer<'tcx>> MemCategorizationContext<'t,TYPER> {
                pat.id, pprust::pat_to_string(pat),
                cmt.repr(self.tcx()));
 
-        op(self, cmt.clone(), pat);
+        (*op)(self, cmt.clone(), pat);
 
         let def_map = self.tcx().def_map.borrow();
         let opt_def = def_map.get(&pat.id);
@@ -1214,7 +1218,7 @@ impl<'t,'tcx,TYPER:Typer<'tcx>> MemCategorizationContext<'t,TYPER> {
                                 pat, cmt.clone(), subpat_ty,
                                 InteriorField(PositionalField(i)));
 
-                        self.cat_pattern(subcmt, &**subpat, |x,y,z| op(x,y,z));
+                        self.cat_pattern_(subcmt, &**subpat, op);
                     }
                 }
                 Some(&def::DefStruct(..)) => {
@@ -1224,13 +1228,12 @@ impl<'t,'tcx,TYPER:Typer<'tcx>> MemCategorizationContext<'t,TYPER> {
                             self.cat_imm_interior(
                                 pat, cmt.clone(), subpat_ty,
                                 InteriorField(PositionalField(i)));
-                        self.cat_pattern(cmt_field, &**subpat,
-                                         |x,y,z| op(x,y,z));
+                        self.cat_pattern_(cmt_field, &**subpat, op);
                     }
                 }
                 Some(&def::DefConst(..)) => {
                     for subpat in subpats.iter() {
-                        self.cat_pattern(cmt.clone(), &**subpat, |x,y,z| op(x,y,z));
+                        self.cat_pattern_(cmt.clone(), &**subpat, op);
                     }
                 }
                 _ => {
@@ -1242,7 +1245,7 @@ impl<'t,'tcx,TYPER:Typer<'tcx>> MemCategorizationContext<'t,TYPER> {
           }
 
           ast::PatIdent(_, _, Some(ref subpat)) => {
-              self.cat_pattern(cmt, &**subpat, op);
+              self.cat_pattern_(cmt, &**subpat, op);
           }
 
           ast::PatIdent(_, _, None) => {
@@ -1254,7 +1257,7 @@ impl<'t,'tcx,TYPER:Typer<'tcx>> MemCategorizationContext<'t,TYPER> {
             for fp in field_pats.iter() {
                 let field_ty = self.pat_ty(&*fp.node.pat); // see (*2)
                 let cmt_field = self.cat_field(pat, cmt.clone(), fp.node.ident.name, field_ty);
-                self.cat_pattern(cmt_field, &*fp.node.pat, |x,y,z| op(x,y,z));
+                self.cat_pattern_(cmt_field, &*fp.node.pat, op);
             }
           }
 
@@ -1266,29 +1269,28 @@ impl<'t,'tcx,TYPER:Typer<'tcx>> MemCategorizationContext<'t,TYPER> {
                     self.cat_imm_interior(
                         pat, cmt.clone(), subpat_ty,
                         InteriorField(PositionalField(i)));
-                self.cat_pattern(subcmt, &**subpat, |x,y,z| op(x,y,z));
+                self.cat_pattern_(subcmt, &**subpat, op);
             }
           }
 
           ast::PatBox(ref subpat) | ast::PatRegion(ref subpat) => {
             // @p1, ~p1, ref p1
             let subcmt = self.cat_deref(pat, cmt, 0, false);
-            self.cat_pattern(subcmt, &**subpat, op);
+            self.cat_pattern_(subcmt, &**subpat, op);
           }
 
           ast::PatVec(ref before, ref slice, ref after) => {
               let elt_cmt = self.cat_index(pat, self.deref_vec(pat, cmt));
               for before_pat in before.iter() {
-                  self.cat_pattern(elt_cmt.clone(), &**before_pat,
-                                   |x,y,z| op(x,y,z));
+                  self.cat_pattern_(elt_cmt.clone(), &**before_pat, op);
               }
               for slice_pat in slice.iter() {
                   let slice_ty = self.pat_ty(&**slice_pat);
                   let slice_cmt = self.cat_rvalue_node(pat.id(), pat.span(), slice_ty);
-                  self.cat_pattern(slice_cmt, &**slice_pat, |x,y,z| op(x,y,z));
+                  self.cat_pattern_(slice_cmt, &**slice_pat, op);
               }
               for after_pat in after.iter() {
-                  self.cat_pattern(elt_cmt.clone(), &**after_pat, |x,y,z| op(x,y,z));
+                  self.cat_pattern_(elt_cmt.clone(), &**after_pat, op);
               }
           }
 
diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs
index ab39c761a3861..ba52266e52d18 100644
--- a/src/librustc/middle/ty.rs
+++ b/src/librustc/middle/ty.rs
@@ -2812,49 +2812,53 @@ pub fn walk_ty<'tcx, F>(ty: Ty<'tcx>, mut f: F) where
     maybe_walk_ty(ty, |ty| { f(ty); true });
 }
 
-// FIXME(#19596) unbox `f`
-pub fn maybe_walk_ty<'tcx>(ty: Ty<'tcx>, f: |Ty<'tcx>| -> bool) {
-    if !f(ty) {
-        return;
-    }
-    match ty.sty {
-        ty_bool | ty_char | ty_int(_) | ty_uint(_) | ty_float(_) |
-        ty_str | ty_infer(_) | ty_param(_) | ty_err => {}
-        ty_uniq(ty) | ty_vec(ty, _) | ty_open(ty) => maybe_walk_ty(ty, f),
-        ty_ptr(ref tm) | ty_rptr(_, ref tm) => {
-            maybe_walk_ty(tm.ty, f);
+pub fn maybe_walk_ty<'tcx, F>(ty: Ty<'tcx>, mut f: F) where F: FnMut(Ty<'tcx>) -> bool {
+    // FIXME(#19596) This is a workaround, but there should be a better way to do this
+    fn maybe_walk_ty_<'tcx, F>(ty: Ty<'tcx>, f: &mut F) where F: FnMut(Ty<'tcx>) -> bool {
+        if !(*f)(ty) {
+            return;
         }
-        ty_trait(box TyTrait { ref principal, .. }) => {
-            for subty in principal.0.substs.types.iter() {
-                maybe_walk_ty(*subty, |x| f(x));
+        match ty.sty {
+            ty_bool | ty_char | ty_int(_) | ty_uint(_) | ty_float(_) |
+            ty_str | ty_infer(_) | ty_param(_) | ty_err => {}
+            ty_uniq(ty) | ty_vec(ty, _) | ty_open(ty) => maybe_walk_ty_(ty, f),
+            ty_ptr(ref tm) | ty_rptr(_, ref tm) => {
+                maybe_walk_ty_(tm.ty, f);
+            }
+            ty_trait(box TyTrait { ref principal, .. }) => {
+                for subty in principal.0.substs.types.iter() {
+                    maybe_walk_ty_(*subty, f);
+                }
             }
-        }
-        ty_projection(ProjectionTy { ref trait_ref, .. }) => {
-            for subty in trait_ref.substs.types.iter() {
-                maybe_walk_ty(*subty, |x| f(x));
+            ty_projection(ProjectionTy { ref trait_ref, .. }) => {
+                for subty in trait_ref.substs.types.iter() {
+                    maybe_walk_ty_(*subty, f);
+                }
             }
-        }
-        ty_enum(_, ref substs) |
-        ty_struct(_, ref substs) |
-        ty_unboxed_closure(_, _, ref substs) => {
-            for subty in substs.types.iter() {
-                maybe_walk_ty(*subty, |x| f(x));
+            ty_enum(_, ref substs) |
+            ty_struct(_, ref substs) |
+            ty_unboxed_closure(_, _, ref substs) => {
+                for subty in substs.types.iter() {
+                    maybe_walk_ty_(*subty, f);
+                }
             }
-        }
-        ty_tup(ref ts) => { for tt in ts.iter() { maybe_walk_ty(*tt, |x| f(x)); } }
-        ty_bare_fn(_, ref ft) => {
-            for a in ft.sig.0.inputs.iter() { maybe_walk_ty(*a, |x| f(x)); }
-            if let ty::FnConverging(output) = ft.sig.0.output {
-                maybe_walk_ty(output, f);
+            ty_tup(ref ts) => { for tt in ts.iter() { maybe_walk_ty_(*tt, f); } }
+            ty_bare_fn(_, ref ft) => {
+                for a in ft.sig.0.inputs.iter() { maybe_walk_ty_(*a, f); }
+                if let ty::FnConverging(output) = ft.sig.0.output {
+                    maybe_walk_ty_(output, f);
+                }
             }
-        }
-        ty_closure(ref ft) => {
-            for a in ft.sig.0.inputs.iter() { maybe_walk_ty(*a, |x| f(x)); }
-            if let ty::FnConverging(output) = ft.sig.0.output {
-                maybe_walk_ty(output, f);
+            ty_closure(ref ft) => {
+                for a in ft.sig.0.inputs.iter() { maybe_walk_ty_(*a, f); }
+                if let ty::FnConverging(output) = ft.sig.0.output {
+                    maybe_walk_ty_(output, f);
+                }
             }
         }
     }
+
+    maybe_walk_ty_(ty, &mut f);
 }
 
 // Folds types from the bottom up.

From 24b49228f0dbd5a4b59a5297532f4b9cb4dfdc6a Mon Sep 17 00:00:00 2001
From: Jorge Aparicio <japaricious@gmail.com>
Date: Tue, 30 Dec 2014 20:09:48 -0500
Subject: [PATCH 06/23] rustc_trans: unbox closures used in function arguments

---
 src/librustc_trans/trans/expr.rs | 18 +++++++++++-------
 1 file changed, 11 insertions(+), 7 deletions(-)

diff --git a/src/librustc_trans/trans/expr.rs b/src/librustc_trans/trans/expr.rs
index 7587adae5b7ef..cf3070919cb38 100644
--- a/src/librustc_trans/trans/expr.rs
+++ b/src/librustc_trans/trans/expr.rs
@@ -299,12 +299,16 @@ fn apply_adjustments<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
     // into a type to be destructed. If we want to end up with a Box pointer,
     // then mk_ty should make a Box pointer (T -> Box<T>), if we want a
     // borrowed reference then it should be T -> &T.
-    // FIXME(#19596) unbox `mk_ty`
-    fn unsized_info<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
-                                kind: &ty::UnsizeKind<'tcx>,
-                                id: ast::NodeId,
-                                unadjusted_ty: Ty<'tcx>,
-                                mk_ty: |Ty<'tcx>| -> Ty<'tcx>) -> ValueRef {
+    fn unsized_info<'blk, 'tcx, F>(bcx: Block<'blk, 'tcx>,
+                                   kind: &ty::UnsizeKind<'tcx>,
+                                   id: ast::NodeId,
+                                   unadjusted_ty: Ty<'tcx>,
+                                   mk_ty: F) -> ValueRef where
+        F: FnOnce(Ty<'tcx>) -> Ty<'tcx>,
+    {
+        // FIXME(#19596) workaround: `|t| t` causes monomorphization recursion
+        fn identity<T>(t: T) -> T { t }
+
         debug!("unsized_info(kind={}, id={}, unadjusted_ty={})",
                kind, id, unadjusted_ty.repr(bcx.tcx()));
         match kind {
@@ -314,7 +318,7 @@ fn apply_adjustments<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
                     let ty_substs = substs.types.get_slice(subst::TypeSpace);
                     // The dtor for a field treats it like a value, so mk_ty
                     // should just be the identity function.
-                    unsized_info(bcx, k, id, ty_substs[tp_index], |t| t)
+                    unsized_info(bcx, k, id, ty_substs[tp_index], identity)
                 }
                 _ => bcx.sess().bug(format!("UnsizeStruct with bad sty: {}",
                                           bcx.ty_to_string(unadjusted_ty))[])

From bcc2120c2134cd4359d160e55ebbc3c3bcb72f16 Mon Sep 17 00:00:00 2001
From: Jorge Aparicio <japaricious@gmail.com>
Date: Tue, 30 Dec 2014 20:13:30 -0500
Subject: [PATCH 07/23] rustc_borrowck: unbox closures used in function
 arguments

---
 src/librustc_borrowck/borrowck/move_data.rs | 16 ++++++++++++----
 1 file changed, 12 insertions(+), 4 deletions(-)

diff --git a/src/librustc_borrowck/borrowck/move_data.rs b/src/librustc_borrowck/borrowck/move_data.rs
index 5d2faa52f1ad0..547e7d272c69d 100644
--- a/src/librustc_borrowck/borrowck/move_data.rs
+++ b/src/librustc_borrowck/borrowck/move_data.rs
@@ -521,15 +521,17 @@ impl<'tcx> MoveData<'tcx> {
         return true;
     }
 
-    // FIXME(#19596) unbox `f`
-    fn each_extending_path(&self, index: MovePathIndex, f: |MovePathIndex| -> bool) -> bool {
-        if !f(index) {
+    // FIXME(#19596) This is a workaround, but there should be better way to do this
+    fn each_extending_path_<F>(&self, index: MovePathIndex, f: &mut F) -> bool where
+        F: FnMut(MovePathIndex) -> bool,
+    {
+        if !(*f)(index) {
             return false;
         }
 
         let mut p = self.path_first_child(index);
         while p != InvalidMovePathIndex {
-            if !self.each_extending_path(p, |x| f(x)) {
+            if !self.each_extending_path_(p, f) {
                 return false;
             }
             p = self.path_next_sibling(p);
@@ -538,6 +540,12 @@ impl<'tcx> MoveData<'tcx> {
         return true;
     }
 
+    fn each_extending_path<F>(&self, index: MovePathIndex, mut f: F) -> bool where
+        F: FnMut(MovePathIndex) -> bool,
+    {
+        self.each_extending_path_(index, &mut f)
+    }
+
     fn each_applicable_move<F>(&self, index0: MovePathIndex, mut f: F) -> bool where
         F: FnMut(MoveIndex) -> bool,
     {

From ddb4e43fa51de0186b6bab12353cb25f5e785a4f Mon Sep 17 00:00:00 2001
From: Jorge Aparicio <japaricious@gmail.com>
Date: Tue, 30 Dec 2014 20:23:24 -0500
Subject: [PATCH 08/23] core: unbox closures used in let bindings

---
 src/libcore/fmt/float.rs | 4 ++--
 src/libcore/fmt/mod.rs   | 2 +-
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/src/libcore/fmt/float.rs b/src/libcore/fmt/float.rs
index 3787ae33fdaad..d3b1d8efe8bfc 100644
--- a/src/libcore/fmt/float.rs
+++ b/src/libcore/fmt/float.rs
@@ -225,10 +225,10 @@ pub fn float_to_str_bytes_common<T: Float, U, F>(
         // cut off the one extra digit, and depending on its value
         // round the remaining ones.
         if limit_digits && dig == digit_count {
-            let ascii2value = |chr: u8| {
+            let ascii2value = |&: chr: u8| {
                 (chr as char).to_digit(radix).unwrap()
             };
-            let value2ascii = |val: uint| {
+            let value2ascii = |&: val: uint| {
                 char::from_digit(val, radix).unwrap() as u8
             };
 
diff --git a/src/libcore/fmt/mod.rs b/src/libcore/fmt/mod.rs
index 9d275c9da9cb3..95753f4b671d5 100644
--- a/src/libcore/fmt/mod.rs
+++ b/src/libcore/fmt/mod.rs
@@ -398,7 +398,7 @@ impl<'a> Formatter<'a> {
         }
 
         // Writes the sign if it exists, and then the prefix if it was requested
-        let write_prefix = |f: &mut Formatter| {
+        let write_prefix = |&: f: &mut Formatter| {
             for c in sign.into_iter() {
                 let mut b = [0, ..4];
                 let n = c.encode_utf8(&mut b).unwrap_or(0);

From 16a4ba8fa5c717bd62a094210ad5926227d7ea95 Mon Sep 17 00:00:00 2001
From: Jorge Aparicio <japaricious@gmail.com>
Date: Tue, 30 Dec 2014 20:32:45 -0500
Subject: [PATCH 09/23] getopts: unbox closures used in let bindings

---
 src/libgetopts/lib.rs | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/libgetopts/lib.rs b/src/libgetopts/lib.rs
index 0184222b9e0b6..0db0bd413ac94 100644
--- a/src/libgetopts/lib.rs
+++ b/src/libgetopts/lib.rs
@@ -875,7 +875,7 @@ fn each_split_within<F>(ss: &str, lim: uint, mut it: F) -> bool where
         lim = fake_i;
     }
 
-    let machine: |&mut bool, (uint, char)| -> bool = |cont, (i, c)| {
+    let mut machine = |&mut: cont: &mut bool, (i, c): (uint, char)| -> bool {
         let whitespace = if c.is_whitespace() { Ws }       else { Cr };
         let limit      = if (i - slice_start + 1) <= lim  { UnderLim } else { OverLim };
 

From 06408b4dd3801f8eba32ef775ad013b56627dcf9 Mon Sep 17 00:00:00 2001
From: Jorge Aparicio <japaricious@gmail.com>
Date: Tue, 30 Dec 2014 20:37:02 -0500
Subject: [PATCH 10/23] rustc: unbox closures used in let bindings

---
 src/librustc/metadata/creader.rs                       | 2 +-
 src/librustc/metadata/encoder.rs                       | 2 +-
 src/librustc/middle/check_const.rs                     | 2 +-
 src/librustc/middle/check_match.rs                     | 2 +-
 src/librustc/middle/infer/region_inference/graphviz.rs | 2 +-
 src/librustc/middle/privacy.rs                         | 8 ++++----
 src/librustc/middle/region.rs                          | 2 +-
 src/librustc/middle/ty.rs                              | 8 ++++----
 8 files changed, 14 insertions(+), 14 deletions(-)

diff --git a/src/librustc/metadata/creader.rs b/src/librustc/metadata/creader.rs
index e03d645aec367..5dac2bafaec3d 100644
--- a/src/librustc/metadata/creader.rs
+++ b/src/librustc/metadata/creader.rs
@@ -177,7 +177,7 @@ fn extract_crate_info(e: &Env, i: &ast::ViewItem) -> Option<CrateInfo> {
 }
 
 pub fn validate_crate_name(sess: Option<&Session>, s: &str, sp: Option<Span>) {
-    let err = |s: &str| {
+    let err = |&: s: &str| {
         match (sp, sess) {
             (_, None) => panic!("{}", s),
             (Some(sp), Some(sess)) => sess.span_err(sp, s),
diff --git a/src/librustc/metadata/encoder.rs b/src/librustc/metadata/encoder.rs
index 5d0532a621022..75fb6fb0cfa7f 100644
--- a/src/librustc/metadata/encoder.rs
+++ b/src/librustc/metadata/encoder.rs
@@ -1417,7 +1417,7 @@ fn encode_info_for_item(ecx: &EncodeContext,
             encode_parent_sort(rbml_w, 't');
 
             let trait_item = &ms[i];
-            let encode_trait_item = |rbml_w: &mut Encoder| {
+            let encode_trait_item = |&: rbml_w: &mut Encoder| {
                 // If this is a static method, we've already
                 // encoded this.
                 if is_nonstatic_method {
diff --git a/src/librustc/middle/check_const.rs b/src/librustc/middle/check_const.rs
index e08dd64d4d411..6277656e03afc 100644
--- a/src/librustc/middle/check_const.rs
+++ b/src/librustc/middle/check_const.rs
@@ -185,7 +185,7 @@ fn check_expr(v: &mut CheckCrateVisitor, e: &ast::Expr) -> bool {
         ast::ExprBlock(ref block) => {
             // Check all statements in the block
             for stmt in block.stmts.iter() {
-                let block_span_err = |span|
+                let block_span_err = |&: span|
                     span_err!(v.tcx.sess, span, E0016,
                               "blocks in constants are limited to items and \
                                tail expressions");
diff --git a/src/librustc/middle/check_match.rs b/src/librustc/middle/check_match.rs
index 522e1d4d3b284..4c5d76a2c40e5 100644
--- a/src/librustc/middle/check_match.rs
+++ b/src/librustc/middle/check_match.rs
@@ -1012,7 +1012,7 @@ fn check_legality_of_move_bindings(cx: &MatchCheckCtxt,
         })
     }
 
-    let check_move: |&Pat, Option<&Pat>| = |p, sub| {
+    let check_move = |&: p: &Pat, sub: Option<&Pat>| {
         // check legality of moving out of the enum
 
         // x @ Foo(..) is legal, but x @ Foo(y) isn't.
diff --git a/src/librustc/middle/infer/region_inference/graphviz.rs b/src/librustc/middle/infer/region_inference/graphviz.rs
index 0ca1a593ce7fe..8455ee3955bd0 100644
--- a/src/librustc/middle/infer/region_inference/graphviz.rs
+++ b/src/librustc/middle/infer/region_inference/graphviz.rs
@@ -136,7 +136,7 @@ impl<'a, 'tcx> ConstraintGraph<'a, 'tcx> {
         let mut i = 0;
         let mut node_ids = FnvHashMap::new();
         {
-            let add_node = |node| {
+            let mut add_node = |&mut : node| {
                 if let Vacant(e) = node_ids.entry(node) {
                     e.set(i);
                     i += 1;
diff --git a/src/librustc/middle/privacy.rs b/src/librustc/middle/privacy.rs
index edba2839f37ea..cfa0d419aa3f0 100644
--- a/src/librustc/middle/privacy.rs
+++ b/src/librustc/middle/privacy.rs
@@ -749,7 +749,7 @@ impl<'a, 'tcx> PrivacyVisitor<'a, 'tcx> {
     fn check_path(&mut self, span: Span, path_id: ast::NodeId, path: &ast::Path) {
         debug!("privacy - path {}", self.nodestr(path_id));
         let orig_def = self.tcx.def_map.borrow()[path_id].clone();
-        let ck = |tyname: &str| {
+        let ck = |&: tyname: &str| {
             let ck_public = |def: ast::DefId| {
                 let name = token::get_ident(path.segments.last().unwrap().identifier);
                 let origdid = orig_def.def_id();
@@ -921,7 +921,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for PrivacyVisitor<'a, 'tcx> {
                 }
             }
             ast::ExprPath(..) => {
-                let guard = |did: ast::DefId| {
+                let guard = |&: did: ast::DefId| {
                     let fields = ty::lookup_struct_fields(self.tcx, did);
                     let any_priv = fields.iter().any(|f| {
                         f.vis != ast::Public && (
@@ -1126,7 +1126,7 @@ impl<'a, 'tcx> SanePrivacyVisitor<'a, 'tcx> {
     /// later on down the road...
     fn check_sane_privacy(&self, item: &ast::Item) {
         let tcx = self.tcx;
-        let check_inherited = |sp: Span, vis: ast::Visibility, note: &str| {
+        let check_inherited = |&: sp: Span, vis: ast::Visibility, note: &str| {
             if vis != ast::Inherited {
                 tcx.sess.span_err(sp, "unnecessary visibility qualifier");
                 if note.len() > 0 {
@@ -1206,7 +1206,7 @@ impl<'a, 'tcx> SanePrivacyVisitor<'a, 'tcx> {
                 tcx.sess.span_err(sp, "visibility has no effect inside functions");
             }
         }
-        let check_struct = |def: &ast::StructDef| {
+        let check_struct = |&: def: &ast::StructDef| {
             for f in def.fields.iter() {
                match f.node.kind {
                     ast::NamedField(_, p) => check_inherited(tcx, f.span, p),
diff --git a/src/librustc/middle/region.rs b/src/librustc/middle/region.rs
index 392724bc9a18e..be89b32cdaae6 100644
--- a/src/librustc/middle/region.rs
+++ b/src/librustc/middle/region.rs
@@ -488,7 +488,7 @@ fn resolve_expr(visitor: &mut RegionResolutionVisitor, expr: &ast::Expr) {
 
     {
         let region_maps = &mut visitor.region_maps;
-        let terminating = |id| {
+        let terminating = |&: id| {
             let scope = CodeExtent::from_node_id(id);
             region_maps.mark_as_terminating_scope(scope)
         };
diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs
index ba52266e52d18..c06a8c1569cb8 100644
--- a/src/librustc/middle/ty.rs
+++ b/src/librustc/middle/ty.rs
@@ -6156,7 +6156,7 @@ pub fn hash_crate_independent<'tcx>(tcx: &ctxt<'tcx>, ty: Ty<'tcx>, svh: &Svh) -
         macro_rules! byte( ($b:expr) => { ($b as u8).hash(state) } );
         macro_rules! hash( ($e:expr) => { $e.hash(state) } );
 
-        let region = |state: &mut sip::SipState, r: Region| {
+        let region = |&: state: &mut sip::SipState, r: Region| {
             match r {
                 ReStatic => {}
                 ReLateBound(db, BrAnon(i)) => {
@@ -6173,7 +6173,7 @@ pub fn hash_crate_independent<'tcx>(tcx: &ctxt<'tcx>, ty: Ty<'tcx>, svh: &Svh) -
                 }
             }
         };
-        let did = |state: &mut sip::SipState, did: DefId| {
+        let did = |&: state: &mut sip::SipState, did: DefId| {
             let h = if ast_util::is_local(did) {
                 svh.clone()
             } else {
@@ -6182,10 +6182,10 @@ pub fn hash_crate_independent<'tcx>(tcx: &ctxt<'tcx>, ty: Ty<'tcx>, svh: &Svh) -
             h.as_str().hash(state);
             did.node.hash(state);
         };
-        let mt = |state: &mut sip::SipState, mt: mt| {
+        let mt = |&: state: &mut sip::SipState, mt: mt| {
             mt.mutbl.hash(state);
         };
-        let fn_sig = |state: &mut sip::SipState, sig: &Binder<FnSig<'tcx>>| {
+        let fn_sig = |&: state: &mut sip::SipState, sig: &Binder<FnSig<'tcx>>| {
             let sig = anonymize_late_bound_regions(tcx, sig);
             for a in sig.inputs.iter() { helper(tcx, *a, svh, state); }
             if let ty::FnConverging(output) = sig.output {

From a6f30532081fe2eab4b8f24008d494ff2ced9b7f Mon Sep 17 00:00:00 2001
From: Jorge Aparicio <japaricious@gmail.com>
Date: Tue, 30 Dec 2014 20:48:21 -0500
Subject: [PATCH 11/23] rustc_back: unbox closures used in let bindings

---
 src/librustc_back/target/mod.rs | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/librustc_back/target/mod.rs b/src/librustc_back/target/mod.rs
index 99a25bebf40ab..fdc9b72f1e9df 100644
--- a/src/librustc_back/target/mod.rs
+++ b/src/librustc_back/target/mod.rs
@@ -217,7 +217,7 @@ impl Target {
 
         let handler = diagnostic::default_handler(diagnostic::Auto, None);
 
-        let get_req_field = |name: &str| {
+        let get_req_field = |&: name: &str| {
             match obj.find(name)
                      .map(|s| s.as_string())
                      .and_then(|os| os.map(|s| s.to_string())) {

From 28ea99eaa6dc052cd3d934769a5c92d144ae5bb2 Mon Sep 17 00:00:00 2001
From: Jorge Aparicio <japaricious@gmail.com>
Date: Tue, 30 Dec 2014 20:55:22 -0500
Subject: [PATCH 12/23] rustc_borrowck: unbox closures used in let bindings

---
 src/librustc_borrowck/borrowck/fragments.rs    | 18 +++++++++---------
 .../borrowck/gather_loans/restrictions.rs      |  2 +-
 src/librustc_borrowck/borrowck/mod.rs          |  2 +-
 3 files changed, 11 insertions(+), 11 deletions(-)

diff --git a/src/librustc_borrowck/borrowck/fragments.rs b/src/librustc_borrowck/borrowck/fragments.rs
index 070ae1151aa6d..90da8906a6fa0 100644
--- a/src/librustc_borrowck/borrowck/fragments.rs
+++ b/src/librustc_borrowck/borrowck/fragments.rs
@@ -44,7 +44,7 @@ enum Fragment {
 
 impl Fragment {
     fn loan_path_repr<'tcx>(&self, move_data: &MoveData<'tcx>, tcx: &ty::ctxt<'tcx>) -> String {
-        let repr = |mpi| move_data.path_loan_path(mpi).repr(tcx);
+        let repr = |&: mpi| move_data.path_loan_path(mpi).repr(tcx);
         match *self {
             Just(mpi) => repr(mpi),
             AllButOneFrom(mpi) => format!("$(allbutone {})", repr(mpi)),
@@ -54,7 +54,7 @@ impl Fragment {
     fn loan_path_user_string<'tcx>(&self,
                                    move_data: &MoveData<'tcx>,
                                    tcx: &ty::ctxt<'tcx>) -> String {
-        let user_string = |mpi| move_data.path_loan_path(mpi).user_string(tcx);
+        let user_string = |&: mpi| move_data.path_loan_path(mpi).user_string(tcx);
         match *self {
             Just(mpi) => user_string(mpi),
             AllButOneFrom(mpi) => format!("$(allbutone {})", user_string(mpi)),
@@ -140,9 +140,9 @@ pub fn instrument_move_fragments<'tcx>(this: &MoveData<'tcx>,
 
     if !span_err && !print { return; }
 
-    let instrument_all_paths = |kind, vec_rc: &Vec<MovePathIndex>| {
+    let instrument_all_paths = |&: kind, vec_rc: &Vec<MovePathIndex>| {
         for (i, mpi) in vec_rc.iter().enumerate() {
-            let render = || this.path_loan_path(*mpi).user_string(tcx);
+            let render = |&:| this.path_loan_path(*mpi).user_string(tcx);
             if span_err {
                 tcx.sess.span_err(sp, format!("{}: `{}`", kind, render())[]);
             }
@@ -152,9 +152,9 @@ pub fn instrument_move_fragments<'tcx>(this: &MoveData<'tcx>,
         }
     };
 
-    let instrument_all_fragments = |kind, vec_rc: &Vec<Fragment>| {
+    let instrument_all_fragments = |&: kind, vec_rc: &Vec<Fragment>| {
         for (i, f) in vec_rc.iter().enumerate() {
-            let render = || f.loan_path_user_string(this, tcx);
+            let render = |&:| f.loan_path_user_string(this, tcx);
             if span_err {
                 tcx.sess.span_err(sp, format!("{}: `{}`", kind, render())[]);
             }
@@ -187,11 +187,11 @@ pub fn fixup_fragment_sets<'tcx>(this: &MoveData<'tcx>, tcx: &ty::ctxt<'tcx>) {
     let mut moved = mem::replace(&mut fragments.moved_leaf_paths, vec![]);
     let mut assigned = mem::replace(&mut fragments.assigned_leaf_paths, vec![]);
 
-    let path_lps = |mpis: &[MovePathIndex]| -> Vec<String> {
+    let path_lps = |&: mpis: &[MovePathIndex]| -> Vec<String> {
         mpis.iter().map(|mpi| this.path_loan_path(*mpi).repr(tcx)).collect()
     };
 
-    let frag_lps = |fs: &[Fragment]| -> Vec<String> {
+    let frag_lps = |&: fs: &[Fragment]| -> Vec<String> {
         fs.iter().map(|f| f.loan_path_repr(this, tcx)).collect()
     };
 
@@ -344,7 +344,7 @@ fn add_fragment_siblings_for_extension<'tcx>(this: &MoveData<'tcx>,
                                                                         Rc<LoanPath<'tcx>>)>) {
     let parent_ty = parent_lp.to_type();
 
-    let add_fragment_sibling_local = |field_name, variant_did| {
+    let mut add_fragment_sibling_local = |&mut : field_name, variant_did| {
         add_fragment_sibling_core(
             this, tcx, gathered_fragments, parent_lp.clone(), mc, field_name, origin_lp,
             variant_did);
diff --git a/src/librustc_borrowck/borrowck/gather_loans/restrictions.rs b/src/librustc_borrowck/borrowck/gather_loans/restrictions.rs
index b3fb7123ef3a7..ad31c52ca34f0 100644
--- a/src/librustc_borrowck/borrowck/gather_loans/restrictions.rs
+++ b/src/librustc_borrowck/borrowck/gather_loans/restrictions.rs
@@ -58,7 +58,7 @@ impl<'a, 'tcx> RestrictionsContext<'a, 'tcx> {
                 cmt: mc::cmt<'tcx>) -> RestrictionResult<'tcx> {
         debug!("restrict(cmt={})", cmt.repr(self.bccx.tcx));
 
-        let new_lp = |v: LoanPathKind<'tcx>| Rc::new(LoanPath::new(v, cmt.ty));
+        let new_lp = |&: v: LoanPathKind<'tcx>| Rc::new(LoanPath::new(v, cmt.ty));
 
         match cmt.cat.clone() {
             mc::cat_rvalue(..) => {
diff --git a/src/librustc_borrowck/borrowck/mod.rs b/src/librustc_borrowck/borrowck/mod.rs
index b57b76d66f719..c27b7b30e1345 100644
--- a/src/librustc_borrowck/borrowck/mod.rs
+++ b/src/librustc_borrowck/borrowck/mod.rs
@@ -431,7 +431,7 @@ pub fn opt_loan_path<'tcx>(cmt: &mc::cmt<'tcx>) -> Option<Rc<LoanPath<'tcx>>> {
     //! which allows it to share common loan path pieces as it
     //! traverses the CMT.
 
-    let new_lp = |v: LoanPathKind<'tcx>| Rc::new(LoanPath::new(v, cmt.ty));
+    let new_lp = |&: v: LoanPathKind<'tcx>| Rc::new(LoanPath::new(v, cmt.ty));
 
     match cmt.cat {
         mc::cat_rvalue(..) |

From a49cdb8c365881e32e5b31f7d438328d2e2344c4 Mon Sep 17 00:00:00 2001
From: Jorge Aparicio <japaricious@gmail.com>
Date: Tue, 30 Dec 2014 20:56:05 -0500
Subject: [PATCH 13/23] rustc_driver: unbox closures used in let bindings

---
 src/librustc_driver/lib.rs    | 8 ++++----
 src/librustc_driver/pretty.rs | 4 ++--
 2 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs
index 0d98434d042ba..181f38d89939e 100644
--- a/src/librustc_driver/lib.rs
+++ b/src/librustc_driver/lib.rs
@@ -278,7 +278,7 @@ Available lint options:
     let max_name_len = plugin.iter().chain(builtin.iter())
         .map(|&s| s.name.width(true))
         .max().unwrap_or(0);
-    let padded = |x: &str| {
+    let padded = |&: x: &str| {
         let mut s = repeat(" ").take(max_name_len - x.chars().count())
                                .collect::<String>();
         s.push_str(x);
@@ -289,7 +289,7 @@ Available lint options:
     println!("    {}  {:7.7}  {}", padded("name"), "default", "meaning");
     println!("    {}  {:7.7}  {}", padded("----"), "-------", "-------");
 
-    let print_lints = |lints: Vec<&Lint>| {
+    let print_lints = |&: lints: Vec<&Lint>| {
         for lint in lints.into_iter() {
             let name = lint.name_lower().replace("_", "-");
             println!("    {}  {:7.7}  {}",
@@ -305,7 +305,7 @@ Available lint options:
     let max_name_len = plugin_groups.iter().chain(builtin_groups.iter())
         .map(|&(s, _)| s.width(true))
         .max().unwrap_or(0);
-    let padded = |x: &str| {
+    let padded = |&: x: &str| {
         let mut s = repeat(" ").take(max_name_len - x.chars().count())
                                .collect::<String>();
         s.push_str(x);
@@ -316,7 +316,7 @@ Available lint options:
     println!("    {}  {}", padded("name"), "sub-lints");
     println!("    {}  {}", padded("----"), "---------");
 
-    let print_lint_groups = |lints: Vec<(&'static str, Vec<lint::LintId>)>| {
+    let print_lint_groups = |&: lints: Vec<(&'static str, Vec<lint::LintId>)>| {
         for (name, to) in lints.into_iter() {
             let name = name.chars().map(|x| x.to_lowercase())
                            .collect::<String>().replace("_", "-");
diff --git a/src/librustc_driver/pretty.rs b/src/librustc_driver/pretty.rs
index cf99d409ceb38..773ea30d401fc 100644
--- a/src/librustc_driver/pretty.rs
+++ b/src/librustc_driver/pretty.rs
@@ -301,7 +301,7 @@ fn gather_flowgraph_variants(sess: &Session) -> Vec<borrowck_dot::Variant> {
     let print_moves   = config::FLOWGRAPH_PRINT_MOVES;
     let print_assigns = config::FLOWGRAPH_PRINT_ASSIGNS;
     let print_all     = config::FLOWGRAPH_PRINT_ALL;
-    let opt = |print_which| sess.debugging_opt(print_which);
+    let opt = |&: print_which| sess.debugging_opt(print_which);
     let mut variants = Vec::new();
     if opt(print_all) || opt(print_loans) {
         variants.push(borrowck_dot::Loans);
@@ -365,7 +365,7 @@ impl UserIdentifiedItem {
     }
 
     fn to_one_node_id(self, user_option: &str, sess: &Session, map: &ast_map::Map) -> ast::NodeId {
-        let fail_because = |is_wrong_because| -> ast::NodeId {
+        let fail_because = |&: is_wrong_because| -> ast::NodeId {
             let message =
                 format!("{} needs NodeId (int) or unique \
                          path suffix (b::c::d); got {}, which {}",

From 1e4bbefae126be24cb443252039ef0fd5ccba62c Mon Sep 17 00:00:00 2001
From: Jorge Aparicio <japaricious@gmail.com>
Date: Tue, 30 Dec 2014 20:56:41 -0500
Subject: [PATCH 14/23] rustc_resolve: unbox closures used in let bindings

---
 src/librustc_resolve/lib.rs | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs
index e371046a9b21d..7efa9ad737f52 100644
--- a/src/librustc_resolve/lib.rs
+++ b/src/librustc_resolve/lib.rs
@@ -1448,7 +1448,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
         let mut import_resolutions = module_.import_resolutions.borrow_mut();
         let import_resolution = &mut (*import_resolutions)[target];
         {
-            let check_and_write_import = |namespace, result: &_, used_public: &mut bool| {
+            let mut check_and_write_import = |&mut: namespace, result: &_, used_public: &mut bool| {
                 let namespace_name = match namespace {
                     TypeNS => "type",
                     ValueNS => "value",
@@ -1691,7 +1691,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
 
         // Merge the child item into the import resolution.
         {
-            let merge_child_item = |namespace| {
+            let mut merge_child_item = |&mut : namespace| {
                 if name_bindings.defined_in_namespace_with(namespace, IMPORTABLE | PUBLIC) {
                     let namespace_name = match namespace {
                         TypeNS => "type",

From e47035b9a58e4dd0cda075928bb93df0b7b25372 Mon Sep 17 00:00:00 2001
From: Jorge Aparicio <japaricious@gmail.com>
Date: Tue, 30 Dec 2014 20:58:47 -0500
Subject: [PATCH 15/23] rustc_trans: unbox closures used in let bindings

---
 src/librustc_trans/back/link.rs          | 2 +-
 src/librustc_trans/back/write.rs         | 8 ++++----
 src/librustc_trans/trans/_match.rs       | 2 +-
 src/librustc_trans/trans/base.rs         | 8 ++++----
 src/librustc_trans/trans/consts.rs       | 2 +-
 src/librustc_trans/trans/debuginfo.rs    | 2 +-
 src/librustc_trans/trans/foreign.rs      | 2 +-
 src/librustc_trans/trans/intrinsic.rs    | 2 +-
 src/librustc_trans/trans/monomorphize.rs | 4 ++--
 9 files changed, 16 insertions(+), 16 deletions(-)

diff --git a/src/librustc_trans/back/link.rs b/src/librustc_trans/back/link.rs
index 39ba2a98ce42a..93ff9f53ec12d 100644
--- a/src/librustc_trans/back/link.rs
+++ b/src/librustc_trans/back/link.rs
@@ -127,7 +127,7 @@ pub const RLIB_BYTECODE_OBJECT_V1_DATA_OFFSET: uint =
 pub fn find_crate_name(sess: Option<&Session>,
                        attrs: &[ast::Attribute],
                        input: &Input) -> String {
-    let validate = |s: String, span: Option<Span>| {
+    let validate = |&: s: String, span: Option<Span>| {
         creader::validate_crate_name(sess, s[], span);
         s
     };
diff --git a/src/librustc_trans/back/write.rs b/src/librustc_trans/back/write.rs
index 99e11bf520205..a6f2c7dfed0b1 100644
--- a/src/librustc_trans/back/write.rs
+++ b/src/librustc_trans/back/write.rs
@@ -431,7 +431,7 @@ unsafe fn optimize_and_codegen(cgcx: &CodegenContext,
 
             // If we're verifying or linting, add them to the function pass
             // manager.
-            let addpass = |pass: &str| {
+            let addpass = |&: pass: &str| {
                 pass.with_c_str(|s| llvm::LLVMRustAddPass(fpm, s))
             };
             if !config.no_verify { assert!(addpass("verify")); }
@@ -652,7 +652,7 @@ pub fn run_passes(sess: &Session,
 
     // Produce final compile outputs.
 
-    let copy_if_one_unit = |ext: &str, output_type: config::OutputType, keep_numbered: bool| {
+    let copy_if_one_unit = |&: ext: &str, output_type: config::OutputType, keep_numbered: bool| {
         // Three cases:
         if sess.opts.cg.codegen_units == 1 {
             // 1) Only one codegen unit.  In this case it's no difficulty
@@ -677,7 +677,7 @@ pub fn run_passes(sess: &Session,
         }
     };
 
-    let link_obj = |output_path: &Path| {
+    let link_obj = |&: output_path: &Path| {
         // Running `ld -r` on a single input is kind of pointless.
         if sess.opts.cg.codegen_units == 1 {
             fs::copy(&crate_output.with_extension("0.o"),
@@ -993,7 +993,7 @@ unsafe fn configure_llvm(sess: &Session) {
     let mut llvm_c_strs = Vec::new();
     let mut llvm_args = Vec::new();
     {
-        let add = |arg: &str| {
+        let mut add = |&mut : arg: &str| {
             let s = arg.to_c_str();
             llvm_args.push(s.as_ptr());
             llvm_c_strs.push(s);
diff --git a/src/librustc_trans/trans/_match.rs b/src/librustc_trans/trans/_match.rs
index c6e4ce9457b53..6e6b1c3406190 100644
--- a/src/librustc_trans/trans/_match.rs
+++ b/src/librustc_trans/trans/_match.rs
@@ -748,7 +748,7 @@ fn pick_column_to_specialize(def_map: &DefMap, m: &[Match]) -> Option<uint> {
         }
     }
 
-    let column_score: |&[Match], uint| -> uint = |m, col| {
+    let column_score = |&: m: &[Match], col: uint| -> uint {
         let total_score = m.iter()
             .map(|row| row.pats[col])
             .map(|pat| pat_score(def_map, pat))
diff --git a/src/librustc_trans/trans/base.rs b/src/librustc_trans/trans/base.rs
index fb4ae21478bc2..475443654264f 100644
--- a/src/librustc_trans/trans/base.rs
+++ b/src/librustc_trans/trans/base.rs
@@ -554,7 +554,7 @@ pub fn compare_scalar_types<'blk, 'tcx>(cx: Block<'blk, 'tcx>,
                                         t: Ty<'tcx>,
                                         op: ast::BinOp)
                                         -> Result<'blk, 'tcx> {
-    let f = |a| Result::new(cx, compare_scalar_values(cx, lhs, rhs, a, op));
+    let f = |&: a| Result::new(cx, compare_scalar_values(cx, lhs, rhs, a, op));
 
     match t.sty {
         ty::ty_tup(ref tys) if tys.is_empty() => f(nil_type),
@@ -2749,7 +2749,7 @@ pub fn get_item_val(ccx: &CrateContext, id: ast::NodeId) -> ValueRef {
     let val = match item {
         ast_map::NodeItem(i) => {
             let ty = ty::node_id_to_type(ccx.tcx(), i.id);
-            let sym = || exported_name(ccx, id, ty, i.attrs[]);
+            let sym = |&:| exported_name(ccx, id, ty, i.attrs[]);
 
             let v = match i.node {
                 ast::ItemStatic(_, _, ref expr) => {
@@ -3013,14 +3013,14 @@ fn internalize_symbols(cx: &SharedCrateContext, reachable: &HashSet<String>) {
     unsafe {
         let mut declared = HashSet::new();
 
-        let iter_globals = |llmod| {
+        let iter_globals = |&: llmod| {
             ValueIter {
                 cur: llvm::LLVMGetFirstGlobal(llmod),
                 step: llvm::LLVMGetNextGlobal,
             }
         };
 
-        let iter_functions = |llmod| {
+        let iter_functions = |&: llmod| {
             ValueIter {
                 cur: llvm::LLVMGetFirstFunction(llmod),
                 step: llvm::LLVMGetNextFunction,
diff --git a/src/librustc_trans/trans/consts.rs b/src/librustc_trans/trans/consts.rs
index 1f01da8a124b3..347ec100ae7ad 100644
--- a/src/librustc_trans/trans/consts.rs
+++ b/src/librustc_trans/trans/consts.rs
@@ -305,7 +305,7 @@ pub fn const_expr<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, e: &ast::Expr)
 // the bool returned is whether this expression can be inlined into other crates
 // if it's assigned to a static.
 fn const_expr_unadjusted(cx: &CrateContext, e: &ast::Expr) -> ValueRef {
-    let map_list = |exprs: &[P<ast::Expr>]| {
+    let map_list = |&: exprs: &[P<ast::Expr>]| {
         exprs.iter().map(|e| const_expr(cx, &**e).0)
              .fold(Vec::new(), |mut l, val| { l.push(val); l })
     };
diff --git a/src/librustc_trans/trans/debuginfo.rs b/src/librustc_trans/trans/debuginfo.rs
index 589250430cd71..bce446b741271 100644
--- a/src/librustc_trans/trans/debuginfo.rs
+++ b/src/librustc_trans/trans/debuginfo.rs
@@ -2489,7 +2489,7 @@ fn prepare_enum_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
         })
         .collect();
 
-    let discriminant_type_metadata = |inttype| {
+    let discriminant_type_metadata = |&: inttype| {
         // We can reuse the type of the discriminant for all monomorphized
         // instances of an enum because it doesn't depend on any type parameters.
         // The def_id, uniquely identifying the enum's polytype acts as key in
diff --git a/src/librustc_trans/trans/foreign.rs b/src/librustc_trans/trans/foreign.rs
index e234d77914b64..83765270ef103 100644
--- a/src/librustc_trans/trans/foreign.rs
+++ b/src/librustc_trans/trans/foreign.rs
@@ -615,7 +615,7 @@ pub fn trans_rust_fn_with_foreign_abi<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
         // Array for the arguments we will pass to the rust function.
         let mut llrust_args = Vec::new();
         let mut next_foreign_arg_counter: c_uint = 0;
-        let next_foreign_arg: |pad: bool| -> c_uint = |pad: bool| {
+        let mut next_foreign_arg = |&mut : pad: bool| -> c_uint {
             next_foreign_arg_counter += if pad {
                 2
             } else {
diff --git a/src/librustc_trans/trans/intrinsic.rs b/src/librustc_trans/trans/intrinsic.rs
index d49018e00c1cb..a22ce297828a9 100644
--- a/src/librustc_trans/trans/intrinsic.rs
+++ b/src/librustc_trans/trans/intrinsic.rs
@@ -181,7 +181,7 @@ pub fn trans_intrinsic_call<'a, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
                 // This should be caught by the intrinsicck pass
                 assert_eq!(in_type_size, out_type_size);
 
-                let nonpointer_nonaggregate = |llkind: TypeKind| -> bool {
+                let nonpointer_nonaggregate = |&: llkind: TypeKind| -> bool {
                     use llvm::TypeKind::*;
                     match llkind {
                         Half | Float | Double | X86_FP80 | FP128 |
diff --git a/src/librustc_trans/trans/monomorphize.rs b/src/librustc_trans/trans/monomorphize.rs
index 3b7043e4f40f0..3166425f3aa3b 100644
--- a/src/librustc_trans/trans/monomorphize.rs
+++ b/src/librustc_trans/trans/monomorphize.rs
@@ -139,7 +139,7 @@ pub fn monomorphic_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
 
     // This shouldn't need to option dance.
     let mut hash_id = Some(hash_id);
-    let mk_lldecl = |abi: abi::Abi| {
+    let mut mk_lldecl = |&mut : abi: abi::Abi| {
         let lldecl = if abi != abi::Rust {
             foreign::decl_rust_fn_with_foreign_abi(ccx, mono_ty, s[])
         } else {
@@ -149,7 +149,7 @@ pub fn monomorphic_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
         ccx.monomorphized().borrow_mut().insert(hash_id.take().unwrap(), lldecl);
         lldecl
     };
-    let setup_lldecl = |lldecl, attrs: &[ast::Attribute]| {
+    let setup_lldecl = |&: lldecl, attrs: &[ast::Attribute]| {
         base::update_linkage(ccx, lldecl, None, base::OriginalTranslation);
         set_llvm_fn_attrs(ccx, attrs, lldecl);
 

From e9ddd825ba7c93a0c75ce25819ac596b835e9332 Mon Sep 17 00:00:00 2001
From: Jorge Aparicio <japaricious@gmail.com>
Date: Tue, 30 Dec 2014 20:59:12 -0500
Subject: [PATCH 16/23] rustc_typeck: unbox closures used in let bindings

---
 src/librustc_typeck/check/vtable.rs | 2 +-
 src/librustc_typeck/variance.rs     | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/librustc_typeck/check/vtable.rs b/src/librustc_typeck/check/vtable.rs
index f153b51c5df77..15e942006f018 100644
--- a/src/librustc_typeck/check/vtable.rs
+++ b/src/librustc_typeck/check/vtable.rs
@@ -223,7 +223,7 @@ fn check_object_safety_inner<'tcx>(tcx: &ty::ctxt<'tcx>,
         }
 
         // reason (a) above
-        let check_for_self_ty = |ty| {
+        let check_for_self_ty = |&: ty| {
             if contains_illegal_self_type_reference(tcx, object_trait.def_id(), ty) {
                 Some(format!(
                     "cannot call a method (`{}`) whose type contains \
diff --git a/src/librustc_typeck/variance.rs b/src/librustc_typeck/variance.rs
index de0b0a7ad3548..cd8bc94b111e7 100644
--- a/src/librustc_typeck/variance.rs
+++ b/src/librustc_typeck/variance.rs
@@ -593,7 +593,7 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
         // parameter (by inspecting parent of its binding declaration
         // to see if it is introduced by a type or by a fn/impl).
 
-        let check_result = |this:&ConstraintContext| -> bool {
+        let check_result = |&: this:&ConstraintContext| -> bool {
             let tcx = this.terms_cx.tcx;
             let decl_id = this.find_binding_for_lifetime(param_id);
             // Currently only called on lifetimes; double-checking that.

From fb14dad4d6f8547dc7e6ca0231d24580bdac96c9 Mon Sep 17 00:00:00 2001
From: Jorge Aparicio <japaricious@gmail.com>
Date: Tue, 30 Dec 2014 20:59:47 -0500
Subject: [PATCH 17/23] rustdoc: unbox closures used in let bindings

---
 src/librustdoc/clean/mod.rs      | 2 +-
 src/librustdoc/html/highlight.rs | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs
index 1fbfbe7eb1ab5..459d6409f676a 100644
--- a/src/librustdoc/clean/mod.rs
+++ b/src/librustdoc/clean/mod.rs
@@ -2016,7 +2016,7 @@ impl Clean<Vec<Item>> for ast::ViewItem {
                 None => false,
             }
         });
-        let convert = |node: &ast::ViewItem_| {
+        let convert = |&: node: &ast::ViewItem_| {
             Item {
                 name: None,
                 attrs: self.attrs.clean(cx),
diff --git a/src/librustdoc/html/highlight.rs b/src/librustdoc/html/highlight.rs
index c936f6a0819d2..cfaae1a9f80fd 100644
--- a/src/librustdoc/html/highlight.rs
+++ b/src/librustdoc/html/highlight.rs
@@ -61,7 +61,7 @@ fn doit(sess: &parse::ParseSess, mut lexer: lexer::StringReader,
     loop {
         let next = lexer.next_token();
 
-        let snip = |sp| sess.span_diagnostic.cm.span_to_snippet(sp).unwrap();
+        let snip = |&: sp| sess.span_diagnostic.cm.span_to_snippet(sp).unwrap();
 
         if next.tok == token::Eof { break }
 

From 12dd7781d64f5898a435bb3d0210e0518285e128 Mon Sep 17 00:00:00 2001
From: Jorge Aparicio <japaricious@gmail.com>
Date: Tue, 30 Dec 2014 21:01:00 -0500
Subject: [PATCH 18/23] std: unbox closures used in let bindings

---
 src/libstd/io/net/udp.rs          | 2 +-
 src/libstd/num/strconv.rs         | 4 ++--
 src/libstd/sys/unix/process.rs    | 2 +-
 src/libstd/sys/windows/process.rs | 2 +-
 4 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/src/libstd/io/net/udp.rs b/src/libstd/io/net/udp.rs
index 1431067d4c6a3..73bcdad34c3a0 100644
--- a/src/libstd/io/net/udp.rs
+++ b/src/libstd/io/net/udp.rs
@@ -344,7 +344,7 @@ mod test {
         let (tx2, rx2) = channel();
 
         spawn(move|| {
-            let send_as = |ip, val: &[u8]| {
+            let send_as = |&: ip, val: &[u8]| {
                 match UdpSocket::bind(ip) {
                     Ok(client) => {
                         let client = box client;
diff --git a/src/libstd/num/strconv.rs b/src/libstd/num/strconv.rs
index b1f4e5acb93f4..25af3bf2d5383 100644
--- a/src/libstd/num/strconv.rs
+++ b/src/libstd/num/strconv.rs
@@ -321,10 +321,10 @@ pub fn float_to_str_bytes_common<T: Float>(
         // cut off the one extra digit, and depending on its value
         // round the remaining ones.
         if limit_digits && dig == digit_count {
-            let ascii2value = |chr: u8| {
+            let ascii2value = |&: chr: u8| {
                 (chr as char).to_digit(radix).unwrap()
             };
-            let value2ascii = |val: uint| {
+            let value2ascii = |&: val: uint| {
                 char::from_digit(val, radix).unwrap() as u8
             };
 
diff --git a/src/libstd/sys/unix/process.rs b/src/libstd/sys/unix/process.rs
index 835f4279d9bc6..615e3a21bd0ac 100644
--- a/src/libstd/sys/unix/process.rs
+++ b/src/libstd/sys/unix/process.rs
@@ -195,7 +195,7 @@ impl Process {
                 // up /dev/null into that file descriptor. Otherwise, the first file
                 // descriptor opened up in the child would be numbered as one of the
                 // stdio file descriptors, which is likely to wreak havoc.
-                let setup = |src: Option<P>, dst: c_int| {
+                let setup = |&: src: Option<P>, dst: c_int| {
                     let src = match src {
                         None => {
                             let flags = if dst == libc::STDIN_FILENO {
diff --git a/src/libstd/sys/windows/process.rs b/src/libstd/sys/windows/process.rs
index 0c2c76077dd54..b03c62395d1a0 100644
--- a/src/libstd/sys/windows/process.rs
+++ b/src/libstd/sys/windows/process.rs
@@ -162,7 +162,7 @@ impl Process {
             // Similarly to unix, we don't actually leave holes for the stdio file
             // descriptors, but rather open up /dev/null equivalents. These
             // equivalents are drawn from libuv's windows process spawning.
-            let set_fd = |fd: &Option<P>, slot: &mut HANDLE,
+            let set_fd = |&: fd: &Option<P>, slot: &mut HANDLE,
                           is_stdin: bool| {
                 match *fd {
                     None => {

From ab402c0744f1cb542dee01f810b0c96e47c44df0 Mon Sep 17 00:00:00 2001
From: Jorge Aparicio <japaricious@gmail.com>
Date: Tue, 30 Dec 2014 21:02:53 -0500
Subject: [PATCH 19/23] syntax: unbox closures used in let bindings

---
 src/libsyntax/ext/deriving/default.rs     |  2 +-
 src/libsyntax/ext/deriving/generic/mod.rs |  2 +-
 src/libsyntax/ext/deriving/hash.rs        |  2 +-
 src/libsyntax/ext/deriving/zero.rs        |  2 +-
 src/libsyntax/ext/expand.rs               |  2 +-
 src/libsyntax/ext/quote.rs                |  4 ++--
 src/libsyntax/parse/mod.rs                | 10 +++++-----
 src/libsyntax/test.rs                     |  6 +++---
 8 files changed, 15 insertions(+), 15 deletions(-)

diff --git a/src/libsyntax/ext/deriving/default.rs b/src/libsyntax/ext/deriving/default.rs
index b3621490ce3bf..49bcb26a4c283 100644
--- a/src/libsyntax/ext/deriving/default.rs
+++ b/src/libsyntax/ext/deriving/default.rs
@@ -55,7 +55,7 @@ fn default_substructure(cx: &mut ExtCtxt, trait_span: Span, substr: &Substructur
         cx.ident_of("Default"),
         cx.ident_of("default")
     );
-    let default_call = |span| cx.expr_call_global(span, default_ident.clone(), Vec::new());
+    let default_call = |&: span| cx.expr_call_global(span, default_ident.clone(), Vec::new());
 
     return match *substr.fields {
         StaticStruct(_, ref summary) => {
diff --git a/src/libsyntax/ext/deriving/generic/mod.rs b/src/libsyntax/ext/deriving/generic/mod.rs
index e4e31139d82f4..9149c20ce1b57 100644
--- a/src/libsyntax/ext/deriving/generic/mod.rs
+++ b/src/libsyntax/ext/deriving/generic/mod.rs
@@ -935,7 +935,7 @@ impl<'a> MethodDef<'a> {
         // where each tuple has length = self_args.len()
         let mut match_arms: Vec<ast::Arm> = variants.iter().enumerate()
             .map(|(index, variant)| {
-                let mk_self_pat = |cx: &mut ExtCtxt, self_arg_name: &str| {
+                let mk_self_pat = |&: cx: &mut ExtCtxt, self_arg_name: &str| {
                     let (p, idents) = trait_.create_enum_variant_pattern(cx, type_ident,
                                                                          &**variant,
                                                                          self_arg_name,
diff --git a/src/libsyntax/ext/deriving/hash.rs b/src/libsyntax/ext/deriving/hash.rs
index 72e3b45dc91b7..9ad0ad1621765 100644
--- a/src/libsyntax/ext/deriving/hash.rs
+++ b/src/libsyntax/ext/deriving/hash.rs
@@ -71,7 +71,7 @@ fn hash_substructure(cx: &mut ExtCtxt, trait_span: Span, substr: &Substructure)
         _ => cx.span_bug(trait_span, "incorrect number of arguments in `deriving(Hash)`")
     };
     let hash_ident = substr.method_ident;
-    let call_hash = |span, thing_expr| {
+    let call_hash = |&: span, thing_expr| {
         let expr = cx.expr_method_call(span, thing_expr, hash_ident, vec!(state_expr.clone()));
         cx.stmt_expr(expr)
     };
diff --git a/src/libsyntax/ext/deriving/zero.rs b/src/libsyntax/ext/deriving/zero.rs
index ea32549cad266..73331f06aa4ee 100644
--- a/src/libsyntax/ext/deriving/zero.rs
+++ b/src/libsyntax/ext/deriving/zero.rs
@@ -71,7 +71,7 @@ fn zero_substructure(cx: &mut ExtCtxt, trait_span: Span, substr: &Substructure)
         cx.ident_of("Zero"),
         cx.ident_of("zero")
     );
-    let zero_call = |span| cx.expr_call_global(span, zero_ident.clone(), Vec::new());
+    let zero_call = |&: span| cx.expr_call_global(span, zero_ident.clone(), Vec::new());
 
     return match *substr.fields {
         StaticStruct(_, ref summary) => {
diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs
index f9bffcc897460..5de7068563d59 100644
--- a/src/libsyntax/ext/expand.rs
+++ b/src/libsyntax/ext/expand.rs
@@ -1660,7 +1660,7 @@ mod test {
             assert!((shouldmatch.len() == 0) ||
                     (varrefs.len() > *shouldmatch.iter().max().unwrap()));
             for (idx,varref) in varrefs.iter().enumerate() {
-                let print_hygiene_debug_info = || {
+                let print_hygiene_debug_info = |&:| {
                     // good lord, you can't make a path with 0 segments, can you?
                     let final_varref_ident = match varref.segments.last() {
                         Some(pathsegment) => pathsegment.identifier,
diff --git a/src/libsyntax/ext/quote.rs b/src/libsyntax/ext/quote.rs
index 368d4fa84476f..d87960ebdb82a 100644
--- a/src/libsyntax/ext/quote.rs
+++ b/src/libsyntax/ext/quote.rs
@@ -800,11 +800,11 @@ fn expand_parse_call(cx: &ExtCtxt,
                      tts: &[ast::TokenTree]) -> P<ast::Expr> {
     let (cx_expr, tts_expr) = expand_tts(cx, sp, tts);
 
-    let cfg_call = || cx.expr_method_call(
+    let cfg_call = |&:| cx.expr_method_call(
         sp, cx.expr_ident(sp, id_ext("ext_cx")),
         id_ext("cfg"), Vec::new());
 
-    let parse_sess_call = || cx.expr_method_call(
+    let parse_sess_call = |&:| cx.expr_method_call(
         sp, cx.expr_ident(sp, id_ext("ext_cx")),
         id_ext("parse_sess"), Vec::new());
 
diff --git a/src/libsyntax/parse/mod.rs b/src/libsyntax/parse/mod.rs
index 8cefb111fd1fc..88c485a07acdf 100644
--- a/src/libsyntax/parse/mod.rs
+++ b/src/libsyntax/parse/mod.rs
@@ -240,7 +240,7 @@ pub fn new_parser_from_tts<'a>(sess: &'a ParseSess,
 /// add the path to the session's codemap and return the new filemap.
 pub fn file_to_filemap(sess: &ParseSess, path: &Path, spanopt: Option<Span>)
     -> Rc<FileMap> {
-    let err = |msg: &str| {
+    let err = |&: msg: &str| {
         match spanopt {
             Some(sp) => sess.span_diagnostic.span_fatal(sp, msg),
             None => sess.span_diagnostic.handler().fatal(msg),
@@ -399,7 +399,7 @@ pub fn char_lit(lit: &str) -> (char, int) {
         .map(|x| (x, len as int))
     }
 
-    let unicode_escape: || -> Option<(char, int)> = ||
+    let unicode_escape = |&: | -> Option<(char, int)>
         if lit.as_bytes()[2] == b'{' {
             let idx = lit.find('}').expect(msg2);
             let subslice = lit[3..idx];
@@ -426,7 +426,7 @@ pub fn str_lit(lit: &str) -> String {
     let mut res = String::with_capacity(lit.len());
 
     // FIXME #8372: This could be a for-loop if it didn't borrow the iterator
-    let error = |i| format!("lexer should have rejected {} at {}", lit, i);
+    let error = |&: i| format!("lexer should have rejected {} at {}", lit, i);
 
     /// Eat everything up to a non-whitespace
     fn eat<'a>(it: &mut iter::Peekable<(uint, char), str::CharIndices<'a>>) {
@@ -561,7 +561,7 @@ pub fn float_lit(s: &str, suffix: Option<&str>, sd: &SpanHandler, sp: Span) -> a
 
 /// Parse a string representing a byte literal into its final form. Similar to `char_lit`
 pub fn byte_lit(lit: &str) -> (u8, uint) {
-    let err = |i| format!("lexer accepted invalid byte literal {} step {}", lit, i);
+    let err = |&: i| format!("lexer accepted invalid byte literal {} step {}", lit, i);
 
     if lit.len() == 1 {
         (lit.as_bytes()[0], 1)
@@ -595,7 +595,7 @@ pub fn binary_lit(lit: &str) -> Rc<Vec<u8>> {
     let mut res = Vec::with_capacity(lit.len());
 
     // FIXME #8372: This could be a for-loop if it didn't borrow the iterator
-    let error = |i| format!("lexer should have rejected {} at {}", lit, i);
+    let error = |&: i| format!("lexer should have rejected {} at {}", lit, i);
 
     /// Eat everything up to a non-whitespace
     fn eat<'a, I: Iterator<(uint, u8)>>(it: &mut iter::Peekable<(uint, u8), I>) {
diff --git a/src/libsyntax/test.rs b/src/libsyntax/test.rs
index bc7dda8c44acc..93fe868f52c68 100644
--- a/src/libsyntax/test.rs
+++ b/src/libsyntax/test.rs
@@ -545,11 +545,11 @@ fn mk_test_desc_and_fn_rec(cx: &TestCtxt, test: &Test) -> P<ast::Expr> {
     let test_id = ecx.ident_of("test");
 
     // creates self::test::$name
-    let test_path = |name| {
+    let test_path = |&: name| {
         ecx.path(span, vec![self_id, test_id, ecx.ident_of(name)])
     };
     // creates $name: $expr
-    let field = |name, expr| ecx.field_imm(span, ecx.ident_of(name), expr);
+    let field = |&: name, expr| ecx.field_imm(span, ecx.ident_of(name), expr);
 
     debug!("encoding {}", ast_util::path_name_i(path[]));
 
@@ -563,7 +563,7 @@ fn mk_test_desc_and_fn_rec(cx: &TestCtxt, test: &Test) -> P<ast::Expr> {
                                   vec![name_expr]);
 
     let ignore_expr = ecx.expr_bool(span, test.ignore);
-    let should_fail_path = |name| {
+    let should_fail_path = |&: name| {
         ecx.path(span, vec![self_id, test_id, ecx.ident_of("ShouldFail"), ecx.ident_of(name)])
     };
     let fail_expr = match test.should_fail {

From 63af3e6cd2a24a02ad38e47f37010fff30c19908 Mon Sep 17 00:00:00 2001
From: Jorge Aparicio <japaricious@gmail.com>
Date: Tue, 30 Dec 2014 21:03:26 -0500
Subject: [PATCH 20/23] time: unbox closures used in let bindings

---
 src/libtime/lib.rs | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/libtime/lib.rs b/src/libtime/lib.rs
index 930aa0270647c..87a00334c478f 100644
--- a/src/libtime/lib.rs
+++ b/src/libtime/lib.rs
@@ -596,7 +596,7 @@ impl<'a> fmt::Show for TmFmt<'a> {
         }
 
         fn parse_type(fmt: &mut fmt::Formatter, ch: char, tm: &Tm) -> fmt::Result {
-            let die = || {
+            let die = |&:| {
                 unreachable!()
             };
             match ch {

From 1d21dad1d29d57875ff47b38e5894668f5bec6f9 Mon Sep 17 00:00:00 2001
From: Jorge Aparicio <japaricious@gmail.com>
Date: Tue, 30 Dec 2014 22:48:22 -0500
Subject: [PATCH 21/23] rustc: replace `GetCrateDataCb` alias with an unboxed
 closure

---
 src/librustc/metadata/csearch.rs |  4 ++--
 src/librustc/metadata/decoder.rs | 33 ++++++++++++++++----------------
 2 files changed, 19 insertions(+), 18 deletions(-)

diff --git a/src/librustc/metadata/csearch.rs b/src/librustc/metadata/csearch.rs
index 0cbc94f379d80..2b11b8517b0d8 100644
--- a/src/librustc/metadata/csearch.rs
+++ b/src/librustc/metadata/csearch.rs
@@ -62,7 +62,7 @@ pub fn each_child_of_item<F>(cstore: &cstore::CStore,
     F: FnMut(decoder::DefLike, ast::Name, ast::Visibility),
 {
     let crate_data = cstore.get_crate_data(def_id.krate);
-    let get_crate_data: decoder::GetCrateDataCb = |cnum| {
+    let get_crate_data = |&mut: cnum| {
         cstore.get_crate_data(cnum)
     };
     decoder::each_child_of_item(cstore.intr.clone(),
@@ -79,7 +79,7 @@ pub fn each_top_level_item_of_crate<F>(cstore: &cstore::CStore,
     F: FnMut(decoder::DefLike, ast::Name, ast::Visibility),
 {
     let crate_data = cstore.get_crate_data(cnum);
-    let get_crate_data: decoder::GetCrateDataCb = |cnum| {
+    let get_crate_data = |&mut: cnum| {
         cstore.get_crate_data(cnum)
     };
     decoder::each_top_level_item_of_crate(cstore.intr.clone(),
diff --git a/src/librustc/metadata/decoder.rs b/src/librustc/metadata/decoder.rs
index a168ac7fa9a78..d079d0e52aafa 100644
--- a/src/librustc/metadata/decoder.rs
+++ b/src/librustc/metadata/decoder.rs
@@ -487,14 +487,13 @@ pub fn each_lang_item<F>(cdata: Cmd, mut f: F) -> bool where
     })
 }
 
-pub type GetCrateDataCb<'a> = |ast::CrateNum|: 'a -> Rc<crate_metadata>;
-
-fn each_child_of_item_or_crate<F>(intr: Rc<IdentInterner>,
-                                  cdata: Cmd,
-                                  item_doc: rbml::Doc,
-                                  get_crate_data: GetCrateDataCb,
-                                  mut callback: F) where
+fn each_child_of_item_or_crate<F, G>(intr: Rc<IdentInterner>,
+                                     cdata: Cmd,
+                                     item_doc: rbml::Doc,
+                                     mut get_crate_data: G,
+                                     mut callback: F) where
     F: FnMut(DefLike, ast::Name, ast::Visibility),
+    G: FnMut(ast::CrateNum) -> Rc<crate_metadata>,
 {
     // Iterate over all children.
     let _ = reader::tagged_docs(item_doc, tag_mod_child, |child_info_doc| {
@@ -608,12 +607,13 @@ fn each_child_of_item_or_crate<F>(intr: Rc<IdentInterner>,
 }
 
 /// Iterates over each child of the given item.
-pub fn each_child_of_item<F>(intr: Rc<IdentInterner>,
-                             cdata: Cmd,
-                             id: ast::NodeId,
-                             get_crate_data: GetCrateDataCb,
-                             callback: F) where
+pub fn each_child_of_item<F, G>(intr: Rc<IdentInterner>,
+                               cdata: Cmd,
+                               id: ast::NodeId,
+                               get_crate_data: G,
+                               callback: F) where
     F: FnMut(DefLike, ast::Name, ast::Visibility),
+    G: FnMut(ast::CrateNum) -> Rc<crate_metadata>,
 {
     // Find the item.
     let root_doc = rbml::Doc::new(cdata.data());
@@ -631,11 +631,12 @@ pub fn each_child_of_item<F>(intr: Rc<IdentInterner>,
 }
 
 /// Iterates over all the top-level crate items.
-pub fn each_top_level_item_of_crate<F>(intr: Rc<IdentInterner>,
-                                       cdata: Cmd,
-                                       get_crate_data: GetCrateDataCb,
-                                       callback: F) where
+pub fn each_top_level_item_of_crate<F, G>(intr: Rc<IdentInterner>,
+                                          cdata: Cmd,
+                                          get_crate_data: G,
+                                          callback: F) where
     F: FnMut(DefLike, ast::Name, ast::Visibility),
+    G: FnMut(ast::CrateNum) -> Rc<crate_metadata>,
 {
     let root_doc = rbml::Doc::new(cdata.data());
     let misc_info_doc = reader::get_doc(root_doc, tag_misc_info);

From c8cf3a307b94349cd4948a860d62730945e8d805 Mon Sep 17 00:00:00 2001
From: Jorge Aparicio <japaricious@gmail.com>
Date: Tue, 30 Dec 2014 22:49:26 -0500
Subject: [PATCH 22/23] rustc: replace `pick` alias with an unboxed closure

---
 src/librustc/metadata/filesearch.rs | 6 +-----
 1 file changed, 1 insertion(+), 5 deletions(-)

diff --git a/src/librustc/metadata/filesearch.rs b/src/librustc/metadata/filesearch.rs
index cc67f3ddf0330..82071931fe3a6 100644
--- a/src/librustc/metadata/filesearch.rs
+++ b/src/librustc/metadata/filesearch.rs
@@ -30,10 +30,6 @@ pub enum FileMatch {
 // FIXME (#2658): I'm not happy how this module turned out. Should
 // probably just be folded into cstore.
 
-/// Functions with type `pick` take a parent directory as well as
-/// a file found in that directory.
-pub type pick<'a> = |path: &Path|: 'a -> FileMatch;
-
 pub struct FileSearch<'a> {
     pub sysroot: &'a Path,
     pub search_paths: &'a SearchPaths,
@@ -95,7 +91,7 @@ impl<'a> FileSearch<'a> {
         make_target_lib_path(self.sysroot, self.triple)
     }
 
-    pub fn search(&self, pick: pick) {
+    pub fn search<F>(&self, mut pick: F) where F: FnMut(&Path) -> FileMatch {
         self.for_each_lib_search_path(|lib_search_path| {
             debug!("searching {}", lib_search_path.display());
             match fs::readdir(lib_search_path) {

From 10bbf69488b4863378e4acd9d55bde36b4a20909 Mon Sep 17 00:00:00 2001
From: Jorge Aparicio <japaricious@gmail.com>
Date: Tue, 30 Dec 2014 22:51:00 -0500
Subject: [PATCH 23/23] rustc_trans: replace `EnterPatterns` alias with an
 unboxed closure

---
 src/librustc_trans/trans/_match.rs | 18 +++++++++---------
 1 file changed, 9 insertions(+), 9 deletions(-)

diff --git a/src/librustc_trans/trans/_match.rs b/src/librustc_trans/trans/_match.rs
index 6e6b1c3406190..fc68d1d3258e1 100644
--- a/src/librustc_trans/trans/_match.rs
+++ b/src/librustc_trans/trans/_match.rs
@@ -410,15 +410,15 @@ fn expand_nested_bindings<'a, 'p, 'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
     }).collect()
 }
 
-type EnterPatterns<'a, 'p> = |&[&'p ast::Pat]|: 'a -> Option<Vec<&'p ast::Pat>>;
-
-fn enter_match<'a, 'b, 'p, 'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
-                                       dm: &DefMap,
-                                       m: &[Match<'a, 'p, 'blk, 'tcx>],
-                                       col: uint,
-                                       val: ValueRef,
-                                       e: EnterPatterns<'b, 'p>)
-                                       -> Vec<Match<'a, 'p, 'blk, 'tcx>> {
+fn enter_match<'a, 'b, 'p, 'blk, 'tcx, F>(bcx: Block<'blk, 'tcx>,
+                                          dm: &DefMap,
+                                          m: &[Match<'a, 'p, 'blk, 'tcx>],
+                                          col: uint,
+                                          val: ValueRef,
+                                          mut e: F)
+                                          -> Vec<Match<'a, 'p, 'blk, 'tcx>> where
+    F: FnMut(&[&'p ast::Pat]) -> Option<Vec<&'p ast::Pat>>,
+{
     debug!("enter_match(bcx={}, m={}, col={}, val={})",
            bcx.to_str(),
            m.repr(bcx.tcx()),