From 56ecb51ba62b973e3a415cc0d6d6979dd7aeee7d Mon Sep 17 00:00:00 2001
From: Jorge Aparicio <japaricious@gmail.com>
Date: Wed, 19 Nov 2014 18:06:41 -0500
Subject: [PATCH 01/92] libcore: use unboxed closures in `Option` methods

---
 src/libcore/option.rs | 16 ++++++++--------
 1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/src/libcore/option.rs b/src/libcore/option.rs
index 5e2d6266f0ec3..7be47f73e9ee7 100644
--- a/src/libcore/option.rs
+++ b/src/libcore/option.rs
@@ -156,7 +156,7 @@ use result::Result::{Ok, Err};
 use slice;
 use slice::AsSlice;
 use clone::Clone;
-use ops::Deref;
+use ops::{Deref, FnOnce};
 
 // Note that this is not a lang item per se, but it has a hidden dependency on
 // `Iterator`, which is one. The compiler assumes that the `next` method of
@@ -389,7 +389,7 @@ impl<T> Option<T> {
     /// ```
     #[inline]
     #[unstable = "waiting for conventions"]
-    pub fn unwrap_or_else(self, f: || -> T) -> T {
+    pub fn unwrap_or_else<F: FnOnce() -> T>(self, f: F) -> T {
         match self {
             Some(x) => x,
             None => f()
@@ -413,7 +413,7 @@ impl<T> Option<T> {
     /// ```
     #[inline]
     #[unstable = "waiting for unboxed closures"]
-    pub fn map<U>(self, f: |T| -> U) -> Option<U> {
+    pub fn map<U, F: FnOnce(T) -> U>(self, f: F) -> Option<U> {
         match self {
             Some(x) => Some(f(x)),
             None => None
@@ -433,7 +433,7 @@ impl<T> Option<T> {
     /// ```
     #[inline]
     #[unstable = "waiting for unboxed closures"]
-    pub fn map_or<U>(self, def: U, f: |T| -> U) -> U {
+    pub fn map_or<U, F: FnOnce(T) -> U>(self, def: U, f: F) -> U {
         match self {
             Some(t) => f(t),
             None => def
@@ -455,7 +455,7 @@ impl<T> Option<T> {
     /// ```
     #[inline]
     #[unstable = "waiting for unboxed closures"]
-    pub fn map_or_else<U>(self, def: || -> U, f: |T| -> U) -> U {
+    pub fn map_or_else<U, D: FnOnce() -> U, F: FnOnce(T) -> U>(self, def: D, f: F) -> U {
         match self {
             Some(t) => f(t),
             None => def()
@@ -497,7 +497,7 @@ impl<T> Option<T> {
     /// ```
     #[inline]
     #[experimental]
-    pub fn ok_or_else<E>(self, err: || -> E) -> Result<T, E> {
+    pub fn ok_or_else<E, F: FnOnce() -> E>(self, err: F) -> Result<T, E> {
         match self {
             Some(v) => Ok(v),
             None => Err(err()),
@@ -615,7 +615,7 @@ impl<T> Option<T> {
     /// ```
     #[inline]
     #[unstable = "waiting for unboxed closures"]
-    pub fn and_then<U>(self, f: |T| -> Option<U>) -> Option<U> {
+    pub fn and_then<U, F: FnOnce(T) -> Option<U>>(self, f: F) -> Option<U> {
         match self {
             Some(x) => f(x),
             None => None,
@@ -667,7 +667,7 @@ impl<T> Option<T> {
     /// ```
     #[inline]
     #[unstable = "waiting for unboxed closures"]
-    pub fn or_else(self, f: || -> Option<T>) -> Option<T> {
+    pub fn or_else<F: FnOnce() -> Option<T>>(self, f: F) -> Option<T> {
         match self {
             Some(_) => self,
             None => f()

From 60b0dd533b211ec434c7729f3952825a6386a329 Mon Sep 17 00:00:00 2001
From: Jorge Aparicio <japaricious@gmail.com>
Date: Mon, 1 Dec 2014 22:52:22 -0500
Subject: [PATCH 02/92] librustc_trans: fix fallout

---
 src/librustc_driver/pretty.rs | 8 +++-----
 1 file changed, 3 insertions(+), 5 deletions(-)

diff --git a/src/librustc_driver/pretty.rs b/src/librustc_driver/pretty.rs
index 971379b8dd296..c872f831649c8 100644
--- a/src/librustc_driver/pretty.rs
+++ b/src/librustc_driver/pretty.rs
@@ -78,7 +78,7 @@ pub fn parse_pretty(sess: &Session, name: &str) -> (PpMode, Option<UserIdentifie
                  or `expanded,identified`; got {}", name).as_slice());
         }
     };
-    let opt_second = opt_second.and_then::<UserIdentifiedItem>(from_str);
+    let opt_second = opt_second.and_then::<UserIdentifiedItem, _>(from_str);
     (first, opt_second)
 }
 
@@ -313,14 +313,12 @@ pub enum UserIdentifiedItem {
 
 impl FromStr for UserIdentifiedItem {
     fn from_str(s: &str) -> Option<UserIdentifiedItem> {
-        let extract_path_parts = || {
+        from_str(s).map(ItemViaNode).or_else(|| {
             let v : Vec<_> = s.split_str("::")
                 .map(|x|x.to_string())
                 .collect();
             Some(ItemViaPath(v))
-        };
-
-        from_str(s).map(ItemViaNode).or_else(extract_path_parts)
+        })
     }
 }
 

From 135c4ab5fe3c6f8befd379846988e7ca6234c116 Mon Sep 17 00:00:00 2001
From: Jorge Aparicio <japaricious@gmail.com>
Date: Tue, 2 Dec 2014 12:42:39 -0500
Subject: [PATCH 03/92] Fix compile fail tests

---
 src/test/compile-fail/coerce-unsafe-to-closure.rs | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/test/compile-fail/coerce-unsafe-to-closure.rs b/src/test/compile-fail/coerce-unsafe-to-closure.rs
index d9fbc08b3211d..fe7635f065cdc 100644
--- a/src/test/compile-fail/coerce-unsafe-to-closure.rs
+++ b/src/test/compile-fail/coerce-unsafe-to-closure.rs
@@ -10,5 +10,5 @@
 
 fn main() {
     let x: Option<&[u8]> = Some("foo").map(std::mem::transmute);
-    //~^ ERROR: mismatched types
+    //~^ ERROR: is not implemented for the type
 }

From 19524f1ed14d8da8b3d953812a3c3b461085d3dc Mon Sep 17 00:00:00 2001
From: Jorge Aparicio <japaricious@gmail.com>
Date: Tue, 2 Dec 2014 12:47:07 -0500
Subject: [PATCH 04/92] libcore: use unboxed closures in `Result` methods

---
 src/libcore/result.rs | 14 ++++++++------
 1 file changed, 8 insertions(+), 6 deletions(-)

diff --git a/src/libcore/result.rs b/src/libcore/result.rs
index 9d1ffa7891116..88d33a59b38bd 100644
--- a/src/libcore/result.rs
+++ b/src/libcore/result.rs
@@ -239,6 +239,7 @@ use slice::AsSlice;
 use iter::{Iterator, IteratorExt, DoubleEndedIterator, FromIterator, ExactSizeIterator};
 use option::Option;
 use option::Option::{None, Some};
+use ops::{FnMut, FnOnce};
 
 /// `Result` is a type that represents either success (`Ok`) or failure (`Err`).
 ///
@@ -466,7 +467,7 @@ impl<T, E> Result<T, E> {
     /// ```
     #[inline]
     #[unstable = "waiting for unboxed closures"]
-    pub fn map<U>(self, op: |T| -> U) -> Result<U,E> {
+    pub fn map<U, F: FnOnce(T) -> U>(self, op: F) -> Result<U,E> {
         match self {
           Ok(t) => Ok(op(t)),
           Err(e) => Err(e)
@@ -492,7 +493,7 @@ impl<T, E> Result<T, E> {
     /// ```
     #[inline]
     #[unstable = "waiting for unboxed closures"]
-    pub fn map_err<F>(self, op: |E| -> F) -> Result<T,F> {
+    pub fn map_err<F, O: FnOnce(E) -> F>(self, op: O) -> Result<T,F> {
         match self {
           Ok(t) => Ok(t),
           Err(e) => Err(op(e))
@@ -612,7 +613,7 @@ impl<T, E> Result<T, E> {
     /// ```
     #[inline]
     #[unstable = "waiting for unboxed closures"]
-    pub fn and_then<U>(self, op: |T| -> Result<U, E>) -> Result<U, E> {
+    pub fn and_then<U, F: FnOnce(T) -> Result<U, E>>(self, op: F) -> Result<U, E> {
         match self {
             Ok(t) => op(t),
             Err(e) => Err(e),
@@ -666,7 +667,7 @@ impl<T, E> Result<T, E> {
     /// ```
     #[inline]
     #[unstable = "waiting for unboxed closures"]
-    pub fn or_else<F>(self, op: |E| -> Result<T, F>) -> Result<T, F> {
+    pub fn or_else<F, O: FnOnce(E) -> Result<T, F>>(self, op: O) -> Result<T, F> {
         match self {
             Ok(t) => Ok(t),
             Err(e) => op(e),
@@ -708,7 +709,7 @@ impl<T, E> Result<T, E> {
     /// ```
     #[inline]
     #[unstable = "waiting for conventions"]
-    pub fn unwrap_or_else(self, op: |E| -> T) -> T {
+    pub fn unwrap_or_else<F: FnOnce(E) -> T>(self, op: F) -> T {
         match self {
             Ok(t) => t,
             Err(e) => op(e)
@@ -904,10 +905,11 @@ impl<A, E, V: FromIterator<A>> FromIterator<Result<A, E>> for Result<V, E> {
 pub fn fold<T,
             V,
             E,
+            F: FnMut(V, T) -> V,
             Iter: Iterator<Result<T, E>>>(
             mut iterator: Iter,
             mut init: V,
-            f: |V, T| -> V)
+            mut f: F)
             -> Result<V, E> {
     for t in iterator {
         match t {

From 1646d10edc57ec82536d6253f866084beb69a73e Mon Sep 17 00:00:00 2001
From: Jorge Aparicio <japaricious@gmail.com>
Date: Tue, 2 Dec 2014 13:59:08 -0500
Subject: [PATCH 05/92] libcore: use unboxed closures in the fields of `Map`

---
 src/libcore/iter.rs | 29 +++++++++++++++++++----------
 src/libcore/str.rs  | 16 +++++++++-------
 2 files changed, 28 insertions(+), 17 deletions(-)

diff --git a/src/libcore/iter.rs b/src/libcore/iter.rs
index ddca9d36bed7e..0c0562a8b68d6 100644
--- a/src/libcore/iter.rs
+++ b/src/libcore/iter.rs
@@ -62,7 +62,7 @@ use cmp::Ord;
 use kinds::Copy;
 use mem;
 use num::{ToPrimitive, Int};
-use ops::{Add, Deref};
+use ops::{Add, Deref, FnMut};
 use option::Option;
 use option::Option::{Some, None};
 use uint;
@@ -165,7 +165,7 @@ pub trait IteratorExt<A>: Iterator<A> {
     /// ```
     #[inline]
     #[unstable = "waiting for unboxed closures"]
-    fn map<'r, B>(self, f: |A|: 'r -> B) -> Map<'r, A, B, Self> {
+    fn map<B, F: FnMut(A) -> B>(self, f: F) -> Map<A, B, Self, F> {
         Map{iter: self, f: f}
     }
 
@@ -778,7 +778,10 @@ impl<'a, A, T: ExactSizeIterator<A>> ExactSizeIterator<A> for Inspect<'a, A, T>
 #[unstable = "trait is unstable"]
 impl<A, T: ExactSizeIterator<A>> ExactSizeIterator<A> for Rev<T> {}
 #[unstable = "trait is unstable"]
-impl<'a, A, B, T: ExactSizeIterator<A>> ExactSizeIterator<B> for Map<'a, A, B, T> {}
+impl<A, B, I, F> ExactSizeIterator<B> for Map<A, B, I, F> where
+    I: ExactSizeIterator<A>,
+    F: FnMut(A) -> B,
+{}
 #[unstable = "trait is unstable"]
 impl<A, B, T, U> ExactSizeIterator<(A, B)> for Zip<T, U>
     where T: ExactSizeIterator<A>, U: ExactSizeIterator<B> {}
@@ -1374,12 +1377,12 @@ RandomAccessIterator<(A, B)> for Zip<T, U> {
 /// An iterator which maps the values of `iter` with `f`
 #[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
 #[stable]
-pub struct Map<'a, A, B, T> {
-    iter: T,
-    f: |A|: 'a -> B
+pub struct Map<A, B, I: Iterator<A>, F: FnMut(A) -> B> {
+    iter: I,
+    f: F,
 }
 
-impl<'a, A, B, T> Map<'a, A, B, T> {
+impl<A, B, I, F> Map<A, B, I, F> where I: Iterator<A>, F: FnMut(A) -> B {
     #[inline]
     fn do_map(&mut self, elt: Option<A>) -> Option<B> {
         match elt {
@@ -1390,7 +1393,7 @@ impl<'a, A, B, T> Map<'a, A, B, T> {
 }
 
 #[unstable = "trait is unstable"]
-impl<'a, A, B, T: Iterator<A>> Iterator<B> for Map<'a, A, B, T> {
+impl<A, B, I, F> Iterator<B> for Map<A, B, I, F> where I: Iterator<A>, F: FnMut(A) -> B {
     #[inline]
     fn next(&mut self) -> Option<B> {
         let next = self.iter.next();
@@ -1404,7 +1407,10 @@ impl<'a, A, B, T: Iterator<A>> Iterator<B> for Map<'a, A, B, T> {
 }
 
 #[unstable = "trait is unstable"]
-impl<'a, A, B, T: DoubleEndedIterator<A>> DoubleEndedIterator<B> for Map<'a, A, B, T> {
+impl<A, B, I, F> DoubleEndedIterator<B> for Map<A, B, I, F> where
+    I: DoubleEndedIterator<A>,
+    F: FnMut(A) -> B,
+{
     #[inline]
     fn next_back(&mut self) -> Option<B> {
         let next = self.iter.next_back();
@@ -1413,7 +1419,10 @@ impl<'a, A, B, T: DoubleEndedIterator<A>> DoubleEndedIterator<B> for Map<'a, A,
 }
 
 #[experimental = "trait is experimental"]
-impl<'a, A, B, T: RandomAccessIterator<A>> RandomAccessIterator<B> for Map<'a, A, B, T> {
+impl<A, B, I, F> RandomAccessIterator<B> for Map<A, B, I, F> where
+    I: RandomAccessIterator<A>,
+    F: FnMut(A) -> B,
+{
     #[inline]
     fn indexable(&self) -> uint {
         self.iter.indexable()
diff --git a/src/libcore/str.rs b/src/libcore/str.rs
index d0c8558b55d07..051c36a2dc0b9 100644
--- a/src/libcore/str.rs
+++ b/src/libcore/str.rs
@@ -323,8 +323,7 @@ impl<'a> DoubleEndedIterator<(uint, char)> for CharOffsets<'a> {
 
 /// External iterator for a string's bytes.
 /// Use with the `std::iter` module.
-pub type Bytes<'a> =
-    Map<'a, &'a u8, u8, slice::Items<'a, u8>>;
+pub type Bytes<'a> = Map<&'a u8, u8, slice::Items<'a, u8>, fn(&u8) -> u8>;
 
 /// An iterator over the substrings of a string, separated by `sep`.
 #[deriving(Clone)]
@@ -349,8 +348,7 @@ pub struct CharSplitsN<'a, Sep> {
 }
 
 /// An iterator over the lines of a string, separated by either `\n` or (`\r\n`).
-pub type AnyLines<'a> =
-    Map<'a, &'a str, &'a str, CharSplits<'a, char>>;
+pub type AnyLines<'a> = Map<&'a str, &'a str, CharSplits<'a, char>, fn(&str) -> &str>;
 
 impl<'a, Sep> CharSplits<'a, Sep> {
     #[inline]
@@ -1980,7 +1978,9 @@ impl StrPrelude for str {
 
     #[inline]
     fn bytes(&self) -> Bytes {
-        self.as_bytes().iter().map(|&b| b)
+        fn deref(&x: &u8) -> u8 { x }
+
+        self.as_bytes().iter().map(deref)
     }
 
     #[inline]
@@ -2053,11 +2053,13 @@ impl StrPrelude for str {
     }
 
     fn lines_any(&self) -> AnyLines {
-        self.lines().map(|line| {
+        fn f(line: &str) -> &str {
             let l = line.len();
             if l > 0 && line.as_bytes()[l - 1] == b'\r' { line.slice(0, l - 1) }
             else { line }
-        })
+        }
+
+        self.lines().map(f)
     }
 
     #[inline]

From f91d87e6a03f4e64034ee8fa073ac8d47e71dc88 Mon Sep 17 00:00:00 2001
From: Jorge Aparicio <japaricious@gmail.com>
Date: Tue, 2 Dec 2014 14:07:40 -0500
Subject: [PATCH 06/92] libcollections: fix fallout

---
 src/libcollections/btree/map.rs | 14 ++++++++++----
 src/libcollections/btree/set.rs |  7 +++++--
 src/libcollections/tree/map.rs  | 12 ++++++++----
 src/libcollections/tree/set.rs  |  6 ++++--
 src/libcollections/trie/map.rs  | 13 ++++++++-----
 src/libcollections/vec_map.rs   | 13 ++++++++-----
 6 files changed, 43 insertions(+), 22 deletions(-)

diff --git a/src/libcollections/btree/map.rs b/src/libcollections/btree/map.rs
index 3d5067d5a516b..e49a8ddbe5ab8 100644
--- a/src/libcollections/btree/map.rs
+++ b/src/libcollections/btree/map.rs
@@ -107,10 +107,12 @@ pub struct MoveEntries<K, V> {
 }
 
 /// An iterator over a BTreeMap's keys.
-pub type Keys<'a, K, V> = iter::Map<'static, (&'a K, &'a V), &'a K, Entries<'a, K, V>>;
+pub type Keys<'a, K, V> =
+    iter::Map<(&'a K, &'a V), &'a K, Entries<'a, K, V>, fn((&'a K, &'a V)) -> &'a K>;
 
 /// An iterator over a BTreeMap's values.
-pub type Values<'a, K, V> = iter::Map<'static, (&'a K, &'a V), &'a V, Entries<'a, K, V>>;
+pub type Values<'a, K, V> =
+    iter::Map<(&'a K, &'a V), &'a V, Entries<'a, K, V>, fn((&'a K, &'a V)) -> &'a V>;
 
 /// A view into a single entry in a map, which may either be vacant or occupied.
 pub enum Entry<'a, K:'a, V:'a> {
@@ -1207,7 +1209,9 @@ impl<K, V> BTreeMap<K, V> {
     /// ```
     #[unstable = "matches collection reform specification, waiting for dust to settle"]
     pub fn keys<'a>(&'a self) -> Keys<'a, K, V> {
-        self.iter().map(|(k, _)| k)
+        fn first<A, B>((a, _): (A, B)) -> A { a }
+
+        self.iter().map(first)
     }
 
     /// Gets an iterator over the values of the map.
@@ -1226,7 +1230,9 @@ impl<K, V> BTreeMap<K, V> {
     /// ```
     #[unstable = "matches collection reform specification, waiting for dust to settle"]
     pub fn values<'a>(&'a self) -> Values<'a, K, V> {
-        self.iter().map(|(_, v)| v)
+        fn second<A, B>((_, b): (A, B)) -> B { b }
+
+        self.iter().map(second)
     }
 
     /// Return the number of elements in the map.
diff --git a/src/libcollections/btree/set.rs b/src/libcollections/btree/set.rs
index 0fbc319f4ff64..4289d42977b48 100644
--- a/src/libcollections/btree/set.rs
+++ b/src/libcollections/btree/set.rs
@@ -36,7 +36,8 @@ pub struct BTreeSet<T>{
 pub type Items<'a, T> = Keys<'a, T, ()>;
 
 /// An owning iterator over a BTreeSet's items.
-pub type MoveItems<T> = iter::Map<'static, (T, ()), T, MoveEntries<T, ()>>;
+pub type MoveItems<T> =
+    iter::Map<(T, ()), T, MoveEntries<T, ()>, fn((T, ())) -> T>;
 
 /// A lazy iterator producing elements in the set difference (in-order).
 pub struct DifferenceItems<'a, T:'a> {
@@ -87,7 +88,9 @@ impl<T> BTreeSet<T> {
     /// Gets an iterator for moving out the BtreeSet's contents.
     #[unstable = "matches collection reform specification, waiting for dust to settle"]
     pub fn into_iter(self) -> MoveItems<T> {
-        self.map.into_iter().map(|(k, _)| k)
+        fn first<A, B>((a, _): (A, B)) -> A { a }
+
+        self.map.into_iter().map(first)
     }
 }
 
diff --git a/src/libcollections/tree/map.rs b/src/libcollections/tree/map.rs
index 24395ca64939c..95fddb6ee1141 100644
--- a/src/libcollections/tree/map.rs
+++ b/src/libcollections/tree/map.rs
@@ -234,7 +234,9 @@ impl<K: Ord, V> TreeMap<K, V> {
     /// ```
     #[unstable = "matches collection reform specification, waiting for dust to settle"]
     pub fn keys<'a>(&'a self) -> Keys<'a, K, V> {
-        self.iter().map(|(k, _v)| k)
+        fn first<A, B>((a, _): (A, B)) -> A { a }
+
+        self.iter().map(first)
     }
 
     /// Gets a lazy iterator over the values in the map, in ascending order
@@ -256,7 +258,9 @@ impl<K: Ord, V> TreeMap<K, V> {
     /// ```
     #[unstable = "matches collection reform specification, waiting for dust to settle"]
     pub fn values<'a>(&'a self) -> Values<'a, K, V> {
-        self.iter().map(|(_k, v)| v)
+        fn second<A, B>((_, b): (A, B)) -> B { b }
+
+        self.iter().map(second)
     }
 
     /// Gets a lazy iterator over the key-value pairs in the map, in ascending order.
@@ -863,11 +867,11 @@ pub struct RevMutEntries<'a, K:'a, V:'a> {
 
 /// TreeMap keys iterator.
 pub type Keys<'a, K, V> =
-    iter::Map<'static, (&'a K, &'a V), &'a K, Entries<'a, K, V>>;
+    iter::Map<(&'a K, &'a V), &'a K, Entries<'a, K, V>, fn((&'a K, &'a V)) -> &'a K>;
 
 /// TreeMap values iterator.
 pub type Values<'a, K, V> =
-    iter::Map<'static, (&'a K, &'a V), &'a V, Entries<'a, K, V>>;
+    iter::Map<(&'a K, &'a V), &'a V, Entries<'a, K, V>, fn((&'a K, &'a V)) -> &'a V>;
 
 
 // FIXME #5846 we want to be able to choose between &x and &mut x
diff --git a/src/libcollections/tree/set.rs b/src/libcollections/tree/set.rs
index 3af2f3e0193a5..cee32619c8101 100644
--- a/src/libcollections/tree/set.rs
+++ b/src/libcollections/tree/set.rs
@@ -205,7 +205,9 @@ impl<T: Ord> TreeSet<T> {
     #[inline]
     #[unstable = "matches collection reform specification, waiting for dust to settle"]
     pub fn into_iter(self) -> MoveSetItems<T> {
-        self.map.into_iter().map(|(value, _)| value)
+        fn first<A, B>((a, _): (A, B)) -> A { a }
+
+        self.map.into_iter().map(first)
     }
 
     /// Gets a lazy iterator pointing to the first value not less than `v` (greater or equal).
@@ -560,7 +562,7 @@ pub struct RevSetItems<'a, T:'a> {
 }
 
 /// A lazy forward iterator over a set that consumes the set while iterating.
-pub type MoveSetItems<T> = iter::Map<'static, (T, ()), T, MoveEntries<T, ()>>;
+pub type MoveSetItems<T> = iter::Map<(T, ()), T, MoveEntries<T, ()>, fn((T, ())) -> T>;
 
 /// A lazy iterator producing elements in the set difference (in-order).
 pub struct DifferenceItems<'a, T:'a> {
diff --git a/src/libcollections/trie/map.rs b/src/libcollections/trie/map.rs
index 1b087d2e63dd5..a4dee8076487d 100644
--- a/src/libcollections/trie/map.rs
+++ b/src/libcollections/trie/map.rs
@@ -197,14 +197,18 @@ impl<T> TrieMap<T> {
     /// The iterator's element type is `uint`.
     #[unstable = "matches collection reform specification, waiting for dust to settle"]
     pub fn keys<'r>(&'r self) -> Keys<'r, T> {
-        self.iter().map(|(k, _v)| k)
+        fn first<A, B>((a, _): (A, B)) -> A { a }
+
+        self.iter().map(first)
     }
 
     /// Gets an iterator visiting all values in ascending order by the keys.
     /// The iterator's element type is `&'r T`.
     #[unstable = "matches collection reform specification, waiting for dust to settle"]
     pub fn values<'r>(&'r self) -> Values<'r, T> {
-        self.iter().map(|(_k, v)| v)
+        fn second<A, B>((_, b): (A, B)) -> B { b }
+
+        self.iter().map(second)
     }
 
     /// Gets an iterator over the key-value pairs in the map, ordered by keys.
@@ -1091,12 +1095,11 @@ pub struct MutEntries<'a, T:'a> {
 }
 
 /// A forward iterator over the keys of a map.
-pub type Keys<'a, T> =
-    iter::Map<'static, (uint, &'a T), uint, Entries<'a, T>>;
+pub type Keys<'a, T> = iter::Map<(uint, &'a T), uint, Entries<'a, T>, fn((uint, &'a T)) -> uint>;
 
 /// A forward iterator over the values of a map.
 pub type Values<'a, T> =
-    iter::Map<'static, (uint, &'a T), &'a T, Entries<'a, T>>;
+    iter::Map<(uint, &'a T), &'a T, Entries<'a, T>, fn((uint, &'a T)) -> &'a T>;
 
 // FIXME #5846: see `addr!` above.
 macro_rules! item { ($i:item) => {$i}}
diff --git a/src/libcollections/vec_map.rs b/src/libcollections/vec_map.rs
index 3b8c690e04749..9356c769d2662 100644
--- a/src/libcollections/vec_map.rs
+++ b/src/libcollections/vec_map.rs
@@ -141,14 +141,18 @@ impl<V> VecMap<V> {
     /// The iterator's element type is `uint`.
     #[unstable = "matches collection reform specification, waiting for dust to settle"]
     pub fn keys<'r>(&'r self) -> Keys<'r, V> {
-        self.iter().map(|(k, _v)| k)
+        fn first<A, B>((a, _): (A, B)) -> A { a }
+
+        self.iter().map(first)
     }
 
     /// Returns an iterator visiting all values in ascending order by the keys.
     /// The iterator's element type is `&'r V`.
     #[unstable = "matches collection reform specification, waiting for dust to settle"]
     pub fn values<'r>(&'r self) -> Values<'r, V> {
-        self.iter().map(|(_k, v)| v)
+        fn second<A, B>((_, b): (A, B)) -> B { b }
+
+        self.iter().map(second)
     }
 
     /// Returns an iterator visiting all key-value pairs in ascending order by the keys.
@@ -620,12 +624,11 @@ iterator!(impl MutEntries -> (uint, &'a mut V), as_mut)
 double_ended_iterator!(impl MutEntries -> (uint, &'a mut V), as_mut)
 
 /// Forward iterator over the keys of a map
-pub type Keys<'a, V> =
-    iter::Map<'static, (uint, &'a V), uint, Entries<'a, V>>;
+pub type Keys<'a, V> = iter::Map<(uint, &'a V), uint, Entries<'a, V>, fn((uint, &'a V)) -> uint>;
 
 /// Forward iterator over the values of a map
 pub type Values<'a, V> =
-    iter::Map<'static, (uint, &'a V), &'a V, Entries<'a, V>>;
+    iter::Map<(uint, &'a V), &'a V, Entries<'a, V>, fn((uint, &'a V)) -> &'a V>;
 
 /// Iterator over the key-value pairs of a map, the iterator consumes the map
 pub type MoveItems<V> =

From 0fcd73037358b5f39276cf48f600299c44c7ccec Mon Sep 17 00:00:00 2001
From: Jorge Aparicio <japaricious@gmail.com>
Date: Tue, 2 Dec 2014 14:24:40 -0500
Subject: [PATCH 07/92] librustrt: fix fallout

---
 src/librustrt/lib.rs  | 1 +
 src/librustrt/task.rs | 7 ++++---
 2 files changed, 5 insertions(+), 3 deletions(-)

diff --git a/src/librustrt/lib.rs b/src/librustrt/lib.rs
index 066e8c51aef0b..c2ee91d6acca2 100644
--- a/src/librustrt/lib.rs
+++ b/src/librustrt/lib.rs
@@ -19,6 +19,7 @@
 #![feature(macro_rules, phase, globs, thread_local, asm)]
 #![feature(linkage, lang_items, unsafe_destructor, default_type_params)]
 #![feature(import_shadowing, slicing_syntax)]
+#![feature(unboxed_closures)]
 #![no_std]
 #![experimental]
 
diff --git a/src/librustrt/task.rs b/src/librustrt/task.rs
index 325bdc284acfc..7e657d3aef391 100644
--- a/src/librustrt/task.rs
+++ b/src/librustrt/task.rs
@@ -22,6 +22,7 @@ use core::atomic::{AtomicUint, SeqCst};
 use core::iter::{IteratorExt, Take};
 use core::kinds::marker;
 use core::mem;
+use core::ops::FnMut;
 use core::prelude::{Clone, Drop, Err, Iterator, None, Ok, Option, Send, Some};
 use core::prelude::{drop};
 
@@ -297,9 +298,9 @@ impl Task {
     // `awoken` field which indicates whether we were actually woken up via some
     // invocation of `reawaken`. This flag is only ever accessed inside the
     // lock, so there's no need to make it atomic.
-    pub fn deschedule(mut self: Box<Task>,
-                      times: uint,
-                      f: |BlockedTask| -> ::core::result::Result<(), BlockedTask>) {
+    pub fn deschedule<F>(mut self: Box<Task>, times: uint, mut f: F) where
+        F: FnMut(BlockedTask) -> ::core::result::Result<(), BlockedTask>,
+    {
         unsafe {
             let me = &mut *self as *mut Task;
             let task = BlockedTask::block(self);

From d22acb77b219f1abe7265ea3a6d88017523a2d7e Mon Sep 17 00:00:00 2001
From: Jorge Aparicio <japaricious@gmail.com>
Date: Tue, 2 Dec 2014 14:28:35 -0500
Subject: [PATCH 08/92] libstd: fix fallout

---
 src/libstd/collections/hash/map.rs | 23 +++++++++++++++++------
 src/libstd/collections/hash/set.rs |  9 +++++----
 src/libstd/path/posix.rs           |  4 ++--
 src/libstd/path/windows.rs         |  8 ++++----
 4 files changed, 28 insertions(+), 16 deletions(-)

diff --git a/src/libstd/collections/hash/map.rs b/src/libstd/collections/hash/map.rs
index a8dce232d26d5..97e0518a072cd 100644
--- a/src/libstd/collections/hash/map.rs
+++ b/src/libstd/collections/hash/map.rs
@@ -852,7 +852,9 @@ impl<K: Eq + Hash<S>, V, S, H: Hasher<S>> HashMap<K, V, H> {
     /// ```
     #[unstable = "matches collection reform specification, waiting for dust to settle"]
     pub fn keys(&self) -> Keys<K, V> {
-        self.iter().map(|(k, _v)| k)
+        fn first<A, B>((a, _): (A, B)) -> A { a }
+
+        self.iter().map(first)
     }
 
     /// An iterator visiting all values in arbitrary order.
@@ -874,7 +876,9 @@ impl<K: Eq + Hash<S>, V, S, H: Hasher<S>> HashMap<K, V, H> {
     /// ```
     #[unstable = "matches collection reform specification, waiting for dust to settle"]
     pub fn values(&self) -> Values<K, V> {
-        self.iter().map(|(_k, v)| v)
+        fn second<A, B>((_, b): (A, B)) -> B { b }
+
+        self.iter().map(second)
     }
 
     /// An iterator visiting all key-value pairs in arbitrary order.
@@ -946,8 +950,10 @@ impl<K: Eq + Hash<S>, V, S, H: Hasher<S>> HashMap<K, V, H> {
     /// ```
     #[unstable = "matches collection reform specification, waiting for dust to settle"]
     pub fn into_iter(self) -> MoveEntries<K, V> {
+        fn last_two<A, B, C>((_, b, c): (A, B, C)) -> (B, C) { (b, c) }
+
         MoveEntries {
-            inner: self.table.into_iter().map(|(_, k, v)| (k, v))
+            inner: self.table.into_iter().map(last_two)
         }
     }
 
@@ -1316,7 +1322,12 @@ pub struct MutEntries<'a, K: 'a, V: 'a> {
 
 /// HashMap move iterator
 pub struct MoveEntries<K, V> {
-    inner: iter::Map<'static, (SafeHash, K, V), (K, V), table::MoveEntries<K, V>>
+    inner: iter::Map<
+        (SafeHash, K, V),
+        (K, V),
+        table::MoveEntries<K, V>,
+        fn((SafeHash, K, V)) -> (K, V),
+    >
 }
 
 /// A view into a single occupied location in a HashMap
@@ -1434,11 +1445,11 @@ impl<'a, K, V> VacantEntry<'a, K, V> {
 
 /// HashMap keys iterator
 pub type Keys<'a, K, V> =
-    iter::Map<'static, (&'a K, &'a V), &'a K, Entries<'a, K, V>>;
+    iter::Map<(&'a K, &'a V), &'a K, Entries<'a, K, V>, fn((&'a K, &'a V)) -> &'a K>;
 
 /// HashMap values iterator
 pub type Values<'a, K, V> =
-    iter::Map<'static, (&'a K, &'a V), &'a V, Entries<'a, K, V>>;
+    iter::Map<(&'a K, &'a V), &'a V, Entries<'a, K, V>, fn((&'a K, &'a V)) -> &'a V>;
 
 impl<K: Eq + Hash<S>, V, S, H: Hasher<S> + Default> FromIterator<(K, V)> for HashMap<K, V, H> {
     fn from_iter<T: Iterator<(K, V)>>(iter: T) -> HashMap<K, V, H> {
diff --git a/src/libstd/collections/hash/set.rs b/src/libstd/collections/hash/set.rs
index b3ccfdbb47cce..5db7bd7fc48d8 100644
--- a/src/libstd/collections/hash/set.rs
+++ b/src/libstd/collections/hash/set.rs
@@ -277,7 +277,9 @@ impl<T: Eq + Hash<S>, S, H: Hasher<S>> HashSet<T, H> {
     /// ```
     #[unstable = "matches collection reform specification, waiting for dust to settle"]
     pub fn into_iter(self) -> SetMoveItems<T> {
-        self.map.into_iter().map(|(k, _)| k)
+        fn first<A, B>((a, _): (A, B)) -> A { a }
+
+        self.map.into_iter().map(first)
     }
 
     /// Visit the values representing the difference.
@@ -611,11 +613,10 @@ impl<T: Eq + Hash<S>, S, H: Hasher<S> + Default> Default for HashSet<T, H> {
 
 /// HashSet iterator
 pub type SetItems<'a, K> =
-    iter::Map<'static, (&'a K, &'a ()), &'a K, Entries<'a, K, ()>>;
+    iter::Map<(&'a K, &'a ()), &'a K, Entries<'a, K, ()>, fn((&'a K, &'a ())) -> &'a K>;
 
 /// HashSet move iterator
-pub type SetMoveItems<K> =
-    iter::Map<'static, (K, ()), K, MoveEntries<K, ()>>;
+pub type SetMoveItems<K> = iter::Map<(K, ()), K, MoveEntries<K, ()>, fn((K, ())) -> K>;
 
 // `Repeat` is used to feed the filter closure an explicit capture
 // of a reference to the other set
diff --git a/src/libstd/path/posix.rs b/src/libstd/path/posix.rs
index 470e1b4dbb7af..6cafedcad116d 100644
--- a/src/libstd/path/posix.rs
+++ b/src/libstd/path/posix.rs
@@ -32,8 +32,8 @@ use super::{BytesContainer, GenericPath, GenericPathUnsafe};
 pub type Components<'a> = Splits<'a, u8>;
 
 /// Iterator that yields successive components of a Path as Option<&str>
-pub type StrComponents<'a> = Map<'a, &'a [u8], Option<&'a str>,
-                                       Components<'a>>;
+pub type StrComponents<'a> =
+    Map<&'a [u8], Option<&'a str>, Components<'a>, fn(&[u8]) -> Option<&str>>;
 
 /// Represents a POSIX file path
 #[deriving(Clone)]
diff --git a/src/libstd/path/windows.rs b/src/libstd/path/windows.rs
index ea522536d22fd..c3242c9cead41 100644
--- a/src/libstd/path/windows.rs
+++ b/src/libstd/path/windows.rs
@@ -38,12 +38,12 @@ use super::{contains_nul, BytesContainer, GenericPath, GenericPathUnsafe};
 ///
 /// Each component is yielded as Option<&str> for compatibility with PosixPath, but
 /// every component in WindowsPath is guaranteed to be Some.
-pub type StrComponents<'a> = Map<'a, &'a str, Option<&'a str>,
-                                       CharSplits<'a, char>>;
+pub type StrComponents<'a> =
+    Map<&'a str, Option<&'a str>, CharSplits<'a, char>, fn(&'a str) -> Option<&'a str>>;
 
 /// Iterator that yields successive components of a Path as &[u8]
-pub type Components<'a> = Map<'a, Option<&'a str>, &'a [u8],
-                                    StrComponents<'a>>;
+pub type Components<'a> =
+    Map<Option<&'a str>, &'a [u8], StrComponents<'a>, fn(Option<&str>) -> &[u8]>;
 
 /// Represents a Windows path
 // Notes for Windows path impl:

From 5e7469cfe18583dbacfdd4a1db424068f8ae69a5 Mon Sep 17 00:00:00 2001
From: Jorge Aparicio <japaricious@gmail.com>
Date: Tue, 2 Dec 2014 14:46:01 -0500
Subject: [PATCH 09/92] libsyntax: fix fallout

---
 src/libsyntax/ext/deriving/clone.rs | 2 +-
 src/libsyntax/lib.rs                | 1 +
 src/libsyntax/owned_slice.rs        | 2 +-
 3 files changed, 3 insertions(+), 2 deletions(-)

diff --git a/src/libsyntax/ext/deriving/clone.rs b/src/libsyntax/ext/deriving/clone.rs
index fccc67bf22093..f6b8c00e7617f 100644
--- a/src/libsyntax/ext/deriving/clone.rs
+++ b/src/libsyntax/ext/deriving/clone.rs
@@ -60,7 +60,7 @@ fn cs_clone(
         cx.ident_of("Clone"),
         cx.ident_of("clone"),
     ];
-    let subcall = |field: &FieldInfo| {
+    let subcall = |&: field: &FieldInfo| {
         let args = vec![cx.expr_addr_of(field.span, field.self_.clone())];
 
         cx.expr_call_global(field.span, fn_path.clone(), args)
diff --git a/src/libsyntax/lib.rs b/src/libsyntax/lib.rs
index ea305642f6655..5d5b56d444f8e 100644
--- a/src/libsyntax/lib.rs
+++ b/src/libsyntax/lib.rs
@@ -25,6 +25,7 @@
 #![allow(unknown_features)]
 #![feature(macro_rules, globs, default_type_params, phase, slicing_syntax)]
 #![feature(quote, unsafe_destructor, import_shadowing)]
+#![feature(unboxed_closures)]
 
 extern crate arena;
 extern crate fmt_macros;
diff --git a/src/libsyntax/owned_slice.rs b/src/libsyntax/owned_slice.rs
index 43b428b5a1c41..8e418e46921ff 100644
--- a/src/libsyntax/owned_slice.rs
+++ b/src/libsyntax/owned_slice.rs
@@ -49,7 +49,7 @@ impl<T> OwnedSlice<T> {
         self.into_vec().into_iter()
     }
 
-    pub fn map<U>(&self, f: |&T| -> U) -> OwnedSlice<U> {
+    pub fn map<U, F: FnMut(&T) -> U>(&self, f: F) -> OwnedSlice<U> {
         self.iter().map(f).collect()
     }
 }

From fd06ef24bb6e91a60dab2d1199acb810ff2875b3 Mon Sep 17 00:00:00 2001
From: Jorge Aparicio <japaricious@gmail.com>
Date: Tue, 2 Dec 2014 14:56:00 -0500
Subject: [PATCH 10/92] librustc: fix fallout

---
 src/librustc/lib.rs               |  1 +
 src/librustc/middle/subst.rs      |  6 ++++--
 src/librustc/middle/traits/mod.rs | 12 ++++--------
 src/librustc/util/ppaux.rs        |  4 +++-
 4 files changed, 12 insertions(+), 11 deletions(-)

diff --git a/src/librustc/lib.rs b/src/librustc/lib.rs
index 51cb7e193ffb8..404c7edeb88d6 100644
--- a/src/librustc/lib.rs
+++ b/src/librustc/lib.rs
@@ -25,6 +25,7 @@
 #![feature(default_type_params, globs, import_shadowing, macro_rules, phase, quote)]
 #![feature(slicing_syntax, unsafe_destructor)]
 #![feature(rustc_diagnostic_macros)]
+#![feature(unboxed_closures)]
 
 extern crate arena;
 extern crate flate;
diff --git a/src/librustc/middle/subst.rs b/src/librustc/middle/subst.rs
index d3b1c2d2afc4d..04ecaf2f483f9 100644
--- a/src/librustc/middle/subst.rs
+++ b/src/librustc/middle/subst.rs
@@ -432,7 +432,7 @@ impl<T> VecPerParamSpace<T> {
         self.all_vecs(|v| v.is_empty())
     }
 
-    pub fn map<U>(&self, pred: |&T| -> U) -> VecPerParamSpace<U> {
+    pub fn map<U, P>(&self, pred: P) -> VecPerParamSpace<U> where P: FnMut(&T) -> U {
         let result = self.iter().map(pred).collect();
         VecPerParamSpace::new_internal(result,
                                        self.type_limit,
@@ -440,7 +440,9 @@ impl<T> VecPerParamSpace<T> {
                                        self.assoc_limit)
     }
 
-    pub fn map_enumerated<U>(&self, pred: |(ParamSpace, uint, &T)| -> U) -> VecPerParamSpace<U> {
+    pub fn map_enumerated<U, P>(&self, pred: P) -> VecPerParamSpace<U> where
+        P: FnMut((ParamSpace, uint, &T)) -> U,
+    {
         let result = self.iter_enumerated().map(pred).collect();
         VecPerParamSpace::new_internal(result,
                                        self.type_limit,
diff --git a/src/librustc/middle/traits/mod.rs b/src/librustc/middle/traits/mod.rs
index 604a0607c0b4c..52d3315398209 100644
--- a/src/librustc/middle/traits/mod.rs
+++ b/src/librustc/middle/traits/mod.rs
@@ -312,7 +312,7 @@ impl<'tcx, N> Vtable<'tcx, N> {
         }
     }
 
-    pub fn map_nested<M>(&self, op: |&N| -> M) -> Vtable<'tcx, M> {
+    pub fn map_nested<M, F>(&self, op: F) -> Vtable<'tcx, M> where F: FnMut(&N) -> M {
         match *self {
             VtableImpl(ref i) => VtableImpl(i.map_nested(op)),
             VtableFnPointer(ref sig) => VtableFnPointer((*sig).clone()),
@@ -338,9 +338,8 @@ impl<'tcx, N> VtableImplData<'tcx, N> {
         self.nested.iter()
     }
 
-    pub fn map_nested<M>(&self,
-                         op: |&N| -> M)
-                         -> VtableImplData<'tcx, M>
+    pub fn map_nested<M, F>(&self, op: F) -> VtableImplData<'tcx, M> where
+        F: FnMut(&N) -> M,
     {
         VtableImplData {
             impl_def_id: self.impl_def_id,
@@ -365,10 +364,7 @@ impl<N> VtableBuiltinData<N> {
         self.nested.iter()
     }
 
-    pub fn map_nested<M>(&self,
-                         op: |&N| -> M)
-                         -> VtableBuiltinData<M>
-    {
+    pub fn map_nested<M, F>(&self, op: F) -> VtableBuiltinData<M> where F: FnMut(&N) -> M {
         VtableBuiltinData {
             nested: self.nested.map(op)
         }
diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs
index 7a14ed9cca8c9..5dbf3208595ed 100644
--- a/src/librustc/util/ppaux.rs
+++ b/src/librustc/util/ppaux.rs
@@ -241,7 +241,9 @@ pub fn trait_store_to_string(cx: &ctxt, s: ty::TraitStore) -> String {
     }
 }
 
-pub fn vec_map_to_string<T>(ts: &[T], f: |t: &T| -> String) -> String {
+pub fn vec_map_to_string<T, F>(ts: &[T], f: F) -> String where
+    F: FnMut(&T) -> String,
+{
     let tstrs = ts.iter().map(f).collect::<Vec<String>>();
     format!("[{}]", tstrs.connect(", "))
 }

From 44b419b82084e1dc1abd8f8cb4b603fe1c43483c Mon Sep 17 00:00:00 2001
From: Jorge Aparicio <japaricious@gmail.com>
Date: Tue, 2 Dec 2014 15:17:55 -0500
Subject: [PATCH 11/92] librustc_trans: fix fallout

---
 src/librustc_trans/trans/basic_block.rs | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/src/librustc_trans/trans/basic_block.rs b/src/librustc_trans/trans/basic_block.rs
index b55c268d9a909..1bd29038fdf69 100644
--- a/src/librustc_trans/trans/basic_block.rs
+++ b/src/librustc_trans/trans/basic_block.rs
@@ -17,7 +17,7 @@ pub struct BasicBlock(pub BasicBlockRef);
 
 impl Copy for BasicBlock {}
 
-pub type Preds<'a> = Map<'a, Value, BasicBlock, Filter<'a, Value, Users>>;
+pub type Preds<'a> = Map<Value, BasicBlock, Filter<'a, Value, Users>, fn(Value) -> BasicBlock>;
 
 /// Wrapper for LLVM BasicBlockRef
 impl BasicBlock {
@@ -32,9 +32,11 @@ impl BasicBlock {
     }
 
     pub fn pred_iter(self) -> Preds<'static> {
+        fn get_parent(user: Value) -> BasicBlock { user.get_parent().unwrap() }
+
         self.as_value().user_iter()
             .filter(|user| user.is_a_terminator_inst())
-            .map(|user| user.get_parent().unwrap())
+            .map(get_parent)
     }
 
     pub fn get_single_predecessor(self) -> Option<BasicBlock> {

From 801ae1333c05ab641ff08c14fee776c08f42cff8 Mon Sep 17 00:00:00 2001
From: Jorge Aparicio <japaricious@gmail.com>
Date: Tue, 2 Dec 2014 17:49:42 -0500
Subject: [PATCH 12/92] libcore: use unboxed closures in the fields of `Filter`

---
 src/libcore/iter.rs | 15 +++++++++------
 1 file changed, 9 insertions(+), 6 deletions(-)

diff --git a/src/libcore/iter.rs b/src/libcore/iter.rs
index 0c0562a8b68d6..490f4e68bcc9d 100644
--- a/src/libcore/iter.rs
+++ b/src/libcore/iter.rs
@@ -183,7 +183,7 @@ pub trait IteratorExt<A>: Iterator<A> {
     /// ```
     #[inline]
     #[unstable = "waiting for unboxed closures"]
-    fn filter<'r>(self, predicate: |&A|: 'r -> bool) -> Filter<'r, A, Self> {
+    fn filter<P>(self, predicate: P) -> Filter<A, Self, P> where P: FnMut(&A) -> bool {
         Filter{iter: self, predicate: predicate}
     }
 
@@ -1438,13 +1438,13 @@ impl<A, B, I, F> RandomAccessIterator<B> for Map<A, B, I, F> where
 /// An iterator which filters the elements of `iter` with `predicate`
 #[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
 #[stable]
-pub struct Filter<'a, A, T> {
-    iter: T,
-    predicate: |&A|: 'a -> bool
+pub struct Filter<A, I, P> where I: Iterator<A>, P: FnMut(&A) -> bool {
+    iter: I,
+    predicate: P,
 }
 
 #[unstable = "trait is unstable"]
-impl<'a, A, T: Iterator<A>> Iterator<A> for Filter<'a, A, T> {
+impl<A, I, P> Iterator<A> for Filter<A, I, P> where I: Iterator<A>, P: FnMut(&A) -> bool {
     #[inline]
     fn next(&mut self) -> Option<A> {
         for x in self.iter {
@@ -1465,7 +1465,10 @@ impl<'a, A, T: Iterator<A>> Iterator<A> for Filter<'a, A, T> {
 }
 
 #[unstable = "trait is unstable"]
-impl<'a, A, T: DoubleEndedIterator<A>> DoubleEndedIterator<A> for Filter<'a, A, T> {
+impl<A, I, P> DoubleEndedIterator<A> for Filter<A, I, P> where
+    I: DoubleEndedIterator<A>,
+    P: FnMut(&A) -> bool,
+{
     #[inline]
     fn next_back(&mut self) -> Option<A> {
         for x in self.iter.by_ref().rev() {

From e66ba157643420c6a46f07c68e9b817a66a64b4f Mon Sep 17 00:00:00 2001
From: Jorge Aparicio <japaricious@gmail.com>
Date: Tue, 2 Dec 2014 17:53:02 -0500
Subject: [PATCH 13/92] libunicode: fix fallout

---
 src/libunicode/u_str.rs | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/src/libunicode/u_str.rs b/src/libunicode/u_str.rs
index f3aaad549c9aa..33e4df3ca3687 100644
--- a/src/libunicode/u_str.rs
+++ b/src/libunicode/u_str.rs
@@ -29,8 +29,7 @@ use tables::grapheme::GraphemeCat;
 
 /// An iterator over the words of a string, separated by a sequence of whitespace
 /// FIXME: This should be opaque
-pub type Words<'a> =
-    Filter<'a, &'a str, CharSplits<'a, |char|:'a -> bool>>;
+pub type Words<'a> = Filter<&'a str, CharSplits<'a, |char|:'a -> bool>, fn(&&str) -> bool>;
 
 /// Methods for Unicode string slices
 pub trait UnicodeStrPrelude for Sized? {
@@ -143,8 +142,9 @@ impl UnicodeStrPrelude for str {
 
     #[inline]
     fn words(&self) -> Words {
+        fn is_not_empty(s: &&str) -> bool { !s.is_empty() }
         let f = |c: char| c.is_whitespace();
-        self.split(f).filter(|s| !s.is_empty())
+        self.split(f).filter(is_not_empty)
     }
 
     #[inline]

From 80a04b1aed74a6f6dc23c3bca6b869b28825f3c6 Mon Sep 17 00:00:00 2001
From: Jorge Aparicio <japaricious@gmail.com>
Date: Tue, 2 Dec 2014 18:03:12 -0500
Subject: [PATCH 14/92] librustc_trans: fix fallout

---
 src/librustc_trans/lib.rs               |  1 +
 src/librustc_trans/trans/_match.rs      |  2 +-
 src/librustc_trans/trans/basic_block.rs | 12 +++++++++---
 3 files changed, 11 insertions(+), 4 deletions(-)

diff --git a/src/librustc_trans/lib.rs b/src/librustc_trans/lib.rs
index 2421b39b8bb15..05b1a86b72b05 100644
--- a/src/librustc_trans/lib.rs
+++ b/src/librustc_trans/lib.rs
@@ -25,6 +25,7 @@
 #![feature(default_type_params, globs, import_shadowing, macro_rules, phase, quote)]
 #![feature(slicing_syntax, unsafe_destructor)]
 #![feature(rustc_diagnostic_macros)]
+#![feature(unboxed_closures)]
 
 extern crate arena;
 extern crate flate;
diff --git a/src/librustc_trans/trans/_match.rs b/src/librustc_trans/trans/_match.rs
index 1ed06938e95c8..7a7a708fcc509 100644
--- a/src/librustc_trans/trans/_match.rs
+++ b/src/librustc_trans/trans/_match.rs
@@ -771,7 +771,7 @@ fn pick_column_to_specialize(def_map: &DefMap, m: &[Match]) -> Option<uint> {
         }
     };
 
-    let column_contains_any_nonwild_patterns: |&uint| -> bool = |&col| {
+    let column_contains_any_nonwild_patterns = |&: &col: &uint| -> bool {
         m.iter().any(|row| match row.pats[col].node {
             ast::PatWild(_) => false,
             _ => true
diff --git a/src/librustc_trans/trans/basic_block.rs b/src/librustc_trans/trans/basic_block.rs
index 1bd29038fdf69..dca106a3897fb 100644
--- a/src/librustc_trans/trans/basic_block.rs
+++ b/src/librustc_trans/trans/basic_block.rs
@@ -17,7 +17,12 @@ pub struct BasicBlock(pub BasicBlockRef);
 
 impl Copy for BasicBlock {}
 
-pub type Preds<'a> = Map<Value, BasicBlock, Filter<'a, Value, Users>, fn(Value) -> BasicBlock>;
+pub type Preds = Map<
+    Value,
+    BasicBlock,
+    Filter<Value, Users, fn(&Value) -> bool>,
+    fn(Value) -> BasicBlock,
+>;
 
 /// Wrapper for LLVM BasicBlockRef
 impl BasicBlock {
@@ -31,11 +36,12 @@ impl BasicBlock {
         }
     }
 
-    pub fn pred_iter(self) -> Preds<'static> {
+    pub fn pred_iter(self) -> Preds {
+        fn is_a_terminator_inst(user: &Value) -> bool { user.is_a_terminator_inst() }
         fn get_parent(user: Value) -> BasicBlock { user.get_parent().unwrap() }
 
         self.as_value().user_iter()
-            .filter(|user| user.is_a_terminator_inst())
+            .filter(is_a_terminator_inst)
             .map(get_parent)
     }
 

From eede5d2bce06cd0546864b279389ec48e8ad7917 Mon Sep 17 00:00:00 2001
From: Jorge Aparicio <japaricious@gmail.com>
Date: Tue, 2 Dec 2014 21:00:07 -0500
Subject: [PATCH 15/92] libcore: use unboxed closures in the fields of
 `FilterMap`

---
 src/libcore/iter.rs | 19 ++++++++++++-------
 1 file changed, 12 insertions(+), 7 deletions(-)

diff --git a/src/libcore/iter.rs b/src/libcore/iter.rs
index 490f4e68bcc9d..b356e42907bcb 100644
--- a/src/libcore/iter.rs
+++ b/src/libcore/iter.rs
@@ -201,7 +201,7 @@ pub trait IteratorExt<A>: Iterator<A> {
     /// ```
     #[inline]
     #[unstable = "waiting for unboxed closures"]
-    fn filter_map<'r, B>(self, f: |A|: 'r -> Option<B>) -> FilterMap<'r, A, B, Self> {
+    fn filter_map<B, F>(self, f: F) -> FilterMap<A, B, Self, F> where F: FnMut(A) -> Option<B> {
         FilterMap { iter: self, f: f }
     }
 
@@ -1483,13 +1483,16 @@ impl<A, I, P> DoubleEndedIterator<A> for Filter<A, I, P> where
 /// An iterator which uses `f` to both filter and map elements from `iter`
 #[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
 #[stable]
-pub struct FilterMap<'a, A, B, T> {
-    iter: T,
-    f: |A|: 'a -> Option<B>
+pub struct FilterMap<A, B, I, F> where I: Iterator<A>, F: FnMut(A) -> Option<B> {
+    iter: I,
+    f: F,
 }
 
 #[unstable = "trait is unstable"]
-impl<'a, A, B, T: Iterator<A>> Iterator<B> for FilterMap<'a, A, B, T> {
+impl<A, B, I, F> Iterator<B> for FilterMap<A, B, I, F> where
+    I: Iterator<A>,
+    F: FnMut(A) -> Option<B>,
+{
     #[inline]
     fn next(&mut self) -> Option<B> {
         for x in self.iter {
@@ -1509,8 +1512,10 @@ impl<'a, A, B, T: Iterator<A>> Iterator<B> for FilterMap<'a, A, B, T> {
 }
 
 #[unstable = "trait is unstable"]
-impl<'a, A, B, T: DoubleEndedIterator<A>> DoubleEndedIterator<B>
-for FilterMap<'a, A, B, T> {
+impl<A, B, I, F> DoubleEndedIterator<B> for FilterMap<A, B, I, F> where
+    I: DoubleEndedIterator<A>,
+    F: FnMut(A) -> Option<B>,
+{
     #[inline]
     fn next_back(&mut self) -> Option<B> {
         for x in self.iter.by_ref().rev() {

From 4f6f6af281b47a95576b648ac924d79835f16db2 Mon Sep 17 00:00:00 2001
From: Jorge Aparicio <japaricious@gmail.com>
Date: Tue, 2 Dec 2014 21:05:30 -0500
Subject: [PATCH 16/92] libcollections: fix fallout

---
 src/libcollections/vec_map.rs | 15 ++++++++++-----
 1 file changed, 10 insertions(+), 5 deletions(-)

diff --git a/src/libcollections/vec_map.rs b/src/libcollections/vec_map.rs
index 9356c769d2662..ce5817e8d9e1a 100644
--- a/src/libcollections/vec_map.rs
+++ b/src/libcollections/vec_map.rs
@@ -234,10 +234,12 @@ impl<V> VecMap<V> {
     /// ```
     #[unstable = "matches collection reform specification, waiting for dust to settle"]
     pub fn into_iter(&mut self) -> MoveItems<V> {
-        let values = replace(&mut self.v, vec!());
-        values.into_iter().enumerate().filter_map(|(i, v)| {
+        fn filter<A>((i, v): (uint, Option<A>)) -> Option<(uint, A)> {
             v.map(|v| (i, v))
-        })
+        }
+
+        let values = replace(&mut self.v, vec!());
+        values.into_iter().enumerate().filter_map(filter)
     }
 
     /// Return the number of elements in the map.
@@ -631,8 +633,11 @@ pub type Values<'a, V> =
     iter::Map<(uint, &'a V), &'a V, Entries<'a, V>, fn((uint, &'a V)) -> &'a V>;
 
 /// Iterator over the key-value pairs of a map, the iterator consumes the map
-pub type MoveItems<V> =
-    FilterMap<'static, (uint, Option<V>), (uint, V), Enumerate<vec::MoveItems<Option<V>>>>;
+pub type MoveItems<V> = FilterMap<
+    (uint, Option<V>),
+    (uint, V),
+    Enumerate<vec::MoveItems<Option<V>>>,
+    fn((uint, Option<V>)) -> Option<(uint, V)>>;
 
 #[cfg(test)]
 mod test_map {

From c3fe7105ba4362bce7f795f4502163bcec039d74 Mon Sep 17 00:00:00 2001
From: Jorge Aparicio <japaricious@gmail.com>
Date: Tue, 2 Dec 2014 21:19:24 -0500
Subject: [PATCH 17/92] libstd: fix fallout

---
 src/libstd/collections/hash/set.rs | 36 ++++++++++++++++++------------
 1 file changed, 22 insertions(+), 14 deletions(-)

diff --git a/src/libstd/collections/hash/set.rs b/src/libstd/collections/hash/set.rs
index 5db7bd7fc48d8..745a8298ee8a5 100644
--- a/src/libstd/collections/hash/set.rs
+++ b/src/libstd/collections/hash/set.rs
@@ -19,7 +19,7 @@ use fmt;
 use hash::{Hash, Hasher, RandomSipHasher};
 use iter::{Iterator, IteratorExt, FromIterator, FilterMap, Chain, Repeat, Zip, Extend, repeat};
 use iter;
-use option::Option::{Some, None};
+use option::Option::{Some, None, mod};
 use result::Result::{Ok, Err};
 
 use super::map::{HashMap, Entries, MoveEntries, INITIAL_CAPACITY};
@@ -306,10 +306,13 @@ impl<T: Eq + Hash<S>, S, H: Hasher<S>> HashSet<T, H> {
     /// ```
     #[unstable = "matches collection reform specification, waiting for dust to settle"]
     pub fn difference<'a>(&'a self, other: &'a HashSet<T, H>) -> SetAlgebraItems<'a, T, H> {
-        repeat(other).zip(self.iter())
-            .filter_map(|(other, elt)| {
-                if !other.contains(elt) { Some(elt) } else { None }
-            })
+        fn filter<'a, T, S, H>((other, elt): (&HashSet<T, H>, &'a T)) -> Option<&'a T> where
+            T: Eq + Hash<S>, H: Hasher<S>
+        {
+            if !other.contains(elt) { Some(elt) } else { None }
+        }
+
+        repeat(other).zip(self.iter()).filter_map(filter)
     }
 
     /// Visit the values representing the symmetric difference.
@@ -356,12 +359,14 @@ impl<T: Eq + Hash<S>, S, H: Hasher<S>> HashSet<T, H> {
     /// assert_eq!(diff, [2i, 3].iter().map(|&x| x).collect());
     /// ```
     #[unstable = "matches collection reform specification, waiting for dust to settle"]
-    pub fn intersection<'a>(&'a self, other: &'a HashSet<T, H>)
-        -> SetAlgebraItems<'a, T, H> {
-        repeat(other).zip(self.iter())
-            .filter_map(|(other, elt)| {
-                if other.contains(elt) { Some(elt) } else { None }
-            })
+    pub fn intersection<'a>(&'a self, other: &'a HashSet<T, H>) -> SetAlgebraItems<'a, T, H> {
+        fn filter<'a, T, S, H>((other, elt): (&HashSet<T, H>, &'a T)) -> Option<&'a T> where
+            T: Eq + Hash<S>, H: Hasher<S>
+        {
+            if other.contains(elt) { Some(elt) } else { None }
+        }
+
+        repeat(other).zip(self.iter()).filter_map(filter)
     }
 
     /// Visit the values representing the union.
@@ -621,9 +626,12 @@ pub type SetMoveItems<K> = iter::Map<(K, ()), K, MoveEntries<K, ()>, fn((K, ()))
 // `Repeat` is used to feed the filter closure an explicit capture
 // of a reference to the other set
 /// Set operations iterator
-pub type SetAlgebraItems<'a, T, H> =
-    FilterMap<'static, (&'a HashSet<T, H>, &'a T), &'a T,
-              Zip<Repeat<&'a HashSet<T, H>>, SetItems<'a, T>>>;
+pub type SetAlgebraItems<'a, T, H> = FilterMap<
+    (&'a HashSet<T, H>, &'a T),
+    &'a T,
+    Zip<Repeat<&'a HashSet<T, H>>, SetItems<'a, T>>,
+    for<'b> fn((&HashSet<T, H>, &'b T)) -> Option<&'b T>,
+>;
 
 #[cfg(test)]
 mod test_set {

From ca001e1bd0accdfe285c50918d1d48730d124999 Mon Sep 17 00:00:00 2001
From: Jorge Aparicio <japaricious@gmail.com>
Date: Tue, 2 Dec 2014 22:29:24 -0500
Subject: [PATCH 18/92] librustdoc: fix fallout

---
 src/librustdoc/fold.rs | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/src/librustdoc/fold.rs b/src/librustdoc/fold.rs
index 173b50dfc5ff0..5623c0f0e535f 100644
--- a/src/librustdoc/fold.rs
+++ b/src/librustdoc/fold.rs
@@ -79,8 +79,7 @@ pub trait DocFolder {
                     StructVariant(mut j) => {
                         let mut foo = Vec::new(); swap(&mut foo, &mut j.fields);
                         let num_fields = foo.len();
-                        let c = |x| self.fold_item(x);
-                        j.fields.extend(foo.into_iter().filter_map(c));
+                        j.fields.extend(foo.into_iter().filter_map(|x| self.fold_item(x)));
                         j.fields_stripped |= num_fields != j.fields.len();
                         VariantItem(Variant {kind: StructVariant(j), ..i2})
                     },

From 0cfdc99c71f132f967cf968e5b2c9d20adf14b46 Mon Sep 17 00:00:00 2001
From: Jorge Aparicio <japaricious@gmail.com>
Date: Tue, 2 Dec 2014 23:28:32 -0500
Subject: [PATCH 19/92] libcore: use unboxed closures in the fields of
 `SkipWhile`

---
 src/libcore/iter.rs | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/src/libcore/iter.rs b/src/libcore/iter.rs
index b356e42907bcb..e1d944dcb2d09 100644
--- a/src/libcore/iter.rs
+++ b/src/libcore/iter.rs
@@ -264,7 +264,7 @@ pub trait IteratorExt<A>: Iterator<A> {
     /// ```
     #[inline]
     #[unstable = "waiting for unboxed closures"]
-    fn skip_while<'r>(self, predicate: |&A|: 'r -> bool) -> SkipWhile<'r, A, Self> {
+    fn skip_while<P>(self, predicate: P) -> SkipWhile<A, Self, P> where P: FnMut(&A) -> bool {
         SkipWhile{iter: self, flag: false, predicate: predicate}
     }
 
@@ -1645,14 +1645,14 @@ impl<'a, A, T: Iterator<A>> Peekable<A, T> {
 /// An iterator which rejects elements while `predicate` is true
 #[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
 #[stable]
-pub struct SkipWhile<'a, A, T> {
-    iter: T,
+pub struct SkipWhile<A, I, P> where I: Iterator<A>, P: FnMut(&A) -> bool {
+    iter: I,
     flag: bool,
-    predicate: |&A|: 'a -> bool
+    predicate: P,
 }
 
 #[unstable = "trait is unstable"]
-impl<'a, A, T: Iterator<A>> Iterator<A> for SkipWhile<'a, A, T> {
+impl<A, I, P> Iterator<A> for SkipWhile<A, I, P> where I: Iterator<A>, P: FnMut(&A) -> bool {
     #[inline]
     fn next(&mut self) -> Option<A> {
         for x in self.iter {

From e2724cb1d53b368e6a18571f345f08a0dd2644c9 Mon Sep 17 00:00:00 2001
From: Jorge Aparicio <japaricious@gmail.com>
Date: Wed, 3 Dec 2014 00:42:28 -0500
Subject: [PATCH 20/92] libcore: use unboxed closures in the fields of
 `TakeWhile`

---
 src/libcore/iter.rs | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/src/libcore/iter.rs b/src/libcore/iter.rs
index e1d944dcb2d09..c3ed1b7a9ad7b 100644
--- a/src/libcore/iter.rs
+++ b/src/libcore/iter.rs
@@ -283,7 +283,7 @@ pub trait IteratorExt<A>: Iterator<A> {
     /// ```
     #[inline]
     #[unstable = "waiting for unboxed closures, may want to require peek"]
-    fn take_while<'r>(self, predicate: |&A|: 'r -> bool) -> TakeWhile<'r, A, Self> {
+    fn take_while<P>(self, predicate: P) -> TakeWhile<A, Self, P> where P: FnMut(&A) -> bool {
         TakeWhile{iter: self, flag: false, predicate: predicate}
     }
 
@@ -1674,14 +1674,14 @@ impl<A, I, P> Iterator<A> for SkipWhile<A, I, P> where I: Iterator<A>, P: FnMut(
 /// An iterator which only accepts elements while `predicate` is true
 #[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
 #[stable]
-pub struct TakeWhile<'a, A, T> {
-    iter: T,
+pub struct TakeWhile<A, I, P> where I: Iterator<A>, P: FnMut(&A) -> bool {
+    iter: I,
     flag: bool,
-    predicate: |&A|: 'a -> bool
+    predicate: P,
 }
 
 #[unstable = "trait is unstable"]
-impl<'a, A, T: Iterator<A>> Iterator<A> for TakeWhile<'a, A, T> {
+impl<A, I, P> Iterator<A> for TakeWhile<A, I, P> where I: Iterator<A>, P: FnMut(&A) -> bool {
     #[inline]
     fn next(&mut self) -> Option<A> {
         if self.flag {

From ba480cbf75387236a364961354b466cbee69146d Mon Sep 17 00:00:00 2001
From: Jorge Aparicio <japaricious@gmail.com>
Date: Wed, 3 Dec 2014 01:59:31 -0500
Subject: [PATCH 21/92] libcore: use unboxed closures in the fields of `Scan`

---
 src/libcore/iter.rs | 16 ++++++++++------
 1 file changed, 10 insertions(+), 6 deletions(-)

diff --git a/src/libcore/iter.rs b/src/libcore/iter.rs
index c3ed1b7a9ad7b..8a28988c2cbc3 100644
--- a/src/libcore/iter.rs
+++ b/src/libcore/iter.rs
@@ -346,8 +346,9 @@ pub trait IteratorExt<A>: Iterator<A> {
     /// ```
     #[inline]
     #[unstable = "waiting for unboxed closures"]
-    fn scan<'r, St, B>(self, initial_state: St, f: |&mut St, A|: 'r -> Option<B>)
-        -> Scan<'r, A, B, Self, St> {
+    fn scan<St, B, F>(self, initial_state: St, f: F) -> Scan<A, B, Self, St, F> where
+        F: FnMut(&mut St, A) -> Option<B>,
+    {
         Scan{iter: self, f: f, state: initial_state}
     }
 
@@ -1833,16 +1834,19 @@ impl<A, T: RandomAccessIterator<A>> RandomAccessIterator<A> for Take<T> {
 /// An iterator to maintain state while iterating another iterator
 #[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
 #[unstable = "waiting for unboxed closures"]
-pub struct Scan<'a, A, B, T, St> {
-    iter: T,
-    f: |&mut St, A|: 'a -> Option<B>,
+pub struct Scan<A, B, I, St, F> where I: Iterator<A>, F: FnMut(&mut St, A) -> Option<B> {
+    iter: I,
+    f: F,
 
     /// The current internal state to be passed to the closure next.
     pub state: St,
 }
 
 #[unstable = "trait is unstable"]
-impl<'a, A, B, T: Iterator<A>, St> Iterator<B> for Scan<'a, A, B, T, St> {
+impl<A, B, I, St, F> Iterator<B> for Scan<A, B, I, St, F> where
+    I: Iterator<A>,
+    F: FnMut(&mut St, A) -> Option<B>,
+{
     #[inline]
     fn next(&mut self) -> Option<B> {
         self.iter.next().and_then(|a| (self.f)(&mut self.state, a))

From a051ba1dffa2648a9cd25d39f70fbb5089505762 Mon Sep 17 00:00:00 2001
From: Jorge Aparicio <japaricious@gmail.com>
Date: Wed, 3 Dec 2014 03:07:16 -0500
Subject: [PATCH 22/92] libcore: use unboxed closures in the fields of
 `FlatMap`

---
 src/libcore/iter.rs | 27 +++++++++++++++++----------
 1 file changed, 17 insertions(+), 10 deletions(-)

diff --git a/src/libcore/iter.rs b/src/libcore/iter.rs
index 8a28988c2cbc3..c0eae92949872 100644
--- a/src/libcore/iter.rs
+++ b/src/libcore/iter.rs
@@ -372,8 +372,10 @@ pub trait IteratorExt<A>: Iterator<A> {
     /// ```
     #[inline]
     #[unstable = "waiting for unboxed closures"]
-    fn flat_map<'r, B, U: Iterator<B>>(self, f: |A|: 'r -> U)
-        -> FlatMap<'r, A, Self, U> {
+    fn flat_map<B, U, F>(self, f: F) -> FlatMap<A, B, Self, U, F> where
+        U: Iterator<B>,
+        F: FnMut(A) -> U,
+    {
         FlatMap{iter: self, f: f, frontiter: None, backiter: None }
     }
 
@@ -1864,15 +1866,19 @@ impl<A, B, I, St, F> Iterator<B> for Scan<A, B, I, St, F> where
 ///
 #[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
 #[unstable = "waiting for unboxed closures"]
-pub struct FlatMap<'a, A, T, U> {
-    iter: T,
-    f: |A|: 'a -> U,
+pub struct FlatMap<A, B, I, U, F> where I: Iterator<A>, U: Iterator<B>, F: FnMut(A) -> U {
+    iter: I,
+    f: F,
     frontiter: Option<U>,
     backiter: Option<U>,
 }
 
 #[unstable = "trait is unstable"]
-impl<'a, A, T: Iterator<A>, B, U: Iterator<B>> Iterator<B> for FlatMap<'a, A, T, U> {
+impl<A, B, I, U, F> Iterator<B> for FlatMap<A, B, I, U, F> where
+    I: Iterator<A>,
+    U: Iterator<B>,
+    F: FnMut(A) -> U,
+{
     #[inline]
     fn next(&mut self) -> Option<B> {
         loop {
@@ -1901,10 +1907,11 @@ impl<'a, A, T: Iterator<A>, B, U: Iterator<B>> Iterator<B> for FlatMap<'a, A, T,
 }
 
 #[unstable = "trait is unstable"]
-impl<'a,
-     A, T: DoubleEndedIterator<A>,
-     B, U: DoubleEndedIterator<B>> DoubleEndedIterator<B>
-     for FlatMap<'a, A, T, U> {
+impl<A, B, I, U, F> DoubleEndedIterator<B> for FlatMap<A, B, I, U, F> where
+    I: DoubleEndedIterator<A>,
+    U: DoubleEndedIterator<B>,
+    F: FnMut(A) -> U,
+{
     #[inline]
     fn next_back(&mut self) -> Option<B> {
         loop {

From 7e3493e5e3a0cc7b4c99f36865305b241ff993d0 Mon Sep 17 00:00:00 2001
From: Jorge Aparicio <japaricious@gmail.com>
Date: Wed, 3 Dec 2014 04:04:27 -0500
Subject: [PATCH 23/92] libcore: use unboxed closures in the fields of
 `Inspect`

---
 src/libcore/iter.rs | 29 ++++++++++++++++++-----------
 1 file changed, 18 insertions(+), 11 deletions(-)

diff --git a/src/libcore/iter.rs b/src/libcore/iter.rs
index c0eae92949872..36b902dbee12e 100644
--- a/src/libcore/iter.rs
+++ b/src/libcore/iter.rs
@@ -432,7 +432,7 @@ pub trait IteratorExt<A>: Iterator<A> {
     /// ```
     #[inline]
     #[unstable = "waiting for unboxed closures"]
-    fn inspect<'r>(self, f: |&A|: 'r) -> Inspect<'r, A, Self> {
+    fn inspect<F>(self, f: F) -> Inspect<A, Self, F> where F: FnMut(&A) {
         Inspect{iter: self, f: f}
     }
 
@@ -777,7 +777,10 @@ pub trait ExactSizeIterator<A> : DoubleEndedIterator<A> {
 #[unstable = "trait is unstable"]
 impl<A, T: ExactSizeIterator<A>> ExactSizeIterator<(uint, A)> for Enumerate<T> {}
 #[unstable = "trait is unstable"]
-impl<'a, A, T: ExactSizeIterator<A>> ExactSizeIterator<A> for Inspect<'a, A, T> {}
+impl<A, I, F> ExactSizeIterator<A> for Inspect<A, I, F> where
+    I: ExactSizeIterator<A>,
+    F: FnMut(&A),
+{}
 #[unstable = "trait is unstable"]
 impl<A, T: ExactSizeIterator<A>> ExactSizeIterator<A> for Rev<T> {}
 #[unstable = "trait is unstable"]
@@ -2012,12 +2015,12 @@ impl<T> Fuse<T> {
 /// element before yielding it.
 #[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
 #[unstable = "waiting for unboxed closures"]
-pub struct Inspect<'a, A, T> {
-    iter: T,
-    f: |&A|: 'a
+pub struct Inspect<A, I, F> where I: Iterator<A>, F: FnMut(&A) {
+    iter: I,
+    f: F,
 }
 
-impl<'a, A, T> Inspect<'a, A, T> {
+impl<A, I, F> Inspect<A, I, F> where I: Iterator<A>, F: FnMut(&A) {
     #[inline]
     fn do_inspect(&mut self, elt: Option<A>) -> Option<A> {
         match elt {
@@ -2030,7 +2033,7 @@ impl<'a, A, T> Inspect<'a, A, T> {
 }
 
 #[unstable = "trait is unstable"]
-impl<'a, A, T: Iterator<A>> Iterator<A> for Inspect<'a, A, T> {
+impl<A, I, F> Iterator<A> for Inspect<A, I, F> where I: Iterator<A>, F: FnMut(&A) {
     #[inline]
     fn next(&mut self) -> Option<A> {
         let next = self.iter.next();
@@ -2044,8 +2047,10 @@ impl<'a, A, T: Iterator<A>> Iterator<A> for Inspect<'a, A, T> {
 }
 
 #[unstable = "trait is unstable"]
-impl<'a, A, T: DoubleEndedIterator<A>> DoubleEndedIterator<A>
-for Inspect<'a, A, T> {
+impl<A, I, F> DoubleEndedIterator<A> for Inspect<A, I, F> where
+    I: DoubleEndedIterator<A>,
+    F: FnMut(&A),
+{
     #[inline]
     fn next_back(&mut self) -> Option<A> {
         let next = self.iter.next_back();
@@ -2054,8 +2059,10 @@ for Inspect<'a, A, T> {
 }
 
 #[experimental = "trait is experimental"]
-impl<'a, A, T: RandomAccessIterator<A>> RandomAccessIterator<A>
-for Inspect<'a, A, T> {
+impl<A, I, F> RandomAccessIterator<A> for Inspect<A, I, F> where
+    I: RandomAccessIterator<A>,
+    F: FnMut(&A),
+{
     #[inline]
     fn indexable(&self) -> uint {
         self.iter.indexable()

From a50c587242903f5c3d69e3684c8a79d3dcd849b7 Mon Sep 17 00:00:00 2001
From: Jorge Aparicio <japaricious@gmail.com>
Date: Wed, 3 Dec 2014 10:09:53 -0500
Subject: [PATCH 24/92] libcoretest: fix fallout

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

diff --git a/src/libcoretest/iter.rs b/src/libcoretest/iter.rs
index d046faa82d405..acc2eab60e778 100644
--- a/src/libcoretest/iter.rs
+++ b/src/libcoretest/iter.rs
@@ -221,7 +221,7 @@ fn test_iterator_flat_map() {
 #[test]
 fn test_inspect() {
     let xs = [1u, 2, 3, 4];
-    let mut n = 0;
+    let mut n = 0u;
 
     let ys = xs.iter()
                .map(|&x| x)

From 216bcfd66b63a9f60e41e4b736145f62edda4150 Mon Sep 17 00:00:00 2001
From: Jorge Aparicio <japaricious@gmail.com>
Date: Wed, 3 Dec 2014 15:51:47 -0500
Subject: [PATCH 25/92] libcore: use unboxed closures in the fields of `Unfold`

---
 src/libcore/iter.rs | 29 ++++++++++++++++++-----------
 1 file changed, 18 insertions(+), 11 deletions(-)

diff --git a/src/libcore/iter.rs b/src/libcore/iter.rs
index 36b902dbee12e..51ae0f4702966 100644
--- a/src/libcore/iter.rs
+++ b/src/libcore/iter.rs
@@ -2108,19 +2108,18 @@ impl<A, I, F> RandomAccessIterator<A> for Inspect<A, I, F> where
 /// }
 /// ```
 #[experimental]
-pub struct Unfold<'a, A, St> {
-    f: |&mut St|: 'a -> Option<A>,
+pub struct Unfold<A, St, F> where F: FnMut(&mut St) -> Option<A> {
+    f: F,
     /// Internal state that will be passed to the closure on the next iteration
     pub state: St,
 }
 
 #[experimental]
-impl<'a, A, St> Unfold<'a, A, St> {
+impl<A, St, F> Unfold<A, St, F> where F: FnMut(&mut St) -> Option<A> {
     /// Creates a new iterator with the specified closure as the "iterator
     /// function" and an initial state to eventually pass to the closure
     #[inline]
-    pub fn new<'a>(initial_state: St, f: |&mut St|: 'a -> Option<A>)
-               -> Unfold<'a, A, St> {
+    pub fn new(initial_state: St, f: F) -> Unfold<A, St, F> {
         Unfold {
             f: f,
             state: initial_state
@@ -2129,7 +2128,7 @@ impl<'a, A, St> Unfold<'a, A, St> {
 }
 
 #[experimental]
-impl<'a, A, St> Iterator<A> for Unfold<'a, A, St> {
+impl<A, St, F> Iterator<A> for Unfold<A, St, F> where F: FnMut(&mut St) -> Option<A> {
     #[inline]
     fn next(&mut self) -> Option<A> {
         (self.f)(&mut self.state)
@@ -2456,18 +2455,24 @@ impl<A: Clone> RandomAccessIterator<A> for Repeat<A> {
     fn idx(&mut self, _: uint) -> Option<A> { Some(self.element.clone()) }
 }
 
-type IterateState<'a, T> = (|T|: 'a -> T, Option<T>, bool);
+type IterateState<T, F> = (F, Option<T>, bool);
 
 /// An iterator that repeatedly applies a given function, starting
 /// from a given seed value.
 #[experimental]
-pub type Iterate<'a, T> = Unfold<'a, T, IterateState<'a, T>>;
+pub type Iterate<T, F> = Unfold<T, IterateState<T, F>, fn(&mut IterateState<T, F>) -> Option<T>>;
 
 /// Create a new iterator that produces an infinite sequence of
 /// repeated applications of the given function `f`.
 #[experimental]
-pub fn iterate<'a, T: Clone>(seed: T, f: |T|: 'a -> T) -> Iterate<'a, T> {
-    Unfold::new((f, Some(seed), true), |st| {
+pub fn iterate<T, F>(seed: T, f: F) -> Iterate<T, F> where
+    T: Clone,
+    F: FnMut(T) -> T,
+{
+    fn next<T, F>(st: &mut IterateState<T, F>) -> Option<T> where
+        T: Clone,
+        F: FnMut(T) -> T,
+    {
         let &(ref mut f, ref mut val, ref mut first) = st;
         if *first {
             *first = false;
@@ -2480,7 +2485,9 @@ pub fn iterate<'a, T: Clone>(seed: T, f: |T|: 'a -> T) -> Iterate<'a, T> {
             }
         }
         val.clone()
-    })
+    }
+
+    Unfold::new((f, Some(seed), true), next)
 }
 
 /// Create a new iterator that endlessly repeats the element `elt`.

From 5e9ca5b25530ab58f9d0b09662884928b054f271 Mon Sep 17 00:00:00 2001
From: Jorge Aparicio <japaricious@gmail.com>
Date: Wed, 3 Dec 2014 19:43:25 -0500
Subject: [PATCH 26/92] libcore: use unboxed closures in `IteratorExt` methods

---
 src/libcore/iter.rs | 14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/src/libcore/iter.rs b/src/libcore/iter.rs
index 51ae0f4702966..e886dfadb47e7 100644
--- a/src/libcore/iter.rs
+++ b/src/libcore/iter.rs
@@ -521,7 +521,7 @@ pub trait IteratorExt<A>: Iterator<A> {
     /// ```
     #[inline]
     #[unstable = "waiting for unboxed closures, just changed to take self by value"]
-    fn fold<B>(mut self, init: B, f: |B, A| -> B) -> B {
+    fn fold<B, F>(mut self, init: B, mut f: F) -> B where F: FnMut(B, A) -> B {
         let mut accum = init;
         for x in self {
             accum = f(accum, x);
@@ -555,7 +555,7 @@ pub trait IteratorExt<A>: Iterator<A> {
     /// ```
     #[inline]
     #[unstable = "waiting for unboxed closures, just changed to take self by value"]
-    fn all(mut self, f: |A| -> bool) -> bool {
+    fn all<F>(mut self, mut f: F) -> bool where F: FnMut(A) -> bool {
         for x in self { if !f(x) { return false; } }
         true
     }
@@ -573,7 +573,7 @@ pub trait IteratorExt<A>: Iterator<A> {
     /// ```
     #[inline]
     #[unstable = "waiting for unboxed closures"]
-    fn any(&mut self, f: |A| -> bool) -> bool {
+    fn any<F>(&mut self, mut f: F) -> bool where F: FnMut(A) -> bool {
         for x in *self { if f(x) { return true; } }
         false
     }
@@ -583,7 +583,7 @@ pub trait IteratorExt<A>: Iterator<A> {
     /// Does not consume the iterator past the first found element.
     #[inline]
     #[unstable = "waiting for unboxed closures"]
-    fn find(&mut self, predicate: |&A| -> bool) -> Option<A> {
+    fn find<P>(&mut self, mut predicate: P) -> Option<A> where P: FnMut(&A) -> bool {
         for x in *self {
             if predicate(&x) { return Some(x) }
         }
@@ -593,7 +593,7 @@ pub trait IteratorExt<A>: Iterator<A> {
     /// Return the index of the first element satisfying the specified predicate
     #[inline]
     #[unstable = "waiting for unboxed closures"]
-    fn position(&mut self, predicate: |A| -> bool) -> Option<uint> {
+    fn position<P>(&mut self, mut predicate: P) -> Option<uint> where P: FnMut(A) -> bool {
         let mut i = 0;
         for x in *self {
             if predicate(x) {
@@ -617,7 +617,7 @@ pub trait IteratorExt<A>: Iterator<A> {
     /// ```
     #[inline]
     #[unstable = "waiting for unboxed closures, just changed to take self by value"]
-    fn max_by<B: Ord>(self, f: |&A| -> B) -> Option<A> {
+    fn max_by<B: Ord, F>(self, mut f: F) -> Option<A> where F: FnMut(&A) -> B {
         self.fold(None, |max: Option<(A, B)>, x| {
             let x_val = f(&x);
             match max {
@@ -644,7 +644,7 @@ pub trait IteratorExt<A>: Iterator<A> {
     /// ```
     #[inline]
     #[unstable = "waiting for unboxed closures, just changed to take self by value"]
-    fn min_by<B: Ord>(self, f: |&A| -> B) -> Option<A> {
+    fn min_by<B: Ord, F>(self, mut f: F) -> Option<A> where F: FnMut(&A) -> B {
         self.fold(None, |min: Option<(A, B)>, x| {
             let x_val = f(&x);
             match min {

From fee500d3124544ee6d9c59d9d9b15927172458d8 Mon Sep 17 00:00:00 2001
From: Jorge Aparicio <japaricious@gmail.com>
Date: Wed, 3 Dec 2014 19:46:51 -0500
Subject: [PATCH 27/92] libregex: fix fallout

---
 src/libregex/lib.rs   | 1 +
 src/libregex/parse.rs | 5 +++--
 2 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/src/libregex/lib.rs b/src/libregex/lib.rs
index b35c3879783a0..05f853a851ea7 100644
--- a/src/libregex/lib.rs
+++ b/src/libregex/lib.rs
@@ -370,6 +370,7 @@
 
 #![allow(unknown_features)]
 #![feature(macro_rules, phase, slicing_syntax, globs)]
+#![feature(unboxed_closures)]
 #![deny(missing_docs)]
 
 #[cfg(test)]
diff --git a/src/libregex/parse.rs b/src/libregex/parse.rs
index 55e533aadee7f..f7ea83a8a3835 100644
--- a/src/libregex/parse.rs
+++ b/src/libregex/parse.rs
@@ -838,8 +838,9 @@ impl<'a> Parser<'a> {
     // Otherwise, an error will be returned.
     // Generally, `allow_start` is only true when you're *not* expecting an
     // opening parenthesis.
-    fn pos_last(&self, allow_start: bool, pred: |&BuildAst| -> bool)
-               -> Result<uint, Error> {
+    fn pos_last<P>(&self, allow_start: bool, pred: P) -> Result<uint, Error> where
+        P: FnMut(&BuildAst) -> bool,
+   {
         let from = match self.stack.iter().rev().position(pred) {
             Some(i) => i,
             None => {

From 5a9047b9b3109be22c219519120881189ca6b61d Mon Sep 17 00:00:00 2001
From: Jorge Aparicio <japaricious@gmail.com>
Date: Wed, 3 Dec 2014 19:52:54 -0500
Subject: [PATCH 28/92] librustc: fix fallout

---
 src/librustc/middle/subst.rs | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/librustc/middle/subst.rs b/src/librustc/middle/subst.rs
index 04ecaf2f483f9..9791f8d2f5929 100644
--- a/src/librustc/middle/subst.rs
+++ b/src/librustc/middle/subst.rs
@@ -420,11 +420,11 @@ impl<T> VecPerParamSpace<T> {
         spaces.iter().all(|&space| { pred(self.get_slice(space)) })
     }
 
-    pub fn all(&self, pred: |&T| -> bool) -> bool {
+    pub fn all<P>(&self, pred: P) -> bool where P: FnMut(&T) -> bool {
         self.iter().all(pred)
     }
 
-    pub fn any(&self, pred: |&T| -> bool) -> bool {
+    pub fn any<P>(&self, pred: P) -> bool where P: FnMut(&T) -> bool {
         self.iter().any(pred)
     }
 

From 10a14d5f04e958918ae3cd3e3a2ef881e5dc0a6d Mon Sep 17 00:00:00 2001
From: Jorge Aparicio <japaricious@gmail.com>
Date: Wed, 3 Dec 2014 20:42:22 -0500
Subject: [PATCH 29/92] Fix run-pass tests

---
 src/test/run-pass/assignability-trait.rs | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/src/test/run-pass/assignability-trait.rs b/src/test/run-pass/assignability-trait.rs
index f822da4cdcfcf..f623b7911ce6d 100644
--- a/src/test/run-pass/assignability-trait.rs
+++ b/src/test/run-pass/assignability-trait.rs
@@ -12,19 +12,20 @@
 // making method calls, but only if there aren't any matches without
 // it.
 
+#![feature(unboxed_closures)]
 
 trait iterable<A> {
-    fn iterate(&self, blk: |x: &A| -> bool) -> bool;
+    fn iterate<F>(&self, blk: F) -> bool where F: FnMut(&A) -> bool;
 }
 
 impl<'a,A> iterable<A> for &'a [A] {
-    fn iterate(&self, f: |x: &A| -> bool) -> bool {
+    fn iterate<F>(&self, f: F) -> bool where F: FnMut(&A) -> bool {
         self.iter().all(f)
     }
 }
 
 impl<A> iterable<A> for Vec<A> {
-    fn iterate(&self, f: |x: &A| -> bool) -> bool {
+    fn iterate<F>(&self, f: F) -> bool where F: FnMut(&A) -> bool {
         self.iter().all(f)
     }
 }

From b3cd05642c98feccee93295a14efa933776cf3e6 Mon Sep 17 00:00:00 2001
From: Jorge Aparicio <japaricious@gmail.com>
Date: Wed, 3 Dec 2014 21:05:25 -0500
Subject: [PATCH 30/92] libcollections: fix unit tests

---
 src/libcollections/btree/set.rs | 27 ++++++++++++++++++---------
 src/libcollections/tree/set.rs  | 27 ++++++++++++++++++---------
 src/libcollections/trie/set.rs  | 27 ++++++++++++++++++---------
 3 files changed, 54 insertions(+), 27 deletions(-)

diff --git a/src/libcollections/btree/set.rs b/src/libcollections/btree/set.rs
index 4289d42977b48..cd01c008fe1bc 100644
--- a/src/libcollections/btree/set.rs
+++ b/src/libcollections/btree/set.rs
@@ -603,10 +603,23 @@ mod test {
       assert!(hash::hash(&x) == hash::hash(&y));
     }
 
-    fn check(a: &[int],
-             b: &[int],
-             expected: &[int],
-             f: |&BTreeSet<int>, &BTreeSet<int>, f: |&int| -> bool| -> bool) {
+    struct Counter<'a, 'b> {
+        i: &'a mut uint,
+        expected: &'b [int],
+    }
+
+    impl<'a, 'b> FnMut(&int) -> bool for Counter<'a, 'b> {
+        extern "rust-call" fn call_mut(&mut self, (&x,): (&int,)) -> bool {
+            assert_eq!(x, self.expected[*self.i]);
+            *self.i += 1;
+            true
+        }
+    }
+
+    fn check<F>(a: &[int], b: &[int], expected: &[int], f: F) where
+        // FIXME Replace Counter with `Box<FnMut(_) -> _>`
+        F: FnOnce(&BTreeSet<int>, &BTreeSet<int>, Counter) -> bool,
+    {
         let mut set_a = BTreeSet::new();
         let mut set_b = BTreeSet::new();
 
@@ -614,11 +627,7 @@ mod test {
         for y in b.iter() { assert!(set_b.insert(*y)) }
 
         let mut i = 0;
-        f(&set_a, &set_b, |x| {
-            assert_eq!(*x, expected[i]);
-            i += 1;
-            true
-        });
+        f(&set_a, &set_b, Counter { i: &mut i, expected: expected });
         assert_eq!(i, expected.len());
     }
 
diff --git a/src/libcollections/tree/set.rs b/src/libcollections/tree/set.rs
index cee32619c8101..bd8bf5c6cb67f 100644
--- a/src/libcollections/tree/set.rs
+++ b/src/libcollections/tree/set.rs
@@ -936,10 +936,23 @@ mod test {
       assert!(hash::hash(&x) == hash::hash(&y));
     }
 
-    fn check(a: &[int],
-             b: &[int],
-             expected: &[int],
-             f: |&TreeSet<int>, &TreeSet<int>, f: |&int| -> bool| -> bool) {
+    struct Counter<'a, 'b> {
+        i: &'a mut uint,
+        expected: &'b [int],
+    }
+
+    impl<'a, 'b> FnMut(&int) -> bool for Counter<'a, 'b> {
+        extern "rust-call" fn call_mut(&mut self, (&x,): (&int,)) -> bool {
+            assert_eq!(x, self.expected[*self.i]);
+            *self.i += 1;
+            true
+        }
+    }
+
+    fn check<F>(a: &[int], b: &[int], expected: &[int], f: F) where
+        // FIXME Replace `Counter` with `Box<FnMut(&int) -> bool>`
+        F: FnOnce(&TreeSet<int>, &TreeSet<int>, Counter) -> bool,
+    {
         let mut set_a = TreeSet::new();
         let mut set_b = TreeSet::new();
 
@@ -947,11 +960,7 @@ mod test {
         for y in b.iter() { assert!(set_b.insert(*y)) }
 
         let mut i = 0;
-        f(&set_a, &set_b, |x| {
-            assert_eq!(*x, expected[i]);
-            i += 1;
-            true
-        });
+        f(&set_a, &set_b, Counter { i: &mut i, expected: expected });
         assert_eq!(i, expected.len());
     }
 
diff --git a/src/libcollections/trie/set.rs b/src/libcollections/trie/set.rs
index 46052ff2f5080..5621726dc5682 100644
--- a/src/libcollections/trie/set.rs
+++ b/src/libcollections/trie/set.rs
@@ -743,10 +743,23 @@ mod test {
         assert!(a < b && a <= b);
     }
 
-    fn check(a: &[uint],
-             b: &[uint],
-             expected: &[uint],
-             f: |&TrieSet, &TrieSet, f: |uint| -> bool| -> bool) {
+    struct Counter<'a, 'b> {
+        i: &'a mut uint,
+        expected: &'b [uint],
+    }
+
+    impl<'a, 'b> FnMut(uint) -> bool for Counter<'a, 'b> {
+        extern "rust-call" fn call_mut(&mut self, (x,): (uint,)) -> bool {
+            assert_eq!(x, self.expected[*self.i]);
+            *self.i += 1;
+            true
+        }
+    }
+
+    fn check<F>(a: &[uint], b: &[uint], expected: &[uint], f: F) where
+        // FIXME Replace `Counter` with `Box<FnMut(&uint) -> bool>`
+        F: FnOnce(&TrieSet, &TrieSet, Counter) -> bool,
+    {
         let mut set_a = TrieSet::new();
         let mut set_b = TrieSet::new();
 
@@ -754,11 +767,7 @@ mod test {
         for y in b.iter() { assert!(set_b.insert(*y)) }
 
         let mut i = 0;
-        f(&set_a, &set_b, |x| {
-            assert_eq!(x, expected[i]);
-            i += 1;
-            true
-        });
+        f(&set_a, &set_b, Counter { i: &mut i, expected: expected });
         assert_eq!(i, expected.len());
     }
 

From aa921b61622a6dc08d5c70cb6a217b1f6d304aac Mon Sep 17 00:00:00 2001
From: Jorge Aparicio <japaricious@gmail.com>
Date: Thu, 4 Dec 2014 16:13:12 -0500
Subject: [PATCH 31/92] libcore: use unboxed closures in `ExactSizeIterator`
 methods

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

diff --git a/src/libcore/iter.rs b/src/libcore/iter.rs
index e886dfadb47e7..8ee2a8874bb03 100644
--- a/src/libcore/iter.rs
+++ b/src/libcore/iter.rs
@@ -749,7 +749,7 @@ pub trait ExactSizeIterator<A> : DoubleEndedIterator<A> {
     ///
     /// If no element matches, None is returned.
     #[inline]
-    fn rposition(&mut self, predicate: |A| -> bool) -> Option<uint> {
+    fn rposition<P>(&mut self, mut predicate: P) -> Option<uint> where P: FnMut(A) -> bool {
         let len = self.len();
         for i in range(0, len).rev() {
             if predicate(self.next_back().expect("rposition: incorrect ExactSizeIterator")) {

From d3f5c1397c5012ce9bb022c0320c958c9fdc1208 Mon Sep 17 00:00:00 2001
From: Jorge Aparicio <japaricious@gmail.com>
Date: Thu, 4 Dec 2014 16:17:07 -0500
Subject: [PATCH 32/92] libcore: impl CharEq for FnMut(char) -> bool
 implementors

---
 src/libcore/str.rs | 19 ++++++-------------
 1 file changed, 6 insertions(+), 13 deletions(-)

diff --git a/src/libcore/str.rs b/src/libcore/str.rs
index 051c36a2dc0b9..328a64acaf8b4 100644
--- a/src/libcore/str.rs
+++ b/src/libcore/str.rs
@@ -31,6 +31,7 @@ use mem;
 use num::Int;
 use option::Option;
 use option::Option::{None, Some};
+use ops::FnMut;
 use ptr::RawPtr;
 use raw::{Repr, Slice};
 use slice::{mod, SlicePrelude};
@@ -136,15 +137,7 @@ impl CharEq for char {
     fn only_ascii(&self) -> bool { (*self as uint) < 128 }
 }
 
-impl<'a> CharEq for |char|: 'a -> bool {
-    #[inline]
-    fn matches(&mut self, c: char) -> bool { (*self)(c) }
-
-    #[inline]
-    fn only_ascii(&self) -> bool { false }
-}
-
-impl CharEq for extern "Rust" fn(char) -> bool {
+impl<F> CharEq for F where F: FnMut(char) -> bool {
     #[inline]
     fn matches(&mut self, c: char) -> bool { (*self)(c) }
 
@@ -2142,11 +2135,11 @@ impl StrPrelude for str {
 
     #[inline]
     fn trim_chars<C: CharEq>(&self, mut to_trim: C) -> &str {
-        let cur = match self.find(|c: char| !to_trim.matches(c)) {
+        let cur = match self.find(|&mut: c: char| !to_trim.matches(c)) {
             None => "",
             Some(i) => unsafe { self.slice_unchecked(i, self.len()) }
         };
-        match cur.rfind(|c: char| !to_trim.matches(c)) {
+        match cur.rfind(|&mut: c: char| !to_trim.matches(c)) {
             None => "",
             Some(i) => {
                 let right = cur.char_range_at(i).next;
@@ -2157,7 +2150,7 @@ impl StrPrelude for str {
 
     #[inline]
     fn trim_left_chars<C: CharEq>(&self, mut to_trim: C) -> &str {
-        match self.find(|c: char| !to_trim.matches(c)) {
+        match self.find(|&mut: c: char| !to_trim.matches(c)) {
             None => "",
             Some(first) => unsafe { self.slice_unchecked(first, self.len()) }
         }
@@ -2165,7 +2158,7 @@ impl StrPrelude for str {
 
     #[inline]
     fn trim_right_chars<C: CharEq>(&self, mut to_trim: C) -> &str {
-        match self.rfind(|c: char| !to_trim.matches(c)) {
+        match self.rfind(|&mut: c: char| !to_trim.matches(c)) {
             None => "",
             Some(last) => {
                 let next = self.char_range_at(last).next;

From 50ef20725395dcaa3226ee1bfb3f186bb8a2a794 Mon Sep 17 00:00:00 2001
From: Jorge Aparicio <japaricious@gmail.com>
Date: Thu, 4 Dec 2014 17:25:18 -0500
Subject: [PATCH 33/92] libunicode: fix fallout

---
 src/libunicode/lib.rs   |  1 +
 src/libunicode/u_str.rs | 11 ++++++-----
 2 files changed, 7 insertions(+), 5 deletions(-)

diff --git a/src/libunicode/lib.rs b/src/libunicode/lib.rs
index 66cd22dfb08c2..1f75daa7bdecd 100644
--- a/src/libunicode/lib.rs
+++ b/src/libunicode/lib.rs
@@ -29,6 +29,7 @@
        html_playground_url = "http://play.rust-lang.org/")]
 #![no_std]
 #![feature(globs)]
+#![feature(unboxed_closures)]
 
 extern crate core;
 
diff --git a/src/libunicode/u_str.rs b/src/libunicode/u_str.rs
index 33e4df3ca3687..80311137b0165 100644
--- a/src/libunicode/u_str.rs
+++ b/src/libunicode/u_str.rs
@@ -29,7 +29,7 @@ use tables::grapheme::GraphemeCat;
 
 /// An iterator over the words of a string, separated by a sequence of whitespace
 /// FIXME: This should be opaque
-pub type Words<'a> = Filter<&'a str, CharSplits<'a, |char|:'a -> bool>, fn(&&str) -> bool>;
+pub type Words<'a> = Filter<&'a str, CharSplits<'a, fn(char) -> bool>, fn(&&str) -> bool>;
 
 /// Methods for Unicode string slices
 pub trait UnicodeStrPrelude for Sized? {
@@ -143,8 +143,9 @@ impl UnicodeStrPrelude for str {
     #[inline]
     fn words(&self) -> Words {
         fn is_not_empty(s: &&str) -> bool { !s.is_empty() }
-        let f = |c: char| c.is_whitespace();
-        self.split(f).filter(is_not_empty)
+        fn is_whitespace(c: char) -> bool { c.is_whitespace() }
+
+        self.split(is_whitespace).filter(is_not_empty)
     }
 
     #[inline]
@@ -165,12 +166,12 @@ impl UnicodeStrPrelude for str {
 
     #[inline]
     fn trim_left(&self) -> &str {
-        self.trim_left_chars(|c: char| c.is_whitespace())
+        self.trim_left_chars(|&: c: char| c.is_whitespace())
     }
 
     #[inline]
     fn trim_right(&self) -> &str {
-        self.trim_right_chars(|c: char| c.is_whitespace())
+        self.trim_right_chars(|&: c: char| c.is_whitespace())
     }
 }
 

From cc242bcf47f59e847436682def1e64ff481097e2 Mon Sep 17 00:00:00 2001
From: Jorge Aparicio <japaricious@gmail.com>
Date: Thu, 4 Dec 2014 17:29:41 -0500
Subject: [PATCH 34/92] libstd: fix fallout

---
 src/libstd/path/windows.rs | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/src/libstd/path/windows.rs b/src/libstd/path/windows.rs
index c3242c9cead41..e1b0d9b139542 100644
--- a/src/libstd/path/windows.rs
+++ b/src/libstd/path/windows.rs
@@ -1038,9 +1038,8 @@ fn parse_prefix<'a>(mut path: &'a str) -> Option<PathPrefix> {
     }
     return None;
 
-    fn parse_two_comps<'a>(mut path: &'a str, f: |char| -> bool)
-                       -> Option<(uint, uint)> {
-        let idx_a = match path.find(|x| f(x)) {
+    fn parse_two_comps(mut path: &str, f: fn(char) -> bool) -> Option<(uint, uint)> {
+        let idx_a = match path.find(f) {
             None => return None,
             Some(x) => x
         };

From 4d4915aa286ca12527ca849a076bf4e7b5d90de1 Mon Sep 17 00:00:00 2001
From: Jorge Aparicio <japaricious@gmail.com>
Date: Thu, 4 Dec 2014 17:58:50 -0500
Subject: [PATCH 35/92] librustdoc: fix fallout

---
 src/librustdoc/html/markdown.rs | 2 +-
 src/librustdoc/lib.rs           | 1 +
 2 files changed, 2 insertions(+), 1 deletion(-)

diff --git a/src/librustdoc/html/markdown.rs b/src/librustdoc/html/markdown.rs
index 10563c61e1465..cba58db7c7f73 100644
--- a/src/librustdoc/html/markdown.rs
+++ b/src/librustdoc/html/markdown.rs
@@ -393,7 +393,7 @@ impl LangString {
         let mut seen_other_tags = false;
         let mut data = LangString::all_false();
 
-        let mut tokens = string.split(|c: char|
+        let mut tokens = string.split(|&: c: char|
             !(c == '_' || c == '-' || c.is_alphanumeric())
         );
 
diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs
index 8062916285496..6da7ec40f3472 100644
--- a/src/librustdoc/lib.rs
+++ b/src/librustdoc/lib.rs
@@ -19,6 +19,7 @@
 
 #![allow(unknown_features)]
 #![feature(globs, macro_rules, phase, slicing_syntax)]
+#![feature(unboxed_closures)]
 
 extern crate arena;
 extern crate getopts;

From 646083510ab82fa48091c942a2a4015bed8c15dc Mon Sep 17 00:00:00 2001
From: Jorge Aparicio <japaricious@gmail.com>
Date: Thu, 4 Dec 2014 19:03:07 -0500
Subject: [PATCH 36/92] libcollections: fix fallout in unit tests

---
 src/libcollections/str.rs | 24 ++++++++++++------------
 1 file changed, 12 insertions(+), 12 deletions(-)

diff --git a/src/libcollections/str.rs b/src/libcollections/str.rs
index 2e96b941c08e0..bf568fd92d565 100644
--- a/src/libcollections/str.rs
+++ b/src/libcollections/str.rs
@@ -903,21 +903,21 @@ mod tests {
     #[test]
     fn test_find() {
         assert_eq!("hello".find('l'), Some(2u));
-        assert_eq!("hello".find(|c:char| c == 'o'), Some(4u));
+        assert_eq!("hello".find(|&: c:char| c == 'o'), Some(4u));
         assert!("hello".find('x').is_none());
-        assert!("hello".find(|c:char| c == 'x').is_none());
+        assert!("hello".find(|&: c:char| c == 'x').is_none());
         assert_eq!("ประเทศไทย中华Việt Nam".find('华'), Some(30u));
-        assert_eq!("ประเทศไทย中华Việt Nam".find(|c: char| c == '华'), Some(30u));
+        assert_eq!("ประเทศไทย中华Việt Nam".find(|&: c: char| c == '华'), Some(30u));
     }
 
     #[test]
     fn test_rfind() {
         assert_eq!("hello".rfind('l'), Some(3u));
-        assert_eq!("hello".rfind(|c:char| c == 'o'), Some(4u));
+        assert_eq!("hello".rfind(|&: c:char| c == 'o'), Some(4u));
         assert!("hello".rfind('x').is_none());
-        assert!("hello".rfind(|c:char| c == 'x').is_none());
+        assert!("hello".rfind(|&: c:char| c == 'x').is_none());
         assert_eq!("ประเทศไทย中华Việt Nam".rfind('华'), Some(30u));
-        assert_eq!("ประเทศไทย中华Việt Nam".rfind(|c: char| c == '华'), Some(30u));
+        assert_eq!("ประเทศไทย中华Việt Nam".rfind(|&: c: char| c == '华'), Some(30u));
     }
 
     #[test]
@@ -1281,7 +1281,7 @@ mod tests {
         assert_eq!("11foo1bar11".trim_left_chars('1'), "foo1bar11");
         let chars: &[char] = &['1', '2'];
         assert_eq!("12foo1bar12".trim_left_chars(chars), "foo1bar12");
-        assert_eq!("123foo1bar123".trim_left_chars(|c: char| c.is_numeric()), "foo1bar123");
+        assert_eq!("123foo1bar123".trim_left_chars(|&: c: char| c.is_numeric()), "foo1bar123");
     }
 
     #[test]
@@ -1296,7 +1296,7 @@ mod tests {
         assert_eq!("11foo1bar11".trim_right_chars('1'), "11foo1bar");
         let chars: &[char] = &['1', '2'];
         assert_eq!("12foo1bar12".trim_right_chars(chars), "12foo1bar");
-        assert_eq!("123foo1bar123".trim_right_chars(|c: char| c.is_numeric()), "123foo1bar");
+        assert_eq!("123foo1bar123".trim_right_chars(|&: c: char| c.is_numeric()), "123foo1bar");
     }
 
     #[test]
@@ -1311,7 +1311,7 @@ mod tests {
         assert_eq!("11foo1bar11".trim_chars('1'), "foo1bar");
         let chars: &[char] = &['1', '2'];
         assert_eq!("12foo1bar12".trim_chars(chars), "foo1bar");
-        assert_eq!("123foo1bar123".trim_chars(|c: char| c.is_numeric()), "foo1bar");
+        assert_eq!("123foo1bar123".trim_chars(|&: c: char| c.is_numeric()), "foo1bar");
     }
 
     #[test]
@@ -1787,14 +1787,14 @@ mod tests {
         let split: Vec<&str> = data.splitn(3, ' ').collect();
         assert_eq!(split, vec!["\nMäry", "häd", "ä", "little lämb\nLittle lämb\n"]);
 
-        let split: Vec<&str> = data.splitn(3, |c: char| c == ' ').collect();
+        let split: Vec<&str> = data.splitn(3, |&: c: char| c == ' ').collect();
         assert_eq!(split, vec!["\nMäry", "häd", "ä", "little lämb\nLittle lämb\n"]);
 
         // Unicode
         let split: Vec<&str> = data.splitn(3, 'ä').collect();
         assert_eq!(split, vec!["\nM", "ry h", "d ", " little lämb\nLittle lämb\n"]);
 
-        let split: Vec<&str> = data.splitn(3, |c: char| c == 'ä').collect();
+        let split: Vec<&str> = data.splitn(3, |&: c: char| c == 'ä').collect();
         assert_eq!(split, vec!["\nM", "ry h", "d ", " little lämb\nLittle lämb\n"]);
     }
 
@@ -2588,7 +2588,7 @@ mod bench {
         let s = "Mary had a little lamb, Little lamb, little-lamb.";
         let len = s.split(' ').count();
 
-        b.iter(|| assert_eq!(s.split(|c: char| c == ' ').count(), len));
+        b.iter(|| assert_eq!(s.split(|&: c: char| c == ' ').count(), len));
     }
 
     #[bench]

From 47acce498a9413f3d4b24993e231393cbbcb6346 Mon Sep 17 00:00:00 2001
From: Jorge Aparicio <japaricious@gmail.com>
Date: Thu, 4 Dec 2014 20:01:55 -0500
Subject: [PATCH 37/92] libcoretest: fix fallout in unit tests

---
 src/libcoretest/lib.rs |  1 +
 src/libcoretest/str.rs | 12 ++++++------
 2 files changed, 7 insertions(+), 6 deletions(-)

diff --git a/src/libcoretest/lib.rs b/src/libcoretest/lib.rs
index 5f31ed35f1b60..089a2cc880eb6 100644
--- a/src/libcoretest/lib.rs
+++ b/src/libcoretest/lib.rs
@@ -8,6 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 #![feature(globs, unsafe_destructor, macro_rules, slicing_syntax)]
+#![feature(unboxed_closures)]
 
 extern crate core;
 extern crate test;
diff --git a/src/libcoretest/str.rs b/src/libcoretest/str.rs
index 9574aeb3762de..763fcccdbfdc8 100644
--- a/src/libcoretest/str.rs
+++ b/src/libcoretest/str.rs
@@ -54,7 +54,7 @@ fn test_rsplitn_char_iterator() {
     split.reverse();
     assert_eq!(split, vec!["\nMäry häd ä", "little", "lämb\nLittle", "lämb\n"]);
 
-    let mut split: Vec<&str> = data.rsplitn(3, |c: char| c == ' ').collect();
+    let mut split: Vec<&str> = data.rsplitn(3, |&: c: char| c == ' ').collect();
     split.reverse();
     assert_eq!(split, vec!["\nMäry häd ä", "little", "lämb\nLittle", "lämb\n"]);
 
@@ -63,7 +63,7 @@ fn test_rsplitn_char_iterator() {
     split.reverse();
     assert_eq!(split, vec!["\nMäry häd ", " little l", "mb\nLittle l", "mb\n"]);
 
-    let mut split: Vec<&str> = data.rsplitn(3, |c: char| c == 'ä').collect();
+    let mut split: Vec<&str> = data.rsplitn(3, |&: c: char| c == 'ä').collect();
     split.reverse();
     assert_eq!(split, vec!["\nMäry häd ", " little l", "mb\nLittle l", "mb\n"]);
 }
@@ -79,10 +79,10 @@ fn test_split_char_iterator() {
     rsplit.reverse();
     assert_eq!(rsplit, vec!["\nMäry", "häd", "ä", "little", "lämb\nLittle", "lämb\n"]);
 
-    let split: Vec<&str> = data.split(|c: char| c == ' ').collect();
+    let split: Vec<&str> = data.split(|&: c: char| c == ' ').collect();
     assert_eq!( split, vec!["\nMäry", "häd", "ä", "little", "lämb\nLittle", "lämb\n"]);
 
-    let mut rsplit: Vec<&str> = data.split(|c: char| c == ' ').rev().collect();
+    let mut rsplit: Vec<&str> = data.split(|&: c: char| c == ' ').rev().collect();
     rsplit.reverse();
     assert_eq!(rsplit, vec!["\nMäry", "häd", "ä", "little", "lämb\nLittle", "lämb\n"]);
 
@@ -94,10 +94,10 @@ fn test_split_char_iterator() {
     rsplit.reverse();
     assert_eq!(rsplit, vec!["\nM", "ry h", "d ", " little l", "mb\nLittle l", "mb\n"]);
 
-    let split: Vec<&str> = data.split(|c: char| c == 'ä').collect();
+    let split: Vec<&str> = data.split(|&: c: char| c == 'ä').collect();
     assert_eq!( split, vec!["\nM", "ry h", "d ", " little l", "mb\nLittle l", "mb\n"]);
 
-    let mut rsplit: Vec<&str> = data.split(|c: char| c == 'ä').rev().collect();
+    let mut rsplit: Vec<&str> = data.split(|&: c: char| c == 'ä').rev().collect();
     rsplit.reverse();
     assert_eq!(rsplit, vec!["\nM", "ry h", "d ", " little l", "mb\nLittle l", "mb\n"]);
 }

From 30ea64ea77dd33d0af9271b032644120b4f5166a Mon Sep 17 00:00:00 2001
From: Jorge Aparicio <japaricious@gmail.com>
Date: Thu, 4 Dec 2014 21:31:49 -0500
Subject: [PATCH 38/92] libcore: fix fallout in doctests

---
 src/libcore/str.rs | 54 ++++++++++++++++++++++++++++++++++++++--------
 1 file changed, 45 insertions(+), 9 deletions(-)

diff --git a/src/libcore/str.rs b/src/libcore/str.rs
index 328a64acaf8b4..92f82bd977114 100644
--- a/src/libcore/str.rs
+++ b/src/libcore/str.rs
@@ -1352,10 +1352,13 @@ pub trait StrPrelude for Sized? {
     /// # Example
     ///
     /// ```rust
+    /// # #![feature(unboxed_closures)]
+    ///
+    /// # fn main() {
     /// let v: Vec<&str> = "Mary had a little lamb".split(' ').collect();
     /// assert_eq!(v, vec!["Mary", "had", "a", "little", "lamb"]);
     ///
-    /// let v: Vec<&str> = "abc1def2ghi".split(|c: char| c.is_numeric()).collect();
+    /// let v: Vec<&str> = "abc1def2ghi".split(|&: c: char| c.is_numeric()).collect();
     /// assert_eq!(v, vec!["abc", "def", "ghi"]);
     ///
     /// let v: Vec<&str> = "lionXXtigerXleopard".split('X').collect();
@@ -1363,6 +1366,7 @@ pub trait StrPrelude for Sized? {
     ///
     /// let v: Vec<&str> = "".split('X').collect();
     /// assert_eq!(v, vec![""]);
+    /// # }
     /// ```
     fn split<'a, Sep: CharEq>(&'a self, sep: Sep) -> CharSplits<'a, Sep>;
 
@@ -1373,10 +1377,13 @@ pub trait StrPrelude for Sized? {
     /// # Example
     ///
     /// ```rust
+    /// # #![feature(unboxed_closures)]
+    ///
+    /// # fn main() {
     /// let v: Vec<&str> = "Mary had a little lambda".splitn(2, ' ').collect();
     /// assert_eq!(v, vec!["Mary", "had", "a little lambda"]);
     ///
-    /// let v: Vec<&str> = "abc1def2ghi".splitn(1, |c: char| c.is_numeric()).collect();
+    /// let v: Vec<&str> = "abc1def2ghi".splitn(1, |&: c: char| c.is_numeric()).collect();
     /// assert_eq!(v, vec!["abc", "def2ghi"]);
     ///
     /// let v: Vec<&str> = "lionXXtigerXleopard".splitn(2, 'X').collect();
@@ -1387,6 +1394,7 @@ pub trait StrPrelude for Sized? {
     ///
     /// let v: Vec<&str> = "".splitn(1, 'X').collect();
     /// assert_eq!(v, vec![""]);
+    /// # }
     /// ```
     fn splitn<'a, Sep: CharEq>(&'a self, count: uint, sep: Sep) -> CharSplitsN<'a, Sep>;
 
@@ -1399,6 +1407,9 @@ pub trait StrPrelude for Sized? {
     /// # Example
     ///
     /// ```rust
+    /// # #![feature(unboxed_closures)]
+    ///
+    /// # fn main() {
     /// let v: Vec<&str> = "A.B.".split_terminator('.').collect();
     /// assert_eq!(v, vec!["A", "B"]);
     ///
@@ -1408,11 +1419,12 @@ pub trait StrPrelude for Sized? {
     /// let v: Vec<&str> = "Mary had a little lamb".split(' ').rev().collect();
     /// assert_eq!(v, vec!["lamb", "little", "a", "had", "Mary"]);
     ///
-    /// let v: Vec<&str> = "abc1def2ghi".split(|c: char| c.is_numeric()).rev().collect();
+    /// let v: Vec<&str> = "abc1def2ghi".split(|&: c: char| c.is_numeric()).rev().collect();
     /// assert_eq!(v, vec!["ghi", "def", "abc"]);
     ///
     /// let v: Vec<&str> = "lionXXtigerXleopard".split('X').rev().collect();
     /// assert_eq!(v, vec!["leopard", "tiger", "", "lion"]);
+    /// # }
     /// ```
     fn split_terminator<'a, Sep: CharEq>(&'a self, sep: Sep) -> CharSplits<'a, Sep>;
 
@@ -1423,14 +1435,18 @@ pub trait StrPrelude for Sized? {
     /// # Example
     ///
     /// ```rust
+    /// # #![feature(unboxed_closures)]
+    ///
+    /// # fn main() {
     /// let v: Vec<&str> = "Mary had a little lamb".rsplitn(2, ' ').collect();
     /// assert_eq!(v, vec!["lamb", "little", "Mary had a"]);
     ///
-    /// let v: Vec<&str> = "abc1def2ghi".rsplitn(1, |c: char| c.is_numeric()).collect();
+    /// let v: Vec<&str> = "abc1def2ghi".rsplitn(1, |&: c: char| c.is_numeric()).collect();
     /// assert_eq!(v, vec!["ghi", "abc1def"]);
     ///
     /// let v: Vec<&str> = "lionXXtigerXleopard".rsplitn(2, 'X').collect();
     /// assert_eq!(v, vec!["leopard", "tiger", "lionX"]);
+    /// # }
     /// ```
     fn rsplitn<'a, Sep: CharEq>(&'a self, count: uint, sep: Sep) -> CharSplitsN<'a, Sep>;
 
@@ -1641,10 +1657,14 @@ pub trait StrPrelude for Sized? {
     /// # Example
     ///
     /// ```rust
+    /// # #![feature(unboxed_closures)]
+    ///
+    /// # fn main() {
     /// assert_eq!("11foo1bar11".trim_chars('1'), "foo1bar")
     /// let x: &[_] = &['1', '2'];
     /// assert_eq!("12foo1bar12".trim_chars(x), "foo1bar")
-    /// assert_eq!("123foo1bar123".trim_chars(|c: char| c.is_numeric()), "foo1bar")
+    /// assert_eq!("123foo1bar123".trim_chars(|&: c: char| c.is_numeric()), "foo1bar")
+    /// # }
     /// ```
     fn trim_chars<'a, C: CharEq>(&'a self, to_trim: C) -> &'a str;
 
@@ -1657,10 +1677,14 @@ pub trait StrPrelude for Sized? {
     /// # Example
     ///
     /// ```rust
+    /// # #![feature(unboxed_closures)]
+    ///
+    /// # fn main() {
     /// assert_eq!("11foo1bar11".trim_left_chars('1'), "foo1bar11")
     /// let x: &[_] = &['1', '2'];
     /// assert_eq!("12foo1bar12".trim_left_chars(x), "foo1bar12")
-    /// assert_eq!("123foo1bar123".trim_left_chars(|c: char| c.is_numeric()), "foo1bar123")
+    /// assert_eq!("123foo1bar123".trim_left_chars(|&: c: char| c.is_numeric()), "foo1bar123")
+    /// # }
     /// ```
     fn trim_left_chars<'a, C: CharEq>(&'a self, to_trim: C) -> &'a str;
 
@@ -1673,10 +1697,14 @@ pub trait StrPrelude for Sized? {
     /// # Example
     ///
     /// ```rust
+    /// # #![feature(unboxed_closures)]
+    ///
+    /// # fn main() {
     /// assert_eq!("11foo1bar11".trim_right_chars('1'), "11foo1bar")
     /// let x: &[_] = &['1', '2'];
     /// assert_eq!("12foo1bar12".trim_right_chars(x), "12foo1bar")
-    /// assert_eq!("123foo1bar123".trim_right_chars(|c: char| c.is_numeric()), "123foo1bar")
+    /// assert_eq!("123foo1bar123".trim_right_chars(|&: c: char| c.is_numeric()), "123foo1bar")
+    /// # }
     /// ```
     fn trim_right_chars<'a, C: CharEq>(&'a self, to_trim: C) -> &'a str;
 
@@ -1817,17 +1845,21 @@ pub trait StrPrelude for Sized? {
     /// # Example
     ///
     /// ```rust
+    /// # #![feature(unboxed_closures)]
+    ///
+    /// # fn main() {
     /// let s = "Löwe 老虎 Léopard";
     ///
     /// assert_eq!(s.find('L'), Some(0));
     /// assert_eq!(s.find('é'), Some(14));
     ///
     /// // the first space
-    /// assert_eq!(s.find(|c: char| c.is_whitespace()), Some(5));
+    /// assert_eq!(s.find(|&: c: char| c.is_whitespace()), Some(5));
     ///
     /// // neither are found
     /// let x: &[_] = &['1', '2'];
     /// assert_eq!(s.find(x), None);
+    /// # }
     /// ```
     fn find<C: CharEq>(&self, search: C) -> Option<uint>;
 
@@ -1842,17 +1874,21 @@ pub trait StrPrelude for Sized? {
     /// # Example
     ///
     /// ```rust
+    /// # #![feature(unboxed_closures)]
+    ///
+    /// # fn main() {
     /// let s = "Löwe 老虎 Léopard";
     ///
     /// assert_eq!(s.rfind('L'), Some(13));
     /// assert_eq!(s.rfind('é'), Some(14));
     ///
     /// // the second space
-    /// assert_eq!(s.rfind(|c: char| c.is_whitespace()), Some(12));
+    /// assert_eq!(s.rfind(|&: c: char| c.is_whitespace()), Some(12));
     ///
     /// // searches for an occurrence of either `1` or `2`, but neither are found
     /// let x: &[_] = &['1', '2'];
     /// assert_eq!(s.rfind(x), None);
+    /// # }
     /// ```
     fn rfind<C: CharEq>(&self, search: C) -> Option<uint>;
 

From 9c7046573b75b988e8291c6d7bf9c126ba2b7b5a Mon Sep 17 00:00:00 2001
From: Jorge Aparicio <japaricious@gmail.com>
Date: Thu, 4 Dec 2014 23:47:40 -0500
Subject: [PATCH 39/92] libcore: use unboxed closures in the fields of `Splits`

---
 src/libcore/slice.rs | 31 +++++++++++++++++++------------
 1 file changed, 19 insertions(+), 12 deletions(-)

diff --git a/src/libcore/slice.rs b/src/libcore/slice.rs
index 4e3007b55fe04..3dad5458b365b 100644
--- a/src/libcore/slice.rs
+++ b/src/libcore/slice.rs
@@ -43,7 +43,7 @@ use default::Default;
 use iter::*;
 use kinds::Copy;
 use num::Int;
-use ops;
+use ops::{FnMut, mod};
 use option::Option;
 use option::Option::{None, Some};
 use ptr;
@@ -105,20 +105,23 @@ pub trait SlicePrelude<T> for Sized? {
     /// Returns an iterator over subslices separated by elements that match
     /// `pred`.  The matched element is not contained in the subslices.
     #[unstable = "iterator type may change, waiting on unboxed closures"]
-    fn split<'a>(&'a self, pred: |&T|: 'a -> bool) -> Splits<'a, T>;
+    fn split<'a, P>(&'a self, pred: P) -> Splits<'a, T, P> where
+        P: FnMut(&T) -> bool;
 
     /// Returns an iterator over subslices separated by elements that match
     /// `pred`, limited to splitting at most `n` times.  The matched element is
     /// not contained in the subslices.
     #[unstable = "iterator type may change"]
-    fn splitn<'a>(&'a self, n: uint, pred: |&T|: 'a -> bool) -> SplitsN<Splits<'a, T>>;
+    fn splitn<'a, P>(&'a self, n: uint, pred: P) -> SplitsN<Splits<'a, T, P>> where
+        P: FnMut(&T) -> bool;
 
     /// Returns an iterator over subslices separated by elements that match
     /// `pred` limited to splitting at most `n` times. This starts at the end of
     /// the slice and works backwards.  The matched element is not contained in
     /// the subslices.
     #[unstable = "iterator type may change"]
-    fn rsplitn<'a>(&'a self,  n: uint, pred: |&T|: 'a -> bool) -> SplitsN<Splits<'a, T>>;
+    fn rsplitn<'a, P>(&'a self,  n: uint, pred: P) -> SplitsN<Splits<'a, T, P>> where
+        P: FnMut(&T) -> bool;
 
     /// Returns an iterator over all contiguous windows of length
     /// `size`. The windows overlap. If the slice is shorter than
@@ -470,7 +473,7 @@ impl<T> SlicePrelude<T> for [T] {
     }
 
     #[inline]
-    fn split<'a>(&'a self, pred: |&T|: 'a -> bool) -> Splits<'a, T> {
+    fn split<'a, P>(&'a self, pred: P) -> Splits<'a, T, P> where P: FnMut(&T) -> bool {
         Splits {
             v: self,
             pred: pred,
@@ -479,7 +482,9 @@ impl<T> SlicePrelude<T> for [T] {
     }
 
     #[inline]
-    fn splitn<'a>(&'a self, n: uint, pred: |&T|: 'a -> bool) -> SplitsN<Splits<'a, T>> {
+    fn splitn<'a, P>(&'a self, n: uint, pred: P) -> SplitsN<Splits<'a, T, P>> where
+        P: FnMut(&T) -> bool,
+    {
         SplitsN {
             iter: self.split(pred),
             count: n,
@@ -488,7 +493,9 @@ impl<T> SlicePrelude<T> for [T] {
     }
 
     #[inline]
-    fn rsplitn<'a>(&'a self, n: uint, pred: |&T|: 'a -> bool) -> SplitsN<Splits<'a, T>> {
+    fn rsplitn<'a, P>(&'a self, n: uint, pred: P) -> SplitsN<Splits<'a, T, P>> where
+        P: FnMut(&T) -> bool,
+    {
         SplitsN {
             iter: self.split(pred),
             count: n,
@@ -1271,14 +1278,14 @@ trait SplitsIter<E>: DoubleEndedIterator<E> {
 /// An iterator over subslices separated by elements that match a predicate
 /// function.
 #[experimental = "needs review"]
-pub struct Splits<'a, T:'a> {
+pub struct Splits<'a, T:'a, P> where P: FnMut(&T) -> bool {
     v: &'a [T],
-    pred: |t: &T|: 'a -> bool,
+    pred: P,
     finished: bool
 }
 
 #[experimental = "needs review"]
-impl<'a, T> Iterator<&'a [T]> for Splits<'a, T> {
+impl<'a, T, P> Iterator<&'a [T]> for Splits<'a, T, P> where P: FnMut(&T) -> bool {
     #[inline]
     fn next(&mut self) -> Option<&'a [T]> {
         if self.finished { return None; }
@@ -1304,7 +1311,7 @@ impl<'a, T> Iterator<&'a [T]> for Splits<'a, T> {
 }
 
 #[experimental = "needs review"]
-impl<'a, T> DoubleEndedIterator<&'a [T]> for Splits<'a, T> {
+impl<'a, T, P> DoubleEndedIterator<&'a [T]> for Splits<'a, T, P> where P: FnMut(&T) -> bool {
     #[inline]
     fn next_back(&mut self) -> Option<&'a [T]> {
         if self.finished { return None; }
@@ -1320,7 +1327,7 @@ impl<'a, T> DoubleEndedIterator<&'a [T]> for Splits<'a, T> {
     }
 }
 
-impl<'a, T> SplitsIter<&'a [T]> for Splits<'a, T> {
+impl<'a, T, P> SplitsIter<&'a [T]> for Splits<'a, T, P> where P: FnMut(&T) -> bool {
     #[inline]
     fn finish(&mut self) -> Option<&'a [T]> {
         if self.finished { None } else { self.finished = true; Some(self.v) }

From 43cf7b4e457ad42aa44ad06469d6587ddb67eb2e Mon Sep 17 00:00:00 2001
From: Jorge Aparicio <japaricious@gmail.com>
Date: Thu, 4 Dec 2014 23:50:57 -0500
Subject: [PATCH 40/92] libstd: fix fallout

---
 src/libstd/path/posix.rs | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/libstd/path/posix.rs b/src/libstd/path/posix.rs
index 6cafedcad116d..3daba53cd866e 100644
--- a/src/libstd/path/posix.rs
+++ b/src/libstd/path/posix.rs
@@ -29,7 +29,7 @@ use vec::Vec;
 use super::{BytesContainer, GenericPath, GenericPathUnsafe};
 
 /// Iterator that yields successive components of a Path as &[u8]
-pub type Components<'a> = Splits<'a, u8>;
+pub type Components<'a> = Splits<'a, u8, fn(&u8) -> bool>;
 
 /// Iterator that yields successive components of a Path as Option<&str>
 pub type StrComponents<'a> =

From 6ae9b9e54a9eb9711b32d663bb1a044f7540b4b0 Mon Sep 17 00:00:00 2001
From: Jorge Aparicio <japaricious@gmail.com>
Date: Fri, 5 Dec 2014 01:00:50 -0500
Subject: [PATCH 41/92] libcore: use unboxed closures in the fields of
 `MutSplits`

---
 src/libcore/slice.rs | 31 ++++++++++++++++++++-----------
 1 file changed, 20 insertions(+), 11 deletions(-)

diff --git a/src/libcore/slice.rs b/src/libcore/slice.rs
index 3dad5458b365b..cfdb406f711ef 100644
--- a/src/libcore/slice.rs
+++ b/src/libcore/slice.rs
@@ -319,20 +319,23 @@ pub trait SlicePrelude<T> for Sized? {
     /// Returns an iterator over mutable subslices separated by elements that
     /// match `pred`.  The matched element is not contained in the subslices.
     #[unstable = "waiting on unboxed closures, iterator type name conventions"]
-    fn split_mut<'a>(&'a mut self, pred: |&T|: 'a -> bool) -> MutSplits<'a, T>;
+    fn split_mut<'a, P>(&'a mut self, pred: P) -> MutSplits<'a, T, P> where
+        P: FnMut(&T) -> bool;
 
     /// Returns an iterator over subslices separated by elements that match
     /// `pred`, limited to splitting at most `n` times.  The matched element is
     /// not contained in the subslices.
     #[unstable = "waiting on unboxed closures, iterator type name conventions"]
-    fn splitn_mut<'a>(&'a mut self, n: uint, pred: |&T|: 'a -> bool) -> SplitsN<MutSplits<'a, T>>;
+    fn splitn_mut<'a, P>(&'a mut self, n: uint, pred: P) -> SplitsN<MutSplits<'a, T, P>> where
+        P: FnMut(&T) -> bool;
 
     /// Returns an iterator over subslices separated by elements that match
     /// `pred` limited to splitting at most `n` times. This starts at the end of
     /// the slice and works backwards.  The matched element is not contained in
     /// the subslices.
     #[unstable = "waiting on unboxed closures, iterator type name conventions"]
-    fn rsplitn_mut<'a>(&'a mut self,  n: uint, pred: |&T|: 'a -> bool) -> SplitsN<MutSplits<'a, T>>;
+    fn rsplitn_mut<'a, P>(&'a mut self,  n: uint, pred: P) -> SplitsN<MutSplits<'a, T, P>> where
+        P: FnMut(&T) -> bool;
 
     /// Returns an iterator over `chunk_size` elements of the slice at a time.
     /// The chunks are mutable and do not overlap. If `chunk_size` does
@@ -644,12 +647,14 @@ impl<T> SlicePrelude<T> for [T] {
     }
 
     #[inline]
-    fn split_mut<'a>(&'a mut self, pred: |&T|: 'a -> bool) -> MutSplits<'a, T> {
+    fn split_mut<'a, P>(&'a mut self, pred: P) -> MutSplits<'a, T, P> where P: FnMut(&T) -> bool {
         MutSplits { v: self, pred: pred, finished: false }
     }
 
     #[inline]
-    fn splitn_mut<'a>(&'a mut self, n: uint, pred: |&T|: 'a -> bool) -> SplitsN<MutSplits<'a, T>> {
+    fn splitn_mut<'a, P>(&'a mut self, n: uint, pred: P) -> SplitsN<MutSplits<'a, T, P>> where
+        P: FnMut(&T) -> bool
+    {
         SplitsN {
             iter: self.split_mut(pred),
             count: n,
@@ -658,7 +663,9 @@ impl<T> SlicePrelude<T> for [T] {
     }
 
     #[inline]
-    fn rsplitn_mut<'a>(&'a mut self, n: uint, pred: |&T|: 'a -> bool) -> SplitsN<MutSplits<'a, T>> {
+    fn rsplitn_mut<'a, P>(&'a mut self, n: uint, pred: P) -> SplitsN<MutSplits<'a, T, P>> where
+        P: FnMut(&T) -> bool,
+    {
         SplitsN {
             iter: self.split_mut(pred),
             count: n,
@@ -1337,13 +1344,13 @@ impl<'a, T, P> SplitsIter<&'a [T]> for Splits<'a, T, P> where P: FnMut(&T) -> bo
 /// An iterator over the subslices of the vector which are separated
 /// by elements that match `pred`.
 #[experimental = "needs review"]
-pub struct MutSplits<'a, T:'a> {
+pub struct MutSplits<'a, T:'a, P> where P: FnMut(&T) -> bool {
     v: &'a mut [T],
-    pred: |t: &T|: 'a -> bool,
+    pred: P,
     finished: bool
 }
 
-impl<'a, T> SplitsIter<&'a mut [T]> for MutSplits<'a, T> {
+impl<'a, T, P> SplitsIter<&'a mut [T]> for MutSplits<'a, T, P> where P: FnMut(&T) -> bool {
     #[inline]
     fn finish(&mut self) -> Option<&'a mut [T]> {
         if self.finished {
@@ -1356,7 +1363,7 @@ impl<'a, T> SplitsIter<&'a mut [T]> for MutSplits<'a, T> {
 }
 
 #[experimental = "needs review"]
-impl<'a, T> Iterator<&'a mut [T]> for MutSplits<'a, T> {
+impl<'a, T, P> Iterator<&'a mut [T]> for MutSplits<'a, T, P> where P: FnMut(&T) -> bool {
     #[inline]
     fn next(&mut self) -> Option<&'a mut [T]> {
         if self.finished { return None; }
@@ -1389,7 +1396,9 @@ impl<'a, T> Iterator<&'a mut [T]> for MutSplits<'a, T> {
 }
 
 #[experimental = "needs review"]
-impl<'a, T> DoubleEndedIterator<&'a mut [T]> for MutSplits<'a, T> {
+impl<'a, T, P> DoubleEndedIterator<&'a mut [T]> for MutSplits<'a, T, P> where
+    P: FnMut(&T) -> bool,
+{
     #[inline]
     fn next_back(&mut self) -> Option<&'a mut [T]> {
         if self.finished { return None; }

From e2a362f9bbf94eedca42eceea2929e4d96f4eeee Mon Sep 17 00:00:00 2001
From: Jorge Aparicio <japaricious@gmail.com>
Date: Fri, 5 Dec 2014 02:04:33 -0500
Subject: [PATCH 42/92] libcore: use unboxed closures in `SlicePrelude` methods

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

diff --git a/src/libcore/slice.rs b/src/libcore/slice.rs
index cfdb406f711ef..af15099476578 100644
--- a/src/libcore/slice.rs
+++ b/src/libcore/slice.rs
@@ -238,7 +238,7 @@ pub trait SlicePrelude<T> for Sized? {
     /// assert!(match r { Found(1...4) => true, _ => false, });
     /// ```
     #[unstable = "waiting on unboxed closures"]
-    fn binary_search(&self, f: |&T| -> Ordering) -> BinarySearchResult;
+    fn binary_search<F>(&self, f: F) -> BinarySearchResult where F: FnMut(&T) -> Ordering;
 
     /// Return the number of elements in the slice
     ///
@@ -552,7 +552,7 @@ impl<T> SlicePrelude<T> for [T] {
     }
 
     #[unstable]
-    fn binary_search(&self, f: |&T| -> Ordering) -> BinarySearchResult {
+    fn binary_search<F>(&self, mut f: F) -> BinarySearchResult where F: FnMut(&T) -> Ordering {
         let mut base : uint = 0;
         let mut lim : uint = self.len();
 

From f18b255bced2dfedc437ea3d54465e4f42b1938a Mon Sep 17 00:00:00 2001
From: Jorge Aparicio <japaricious@gmail.com>
Date: Fri, 5 Dec 2014 08:24:40 -0500
Subject: [PATCH 43/92] libcore: use unboxed closures in the `finally` module

---
 src/libcore/finally.rs | 35 ++++++++++++-----------------------
 1 file changed, 12 insertions(+), 23 deletions(-)

diff --git a/src/libcore/finally.rs b/src/libcore/finally.rs
index d2b7591b3efa1..db76ce35cad38 100644
--- a/src/libcore/finally.rs
+++ b/src/libcore/finally.rs
@@ -30,29 +30,19 @@
 
 #![experimental]
 
-use ops::Drop;
+use ops::{Drop, FnMut, FnOnce};
 
 /// A trait for executing a destructor unconditionally after a block of code,
 /// regardless of whether the blocked fails.
 pub trait Finally<T> {
     /// Executes this object, unconditionally running `dtor` after this block of
     /// code has run.
-    fn finally(&mut self, dtor: ||) -> T;
+    fn finally<F>(&mut self, dtor: F) -> T where F: FnMut();
 }
 
-impl<'a,T> Finally<T> for ||: 'a -> T {
-    fn finally(&mut self, dtor: ||) -> T {
-        try_finally(&mut (), self,
-                    |_, f| (*f)(),
-                    |_| dtor())
-    }
-}
-
-impl<T> Finally<T> for fn() -> T {
-    fn finally(&mut self, dtor: ||) -> T {
-        try_finally(&mut (), (),
-                    |_, _| (*self)(),
-                    |_| dtor())
+impl<T, F> Finally<T> for F where F: FnMut() -> T {
+    fn finally<G>(&mut self, mut dtor: G) -> T where G: FnMut() {
+        try_finally(&mut (), self, |_, f| (*f)(), |_| dtor())
     }
 }
 
@@ -86,11 +76,10 @@ impl<T> Finally<T> for fn() -> T {
 ///         // use state.buffer, state.len to cleanup
 ///     })
 /// ```
-pub fn try_finally<T,U,R>(mutate: &mut T,
-                          drop: U,
-                          try_fn: |&mut T, U| -> R,
-                          finally_fn: |&mut T|)
-                          -> R {
+pub fn try_finally<T, U, R, F, G>(mutate: &mut T, drop: U, try_fn: F, finally_fn: G) -> R where
+    F: FnOnce(&mut T, U) -> R,
+    G: FnMut(&mut T),
+{
     let f = Finallyalizer {
         mutate: mutate,
         dtor: finally_fn,
@@ -98,13 +87,13 @@ pub fn try_finally<T,U,R>(mutate: &mut T,
     try_fn(&mut *f.mutate, drop)
 }
 
-struct Finallyalizer<'a,A:'a> {
+struct Finallyalizer<'a, A:'a, F> where F: FnMut(&mut A) {
     mutate: &'a mut A,
-    dtor: |&mut A|: 'a
+    dtor: F,
 }
 
 #[unsafe_destructor]
-impl<'a,A> Drop for Finallyalizer<'a,A> {
+impl<'a, A, F> Drop for Finallyalizer<'a, A, F> where F: FnMut(&mut A) {
     #[inline]
     fn drop(&mut self) {
         (self.dtor)(self.mutate);

From 40b361703515f1909e0a5fba8d419cfbcf1c4a74 Mon Sep 17 00:00:00 2001
From: Jorge Aparicio <japaricious@gmail.com>
Date: Fri, 5 Dec 2014 08:54:28 -0500
Subject: [PATCH 44/92] libstd: fix fallout

---
 src/libstd/lib.rs | 1 +
 1 file changed, 1 insertion(+)

diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs
index f6b73f037f25b..c2363c9946a96 100644
--- a/src/libstd/lib.rs
+++ b/src/libstd/lib.rs
@@ -107,6 +107,7 @@
 #![feature(macro_rules, globs, linkage)]
 #![feature(default_type_params, phase, lang_items, unsafe_destructor)]
 #![feature(import_shadowing, slicing_syntax)]
+#![feature(unboxed_closures)]
 
 // Don't link to std. We are std.
 #![no_std]

From 45860b53e076f219a56c3ad0fac825bcbce2cca7 Mon Sep 17 00:00:00 2001
From: Jorge Aparicio <japaricious@gmail.com>
Date: Fri, 5 Dec 2014 10:16:53 -0500
Subject: [PATCH 45/92] Fix run pass test

---
 src/test/run-pass/backtrace.rs | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/src/test/run-pass/backtrace.rs b/src/test/run-pass/backtrace.rs
index a267b8dcc86d2..da5fa19f816f7 100644
--- a/src/test/run-pass/backtrace.rs
+++ b/src/test/run-pass/backtrace.rs
@@ -10,6 +10,9 @@
 
 // no-pretty-expanded FIXME #15189
 // ignore-windows FIXME #13259
+
+#![feature(unboxed_closures)]
+
 use std::os;
 use std::io::process::Command;
 use std::finally::Finally;
@@ -25,7 +28,7 @@ fn foo() {
 
 #[inline(never)]
 fn double() {
-    (|| {
+    (|&mut:| {
         panic!("once");
     }).finally(|| {
         panic!("twice");

From 8df27d26bd258cb54981820fb8c1bc83710970fe Mon Sep 17 00:00:00 2001
From: Jorge Aparicio <japaricious@gmail.com>
Date: Fri, 5 Dec 2014 10:49:51 -0500
Subject: [PATCH 46/92] libcoretest: fix fallout

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

diff --git a/src/libcoretest/finally.rs b/src/libcoretest/finally.rs
index 032f5f7194117..2d77c1bc0978c 100644
--- a/src/libcoretest/finally.rs
+++ b/src/libcoretest/finally.rs
@@ -45,7 +45,7 @@ fn test_fail() {
 
 #[test]
 fn test_retval() {
-    let mut closure: || -> int = || 10;
+    let mut closure = |&mut:| 10i;
     let i = closure.finally(|| { });
     assert_eq!(i, 10);
 }

From 950fbf4e106578b779e4f9ad68643bafae3e19e1 Mon Sep 17 00:00:00 2001
From: Jorge Aparicio <japaricious@gmail.com>
Date: Fri, 5 Dec 2014 10:52:51 -0500
Subject: [PATCH 47/92] librustrt: fix fallout

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

diff --git a/src/librustrt/args.rs b/src/librustrt/args.rs
index d94f731e75c64..4632eca4d0fd5 100644
--- a/src/librustrt/args.rs
+++ b/src/librustrt/args.rs
@@ -128,7 +128,7 @@ mod imp {
             assert!(take() == Some(expected.clone()));
             assert!(take() == None);
 
-            (|| {
+            (|&mut:| {
             }).finally(|| {
                 // Restore the actual global state.
                 match saved_value {

From 0b0c3e1d9623f4cb55a717cd3ffe8d985c84247f Mon Sep 17 00:00:00 2001
From: Jorge Aparicio <japaricious@gmail.com>
Date: Fri, 5 Dec 2014 11:55:36 -0500
Subject: [PATCH 48/92] libcore: fix fallout in doc tests

---
 src/libcore/finally.rs | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/src/libcore/finally.rs b/src/libcore/finally.rs
index db76ce35cad38..2b48b2bf81afb 100644
--- a/src/libcore/finally.rs
+++ b/src/libcore/finally.rs
@@ -19,13 +19,17 @@
 //! # Example
 //!
 //! ```
+//! # #![feature(unboxed_closures)]
+//!
 //! use std::finally::Finally;
 //!
-//! (|| {
+//! # fn main() {
+//! (|&mut:| {
 //!     // ...
 //! }).finally(|| {
 //!     // this code is always run
 //! })
+//! # }
 //! ```
 
 #![experimental]

From 1a87fc7c9f6ce91293fd6553a49536f2ceccc165 Mon Sep 17 00:00:00 2001
From: Jorge Aparicio <japaricious@gmail.com>
Date: Fri, 5 Dec 2014 13:06:24 -0500
Subject: [PATCH 49/92] libcore: use unboxed closures in `Formatter` methods

---
 src/libcore/fmt/mod.rs | 9 ++++-----
 1 file changed, 4 insertions(+), 5 deletions(-)

diff --git a/src/libcore/fmt/mod.rs b/src/libcore/fmt/mod.rs
index 88ea811cfd694..37a1d4d564d84 100644
--- a/src/libcore/fmt/mod.rs
+++ b/src/libcore/fmt/mod.rs
@@ -19,7 +19,7 @@ use kinds::{Copy, Sized};
 use mem;
 use option::Option;
 use option::Option::{Some, None};
-use ops::Deref;
+use ops::{Deref, FnOnce};
 use result::Result::{Ok, Err};
 use result;
 use slice::SlicePrelude;
@@ -491,10 +491,9 @@ impl<'a> Formatter<'a> {
 
     /// Runs a callback, emitting the correct padding either before or
     /// afterwards depending on whether right or left alignment is requested.
-    fn with_padding(&mut self,
-                    padding: uint,
-                    default: rt::Alignment,
-                    f: |&mut Formatter| -> Result) -> Result {
+    fn with_padding<F>(&mut self, padding: uint, default: rt::Alignment, f: F) -> Result where
+        F: FnOnce(&mut Formatter) -> Result,
+    {
         use char::Char;
         let align = match self.align {
             rt::AlignUnknown => default,

From 02e7389c5d3e7fd9dfec13f691a04cfff003205d Mon Sep 17 00:00:00 2001
From: Jorge Aparicio <japaricious@gmail.com>
Date: Fri, 5 Dec 2014 13:53:25 -0500
Subject: [PATCH 50/92] libcore: use unboxed closures in the `char` module

---
 src/libcore/char.rs | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/src/libcore/char.rs b/src/libcore/char.rs
index 671b4ccb9e4f4..75f7991df027b 100644
--- a/src/libcore/char.rs
+++ b/src/libcore/char.rs
@@ -16,6 +16,7 @@
 #![doc(primitive = "char")]
 
 use mem::transmute;
+use ops::FnMut;
 use option::Option;
 use option::Option::{None, Some};
 use iter::{range_step, Iterator, RangeStep};
@@ -165,7 +166,7 @@ pub fn from_digit(num: uint, radix: uint) -> Option<char> {
 /// - chars above 0x10000 get 8-digit escapes: `\\u{{NNN}NNNNN}`
 ///
 #[deprecated = "use the Char::escape_unicode method"]
-pub fn escape_unicode(c: char, f: |char|) {
+pub fn escape_unicode<F>(c: char, mut f: F) where F: FnMut(char) {
     for char in c.escape_unicode() {
         f(char);
     }
@@ -184,7 +185,7 @@ pub fn escape_unicode(c: char, f: |char|) {
 /// - Any other chars are given hex Unicode escapes; see `escape_unicode`.
 ///
 #[deprecated = "use the Char::escape_default method"]
-pub fn escape_default(c: char, f: |char|) {
+pub fn escape_default<F>(c: char, mut f: F) where F: FnMut(char) {
     for c in c.escape_default() {
         f(c);
     }

From 0d39fc01bf2b105abd323a8f8ebd59b60f2790e7 Mon Sep 17 00:00:00 2001
From: Jorge Aparicio <japaricious@gmail.com>
Date: Fri, 5 Dec 2014 16:16:07 -0500
Subject: [PATCH 51/92] libcollections: use unboxed closures in `TreeMap`
 methods

---
 src/libcollections/tree/map.rs | 22 ++++++++++++++++------
 1 file changed, 16 insertions(+), 6 deletions(-)

diff --git a/src/libcollections/tree/map.rs b/src/libcollections/tree/map.rs
index 95fddb6ee1141..5c2cf4a81808d 100644
--- a/src/libcollections/tree/map.rs
+++ b/src/libcollections/tree/map.rs
@@ -616,7 +616,7 @@ impl<K, V> TreeMap<K, V> {
     /// ```
     #[inline]
     #[experimental = "likely to be renamed, may be removed"]
-    pub fn find_with(&self, f:|&K| -> Ordering) -> Option<&V> {
+    pub fn find_with<F>(&self, f: F) -> Option<&V> where F: FnMut(&K) -> Ordering {
         tree_find_with(&self.root, f)
     }
 
@@ -641,7 +641,9 @@ impl<K, V> TreeMap<K, V> {
     /// ```
     #[inline]
     #[experimental = "likely to be renamed, may be removed"]
-    pub fn find_with_mut<'a>(&'a mut self, f:|&K| -> Ordering) -> Option<&'a mut V> {
+    pub fn find_with_mut<'a, F>(&'a mut self, f: F) -> Option<&'a mut V> where
+        F: FnMut(&K) -> Ordering
+    {
         tree_find_with_mut(&mut self.root, f)
     }
 }
@@ -1129,8 +1131,12 @@ fn split<K: Ord, V>(node: &mut Box<TreeNode<K, V>>) {
 // Next 2 functions have the same convention: comparator gets
 // at input current key and returns search_key cmp cur_key
 // (i.e. search_key.cmp(&cur_key))
-fn tree_find_with<'r, K, V>(node: &'r Option<Box<TreeNode<K, V>>>,
-                            f: |&K| -> Ordering) -> Option<&'r V> {
+fn tree_find_with<'r, K, V, F>(
+    node: &'r Option<Box<TreeNode<K, V>>>,
+    mut f: F,
+) -> Option<&'r V> where
+    F: FnMut(&K) -> Ordering,
+{
     let mut current: &'r Option<Box<TreeNode<K, V>>> = node;
     loop {
         match *current {
@@ -1147,8 +1153,12 @@ fn tree_find_with<'r, K, V>(node: &'r Option<Box<TreeNode<K, V>>>,
 }
 
 // See comments above tree_find_with
-fn tree_find_with_mut<'r, K, V>(node: &'r mut Option<Box<TreeNode<K, V>>>,
-                                f: |&K| -> Ordering) -> Option<&'r mut V> {
+fn tree_find_with_mut<'r, K, V, F>(
+    node: &'r mut Option<Box<TreeNode<K, V>>>,
+    mut f: F,
+) -> Option<&'r mut V> where
+    F: FnMut(&K) -> Ordering,
+{
 
     let mut current = node;
     loop {

From 0055678f7a5f49fc5df93a38cc27fea4eb6ae416 Mon Sep 17 00:00:00 2001
From: Jorge Aparicio <japaricious@gmail.com>
Date: Fri, 5 Dec 2014 16:44:03 -0500
Subject: [PATCH 52/92] libcollections: use unboxed closures in `Bitv` methods

---
 src/libcollections/bit.rs | 24 ++++++++++++++++--------
 1 file changed, 16 insertions(+), 8 deletions(-)

diff --git a/src/libcollections/bit.rs b/src/libcollections/bit.rs
index b401978c9c9cd..a0c4f6e7ee8c7 100644
--- a/src/libcollections/bit.rs
+++ b/src/libcollections/bit.rs
@@ -174,7 +174,7 @@ impl<'a> Iterator<(uint, u32)> for MaskWords<'a> {
 
 impl Bitv {
     #[inline]
-    fn process(&mut self, other: &Bitv, op: |u32, u32| -> u32) -> bool {
+    fn process<F>(&mut self, other: &Bitv, mut op: F) -> bool where F: FnMut(u32, u32) -> u32 {
         let len = other.storage.len();
         assert_eq!(self.storage.len(), len);
         let mut changed = false;
@@ -816,7 +816,7 @@ pub fn from_bytes(bytes: &[u8]) -> Bitv {
 /// let bv = from_fn(5, |i| { i % 2 == 0 });
 /// assert!(bv.eq_vec(&[true, false, true, false, true]));
 /// ```
-pub fn from_fn(len: uint, f: |index: uint| -> bool) -> Bitv {
+pub fn from_fn<F>(len: uint, mut f: F) -> Bitv where F: FnMut(uint) -> bool {
     let mut bitv = Bitv::with_capacity(len, false);
     for i in range(0u, len) {
         bitv.set(i, f(i));
@@ -1182,7 +1182,7 @@ impl BitvSet {
     }
 
     #[inline]
-    fn other_op(&mut self, other: &BitvSet, f: |u32, u32| -> u32) {
+    fn other_op<F>(&mut self, other: &BitvSet, mut f: F) where F: FnMut(u32, u32) -> u32 {
         // Expand the vector if necessary
         self.reserve(other.capacity());
 
@@ -1277,10 +1277,12 @@ impl BitvSet {
     #[inline]
     #[unstable = "matches collection reform specification, waiting for dust to settle"]
     pub fn union<'a>(&'a self, other: &'a BitvSet) -> TwoBitPositions<'a> {
+        fn or(w1: u32, w2: u32) -> u32 { w1 | w2 }
+
         TwoBitPositions {
             set: self,
             other: other,
-            merge: |w1, w2| w1 | w2,
+            merge: or,
             current_word: 0u32,
             next_idx: 0u
         }
@@ -1306,11 +1308,13 @@ impl BitvSet {
     #[inline]
     #[unstable = "matches collection reform specification, waiting for dust to settle"]
     pub fn intersection<'a>(&'a self, other: &'a BitvSet) -> Take<TwoBitPositions<'a>> {
+        fn bitand(w1: u32, w2: u32) -> u32 { w1 & w2 }
+
         let min = cmp::min(self.capacity(), other.capacity());
         TwoBitPositions {
             set: self,
             other: other,
-            merge: |w1, w2| w1 & w2,
+            merge: bitand,
             current_word: 0u32,
             next_idx: 0
         }.take(min)
@@ -1343,10 +1347,12 @@ impl BitvSet {
     #[inline]
     #[unstable = "matches collection reform specification, waiting for dust to settle"]
     pub fn difference<'a>(&'a self, other: &'a BitvSet) -> TwoBitPositions<'a> {
+        fn diff(w1: u32, w2: u32) -> u32 { w1 & !w2 }
+
         TwoBitPositions {
             set: self,
             other: other,
-            merge: |w1, w2| w1 & !w2,
+            merge: diff,
             current_word: 0u32,
             next_idx: 0
         }
@@ -1373,10 +1379,12 @@ impl BitvSet {
     #[inline]
     #[unstable = "matches collection reform specification, waiting for dust to settle"]
     pub fn symmetric_difference<'a>(&'a self, other: &'a BitvSet) -> TwoBitPositions<'a> {
+        fn bitxor(w1: u32, w2: u32) -> u32 { w1 ^ w2 }
+
         TwoBitPositions {
             set: self,
             other: other,
-            merge: |w1, w2| w1 ^ w2,
+            merge: bitxor,
             current_word: 0u32,
             next_idx: 0
         }
@@ -1614,7 +1622,7 @@ pub struct BitPositions<'a> {
 pub struct TwoBitPositions<'a> {
     set: &'a BitvSet,
     other: &'a BitvSet,
-    merge: |u32, u32|: 'a -> u32,
+    merge: fn(u32, u32) -> u32,
     current_word: u32,
     next_idx: uint
 }

From d5c332688c83043dffcf14ef8fd6ba3fafdae55e Mon Sep 17 00:00:00 2001
From: Jorge Aparicio <japaricious@gmail.com>
Date: Fri, 5 Dec 2014 16:54:09 -0500
Subject: [PATCH 53/92] libcollections: use unboxed closures in `Vec` methods

---
 src/libcollections/vec.rs | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/src/libcollections/vec.rs b/src/libcollections/vec.rs
index f8a971db173f8..2ed8686394c01 100644
--- a/src/libcollections/vec.rs
+++ b/src/libcollections/vec.rs
@@ -206,7 +206,7 @@ impl<T> Vec<T> {
     #[inline]
     #[unstable = "the naming is uncertain as well as this migrating to unboxed \
                   closures in the future"]
-    pub fn from_fn(length: uint, op: |uint| -> T) -> Vec<T> {
+    pub fn from_fn<F>(length: uint, mut op: F) -> Vec<T> where F: FnMut(uint) -> T {
         unsafe {
             let mut xs = Vec::with_capacity(length);
             while xs.len < length {
@@ -289,7 +289,7 @@ impl<T> Vec<T> {
     /// ```
     #[inline]
     #[experimental]
-    pub fn partition(self, f: |&T| -> bool) -> (Vec<T>, Vec<T>) {
+    pub fn partition<F>(self, mut f: F) -> (Vec<T>, Vec<T>) where F: FnMut(&T) -> bool {
         let mut lefts  = Vec::new();
         let mut rights = Vec::new();
 
@@ -400,7 +400,7 @@ impl<T: Clone> Vec<T> {
     /// assert_eq!(odd, vec![1i, 3]);
     /// ```
     #[experimental]
-    pub fn partitioned(&self, f: |&T| -> bool) -> (Vec<T>, Vec<T>) {
+    pub fn partitioned<F>(&self, mut f: F) -> (Vec<T>, Vec<T>) where F: FnMut(&T) -> bool {
         let mut lefts = Vec::new();
         let mut rights = Vec::new();
 
@@ -991,7 +991,7 @@ impl<T> Vec<T> {
     /// assert_eq!(vec, vec![2, 4]);
     /// ```
     #[unstable = "the closure argument may become an unboxed closure"]
-    pub fn retain(&mut self, f: |&T| -> bool) {
+    pub fn retain<F>(&mut self, mut f: F) where F: FnMut(&T) -> bool {
         let len = self.len();
         let mut del = 0u;
         {
@@ -1023,7 +1023,7 @@ impl<T> Vec<T> {
     /// assert_eq!(vec, vec![0, 1, 0, 1, 2]);
     /// ```
     #[unstable = "this function may be renamed or change to unboxed closures"]
-    pub fn grow_fn(&mut self, n: uint, f: |uint| -> T) {
+    pub fn grow_fn<F>(&mut self, n: uint, mut f: F) where F: FnMut(uint) -> T {
         self.reserve(n);
         for i in range(0u, n) {
             self.push(f(i));
@@ -1570,7 +1570,7 @@ impl<T> Vec<T> {
     /// let newtyped_bytes = bytes.map_in_place(|x| Newtype(x));
     /// assert_eq!(newtyped_bytes.as_slice(), [Newtype(0x11), Newtype(0x22)].as_slice());
     /// ```
-    pub fn map_in_place<U>(self, f: |T| -> U) -> Vec<U> {
+    pub fn map_in_place<U, F>(self, mut f: F) -> Vec<U> where F: FnMut(T) -> U {
         // FIXME: Assert statically that the types `T` and `U` have the same
         // size.
         assert!(mem::size_of::<T>() == mem::size_of::<U>());

From 6f19f8d43051f8c8dff81ed0c82ca2d9026d58a8 Mon Sep 17 00:00:00 2001
From: Jorge Aparicio <japaricious@gmail.com>
Date: Fri, 5 Dec 2014 16:55:16 -0500
Subject: [PATCH 54/92] libcollections: use unboxed closures in `DList` methods

---
 src/libcollections/dlist.rs | 20 +++++++++-----------
 1 file changed, 9 insertions(+), 11 deletions(-)

diff --git a/src/libcollections/dlist.rs b/src/libcollections/dlist.rs
index d50b212c7dd9a..f49a0c037de84 100644
--- a/src/libcollections/dlist.rs
+++ b/src/libcollections/dlist.rs
@@ -351,18 +351,16 @@ impl<T> DList<T> {
     ///     println!("{}", e); // prints 2, then 4, then 11, then 7, then 8
     /// }
     /// ```
-    pub fn insert_when(&mut self, elt: T, f: |&T, &T| -> bool) {
-        {
-            let mut it = self.iter_mut();
-            loop {
-                match it.peek_next() {
-                    None => break,
-                    Some(x) => if f(x, &elt) { break }
-                }
-                it.next();
+    pub fn insert_when<F>(&mut self, elt: T, mut f: F) where F: FnMut(&T, &T) -> bool {
+        let mut it = self.iter_mut();
+        loop {
+            match it.peek_next() {
+                None => break,
+                Some(x) => if f(x, &elt) { break }
             }
-            it.insert_next(elt);
+            it.next();
         }
+        it.insert_next(elt);
     }
 
     /// Merges `other` into this `DList`, using the function `f`.
@@ -371,7 +369,7 @@ impl<T> DList<T> {
     /// put `a` in the result if `f(a, b)` is true, and otherwise `b`.
     ///
     /// This operation should compute in O(max(N, M)) time.
-    pub fn merge(&mut self, mut other: DList<T>, f: |&T, &T| -> bool) {
+    pub fn merge<F>(&mut self, mut other: DList<T>, mut f: F) where F: FnMut(&T, &T) -> bool {
         {
             let mut it = self.iter_mut();
             loop {

From a7a065bd98e9959d09362ca4982c2f7226ddc94b Mon Sep 17 00:00:00 2001
From: Jorge Aparicio <japaricious@gmail.com>
Date: Fri, 5 Dec 2014 16:59:13 -0500
Subject: [PATCH 55/92] libcollections: use unboxed closures in
 `[Clone]SliceAllocPrelude` methods

---
 src/libcollections/slice.rs | 13 +++++++------
 1 file changed, 7 insertions(+), 6 deletions(-)

diff --git a/src/libcollections/slice.rs b/src/libcollections/slice.rs
index 6bdfa490748fa..463e28b420d15 100644
--- a/src/libcollections/slice.rs
+++ b/src/libcollections/slice.rs
@@ -94,6 +94,7 @@ use core::cmp;
 use core::kinds::{Copy, Sized};
 use core::mem::size_of;
 use core::mem;
+use core::ops::FnMut;
 use core::prelude::{Clone, Greater, Iterator, IteratorExt, Less, None, Option};
 use core::prelude::{Ord, Ordering, RawPtr, Some, range};
 use core::ptr;
@@ -296,7 +297,7 @@ pub trait CloneSliceAllocPrelude<T> for Sized? {
 
     /// Partitions the vector into two vectors `(a, b)`, where all
     /// elements of `a` satisfy `f` and all elements of `b` do not.
-    fn partitioned(&self, f: |&T| -> bool) -> (Vec<T>, Vec<T>);
+    fn partitioned<F>(&self, f: F) -> (Vec<T>, Vec<T>) where F: FnMut(&T) -> bool;
 
     /// Creates an iterator that yields every possible permutation of the
     /// vector in succession.
@@ -336,7 +337,7 @@ impl<T: Clone> CloneSliceAllocPrelude<T> for [T] {
 
 
     #[inline]
-    fn partitioned(&self, f: |&T| -> bool) -> (Vec<T>, Vec<T>) {
+    fn partitioned<F>(&self, mut f: F) -> (Vec<T>, Vec<T>) where F: FnMut(&T) -> bool {
         let mut lefts  = Vec::new();
         let mut rights = Vec::new();
 
@@ -361,7 +362,7 @@ impl<T: Clone> CloneSliceAllocPrelude<T> for [T] {
 
 }
 
-fn insertion_sort<T>(v: &mut [T], compare: |&T, &T| -> Ordering) {
+fn insertion_sort<T, F>(v: &mut [T], mut compare: F) where F: FnMut(&T, &T) -> Ordering {
     let len = v.len() as int;
     let buf_v = v.as_mut_ptr();
 
@@ -403,7 +404,7 @@ fn insertion_sort<T>(v: &mut [T], compare: |&T, &T| -> Ordering) {
     }
 }
 
-fn merge_sort<T>(v: &mut [T], compare: |&T, &T| -> Ordering) {
+fn merge_sort<T, F>(v: &mut [T], mut compare: F) where F: FnMut(&T, &T) -> Ordering {
     // warning: this wildly uses unsafe.
     static BASE_INSERTION: uint = 32;
     static LARGE_INSERTION: uint = 16;
@@ -611,7 +612,7 @@ pub trait SliceAllocPrelude<T> for Sized? {
     /// v.sort_by(|a, b| b.cmp(a));
     /// assert!(v == [5, 4, 3, 2, 1]);
     /// ```
-    fn sort_by(&mut self, compare: |&T, &T| -> Ordering);
+    fn sort_by<F>(&mut self, compare: F) where F: FnMut(&T, &T) -> Ordering;
 
     /// Consumes `src` and moves as many elements as it can into `self`
     /// from the range [start,end).
@@ -639,7 +640,7 @@ pub trait SliceAllocPrelude<T> for Sized? {
 
 impl<T> SliceAllocPrelude<T> for [T] {
     #[inline]
-    fn sort_by(&mut self, compare: |&T, &T| -> Ordering) {
+    fn sort_by<F>(&mut self, compare: F) where F: FnMut(&T, &T) -> Ordering {
         merge_sort(self, compare)
     }
 

From 683342c3f0e6cb4142876ad06ba418df2aae1450 Mon Sep 17 00:00:00 2001
From: Jorge Aparicio <japaricious@gmail.com>
Date: Fri, 5 Dec 2014 18:17:24 -0500
Subject: [PATCH 56/92] libgraphviz: fix fallout

---
 src/libgraphviz/lib.rs             | 1 +
 src/libgraphviz/maybe_owned_vec.rs | 2 +-
 2 files changed, 2 insertions(+), 1 deletion(-)

diff --git a/src/libgraphviz/lib.rs b/src/libgraphviz/lib.rs
index c1c397db213f6..2ca0c0e204348 100644
--- a/src/libgraphviz/lib.rs
+++ b/src/libgraphviz/lib.rs
@@ -269,6 +269,7 @@
        html_favicon_url = "http://www.rust-lang.org/favicon.ico",
        html_root_url = "http://doc.rust-lang.org/nightly/")]
 #![feature(globs, slicing_syntax)]
+#![feature(unboxed_closures)]
 
 pub use self::LabelText::*;
 
diff --git a/src/libgraphviz/maybe_owned_vec.rs b/src/libgraphviz/maybe_owned_vec.rs
index 05932db6632ff..7ebf9b6335208 100644
--- a/src/libgraphviz/maybe_owned_vec.rs
+++ b/src/libgraphviz/maybe_owned_vec.rs
@@ -142,7 +142,7 @@ impl<'a,T:Clone> CloneSliceAllocPrelude<T> for MaybeOwnedVector<'a,T> {
         self.as_slice().to_vec()
     }
 
-    fn partitioned(&self, f: |&T| -> bool) -> (Vec<T>, Vec<T>) {
+    fn partitioned<F>(&self, f: F) -> (Vec<T>, Vec<T>) where F: FnMut(&T) -> bool {
         self.as_slice().partitioned(f)
     }
 

From 5579692ce77df5f8227ab7a226145f7cf18ef747 Mon Sep 17 00:00:00 2001
From: Jorge Aparicio <japaricious@gmail.com>
Date: Fri, 5 Dec 2014 17:03:04 -0500
Subject: [PATCH 57/92] libcollections: use unboxed closures in `VecMap`
 methods

---
 src/libcollections/vec_map.rs | 13 ++++++-------
 1 file changed, 6 insertions(+), 7 deletions(-)

diff --git a/src/libcollections/vec_map.rs b/src/libcollections/vec_map.rs
index ce5817e8d9e1a..cc2fd0a664690 100644
--- a/src/libcollections/vec_map.rs
+++ b/src/libcollections/vec_map.rs
@@ -20,6 +20,7 @@ use core::fmt;
 use core::iter;
 use core::iter::{Enumerate, FilterMap};
 use core::mem::replace;
+use core::ops::FnOnce;
 
 use hash::{Hash, Writer};
 use {vec, slice};
@@ -452,8 +453,8 @@ impl<V:Clone> VecMap<V> {
     /// assert!(!map.update(1, vec![3i, 4], |mut old, new| { old.extend(new.into_iter()); old }));
     /// assert_eq!(map[1], vec![1i, 2, 3, 4]);
     /// ```
-    pub fn update(&mut self, key: uint, newval: V, ff: |V, V| -> V) -> bool {
-        self.update_with_key(key, newval, |_k, v, v1| ff(v,v1))
+    pub fn update<F>(&mut self, key: uint, newval: V, ff: F) -> bool where F: FnOnce(V, V) -> V {
+        self.update_with_key(key, newval, move |_k, v, v1| ff(v,v1))
     }
 
     /// Updates a value in the map. If the key already exists in the map,
@@ -476,11 +477,9 @@ impl<V:Clone> VecMap<V> {
     /// assert!(!map.update_with_key(7, 20, |key, old, new| (old + new) % key));
     /// assert_eq!(map[7], 2);
     /// ```
-    pub fn update_with_key(&mut self,
-                           key: uint,
-                           val: V,
-                           ff: |uint, V, V| -> V)
-                           -> bool {
+    pub fn update_with_key<F>(&mut self, key: uint, val: V, ff: F) -> bool where
+        F: FnOnce(uint, V, V) -> V
+    {
         let new_val = match self.get(&key) {
             None => val,
             Some(orig) => ff(key, (*orig).clone(), val)

From c7b6eb38ff14b7225b7ccb86f9a2080fdba4a3e0 Mon Sep 17 00:00:00 2001
From: Jorge Aparicio <japaricious@gmail.com>
Date: Sat, 6 Dec 2014 12:05:38 -0500
Subject: [PATCH 58/92] libcore: use unboxed closures in
 `float_to_str_bytes_common`

---
 src/libcore/fmt/float.rs | 9 ++++++---
 1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/src/libcore/fmt/float.rs b/src/libcore/fmt/float.rs
index 400ce76baa0d2..fb4d91e912a3b 100644
--- a/src/libcore/fmt/float.rs
+++ b/src/libcore/fmt/float.rs
@@ -20,6 +20,7 @@ use fmt;
 use iter::{range, DoubleEndedIteratorExt};
 use num::{Float, FPNaN, FPInfinite, ToPrimitive};
 use num::cast;
+use ops::FnOnce;
 use result::Result::Ok;
 use slice::{mod, SlicePrelude};
 use str::StrPrelude;
@@ -84,7 +85,7 @@ static DIGIT_E_RADIX: uint = ('e' as uint) - ('a' as uint) + 11u;
 ///   between digit and exponent sign `'e'`.
 /// - Panics if `radix` > 25 and `exp_format` is `ExpBin` due to conflict
 ///   between digit and exponent sign `'p'`.
-pub fn float_to_str_bytes_common<T: Float, U>(
+pub fn float_to_str_bytes_common<T: Float, U, F>(
     num: T,
     radix: uint,
     negative_zero: bool,
@@ -92,8 +93,10 @@ pub fn float_to_str_bytes_common<T: Float, U>(
     digits: SignificantDigits,
     exp_format: ExponentFormat,
     exp_upper: bool,
-    f: |&[u8]| -> U
-) -> U {
+    f: F
+) -> U where
+    F: FnOnce(&[u8]) -> U,
+{
     assert!(2 <= radix && radix <= 36);
     match exp_format {
         ExpDec if radix >= DIGIT_E_RADIX       // decimal exponent 'e'

From f56f9728e626886a89be852e642b84be7be36ab8 Mon Sep 17 00:00:00 2001
From: Jorge Aparicio <japaricious@gmail.com>
Date: Sat, 6 Dec 2014 12:11:15 -0500
Subject: [PATCH 59/92] libcore: use unboxed closures in `slice::raw` free
 functions

---
 src/libcore/slice.rs | 15 +++++++--------
 1 file changed, 7 insertions(+), 8 deletions(-)

diff --git a/src/libcore/slice.rs b/src/libcore/slice.rs
index af15099476578..27a4328ba8017 100644
--- a/src/libcore/slice.rs
+++ b/src/libcore/slice.rs
@@ -1725,6 +1725,7 @@ pub mod raw {
     use mem::transmute;
     use ptr::RawPtr;
     use raw::Slice;
+    use ops::FnOnce;
     use option::Option;
     use option::Option::{None, Some};
 
@@ -1732,8 +1733,9 @@ pub mod raw {
     /// not bytes).
     #[inline]
     #[deprecated = "renamed to slice::from_raw_buf"]
-    pub unsafe fn buf_as_slice<T,U>(p: *const T, len: uint, f: |v: &[T]| -> U)
-                               -> U {
+    pub unsafe fn buf_as_slice<T, U, F>(p: *const T, len: uint, f: F) -> U where
+        F: FnOnce(&[T]) -> U,
+    {
         f(transmute(Slice {
             data: p,
             len: len
@@ -1744,12 +1746,9 @@ pub mod raw {
     /// not bytes).
     #[inline]
     #[deprecated = "renamed to slice::from_raw_mut_buf"]
-    pub unsafe fn mut_buf_as_slice<T,
-                                   U>(
-                                   p: *mut T,
-                                   len: uint,
-                                   f: |v: &mut [T]| -> U)
-                                   -> U {
+    pub unsafe fn mut_buf_as_slice<T, U, F>(p: *mut T, len: uint, f: F) -> U where
+        F: FnOnce(&mut [T]) -> U,
+    {
         f(transmute(Slice {
             data: p as *const T,
             len: len

From 04652b57e5b3a635c134fda670b82324ed6053e6 Mon Sep 17 00:00:00 2001
From: Jorge Aparicio <japaricious@gmail.com>
Date: Sat, 6 Dec 2014 12:26:58 -0500
Subject: [PATCH 60/92] libgetopts: use unboxed closures in `each_split_within`

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

diff --git a/src/libgetopts/lib.rs b/src/libgetopts/lib.rs
index a47fab124c3b1..79c435f01e4e6 100644
--- a/src/libgetopts/lib.rs
+++ b/src/libgetopts/lib.rs
@@ -87,6 +87,7 @@
        html_playground_url = "http://play.rust-lang.org/")]
 #![feature(globs, phase)]
 #![feature(import_shadowing)]
+#![feature(unboxed_closures)]
 #![deny(missing_docs)]
 
 #[cfg(test)] #[phase(plugin, link)] extern crate log;
@@ -867,8 +868,9 @@ impl Copy for LengthLimit {}
 ///
 /// Panics during iteration if the string contains a non-whitespace
 /// sequence longer than the limit.
-fn each_split_within<'a>(ss: &'a str, lim: uint, it: |&'a str| -> bool)
-                     -> bool {
+fn each_split_within<F>(ss: &str, lim: uint, mut it: F) -> bool where
+    F: FnMut(&str) -> bool
+{
     // Just for fun, let's write this as a state machine:
 
     let mut slice_start = 0;

From 5d7543b6baf511306ea91ac5f59ae8265ab0b6a3 Mon Sep 17 00:00:00 2001
From: Jorge Aparicio <japaricious@gmail.com>
Date: Sat, 6 Dec 2014 12:28:18 -0500
Subject: [PATCH 61/92] libgraphviz: use unboxed closures in `LabelText`
 methods

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

diff --git a/src/libgraphviz/lib.rs b/src/libgraphviz/lib.rs
index 2ca0c0e204348..8ebb3ae365c07 100644
--- a/src/libgraphviz/lib.rs
+++ b/src/libgraphviz/lib.rs
@@ -421,7 +421,7 @@ pub trait Labeller<'a,N,E> {
 }
 
 impl<'a> LabelText<'a> {
-    fn escape_char(c: char, f: |char|) {
+    fn escape_char<F>(c: char, mut f: F) where F: FnMut(char) {
         match c {
             // not escaping \\, since Graphviz escString needs to
             // interpret backslashes; see EscStr above.

From 533a47bd9bb4aebe61af8d7ff9327af8cffdb583 Mon Sep 17 00:00:00 2001
From: Jorge Aparicio <japaricious@gmail.com>
Date: Sat, 6 Dec 2014 12:30:35 -0500
Subject: [PATCH 62/92] librand: use unboxed closures in `distributions` module

---
 src/librand/distributions/mod.rs | 8 ++++----
 src/librand/lib.rs               | 1 +
 2 files changed, 5 insertions(+), 4 deletions(-)

diff --git a/src/librand/distributions/mod.rs b/src/librand/distributions/mod.rs
index 0fa989bf0b2b9..a44197c98590c 100644
--- a/src/librand/distributions/mod.rs
+++ b/src/librand/distributions/mod.rs
@@ -208,14 +208,14 @@ mod ziggurat_tables;
 // the perf improvement (25-50%) is definitely worth the extra code
 // size from force-inlining.
 #[inline(always)]
-fn ziggurat<R:Rng>(
+fn ziggurat<R: Rng, P, Z>(
             rng: &mut R,
             symmetric: bool,
             x_tab: ziggurat_tables::ZigTable,
             f_tab: ziggurat_tables::ZigTable,
-            pdf: |f64|: 'static -> f64,
-            zero_case: |&mut R, f64|: 'static -> f64)
-            -> f64 {
+            mut pdf: P,
+            mut zero_case: Z)
+            -> f64 where P: FnMut(f64) -> f64, Z: FnMut(&mut R, f64) -> f64 {
     static SCALE: f64 = (1u64 << 53) as f64;
     loop {
         // reimplement the f64 generation as an optimisation suggested
diff --git a/src/librand/lib.rs b/src/librand/lib.rs
index d357f247f1b74..4fba3707703a5 100644
--- a/src/librand/lib.rs
+++ b/src/librand/lib.rs
@@ -24,6 +24,7 @@
        html_playground_url = "http://play.rust-lang.org/")]
 
 #![feature(macro_rules, phase, globs)]
+#![feature(unboxed_closures)]
 #![no_std]
 #![experimental]
 

From a8aff7e95c92bbccd4093ca71e53353912a17024 Mon Sep 17 00:00:00 2001
From: Jorge Aparicio <japaricious@gmail.com>
Date: Sat, 6 Dec 2014 14:30:22 -0500
Subject: [PATCH 63/92] libserialize: use unboxed closures

---
 src/libserialize/json.rs      | 357 +++++++++++++++++++---------------
 src/libserialize/lib.rs       |   1 +
 src/libserialize/serialize.rs | 207 ++++++++++----------
 3 files changed, 304 insertions(+), 261 deletions(-)

diff --git a/src/libserialize/json.rs b/src/libserialize/json.rs
index 7919ac0eff16c..37bd11ba59f45 100644
--- a/src/libserialize/json.rs
+++ b/src/libserialize/json.rs
@@ -458,17 +458,19 @@ impl<'a> ::Encoder<io::IoError> for Encoder<'a> {
         escape_str(self.writer, v)
     }
 
-    fn emit_enum(&mut self,
-                 _name: &str,
-                 f: |&mut Encoder<'a>| -> EncodeResult) -> EncodeResult {
+    fn emit_enum<F>(&mut self, _name: &str, f: F) -> EncodeResult where
+        F: FnOnce(&mut Encoder<'a>) -> EncodeResult,
+    {
         f(self)
     }
 
-    fn emit_enum_variant(&mut self,
-                         name: &str,
-                         _id: uint,
-                         cnt: uint,
-                         f: |&mut Encoder<'a>| -> EncodeResult) -> EncodeResult {
+    fn emit_enum_variant<F>(&mut self,
+                            name: &str,
+                            _id: uint,
+                            cnt: uint,
+                            f: F) -> EncodeResult where
+        F: FnOnce(&mut Encoder<'a>) -> EncodeResult,
+    {
         // enums are encoded as strings or objects
         // Bunny => "Bunny"
         // Kangaroo(34,"William") => {"variant": "Kangaroo", "fields": [34,"William"]}
@@ -483,100 +485,113 @@ impl<'a> ::Encoder<io::IoError> for Encoder<'a> {
         }
     }
 
-    fn emit_enum_variant_arg(&mut self,
-                             idx: uint,
-                             f: |&mut Encoder<'a>| -> EncodeResult) -> EncodeResult {
+    fn emit_enum_variant_arg<F>(&mut self, idx: uint, f: F) -> EncodeResult where
+        F: FnOnce(&mut Encoder<'a>) -> EncodeResult,
+    {
         if idx != 0 {
             try!(write!(self.writer, ","));
         }
         f(self)
     }
 
-    fn emit_enum_struct_variant(&mut self,
-                                name: &str,
-                                id: uint,
-                                cnt: uint,
-                                f: |&mut Encoder<'a>| -> EncodeResult) -> EncodeResult {
+    fn emit_enum_struct_variant<F>(&mut self,
+                                   name: &str,
+                                   id: uint,
+                                   cnt: uint,
+                                   f: F) -> EncodeResult where
+        F: FnOnce(&mut Encoder<'a>) -> EncodeResult,
+    {
         self.emit_enum_variant(name, id, cnt, f)
     }
 
-    fn emit_enum_struct_variant_field(&mut self,
-                                      _: &str,
-                                      idx: uint,
-                                      f: |&mut Encoder<'a>| -> EncodeResult) -> EncodeResult {
+    fn emit_enum_struct_variant_field<F>(&mut self,
+                                         _: &str,
+                                         idx: uint,
+                                         f: F) -> EncodeResult where
+        F: FnOnce(&mut Encoder<'a>) -> EncodeResult,
+    {
         self.emit_enum_variant_arg(idx, f)
     }
 
-    fn emit_struct(&mut self,
-                   _: &str,
-                   _: uint,
-                   f: |&mut Encoder<'a>| -> EncodeResult) -> EncodeResult {
+    fn emit_struct<F>(&mut self, _: &str, _: uint, f: F) -> EncodeResult where
+        F: FnOnce(&mut Encoder<'a>) -> EncodeResult,
+    {
         try!(write!(self.writer, "{{"));
         try!(f(self));
         write!(self.writer, "}}")
     }
 
-    fn emit_struct_field(&mut self,
-                         name: &str,
-                         idx: uint,
-                         f: |&mut Encoder<'a>| -> EncodeResult) -> EncodeResult {
+    fn emit_struct_field<F>(&mut self, name: &str, idx: uint, f: F) -> EncodeResult where
+        F: FnOnce(&mut Encoder<'a>) -> EncodeResult,
+    {
         if idx != 0 { try!(write!(self.writer, ",")); }
         try!(escape_str(self.writer, name));
         try!(write!(self.writer, ":"));
         f(self)
     }
 
-    fn emit_tuple(&mut self, len: uint, f: |&mut Encoder<'a>| -> EncodeResult) -> EncodeResult {
+    fn emit_tuple<F>(&mut self, len: uint, f: F) -> EncodeResult where
+        F: FnOnce(&mut Encoder<'a>) -> EncodeResult,
+    {
         self.emit_seq(len, f)
     }
-    fn emit_tuple_arg(&mut self,
-                      idx: uint,
-                      f: |&mut Encoder<'a>| -> EncodeResult) -> EncodeResult {
+    fn emit_tuple_arg<F>(&mut self, idx: uint, f: F) -> EncodeResult where
+        F: FnOnce(&mut Encoder<'a>) -> EncodeResult,
+    {
         self.emit_seq_elt(idx, f)
     }
 
-    fn emit_tuple_struct(&mut self,
-                         _name: &str,
-                         len: uint,
-                         f: |&mut Encoder<'a>| -> EncodeResult) -> EncodeResult {
+    fn emit_tuple_struct<F>(&mut self, _name: &str, len: uint, f: F) -> EncodeResult where
+        F: FnOnce(&mut Encoder<'a>) -> EncodeResult,
+    {
         self.emit_seq(len, f)
     }
-    fn emit_tuple_struct_arg(&mut self,
-                             idx: uint,
-                             f: |&mut Encoder<'a>| -> EncodeResult) -> EncodeResult {
+    fn emit_tuple_struct_arg<F>(&mut self, idx: uint, f: F) -> EncodeResult where
+        F: FnOnce(&mut Encoder<'a>) -> EncodeResult,
+    {
         self.emit_seq_elt(idx, f)
     }
 
-    fn emit_option(&mut self, f: |&mut Encoder<'a>| -> EncodeResult) -> EncodeResult {
+    fn emit_option<F>(&mut self, f: F) -> EncodeResult where
+        F: FnOnce(&mut Encoder<'a>) -> EncodeResult,
+    {
         f(self)
     }
     fn emit_option_none(&mut self) -> EncodeResult { self.emit_nil() }
-    fn emit_option_some(&mut self, f: |&mut Encoder<'a>| -> EncodeResult) -> EncodeResult {
+    fn emit_option_some<F>(&mut self, f: F) -> EncodeResult where
+        F: FnOnce(&mut Encoder<'a>) -> EncodeResult,
+    {
         f(self)
     }
 
-    fn emit_seq(&mut self, _len: uint, f: |&mut Encoder<'a>| -> EncodeResult) -> EncodeResult {
+    fn emit_seq<F>(&mut self, _len: uint, f: F) -> EncodeResult where
+        F: FnOnce(&mut Encoder<'a>) -> EncodeResult,
+    {
         try!(write!(self.writer, "["));
         try!(f(self));
         write!(self.writer, "]")
     }
 
-    fn emit_seq_elt(&mut self, idx: uint, f: |&mut Encoder<'a>| -> EncodeResult) -> EncodeResult {
+    fn emit_seq_elt<F>(&mut self, idx: uint, f: F) -> EncodeResult where
+        F: FnOnce(&mut Encoder<'a>) -> EncodeResult,
+    {
         if idx != 0 {
             try!(write!(self.writer, ","));
         }
         f(self)
     }
 
-    fn emit_map(&mut self, _len: uint, f: |&mut Encoder<'a>| -> EncodeResult) -> EncodeResult {
+    fn emit_map<F>(&mut self, _len: uint, f: F) -> EncodeResult where
+        F: FnOnce(&mut Encoder<'a>) -> EncodeResult,
+    {
         try!(write!(self.writer, "{{"));
         try!(f(self));
         write!(self.writer, "}}")
     }
 
-    fn emit_map_elt_key(&mut self,
-                        idx: uint,
-                        f: |&mut Encoder<'a>| -> EncodeResult) -> EncodeResult {
+    fn emit_map_elt_key<F>(&mut self, idx: uint, mut f: F) -> EncodeResult where
+        F: FnMut(&mut Encoder<'a>) -> EncodeResult,
+    {
         if idx != 0 { try!(write!(self.writer, ",")) }
         // ref #12967, make sure to wrap a key in double quotes,
         // in the event that its of a type that omits them (eg numbers)
@@ -594,9 +609,9 @@ impl<'a> ::Encoder<io::IoError> for Encoder<'a> {
         Ok(())
     }
 
-    fn emit_map_elt_val(&mut self,
-                        _idx: uint,
-                        f: |&mut Encoder<'a>| -> EncodeResult) -> EncodeResult {
+    fn emit_map_elt_val<F>(&mut self, _idx: uint, f: F) -> EncodeResult where
+        F: FnOnce(&mut Encoder<'a>) -> EncodeResult,
+    {
         try!(write!(self.writer, ":"));
         f(self)
     }
@@ -663,17 +678,20 @@ impl<'a> ::Encoder<io::IoError> for PrettyEncoder<'a> {
         escape_str(self.writer, v)
     }
 
-    fn emit_enum(&mut self,
-                 _name: &str,
-                 f: |&mut PrettyEncoder<'a>| -> EncodeResult) -> EncodeResult {
+    fn emit_enum<F>(&mut self, _name: &str, f: F) -> EncodeResult where
+        F: FnOnce(&mut PrettyEncoder<'a>) -> EncodeResult,
+    {
         f(self)
     }
 
-    fn emit_enum_variant(&mut self,
-                         name: &str,
-                         _id: uint,
-                         cnt: uint,
-                         f: |&mut PrettyEncoder<'a>| -> EncodeResult) -> EncodeResult {
+    fn emit_enum_variant<F>(&mut self,
+                            name: &str,
+                            _id: uint,
+                            cnt: uint,
+                            f: F)
+                            -> EncodeResult where
+        F: FnOnce(&mut PrettyEncoder<'a>) -> EncodeResult,
+    {
         if cnt == 0 {
             escape_str(self.writer, name)
         } else {
@@ -697,9 +715,9 @@ impl<'a> ::Encoder<io::IoError> for PrettyEncoder<'a> {
         }
     }
 
-    fn emit_enum_variant_arg(&mut self,
-                             idx: uint,
-                             f: |&mut PrettyEncoder<'a>| -> EncodeResult) -> EncodeResult {
+    fn emit_enum_variant_arg<F>(&mut self, idx: uint, f: F) -> EncodeResult where
+        F: FnOnce(&mut PrettyEncoder<'a>) -> EncodeResult,
+    {
         if idx != 0 {
             try!(write!(self.writer, ",\n"));
         }
@@ -707,26 +725,29 @@ impl<'a> ::Encoder<io::IoError> for PrettyEncoder<'a> {
         f(self)
     }
 
-    fn emit_enum_struct_variant(&mut self,
-                                name: &str,
-                                id: uint,
-                                cnt: uint,
-                                f: |&mut PrettyEncoder<'a>| -> EncodeResult) -> EncodeResult {
+    fn emit_enum_struct_variant<F>(&mut self,
+                                   name: &str,
+                                   id: uint,
+                                   cnt: uint,
+                                   f: F) -> EncodeResult where
+        F: FnOnce(&mut PrettyEncoder<'a>) -> EncodeResult,
+    {
         self.emit_enum_variant(name, id, cnt, f)
     }
 
-    fn emit_enum_struct_variant_field(&mut self,
-                                      _: &str,
-                                      idx: uint,
-                                      f: |&mut PrettyEncoder<'a>| -> EncodeResult) -> EncodeResult {
+    fn emit_enum_struct_variant_field<F>(&mut self,
+                                         _: &str,
+                                         idx: uint,
+                                         f: F) -> EncodeResult where
+        F: FnOnce(&mut PrettyEncoder<'a>) -> EncodeResult,
+    {
         self.emit_enum_variant_arg(idx, f)
     }
 
 
-    fn emit_struct(&mut self,
-                   _: &str,
-                   len: uint,
-                   f: |&mut PrettyEncoder<'a>| -> EncodeResult) -> EncodeResult {
+    fn emit_struct<F>(&mut self, _: &str, len: uint, f: F) -> EncodeResult where
+        F: FnOnce(&mut PrettyEncoder<'a>) -> EncodeResult,
+    {
         if len == 0 {
             write!(self.writer, "{{}}")
         } else {
@@ -740,10 +761,9 @@ impl<'a> ::Encoder<io::IoError> for PrettyEncoder<'a> {
         }
     }
 
-    fn emit_struct_field(&mut self,
-                         name: &str,
-                         idx: uint,
-                         f: |&mut PrettyEncoder<'a>| -> EncodeResult) -> EncodeResult {
+    fn emit_struct_field<F>(&mut self, name: &str, idx: uint, f: F) -> EncodeResult where
+        F: FnOnce(&mut PrettyEncoder<'a>) -> EncodeResult,
+    {
         if idx == 0 {
             try!(write!(self.writer, "\n"));
         } else {
@@ -755,40 +775,43 @@ impl<'a> ::Encoder<io::IoError> for PrettyEncoder<'a> {
         f(self)
     }
 
-    fn emit_tuple(&mut self,
-                  len: uint,
-                  f: |&mut PrettyEncoder<'a>| -> EncodeResult) -> EncodeResult {
+    fn emit_tuple<F>(&mut self, len: uint, f: F) -> EncodeResult where
+        F: FnOnce(&mut PrettyEncoder<'a>) -> EncodeResult,
+    {
         self.emit_seq(len, f)
     }
-    fn emit_tuple_arg(&mut self,
-                      idx: uint,
-                      f: |&mut PrettyEncoder<'a>| -> EncodeResult) -> EncodeResult {
+    fn emit_tuple_arg<F>(&mut self, idx: uint, f: F) -> EncodeResult where
+        F: FnOnce(&mut PrettyEncoder<'a>) -> EncodeResult,
+    {
         self.emit_seq_elt(idx, f)
     }
 
-    fn emit_tuple_struct(&mut self,
-                         _: &str,
-                         len: uint,
-                         f: |&mut PrettyEncoder<'a>| -> EncodeResult) -> EncodeResult {
+    fn emit_tuple_struct<F>(&mut self, _: &str, len: uint, f: F) -> EncodeResult where
+        F: FnOnce(&mut PrettyEncoder<'a>) -> EncodeResult,
+    {
         self.emit_seq(len, f)
     }
-    fn emit_tuple_struct_arg(&mut self,
-                             idx: uint,
-                             f: |&mut PrettyEncoder<'a>| -> EncodeResult) -> EncodeResult {
+    fn emit_tuple_struct_arg<F>(&mut self, idx: uint, f: F) -> EncodeResult where
+        F: FnOnce(&mut PrettyEncoder<'a>) -> EncodeResult,
+    {
         self.emit_seq_elt(idx, f)
     }
 
-    fn emit_option(&mut self, f: |&mut PrettyEncoder<'a>| -> EncodeResult) -> EncodeResult {
+    fn emit_option<F>(&mut self, f: F) -> EncodeResult where
+        F: FnOnce(&mut PrettyEncoder<'a>) -> EncodeResult,
+    {
         f(self)
     }
     fn emit_option_none(&mut self) -> EncodeResult { self.emit_nil() }
-    fn emit_option_some(&mut self, f: |&mut PrettyEncoder<'a>| -> EncodeResult) -> EncodeResult {
+    fn emit_option_some<F>(&mut self, f: F) -> EncodeResult where
+        F: FnOnce(&mut PrettyEncoder<'a>) -> EncodeResult,
+    {
         f(self)
     }
 
-    fn emit_seq(&mut self,
-                len: uint,
-                f: |&mut PrettyEncoder<'a>| -> EncodeResult) -> EncodeResult {
+    fn emit_seq<F>(&mut self, len: uint, f: F) -> EncodeResult where
+        F: FnOnce(&mut PrettyEncoder<'a>) -> EncodeResult,
+    {
         if len == 0 {
             write!(self.writer, "[]")
         } else {
@@ -802,9 +825,9 @@ impl<'a> ::Encoder<io::IoError> for PrettyEncoder<'a> {
         }
     }
 
-    fn emit_seq_elt(&mut self,
-                    idx: uint,
-                    f: |&mut PrettyEncoder<'a>| -> EncodeResult) -> EncodeResult {
+    fn emit_seq_elt<F>(&mut self, idx: uint, f: F) -> EncodeResult where
+        F: FnOnce(&mut PrettyEncoder<'a>) -> EncodeResult,
+    {
         if idx == 0 {
             try!(write!(self.writer, "\n"));
         } else {
@@ -814,9 +837,9 @@ impl<'a> ::Encoder<io::IoError> for PrettyEncoder<'a> {
         f(self)
     }
 
-    fn emit_map(&mut self,
-                len: uint,
-                f: |&mut PrettyEncoder<'a>| -> EncodeResult) -> EncodeResult {
+    fn emit_map<F>(&mut self, len: uint, f: F) -> EncodeResult where
+        F: FnOnce(&mut PrettyEncoder<'a>) -> EncodeResult,
+    {
         if len == 0 {
             write!(self.writer, "{{}}")
         } else {
@@ -830,9 +853,9 @@ impl<'a> ::Encoder<io::IoError> for PrettyEncoder<'a> {
         }
     }
 
-    fn emit_map_elt_key(&mut self,
-                        idx: uint,
-                        f: |&mut PrettyEncoder<'a>| -> EncodeResult) -> EncodeResult {
+    fn emit_map_elt_key<F>(&mut self, idx: uint, mut f: F) -> EncodeResult where
+        F: FnMut(&mut PrettyEncoder<'a>) -> EncodeResult,
+    {
         if idx == 0 {
             try!(write!(self.writer, "\n"));
         } else {
@@ -855,9 +878,9 @@ impl<'a> ::Encoder<io::IoError> for PrettyEncoder<'a> {
         Ok(())
     }
 
-    fn emit_map_elt_val(&mut self,
-                        _idx: uint,
-                        f: |&mut PrettyEncoder<'a>| -> EncodeResult) -> EncodeResult {
+    fn emit_map_elt_val<F>(&mut self, _idx: uint, f: F) -> EncodeResult where
+        F: FnOnce(&mut PrettyEncoder<'a>) -> EncodeResult,
+    {
         try!(write!(self.writer, ": "));
         f(self)
     }
@@ -2052,17 +2075,16 @@ impl ::Decoder<DecoderError> for Decoder {
         expect!(self.pop(), String)
     }
 
-    fn read_enum<T>(&mut self,
-                    name: &str,
-                    f: |&mut Decoder| -> DecodeResult<T>) -> DecodeResult<T> {
+    fn read_enum<T, F>(&mut self, name: &str, f: F) -> DecodeResult<T> where
+        F: FnOnce(&mut Decoder) -> DecodeResult<T>,
+    {
         debug!("read_enum({})", name);
         f(self)
     }
 
-    fn read_enum_variant<T>(&mut self,
-                            names: &[&str],
-                            f: |&mut Decoder, uint| -> DecodeResult<T>)
-                            -> DecodeResult<T> {
+    fn read_enum_variant<T, F>(&mut self, names: &[&str], f: F) -> DecodeResult<T> where
+        F: FnOnce(&mut Decoder, uint) -> DecodeResult<T>,
+    {
         debug!("read_enum_variant(names={})", names);
         let name = match self.pop() {
             Json::String(s) => s,
@@ -2103,46 +2125,48 @@ impl ::Decoder<DecoderError> for Decoder {
         f(self, idx)
     }
 
-    fn read_enum_variant_arg<T>(&mut self, idx: uint, f: |&mut Decoder| -> DecodeResult<T>)
-                                -> DecodeResult<T> {
+    fn read_enum_variant_arg<T, F>(&mut self, idx: uint, f: F) -> DecodeResult<T> where
+        F: FnOnce(&mut Decoder) -> DecodeResult<T>,
+    {
         debug!("read_enum_variant_arg(idx={})", idx);
         f(self)
     }
 
-    fn read_enum_struct_variant<T>(&mut self,
-                                   names: &[&str],
-                                   f: |&mut Decoder, uint| -> DecodeResult<T>)
-                                   -> DecodeResult<T> {
+    fn read_enum_struct_variant<T, F>(&mut self, names: &[&str], f: F) -> DecodeResult<T> where
+        F: FnOnce(&mut Decoder, uint) -> DecodeResult<T>,
+    {
         debug!("read_enum_struct_variant(names={})", names);
         self.read_enum_variant(names, f)
     }
 
 
-    fn read_enum_struct_variant_field<T>(&mut self,
+    fn read_enum_struct_variant_field<T, F>(&mut self,
                                          name: &str,
                                          idx: uint,
-                                         f: |&mut Decoder| -> DecodeResult<T>)
-                                         -> DecodeResult<T> {
+                                         f: F)
+                                         -> DecodeResult<T> where
+        F: FnOnce(&mut Decoder) -> DecodeResult<T>,
+    {
         debug!("read_enum_struct_variant_field(name={}, idx={})", name, idx);
         self.read_enum_variant_arg(idx, f)
     }
 
-    fn read_struct<T>(&mut self,
-                      name: &str,
-                      len: uint,
-                      f: |&mut Decoder| -> DecodeResult<T>)
-                      -> DecodeResult<T> {
+    fn read_struct<T, F>(&mut self, name: &str, len: uint, f: F) -> DecodeResult<T> where
+        F: FnOnce(&mut Decoder) -> DecodeResult<T>,
+    {
         debug!("read_struct(name={}, len={})", name, len);
         let value = try!(f(self));
         self.pop();
         Ok(value)
     }
 
-    fn read_struct_field<T>(&mut self,
-                            name: &str,
-                            idx: uint,
-                            f: |&mut Decoder| -> DecodeResult<T>)
-                            -> DecodeResult<T> {
+    fn read_struct_field<T, F>(&mut self,
+                               name: &str,
+                               idx: uint,
+                               f: F)
+                               -> DecodeResult<T> where
+        F: FnOnce(&mut Decoder) -> DecodeResult<T>,
+    {
         debug!("read_struct_field(name={}, idx={})", name, idx);
         let mut obj = try!(expect!(self.pop(), Object));
 
@@ -2165,12 +2189,11 @@ impl ::Decoder<DecoderError> for Decoder {
         Ok(value)
     }
 
-    fn read_tuple<T>(&mut self,
-                     tuple_len: uint,
-                     f: |&mut Decoder| -> DecodeResult<T>)
-                     -> DecodeResult<T> {
+    fn read_tuple<T, F>(&mut self, tuple_len: uint, f: F) -> DecodeResult<T> where
+        F: FnOnce(&mut Decoder) -> DecodeResult<T>,
+    {
         debug!("read_tuple()");
-        self.read_seq(|d, len| {
+        self.read_seq(move |d, len| {
             if len == tuple_len {
                 f(d)
             } else {
@@ -2179,31 +2202,37 @@ impl ::Decoder<DecoderError> for Decoder {
         })
     }
 
-    fn read_tuple_arg<T>(&mut self,
-                         idx: uint,
-                         f: |&mut Decoder| -> DecodeResult<T>) -> DecodeResult<T> {
+    fn read_tuple_arg<T, F>(&mut self, idx: uint, f: F) -> DecodeResult<T> where
+        F: FnOnce(&mut Decoder) -> DecodeResult<T>,
+    {
         debug!("read_tuple_arg(idx={})", idx);
         self.read_seq_elt(idx, f)
     }
 
-    fn read_tuple_struct<T>(&mut self,
-                            name: &str,
-                            len: uint,
-                            f: |&mut Decoder| -> DecodeResult<T>)
-                            -> DecodeResult<T> {
+    fn read_tuple_struct<T, F>(&mut self,
+                               name: &str,
+                               len: uint,
+                               f: F)
+                               -> DecodeResult<T> where
+        F: FnOnce(&mut Decoder) -> DecodeResult<T>,
+    {
         debug!("read_tuple_struct(name={})", name);
         self.read_tuple(len, f)
     }
 
-    fn read_tuple_struct_arg<T>(&mut self,
-                                idx: uint,
-                                f: |&mut Decoder| -> DecodeResult<T>)
-                                -> DecodeResult<T> {
+    fn read_tuple_struct_arg<T, F>(&mut self,
+                                   idx: uint,
+                                   f: F)
+                                   -> DecodeResult<T> where
+        F: FnOnce(&mut Decoder) -> DecodeResult<T>,
+    {
         debug!("read_tuple_struct_arg(idx={})", idx);
         self.read_tuple_arg(idx, f)
     }
 
-    fn read_option<T>(&mut self, f: |&mut Decoder, bool| -> DecodeResult<T>) -> DecodeResult<T> {
+    fn read_option<T, F>(&mut self, f: F) -> DecodeResult<T> where
+        F: FnOnce(&mut Decoder, bool) -> DecodeResult<T>,
+    {
         debug!("read_option()");
         match self.pop() {
             Json::Null => f(self, false),
@@ -2211,7 +2240,9 @@ impl ::Decoder<DecoderError> for Decoder {
         }
     }
 
-    fn read_seq<T>(&mut self, f: |&mut Decoder, uint| -> DecodeResult<T>) -> DecodeResult<T> {
+    fn read_seq<T, F>(&mut self, f: F) -> DecodeResult<T> where
+        F: FnOnce(&mut Decoder, uint) -> DecodeResult<T>,
+    {
         debug!("read_seq()");
         let array = try!(expect!(self.pop(), Array));
         let len = array.len();
@@ -2221,14 +2252,16 @@ impl ::Decoder<DecoderError> for Decoder {
         f(self, len)
     }
 
-    fn read_seq_elt<T>(&mut self,
-                       idx: uint,
-                       f: |&mut Decoder| -> DecodeResult<T>) -> DecodeResult<T> {
+    fn read_seq_elt<T, F>(&mut self, idx: uint, f: F) -> DecodeResult<T> where
+        F: FnOnce(&mut Decoder) -> DecodeResult<T>,
+    {
         debug!("read_seq_elt(idx={})", idx);
         f(self)
     }
 
-    fn read_map<T>(&mut self, f: |&mut Decoder, uint| -> DecodeResult<T>) -> DecodeResult<T> {
+    fn read_map<T, F>(&mut self, f: F) -> DecodeResult<T> where
+        F: FnOnce(&mut Decoder, uint) -> DecodeResult<T>,
+    {
         debug!("read_map()");
         let obj = try!(expect!(self.pop(), Object));
         let len = obj.len();
@@ -2239,14 +2272,16 @@ impl ::Decoder<DecoderError> for Decoder {
         f(self, len)
     }
 
-    fn read_map_elt_key<T>(&mut self, idx: uint, f: |&mut Decoder| -> DecodeResult<T>)
-                           -> DecodeResult<T> {
+    fn read_map_elt_key<T, F>(&mut self, idx: uint, f: F) -> DecodeResult<T> where
+       F: FnOnce(&mut Decoder) -> DecodeResult<T>,
+    {
         debug!("read_map_elt_key(idx={})", idx);
         f(self)
     }
 
-    fn read_map_elt_val<T>(&mut self, idx: uint, f: |&mut Decoder| -> DecodeResult<T>)
-                           -> DecodeResult<T> {
+    fn read_map_elt_val<T, F>(&mut self, idx: uint, f: F) -> DecodeResult<T> where
+       F: FnOnce(&mut Decoder) -> DecodeResult<T>,
+    {
         debug!("read_map_elt_val(idx={})", idx);
         f(self)
     }
diff --git a/src/libserialize/lib.rs b/src/libserialize/lib.rs
index 9711d5c7209be..390b3976562ff 100644
--- a/src/libserialize/lib.rs
+++ b/src/libserialize/lib.rs
@@ -24,6 +24,7 @@ Core encoding and decoding interfaces.
        html_playground_url = "http://play.rust-lang.org/")]
 #![allow(unknown_features)]
 #![feature(macro_rules, default_type_params, phase, slicing_syntax, globs)]
+#![feature(unboxed_closures)]
 
 // test harness access
 #[cfg(test)]
diff --git a/src/libserialize/serialize.rs b/src/libserialize/serialize.rs
index 7539a6dc3486b..98bd2f6bc930f 100644
--- a/src/libserialize/serialize.rs
+++ b/src/libserialize/serialize.rs
@@ -39,58 +39,61 @@ pub trait Encoder<E> {
     fn emit_str(&mut self, v: &str) -> Result<(), E>;
 
     // Compound types:
-    fn emit_enum(&mut self, name: &str, f: |&mut Self| -> Result<(), E>) -> Result<(), E>;
-
-    fn emit_enum_variant(&mut self,
-                         v_name: &str,
-                         v_id: uint,
-                         len: uint,
-                         f: |&mut Self| -> Result<(), E>) -> Result<(), E>;
-    fn emit_enum_variant_arg(&mut self,
-                             a_idx: uint,
-                             f: |&mut Self| -> Result<(), E>) -> Result<(), E>;
-
-    fn emit_enum_struct_variant(&mut self,
-                                v_name: &str,
-                                v_id: uint,
-                                len: uint,
-                                f: |&mut Self| -> Result<(), E>) -> Result<(), E>;
-    fn emit_enum_struct_variant_field(&mut self,
-                                      f_name: &str,
-                                      f_idx: uint,
-                                      f: |&mut Self| -> Result<(), E>) -> Result<(), E>;
-
-    fn emit_struct(&mut self,
-                   name: &str,
-                   len: uint,
-                   f: |&mut Self| -> Result<(), E>) -> Result<(), E>;
-    fn emit_struct_field(&mut self,
-                         f_name: &str,
-                         f_idx: uint,
-                         f: |&mut Self| -> Result<(), E>) -> Result<(), E>;
-
-    fn emit_tuple(&mut self, len: uint, f: |&mut Self| -> Result<(), E>) -> Result<(), E>;
-    fn emit_tuple_arg(&mut self, idx: uint, f: |&mut Self| -> Result<(), E>) -> Result<(), E>;
-
-    fn emit_tuple_struct(&mut self,
-                         name: &str,
-                         len: uint,
-                         f: |&mut Self| -> Result<(), E>) -> Result<(), E>;
-    fn emit_tuple_struct_arg(&mut self,
-                             f_idx: uint,
-                             f: |&mut Self| -> Result<(), E>) -> Result<(), E>;
+    fn emit_enum<F>(&mut self, name: &str, f: F) -> Result<(), E> where
+        F: FnOnce(&mut Self) -> Result<(), E>;
+
+    fn emit_enum_variant<F>(&mut self, v_name: &str,
+                            v_id: uint,
+                            len: uint,
+                            f: F) -> Result<(), E> where
+        F: FnOnce(&mut Self) -> Result<(), E>;
+    fn emit_enum_variant_arg<F>(&mut self, a_idx: uint, f: F) -> Result<(), E> where
+        F: FnOnce(&mut Self) -> Result<(), E>;
+
+    fn emit_enum_struct_variant<F>(&mut self, v_name: &str,
+                                   v_id: uint,
+                                   len: uint,
+                                   f: F) -> Result<(), E> where
+        F: FnOnce(&mut Self) -> Result<(), E>;
+    fn emit_enum_struct_variant_field<F>(&mut self,
+                                         f_name: &str,
+                                         f_idx: uint,
+                                         f: F) -> Result<(), E> where
+        F: FnOnce(&mut Self) -> Result<(), E>;
+
+    fn emit_struct<F>(&mut self, name: &str, len: uint, f: F) -> Result<(), E> where
+        F: FnOnce(&mut Self) -> Result<(), E>;
+    fn emit_struct_field<F>(&mut self, f_name: &str, f_idx: uint, f: F) -> Result<(), E> where
+        F: FnOnce(&mut Self) -> Result<(), E>;
+
+    fn emit_tuple<F>(&mut self, len: uint, f: F) -> Result<(), E> where
+        F: FnOnce(&mut Self) -> Result<(), E>;
+    fn emit_tuple_arg<F>(&mut self, idx: uint, f: F) -> Result<(), E> where
+        F: FnOnce(&mut Self) -> Result<(), E>;
+
+    fn emit_tuple_struct<F>(&mut self, name: &str, len: uint, f: F) -> Result<(), E> where
+        F: FnOnce(&mut Self) -> Result<(), E>;
+    fn emit_tuple_struct_arg<F>(&mut self, f_idx: uint, f: F) -> Result<(), E> where
+        F: FnOnce(&mut Self) -> Result<(), E>;
 
     // Specialized types:
-    fn emit_option(&mut self, f: |&mut Self| -> Result<(), E>) -> Result<(), E>;
+    fn emit_option<F>(&mut self, f: F) -> Result<(), E> where
+        F: FnOnce(&mut Self) -> Result<(), E>;
     fn emit_option_none(&mut self) -> Result<(), E>;
-    fn emit_option_some(&mut self, f: |&mut Self| -> Result<(), E>) -> Result<(), E>;
+    fn emit_option_some<F>(&mut self, f: F) -> Result<(), E> where
+        F: FnOnce(&mut Self) -> Result<(), E>;
 
-    fn emit_seq(&mut self, len: uint, f: |this: &mut Self| -> Result<(), E>) -> Result<(), E>;
-    fn emit_seq_elt(&mut self, idx: uint, f: |this: &mut Self| -> Result<(), E>) -> Result<(), E>;
+    fn emit_seq<F>(&mut self, len: uint, f: F) -> Result<(), E> where
+        F: FnOnce(&mut Self) -> Result<(), E>;
+    fn emit_seq_elt<F>(&mut self, idx: uint, f: F) -> Result<(), E> where
+        F: FnOnce(&mut Self) -> Result<(), E>;
 
-    fn emit_map(&mut self, len: uint, f: |&mut Self| -> Result<(), E>) -> Result<(), E>;
-    fn emit_map_elt_key(&mut self, idx: uint, f: |&mut Self| -> Result<(), E>) -> Result<(), E>;
-    fn emit_map_elt_val(&mut self, idx: uint, f: |&mut Self| -> Result<(), E>) -> Result<(), E>;
+    fn emit_map<F>(&mut self, len: uint, f: F) -> Result<(), E> where
+        F: FnOnce(&mut Self) -> Result<(), E>;
+    fn emit_map_elt_key<F>(&mut self, idx: uint, f: F) -> Result<(), E> where
+        F: FnMut(&mut Self) -> Result<(), E>;
+    fn emit_map_elt_val<F>(&mut self, idx: uint, f: F) -> Result<(), E> where
+        F: FnOnce(&mut Self) -> Result<(), E>;
 }
 
 pub trait Decoder<E> {
@@ -113,57 +116,57 @@ pub trait Decoder<E> {
     fn read_str(&mut self) -> Result<String, E>;
 
     // Compound types:
-    fn read_enum<T>(&mut self, name: &str, f: |&mut Self| -> Result<T, E>) -> Result<T, E>;
-
-    fn read_enum_variant<T>(&mut self,
-                            names: &[&str],
-                            f: |&mut Self, uint| -> Result<T, E>)
-                            -> Result<T, E>;
-    fn read_enum_variant_arg<T>(&mut self,
-                                a_idx: uint,
-                                f: |&mut Self| -> Result<T, E>)
-                                -> Result<T, E>;
-
-    fn read_enum_struct_variant<T>(&mut self,
-                                   names: &[&str],
-                                   f: |&mut Self, uint| -> Result<T, E>)
-                                   -> Result<T, E>;
-    fn read_enum_struct_variant_field<T>(&mut self,
-                                         &f_name: &str,
-                                         f_idx: uint,
-                                         f: |&mut Self| -> Result<T, E>)
-                                         -> Result<T, E>;
-
-    fn read_struct<T>(&mut self, s_name: &str, len: uint, f: |&mut Self| -> Result<T, E>)
-                      -> Result<T, E>;
-    fn read_struct_field<T>(&mut self,
-                            f_name: &str,
-                            f_idx: uint,
-                            f: |&mut Self| -> Result<T, E>)
-                            -> Result<T, E>;
-
-    fn read_tuple<T>(&mut self, len: uint, f: |&mut Self| -> Result<T, E>) -> Result<T, E>;
-    fn read_tuple_arg<T>(&mut self, a_idx: uint, f: |&mut Self| -> Result<T, E>) -> Result<T, E>;
-
-    fn read_tuple_struct<T>(&mut self,
-                            s_name: &str,
-                            len: uint,
-                            f: |&mut Self| -> Result<T, E>)
-                            -> Result<T, E>;
-    fn read_tuple_struct_arg<T>(&mut self,
-                                a_idx: uint,
-                                f: |&mut Self| -> Result<T, E>)
-                                -> Result<T, E>;
+    fn read_enum<T, F>(&mut self, name: &str, f: F) -> Result<T, E> where
+        F: FnOnce(&mut Self) -> Result<T, E>;
+
+    fn read_enum_variant<T, F>(&mut self, names: &[&str], f: F) -> Result<T, E> where
+        F: FnOnce(&mut Self, uint) -> Result<T, E>;
+    fn read_enum_variant_arg<T, F>(&mut self, a_idx: uint, f: F) -> Result<T, E> where
+        F: FnOnce(&mut Self) -> Result<T, E>;
+
+    fn read_enum_struct_variant<T, F>(&mut self, names: &[&str], f: F) -> Result<T, E> where
+        F: FnOnce(&mut Self, uint) -> Result<T, E>;
+    fn read_enum_struct_variant_field<T, F>(&mut self,
+                                            &f_name: &str,
+                                            f_idx: uint,
+                                            f: F)
+                                            -> Result<T, E> where
+        F: FnOnce(&mut Self) -> Result<T, E>;
+
+    fn read_struct<T, F>(&mut self, s_name: &str, len: uint, f: F) -> Result<T, E> where
+        F: FnOnce(&mut Self) -> Result<T, E>;
+    fn read_struct_field<T, F>(&mut self,
+                               f_name: &str,
+                               f_idx: uint,
+                               f: F)
+                               -> Result<T, E> where
+        F: FnOnce(&mut Self) -> Result<T, E>;
+
+    fn read_tuple<T, F>(&mut self, len: uint, f: F) -> Result<T, E> where
+        F: FnOnce(&mut Self) -> Result<T, E>;
+    fn read_tuple_arg<T, F>(&mut self, a_idx: uint, f: F) -> Result<T, E> where
+        F: FnOnce(&mut Self) -> Result<T, E>;
+
+    fn read_tuple_struct<T, F>(&mut self, s_name: &str, len: uint, f: F) -> Result<T, E> where
+        F: FnOnce(&mut Self) -> Result<T, E>;
+    fn read_tuple_struct_arg<T, F>(&mut self, a_idx: uint, f: F) -> Result<T, E> where
+        F: FnOnce(&mut Self) -> Result<T, E>;
 
     // Specialized types:
-    fn read_option<T>(&mut self, f: |&mut Self, bool| -> Result<T, E>) -> Result<T, E>;
+    fn read_option<T, F>(&mut self, f: F) -> Result<T, E> where
+        F: FnOnce(&mut Self, bool) -> Result<T, E>;
 
-    fn read_seq<T>(&mut self, f: |&mut Self, uint| -> Result<T, E>) -> Result<T, E>;
-    fn read_seq_elt<T>(&mut self, idx: uint, f: |&mut Self| -> Result<T, E>) -> Result<T, E>;
+    fn read_seq<T, F>(&mut self, f: F) -> Result<T, E> where
+        F: FnOnce(&mut Self, uint) -> Result<T, E>;
+    fn read_seq_elt<T, F>(&mut self, idx: uint, f: F) -> Result<T, E> where
+        F: FnOnce(&mut Self) -> Result<T, E>;
 
-    fn read_map<T>(&mut self, f: |&mut Self, uint| -> Result<T, E>) -> Result<T, E>;
-    fn read_map_elt_key<T>(&mut self, idx: uint, f: |&mut Self| -> Result<T, E>) -> Result<T, E>;
-    fn read_map_elt_val<T>(&mut self, idx: uint, f: |&mut Self| -> Result<T, E>) -> Result<T, E>;
+    fn read_map<T, F>(&mut self, f: F) -> Result<T, E> where
+        F: FnOnce(&mut Self, uint) -> Result<T, E>;
+    fn read_map_elt_key<T, F>(&mut self, idx: uint, f: F) -> Result<T, E> where
+        F: FnOnce(&mut Self) -> Result<T, E>;
+    fn read_map_elt_val<T, F>(&mut self, idx: uint, f: F) -> Result<T, E> where
+        F: FnOnce(&mut Self) -> Result<T, E>;
 
     // Failure
     fn error(&mut self, err: &str) -> E;
@@ -585,13 +588,14 @@ impl<E, D:Decoder<E>,T:Decodable<D, E>+Send+Sync> Decodable<D, E> for Arc<T> {
 // Helper routines
 
 pub trait EncoderHelpers<E> {
-    fn emit_from_vec<T>(&mut self,
-                        v: &[T],
-                        f: |&mut Self, v: &T| -> Result<(), E>) -> Result<(), E>;
+    fn emit_from_vec<T, F>(&mut self, v: &[T], f: F) -> Result<(), E> where
+        F: FnMut(&mut Self, &T) -> Result<(), E>;
 }
 
 impl<E, S:Encoder<E>> EncoderHelpers<E> for S {
-    fn emit_from_vec<T>(&mut self, v: &[T], f: |&mut S, &T| -> Result<(), E>) -> Result<(), E> {
+    fn emit_from_vec<T, F>(&mut self, v: &[T], mut f: F) -> Result<(), E> where
+        F: FnMut(&mut S, &T) -> Result<(), E>,
+    {
         self.emit_seq(v.len(), |this| {
             for (i, e) in v.iter().enumerate() {
                 try!(this.emit_seq_elt(i, |this| {
@@ -604,11 +608,14 @@ impl<E, S:Encoder<E>> EncoderHelpers<E> for S {
 }
 
 pub trait DecoderHelpers<E> {
-    fn read_to_vec<T>(&mut self, f: |&mut Self| -> Result<T, E>) -> Result<Vec<T>, E>;
+    fn read_to_vec<T, F>(&mut self, f: F) -> Result<Vec<T>, E> where
+        F: FnMut(&mut Self) -> Result<T, E>;
 }
 
 impl<E, D:Decoder<E>> DecoderHelpers<E> for D {
-    fn read_to_vec<T>(&mut self, f: |&mut D| -> Result<T, E>) -> Result<Vec<T>, E> {
+    fn read_to_vec<T, F>(&mut self, mut f: F) -> Result<Vec<T>, E> where F:
+        FnMut(&mut D) -> Result<T, E>,
+    {
         self.read_seq(|this, len| {
             let mut v = Vec::with_capacity(len);
             for i in range(0, len) {

From 807c5e8c8d9a6275846e010007119ba64f42f105 Mon Sep 17 00:00:00 2001
From: Jorge Aparicio <japaricious@gmail.com>
Date: Sat, 6 Dec 2014 16:53:18 -0500
Subject: [PATCH 64/92] librbml: fix fallout

---
 src/librbml/lib.rs | 257 +++++++++++++++++++++++----------------------
 1 file changed, 133 insertions(+), 124 deletions(-)

diff --git a/src/librbml/lib.rs b/src/librbml/lib.rs
index 426a987d25d1c..ef59b4742faf8 100644
--- a/src/librbml/lib.rs
+++ b/src/librbml/lib.rs
@@ -25,6 +25,7 @@
        html_playground_url = "http://play.rust-lang.org/")]
 #![allow(unknown_features)]
 #![feature(macro_rules, phase, slicing_syntax, globs)]
+#![feature(unboxed_closures)]
 #![allow(missing_docs)]
 
 extern crate serialize;
@@ -378,8 +379,9 @@ pub mod reader {
             Ok(r_doc)
         }
 
-        fn push_doc<T>(&mut self, exp_tag: EbmlEncoderTag,
-                       f: |&mut Decoder<'doc>| -> DecodeResult<T>) -> DecodeResult<T> {
+        fn push_doc<T, F>(&mut self, exp_tag: EbmlEncoderTag, f: F) -> DecodeResult<T> where
+            F: FnOnce(&mut Decoder<'doc>) -> DecodeResult<T>,
+        {
             let d = try!(self.next_doc(exp_tag));
             let old_parent = self.parent;
             let old_pos = self.pos;
@@ -471,9 +473,9 @@ pub mod reader {
         }
 
         // Compound types:
-        fn read_enum<T>(&mut self,
-                        name: &str,
-                        f: |&mut Decoder<'doc>| -> DecodeResult<T>) -> DecodeResult<T> {
+        fn read_enum<T, F>(&mut self, name: &str, f: F) -> DecodeResult<T> where
+            F: FnOnce(&mut Decoder<'doc>) -> DecodeResult<T>,
+        {
             debug!("read_enum({})", name);
             try!(self._check_label(name));
 
@@ -490,10 +492,9 @@ pub mod reader {
             Ok(result)
         }
 
-        fn read_enum_variant<T>(&mut self,
-                                _: &[&str],
-                                f: |&mut Decoder<'doc>, uint| -> DecodeResult<T>)
-                                -> DecodeResult<T> {
+        fn read_enum_variant<T, F>(&mut self, _: &[&str], f: F) -> DecodeResult<T> where
+            F: FnOnce(&mut Decoder<'doc>, uint) -> DecodeResult<T>,
+        {
             debug!("read_enum_variant()");
             let idx = try!(self._next_uint(EsEnumVid));
             debug!("  idx={}", idx);
@@ -511,17 +512,16 @@ pub mod reader {
             Ok(result)
         }
 
-        fn read_enum_variant_arg<T>(&mut self,
-                                    idx: uint,
-                                    f: |&mut Decoder<'doc>| -> DecodeResult<T>) -> DecodeResult<T> {
+        fn read_enum_variant_arg<T, F>(&mut self, idx: uint, f: F) -> DecodeResult<T> where
+            F: FnOnce(&mut Decoder<'doc>) -> DecodeResult<T>,
+        {
             debug!("read_enum_variant_arg(idx={})", idx);
             f(self)
         }
 
-        fn read_enum_struct_variant<T>(&mut self,
-                                       _: &[&str],
-                                       f: |&mut Decoder<'doc>, uint| -> DecodeResult<T>)
-                                       -> DecodeResult<T> {
+        fn read_enum_struct_variant<T, F>(&mut self, _: &[&str], f: F) -> DecodeResult<T> where
+            F: FnOnce(&mut Decoder<'doc>, uint) -> DecodeResult<T>,
+        {
             debug!("read_enum_struct_variant()");
             let idx = try!(self._next_uint(EsEnumVid));
             debug!("  idx={}", idx);
@@ -539,39 +539,37 @@ pub mod reader {
             Ok(result)
         }
 
-        fn read_enum_struct_variant_field<T>(&mut self,
-                                             name: &str,
-                                             idx: uint,
-                                             f: |&mut Decoder<'doc>| -> DecodeResult<T>)
-                                             -> DecodeResult<T> {
-            debug!("read_enum_struct_variant_arg(name={}, idx={})", name, idx);
+        fn read_enum_struct_variant_field<T, F>(&mut self,
+                                                name: &str,
+                                                idx: uint,
+                                                f: F)
+                                                -> DecodeResult<T> where
+            F: FnOnce(&mut Decoder<'doc>) -> DecodeResult<T>,
+        {
+                debug!("read_enum_struct_variant_arg(name={}, idx={})", name, idx);
             f(self)
         }
 
-        fn read_struct<T>(&mut self,
-                          name: &str,
-                          _: uint,
-                          f: |&mut Decoder<'doc>| -> DecodeResult<T>)
-                          -> DecodeResult<T> {
+        fn read_struct<T, F>(&mut self, name: &str, _: uint, f: F) -> DecodeResult<T> where
+            F: FnOnce(&mut Decoder<'doc>) -> DecodeResult<T>,
+        {
             debug!("read_struct(name={})", name);
             f(self)
         }
 
-        fn read_struct_field<T>(&mut self,
-                                name: &str,
-                                idx: uint,
-                                f: |&mut Decoder<'doc>| -> DecodeResult<T>)
-                                -> DecodeResult<T> {
+        fn read_struct_field<T, F>(&mut self, name: &str, idx: uint, f: F) -> DecodeResult<T> where
+            F: FnOnce(&mut Decoder<'doc>) -> DecodeResult<T>,
+        {
             debug!("read_struct_field(name={}, idx={})", name, idx);
             try!(self._check_label(name));
             f(self)
         }
 
-        fn read_tuple<T>(&mut self,
-                         tuple_len: uint,
-                         f: |&mut Decoder<'doc>| -> DecodeResult<T>) -> DecodeResult<T> {
+        fn read_tuple<T, F>(&mut self, tuple_len: uint, f: F) -> DecodeResult<T> where
+            F: FnOnce(&mut Decoder<'doc>) -> DecodeResult<T>,
+        {
             debug!("read_tuple()");
-            self.read_seq(|d, len| {
+            self.read_seq(move |d, len| {
                 if len == tuple_len {
                     f(d)
                 } else {
@@ -581,34 +579,36 @@ pub mod reader {
             })
         }
 
-        fn read_tuple_arg<T>(&mut self, idx: uint, f: |&mut Decoder<'doc>| -> DecodeResult<T>)
-                             -> DecodeResult<T> {
+        fn read_tuple_arg<T, F>(&mut self, idx: uint, f: F) -> DecodeResult<T> where
+            F: FnOnce(&mut Decoder<'doc>) -> DecodeResult<T>,
+        {
             debug!("read_tuple_arg(idx={})", idx);
             self.read_seq_elt(idx, f)
         }
 
-        fn read_tuple_struct<T>(&mut self,
-                                name: &str,
-                                len: uint,
-                                f: |&mut Decoder<'doc>| -> DecodeResult<T>)
-                                -> DecodeResult<T> {
+        fn read_tuple_struct<T, F>(&mut self, name: &str, len: uint, f: F) -> DecodeResult<T> where
+            F: FnOnce(&mut Decoder<'doc>) -> DecodeResult<T>,
+        {
             debug!("read_tuple_struct(name={})", name);
             self.read_tuple(len, f)
         }
 
-        fn read_tuple_struct_arg<T>(&mut self,
-                                    idx: uint,
-                                    f: |&mut Decoder<'doc>| -> DecodeResult<T>)
-                                    -> DecodeResult<T> {
+        fn read_tuple_struct_arg<T, F>(&mut self,
+                                       idx: uint,
+                                       f: F)
+                                       -> DecodeResult<T> where
+            F: FnOnce(&mut Decoder<'doc>) -> DecodeResult<T>,
+        {
             debug!("read_tuple_struct_arg(idx={})", idx);
             self.read_tuple_arg(idx, f)
         }
 
-        fn read_option<T>(&mut self,
-                          f: |&mut Decoder<'doc>, bool| -> DecodeResult<T>) -> DecodeResult<T> {
+        fn read_option<T, F>(&mut self, f: F) -> DecodeResult<T> where
+            F: FnOnce(&mut Decoder<'doc>, bool) -> DecodeResult<T>,
+        {
             debug!("read_option()");
-            self.read_enum("Option", |this| {
-                this.read_enum_variant(&["None", "Some"], |this, idx| {
+            self.read_enum("Option", move |this| {
+                this.read_enum_variant(&["None", "Some"], move |this, idx| {
                     match idx {
                         0 => f(this, false),
                         1 => f(this, true),
@@ -620,40 +620,45 @@ pub mod reader {
             })
         }
 
-        fn read_seq<T>(&mut self,
-                       f: |&mut Decoder<'doc>, uint| -> DecodeResult<T>) -> DecodeResult<T> {
+        fn read_seq<T, F>(&mut self, f: F) -> DecodeResult<T> where
+            F: FnOnce(&mut Decoder<'doc>, uint) -> DecodeResult<T>,
+        {
             debug!("read_seq()");
-            self.push_doc(EsVec, |d| {
+            self.push_doc(EsVec, move |d| {
                 let len = try!(d._next_uint(EsVecLen));
                 debug!("  len={}", len);
                 f(d, len)
             })
         }
 
-        fn read_seq_elt<T>(&mut self, idx: uint, f: |&mut Decoder<'doc>| -> DecodeResult<T>)
-                           -> DecodeResult<T> {
+        fn read_seq_elt<T, F>(&mut self, idx: uint, f: F) -> DecodeResult<T> where
+            F: FnOnce(&mut Decoder<'doc>) -> DecodeResult<T>,
+        {
             debug!("read_seq_elt(idx={})", idx);
             self.push_doc(EsVecElt, f)
         }
 
-        fn read_map<T>(&mut self,
-                       f: |&mut Decoder<'doc>, uint| -> DecodeResult<T>) -> DecodeResult<T> {
+        fn read_map<T, F>(&mut self, f: F) -> DecodeResult<T> where
+            F: FnOnce(&mut Decoder<'doc>, uint) -> DecodeResult<T>,
+        {
             debug!("read_map()");
-            self.push_doc(EsMap, |d| {
+            self.push_doc(EsMap, move |d| {
                 let len = try!(d._next_uint(EsMapLen));
                 debug!("  len={}", len);
                 f(d, len)
             })
         }
 
-        fn read_map_elt_key<T>(&mut self, idx: uint, f: |&mut Decoder<'doc>| -> DecodeResult<T>)
-                               -> DecodeResult<T> {
+        fn read_map_elt_key<T, F>(&mut self, idx: uint, f: F) -> DecodeResult<T> where
+            F: FnOnce(&mut Decoder<'doc>) -> DecodeResult<T>,
+        {
             debug!("read_map_elt_key(idx={})", idx);
             self.push_doc(EsMapKey, f)
         }
 
-        fn read_map_elt_val<T>(&mut self, idx: uint, f: |&mut Decoder<'doc>| -> DecodeResult<T>)
-                               -> DecodeResult<T> {
+        fn read_map_elt_val<T, F>(&mut self, idx: uint, f: F) -> DecodeResult<T> where
+            F: FnOnce(&mut Decoder<'doc>) -> DecodeResult<T>,
+        {
             debug!("read_map_elt_val(idx={})", idx);
             self.push_doc(EsMapVal, f)
         }
@@ -916,102 +921,106 @@ pub mod writer {
             self.wr_tagged_str(EsStr as uint, v)
         }
 
-        fn emit_enum(&mut self,
-                     name: &str,
-                     f: |&mut Encoder<'a, W>| -> EncodeResult) -> EncodeResult {
+        fn emit_enum<F>(&mut self, name: &str, f: F) -> EncodeResult where
+            F: FnOnce(&mut Encoder<'a, W>) -> EncodeResult,
+        {
             try!(self._emit_label(name));
             try!(self.start_tag(EsEnum as uint));
             try!(f(self));
             self.end_tag()
         }
 
-        fn emit_enum_variant(&mut self,
-                             _: &str,
-                             v_id: uint,
-                             _: uint,
-                             f: |&mut Encoder<'a, W>| -> EncodeResult) -> EncodeResult {
+        fn emit_enum_variant<F>(&mut self,
+                                _: &str,
+                                v_id: uint,
+                                _: uint,
+                                f: F) -> EncodeResult where
+            F: FnOnce(&mut Encoder<'a, W>) -> EncodeResult,
+        {
             try!(self._emit_tagged_uint(EsEnumVid, v_id));
             try!(self.start_tag(EsEnumBody as uint));
             try!(f(self));
             self.end_tag()
         }
 
-        fn emit_enum_variant_arg(&mut self,
-                                 _: uint,
-                                 f: |&mut Encoder<'a, W>| -> EncodeResult) -> EncodeResult {
+        fn emit_enum_variant_arg<F>(&mut self, _: uint, f: F) -> EncodeResult where
+            F: FnOnce(&mut Encoder<'a, W>) -> EncodeResult,
+        {
             f(self)
         }
 
-        fn emit_enum_struct_variant(&mut self,
-                                    v_name: &str,
-                                    v_id: uint,
-                                    cnt: uint,
-                                    f: |&mut Encoder<'a, W>| -> EncodeResult) -> EncodeResult {
+        fn emit_enum_struct_variant<F>(&mut self,
+                                       v_name: &str,
+                                       v_id: uint,
+                                       cnt: uint,
+                                       f: F) -> EncodeResult where
+            F: FnOnce(&mut Encoder<'a, W>) -> EncodeResult,
+        {
             self.emit_enum_variant(v_name, v_id, cnt, f)
         }
 
-        fn emit_enum_struct_variant_field(&mut self,
-                                          _: &str,
-                                          idx: uint,
-                                          f: |&mut Encoder<'a, W>| -> EncodeResult)
-            -> EncodeResult {
+        fn emit_enum_struct_variant_field<F>(&mut self,
+                                             _: &str,
+                                             idx: uint,
+                                             f: F) -> EncodeResult where
+            F: FnOnce(&mut Encoder<'a, W>) -> EncodeResult,
+        {
             self.emit_enum_variant_arg(idx, f)
         }
 
-        fn emit_struct(&mut self,
-                       _: &str,
-                       _len: uint,
-                       f: |&mut Encoder<'a, W>| -> EncodeResult) -> EncodeResult {
+        fn emit_struct<F>(&mut self, _: &str, _len: uint, f: F) -> EncodeResult where
+            F: FnOnce(&mut Encoder<'a, W>) -> EncodeResult,
+        {
             f(self)
         }
 
-        fn emit_struct_field(&mut self,
-                             name: &str,
-                             _: uint,
-                             f: |&mut Encoder<'a, W>| -> EncodeResult) -> EncodeResult {
+        fn emit_struct_field<F>(&mut self, name: &str, _: uint, f: F) -> EncodeResult where
+            F: FnOnce(&mut Encoder<'a, W>) -> EncodeResult,
+        {
             try!(self._emit_label(name));
             f(self)
         }
 
-        fn emit_tuple(&mut self,
-                      len: uint,
-                      f: |&mut Encoder<'a, W>| -> EncodeResult) -> EncodeResult {
+        fn emit_tuple<F>(&mut self, len: uint, f: F) -> EncodeResult where
+            F: FnOnce(&mut Encoder<'a, W>) -> EncodeResult,
+        {
             self.emit_seq(len, f)
         }
-        fn emit_tuple_arg(&mut self,
-                          idx: uint,
-                          f: |&mut Encoder<'a, W>| -> EncodeResult) -> EncodeResult {
+        fn emit_tuple_arg<F>(&mut self, idx: uint, f: F) -> EncodeResult where
+            F: FnOnce(&mut Encoder<'a, W>) -> EncodeResult,
+        {
             self.emit_seq_elt(idx, f)
         }
 
-        fn emit_tuple_struct(&mut self,
-                             _: &str,
-                             len: uint,
-                             f: |&mut Encoder<'a, W>| -> EncodeResult) -> EncodeResult {
+        fn emit_tuple_struct<F>(&mut self, _: &str, len: uint, f: F) -> EncodeResult where
+            F: FnOnce(&mut Encoder<'a, W>) -> EncodeResult,
+        {
             self.emit_seq(len, f)
         }
-        fn emit_tuple_struct_arg(&mut self,
-                                 idx: uint,
-                                 f: |&mut Encoder<'a, W>| -> EncodeResult) -> EncodeResult {
+        fn emit_tuple_struct_arg<F>(&mut self, idx: uint, f: F) -> EncodeResult where
+            F: FnOnce(&mut Encoder<'a, W>) -> EncodeResult,
+        {
             self.emit_seq_elt(idx, f)
         }
 
-        fn emit_option(&mut self,
-                       f: |&mut Encoder<'a, W>| -> EncodeResult) -> EncodeResult {
+        fn emit_option<F>(&mut self, f: F) -> EncodeResult where
+            F: FnOnce(&mut Encoder<'a, W>) -> EncodeResult,
+        {
             self.emit_enum("Option", f)
         }
         fn emit_option_none(&mut self) -> EncodeResult {
             self.emit_enum_variant("None", 0, 0, |_| Ok(()))
         }
-        fn emit_option_some(&mut self,
-                            f: |&mut Encoder<'a, W>| -> EncodeResult) -> EncodeResult {
+        fn emit_option_some<F>(&mut self, f: F) -> EncodeResult where
+            F: FnOnce(&mut Encoder<'a, W>) -> EncodeResult,
+        {
 
             self.emit_enum_variant("Some", 1, 1, f)
         }
 
-        fn emit_seq(&mut self,
-                    len: uint,
-                    f: |&mut Encoder<'a, W>| -> EncodeResult) -> EncodeResult {
+        fn emit_seq<F>(&mut self, len: uint, f: F) -> EncodeResult where
+            F: FnOnce(&mut Encoder<'a, W>) -> EncodeResult,
+        {
 
             try!(self.start_tag(EsVec as uint));
             try!(self._emit_tagged_uint(EsVecLen, len));
@@ -1019,18 +1028,18 @@ pub mod writer {
             self.end_tag()
         }
 
-        fn emit_seq_elt(&mut self,
-                        _idx: uint,
-                        f: |&mut Encoder<'a, W>| -> EncodeResult) -> EncodeResult {
+        fn emit_seq_elt<F>(&mut self, _idx: uint, f: F) -> EncodeResult where
+            F: FnOnce(&mut Encoder<'a, W>) -> EncodeResult,
+        {
 
             try!(self.start_tag(EsVecElt as uint));
             try!(f(self));
             self.end_tag()
         }
 
-        fn emit_map(&mut self,
-                    len: uint,
-                    f: |&mut Encoder<'a, W>| -> EncodeResult) -> EncodeResult {
+        fn emit_map<F>(&mut self, len: uint, f: F) -> EncodeResult where
+            F: FnOnce(&mut Encoder<'a, W>) -> EncodeResult,
+        {
 
             try!(self.start_tag(EsMap as uint));
             try!(self._emit_tagged_uint(EsMapLen, len));
@@ -1038,18 +1047,18 @@ pub mod writer {
             self.end_tag()
         }
 
-        fn emit_map_elt_key(&mut self,
-                            _idx: uint,
-                            f: |&mut Encoder<'a, W>| -> EncodeResult) -> EncodeResult {
+        fn emit_map_elt_key<F>(&mut self, _idx: uint, mut f: F) -> EncodeResult where
+            F: FnMut(&mut Encoder<'a, W>) -> EncodeResult,
+        {
 
             try!(self.start_tag(EsMapKey as uint));
             try!(f(self));
             self.end_tag()
         }
 
-        fn emit_map_elt_val(&mut self,
-                            _idx: uint,
-                            f: |&mut Encoder<'a, W>| -> EncodeResult) -> EncodeResult {
+        fn emit_map_elt_val<F>(&mut self, _idx: uint, f: F) -> EncodeResult where
+            F: FnOnce(&mut Encoder<'a, W>) -> EncodeResult,
+        {
             try!(self.start_tag(EsMapVal as uint));
             try!(f(self));
             self.end_tag()

From 594ff51b237299565a79de323aa1ba390190e28a Mon Sep 17 00:00:00 2001
From: Jorge Aparicio <japaricious@gmail.com>
Date: Sat, 6 Dec 2014 17:44:01 -0500
Subject: [PATCH 65/92] librbml: use unboxed closures in free functions

---
 src/librbml/lib.rs | 25 ++++++++++++++++++-------
 1 file changed, 18 insertions(+), 7 deletions(-)

diff --git a/src/librbml/lib.rs b/src/librbml/lib.rs
index ef59b4742faf8..28d5e1812f090 100644
--- a/src/librbml/lib.rs
+++ b/src/librbml/lib.rs
@@ -260,7 +260,9 @@ pub mod reader {
         }
     }
 
-    pub fn docs<'a>(d: Doc<'a>, it: |uint, Doc<'a>| -> bool) -> bool {
+    pub fn docs<F>(d: Doc, mut it: F) -> bool where
+        F: FnMut(uint, Doc) -> bool,
+    {
         let mut pos = d.start;
         while pos < d.end {
             let elt_tag = try_or!(vuint_at(d.data, pos), false);
@@ -274,7 +276,9 @@ pub mod reader {
         return true;
     }
 
-    pub fn tagged_docs<'a>(d: Doc<'a>, tg: uint, it: |Doc<'a>| -> bool) -> bool {
+    pub fn tagged_docs<F>(d: Doc, tg: uint, mut it: F) -> bool where
+        F: FnMut(Doc) -> bool,
+    {
         let mut pos = d.start;
         while pos < d.end {
             let elt_tag = try_or!(vuint_at(d.data, pos), false);
@@ -291,7 +295,9 @@ pub mod reader {
         return true;
     }
 
-    pub fn with_doc_data<'a, T>(d: Doc<'a>, f: |x: &'a [u8]| -> T) -> T {
+    pub fn with_doc_data<T, F>(d: Doc, f: F) -> T where
+        F: FnOnce(&[u8]) -> T,
+    {
         f(d.data[d.start..d.end])
     }
 
@@ -399,8 +405,9 @@ pub mod reader {
             Ok(r as uint)
         }
 
-        pub fn read_opaque<R>(&mut self,
-                              op: |&mut Decoder<'doc>, Doc| -> DecodeResult<R>) -> DecodeResult<R> {
+        pub fn read_opaque<R, F>(&mut self, op: F) -> DecodeResult<R> where
+            F: FnOnce(&mut Decoder, Doc) -> DecodeResult<R>,
+        {
             let doc = try!(self.next_doc(EsOpaque));
 
             let (old_parent, old_pos) = (self.parent, self.pos);
@@ -761,7 +768,9 @@ pub mod writer {
             Ok(r)
         }
 
-        pub fn wr_tag(&mut self, tag_id: uint, blk: || -> EncodeResult) -> EncodeResult {
+        pub fn wr_tag<F>(&mut self, tag_id: uint, blk: F) -> EncodeResult where
+            F: FnOnce() -> EncodeResult,
+        {
             try!(self.start_tag(tag_id));
             try!(blk());
             self.end_tag()
@@ -857,7 +866,9 @@ pub mod writer {
             else { Ok(()) }
         }
 
-        pub fn emit_opaque(&mut self, f: |&mut Encoder<W>| -> EncodeResult) -> EncodeResult {
+        pub fn emit_opaque<F>(&mut self, f: F) -> EncodeResult where
+            F: FnOnce(&mut Encoder<W>) -> EncodeResult,
+        {
             try!(self.start_tag(EsOpaque as uint));
             try!(f(self));
             self.end_tag()

From 01d2e46a2d952c65071b363701faa6eea952d55f Mon Sep 17 00:00:00 2001
From: Jorge Aparicio <japaricious@gmail.com>
Date: Sat, 6 Dec 2014 17:55:55 -0500
Subject: [PATCH 66/92] librustc: fix fallout

---
 src/librustc/metadata/decoder.rs | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/src/librustc/metadata/decoder.rs b/src/librustc/metadata/decoder.rs
index 898f5d2ef93ca..2000c4e1abe9b 100644
--- a/src/librustc/metadata/decoder.rs
+++ b/src/librustc/metadata/decoder.rs
@@ -212,7 +212,9 @@ fn get_provided_source(d: rbml::Doc, cdata: Cmd) -> Option<ast::DefId> {
     })
 }
 
-fn each_reexport(d: rbml::Doc, f: |rbml::Doc| -> bool) -> bool {
+fn each_reexport<F>(d: rbml::Doc, f: F) -> bool where
+    F: FnMut(rbml::Doc) -> bool,
+{
     reader::tagged_docs(d, tag_items_data_item_reexport, f)
 }
 

From 61ba334452102e7c7bf227927d56c28ec4f025f3 Mon Sep 17 00:00:00 2001
From: Jorge Aparicio <japaricious@gmail.com>
Date: Sat, 6 Dec 2014 19:35:02 -0500
Subject: [PATCH 67/92] libregex: impl Replacer for FnMut(&Captures) -> String
 implementors

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

diff --git a/src/libregex/re.rs b/src/libregex/re.rs
index 2a1fda06431c8..ec93a2b5a5917 100644
--- a/src/libregex/re.rs
+++ b/src/libregex/re.rs
@@ -585,7 +585,7 @@ impl<'t> Replacer for &'t str {
     }
 }
 
-impl<'t> Replacer for |&Captures|: 't -> String {
+impl<F> Replacer for F where F: FnMut(&Captures) -> String {
     fn reg_replace<'a>(&'a mut self, caps: &Captures) -> CowString<'a> {
         (*self)(caps).into_cow()
     }
@@ -767,7 +767,7 @@ impl<'t> Captures<'t> {
         // How evil can you get?
         // FIXME: Don't use regexes for this. It's completely unnecessary.
         let re = Regex::new(r"(^|[^$]|\b)\$(\w+)").unwrap();
-        let text = re.replace_all(text, |refs: &Captures| -> String {
+        let text = re.replace_all(text, |&mut: refs: &Captures| -> String {
             let (pre, name) = (refs.at(1), refs.at(2));
             format!("{}{}", pre,
                     match from_str::<uint>(name.as_slice()) {

From 341e7bc08bfab8fa3abe851501d72336b8556275 Mon Sep 17 00:00:00 2001
From: Jorge Aparicio <japaricious@gmail.com>
Date: Sun, 7 Dec 2014 20:32:53 -0500
Subject: [PATCH 68/92] libregex: fix fallout in doc tests

---
 src/libregex/re.rs | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/src/libregex/re.rs b/src/libregex/re.rs
index ec93a2b5a5917..1504e1919852d 100644
--- a/src/libregex/re.rs
+++ b/src/libregex/re.rs
@@ -429,10 +429,11 @@ impl Regex {
     ///
     /// ```rust
     /// # #![feature(phase)]
+    /// # #![feature(unboxed_closures)]
     /// # extern crate regex; #[phase(plugin)] extern crate regex_macros;
     /// # use regex::Captures; fn main() {
     /// let re = regex!(r"([^,\s]+),\s+(\S+)");
-    /// let result = re.replace("Springsteen, Bruce", |caps: &Captures| {
+    /// let result = re.replace("Springsteen, Bruce", |&: caps: &Captures| {
     ///     format!("{} {}", caps.at(2), caps.at(1))
     /// });
     /// assert_eq!(result.as_slice(), "Bruce Springsteen");

From 1c5aac2b308445c7a03cdf9ff4b5457f7adbf1fb Mon Sep 17 00:00:00 2001
From: Jorge Aparicio <japaricious@gmail.com>
Date: Sun, 7 Dec 2014 11:11:15 -0500
Subject: [PATCH 69/92] libarena: use unboxed closures

---
 src/libarena/lib.rs | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/src/libarena/lib.rs b/src/libarena/lib.rs
index 95c4dff323ef0..1f4df1fd0a5a2 100644
--- a/src/libarena/lib.rs
+++ b/src/libarena/lib.rs
@@ -28,6 +28,7 @@
        html_root_url = "http://doc.rust-lang.org/nightly/")]
 
 #![feature(unsafe_destructor)]
+#![feature(unboxed_closures)]
 #![allow(missing_docs)]
 
 extern crate alloc;
@@ -209,7 +210,7 @@ impl Arena {
     }
 
     #[inline]
-    fn alloc_copy<T>(&self, op: || -> T) -> &mut T {
+    fn alloc_copy<T, F>(&self, op: F) -> &mut T where F: FnOnce() -> T {
         unsafe {
             let ptr = self.alloc_copy_inner(mem::size_of::<T>(),
                                             mem::min_align_of::<T>());
@@ -263,7 +264,7 @@ impl Arena {
     }
 
     #[inline]
-    fn alloc_noncopy<T>(&self, op: || -> T) -> &mut T {
+    fn alloc_noncopy<T, F>(&self, op: F) -> &mut T where F: FnOnce() -> T {
         unsafe {
             let tydesc = get_tydesc::<T>();
             let (ty_ptr, ptr) =
@@ -287,7 +288,7 @@ impl Arena {
     /// Allocates a new item in the arena, using `op` to initialize the value,
     /// and returns a reference to it.
     #[inline]
-    pub fn alloc<T>(&self, op: || -> T) -> &mut T {
+    pub fn alloc<T, F>(&self, op: F) -> &mut T where F: FnOnce() -> T {
         unsafe {
             if intrinsics::needs_drop::<T>() {
                 self.alloc_noncopy(op)
@@ -339,7 +340,7 @@ fn test_arena_destructors_fail() {
         arena.alloc(|| { [0u8, 1u8, 2u8] });
     }
     // Now, panic while allocating
-    arena.alloc::<Rc<int>>(|| {
+    arena.alloc::<Rc<int>, _>(|| {
         panic!();
     });
 }

From 95d0763707956ec6518694ec0fb8b82a7b3a1261 Mon Sep 17 00:00:00 2001
From: Jorge Aparicio <japaricious@gmail.com>
Date: Sun, 7 Dec 2014 11:14:43 -0500
Subject: [PATCH 70/92] libregex: use unboxed closures

---
 src/libregex/parse.rs | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/src/libregex/parse.rs b/src/libregex/parse.rs
index f7ea83a8a3835..ccbd53c4f2a88 100644
--- a/src/libregex/parse.rs
+++ b/src/libregex/parse.rs
@@ -888,8 +888,9 @@ impl<'a> Parser<'a> {
     // build_from combines all AST elements starting at 'from' in the
     // parser's stack using 'mk' to combine them. If any such element is not an
     // AST then it is popped off the stack and ignored.
-    fn build_from(&mut self, from: uint, mk: |Ast, Ast| -> Ast)
-                 -> Result<Ast, Error> {
+    fn build_from<F>(&mut self, from: uint, mut mk: F) -> Result<Ast, Error> where
+        F: FnMut(Ast, Ast) -> Ast,
+    {
         if from >= self.stack.len() {
             return self.err("Empty group or alternate not allowed.")
         }

From 9b075bcf3ffef3f11d8401b55feaa02c1e6553d2 Mon Sep 17 00:00:00 2001
From: Jorge Aparicio <japaricious@gmail.com>
Date: Sun, 7 Dec 2014 11:59:59 -0500
Subject: [PATCH 71/92] libserialize: use unboxed closures

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

diff --git a/src/libserialize/json.rs b/src/libserialize/json.rs
index 37bd11ba59f45..d34828ccee328 100644
--- a/src/libserialize/json.rs
+++ b/src/libserialize/json.rs
@@ -2680,7 +2680,7 @@ mod tests {
                    from_str(a.to_pretty_str().as_slice()).unwrap());
     }
 
-    fn with_str_writer(f: |&mut io::Writer|) -> string::String {
+    fn with_str_writer<F>(f: F) -> string::String where F: FnOnce(&mut io::Writer){
         use std::str;
 
         let mut m = Vec::new();

From 879ebce6a4023632cfd448749997ce3e4e24b05d Mon Sep 17 00:00:00 2001
From: Jorge Aparicio <japaricious@gmail.com>
Date: Sun, 7 Dec 2014 12:17:33 -0500
Subject: [PATCH 72/92] libcollections: use unboxed closures

---
 src/libcollections/bench.rs | 44 +++++++++++++++++++++++++++----------
 1 file changed, 32 insertions(+), 12 deletions(-)

diff --git a/src/libcollections/bench.rs b/src/libcollections/bench.rs
index a212f22f89929..3346e55158a2a 100644
--- a/src/libcollections/bench.rs
+++ b/src/libcollections/bench.rs
@@ -13,9 +13,14 @@ use std::rand;
 use std::rand::Rng;
 use test::Bencher;
 
-pub fn insert_rand_n<M>(n: uint, map: &mut M, b: &mut Bencher,
-                        insert: |&mut M, uint|,
-                        remove: |&mut M, uint|) {
+pub fn insert_rand_n<M, I, R>(n: uint,
+                              map: &mut M,
+                              b: &mut Bencher,
+                              mut insert: I,
+                              mut remove: R) where
+    I: FnMut(&mut M, uint),
+    R: FnMut(&mut M, uint),
+{
     // setup
     let mut rng = rand::weak_rng();
 
@@ -31,9 +36,14 @@ pub fn insert_rand_n<M>(n: uint, map: &mut M, b: &mut Bencher,
     })
 }
 
-pub fn insert_seq_n<M>(n: uint, map: &mut M, b: &mut Bencher,
-                       insert: |&mut M, uint|,
-                       remove: |&mut M, uint|) {
+pub fn insert_seq_n<M, I, R>(n: uint,
+                             map: &mut M,
+                             b: &mut Bencher,
+                             mut insert: I,
+                             mut remove: R) where
+    I: FnMut(&mut M, uint),
+    R: FnMut(&mut M, uint),
+{
     // setup
     for i in range(0u, n) {
         insert(map, i * 2);
@@ -48,9 +58,14 @@ pub fn insert_seq_n<M>(n: uint, map: &mut M, b: &mut Bencher,
     })
 }
 
-pub fn find_rand_n<M, T>(n: uint, map: &mut M, b: &mut Bencher,
-                         insert: |&mut M, uint|,
-                         find: |&M, uint| -> T) {
+pub fn find_rand_n<M, T, I, F>(n: uint,
+                               map: &mut M,
+                               b: &mut Bencher,
+                               mut insert: I,
+                               mut find: F) where
+    I: FnMut(&mut M, uint),
+    F: FnMut(&M, uint) -> T,
+{
     // setup
     let mut rng = rand::weak_rng();
     let mut keys = Vec::from_fn(n, |_| rng.gen::<uint>() % n);
@@ -70,9 +85,14 @@ pub fn find_rand_n<M, T>(n: uint, map: &mut M, b: &mut Bencher,
     })
 }
 
-pub fn find_seq_n<M, T>(n: uint, map: &mut M, b: &mut Bencher,
-                        insert: |&mut M, uint|,
-                        find: |&M, uint| -> T) {
+pub fn find_seq_n<M, T, I, F>(n: uint,
+                              map: &mut M,
+                              b: &mut Bencher,
+                              mut insert: I,
+                              mut find: F) where
+    I: FnMut(&mut M, uint),
+    F: FnMut(&M, uint) -> T,
+{
     // setup
     for i in range(0u, n) {
         insert(map, i);

From b44b5da8c2ad8befb7deb88dc8df61508e1df22f Mon Sep 17 00:00:00 2001
From: Jorge Aparicio <japaricious@gmail.com>
Date: Sun, 7 Dec 2014 12:36:42 -0500
Subject: [PATCH 73/92] libregex_macros: use unboxed closures

---
 src/libregex_macros/lib.rs | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/src/libregex_macros/lib.rs b/src/libregex_macros/lib.rs
index 4df8819774319..c1e8677fa8f3d 100644
--- a/src/libregex_macros/lib.rs
+++ b/src/libregex_macros/lib.rs
@@ -19,6 +19,7 @@
        html_root_url = "http://doc.rust-lang.org/nightly/")]
 
 #![feature(plugin_registrar, quote)]
+#![feature(unboxed_closures)]
 
 extern crate regex;
 extern crate syntax;
@@ -601,9 +602,10 @@ fn exec<'t>(which: ::regex::native::MatchKind, input: &'t str,
 
     // Converts `xs` to a `[x1, x2, .., xN]` expression by calling `to_expr`
     // on each element in `xs`.
-    fn vec_expr<T, It: Iterator<T>>(&self, xs: It,
-                                    to_expr: |&ExtCtxt, T| -> P<ast::Expr>)
-                  -> P<ast::Expr> {
+    fn vec_expr<T, It, F>(&self, xs: It, mut to_expr: F) -> P<ast::Expr> where
+        It: Iterator<T>,
+        F: FnMut(&ExtCtxt, T) -> P<ast::Expr>,
+    {
         let exprs = xs.map(|x| to_expr(self.cx, x)).collect();
         self.cx.expr_vec(self.sp, exprs)
     }

From be53d619f874cbe8e4d87f900060561d16405d53 Mon Sep 17 00:00:00 2001
From: Jorge Aparicio <japaricious@gmail.com>
Date: Sun, 7 Dec 2014 13:22:04 -0500
Subject: [PATCH 74/92] librustrt: use unboxed closures

---
 src/librustrt/args.rs  |  2 +-
 src/librustrt/c_str.rs | 57 ++++++++++++++++++++++++++++++------------
 2 files changed, 42 insertions(+), 17 deletions(-)

diff --git a/src/librustrt/args.rs b/src/librustrt/args.rs
index 4632eca4d0fd5..c1b48e989a1c1 100644
--- a/src/librustrt/args.rs
+++ b/src/librustrt/args.rs
@@ -89,7 +89,7 @@ mod imp {
         })
     }
 
-    fn with_lock<T>(f: || -> T) -> T {
+    fn with_lock<T, F>(f: F) -> T where F: FnOnce() -> T {
         unsafe {
             let _guard = LOCK.lock();
             f()
diff --git a/src/librustrt/c_str.rs b/src/librustrt/c_str.rs
index 07094f08c5de9..865c1af1d1427 100644
--- a/src/librustrt/c_str.rs
+++ b/src/librustrt/c_str.rs
@@ -72,6 +72,7 @@ use collections::hash;
 use core::fmt;
 use core::kinds::{Sized, marker};
 use core::mem;
+use core::ops::{FnMut, FnOnce};
 use core::prelude::{Clone, Drop, Eq, Iterator};
 use core::prelude::{SlicePrelude, None, Option, Ordering, PartialEq};
 use core::prelude::{PartialOrd, RawPtr, Some, StrPrelude, range};
@@ -319,14 +320,18 @@ pub trait ToCStr for Sized? {
     ///
     /// Panics the task if the receiver has an interior null.
     #[inline]
-    fn with_c_str<T>(&self, f: |*const libc::c_char| -> T) -> T {
+    fn with_c_str<T, F>(&self, f: F) -> T where
+        F: FnOnce(*const libc::c_char) -> T,
+    {
         let c_str = self.to_c_str();
         f(c_str.as_ptr())
     }
 
     /// Unsafe variant of `with_c_str()` that doesn't check for nulls.
     #[inline]
-    unsafe fn with_c_str_unchecked<T>(&self, f: |*const libc::c_char| -> T) -> T {
+    unsafe fn with_c_str_unchecked<T, F>(&self, f: F) -> T where
+        F: FnOnce(*const libc::c_char) -> T,
+    {
         let c_str = self.to_c_str_unchecked();
         f(c_str.as_ptr())
     }
@@ -344,12 +349,16 @@ impl ToCStr for str {
     }
 
     #[inline]
-    fn with_c_str<T>(&self, f: |*const libc::c_char| -> T) -> T {
+    fn with_c_str<T, F>(&self, f: F) -> T where
+        F: FnOnce(*const libc::c_char) -> T,
+    {
         self.as_bytes().with_c_str(f)
     }
 
     #[inline]
-    unsafe fn with_c_str_unchecked<T>(&self, f: |*const libc::c_char| -> T) -> T {
+    unsafe fn with_c_str_unchecked<T, F>(&self, f: F) -> T where
+        F: FnOnce(*const libc::c_char) -> T,
+    {
         self.as_bytes().with_c_str_unchecked(f)
     }
 }
@@ -366,12 +375,16 @@ impl ToCStr for String {
     }
 
     #[inline]
-    fn with_c_str<T>(&self, f: |*const libc::c_char| -> T) -> T {
+    fn with_c_str<T, F>(&self, f: F) -> T where
+        F: FnOnce(*const libc::c_char) -> T,
+    {
         self.as_bytes().with_c_str(f)
     }
 
     #[inline]
-    unsafe fn with_c_str_unchecked<T>(&self, f: |*const libc::c_char| -> T) -> T {
+    unsafe fn with_c_str_unchecked<T, F>(&self, f: F) -> T where
+        F: FnOnce(*const libc::c_char) -> T,
+    {
         self.as_bytes().with_c_str_unchecked(f)
     }
 }
@@ -397,11 +410,15 @@ impl ToCStr for [u8] {
         CString::new(buf as *const libc::c_char, true)
     }
 
-    fn with_c_str<T>(&self, f: |*const libc::c_char| -> T) -> T {
+    fn with_c_str<T, F>(&self, f: F) -> T where
+        F: FnOnce(*const libc::c_char) -> T,
+    {
         unsafe { with_c_str(self, true, f) }
     }
 
-    unsafe fn with_c_str_unchecked<T>(&self, f: |*const libc::c_char| -> T) -> T {
+    unsafe fn with_c_str_unchecked<T, F>(&self, f: F) -> T where
+        F: FnOnce(*const libc::c_char) -> T,
+    {
         with_c_str(self, false, f)
     }
 }
@@ -418,19 +435,24 @@ impl<'a, Sized? T: ToCStr> ToCStr for &'a T {
     }
 
     #[inline]
-    fn with_c_str<T>(&self, f: |*const libc::c_char| -> T) -> T {
+    fn with_c_str<T, F>(&self, f: F) -> T where
+        F: FnOnce(*const libc::c_char) -> T,
+    {
         (**self).with_c_str(f)
     }
 
     #[inline]
-    unsafe fn with_c_str_unchecked<T>(&self, f: |*const libc::c_char| -> T) -> T {
+    unsafe fn with_c_str_unchecked<T, F>(&self, f: F) -> T where
+        F: FnOnce(*const libc::c_char) -> T,
+    {
         (**self).with_c_str_unchecked(f)
     }
 }
 
 // Unsafe function that handles possibly copying the &[u8] into a stack array.
-unsafe fn with_c_str<T>(v: &[u8], checked: bool,
-                        f: |*const libc::c_char| -> T) -> T {
+unsafe fn with_c_str<T, F>(v: &[u8], checked: bool, f: F) -> T where
+    F: FnOnce(*const libc::c_char) -> T,
+{
     let c_str = if v.len() < BUF_LEN {
         let mut buf: [u8, .. BUF_LEN] = mem::uninitialized();
         slice::bytes::copy_memory(&mut buf, v);
@@ -489,9 +511,12 @@ impl<'a> Iterator<libc::c_char> for CChars<'a> {
 ///
 /// The specified closure is invoked with each string that
 /// is found, and the number of strings found is returned.
-pub unsafe fn from_c_multistring(buf: *const libc::c_char,
-                                 count: Option<uint>,
-                                 f: |&CString|) -> uint {
+pub unsafe fn from_c_multistring<F>(buf: *const libc::c_char,
+                                    count: Option<uint>,
+                                    mut f: F)
+                                    -> uint where
+    F: FnMut(&CString),
+{
 
     let mut curr_ptr: uint = buf as uint;
     let mut ctr = 0;
@@ -678,7 +703,7 @@ mod tests {
 
     #[test]
     fn test_clone_noleak() {
-        fn foo(f: |c: &CString|) {
+        fn foo<F>(f: F) where F: FnOnce(&CString) {
             let s = "test".to_string();
             let c = s.to_c_str();
             // give the closure a non-owned CString

From cdbb3ca9b776b066e2c93acfb60da8537d2b1c9b Mon Sep 17 00:00:00 2001
From: Jorge Aparicio <japaricious@gmail.com>
Date: Sun, 7 Dec 2014 14:15:25 -0500
Subject: [PATCH 75/92] libstd: use unboxed closures

---
 src/libstd/ascii.rs                    |  5 ++-
 src/libstd/collections/hash/map.rs     | 27 +++++++++------
 src/libstd/dynamic_lib.rs              |  9 +++--
 src/libstd/io/extensions.rs            |  9 +++--
 src/libstd/io/mod.rs                   | 20 +++++++----
 src/libstd/io/net/ip.rs                | 48 ++++++++++++++------------
 src/libstd/io/net/mod.rs               |  7 ++--
 src/libstd/io/net/udp.rs               |  5 ++-
 src/libstd/io/stdio.rs                 | 10 ++++--
 src/libstd/num/strconv.rs              |  6 +++-
 src/libstd/num/u16.rs                  |  2 ++
 src/libstd/num/u32.rs                  |  2 ++
 src/libstd/num/u64.rs                  |  2 ++
 src/libstd/num/u8.rs                   |  2 ++
 src/libstd/num/uint.rs                 |  2 ++
 src/libstd/num/uint_macros.rs          |  4 ++-
 src/libstd/os.rs                       | 11 +++---
 src/libstd/sync/once.rs                |  3 +-
 src/libstd/sys/common/helper_thread.rs |  7 ++--
 src/libstd/sys/common/mod.rs           |  4 ++-
 src/libstd/sys/common/net.rs           | 37 +++++++++++---------
 src/libstd/sys/unix/mod.rs             |  5 ++-
 src/libstd/sys/unix/pipe.rs            |  8 ++---
 src/libstd/sys/windows/mod.rs          |  2 +-
 src/libstd/sys/windows/process.rs      |  9 ++---
 src/libstd/task.rs                     |  4 ++-
 src/libstd/thread_local/mod.rs         |  4 ++-
 src/libstd/thread_local/scoped.rs      |  8 +++--
 src/libstd/time/duration.rs            |  4 +--
 29 files changed, 171 insertions(+), 95 deletions(-)

diff --git a/src/libstd/ascii.rs b/src/libstd/ascii.rs
index b5c8e271492ea..ad2167214a7d4 100644
--- a/src/libstd/ascii.rs
+++ b/src/libstd/ascii.rs
@@ -20,6 +20,7 @@ use fmt;
 use iter::IteratorExt;
 use kinds::Copy;
 use mem;
+use ops::FnMut;
 use option::Option;
 use option::Option::{Some, None};
 use slice::{SlicePrelude, AsSlice};
@@ -527,7 +528,9 @@ impl OwnedAsciiExt for Vec<u8> {
 /// - Any other chars are given hex escapes.
 /// - Unicode escapes are never generated by this function.
 #[unstable = "needs to be updated to use an iterator"]
-pub fn escape_default(c: u8, f: |u8|) {
+pub fn escape_default<F>(c: u8, mut f: F) where
+    F: FnMut(u8),
+{
     match c {
         b'\t' => { f(b'\\'); f(b't'); }
         b'\r' => { f(b'\\'); f(b'r'); }
diff --git a/src/libstd/collections/hash/map.rs b/src/libstd/collections/hash/map.rs
index 97e0518a072cd..2a8d97eed05bc 100644
--- a/src/libstd/collections/hash/map.rs
+++ b/src/libstd/collections/hash/map.rs
@@ -24,7 +24,7 @@ use iter::{mod, Iterator, IteratorExt, FromIterator, Extend};
 use kinds::Sized;
 use mem::{mod, replace};
 use num::{Int, UnsignedInt};
-use ops::{Deref, Index, IndexMut};
+use ops::{Deref, FnMut, Index, IndexMut};
 use option::Option;
 use option::Option::{Some, None};
 use result::Result;
@@ -296,10 +296,13 @@ pub struct HashMap<K, V, H = RandomSipHasher> {
 }
 
 /// Search for a pre-hashed key.
-fn search_hashed<K, V, M: Deref<RawTable<K, V>>>(table: M,
-                                                 hash: &SafeHash,
-                                                 is_match: |&K| -> bool)
-                                                 -> SearchResult<K, V, M> {
+fn search_hashed<K, V, M, F>(table: M,
+                             hash: &SafeHash,
+                             mut is_match: F)
+                             -> SearchResult<K, V, M> where
+    M: Deref<RawTable<K, V>>,
+    F: FnMut(&K) -> bool,
+{
     let size = table.size();
     let mut probe = Bucket::new(table, hash);
     let ib = probe.index();
@@ -749,12 +752,14 @@ impl<K: Eq + Hash<S>, V, S, H: Hasher<S>> HashMap<K, V, H> {
         self.insert_or_replace_with(hash, k, v, |_, _, _| ())
     }
 
-    fn insert_or_replace_with<'a>(&'a mut self,
-                                  hash: SafeHash,
-                                  k: K,
-                                  v: V,
-                                  found_existing: |&mut K, &mut V, V|)
-                                  -> &'a mut V {
+    fn insert_or_replace_with<'a, F>(&'a mut self,
+                                     hash: SafeHash,
+                                     k: K,
+                                     v: V,
+                                     mut found_existing: F)
+                                     -> &'a mut V where
+        F: FnMut(&mut K, &mut V, V),
+    {
         // Worst case, we'll find one empty bucket among `size + 1` buckets.
         let size = self.table.size();
         let mut probe = Bucket::new(&mut self.table, &hash);
diff --git a/src/libstd/dynamic_lib.rs b/src/libstd/dynamic_lib.rs
index 96b075ab569bf..ebb2a491b4ace 100644
--- a/src/libstd/dynamic_lib.rs
+++ b/src/libstd/dynamic_lib.rs
@@ -216,6 +216,7 @@ pub mod dl {
     use c_str::{CString, ToCStr};
     use libc;
     use kinds::Copy;
+    use ops::FnOnce;
     use ptr;
     use result::*;
     use result::Result::{Err, Ok};
@@ -231,7 +232,9 @@ pub mod dl {
         dlopen(ptr::null(), Lazy as libc::c_int) as *mut u8
     }
 
-    pub fn check_for_errors_in<T>(f: || -> T) -> Result<T, String> {
+    pub fn check_for_errors_in<T, F>(f: F) -> Result<T, String> where
+        F: FnOnce() -> T,
+    {
         use sync::{StaticMutex, MUTEX_INIT};
         static LOCK: StaticMutex = MUTEX_INIT;
         unsafe {
@@ -312,7 +315,9 @@ pub mod dl {
         handle as *mut u8
     }
 
-    pub fn check_for_errors_in<T>(f: || -> T) -> Result<T, String> {
+    pub fn check_for_errors_in<T, F>(f: F) -> Result<T, String> where
+        F: FnOnce() -> T,
+    {
         unsafe {
             SetLastError(0);
 
diff --git a/src/libstd/io/extensions.rs b/src/libstd/io/extensions.rs
index 1bdf99f6d6dce..69712e39d9108 100644
--- a/src/libstd/io/extensions.rs
+++ b/src/libstd/io/extensions.rs
@@ -19,6 +19,7 @@ use io::{IoError, IoResult, Reader};
 use io;
 use iter::Iterator;
 use num::Int;
+use ops::FnOnce;
 use option::Option;
 use option::Option::{Some, None};
 use ptr::RawPtr;
@@ -76,7 +77,9 @@ impl<'r, R: Reader> Iterator<IoResult<u8>> for Bytes<'r, R> {
 /// * `f`: A callback that receives the value.
 ///
 /// This function returns the value returned by the callback, for convenience.
-pub fn u64_to_le_bytes<T>(n: u64, size: uint, f: |v: &[u8]| -> T) -> T {
+pub fn u64_to_le_bytes<T, F>(n: u64, size: uint, f: F) -> T where
+    F: FnOnce(&[u8]) -> T,
+{
     use mem::transmute;
 
     // LLVM fails to properly optimize this when using shifts instead of the to_le* intrinsics
@@ -115,7 +118,9 @@ pub fn u64_to_le_bytes<T>(n: u64, size: uint, f: |v: &[u8]| -> T) -> T {
 /// * `f`: A callback that receives the value.
 ///
 /// This function returns the value returned by the callback, for convenience.
-pub fn u64_to_be_bytes<T>(n: u64, size: uint, f: |v: &[u8]| -> T) -> T {
+pub fn u64_to_be_bytes<T, F>(n: u64, size: uint, f: F) -> T where
+    F: FnOnce(&[u8]) -> T,
+{
     use mem::transmute;
 
     // LLVM fails to properly optimize this when using shifts instead of the to_be* intrinsics
diff --git a/src/libstd/io/mod.rs b/src/libstd/io/mod.rs
index dc212e7cab3ae..bad86258bb85d 100644
--- a/src/libstd/io/mod.rs
+++ b/src/libstd/io/mod.rs
@@ -233,7 +233,7 @@ use int;
 use iter::{Iterator, IteratorExt};
 use kinds::Copy;
 use mem::transmute;
-use ops::{BitOr, BitXor, BitAnd, Sub, Not};
+use ops::{BitOr, BitXor, BitAnd, Sub, Not, FnOnce};
 use option::Option;
 use option::Option::{Some, None};
 use os;
@@ -426,18 +426,22 @@ impl Copy for IoErrorKind {}
 /// A trait that lets you add a `detail` to an IoError easily
 trait UpdateIoError<T> {
     /// Returns an IoError with updated description and detail
-    fn update_err(self, desc: &'static str, detail: |&IoError| -> String) -> Self;
+    fn update_err<D>(self, desc: &'static str, detail: D) -> Self where
+        D: FnOnce(&IoError) -> String;
 
     /// Returns an IoError with updated detail
-    fn update_detail(self, detail: |&IoError| -> String) -> Self;
+    fn update_detail<D>(self, detail: D) -> Self where
+        D: FnOnce(&IoError) -> String;
 
     /// Returns an IoError with update description
     fn update_desc(self, desc: &'static str) -> Self;
 }
 
 impl<T> UpdateIoError<T> for IoResult<T> {
-    fn update_err(self, desc: &'static str, detail: |&IoError| -> String) -> IoResult<T> {
-        self.map_err(|mut e| {
+    fn update_err<D>(self, desc: &'static str, detail: D) -> IoResult<T> where
+        D: FnOnce(&IoError) -> String,
+    {
+        self.map_err(move |mut e| {
             let detail = detail(&e);
             e.desc = desc;
             e.detail = Some(detail);
@@ -445,8 +449,10 @@ impl<T> UpdateIoError<T> for IoResult<T> {
         })
     }
 
-    fn update_detail(self, detail: |&IoError| -> String) -> IoResult<T> {
-        self.map_err(|mut e| { e.detail = Some(detail(&e)); e })
+    fn update_detail<D>(self, detail: D) -> IoResult<T> where
+        D: FnOnce(&IoError) -> String,
+    {
+        self.map_err(move |mut e| { e.detail = Some(detail(&e)); e })
     }
 
     fn update_desc(self, desc: &'static str) -> IoResult<T> {
diff --git a/src/libstd/io/net/ip.rs b/src/libstd/io/net/ip.rs
index f59dd37c0da16..62965c48a2680 100644
--- a/src/libstd/io/net/ip.rs
+++ b/src/libstd/io/net/ip.rs
@@ -22,6 +22,7 @@ use kinds::Copy;
 use io::{mod, IoResult, IoError};
 use io::net;
 use iter::{Iterator, IteratorExt};
+use ops::FnOnce;
 use option::Option;
 use option::Option::{None, Some};
 use result::Result::{Ok, Err};
@@ -100,8 +101,9 @@ impl<'a> Parser<'a> {
     }
 
     // Commit only if parser returns Some
-    fn read_atomically<T>(&mut self, cb: |&mut Parser| -> Option<T>)
-                       -> Option<T> {
+    fn read_atomically<T, F>(&mut self, cb: F) -> Option<T> where
+        F: FnOnce(&mut Parser) -> Option<T>,
+    {
         let pos = self.pos;
         let r = cb(self);
         if r.is_none() {
@@ -111,9 +113,10 @@ impl<'a> Parser<'a> {
     }
 
     // Commit only if parser read till EOF
-    fn read_till_eof<T>(&mut self, cb: |&mut Parser| -> Option<T>)
-                     -> Option<T> {
-        self.read_atomically(|p| {
+    fn read_till_eof<T, F>(&mut self, cb: F) -> Option<T> where
+        F: FnOnce(&mut Parser) -> Option<T>,
+    {
+        self.read_atomically(move |p| {
             match cb(p) {
                 Some(x) => if p.is_eof() {Some(x)} else {None},
                 None => None,
@@ -134,15 +137,16 @@ impl<'a> Parser<'a> {
     }
 
     // Apply 3 parsers sequentially
-    fn read_seq_3<A,
-                  B,
-                  C>(
-                  &mut self,
-                  pa: |&mut Parser| -> Option<A>,
-                  pb: |&mut Parser| -> Option<B>,
-                  pc: |&mut Parser| -> Option<C>)
-                  -> Option<(A, B, C)> {
-        self.read_atomically(|p| {
+    fn read_seq_3<A, B, C, PA, PB, PC>(&mut self,
+                                       pa: PA,
+                                       pb: PB,
+                                       pc: PC)
+                                       -> Option<(A, B, C)> where
+        PA: FnOnce(&mut Parser) -> Option<A>,
+        PB: FnOnce(&mut Parser) -> Option<B>,
+        PC: FnOnce(&mut Parser) -> Option<C>,
+    {
+        self.read_atomically(move |p| {
             let a = pa(p);
             let b = if a.is_some() { pb(p) } else { None };
             let c = if b.is_some() { pc(p) } else { None };
@@ -327,22 +331,22 @@ impl<'a> Parser<'a> {
     }
 
     fn read_socket_addr(&mut self) -> Option<SocketAddr> {
-        let ip_addr = |p: &mut Parser| {
+        let ip_addr = |&: p: &mut Parser| {
             let ipv4_p = |p: &mut Parser| p.read_ip_addr();
             let ipv6_p = |p: &mut Parser| {
-                let open_br = |p: &mut Parser| p.read_given_char('[');
-                let ip_addr = |p: &mut Parser| p.read_ipv6_addr();
-                let clos_br = |p: &mut Parser| p.read_given_char(']');
-                p.read_seq_3::<char, IpAddr, char>(open_br, ip_addr, clos_br)
+                let open_br = |&: p: &mut Parser| p.read_given_char('[');
+                let ip_addr = |&: p: &mut Parser| p.read_ipv6_addr();
+                let clos_br = |&: p: &mut Parser| p.read_given_char(']');
+                p.read_seq_3::<char, IpAddr, char, _, _, _>(open_br, ip_addr, clos_br)
                         .map(|t| match t { (_, ip, _) => ip })
             };
             p.read_or(&mut [ipv4_p, ipv6_p])
         };
-        let colon = |p: &mut Parser| p.read_given_char(':');
-        let port  = |p: &mut Parser| p.read_number(10, 5, 0x10000).map(|n| n as u16);
+        let colon = |&: p: &mut Parser| p.read_given_char(':');
+        let port  = |&: p: &mut Parser| p.read_number(10, 5, 0x10000).map(|n| n as u16);
 
         // host, colon, port
-        self.read_seq_3::<IpAddr, char, u16>(ip_addr, colon, port)
+        self.read_seq_3::<IpAddr, char, u16, _, _, _>(ip_addr, colon, port)
                 .map(|t| match t { (ip, _, port) => SocketAddr { ip: ip, port: port } })
     }
 }
diff --git a/src/libstd/io/net/mod.rs b/src/libstd/io/net/mod.rs
index 09e5639bea944..2056933e6df6f 100644
--- a/src/libstd/io/net/mod.rs
+++ b/src/libstd/io/net/mod.rs
@@ -11,6 +11,7 @@
 //! Networking I/O
 
 use io::{IoError, IoResult, InvalidInput};
+use ops::FnMut;
 use option::Option::None;
 use result::Result::{Ok, Err};
 use self::ip::{SocketAddr, ToSocketAddr};
@@ -23,8 +24,10 @@ pub mod udp;
 pub mod ip;
 pub mod pipe;
 
-fn with_addresses<A: ToSocketAddr, T>(addr: A, action: |SocketAddr| -> IoResult<T>)
-    -> IoResult<T> {
+fn with_addresses<A, T, F>(addr: A, mut action: F) -> IoResult<T> where
+    A: ToSocketAddr,
+    F: FnMut(SocketAddr) -> IoResult<T>,
+{
     const DEFAULT_ERROR: IoError = IoError {
         kind: InvalidInput,
         desc: "no addresses found for hostname",
diff --git a/src/libstd/io/net/udp.rs b/src/libstd/io/net/udp.rs
index a2ad365dd2a0e..b23921ba3594d 100644
--- a/src/libstd/io/net/udp.rs
+++ b/src/libstd/io/net/udp.rs
@@ -18,6 +18,7 @@
 use clone::Clone;
 use io::net::ip::{SocketAddr, IpAddr, ToSocketAddr};
 use io::{Reader, Writer, IoResult};
+use ops::FnOnce;
 use option::Option;
 use result::Result::{Ok, Err};
 use sys::udp::UdpSocket as UdpSocketImp;
@@ -210,7 +211,9 @@ impl UdpStream {
     /// Allows access to the underlying UDP socket owned by this stream. This
     /// is useful to, for example, use the socket to send data to hosts other
     /// than the one that this stream is connected to.
-    pub fn as_socket<T>(&mut self, f: |&mut UdpSocket| -> T) -> T {
+    pub fn as_socket<T, F>(&mut self, f: F) -> T where
+        F: FnOnce(&mut UdpSocket) -> T,
+    {
         f(&mut self.socket)
     }
 
diff --git a/src/libstd/io/stdio.rs b/src/libstd/io/stdio.rs
index 48c333f0733a5..8438c9fb441ed 100644
--- a/src/libstd/io/stdio.rs
+++ b/src/libstd/io/stdio.rs
@@ -39,7 +39,7 @@ use libc;
 use mem;
 use option::Option;
 use option::Option::{Some, None};
-use ops::{Deref, DerefMut};
+use ops::{Deref, DerefMut, FnOnce};
 use result::Result::{Ok, Err};
 use rustrt;
 use rustrt::local::Local;
@@ -85,7 +85,9 @@ enum StdSource {
     File(fs::FileDesc),
 }
 
-fn src<T>(fd: libc::c_int, _readable: bool, f: |StdSource| -> T) -> T {
+fn src<T, F>(fd: libc::c_int, _readable: bool, f: F) -> T where
+    F: FnOnce(StdSource) -> T,
+{
     match tty::TTY::new(fd) {
         Ok(tty) => f(TTY(tty)),
         Err(_) => f(File(fs::FileDesc::new(fd, false))),
@@ -318,7 +320,9 @@ 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 result = if Local::exists(None::<Task>) {
         let mut my_stdout = LOCAL_STDOUT.with(|slot| {
             slot.borrow_mut().take()
diff --git a/src/libstd/num/strconv.rs b/src/libstd/num/strconv.rs
index c41f55d567ff6..d5c27c7fbf82a 100644
--- a/src/libstd/num/strconv.rs
+++ b/src/libstd/num/strconv.rs
@@ -21,6 +21,7 @@ use char::Char;
 use kinds::Copy;
 use num;
 use num::{Int, Float, FPNaN, FPInfinite, ToPrimitive};
+use ops::FnMut;
 use slice::{SlicePrelude, CloneSliceAllocPrelude};
 use str::StrPrelude;
 use string::String;
@@ -93,7 +94,10 @@ impl Copy for SignFormat {}
 /// # Panics
 ///
 /// - Panics if `radix` < 2 or `radix` > 36.
-fn int_to_str_bytes_common<T: Int>(num: T, radix: uint, sign: SignFormat, f: |u8|) {
+fn int_to_str_bytes_common<T, F>(num: T, radix: uint, sign: SignFormat, mut f: F) where
+    T: Int,
+    F: FnMut(u8),
+{
     assert!(2 <= radix && radix <= 36);
 
     let _0: T = Int::zero();
diff --git a/src/libstd/num/u16.rs b/src/libstd/num/u16.rs
index a83a66c23a526..6d9b177574afc 100644
--- a/src/libstd/num/u16.rs
+++ b/src/libstd/num/u16.rs
@@ -15,4 +15,6 @@
 
 pub use core::u16::{BITS, BYTES, MIN, MAX};
 
+use ops::FnOnce;
+
 uint_module!(u16)
diff --git a/src/libstd/num/u32.rs b/src/libstd/num/u32.rs
index 7271203b23b6c..0d6d17fa007bf 100644
--- a/src/libstd/num/u32.rs
+++ b/src/libstd/num/u32.rs
@@ -15,4 +15,6 @@
 
 pub use core::u32::{BITS, BYTES, MIN, MAX};
 
+use ops::FnOnce;
+
 uint_module!(u32)
diff --git a/src/libstd/num/u64.rs b/src/libstd/num/u64.rs
index 25de2f3b25565..ebb5d2946c531 100644
--- a/src/libstd/num/u64.rs
+++ b/src/libstd/num/u64.rs
@@ -15,4 +15,6 @@
 
 pub use core::u64::{BITS, BYTES, MIN, MAX};
 
+use ops::FnOnce;
+
 uint_module!(u64)
diff --git a/src/libstd/num/u8.rs b/src/libstd/num/u8.rs
index 22dedeecf3b10..59aea214aae0c 100644
--- a/src/libstd/num/u8.rs
+++ b/src/libstd/num/u8.rs
@@ -15,4 +15,6 @@
 
 pub use core::u8::{BITS, BYTES, MIN, MAX};
 
+use ops::FnOnce;
+
 uint_module!(u8)
diff --git a/src/libstd/num/uint.rs b/src/libstd/num/uint.rs
index a425aab3aa10c..484d28dfed058 100644
--- a/src/libstd/num/uint.rs
+++ b/src/libstd/num/uint.rs
@@ -15,4 +15,6 @@
 
 pub use core::uint::{BITS, BYTES, MIN, MAX};
 
+use ops::FnOnce;
+
 uint_module!(uint)
diff --git a/src/libstd/num/uint_macros.rs b/src/libstd/num/uint_macros.rs
index 0baefb11cf8f2..bd6f3d4bb286b 100644
--- a/src/libstd/num/uint_macros.rs
+++ b/src/libstd/num/uint_macros.rs
@@ -32,7 +32,9 @@ macro_rules! uint_module (($T:ty) => (
 /// ```
 #[inline]
 #[deprecated = "just use .to_string(), or a BufWriter with write! if you mustn't allocate"]
-pub fn to_str_bytes<U>(n: $T, radix: uint, f: |v: &[u8]| -> U) -> U {
+pub fn to_str_bytes<U, F>(n: $T, radix: uint, f: F) -> U where
+    F: FnOnce(&[u8]) -> U,
+{
     use io::{Writer, Seek};
     // The radix can be as low as 2, so we need at least 64 characters for a
     // base 2 number, and then we need another for a possible '-' character.
diff --git a/src/libstd/os.rs b/src/libstd/os.rs
index 138296cca70d2..38411fd6254da 100644
--- a/src/libstd/os.rs
+++ b/src/libstd/os.rs
@@ -40,7 +40,7 @@ use kinds::Copy;
 use libc::{c_void, c_int};
 use libc;
 use boxed::Box;
-use ops::Drop;
+use ops::{Drop, FnOnce};
 use option::Option;
 use option::Option::{Some, None};
 use os;
@@ -172,8 +172,9 @@ pub mod windoze {
     use str::StrPrelude;
     use vec::Vec;
 
-    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;
@@ -212,7 +213,9 @@ pub mod windoze {
 Accessing environment variables is not generally threadsafe.
 Serialize access through a global lock.
 */
-fn with_env_lock<T>(f: || -> T) -> T {
+fn with_env_lock<T, F>(f: F) -> T where
+    F: FnOnce() -> T,
+{
     use sync::{StaticMutex, MUTEX_INIT};
 
     static LOCK: StaticMutex = MUTEX_INIT;
diff --git a/src/libstd/sync/once.rs b/src/libstd/sync/once.rs
index a75088120f869..1bcdc760fc680 100644
--- a/src/libstd/sync/once.rs
+++ b/src/libstd/sync/once.rs
@@ -15,6 +15,7 @@
 
 use int;
 use mem::drop;
+use ops::FnOnce;
 use sync::atomic;
 use sync::{StaticMutex, MUTEX_INIT};
 
@@ -57,7 +58,7 @@ impl Once {
     ///
     /// When this function returns, it is guaranteed that some initialization
     /// has run and completed (it may not be the closure specified).
-    pub fn doit(&'static self, f: ||) {
+    pub fn doit<F>(&'static self, f: F) where F: FnOnce() {
         // Optimize common path: load is much cheaper than fetch_add.
         if self.cnt.load(atomic::SeqCst) < 0 {
             return
diff --git a/src/libstd/sys/common/helper_thread.rs b/src/libstd/sys/common/helper_thread.rs
index c0018c5d97042..6c5fc3005edd2 100644
--- a/src/libstd/sys/common/helper_thread.rs
+++ b/src/libstd/sys/common/helper_thread.rs
@@ -70,9 +70,10 @@ impl<M: Send> Helper<M> {
     /// passed to the helper thread in a separate task.
     ///
     /// This function is safe to be called many times.
-    pub fn boot<T: Send>(&'static self,
-                         f: || -> T,
-                         helper: fn(helper_signal::signal, Receiver<M>, T)) {
+    pub fn boot<T, F>(&'static self, f: F, helper: fn(helper_signal::signal, Receiver<M>, T)) where
+        T: Send,
+        F: FnOnce() -> T,
+    {
         unsafe {
             let _guard = self.lock.lock();
             if !*self.initialized.get() {
diff --git a/src/libstd/sys/common/mod.rs b/src/libstd/sys/common/mod.rs
index f8861c20464dd..73e1c7bd9e5e0 100644
--- a/src/libstd/sys/common/mod.rs
+++ b/src/libstd/sys/common/mod.rs
@@ -69,7 +69,9 @@ pub fn mkerr_libc<T: Int>(ret: T) -> IoResult<()> {
     }
 }
 
-pub fn keep_going(data: &[u8], f: |*const u8, uint| -> i64) -> i64 {
+pub fn keep_going<F>(data: &[u8], mut f: F) -> i64 where
+    F: FnMut(*const u8, uint) -> i64,
+{
     let origamt = data.len();
     let mut data = data.as_ptr();
     let mut amt = origamt;
diff --git a/src/libstd/sys/common/net.rs b/src/libstd/sys/common/net.rs
index ddc6dd021c30f..73da200e16238 100644
--- a/src/libstd/sys/common/net.rs
+++ b/src/libstd/sys/common/net.rs
@@ -344,10 +344,10 @@ pub fn get_host_addresses(host: Option<&str>, servname: Option<&str>,
 // [1] http://twistedmatrix.com/pipermail/twisted-commits/2012-April/034692.html
 // [2] http://stackoverflow.com/questions/19819198/does-send-msg-dontwait
 
-pub fn read<T>(fd: sock_t,
-               deadline: u64,
-               lock: || -> T,
-               read: |bool| -> libc::c_int) -> IoResult<uint> {
+pub fn read<T, L, R>(fd: sock_t, deadline: u64, mut lock: L, mut read: R) -> IoResult<uint> where
+    L: FnMut() -> T,
+    R: FnMut(bool) -> libc::c_int,
+{
     let mut ret = -1;
     if deadline == 0 {
         ret = retry(|| read(false));
@@ -386,12 +386,15 @@ pub fn read<T>(fd: sock_t,
     }
 }
 
-pub fn write<T>(fd: sock_t,
-                deadline: u64,
-                buf: &[u8],
-                write_everything: bool,
-                lock: || -> T,
-                write: |bool, *const u8, uint| -> i64) -> IoResult<uint> {
+pub fn write<T, L, W>(fd: sock_t,
+                      deadline: u64,
+                      buf: &[u8],
+                      write_everything: bool,
+                      mut lock: L,
+                      mut write: W) -> IoResult<uint> where
+    L: FnMut() -> T,
+    W: FnMut(bool, *const u8, uint) -> i64,
+{
     let mut ret = -1;
     let mut written = 0;
     if deadline == 0 {
@@ -674,8 +677,8 @@ impl TcpStream {
 
     pub fn read(&mut self, buf: &mut [u8]) -> IoResult<uint> {
         let fd = self.fd();
-        let dolock = || self.lock_nonblocking();
-        let doread = |nb| unsafe {
+        let dolock = |&:| self.lock_nonblocking();
+        let doread = |&mut: nb| unsafe {
             let flags = if nb {c::MSG_DONTWAIT} else {0};
             libc::recv(fd,
                        buf.as_mut_ptr() as *mut libc::c_void,
@@ -687,8 +690,8 @@ impl TcpStream {
 
     pub fn write(&mut self, buf: &[u8]) -> IoResult<()> {
         let fd = self.fd();
-        let dolock = || self.lock_nonblocking();
-        let dowrite = |nb: bool, buf: *const u8, len: uint| unsafe {
+        let dolock = |&:| self.lock_nonblocking();
+        let dowrite = |&: nb: bool, buf: *const u8, len: uint| unsafe {
             let flags = if nb {c::MSG_DONTWAIT} else {0};
             libc::send(fd,
                        buf as *const _,
@@ -822,7 +825,7 @@ impl UdpSocket {
         let mut addrlen: libc::socklen_t =
                 mem::size_of::<libc::sockaddr_storage>() as libc::socklen_t;
 
-        let dolock = || self.lock_nonblocking();
+        let dolock = |&:| self.lock_nonblocking();
         let n = try!(read(fd, self.read_deadline, dolock, |nb| unsafe {
             let flags = if nb {c::MSG_DONTWAIT} else {0};
             libc::recvfrom(fd,
@@ -843,8 +846,8 @@ impl UdpSocket {
         let dstp = &storage as *const _ as *const libc::sockaddr;
 
         let fd = self.fd();
-        let dolock = || self.lock_nonblocking();
-        let dowrite = |nb, buf: *const u8, len: uint| unsafe {
+        let dolock = |&: | self.lock_nonblocking();
+        let dowrite = |&mut: nb, buf: *const u8, len: uint| unsafe {
             let flags = if nb {c::MSG_DONTWAIT} else {0};
             libc::sendto(fd,
                          buf as *const libc::c_void,
diff --git a/src/libstd/sys/unix/mod.rs b/src/libstd/sys/unix/mod.rs
index 4effedbe3abd8..107263c31a766 100644
--- a/src/libstd/sys/unix/mod.rs
+++ b/src/libstd/sys/unix/mod.rs
@@ -125,7 +125,10 @@ pub fn decode_error_detailed(errno: i32) -> IoError {
 }
 
 #[inline]
-pub fn retry<T: SignedInt> (f: || -> T) -> T {
+pub fn retry<T, F> (mut f: F) -> T where
+    T: SignedInt,
+    F: FnMut() -> T,
+{
     let one: T = Int::one();
     loop {
         let n = f();
diff --git a/src/libstd/sys/unix/pipe.rs b/src/libstd/sys/unix/pipe.rs
index 08e6f7059d8c6..26fd410a7a9b6 100644
--- a/src/libstd/sys/unix/pipe.rs
+++ b/src/libstd/sys/unix/pipe.rs
@@ -149,8 +149,8 @@ impl UnixStream {
 
     pub fn read(&mut self, buf: &mut [u8]) -> IoResult<uint> {
         let fd = self.fd();
-        let dolock = || self.lock_nonblocking();
-        let doread = |nb| unsafe {
+        let dolock = |&:| self.lock_nonblocking();
+        let doread = |&mut: nb| unsafe {
             let flags = if nb {c::MSG_DONTWAIT} else {0};
             libc::recv(fd,
                        buf.as_mut_ptr() as *mut libc::c_void,
@@ -162,8 +162,8 @@ impl UnixStream {
 
     pub fn write(&mut self, buf: &[u8]) -> IoResult<()> {
         let fd = self.fd();
-        let dolock = || self.lock_nonblocking();
-        let dowrite = |nb: bool, buf: *const u8, len: uint| unsafe {
+        let dolock = |&: | self.lock_nonblocking();
+        let dowrite = |&: nb: bool, buf: *const u8, len: uint| unsafe {
             let flags = if nb {c::MSG_DONTWAIT} else {0};
             libc::send(fd,
                        buf as *const _,
diff --git a/src/libstd/sys/windows/mod.rs b/src/libstd/sys/windows/mod.rs
index 9fce308cb9468..41361a0cde695 100644
--- a/src/libstd/sys/windows/mod.rs
+++ b/src/libstd/sys/windows/mod.rs
@@ -138,7 +138,7 @@ pub fn decode_error_detailed(errno: i32) -> IoError {
 }
 
 #[inline]
-pub fn retry<I> (f: || -> I) -> I { f() } // PR rust-lang/rust/#17020
+pub fn retry<I, F>(f: F) -> I where F: FnOnce() -> I { f() } // PR rust-lang/rust/#17020
 
 pub fn ms_to_timeval(ms: u64) -> libc::timeval {
     libc::timeval {
diff --git a/src/libstd/sys/windows/process.rs b/src/libstd/sys/windows/process.rs
index adbcff8a53f6e..356d6f02565ed 100644
--- a/src/libstd/sys/windows/process.rs
+++ b/src/libstd/sys/windows/process.rs
@@ -418,9 +418,8 @@ fn make_command_line(prog: &CString, args: &[CString]) -> String {
     }
 }
 
-fn with_envp<K, V, T>(env: Option<&collections::HashMap<K, V>>,
-                      cb: |*mut c_void| -> T) -> T
-    where K: BytesContainer + Eq + Hash, V: BytesContainer
+fn with_envp<K, V, T, F>(env: Option<&collections::HashMap<K, V>>, cb: F) -> T where
+    K: BytesContainer + Eq + Hash, V: BytesContainer, F: FnOnce(*mut c_void) -> T,
 {
     // On Windows we pass an "environment block" which is not a char**, but
     // rather a concatenation of null-terminated k=v\0 sequences, with a final
@@ -445,7 +444,9 @@ fn with_envp<K, V, T>(env: Option<&collections::HashMap<K, V>>,
     }
 }
 
-fn with_dirp<T>(d: Option<&CString>, cb: |*const u16| -> T) -> T {
+fn with_dirp<T, F>(d: Option<&CString>, cb: F) -> T where
+    F: FnOnce(*const u16) -> T,
+{
     match d {
       Some(dir) => {
           let dir_str = dir.as_str()
diff --git a/src/libstd/task.rs b/src/libstd/task.rs
index c91417e611ed1..5a1a5b4fb7a10 100644
--- a/src/libstd/task.rs
+++ b/src/libstd/task.rs
@@ -381,7 +381,9 @@ mod test {
         rx.recv();
     }
 
-    fn avoid_copying_the_body(spawnfn: |v: proc():Send|) {
+    fn avoid_copying_the_body<F>(spawnfn: F) where
+        F: FnOnce(proc():Send),
+    {
         let (tx, rx) = channel::<uint>();
 
         let x = box 1;
diff --git a/src/libstd/thread_local/mod.rs b/src/libstd/thread_local/mod.rs
index 029b8bf113877..b85b6eccb7718 100644
--- a/src/libstd/thread_local/mod.rs
+++ b/src/libstd/thread_local/mod.rs
@@ -218,7 +218,9 @@ impl<T: 'static> Key<T> {
     /// This function will `panic!()` if the key currently has its
     /// destructor running, and it **may** panic if the destructor has
     /// previously been run for this thread.
-    pub fn with<R>(&'static self, f: |&T| -> R) -> R {
+    pub fn with<R, F>(&'static self, f: F) -> R where
+        F: FnOnce(&T) -> R,
+    {
         let slot = (self.inner)();
         unsafe {
             let slot = slot.get().expect("cannot access a TLS value during or \
diff --git a/src/libstd/thread_local/scoped.rs b/src/libstd/thread_local/scoped.rs
index 11d539c4f9fa8..ee742ab83751d 100644
--- a/src/libstd/thread_local/scoped.rs
+++ b/src/libstd/thread_local/scoped.rs
@@ -135,7 +135,9 @@ impl<T> Key<T> {
     ///     assert_eq!(val, 100);
     /// });
     /// ```
-    pub fn set<R>(&'static self, t: &T, cb: || -> R) -> R {
+    pub fn set<R, F>(&'static self, t: &T, cb: F) -> R where
+        F: FnOnce() -> R,
+    {
         struct Reset<'a, T: 'a> {
             key: &'a KeyInner<T>,
             val: *mut T,
@@ -175,7 +177,9 @@ impl<T> Key<T> {
     ///     // work with `slot`
     /// });
     /// ```
-    pub fn with<R>(&'static self, cb: |&T| -> R) -> R {
+    pub fn with<R, F>(&'static self, cb: F) -> R where
+        F: FnOnce(&T) -> R
+    {
         unsafe {
             let ptr = self.inner.get();
             assert!(!ptr.is_null(), "cannot access a scoped thread local \
diff --git a/src/libstd/time/duration.rs b/src/libstd/time/duration.rs
index 7e6065129a384..34a3d6aa27536 100644
--- a/src/libstd/time/duration.rs
+++ b/src/libstd/time/duration.rs
@@ -14,7 +14,7 @@
 
 use {fmt, i64};
 use kinds::Copy;
-use ops::{Add, Sub, Mul, Div, Neg};
+use ops::{Add, Sub, Mul, Div, Neg, FnOnce};
 use option::Option;
 use option::Option::{Some, None};
 use num::Int;
@@ -141,7 +141,7 @@ impl Duration {
 
     /// Runs a closure, returning the duration of time it took to run the
     /// closure.
-    pub fn span(f: ||) -> Duration {
+    pub fn span<F>(f: F) -> Duration where F: FnOnce() {
         let before = super::precise_time_ns();
         f();
         Duration::nanoseconds((super::precise_time_ns() - before) as i64)

From 2160427900ea675e494274d42a8d8485724f440e Mon Sep 17 00:00:00 2001
From: Jorge Aparicio <japaricious@gmail.com>
Date: Mon, 8 Dec 2014 08:35:34 -0500
Subject: [PATCH 76/92] Fix benches

---
 src/test/bench/core-map.rs |  4 +++-
 src/test/bench/core-set.rs | 16 +++++++++-------
 src/test/bench/core-std.rs |  3 ++-
 3 files changed, 14 insertions(+), 9 deletions(-)

diff --git a/src/test/bench/core-map.rs b/src/test/bench/core-map.rs
index bbbd878e8b8ad..112d4fd0912d4 100644
--- a/src/test/bench/core-map.rs
+++ b/src/test/bench/core-map.rs
@@ -8,13 +8,15 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#![feature(unboxed_closures)]
+
 use std::collections::{TrieMap, TreeMap, HashMap, HashSet};
 use std::os;
 use std::rand::{Rng, IsaacRng, SeedableRng};
 use std::time::Duration;
 use std::uint;
 
-fn timed(label: &str, f: ||) {
+fn timed<F>(label: &str, f: F) where F: FnMut() {
     println!("  {}: {}", label, Duration::span(f));
 }
 
diff --git a/src/test/bench/core-set.rs b/src/test/bench/core-set.rs
index 07300b73c85a7..38c31da1a6d32 100644
--- a/src/test/bench/core-set.rs
+++ b/src/test/bench/core-set.rs
@@ -10,6 +10,8 @@
 
 // ignore-pretty very bad with line comments
 
+#![feature(unboxed_closures)]
+
 extern crate collections;
 extern crate rand;
 
@@ -31,7 +33,7 @@ struct Results {
     delete_strings: Duration,
 }
 
-fn timed(result: &mut Duration, op: ||) {
+fn timed<F>(result: &mut Duration, op: F) where F: FnOnce() {
     *result = Duration::span(op);
 }
 
@@ -66,7 +68,7 @@ impl Results {
                      rand_cap: uint,
                      f: || -> T) { {
             let mut set = f();
-            timed(&mut self.sequential_ints, || {
+            timed(&mut self.sequential_ints, move || {
                 for i in range(0u, num_keys) {
                     set.insert(i);
                 }
@@ -79,7 +81,7 @@ impl Results {
 
         {
             let mut set = f();
-            timed(&mut self.random_ints, || {
+            timed(&mut self.random_ints, move || {
                 for _ in range(0, num_keys) {
                     set.insert(rng.gen::<uint>() % rand_cap);
                 }
@@ -92,7 +94,7 @@ impl Results {
                 set.insert(i);
             }
 
-            timed(&mut self.delete_ints, || {
+            timed(&mut self.delete_ints, move || {
                 for i in range(0u, num_keys) {
                     assert!(set.remove(&i));
                 }
@@ -108,7 +110,7 @@ impl Results {
                      f: || -> T) {
         {
             let mut set = f();
-            timed(&mut self.sequential_strings, || {
+            timed(&mut self.sequential_strings, move || {
                 for i in range(0u, num_keys) {
                     set.insert(i.to_string());
                 }
@@ -121,7 +123,7 @@ impl Results {
 
         {
             let mut set = f();
-            timed(&mut self.random_strings, || {
+            timed(&mut self.random_strings, move || {
                 for _ in range(0, num_keys) {
                     let s = rng.gen::<uint>().to_string();
                     set.insert(s);
@@ -134,7 +136,7 @@ impl Results {
             for i in range(0u, num_keys) {
                 set.insert(i.to_string());
             }
-            timed(&mut self.delete_strings, || {
+            timed(&mut self.delete_strings, move || {
                 for i in range(0u, num_keys) {
                     assert!(set.remove(&i.to_string()));
                 }
diff --git a/src/test/bench/core-std.rs b/src/test/bench/core-std.rs
index 24bd26b028813..6e2cd508291e0 100644
--- a/src/test/bench/core-std.rs
+++ b/src/test/bench/core-std.rs
@@ -12,6 +12,7 @@
 // Microbenchmarks for various functions in std and extra
 
 #![feature(macro_rules)]
+#![feature(unboxed_closures)]
 
 use std::io::File;
 use std::mem::swap;
@@ -41,7 +42,7 @@ fn main() {
     bench!(is_utf8_multibyte);
 }
 
-fn maybe_run_test(argv: &[String], name: String, test: ||) {
+fn maybe_run_test<F>(argv: &[String], name: String, test: F) where F: FnOnce() {
     let mut run_test = false;
 
     if os::getenv("RUST_BENCH").is_some() {

From 0dac05dd627612232403c07ca8bd6d3376eec64a Mon Sep 17 00:00:00 2001
From: Jorge Aparicio <japaricious@gmail.com>
Date: Mon, 8 Dec 2014 13:28:32 -0500
Subject: [PATCH 77/92] libsyntax: use unboxed closures

---
 src/libsyntax/ast_map/blocks.rs            |  15 +--
 src/libsyntax/ast_map/mod.rs               |  12 +-
 src/libsyntax/ast_util.rs                  |  11 +-
 src/libsyntax/attr.rs                      |   7 +-
 src/libsyntax/codemap.rs                   |   4 +-
 src/libsyntax/config.rs                    |  82 +++++++++----
 src/libsyntax/diagnostic.rs                |   4 +-
 src/libsyntax/diagnostics/plugin.rs        |  12 +-
 src/libsyntax/ext/deriving/bounds.rs       |  13 +-
 src/libsyntax/ext/deriving/clone.rs        |  12 +-
 src/libsyntax/ext/deriving/cmp/eq.rs       |  12 +-
 src/libsyntax/ext/deriving/cmp/ord.rs      |  12 +-
 src/libsyntax/ext/deriving/cmp/totaleq.rs  |  12 +-
 src/libsyntax/ext/deriving/cmp/totalord.rs |  12 +-
 src/libsyntax/ext/deriving/decodable.rs    |  26 ++--
 src/libsyntax/ext/deriving/default.rs      |  12 +-
 src/libsyntax/ext/deriving/encodable.rs    |  12 +-
 src/libsyntax/ext/deriving/generic/mod.rs  |  62 +++++-----
 src/libsyntax/ext/deriving/hash.rs         |  12 +-
 src/libsyntax/ext/deriving/primitive.rs    |  12 +-
 src/libsyntax/ext/deriving/rand.rs         |  28 +++--
 src/libsyntax/ext/deriving/show.rs         |  12 +-
 src/libsyntax/ext/deriving/zero.rs         |  12 +-
 src/libsyntax/ext/expand.rs                |  12 +-
 src/libsyntax/ext/mtwt.rs                  |  12 +-
 src/libsyntax/fold.rs                      |   6 +-
 src/libsyntax/parse/lexer/mod.rs           |   8 +-
 src/libsyntax/parse/parser.rs              | 132 ++++++++++++---------
 src/libsyntax/print/pprust.rs              |  30 +++--
 src/libsyntax/ptr.rs                       |   8 +-
 src/libsyntax/util/parser_testing.rs       |   4 +-
 src/libsyntax/util/small_vector.rs         |   2 +-
 32 files changed, 377 insertions(+), 245 deletions(-)

diff --git a/src/libsyntax/ast_map/blocks.rs b/src/libsyntax/ast_map/blocks.rs
index 639a33a806395..75f69f2f6d062 100644
--- a/src/libsyntax/ast_map/blocks.rs
+++ b/src/libsyntax/ast_map/blocks.rs
@@ -181,22 +181,23 @@ impl<'a> FnLikeNode<'a> {
     }
 
     pub fn kind(self) -> visit::FnKind<'a> {
-        let item = |p: ItemFnParts<'a>| -> visit::FnKind<'a> {
+        let item = |: p: ItemFnParts<'a>| -> visit::FnKind<'a> {
             visit::FkItemFn(p.ident, p.generics, p.style, p.abi)
         };
-        let closure = |_: ClosureParts| {
+        let closure = |: _: ClosureParts| {
             visit::FkFnBlock
         };
-        let method = |m: &'a ast::Method| {
+        let method = |: m: &'a ast::Method| {
             visit::FkMethod(m.pe_ident(), m.pe_generics(), m)
         };
         self.handle(item, method, closure)
     }
 
-    fn handle<A>(self,
-                 item_fn: |ItemFnParts<'a>| -> A,
-                 method: |&'a ast::Method| -> A,
-                 closure: |ClosureParts<'a>| -> A) -> A {
+    fn handle<A, I, M, C>(self, item_fn: I, method: M, closure: C) -> A where
+        I: FnOnce(ItemFnParts<'a>) -> A,
+        M: FnOnce(&'a ast::Method) -> A,
+        C: FnOnce(ClosureParts<'a>) -> A,
+    {
         match self.node {
             ast_map::NodeItem(i) => match i.node {
                 ast::ItemFn(ref decl, style, abi, ref generics, ref block) =>
diff --git a/src/libsyntax/ast_map/mod.rs b/src/libsyntax/ast_map/mod.rs
index 2c985f403f851..907ac6b19fc0d 100644
--- a/src/libsyntax/ast_map/mod.rs
+++ b/src/libsyntax/ast_map/mod.rs
@@ -424,7 +424,9 @@ impl<'ast> Map<'ast> {
         }
     }
 
-    pub fn with_path<T>(&self, id: NodeId, f: |PathElems| -> T) -> T {
+    pub fn with_path<T, F>(&self, id: NodeId, f: F) -> T where
+        F: FnOnce(PathElems) -> T,
+    {
         self.with_path_next(id, None, f)
     }
 
@@ -438,7 +440,9 @@ impl<'ast> Map<'ast> {
         })
     }
 
-    fn with_path_next<T>(&self, id: NodeId, next: LinkedPath, f: |PathElems| -> T) -> T {
+    fn with_path_next<T, F>(&self, id: NodeId, next: LinkedPath, f: F) -> T where
+        F: FnOnce(PathElems) -> T,
+    {
         let parent = self.get_parent(id);
         let parent = match self.find_entry(id) {
             Some(EntryForeignItem(..)) | Some(EntryVariant(..)) => {
@@ -470,7 +474,9 @@ impl<'ast> Map<'ast> {
 
     /// Given a node ID and a closure, apply the closure to the array
     /// of attributes associated with the AST corresponding to the Node ID
-    pub fn with_attrs<T>(&self, id: NodeId, f: |Option<&[Attribute]>| -> T) -> T {
+    pub fn with_attrs<T, F>(&self, id: NodeId, f: F) -> T where
+        F: FnOnce(Option<&[Attribute]>) -> T,
+    {
         let attrs = match self.get(id) {
             NodeItem(i) => Some(i.attrs.as_slice()),
             NodeForeignItem(fi) => Some(fi.attrs.as_slice()),
diff --git a/src/libsyntax/ast_util.rs b/src/libsyntax/ast_util.rs
index eec3f69ee64de..7579972c6d843 100644
--- a/src/libsyntax/ast_util.rs
+++ b/src/libsyntax/ast_util.rs
@@ -602,6 +602,7 @@ 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;
@@ -632,21 +633,21 @@ pub fn walk_pat(pat: &Pat, it: |&Pat| -> bool) -> bool {
 }
 
 pub trait EachViewItem {
-    fn each_view_item(&self, f: |&ast::ViewItem| -> bool) -> bool;
+    fn each_view_item<F>(&self, f: F) -> bool where F: FnMut(&ast::ViewItem) -> bool;
 }
 
-struct EachViewItemData<'a> {
-    callback: |&ast::ViewItem|: 'a -> bool,
+struct EachViewItemData<F> where F: FnMut(&ast::ViewItem) -> bool {
+    callback: F,
 }
 
-impl<'a, 'v> Visitor<'v> for EachViewItemData<'a> {
+impl<'v, F> Visitor<'v> for EachViewItemData<F> where F: FnMut(&ast::ViewItem) -> bool {
     fn visit_view_item(&mut self, view_item: &ast::ViewItem) {
         let _ = (self.callback)(view_item);
     }
 }
 
 impl EachViewItem for ast::Crate {
-    fn each_view_item(&self, f: |&ast::ViewItem| -> bool) -> bool {
+    fn each_view_item<F>(&self, f: F) -> bool where F: FnMut(&ast::ViewItem) -> bool {
         let mut visit = EachViewItemData {
             callback: f,
         };
diff --git a/src/libsyntax/attr.rs b/src/libsyntax/attr.rs
index 5894a88ece65a..8248eae4b8cdd 100644
--- a/src/libsyntax/attr.rs
+++ b/src/libsyntax/attr.rs
@@ -115,7 +115,8 @@ impl AttrMetaMethods for P<MetaItem> {
 
 pub trait AttributeMethods {
     fn meta<'a>(&'a self) -> &'a MetaItem;
-    fn with_desugared_doc<T>(&self, f: |&Attribute| -> T) -> T;
+    fn with_desugared_doc<T, F>(&self, f: F) -> T where
+        F: FnOnce(&Attribute) -> T;
 }
 
 impl AttributeMethods for Attribute {
@@ -127,7 +128,9 @@ impl AttributeMethods for Attribute {
     /// Convert self to a normal #[doc="foo"] comment, if it is a
     /// comment like `///` or `/** */`. (Returns self unchanged for
     /// non-sugared doc attributes.)
-    fn with_desugared_doc<T>(&self, f: |&Attribute| -> T) -> T {
+    fn with_desugared_doc<T, F>(&self, f: F) -> T where
+        F: FnOnce(&Attribute) -> T,
+    {
         if self.node.is_sugared_doc {
             let comment = self.value_str().unwrap();
             let meta = mk_name_value_item_str(
diff --git a/src/libsyntax/codemap.rs b/src/libsyntax/codemap.rs
index 7f2becf820147..d2fe667339c84 100644
--- a/src/libsyntax/codemap.rs
+++ b/src/libsyntax/codemap.rs
@@ -568,7 +568,9 @@ impl CodeMap {
         ExpnId(expansions.len().to_u32().expect("too many ExpnInfo's!") - 1)
     }
 
-    pub fn with_expn_info<T>(&self, id: ExpnId, f: |Option<&ExpnInfo>| -> T) -> T {
+    pub fn with_expn_info<T, F>(&self, id: ExpnId, f: F) -> T where
+        F: FnOnce(Option<&ExpnInfo>) -> T,
+    {
         match id {
             NO_EXPANSION => f(None),
             ExpnId(i) => f(Some(&(*self.expansions.borrow())[i as uint]))
diff --git a/src/libsyntax/config.rs b/src/libsyntax/config.rs
index 4f718555d5331..87426dce91817 100644
--- a/src/libsyntax/config.rs
+++ b/src/libsyntax/config.rs
@@ -19,8 +19,8 @@ use util::small_vector::SmallVector;
 
 /// A folder that strips out items that do not belong in the current
 /// configuration.
-struct Context<'a> {
-    in_cfg: |attrs: &[ast::Attribute]|: 'a -> bool,
+struct Context<F> where F: FnMut(&[ast::Attribute]) -> bool {
+    in_cfg: F,
 }
 
 // Support conditional compilation by transforming the AST, stripping out
@@ -30,7 +30,7 @@ pub fn strip_unconfigured_items(diagnostic: &SpanHandler, krate: ast::Crate) ->
     strip_items(krate, |attrs| in_cfg(diagnostic, config.as_slice(), attrs))
 }
 
-impl<'a> fold::Folder for Context<'a> {
+impl<F> fold::Folder for Context<F> where F: FnMut(&[ast::Attribute]) -> bool {
     fn fold_mod(&mut self, module: ast::Mod) -> ast::Mod {
         fold_mod(self, module)
     }
@@ -54,16 +54,20 @@ impl<'a> fold::Folder for Context<'a> {
     }
 }
 
-pub fn strip_items(krate: ast::Crate,
-                   in_cfg: |attrs: &[ast::Attribute]| -> bool)
-                   -> ast::Crate {
+pub fn strip_items<F>(krate: ast::Crate, in_cfg: F) -> ast::Crate where
+    F: FnMut(&[ast::Attribute]) -> bool,
+{
     let mut ctxt = Context {
         in_cfg: in_cfg,
     };
     ctxt.fold_crate(krate)
 }
 
-fn filter_view_item(cx: &mut Context, view_item: ast::ViewItem) -> Option<ast::ViewItem> {
+fn filter_view_item<F>(cx: &mut Context<F>,
+                       view_item: ast::ViewItem)
+                       -> Option<ast::ViewItem> where
+    F: FnMut(&[ast::Attribute]) -> bool
+{
     if view_item_in_cfg(cx, &view_item) {
         Some(view_item)
     } else {
@@ -71,7 +75,11 @@ fn filter_view_item(cx: &mut Context, view_item: ast::ViewItem) -> Option<ast::V
     }
 }
 
-fn fold_mod(cx: &mut Context, ast::Mod {inner, view_items, items}: ast::Mod) -> ast::Mod {
+fn fold_mod<F>(cx: &mut Context<F>,
+               ast::Mod {inner,
+               view_items, items}: ast::Mod) -> ast::Mod where
+    F: FnMut(&[ast::Attribute]) -> bool
+{
     ast::Mod {
         inner: inner,
         view_items: view_items.into_iter().filter_map(|a| {
@@ -83,8 +91,11 @@ fn fold_mod(cx: &mut Context, ast::Mod {inner, view_items, items}: ast::Mod) ->
     }
 }
 
-fn filter_foreign_item(cx: &mut Context, item: P<ast::ForeignItem>)
-                       -> Option<P<ast::ForeignItem>> {
+fn filter_foreign_item<F>(cx: &mut Context<F>,
+                          item: P<ast::ForeignItem>)
+                          -> Option<P<ast::ForeignItem>> where
+    F: FnMut(&[ast::Attribute]) -> bool
+{
     if foreign_item_in_cfg(cx, &*item) {
         Some(item)
     } else {
@@ -92,8 +103,11 @@ fn filter_foreign_item(cx: &mut Context, item: P<ast::ForeignItem>)
     }
 }
 
-fn fold_foreign_mod(cx: &mut Context, ast::ForeignMod {abi, view_items, items}: ast::ForeignMod)
-                    -> ast::ForeignMod {
+fn fold_foreign_mod<F>(cx: &mut Context<F>,
+                       ast::ForeignMod {abi, view_items, items}: ast::ForeignMod)
+                       -> ast::ForeignMod where
+    F: FnMut(&[ast::Attribute]) -> bool
+{
     ast::ForeignMod {
         abi: abi,
         view_items: view_items.into_iter().filter_map(|a| {
@@ -105,7 +119,9 @@ fn fold_foreign_mod(cx: &mut Context, ast::ForeignMod {abi, view_items, items}:
     }
 }
 
-fn fold_item(cx: &mut Context, item: P<ast::Item>) -> SmallVector<P<ast::Item>> {
+fn fold_item<F>(cx: &mut Context<F>, item: P<ast::Item>) -> SmallVector<P<ast::Item>> where
+    F: FnMut(&[ast::Attribute]) -> bool
+{
     if item_in_cfg(cx, &*item) {
         SmallVector::one(item.map(|i| cx.fold_item_simple(i)))
     } else {
@@ -113,7 +129,9 @@ fn fold_item(cx: &mut Context, item: P<ast::Item>) -> SmallVector<P<ast::Item>>
     }
 }
 
-fn fold_item_underscore(cx: &mut Context, item: ast::Item_) -> ast::Item_ {
+fn fold_item_underscore<F>(cx: &mut Context<F>, item: ast::Item_) -> ast::Item_ where
+    F: FnMut(&[ast::Attribute]) -> bool
+{
     let item = match item {
         ast::ItemImpl(a, b, c, impl_items) => {
             let impl_items = impl_items.into_iter()
@@ -166,7 +184,9 @@ fn fold_item_underscore(cx: &mut Context, item: ast::Item_) -> ast::Item_ {
     fold::noop_fold_item_underscore(item, cx)
 }
 
-fn fold_struct(cx: &mut Context, def: P<ast::StructDef>) -> P<ast::StructDef> {
+fn fold_struct<F>(cx: &mut Context<F>, def: P<ast::StructDef>) -> P<ast::StructDef> where
+    F: FnMut(&[ast::Attribute]) -> bool
+{
     def.map(|ast::StructDef { fields, ctor_id }| {
         ast::StructDef {
             fields: fields.into_iter().filter(|m| {
@@ -177,7 +197,9 @@ fn fold_struct(cx: &mut Context, def: P<ast::StructDef>) -> P<ast::StructDef> {
     })
 }
 
-fn retain_stmt(cx: &mut Context, stmt: &ast::Stmt) -> bool {
+fn retain_stmt<F>(cx: &mut Context<F>, stmt: &ast::Stmt) -> bool where
+    F: FnMut(&[ast::Attribute]) -> bool
+{
     match stmt.node {
         ast::StmtDecl(ref decl, _) => {
             match decl.node {
@@ -191,7 +213,9 @@ fn retain_stmt(cx: &mut Context, stmt: &ast::Stmt) -> bool {
     }
 }
 
-fn fold_block(cx: &mut Context, b: P<ast::Block>) -> P<ast::Block> {
+fn fold_block<F>(cx: &mut Context<F>, b: P<ast::Block>) -> P<ast::Block> where
+    F: FnMut(&[ast::Attribute]) -> bool
+{
     b.map(|ast::Block {id, view_items, stmts, expr, rules, span}| {
         let resulting_stmts: Vec<P<ast::Stmt>> =
             stmts.into_iter().filter(|a| retain_stmt(cx, &**a)).collect();
@@ -212,7 +236,9 @@ fn fold_block(cx: &mut Context, b: P<ast::Block>) -> P<ast::Block> {
     })
 }
 
-fn fold_expr(cx: &mut Context, expr: P<ast::Expr>) -> P<ast::Expr> {
+fn fold_expr<F>(cx: &mut Context<F>, expr: P<ast::Expr>) -> P<ast::Expr> where
+    F: FnMut(&[ast::Attribute]) -> bool
+{
     expr.map(|ast::Expr {id, span, node}| {
         fold::noop_fold_expr(ast::Expr {
             id: id,
@@ -229,19 +255,27 @@ fn fold_expr(cx: &mut Context, expr: P<ast::Expr>) -> P<ast::Expr> {
     })
 }
 
-fn item_in_cfg(cx: &mut Context, item: &ast::Item) -> bool {
+fn item_in_cfg<F>(cx: &mut Context<F>, item: &ast::Item) -> bool where
+    F: FnMut(&[ast::Attribute]) -> bool
+{
     return (cx.in_cfg)(item.attrs.as_slice());
 }
 
-fn foreign_item_in_cfg(cx: &mut Context, item: &ast::ForeignItem) -> bool {
+fn foreign_item_in_cfg<F>(cx: &mut Context<F>, item: &ast::ForeignItem) -> bool where
+    F: FnMut(&[ast::Attribute]) -> bool
+{
     return (cx.in_cfg)(item.attrs.as_slice());
 }
 
-fn view_item_in_cfg(cx: &mut Context, item: &ast::ViewItem) -> bool {
+fn view_item_in_cfg<F>(cx: &mut Context<F>, item: &ast::ViewItem) -> bool where
+    F: FnMut(&[ast::Attribute]) -> bool
+{
     return (cx.in_cfg)(item.attrs.as_slice());
 }
 
-fn trait_method_in_cfg(cx: &mut Context, meth: &ast::TraitItem) -> bool {
+fn trait_method_in_cfg<F>(cx: &mut Context<F>, meth: &ast::TraitItem) -> bool where
+    F: FnMut(&[ast::Attribute]) -> bool
+{
     match *meth {
         ast::RequiredMethod(ref meth) => (cx.in_cfg)(meth.attrs.as_slice()),
         ast::ProvidedMethod(ref meth) => (cx.in_cfg)(meth.attrs.as_slice()),
@@ -249,7 +283,9 @@ fn trait_method_in_cfg(cx: &mut Context, meth: &ast::TraitItem) -> bool {
     }
 }
 
-fn impl_item_in_cfg(cx: &mut Context, impl_item: &ast::ImplItem) -> bool {
+fn impl_item_in_cfg<F>(cx: &mut Context<F>, impl_item: &ast::ImplItem) -> bool where
+    F: FnMut(&[ast::Attribute]) -> bool
+{
     match *impl_item {
         ast::MethodImplItem(ref meth) => (cx.in_cfg)(meth.attrs.as_slice()),
         ast::TypeImplItem(ref typ) => (cx.in_cfg)(typ.attrs.as_slice()),
diff --git a/src/libsyntax/diagnostic.rs b/src/libsyntax/diagnostic.rs
index bbda80bd96c33..3a81698792264 100644
--- a/src/libsyntax/diagnostic.rs
+++ b/src/libsyntax/diagnostic.rs
@@ -581,7 +581,9 @@ fn print_macro_backtrace(w: &mut EmitterWriter,
     cs.map_or(Ok(()), |call_site| print_macro_backtrace(w, cm, call_site))
 }
 
-pub fn expect<T>(diag: &SpanHandler, opt: Option<T>, msg: || -> String) -> T {
+pub fn expect<T, M>(diag: &SpanHandler, opt: Option<T>, msg: M) -> T where
+    M: FnOnce() -> String,
+{
     match opt {
         Some(t) => t,
         None => diag.handler().bug(msg().as_slice()),
diff --git a/src/libsyntax/diagnostics/plugin.rs b/src/libsyntax/diagnostics/plugin.rs
index 2be11a236d3b7..cb2a1f8acd8bf 100644
--- a/src/libsyntax/diagnostics/plugin.rs
+++ b/src/libsyntax/diagnostics/plugin.rs
@@ -25,14 +25,18 @@ thread_local!(static USED_DIAGNOSTICS: RefCell<HashMap<Name, Span>> = {
     RefCell::new(HashMap::new())
 })
 
-fn with_registered_diagnostics<T>(f: |&mut HashMap<Name, Option<Name>>| -> T) -> T {
-    REGISTERED_DIAGNOSTICS.with(|slot| {
+fn with_registered_diagnostics<T, F>(f: F) -> T where
+    F: FnOnce(&mut HashMap<Name, Option<Name>>) -> T,
+{
+    REGISTERED_DIAGNOSTICS.with(move |slot| {
         f(&mut *slot.borrow_mut())
     })
 }
 
-fn with_used_diagnostics<T>(f: |&mut HashMap<Name, Span>| -> T) -> T {
-    USED_DIAGNOSTICS.with(|slot| {
+fn with_used_diagnostics<T, F>(f: F) -> T where
+    F: FnOnce(&mut HashMap<Name, Span>) -> T,
+{
+    USED_DIAGNOSTICS.with(move |slot| {
         f(&mut *slot.borrow_mut())
     })
 }
diff --git a/src/libsyntax/ext/deriving/bounds.rs b/src/libsyntax/ext/deriving/bounds.rs
index 0595b0bc7f440..3145b3bb1a4fe 100644
--- a/src/libsyntax/ext/deriving/bounds.rs
+++ b/src/libsyntax/ext/deriving/bounds.rs
@@ -15,12 +15,13 @@ use ext::deriving::generic::*;
 use ext::deriving::generic::ty::*;
 use ptr::P;
 
-pub fn expand_deriving_bound(cx: &mut ExtCtxt,
-                             span: Span,
-                             mitem: &MetaItem,
-                             item: &Item,
-                             push: |P<Item>|) {
-
+pub fn expand_deriving_bound<F>(cx: &mut ExtCtxt,
+                                span: Span,
+                                mitem: &MetaItem,
+                                item: &Item,
+                                push: F) where
+    F: FnOnce(P<Item>),
+{
     let name = match mitem.node {
         MetaWord(ref tname) => {
             match tname.get() {
diff --git a/src/libsyntax/ext/deriving/clone.rs b/src/libsyntax/ext/deriving/clone.rs
index f6b8c00e7617f..a34764221b3b6 100644
--- a/src/libsyntax/ext/deriving/clone.rs
+++ b/src/libsyntax/ext/deriving/clone.rs
@@ -17,11 +17,13 @@ use ext::deriving::generic::ty::*;
 use parse::token::InternedString;
 use ptr::P;
 
-pub fn expand_deriving_clone(cx: &mut ExtCtxt,
-                             span: Span,
-                             mitem: &MetaItem,
-                             item: &Item,
-                             push: |P<Item>|) {
+pub fn expand_deriving_clone<F>(cx: &mut ExtCtxt,
+                                span: Span,
+                                mitem: &MetaItem,
+                                item: &Item,
+                                push: F) where
+    F: FnOnce(P<Item>),
+{
     let inline = cx.meta_word(span, InternedString::new("inline"));
     let attrs = vec!(cx.attribute(span, inline));
     let trait_def = TraitDef {
diff --git a/src/libsyntax/ext/deriving/cmp/eq.rs b/src/libsyntax/ext/deriving/cmp/eq.rs
index 7727bb824db3a..c8bf5ec326cd9 100644
--- a/src/libsyntax/ext/deriving/cmp/eq.rs
+++ b/src/libsyntax/ext/deriving/cmp/eq.rs
@@ -17,11 +17,13 @@ use ext::deriving::generic::ty::*;
 use parse::token::InternedString;
 use ptr::P;
 
-pub fn expand_deriving_eq(cx: &mut ExtCtxt,
-                          span: Span,
-                          mitem: &MetaItem,
-                          item: &Item,
-                          push: |P<Item>|) {
+pub fn expand_deriving_eq<F>(cx: &mut ExtCtxt,
+                             span: Span,
+                             mitem: &MetaItem,
+                             item: &Item,
+                             push: F) where
+    F: FnOnce(P<Item>),
+{
     // structures are equal if all fields are equal, and non equal, if
     // any fields are not equal or if the enum variants are different
     fn cs_eq(cx: &mut ExtCtxt, span: Span, substr: &Substructure) -> P<Expr> {
diff --git a/src/libsyntax/ext/deriving/cmp/ord.rs b/src/libsyntax/ext/deriving/cmp/ord.rs
index 1bd55b5d50451..bd1962de56ed9 100644
--- a/src/libsyntax/ext/deriving/cmp/ord.rs
+++ b/src/libsyntax/ext/deriving/cmp/ord.rs
@@ -20,11 +20,13 @@ use ext::deriving::generic::ty::*;
 use parse::token::InternedString;
 use ptr::P;
 
-pub fn expand_deriving_ord(cx: &mut ExtCtxt,
-                           span: Span,
-                           mitem: &MetaItem,
-                           item: &Item,
-                           push: |P<Item>|) {
+pub fn expand_deriving_ord<F>(cx: &mut ExtCtxt,
+                              span: Span,
+                              mitem: &MetaItem,
+                              item: &Item,
+                              push: F) where
+    F: FnOnce(P<Item>),
+{
     macro_rules! md (
         ($name:expr, $op:expr, $equal:expr) => { {
             let inline = cx.meta_word(span, InternedString::new("inline"));
diff --git a/src/libsyntax/ext/deriving/cmp/totaleq.rs b/src/libsyntax/ext/deriving/cmp/totaleq.rs
index ecee2008254dd..2b986bea1221e 100644
--- a/src/libsyntax/ext/deriving/cmp/totaleq.rs
+++ b/src/libsyntax/ext/deriving/cmp/totaleq.rs
@@ -17,11 +17,13 @@ use ext::deriving::generic::ty::*;
 use parse::token::InternedString;
 use ptr::P;
 
-pub fn expand_deriving_totaleq(cx: &mut ExtCtxt,
-                               span: Span,
-                               mitem: &MetaItem,
-                               item: &Item,
-                               push: |P<Item>|) {
+pub fn expand_deriving_totaleq<F>(cx: &mut ExtCtxt,
+                                  span: Span,
+                                  mitem: &MetaItem,
+                                  item: &Item,
+                                  push: F) where
+    F: FnOnce(P<Item>),
+{
     fn cs_total_eq_assert(cx: &mut ExtCtxt, span: Span, substr: &Substructure) -> P<Expr> {
         cs_same_method(|cx, span, exprs| {
             // create `a.<method>(); b.<method>(); c.<method>(); ...`
diff --git a/src/libsyntax/ext/deriving/cmp/totalord.rs b/src/libsyntax/ext/deriving/cmp/totalord.rs
index 6900773f44d4b..a2bf46f41fc96 100644
--- a/src/libsyntax/ext/deriving/cmp/totalord.rs
+++ b/src/libsyntax/ext/deriving/cmp/totalord.rs
@@ -18,11 +18,13 @@ use ext::deriving::generic::ty::*;
 use parse::token::InternedString;
 use ptr::P;
 
-pub fn expand_deriving_totalord(cx: &mut ExtCtxt,
-                                span: Span,
-                                mitem: &MetaItem,
-                                item: &Item,
-                                push: |P<Item>|) {
+pub fn expand_deriving_totalord<F>(cx: &mut ExtCtxt,
+                                   span: Span,
+                                   mitem: &MetaItem,
+                                   item: &Item,
+                                   push: F) where
+    F: FnOnce(P<Item>),
+{
     let inline = cx.meta_word(span, InternedString::new("inline"));
     let attrs = vec!(cx.attribute(span, inline));
     let trait_def = TraitDef {
diff --git a/src/libsyntax/ext/deriving/decodable.rs b/src/libsyntax/ext/deriving/decodable.rs
index e3cf2b68752fd..0a8d59da89677 100644
--- a/src/libsyntax/ext/deriving/decodable.rs
+++ b/src/libsyntax/ext/deriving/decodable.rs
@@ -21,11 +21,13 @@ use parse::token::InternedString;
 use parse::token;
 use ptr::P;
 
-pub fn expand_deriving_decodable(cx: &mut ExtCtxt,
-                                 span: Span,
-                                 mitem: &MetaItem,
-                                 item: &Item,
-                                 push: |P<Item>|) {
+pub fn expand_deriving_decodable<F>(cx: &mut ExtCtxt,
+                                    span: Span,
+                                    mitem: &MetaItem,
+                                    item: &Item,
+                                    push: F) where
+    F: FnOnce(P<Item>),
+{
     let trait_def = TraitDef {
         span: span,
         attributes: Vec::new(),
@@ -155,12 +157,14 @@ fn decodable_substructure(cx: &mut ExtCtxt, trait_span: Span,
 /// Create a decoder for a single enum variant/struct:
 /// - `outer_pat_path` is the path to this enum variant/struct
 /// - `getarg` should retrieve the `uint`-th field with name `@str`.
-fn decode_static_fields(cx: &mut ExtCtxt,
-                        trait_span: Span,
-                        outer_pat_path: ast::Path,
-                        fields: &StaticFields,
-                        getarg: |&mut ExtCtxt, Span, InternedString, uint| -> P<Expr>)
-                        -> P<Expr> {
+fn decode_static_fields<F>(cx: &mut ExtCtxt,
+                           trait_span: Span,
+                           outer_pat_path: ast::Path,
+                           fields: &StaticFields,
+                           mut getarg: F)
+                           -> P<Expr> where
+    F: FnMut(&mut ExtCtxt, Span, InternedString, uint) -> P<Expr>,
+{
     match *fields {
         Unnamed(ref fields) => {
             let path_expr = cx.expr_path(outer_pat_path);
diff --git a/src/libsyntax/ext/deriving/default.rs b/src/libsyntax/ext/deriving/default.rs
index f4a66414d89bd..b3621490ce3bf 100644
--- a/src/libsyntax/ext/deriving/default.rs
+++ b/src/libsyntax/ext/deriving/default.rs
@@ -17,11 +17,13 @@ use ext::deriving::generic::ty::*;
 use parse::token::InternedString;
 use ptr::P;
 
-pub fn expand_deriving_default(cx: &mut ExtCtxt,
-                            span: Span,
-                            mitem: &MetaItem,
-                            item: &Item,
-                            push: |P<Item>|) {
+pub fn expand_deriving_default<F>(cx: &mut ExtCtxt,
+                                  span: Span,
+                                  mitem: &MetaItem,
+                                  item: &Item,
+                                  push: F) where
+    F: FnOnce(P<Item>),
+{
     let inline = cx.meta_word(span, InternedString::new("inline"));
     let attrs = vec!(cx.attribute(span, inline));
     let trait_def = TraitDef {
diff --git a/src/libsyntax/ext/deriving/encodable.rs b/src/libsyntax/ext/deriving/encodable.rs
index 62f3b5d01b41a..30851ebeaaef3 100644
--- a/src/libsyntax/ext/deriving/encodable.rs
+++ b/src/libsyntax/ext/deriving/encodable.rs
@@ -97,11 +97,13 @@ use ext::deriving::generic::ty::*;
 use parse::token;
 use ptr::P;
 
-pub fn expand_deriving_encodable(cx: &mut ExtCtxt,
-                                 span: Span,
-                                 mitem: &MetaItem,
-                                 item: &Item,
-                                 push: |P<Item>|) {
+pub fn expand_deriving_encodable<F>(cx: &mut ExtCtxt,
+                                    span: Span,
+                                    mitem: &MetaItem,
+                                    item: &Item,
+                                    push: F) where
+    F: FnOnce(P<Item>),
+{
     let trait_def = TraitDef {
         span: span,
         attributes: Vec::new(),
diff --git a/src/libsyntax/ext/deriving/generic/mod.rs b/src/libsyntax/ext/deriving/generic/mod.rs
index cf3b3ad9051aa..a75be40604ea6 100644
--- a/src/libsyntax/ext/deriving/generic/mod.rs
+++ b/src/libsyntax/ext/deriving/generic/mod.rs
@@ -333,11 +333,13 @@ pub fn combine_substructure<'a>(f: CombineSubstructureFunc<'a>)
 
 
 impl<'a> TraitDef<'a> {
-    pub fn expand(&self,
-                  cx: &mut ExtCtxt,
-                  mitem: &ast::MetaItem,
-                  item: &ast::Item,
-                  push: |P<ast::Item>|) {
+    pub fn expand<F>(&self,
+                     cx: &mut ExtCtxt,
+                     mitem: &ast::MetaItem,
+                     item: &ast::Item,
+                     push: F) where
+        F: FnOnce(P<ast::Item>),
+    {
         let newitem = match item.node {
             ast::ItemStruct(ref struct_def, ref generics) => {
                 self.expand_struct_def(cx,
@@ -1309,14 +1311,16 @@ impl<'a> TraitDef<'a> {
 
 /// Fold the fields. `use_foldl` controls whether this is done
 /// left-to-right (`true`) or right-to-left (`false`).
-pub fn cs_fold(use_foldl: bool,
-               f: |&mut ExtCtxt, Span, P<Expr>, P<Expr>, &[P<Expr>]| -> P<Expr>,
-               base: P<Expr>,
-               enum_nonmatch_f: EnumNonMatchCollapsedFunc,
-               cx: &mut ExtCtxt,
-               trait_span: Span,
-               substructure: &Substructure)
-               -> P<Expr> {
+pub fn cs_fold<F>(use_foldl: bool,
+                  mut f: F,
+                  base: P<Expr>,
+                  enum_nonmatch_f: EnumNonMatchCollapsedFunc,
+                  cx: &mut ExtCtxt,
+                  trait_span: Span,
+                  substructure: &Substructure)
+                  -> P<Expr> where
+    F: FnMut(&mut ExtCtxt, Span, P<Expr>, P<Expr>, &[P<Expr>]) -> P<Expr>,
+{
     match *substructure.fields {
         EnumMatching(_, _, ref all_fields) | Struct(ref all_fields) => {
             if use_foldl {
@@ -1355,12 +1359,14 @@ pub fn cs_fold(use_foldl: bool,
 ///              self_2.method(__arg_1_2, __arg_2_2)])
 /// ```
 #[inline]
-pub fn cs_same_method(f: |&mut ExtCtxt, Span, Vec<P<Expr>>| -> P<Expr>,
-                      enum_nonmatch_f: EnumNonMatchCollapsedFunc,
-                      cx: &mut ExtCtxt,
-                      trait_span: Span,
-                      substructure: &Substructure)
-                      -> P<Expr> {
+pub fn cs_same_method<F>(f: F,
+                         enum_nonmatch_f: EnumNonMatchCollapsedFunc,
+                         cx: &mut ExtCtxt,
+                         trait_span: Span,
+                         substructure: &Substructure)
+                         -> P<Expr> where
+    F: FnOnce(&mut ExtCtxt, Span, Vec<P<Expr>>) -> P<Expr>,
+{
     match *substructure.fields {
         EnumMatching(_, _, ref all_fields) | Struct(ref all_fields) => {
             // call self_n.method(other_1_n, other_2_n, ...)
@@ -1388,14 +1394,16 @@ pub fn cs_same_method(f: |&mut ExtCtxt, Span, Vec<P<Expr>>| -> P<Expr>,
 /// fields. `use_foldl` controls whether this is done left-to-right
 /// (`true`) or right-to-left (`false`).
 #[inline]
-pub fn cs_same_method_fold(use_foldl: bool,
-                           f: |&mut ExtCtxt, Span, P<Expr>, P<Expr>| -> P<Expr>,
-                           base: P<Expr>,
-                           enum_nonmatch_f: EnumNonMatchCollapsedFunc,
-                           cx: &mut ExtCtxt,
-                           trait_span: Span,
-                           substructure: &Substructure)
-                           -> P<Expr> {
+pub fn cs_same_method_fold<F>(use_foldl: bool,
+                              mut f: F,
+                              base: P<Expr>,
+                              enum_nonmatch_f: EnumNonMatchCollapsedFunc,
+                              cx: &mut ExtCtxt,
+                              trait_span: Span,
+                              substructure: &Substructure)
+                              -> P<Expr> where
+    F: FnMut(&mut ExtCtxt, Span, P<Expr>, P<Expr>) -> P<Expr>,
+{
     cs_same_method(
         |cx, span, vals| {
             if use_foldl {
diff --git a/src/libsyntax/ext/deriving/hash.rs b/src/libsyntax/ext/deriving/hash.rs
index b7f11c2582548..4e59124a1294f 100644
--- a/src/libsyntax/ext/deriving/hash.rs
+++ b/src/libsyntax/ext/deriving/hash.rs
@@ -17,11 +17,13 @@ use ext::deriving::generic::ty::*;
 use parse::token::InternedString;
 use ptr::P;
 
-pub fn expand_deriving_hash(cx: &mut ExtCtxt,
-                            span: Span,
-                            mitem: &MetaItem,
-                            item: &Item,
-                            push: |P<Item>|) {
+pub fn expand_deriving_hash<F>(cx: &mut ExtCtxt,
+                               span: Span,
+                               mitem: &MetaItem,
+                               item: &Item,
+                               push: F) where
+    F: FnOnce(P<Item>),
+{
 
     let (path, generics, args) = if cx.ecfg.deriving_hash_type_parameter {
         (Path::new_(vec!("std", "hash", "Hash"), None,
diff --git a/src/libsyntax/ext/deriving/primitive.rs b/src/libsyntax/ext/deriving/primitive.rs
index cd2d98b70f105..8abd846373ae1 100644
--- a/src/libsyntax/ext/deriving/primitive.rs
+++ b/src/libsyntax/ext/deriving/primitive.rs
@@ -18,11 +18,13 @@ use ext::deriving::generic::ty::*;
 use parse::token::InternedString;
 use ptr::P;
 
-pub fn expand_deriving_from_primitive(cx: &mut ExtCtxt,
-                                      span: Span,
-                                      mitem: &MetaItem,
-                                      item: &Item,
-                                      push: |P<Item>|) {
+pub fn expand_deriving_from_primitive<F>(cx: &mut ExtCtxt,
+                                         span: Span,
+                                         mitem: &MetaItem,
+                                         item: &Item,
+                                         push: F) where
+    F: FnOnce(P<Item>),
+{
     let inline = cx.meta_word(span, InternedString::new("inline"));
     let attrs = vec!(cx.attribute(span, inline));
     let trait_def = TraitDef {
diff --git a/src/libsyntax/ext/deriving/rand.rs b/src/libsyntax/ext/deriving/rand.rs
index c4e64d58c2932..4f6e4d1fb3c10 100644
--- a/src/libsyntax/ext/deriving/rand.rs
+++ b/src/libsyntax/ext/deriving/rand.rs
@@ -17,11 +17,13 @@ use ext::deriving::generic::*;
 use ext::deriving::generic::ty::*;
 use ptr::P;
 
-pub fn expand_deriving_rand(cx: &mut ExtCtxt,
-                            span: Span,
-                            mitem: &MetaItem,
-                            item: &Item,
-                            push: |P<Item>|) {
+pub fn expand_deriving_rand<F>(cx: &mut ExtCtxt,
+                               span: Span,
+                               mitem: &MetaItem,
+                               item: &Item,
+                               push: F) where
+    F: FnOnce(P<Item>),
+{
     let trait_def = TraitDef {
         span: span,
         attributes: Vec::new(),
@@ -64,7 +66,7 @@ fn rand_substructure(cx: &mut ExtCtxt, trait_span: Span, substr: &Substructure)
         cx.ident_of("Rand"),
         cx.ident_of("rand")
     );
-    let rand_call = |cx: &mut ExtCtxt, span| {
+    let mut rand_call = |&mut: cx: &mut ExtCtxt, span| {
         cx.expr_call_global(span,
                             rand_ident.clone(),
                             vec!(rng.clone()))
@@ -133,12 +135,14 @@ fn rand_substructure(cx: &mut ExtCtxt, trait_span: Span, substr: &Substructure)
         _ => cx.bug("Non-static method in `deriving(Rand)`")
     };
 
-    fn rand_thing(cx: &mut ExtCtxt,
-                  trait_span: Span,
-                  ctor_path: ast::Path,
-                  summary: &StaticFields,
-                  rand_call: |&mut ExtCtxt, Span| -> P<Expr>)
-                  -> P<Expr> {
+    fn rand_thing<F>(cx: &mut ExtCtxt,
+                     trait_span: Span,
+                     ctor_path: ast::Path,
+                     summary: &StaticFields,
+                     mut rand_call: F)
+                     -> P<Expr> where
+        F: FnMut(&mut ExtCtxt, Span) -> P<Expr>,
+    {
         let path = cx.expr_path(ctor_path.clone());
         match *summary {
             Unnamed(ref fields) => {
diff --git a/src/libsyntax/ext/deriving/show.rs b/src/libsyntax/ext/deriving/show.rs
index 322a84eaa2be0..a68b521bbc9a2 100644
--- a/src/libsyntax/ext/deriving/show.rs
+++ b/src/libsyntax/ext/deriving/show.rs
@@ -21,11 +21,13 @@ use ptr::P;
 
 use std::collections::HashMap;
 
-pub fn expand_deriving_show(cx: &mut ExtCtxt,
-                            span: Span,
-                            mitem: &MetaItem,
-                            item: &Item,
-                            push: |P<Item>|) {
+pub fn expand_deriving_show<F>(cx: &mut ExtCtxt,
+                               span: Span,
+                               mitem: &MetaItem,
+                               item: &Item,
+                               push: F) where
+    F: FnOnce(P<Item>),
+{
     // &mut ::std::fmt::Formatter
     let fmtr = Ptr(box Literal(Path::new(vec!("std", "fmt", "Formatter"))),
                    Borrowed(None, ast::MutMutable));
diff --git a/src/libsyntax/ext/deriving/zero.rs b/src/libsyntax/ext/deriving/zero.rs
index 7f265b529ffea..ea32549cad266 100644
--- a/src/libsyntax/ext/deriving/zero.rs
+++ b/src/libsyntax/ext/deriving/zero.rs
@@ -17,11 +17,13 @@ use ext::deriving::generic::ty::*;
 use parse::token::InternedString;
 use ptr::P;
 
-pub fn expand_deriving_zero(cx: &mut ExtCtxt,
-                            span: Span,
-                            mitem: &MetaItem,
-                            item: &Item,
-                            push: |P<Item>|) {
+pub fn expand_deriving_zero<F>(cx: &mut ExtCtxt,
+                               span: Span,
+                               mitem: &MetaItem,
+                               item: &Item,
+                               push: F) where
+    F: FnOnce(P<Item>),
+{
     let inline = cx.meta_word(span, InternedString::new("inline"));
     let attrs = vec!(cx.attribute(span, inline));
     let trait_def = TraitDef {
diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs
index a697d332d16af..9c4e85f16ff85 100644
--- a/src/libsyntax/ext/expand.rs
+++ b/src/libsyntax/ext/expand.rs
@@ -238,11 +238,13 @@ pub fn expand_expr(e: P<ast::Expr>, fld: &mut MacroExpander) -> P<ast::Expr> {
 /// of expansion and the mark which must be applied to the result.
 /// Our current interface doesn't allow us to apply the mark to the
 /// result until after calling make_expr, make_items, etc.
-fn expand_mac_invoc<T>(mac: ast::Mac, span: codemap::Span,
-                       parse_thunk: |Box<MacResult>|->Option<T>,
-                       mark_thunk: |T,Mrk|->T,
-                       fld: &mut MacroExpander)
-                       -> Option<T>
+fn expand_mac_invoc<T, F, G>(mac: ast::Mac, span: codemap::Span,
+                             parse_thunk: F,
+                             mark_thunk: G,
+                             fld: &mut MacroExpander)
+                             -> Option<T> where
+    F: FnOnce(Box<MacResult>) -> Option<T>,
+    G: FnOnce(T, Mrk) -> T,
 {
     match mac.node {
         // it would almost certainly be cleaner to pass the whole
diff --git a/src/libsyntax/ext/mtwt.rs b/src/libsyntax/ext/mtwt.rs
index 48120b575acd2..a4e06aeaf63b9 100644
--- a/src/libsyntax/ext/mtwt.rs
+++ b/src/libsyntax/ext/mtwt.rs
@@ -105,9 +105,11 @@ pub fn apply_renames(renames: &RenameList, ctxt: SyntaxContext) -> SyntaxContext
 }
 
 /// Fetch the SCTable from TLS, create one if it doesn't yet exist.
-pub fn with_sctable<T>(op: |&SCTable| -> T) -> T {
+pub fn with_sctable<T, F>(op: F) -> T where
+    F: FnOnce(&SCTable) -> T,
+{
     thread_local!(static SCTABLE_KEY: SCTable = new_sctable_internal())
-    SCTABLE_KEY.with(|slot| op(slot))
+    SCTABLE_KEY.with(move |slot| op(slot))
 }
 
 // Make a fresh syntax context table with EmptyCtxt in slot zero
@@ -167,12 +169,14 @@ type ResolveTable = HashMap<(Name,SyntaxContext),Name>;
 
 // okay, I admit, putting this in TLS is not so nice:
 // fetch the SCTable from TLS, create one if it doesn't yet exist.
-fn with_resolve_table_mut<T>(op: |&mut ResolveTable| -> T) -> T {
+fn with_resolve_table_mut<T, F>(op: F) -> T where
+    F: FnOnce(&mut ResolveTable) -> T,
+{
     thread_local!(static RESOLVE_TABLE_KEY: RefCell<ResolveTable> = {
         RefCell::new(HashMap::new())
     })
 
-    RESOLVE_TABLE_KEY.with(|slot| op(&mut *slot.borrow_mut()))
+    RESOLVE_TABLE_KEY.with(move |slot| op(&mut *slot.borrow_mut()))
 }
 
 /// Resolve a syntax object to a name, per MTWT.
diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs
index 69e311c57f5ab..0318dd5b0cd2d 100644
--- a/src/libsyntax/fold.rs
+++ b/src/libsyntax/fold.rs
@@ -32,11 +32,11 @@ use std::rc::Rc;
 
 // This could have a better place to live.
 pub trait MoveMap<T> {
-    fn move_map(self, f: |T| -> T) -> Self;
+    fn move_map<F>(self, f: F) -> Self where F: FnMut(T) -> T;
 }
 
 impl<T> MoveMap<T> for Vec<T> {
-    fn move_map(mut self, f: |T| -> T) -> Vec<T> {
+    fn move_map<F>(mut self, mut f: F) -> Vec<T> where F: FnMut(T) -> T {
         for p in self.iter_mut() {
             unsafe {
                 // FIXME(#5016) this shouldn't need to zero to be safe.
@@ -48,7 +48,7 @@ impl<T> MoveMap<T> for Vec<T> {
 }
 
 impl<T> MoveMap<T> for OwnedSlice<T> {
-    fn move_map(self, f: |T| -> T) -> OwnedSlice<T> {
+    fn move_map<F>(self, f: F) -> OwnedSlice<T> where F: FnMut(T) -> T {
         OwnedSlice::from_vec(self.into_vec().move_map(f))
     }
 }
diff --git a/src/libsyntax/parse/lexer/mod.rs b/src/libsyntax/parse/lexer/mod.rs
index 4c15fae9feb87..50c7258fe1c7b 100644
--- a/src/libsyntax/parse/lexer/mod.rs
+++ b/src/libsyntax/parse/lexer/mod.rs
@@ -244,7 +244,9 @@ impl<'a> StringReader<'a> {
     /// Calls `f` with a string slice of the source text spanning from `start`
     /// up to but excluding `self.last_pos`, meaning the slice does not include
     /// the character `self.curr`.
-    pub fn with_str_from<T>(&self, start: BytePos, f: |s: &str| -> T) -> T {
+    pub fn with_str_from<T, F>(&self, start: BytePos, f: F) -> T where
+        F: FnOnce(&str) -> T,
+    {
         self.with_str_from_to(start, self.last_pos, f)
     }
 
@@ -264,7 +266,9 @@ impl<'a> StringReader<'a> {
 
     /// Calls `f` with a string slice of the source text spanning from `start`
     /// up to but excluding `end`.
-    fn with_str_from_to<T>(&self, start: BytePos, end: BytePos, f: |s: &str| -> T) -> T {
+    fn with_str_from_to<T, F>(&self, start: BytePos, end: BytePos, f: F) -> T where
+        F: FnOnce(&str) -> T,
+    {
         f(self.filemap.src.slice(
                 self.byte_offset(start).to_uint(),
                 self.byte_offset(end).to_uint()))
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs
index 92c7380a61ded..8c44f9fdf26b7 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser.rs
@@ -718,11 +718,12 @@ impl<'a> Parser<'a> {
     }
 
     /// Parse a sequence bracketed by `|` and `|`, stopping before the `|`.
-    fn parse_seq_to_before_or<T>(
-                              &mut self,
-                              sep: &token::Token,
-                              f: |&mut Parser| -> T)
-                              -> Vec<T> {
+    fn parse_seq_to_before_or<T, F>(&mut self,
+                                    sep: &token::Token,
+                                    mut f: F)
+                                    -> Vec<T> where
+        F: FnMut(&mut Parser) -> T,
+    {
         let mut first = true;
         let mut vector = Vec::new();
         while self.token != token::BinOp(token::Or) &&
@@ -769,10 +770,12 @@ impl<'a> Parser<'a> {
         }
     }
 
-    pub fn parse_seq_to_before_gt_or_return<T>(&mut self,
-                                               sep: Option<token::Token>,
-                                               f: |&mut Parser| -> Option<T>)
-                                               -> (OwnedSlice<T>, bool) {
+    pub fn parse_seq_to_before_gt_or_return<T, F>(&mut self,
+                                                  sep: Option<token::Token>,
+                                                  mut f: F)
+                                                  -> (OwnedSlice<T>, bool) where
+        F: FnMut(&mut Parser) -> Option<T>,
+    {
         let mut v = Vec::new();
         // This loop works by alternating back and forth between parsing types
         // and commas.  For example, given a string `A, B,>`, the parser would
@@ -802,28 +805,34 @@ impl<'a> Parser<'a> {
 
     /// Parse a sequence bracketed by '<' and '>', stopping
     /// before the '>'.
-    pub fn parse_seq_to_before_gt<T>(&mut self,
-                                     sep: Option<token::Token>,
-                                     f: |&mut Parser| -> T)
-                                     -> OwnedSlice<T> {
+    pub fn parse_seq_to_before_gt<T, F>(&mut self,
+                                        sep: Option<token::Token>,
+                                        mut f: F)
+                                        -> OwnedSlice<T> where
+        F: FnMut(&mut Parser) -> T,
+    {
         let (result, returned) = self.parse_seq_to_before_gt_or_return(sep, |p| Some(f(p)));
         assert!(!returned);
         return result;
     }
 
-    pub fn parse_seq_to_gt<T>(&mut self,
-                              sep: Option<token::Token>,
-                              f: |&mut Parser| -> T)
-                              -> OwnedSlice<T> {
+    pub fn parse_seq_to_gt<T, F>(&mut self,
+                                 sep: Option<token::Token>,
+                                 f: F)
+                                 -> OwnedSlice<T> where
+        F: FnMut(&mut Parser) -> T,
+    {
         let v = self.parse_seq_to_before_gt(sep, f);
         self.expect_gt();
         return v;
     }
 
-    pub fn parse_seq_to_gt_or_return<T>(&mut self,
-                                        sep: Option<token::Token>,
-                                        f: |&mut Parser| -> Option<T>)
-                                        -> (OwnedSlice<T>, bool) {
+    pub fn parse_seq_to_gt_or_return<T, F>(&mut self,
+                                           sep: Option<token::Token>,
+                                           f: F)
+                                           -> (OwnedSlice<T>, bool) where
+        F: FnMut(&mut Parser) -> Option<T>,
+    {
         let (v, returned) = self.parse_seq_to_before_gt_or_return(sep, f);
         if !returned {
             self.expect_gt();
@@ -834,12 +843,13 @@ impl<'a> Parser<'a> {
     /// Parse a sequence, including the closing delimiter. The function
     /// f must consume tokens until reaching the next separator or
     /// closing bracket.
-    pub fn parse_seq_to_end<T>(
-                            &mut self,
-                            ket: &token::Token,
-                            sep: SeqSep,
-                            f: |&mut Parser| -> T)
-                            -> Vec<T> {
+    pub fn parse_seq_to_end<T, F>(&mut self,
+                                  ket: &token::Token,
+                                  sep: SeqSep,
+                                  f: F)
+                                  -> Vec<T> where
+        F: FnMut(&mut Parser) -> T,
+    {
         let val = self.parse_seq_to_before_end(ket, sep, f);
         self.bump();
         val
@@ -848,12 +858,13 @@ impl<'a> Parser<'a> {
     /// Parse a sequence, not including the closing delimiter. The function
     /// f must consume tokens until reaching the next separator or
     /// closing bracket.
-    pub fn parse_seq_to_before_end<T>(
-                                   &mut self,
-                                   ket: &token::Token,
-                                   sep: SeqSep,
-                                   f: |&mut Parser| -> T)
-                                   -> Vec<T> {
+    pub fn parse_seq_to_before_end<T, F>(&mut self,
+                                         ket: &token::Token,
+                                         sep: SeqSep,
+                                         mut f: F)
+                                         -> Vec<T> where
+        F: FnMut(&mut Parser) -> T,
+    {
         let mut first: bool = true;
         let mut v = vec!();
         while self.token != *ket {
@@ -873,13 +884,14 @@ impl<'a> Parser<'a> {
     /// Parse a sequence, including the closing delimiter. The function
     /// f must consume tokens until reaching the next separator or
     /// closing bracket.
-    pub fn parse_unspanned_seq<T>(
-                               &mut self,
-                               bra: &token::Token,
-                               ket: &token::Token,
-                               sep: SeqSep,
-                               f: |&mut Parser| -> T)
-                               -> Vec<T> {
+    pub fn parse_unspanned_seq<T, F>(&mut self,
+                                     bra: &token::Token,
+                                     ket: &token::Token,
+                                     sep: SeqSep,
+                                     f: F)
+                                     -> Vec<T> where
+        F: FnMut(&mut Parser) -> T,
+    {
         self.expect(bra);
         let result = self.parse_seq_to_before_end(ket, sep, f);
         self.bump();
@@ -888,13 +900,14 @@ impl<'a> Parser<'a> {
 
     /// Parse a sequence parameter of enum variant. For consistency purposes,
     /// these should not be empty.
-    pub fn parse_enum_variant_seq<T>(
-                               &mut self,
-                               bra: &token::Token,
-                               ket: &token::Token,
-                               sep: SeqSep,
-                               f: |&mut Parser| -> T)
-                               -> Vec<T> {
+    pub fn parse_enum_variant_seq<T, F>(&mut self,
+                                        bra: &token::Token,
+                                        ket: &token::Token,
+                                        sep: SeqSep,
+                                        f: F)
+                                        -> Vec<T> where
+        F: FnMut(&mut Parser) -> T,
+    {
         let result = self.parse_unspanned_seq(bra, ket, sep, f);
         if result.is_empty() {
             let last_span = self.last_span;
@@ -906,13 +919,14 @@ impl<'a> Parser<'a> {
 
     // NB: Do not use this function unless you actually plan to place the
     // spanned list in the AST.
-    pub fn parse_seq<T>(
-                     &mut self,
-                     bra: &token::Token,
-                     ket: &token::Token,
-                     sep: SeqSep,
-                     f: |&mut Parser| -> T)
-                     -> Spanned<Vec<T> > {
+    pub fn parse_seq<T, F>(&mut self,
+                           bra: &token::Token,
+                           ket: &token::Token,
+                           sep: SeqSep,
+                           f: F)
+                           -> Spanned<Vec<T>> where
+        F: FnMut(&mut Parser) -> T,
+    {
         let lo = self.span.lo;
         self.expect(bra);
         let result = self.parse_seq_to_before_end(ket, sep, f);
@@ -972,8 +986,9 @@ impl<'a> Parser<'a> {
         }
         return (4 - self.buffer_start) + self.buffer_end;
     }
-    pub fn look_ahead<R>(&mut self, distance: uint, f: |&token::Token| -> R)
-                      -> R {
+    pub fn look_ahead<R, F>(&mut self, distance: uint, f: F) -> R where
+        F: FnOnce(&token::Token) -> R,
+    {
         let dist = distance as int;
         while self.buffer_length() < dist {
             self.buffer[self.buffer_end as uint] = self.reader.real_token();
@@ -4285,8 +4300,9 @@ impl<'a> Parser<'a> {
 
     /// Parse the argument list and result type of a function
     /// that may have a self type.
-    fn parse_fn_decl_with_self(&mut self, parse_arg_fn: |&mut Parser| -> Arg)
-                               -> (ExplicitSelf, P<FnDecl>) {
+    fn parse_fn_decl_with_self<F>(&mut self, parse_arg_fn: F) -> (ExplicitSelf, P<FnDecl>) where
+        F: FnMut(&mut Parser) -> Arg,
+    {
         fn maybe_parse_borrowed_explicit_self(this: &mut Parser)
                                               -> ast::ExplicitSelf_ {
             // The following things are possible to see here:
diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs
index 26373d00aaf60..6d8b8dcb8ba5d 100644
--- a/src/libsyntax/print/pprust.rs
+++ b/src/libsyntax/print/pprust.rs
@@ -165,7 +165,9 @@ impl<'a> State<'a> {
     }
 }
 
-pub fn to_string(f: |&mut State| -> IoResult<()>) -> String {
+pub fn to_string<F>(f: F) -> String where
+    F: FnOnce(&mut State) -> IoResult<()>,
+{
     use std::raw::TraitObject;
     let mut s = rust_printer(box Vec::new());
     f(&mut s).unwrap();
@@ -426,8 +428,10 @@ pub mod with_hygiene {
 
     // This function is the trick that all the rest of the routines
     // hang on.
-    pub fn to_string_hyg(f: |&mut super::State| -> IoResult<()>) -> String {
-        super::to_string(|s| {
+    pub fn to_string_hyg<F>(f: F) -> String where
+        F: FnOnce(&mut super::State) -> IoResult<()>,
+    {
+        super::to_string(move |s| {
             s.encode_idents_with_hygiene = true;
             f(s)
         })
@@ -580,9 +584,9 @@ impl<'a> State<'a> {
         word(&mut self.s, "*/")
     }
 
-    pub fn commasep<T>(&mut self, b: Breaks, elts: &[T],
-                       op: |&mut State, &T| -> IoResult<()>)
-        -> IoResult<()> {
+    pub fn commasep<T, F>(&mut self, b: Breaks, elts: &[T], mut op: F) -> IoResult<()> where
+        F: FnMut(&mut State, &T) -> IoResult<()>,
+    {
         try!(self.rbox(0u, b));
         let mut first = true;
         for elt in elts.iter() {
@@ -593,12 +597,14 @@ impl<'a> State<'a> {
     }
 
 
-    pub fn commasep_cmnt<T>(
-                         &mut self,
-                         b: Breaks,
-                         elts: &[T],
-                         op: |&mut State, &T| -> IoResult<()>,
-                         get_span: |&T| -> codemap::Span) -> IoResult<()> {
+    pub fn commasep_cmnt<T, F, G>(&mut self,
+                                  b: Breaks,
+                                  elts: &[T],
+                                  mut op: F,
+                                  mut get_span: G) -> IoResult<()> where
+        F: FnMut(&mut State, &T) -> IoResult<()>,
+        G: FnMut(&T) -> codemap::Span,
+    {
         try!(self.rbox(0u, b));
         let len = elts.len();
         let mut i = 0u;
diff --git a/src/libsyntax/ptr.rs b/src/libsyntax/ptr.rs
index 1b231ed861b89..1b3ebde2461e6 100644
--- a/src/libsyntax/ptr.rs
+++ b/src/libsyntax/ptr.rs
@@ -56,12 +56,16 @@ pub fn P<T: 'static>(value: T) -> P<T> {
 impl<T: 'static> P<T> {
     /// Move out of the pointer.
     /// Intended for chaining transformations not covered by `map`.
-    pub fn and_then<U>(self, f: |T| -> U) -> U {
+    pub fn and_then<U, F>(self, f: F) -> U where
+        F: FnOnce(T) -> U,
+    {
         f(*self.ptr)
     }
 
     /// Transform the inner value, consuming `self` and producing a new `P<T>`.
-    pub fn map(mut self, f: |T| -> T) -> P<T> {
+    pub fn map<F>(mut self, f: F) -> P<T> where
+        F: FnOnce(T) -> T,
+    {
         unsafe {
             let p = &mut *self.ptr;
             // FIXME(#5016) this shouldn't need to zero to be safe.
diff --git a/src/libsyntax/util/parser_testing.rs b/src/libsyntax/util/parser_testing.rs
index c1ea8f60b8201..83bbff8473d04 100644
--- a/src/libsyntax/util/parser_testing.rs
+++ b/src/libsyntax/util/parser_testing.rs
@@ -31,7 +31,9 @@ pub fn string_to_parser<'a>(ps: &'a ParseSess, source_str: String) -> Parser<'a>
                                source_str)
 }
 
-fn with_error_checking_parse<T>(s: String, f: |&mut Parser| -> T) -> T {
+fn with_error_checking_parse<T, F>(s: String, f: F) -> T where
+    F: FnOnce(&mut Parser) -> T,
+{
     let ps = new_parse_sess();
     let mut p = string_to_parser(&ps, s);
     let x = f(&mut p);
diff --git a/src/libsyntax/util/small_vector.rs b/src/libsyntax/util/small_vector.rs
index d56e4f704499e..8d050e34abf4c 100644
--- a/src/libsyntax/util/small_vector.rs
+++ b/src/libsyntax/util/small_vector.rs
@@ -171,7 +171,7 @@ impl<T> Iterator<T> for MoveItems<T> {
 }
 
 impl<T> MoveMap<T> for SmallVector<T> {
-    fn move_map(self, f: |T| -> T) -> SmallVector<T> {
+    fn move_map<F>(self, mut f: F) -> SmallVector<T> where F: FnMut(T) -> T {
         let repr = match self.repr {
             Zero => Zero,
             One(v) => One(f(v)),

From d3d707c88397d8356f5181be600166ded3390907 Mon Sep 17 00:00:00 2001
From: Jorge Aparicio <japaricious@gmail.com>
Date: Mon, 8 Dec 2014 14:14:06 -0500
Subject: [PATCH 78/92] librustc: fix fallout

---
 src/librustc/middle/ty.rs   | 4 +++-
 src/librustc/session/mod.rs | 4 +++-
 2 files changed, 6 insertions(+), 2 deletions(-)

diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs
index ddbf69685cd91..ffca616d76a81 100644
--- a/src/librustc/middle/ty.rs
+++ b/src/librustc/middle/ty.rs
@@ -4916,7 +4916,9 @@ pub fn has_dtor(cx: &ctxt, struct_id: DefId) -> bool {
     cx.destructor_for_type.borrow().contains_key(&struct_id)
 }
 
-pub fn with_path<T>(cx: &ctxt, id: ast::DefId, f: |ast_map::PathElems| -> T) -> T {
+pub fn with_path<T, F>(cx: &ctxt, id: ast::DefId, f: F) -> T where
+    F: FnOnce(ast_map::PathElems) -> T,
+{
     if id.krate == ast::LOCAL_CRATE {
         cx.map.with_path(id.node, f)
     } else {
diff --git a/src/librustc/session/mod.rs b/src/librustc/session/mod.rs
index e4d34e09d330a..8516ece202c75 100644
--- a/src/librustc/session/mod.rs
+++ b/src/librustc/session/mod.rs
@@ -288,7 +288,9 @@ pub fn build_session_(sopts: config::Options,
 }
 
 // Seems out of place, but it uses session, so I'm putting it here
-pub fn expect<T>(sess: &Session, opt: Option<T>, msg: || -> String) -> T {
+pub fn expect<T, M>(sess: &Session, opt: Option<T>, msg: M) -> T where
+    M: FnOnce() -> String,
+{
     diagnostic::expect(sess.diagnostic(), opt, msg)
 }
 

From 451eef5c4021d8882fa42ef369094e1897ae3af7 Mon Sep 17 00:00:00 2001
From: Jorge Aparicio <japaricious@gmail.com>
Date: Mon, 8 Dec 2014 18:35:22 -0500
Subject: [PATCH 79/92] librustc_back: use unboxed closures

---
 src/librustc_back/archive.rs |  5 +++--
 src/librustc_back/lib.rs     |  1 +
 src/librustc_back/rpath.rs   | 39 +++++++++++++++++++++++++-----------
 src/librustc_back/sha2.rs    | 11 ++++++----
 4 files changed, 38 insertions(+), 18 deletions(-)

diff --git a/src/librustc_back/archive.rs b/src/librustc_back/archive.rs
index a88bcafaa64b3..3a4510703166c 100644
--- a/src/librustc_back/archive.rs
+++ b/src/librustc_back/archive.rs
@@ -279,8 +279,9 @@ impl<'a> ArchiveBuilder<'a> {
         self.archive
     }
 
-    fn add_archive(&mut self, archive: &Path, name: &str,
-                   skip: |&str| -> bool) -> io::IoResult<()> {
+    fn add_archive<F>(&mut self, archive: &Path, name: &str, mut skip: F) -> io::IoResult<()> where
+        F: FnMut(&str) -> bool,
+    {
         let loc = TempDir::new("rsar").unwrap();
 
         // First, extract the contents of the archive to a temporary directory.
diff --git a/src/librustc_back/lib.rs b/src/librustc_back/lib.rs
index fc98a5cd6b559..cb547df7d9cd8 100644
--- a/src/librustc_back/lib.rs
+++ b/src/librustc_back/lib.rs
@@ -31,6 +31,7 @@
 
 #![allow(unknown_features)]
 #![feature(globs, phase, macro_rules, slicing_syntax)]
+#![feature(unboxed_closures)]
 
 #[phase(plugin, link)]
 extern crate log;
diff --git a/src/librustc_back/rpath.rs b/src/librustc_back/rpath.rs
index a90b49ba101fa..1f8549098d949 100644
--- a/src/librustc_back/rpath.rs
+++ b/src/librustc_back/rpath.rs
@@ -14,17 +14,22 @@ use std::os;
 use std::io::IoError;
 use syntax::ast;
 
-pub struct RPathConfig<'a> {
+pub struct RPathConfig<F, G> where
+    F: FnOnce() -> Path,
+    G: FnMut(&Path) -> Result<Path, IoError>,
+{
     pub used_crates: Vec<(ast::CrateNum, Option<Path>)>,
     pub out_filename: Path,
     pub is_like_osx: bool,
     pub has_rpath: bool,
-    pub get_install_prefix_lib_path: ||:'a -> Path,
-    pub realpath: |&Path|:'a -> Result<Path, IoError>
+    pub get_install_prefix_lib_path: F,
+    pub realpath: G,
 }
 
-pub fn get_rpath_flags(config: RPathConfig) -> Vec<String> {
-
+pub fn get_rpath_flags<F, G>(config: RPathConfig<F, G>) -> Vec<String> where
+    F: FnOnce() -> Path,
+    G: FnMut(&Path) -> Result<Path, IoError>,
+{
     // No rpath on windows
     if !config.has_rpath {
         return Vec::new();
@@ -52,8 +57,10 @@ fn rpaths_to_flags(rpaths: &[String]) -> Vec<String> {
     return ret;
 }
 
-fn get_rpaths(mut config: RPathConfig,
-              libs: &[Path]) -> Vec<String> {
+fn get_rpaths<F, G>(mut config: RPathConfig<F, G>, libs: &[Path]) -> Vec<String> where
+    F: FnOnce() -> Path,
+    G: FnMut(&Path) -> Result<Path, IoError>,
+{
     debug!("output: {}", config.out_filename.display());
     debug!("libs:");
     for libpath in libs.iter() {
@@ -86,13 +93,18 @@ fn get_rpaths(mut config: RPathConfig,
     return rpaths;
 }
 
-fn get_rpaths_relative_to_output(config: &mut RPathConfig,
-                                 libs: &[Path]) -> Vec<String> {
+fn get_rpaths_relative_to_output<F, G>(config: &mut RPathConfig<F, G>,
+                                       libs: &[Path]) -> Vec<String> where
+    F: FnOnce() -> Path,
+    G: FnMut(&Path) -> Result<Path, IoError>,
+{
     libs.iter().map(|a| get_rpath_relative_to_output(config, a)).collect()
 }
 
-fn get_rpath_relative_to_output(config: &mut RPathConfig,
-                                lib: &Path) -> String {
+fn get_rpath_relative_to_output<F, G>(config: &mut RPathConfig<F, G>, lib: &Path) -> String where
+    F: FnOnce() -> Path,
+    G: FnMut(&Path) -> Result<Path, IoError>,
+{
     use std::os;
 
     // Mac doesn't appear to support $ORIGIN
@@ -114,7 +126,10 @@ fn get_rpath_relative_to_output(config: &mut RPathConfig,
             relative.as_str().expect("non-utf8 component in path"))
 }
 
-fn get_install_prefix_rpath(config: RPathConfig) -> String {
+fn get_install_prefix_rpath<F, G>(config: RPathConfig<F, G>) -> String where
+    F: FnOnce() -> Path,
+    G: FnMut(&Path) -> Result<Path, IoError>,
+{
     let path = (config.get_install_prefix_lib_path)();
     let path = os::make_absolute(&path).unwrap();
     // FIXME (#9639): This needs to handle non-utf8 paths
diff --git a/src/librustc_back/sha2.rs b/src/librustc_back/sha2.rs
index 1b662ef178760..1587104ca49d1 100644
--- a/src/librustc_back/sha2.rs
+++ b/src/librustc_back/sha2.rs
@@ -82,7 +82,8 @@ fn add_bytes_to_bits<T: Int + ToBits>(bits: T, bytes: T) -> T {
 trait FixedBuffer {
     /// Input a vector of bytes. If the buffer becomes full, process it with the provided
     /// function and then clear the buffer.
-    fn input(&mut self, input: &[u8], func: |&[u8]|);
+    fn input<F>(&mut self, input: &[u8], func: F) where
+        F: FnMut(&[u8]);
 
     /// Reset the buffer.
     fn reset(&mut self);
@@ -125,7 +126,9 @@ impl FixedBuffer64 {
 }
 
 impl FixedBuffer for FixedBuffer64 {
-    fn input(&mut self, input: &[u8], func: |&[u8]|) {
+    fn input<F>(&mut self, input: &[u8], mut func: F) where
+        F: FnMut(&[u8]),
+    {
         let mut i = 0;
 
         let size = self.size();
@@ -201,11 +204,11 @@ trait StandardPadding {
     /// guaranteed to have exactly rem remaining bytes when it returns. If there are not at least
     /// rem bytes available, the buffer will be zero padded, processed, cleared, and then filled
     /// with zeros again until only rem bytes are remaining.
-    fn standard_padding(&mut self, rem: uint, func: |&[u8]|);
+    fn standard_padding<F>(&mut self, rem: uint, func: F) where F: FnMut(&[u8]);
 }
 
 impl <T: FixedBuffer> StandardPadding for T {
-    fn standard_padding(&mut self, rem: uint, func: |&[u8]|) {
+    fn standard_padding<F>(&mut self, rem: uint, mut func: F) where F: FnMut(&[u8]) {
         let size = self.size();
 
         self.next(1)[0] = 128;

From 3739a2427bc66dc9a8ea4cb34bffee2fba6d107c Mon Sep 17 00:00:00 2001
From: Jorge Aparicio <japaricious@gmail.com>
Date: Mon, 8 Dec 2014 20:00:29 -0500
Subject: [PATCH 80/92] librustc_trans: fix fallout

---
 src/librustc_trans/back/link.rs | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/librustc_trans/back/link.rs b/src/librustc_trans/back/link.rs
index 62f8177ed758d..5617110bfecf7 100644
--- a/src/librustc_trans/back/link.rs
+++ b/src/librustc_trans/back/link.rs
@@ -1002,7 +1002,7 @@ fn link_args(cmd: &mut Command,
     if sess.opts.cg.rpath {
         let sysroot = sess.sysroot();
         let target_triple = sess.opts.target_triple.as_slice();
-        let get_install_prefix_lib_path = || {
+        let get_install_prefix_lib_path = |:| {
             let install_prefix = option_env!("CFG_PREFIX").expect("CFG_PREFIX");
             let tlib = filesearch::relative_target_lib_path(sysroot, target_triple);
             let mut path = Path::new(install_prefix);

From 933e7b4a3ec1ca93af8fa1cacba0f9bf55fe9daf Mon Sep 17 00:00:00 2001
From: Jorge Aparicio <japaricious@gmail.com>
Date: Mon, 8 Dec 2014 20:17:18 -0500
Subject: [PATCH 81/92] librustc_llvm: use unboxed closures

---
 src/librustc_llvm/lib.rs | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/src/librustc_llvm/lib.rs b/src/librustc_llvm/lib.rs
index 23dad21e5303f..7d8338ba976dd 100644
--- a/src/librustc_llvm/lib.rs
+++ b/src/librustc_llvm/lib.rs
@@ -23,6 +23,7 @@
 
 #![feature(globs)]
 #![feature(link_args)]
+#![feature(unboxed_closures)]
 
 extern crate libc;
 
@@ -2206,7 +2207,7 @@ pub unsafe extern "C" fn rust_llvm_string_write_impl(sr: RustStringRef,
     (*sr).borrow_mut().push_all(slice);
 }
 
-pub fn build_string(f: |RustStringRef|) -> Option<String> {
+pub fn build_string<F>(f: F) -> Option<String> where F: FnOnce(RustStringRef){
     let mut buf = RefCell::new(Vec::new());
     f(&mut buf as RustStringRepr as RustStringRef);
     String::from_utf8(buf.into_inner()).ok()

From 1195708f64f34f6c402f98f5b551e2567be731c9 Mon Sep 17 00:00:00 2001
From: Jorge Aparicio <japaricious@gmail.com>
Date: Mon, 8 Dec 2014 20:26:43 -0500
Subject: [PATCH 82/92] librustc: use unboxed closures

---
 src/librustc/lint/context.rs                  | 12 ++-
 src/librustc/metadata/csearch.rs              | 62 ++++++++------
 src/librustc/metadata/cstore.rs               | 10 ++-
 src/librustc/metadata/decoder.rs              | 73 +++++++++-------
 src/librustc/metadata/encoder.rs              | 10 ++-
 src/librustc/metadata/filesearch.rs           |  4 +-
 src/librustc/metadata/tydecode.rs             | 21 +++--
 src/librustc/metadata/tyencode.rs             | 14 ++--
 src/librustc/middle/astencode.rs              | 28 ++++---
 src/librustc/middle/check_const.rs            | 12 ++-
 src/librustc/middle/check_loop.rs             |  4 +-
 src/librustc/middle/check_match.rs            |  4 +-
 src/librustc/middle/check_static.rs           |  4 +-
 src/librustc/middle/dataflow.rs               | 24 +++---
 src/librustc/middle/def.rs                    |  4 +-
 src/librustc/middle/graph.rs                  | 46 +++++-----
 src/librustc/middle/infer/coercion.rs         | 21 +++--
 .../middle/infer/higher_ranked/mod.rs         |  8 +-
 src/librustc/middle/infer/mod.rs              | 84 ++++++++++++-------
 .../middle/infer/region_inference/mod.rs      | 24 +++---
 src/librustc/middle/infer/skolemize.rs        | 11 +--
 src/librustc/middle/liveness.rs               | 44 +++++-----
 src/librustc/middle/mem_categorization.rs     |  5 +-
 src/librustc/middle/pat_util.rs               |  6 +-
 src/librustc/middle/region.rs                 |  4 +-
 src/librustc/middle/resolve.rs                | 44 ++++++----
 src/librustc/middle/resolve_lifetime.rs       | 18 ++--
 src/librustc/middle/stability.rs              |  4 +-
 src/librustc/middle/subst.rs                  | 15 ++--
 src/librustc/middle/traits/mod.rs             | 13 ++-
 src/librustc/middle/traits/util.rs            |  9 +-
 src/librustc/middle/ty.rs                     | 82 +++++++++++-------
 src/librustc/middle/ty_fold.rs                | 21 +++--
 src/librustc/util/common.rs                   | 46 ++++++----
 src/librustc_borrowck/borrowck/check_loans.rs | 24 +++---
 src/librustc_borrowck/borrowck/move_data.rs   | 42 +++++-----
 src/librustc_borrowck/graphviz.rs             | 18 ++--
 37 files changed, 517 insertions(+), 358 deletions(-)

diff --git a/src/librustc/lint/context.rs b/src/librustc/lint/context.rs
index 153a00e561776..9f9e266c6c74b 100644
--- a/src/librustc/lint/context.rs
+++ b/src/librustc/lint/context.rs
@@ -464,9 +464,11 @@ impl<'a, 'tcx> Context<'a, 'tcx> {
     /// Merge the lints specified by any lint attributes into the
     /// current lint context, call the provided function, then reset the
     /// lints in effect to their previous state.
-    fn with_lint_attrs(&mut self,
-                       attrs: &[ast::Attribute],
-                       f: |&mut Context|) {
+    fn with_lint_attrs<F>(&mut self,
+                          attrs: &[ast::Attribute],
+                          f: F) where
+        F: FnOnce(&mut Context),
+    {
         // Parse all of the lint attributes, and then add them all to the
         // current dictionary of lint information. Along the way, keep a history
         // of what we changed so we can roll everything back after invoking the
@@ -528,7 +530,9 @@ impl<'a, 'tcx> Context<'a, 'tcx> {
         }
     }
 
-    fn visit_ids(&mut self, f: |&mut ast_util::IdVisitor<Context>|) {
+    fn visit_ids<F>(&mut self, f: F) where
+        F: FnOnce(&mut ast_util::IdVisitor<Context>)
+    {
         let mut v = ast_util::IdVisitor {
             operation: self,
             pass_through_items: false,
diff --git a/src/librustc/metadata/csearch.rs b/src/librustc/metadata/csearch.rs
index 7ce9893afc8b1..4cbb1babf9a2c 100644
--- a/src/librustc/metadata/csearch.rs
+++ b/src/librustc/metadata/csearch.rs
@@ -47,20 +47,22 @@ pub fn get_symbol(cstore: &cstore::CStore, def: ast::DefId) -> String {
 }
 
 /// Iterates over all the language items in the given crate.
-pub fn each_lang_item(cstore: &cstore::CStore,
-                      cnum: ast::CrateNum,
-                      f: |ast::NodeId, uint| -> bool)
-                      -> bool {
+pub fn each_lang_item<F>(cstore: &cstore::CStore,
+                         cnum: ast::CrateNum,
+                         f: F)
+                         -> bool where
+    F: FnMut(ast::NodeId, uint) -> bool,
+{
     let crate_data = cstore.get_crate_data(cnum);
     decoder::each_lang_item(&*crate_data, f)
 }
 
 /// Iterates over each child of the given item.
-pub fn each_child_of_item(cstore: &cstore::CStore,
-                          def_id: ast::DefId,
-                          callback: |decoder::DefLike,
-                                     ast::Name,
-                                     ast::Visibility|) {
+pub fn each_child_of_item<F>(cstore: &cstore::CStore,
+                             def_id: ast::DefId,
+                             callback: F) where
+    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| {
         cstore.get_crate_data(cnum)
@@ -73,11 +75,11 @@ pub fn each_child_of_item(cstore: &cstore::CStore,
 }
 
 /// Iterates over each top-level crate item.
-pub fn each_top_level_item_of_crate(cstore: &cstore::CStore,
-                                    cnum: ast::CrateNum,
-                                    callback: |decoder::DefLike,
-                                               ast::Name,
-                                               ast::Visibility|) {
+pub fn each_top_level_item_of_crate<F>(cstore: &cstore::CStore,
+                                       cnum: ast::CrateNum,
+                                       callback: F) where
+    F: FnMut(decoder::DefLike, ast::Name, ast::Visibility),
+{
     let crate_data = cstore.get_crate_data(cnum);
     let get_crate_data: decoder::GetCrateDataCb = |cnum| {
         cstore.get_crate_data(cnum)
@@ -195,9 +197,11 @@ pub fn get_methods_if_impl(cstore: &cstore::CStore,
     decoder::get_methods_if_impl(cstore.intr.clone(), &*cdata, def.node)
 }
 
-pub fn get_item_attrs(cstore: &cstore::CStore,
-                      def_id: ast::DefId,
-                      f: |Vec<ast::Attribute>|) {
+pub fn get_item_attrs<F>(cstore: &cstore::CStore,
+                         def_id: ast::DefId,
+                         f: F) where
+    F: FnOnce(Vec<ast::Attribute>),
+{
     let cdata = cstore.get_crate_data(def_id.krate);
     decoder::get_item_attrs(&*cdata, def_id.node, f)
 }
@@ -279,23 +283,29 @@ pub fn get_native_libraries(cstore: &cstore::CStore, crate_num: ast::CrateNum)
     decoder::get_native_libraries(&*cdata)
 }
 
-pub fn each_impl(cstore: &cstore::CStore,
-                 crate_num: ast::CrateNum,
-                 callback: |ast::DefId|) {
+pub fn each_impl<F>(cstore: &cstore::CStore,
+                    crate_num: ast::CrateNum,
+                    callback: F) where
+    F: FnMut(ast::DefId),
+{
     let cdata = cstore.get_crate_data(crate_num);
     decoder::each_impl(&*cdata, callback)
 }
 
-pub fn each_implementation_for_type(cstore: &cstore::CStore,
-                                    def_id: ast::DefId,
-                                    callback: |ast::DefId|) {
+pub fn each_implementation_for_type<F>(cstore: &cstore::CStore,
+                                       def_id: ast::DefId,
+                                       callback: F) where
+    F: FnMut(ast::DefId),
+{
     let cdata = cstore.get_crate_data(def_id.krate);
     decoder::each_implementation_for_type(&*cdata, def_id.node, callback)
 }
 
-pub fn each_implementation_for_trait(cstore: &cstore::CStore,
-                                     def_id: ast::DefId,
-                                     callback: |ast::DefId|) {
+pub fn each_implementation_for_trait<F>(cstore: &cstore::CStore,
+                                        def_id: ast::DefId,
+                                        callback: F) where
+    F: FnMut(ast::DefId),
+{
     let cdata = cstore.get_crate_data(def_id.krate);
     decoder::each_implementation_for_trait(&*cdata, def_id.node, callback)
 }
diff --git a/src/librustc/metadata/cstore.rs b/src/librustc/metadata/cstore.rs
index bb1c75b075c2b..c0642f29abc90 100644
--- a/src/librustc/metadata/cstore.rs
+++ b/src/librustc/metadata/cstore.rs
@@ -113,16 +113,18 @@ impl CStore {
         self.metas.borrow_mut().insert(cnum, data);
     }
 
-    pub fn iter_crate_data(&self, i: |ast::CrateNum, &crate_metadata|) {
+    pub fn iter_crate_data<I>(&self, mut i: I) where
+        I: FnMut(ast::CrateNum, &crate_metadata),
+    {
         for (&k, v) in self.metas.borrow().iter() {
             i(k, &**v);
         }
     }
 
     /// Like `iter_crate_data`, but passes source paths (if available) as well.
-    pub fn iter_crate_data_origins(&self, i: |ast::CrateNum,
-                                              &crate_metadata,
-                                              Option<CrateSource>|) {
+    pub fn iter_crate_data_origins<I>(&self, mut i: I) where
+        I: FnMut(ast::CrateNum, &crate_metadata, Option<CrateSource>),
+    {
         for (&k, v) in self.metas.borrow().iter() {
             let origin = self.get_used_crate_source(k);
             origin.as_ref().map(|cs| { assert!(k == cs.cnum); });
diff --git a/src/librustc/metadata/decoder.rs b/src/librustc/metadata/decoder.rs
index 2000c4e1abe9b..4e892f53186bc 100644
--- a/src/librustc/metadata/decoder.rs
+++ b/src/librustc/metadata/decoder.rs
@@ -60,8 +60,9 @@ pub type Cmd<'a> = &'a crate_metadata;
 // what crate that's in and give us a def_id that makes sense for the current
 // build.
 
-fn lookup_hash<'a>(d: rbml::Doc<'a>, eq_fn: |&[u8]| -> bool,
-                   hash: u64) -> Option<rbml::Doc<'a>> {
+fn lookup_hash<'a, F>(d: rbml::Doc<'a>, mut eq_fn: F, hash: u64) -> Option<rbml::Doc<'a>> where
+    F: FnMut(&[u8]) -> bool,
+{
     let index = reader::get_doc(d, tag_index);
     let table = reader::get_doc(index, tag_index_table);
     let hash_pos = table.start + (hash % 256 * 4) as uint;
@@ -448,7 +449,9 @@ pub enum DefLike {
 impl Copy for DefLike {}
 
 /// Iterates over the language items in the given crate.
-pub fn each_lang_item(cdata: Cmd, f: |ast::NodeId, uint| -> bool) -> bool {
+pub fn each_lang_item<F>(cdata: Cmd, mut f: F) -> bool where
+    F: FnMut(ast::NodeId, uint) -> bool,
+{
     let root = rbml::Doc::new(cdata.data());
     let lang_items = reader::get_doc(root, tag_lang_items);
     reader::tagged_docs(lang_items, tag_lang_items_item, |item_doc| {
@@ -464,13 +467,13 @@ pub fn each_lang_item(cdata: Cmd, f: |ast::NodeId, uint| -> bool) -> bool {
 
 pub type GetCrateDataCb<'a> = |ast::CrateNum|: 'a -> Rc<crate_metadata>;
 
-fn each_child_of_item_or_crate(intr: Rc<IdentInterner>,
-                               cdata: Cmd,
-                               item_doc: rbml::Doc,
-                               get_crate_data: GetCrateDataCb,
-                               callback: |DefLike,
-                                          ast::Name,
-                                          ast::Visibility|) {
+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
+    F: FnMut(DefLike, ast::Name, ast::Visibility),
+{
     // Iterate over all children.
     let _ = reader::tagged_docs(item_doc, tag_mod_child, |child_info_doc| {
         let child_def_id = reader::with_doc_data(child_info_doc,
@@ -583,11 +586,13 @@ fn each_child_of_item_or_crate(intr: Rc<IdentInterner>,
 }
 
 /// Iterates over each child of the given item.
-pub fn each_child_of_item(intr: Rc<IdentInterner>,
-                          cdata: Cmd,
-                          id: ast::NodeId,
-                          get_crate_data: GetCrateDataCb,
-                          callback: |DefLike, ast::Name, ast::Visibility|) {
+pub fn each_child_of_item<F>(intr: Rc<IdentInterner>,
+                             cdata: Cmd,
+                             id: ast::NodeId,
+                             get_crate_data: GetCrateDataCb,
+                             callback: F) where
+    F: FnMut(DefLike, ast::Name, ast::Visibility),
+{
     // Find the item.
     let root_doc = rbml::Doc::new(cdata.data());
     let items = reader::get_doc(root_doc, tag_items);
@@ -604,12 +609,12 @@ pub fn each_child_of_item(intr: Rc<IdentInterner>,
 }
 
 /// Iterates over all the top-level crate items.
-pub fn each_top_level_item_of_crate(intr: Rc<IdentInterner>,
-                                    cdata: Cmd,
-                                    get_crate_data: GetCrateDataCb,
-                                    callback: |DefLike,
-                                               ast::Name,
-                                               ast::Visibility|) {
+pub fn each_top_level_item_of_crate<F>(intr: Rc<IdentInterner>,
+                                       cdata: Cmd,
+                                       get_crate_data: GetCrateDataCb,
+                                       callback: F) where
+    F: FnMut(DefLike, ast::Name, ast::Visibility),
+{
     let root_doc = rbml::Doc::new(cdata.data());
     let misc_info_doc = reader::get_doc(root_doc, tag_misc_info);
     let crate_items_doc = reader::get_doc(misc_info_doc,
@@ -982,9 +987,11 @@ pub fn get_tuple_struct_definition_if_ctor(cdata: Cmd,
     ret
 }
 
-pub fn get_item_attrs(cdata: Cmd,
-                      orig_node_id: ast::NodeId,
-                      f: |Vec<ast::Attribute>|) {
+pub fn get_item_attrs<F>(cdata: Cmd,
+                         orig_node_id: ast::NodeId,
+                         f: F) where
+    F: FnOnce(Vec<ast::Attribute>),
+{
     // The attributes for a tuple struct are attached to the definition, not the ctor;
     // we assume that someone passing in a tuple struct ctor is actually wanting to
     // look at the definition
@@ -1224,7 +1231,9 @@ pub fn translate_def_id(cdata: Cmd, did: ast::DefId) -> ast::DefId {
     }
 }
 
-pub fn each_impl(cdata: Cmd, callback: |ast::DefId|) {
+pub fn each_impl<F>(cdata: Cmd, mut callback: F) where
+    F: FnMut(ast::DefId),
+{
     let impls_doc = reader::get_doc(rbml::Doc::new(cdata.data()), tag_impls);
     let _ = reader::tagged_docs(impls_doc, tag_impls_impl, |impl_doc| {
         callback(item_def_id(impl_doc, cdata));
@@ -1232,9 +1241,11 @@ pub fn each_impl(cdata: Cmd, callback: |ast::DefId|) {
     });
 }
 
-pub fn each_implementation_for_type(cdata: Cmd,
+pub fn each_implementation_for_type<F>(cdata: Cmd,
                                     id: ast::NodeId,
-                                    callback: |ast::DefId|) {
+                                    mut callback: F) where
+    F: FnMut(ast::DefId),
+{
     let item_doc = lookup_item(id, cdata.data());
     reader::tagged_docs(item_doc,
                         tag_items_data_item_inherent_impl,
@@ -1245,9 +1256,11 @@ pub fn each_implementation_for_type(cdata: Cmd,
     });
 }
 
-pub fn each_implementation_for_trait(cdata: Cmd,
-                                     id: ast::NodeId,
-                                     callback: |ast::DefId|) {
+pub fn each_implementation_for_trait<F>(cdata: Cmd,
+                                        id: ast::NodeId,
+                                        mut callback: F) where
+    F: FnMut(ast::DefId),
+{
     let item_doc = lookup_item(id, cdata.data());
 
     let _ = reader::tagged_docs(item_doc,
diff --git a/src/librustc/metadata/encoder.rs b/src/librustc/metadata/encoder.rs
index 48d1284f50787..9804e3c20aa35 100644
--- a/src/librustc/metadata/encoder.rs
+++ b/src/librustc/metadata/encoder.rs
@@ -493,7 +493,9 @@ fn encode_reexported_static_methods(ecx: &EncodeContext,
 /// top-level items that are sub-items of the given item. Specifically:
 ///
 /// * For newtype structs, iterates through the node ID of the constructor.
-fn each_auxiliary_node_id(item: &ast::Item, callback: |NodeId| -> bool) -> bool {
+fn each_auxiliary_node_id<F>(item: &ast::Item, callback: F) -> bool where
+    F: FnOnce(NodeId) -> bool,
+{
     let mut continue_ = true;
     match item.node {
         ast::ItemStruct(ref struct_def, _) => {
@@ -1579,8 +1581,10 @@ fn encode_info_for_items(ecx: &EncodeContext,
 
 // Path and definition ID indexing
 
-fn encode_index<T: Hash>(rbml_w: &mut Encoder, index: Vec<entry<T>>,
-                         write_fn: |&mut SeekableMemWriter, &T|) {
+fn encode_index<T, F>(rbml_w: &mut Encoder, index: Vec<entry<T>>, mut write_fn: F) where
+    F: FnMut(&mut SeekableMemWriter, &T),
+    T: Hash,
+{
     let mut buckets: Vec<Vec<entry<T>>> = Vec::from_fn(256, |_| Vec::new());
     for elt in index.into_iter() {
         let h = hash::hash(&elt.val) as uint;
diff --git a/src/librustc/metadata/filesearch.rs b/src/librustc/metadata/filesearch.rs
index 2d23a61813a9c..507fb751303f9 100644
--- a/src/librustc/metadata/filesearch.rs
+++ b/src/librustc/metadata/filesearch.rs
@@ -42,7 +42,9 @@ pub struct FileSearch<'a> {
 }
 
 impl<'a> FileSearch<'a> {
-    pub fn for_each_lib_search_path(&self, f: |&Path| -> FileMatch) {
+    pub fn for_each_lib_search_path<F>(&self, mut f: F) where
+        F: FnMut(&Path) -> FileMatch,
+    {
         let mut visited_dirs = HashSet::new();
         let mut found = false;
 
diff --git a/src/librustc/metadata/tydecode.rs b/src/librustc/metadata/tydecode.rs
index 37d790df37f46..7358b3bc9c969 100644
--- a/src/librustc/metadata/tydecode.rs
+++ b/src/librustc/metadata/tydecode.rs
@@ -89,7 +89,10 @@ fn next_byte(st: &mut PState) -> u8 {
     return b;
 }
 
-fn scan<R>(st: &mut PState, is_last: |char| -> bool, op: |&[u8]| -> R) -> R {
+fn scan<R, F, G>(st: &mut PState, mut is_last: F, op: G) -> R where
+    F: FnMut(char) -> bool,
+    G: FnOnce(&[u8]) -> R,
+{
     let start_pos = st.pos;
     debug!("scan: '{}' (start)", st.data[st.pos] as char);
     while !is_last(st.data[st.pos] as char) {
@@ -110,7 +113,9 @@ pub fn parse_name(st: &mut PState, last: char) -> ast::Name {
     parse_name_(st, |a| is_last(last, a) )
 }
 
-fn parse_name_(st: &mut PState, is_last: |char| -> bool) -> ast::Name {
+fn parse_name_<F>(st: &mut PState, is_last: F) -> ast::Name where
+    F: FnMut(char) -> bool,
+{
     scan(st, is_last, |bytes| {
         token::intern(str::from_utf8(bytes).unwrap())
     })
@@ -234,9 +239,10 @@ fn parse_trait_store(st: &mut PState, conv: conv_did) -> ty::TraitStore {
     }
 }
 
-fn parse_vec_per_param_space<'a, 'tcx, T>(st: &mut PState<'a, 'tcx>,
-                                          f: |&mut PState<'a, 'tcx>| -> T)
-                                          -> VecPerParamSpace<T>
+fn parse_vec_per_param_space<'a, 'tcx, T, F>(st: &mut PState<'a, 'tcx>,
+                                             mut f: F)
+                                             -> VecPerParamSpace<T> where
+    F: FnMut(&mut PState<'a, 'tcx>) -> T,
 {
     let mut r = VecPerParamSpace::empty();
     for &space in subst::ParamSpace::all().iter() {
@@ -350,8 +356,9 @@ fn parse_scope(st: &mut PState) -> region::CodeExtent {
     }
 }
 
-fn parse_opt<'a, 'tcx, T>(st: &mut PState<'a, 'tcx>, f: |&mut PState<'a, 'tcx>| -> T)
-                          -> Option<T> {
+fn parse_opt<'a, 'tcx, T, F>(st: &mut PState<'a, 'tcx>, f: F) -> Option<T> where
+    F: FnOnce(&mut PState<'a, 'tcx>) -> T,
+{
     match next(st) {
       'n' => None,
       's' => Some(f(st)),
diff --git a/src/librustc/metadata/tyencode.rs b/src/librustc/metadata/tyencode.rs
index 5c7d15e16018b..54376cd7b9078 100644
--- a/src/librustc/metadata/tyencode.rs
+++ b/src/librustc/metadata/tyencode.rs
@@ -86,7 +86,9 @@ fn enc_mt<'a, 'tcx>(w: &mut SeekableMemWriter, cx: &ctxt<'a, 'tcx>,
     enc_ty(w, cx, mt.ty);
 }
 
-fn enc_opt<T>(w: &mut SeekableMemWriter, t: Option<T>, enc_f: |&mut SeekableMemWriter, T|) {
+fn enc_opt<T, F>(w: &mut SeekableMemWriter, t: Option<T>, enc_f: F) where
+    F: FnOnce(&mut SeekableMemWriter, T),
+{
     match t {
         None => mywrite!(w, "n"),
         Some(v) => {
@@ -96,10 +98,12 @@ fn enc_opt<T>(w: &mut SeekableMemWriter, t: Option<T>, enc_f: |&mut SeekableMemW
     }
 }
 
-fn enc_vec_per_param_space<'a, 'tcx, T>(w: &mut SeekableMemWriter,
-                                        cx: &ctxt<'a, 'tcx>,
-                                        v: &VecPerParamSpace<T>,
-                                        op: |&mut SeekableMemWriter, &ctxt<'a, 'tcx>, &T|) {
+fn enc_vec_per_param_space<'a, 'tcx, T, F>(w: &mut SeekableMemWriter,
+                                           cx: &ctxt<'a, 'tcx>,
+                                           v: &VecPerParamSpace<T>,
+                                           mut op: F) where
+    F: FnMut(&mut SeekableMemWriter, &ctxt<'a, 'tcx>, &T),
+{
     for &space in subst::ParamSpace::all().iter() {
         mywrite!(w, "[");
         for t in v.get_slice(space).iter() {
diff --git a/src/librustc/middle/astencode.rs b/src/librustc/middle/astencode.rs
index 50337ec25bd19..26d70502a5b16 100644
--- a/src/librustc/middle/astencode.rs
+++ b/src/librustc/middle/astencode.rs
@@ -680,9 +680,8 @@ pub fn encode_unboxed_closure_kind(ebml_w: &mut Encoder,
 }
 
 pub trait vtable_decoder_helpers<'tcx> {
-    fn read_vec_per_param_space<T>(&mut self,
-                                   f: |&mut Self| -> T)
-                                   -> VecPerParamSpace<T>;
+    fn read_vec_per_param_space<T, F>(&mut self, f: F) -> VecPerParamSpace<T> where
+        F: FnMut(&mut Self) -> T;
     fn read_vtable_res_with_key(&mut self,
                                 tcx: &ty::ctxt<'tcx>,
                                 cdata: &cstore::crate_metadata)
@@ -699,9 +698,8 @@ pub trait vtable_decoder_helpers<'tcx> {
 }
 
 impl<'tcx, 'a> vtable_decoder_helpers<'tcx> for reader::Decoder<'a> {
-    fn read_vec_per_param_space<T>(&mut self,
-                                   f: |&mut reader::Decoder<'a>| -> T)
-                                   -> VecPerParamSpace<T>
+    fn read_vec_per_param_space<T, F>(&mut self, mut f: F) -> VecPerParamSpace<T> where
+        F: FnMut(&mut reader::Decoder<'a>) -> T,
     {
         let types = self.read_to_vec(|this| Ok(f(this))).unwrap();
         let selfs = self.read_to_vec(|this| Ok(f(this))).unwrap();
@@ -793,9 +791,11 @@ impl<'tcx, 'a> vtable_decoder_helpers<'tcx> for reader::Decoder<'a> {
 // ___________________________________________________________________________
 //
 
-fn encode_vec_per_param_space<T>(rbml_w: &mut Encoder,
-                                 v: &subst::VecPerParamSpace<T>,
-                                 f: |&mut Encoder, &T|) {
+fn encode_vec_per_param_space<T, F>(rbml_w: &mut Encoder,
+                                    v: &subst::VecPerParamSpace<T>,
+                                    mut f: F) where
+    F: FnMut(&mut Encoder, &T),
+{
     for &space in subst::ParamSpace::all().iter() {
         rbml_w.emit_from_vec(v.get_slice(space),
                              |rbml_w, n| Ok(f(rbml_w, n))).unwrap();
@@ -1124,14 +1124,16 @@ impl<'a, 'tcx> rbml_writer_helpers<'tcx> for Encoder<'a> {
 }
 
 trait write_tag_and_id {
-    fn tag(&mut self, tag_id: c::astencode_tag, f: |&mut Self|);
+    fn tag<F>(&mut self, tag_id: c::astencode_tag, f: F) where F: FnOnce(&mut Self);
     fn id(&mut self, id: ast::NodeId);
 }
 
 impl<'a> write_tag_and_id for Encoder<'a> {
-    fn tag(&mut self,
-           tag_id: c::astencode_tag,
-           f: |&mut Encoder<'a>|) {
+    fn tag<F>(&mut self,
+              tag_id: c::astencode_tag,
+              f: F) where
+        F: FnOnce(&mut Encoder<'a>),
+    {
         self.start_tag(tag_id as uint);
         f(self);
         self.end_tag();
diff --git a/src/librustc/middle/check_const.rs b/src/librustc/middle/check_const.rs
index de140fd5c306c..a91ea8bfef8c7 100644
--- a/src/librustc/middle/check_const.rs
+++ b/src/librustc/middle/check_const.rs
@@ -24,16 +24,22 @@ struct CheckCrateVisitor<'a, 'tcx: 'a> {
 }
 
 impl<'a, 'tcx> CheckCrateVisitor<'a, 'tcx> {
-    fn with_const(&mut self, in_const: bool, f: |&mut CheckCrateVisitor<'a, 'tcx>|) {
+    fn with_const<F>(&mut self, in_const: bool, f: F) where
+        F: FnOnce(&mut CheckCrateVisitor<'a, 'tcx>),
+    {
         let was_const = self.in_const;
         self.in_const = in_const;
         f(self);
         self.in_const = was_const;
     }
-    fn inside_const(&mut self, f: |&mut CheckCrateVisitor<'a, 'tcx>|) {
+    fn inside_const<F>(&mut self, f: F) where
+        F: FnOnce(&mut CheckCrateVisitor<'a, 'tcx>),
+    {
         self.with_const(true, f);
     }
-    fn outside_const(&mut self, f: |&mut CheckCrateVisitor<'a, 'tcx>|) {
+    fn outside_const<F>(&mut self, f: F) where
+        F: FnOnce(&mut CheckCrateVisitor<'a, 'tcx>),
+    {
         self.with_const(false, f);
     }
 }
diff --git a/src/librustc/middle/check_loop.rs b/src/librustc/middle/check_loop.rs
index eb073e07b02f1..fee2d810fcb3d 100644
--- a/src/librustc/middle/check_loop.rs
+++ b/src/librustc/middle/check_loop.rs
@@ -64,7 +64,9 @@ impl<'a, 'v> Visitor<'v> for CheckLoopVisitor<'a> {
 }
 
 impl<'a> CheckLoopVisitor<'a> {
-    fn with_context(&mut self, cx: Context, f: |&mut CheckLoopVisitor<'a>|) {
+    fn with_context<F>(&mut self, cx: Context, f: F) where
+        F: FnOnce(&mut CheckLoopVisitor<'a>),
+    {
         let old_cx = self.cx;
         self.cx = cx;
         f(self);
diff --git a/src/librustc/middle/check_match.rs b/src/librustc/middle/check_match.rs
index 2c437ae046b46..ea3ef2af73906 100644
--- a/src/librustc/middle/check_match.rs
+++ b/src/librustc/middle/check_match.rs
@@ -980,7 +980,9 @@ fn check_fn(cx: &mut MatchCheckCtxt,
     }
 }
 
-fn is_refutable<A>(cx: &MatchCheckCtxt, pat: &Pat, refutable: |&Pat| -> A) -> Option<A> {
+fn is_refutable<A, F>(cx: &MatchCheckCtxt, pat: &Pat, refutable: F) -> Option<A> where
+    F: FnOnce(&Pat) -> A,
+{
     let pats = Matrix(vec!(vec!(pat)));
     match is_useful(cx, &pats, &[DUMMY_WILD_PAT], ConstructWitness) {
         UsefulWithWitness(pats) => {
diff --git a/src/librustc/middle/check_static.rs b/src/librustc/middle/check_static.rs
index 5a53979d71932..65412ff8effc9 100644
--- a/src/librustc/middle/check_static.rs
+++ b/src/librustc/middle/check_static.rs
@@ -85,7 +85,9 @@ pub fn check_crate(tcx: &ty::ctxt) {
 }
 
 impl<'a, 'tcx> CheckStaticVisitor<'a, 'tcx> {
-    fn with_mode(&mut self, mode: Mode, f: |&mut CheckStaticVisitor<'a, 'tcx>|) {
+    fn with_mode<F>(&mut self, mode: Mode, f: F) where
+        F: FnOnce(&mut CheckStaticVisitor<'a, 'tcx>),
+    {
         let old = self.mode;
         self.mode = mode;
         f(self);
diff --git a/src/librustc/middle/dataflow.rs b/src/librustc/middle/dataflow.rs
index db8fd999f380b..9373a5704b2b0 100644
--- a/src/librustc/middle/dataflow.rs
+++ b/src/librustc/middle/dataflow.rs
@@ -280,10 +280,9 @@ impl<'a, 'tcx, O:DataFlowOperator> DataFlowContext<'a, 'tcx, O> {
     }
 
 
-    pub fn each_bit_on_entry(&self,
-                             id: ast::NodeId,
-                             f: |uint| -> bool)
-                             -> bool {
+    pub fn each_bit_on_entry<F>(&self, id: ast::NodeId, f: F) -> bool where
+        F: FnMut(uint) -> bool,
+    {
         //! Iterates through each bit that is set on entry to `id`.
         //! Only useful after `propagate()` has been called.
         if !self.has_bitset_for_nodeid(id) {
@@ -293,11 +292,9 @@ impl<'a, 'tcx, O:DataFlowOperator> DataFlowContext<'a, 'tcx, O> {
         self.each_bit_for_node(Entry, cfgidx, f)
     }
 
-    pub fn each_bit_for_node(&self,
-                             e: EntryOrExit,
-                             cfgidx: CFGIndex,
-                             f: |uint| -> bool)
-                             -> bool {
+    pub fn each_bit_for_node<F>(&self, e: EntryOrExit, cfgidx: CFGIndex, f: F) -> bool where
+        F: FnMut(uint) -> bool,
+    {
         //! Iterates through each bit that is set on entry/exit to `cfgidx`.
         //! Only useful after `propagate()` has been called.
 
@@ -324,8 +321,9 @@ impl<'a, 'tcx, O:DataFlowOperator> DataFlowContext<'a, 'tcx, O> {
         self.each_bit(slice, f)
     }
 
-    pub fn each_gen_bit(&self, id: ast::NodeId, f: |uint| -> bool)
-                        -> bool {
+    pub fn each_gen_bit<F>(&self, id: ast::NodeId, f: F) -> bool where
+        F: FnMut(uint) -> bool,
+    {
         //! Iterates through each bit in the gen set for `id`.
         if !self.has_bitset_for_nodeid(id) {
             return true;
@@ -345,7 +343,9 @@ impl<'a, 'tcx, O:DataFlowOperator> DataFlowContext<'a, 'tcx, O> {
         self.each_bit(gens, f)
     }
 
-    fn each_bit(&self, words: &[uint], f: |uint| -> bool) -> bool {
+    fn each_bit<F>(&self, words: &[uint], mut f: F) -> bool where
+        F: FnMut(uint) -> bool,
+    {
         //! Helper for iterating over the bits in a bit set.
         //! Returns false on the first call to `f` that returns false;
         //! if all calls to `f` return true, then returns true.
diff --git a/src/librustc/middle/def.rs b/src/librustc/middle/def.rs
index b3e4dd25adc7a..ca60ac45e266a 100644
--- a/src/librustc/middle/def.rs
+++ b/src/librustc/middle/def.rs
@@ -61,7 +61,9 @@ pub enum MethodProvenance {
 }
 
 impl MethodProvenance {
-    pub fn map(self, f: |ast::DefId| -> ast::DefId) -> MethodProvenance {
+    pub fn map<F>(self, f: F) -> MethodProvenance where
+        F: FnOnce(ast::DefId) -> ast::DefId,
+    {
         match self {
             FromTrait(did) => FromTrait(f(did)),
             FromImpl(did) => FromImpl(f(did))
diff --git a/src/librustc/middle/graph.rs b/src/librustc/middle/graph.rs
index e45232a3c3038..4c03ed2a480ef 100644
--- a/src/librustc/middle/graph.rs
+++ b/src/librustc/middle/graph.rs
@@ -221,39 +221,43 @@ impl<N,E> Graph<N,E> {
     ///////////////////////////////////////////////////////////////////////////
     // Iterating over nodes, edges
 
-    pub fn each_node<'a>(&'a self, f: |NodeIndex, &'a Node<N>| -> bool) -> bool {
+    pub fn each_node<'a, F>(&'a self, mut f: F) -> bool where
+        F: FnMut(NodeIndex, &'a Node<N>) -> bool,
+    {
         //! Iterates over all edges defined in the graph.
         self.nodes.iter().enumerate().all(|(i, node)| f(NodeIndex(i), node))
     }
 
-    pub fn each_edge<'a>(&'a self, f: |EdgeIndex, &'a Edge<E>| -> bool) -> bool {
+    pub fn each_edge<'a, F>(&'a self, mut f: F) -> bool where
+        F: FnMut(EdgeIndex, &'a Edge<E>) -> bool,
+    {
         //! Iterates over all edges defined in the graph
         self.edges.iter().enumerate().all(|(i, edge)| f(EdgeIndex(i), edge))
     }
 
-    pub fn each_outgoing_edge<'a>(&'a self,
-                                  source: NodeIndex,
-                                  f: |EdgeIndex, &'a Edge<E>| -> bool)
-                                  -> bool {
+    pub fn each_outgoing_edge<'a, F>(&'a self, source: NodeIndex, f: F) -> bool where
+        F: FnMut(EdgeIndex, &'a Edge<E>) -> bool,
+    {
         //! Iterates over all outgoing edges from the node `from`
 
         self.each_adjacent_edge(source, Outgoing, f)
     }
 
-    pub fn each_incoming_edge<'a>(&'a self,
-                                  target: NodeIndex,
-                                  f: |EdgeIndex, &'a Edge<E>| -> bool)
-                                  -> bool {
+    pub fn each_incoming_edge<'a, F>(&'a self, target: NodeIndex, f: F) -> bool where
+        F: FnMut(EdgeIndex, &'a Edge<E>) -> bool,
+    {
         //! Iterates over all incoming edges to the node `target`
 
         self.each_adjacent_edge(target, Incoming, f)
     }
 
-    pub fn each_adjacent_edge<'a>(&'a self,
-                                  node: NodeIndex,
-                                  dir: Direction,
-                                  f: |EdgeIndex, &'a Edge<E>| -> bool)
-                                  -> bool {
+    pub fn each_adjacent_edge<'a, F>(&'a self,
+                                     node: NodeIndex,
+                                     dir: Direction,
+                                     mut f: F)
+                                     -> bool where
+        F: FnMut(EdgeIndex, &'a Edge<E>) -> bool,
+    {
         //! Iterates over all edges adjacent to the node `node`
         //! in the direction `dir` (either `Outgoing` or `Incoming)
 
@@ -277,11 +281,9 @@ impl<N,E> Graph<N,E> {
     // variables or other bitsets. This method facilitates such a
     // computation.
 
-    pub fn iterate_until_fixed_point<'a>(&'a self,
-                                         op: |iter_index: uint,
-                                              edge_index: EdgeIndex,
-                                              edge: &'a Edge<E>|
-                                              -> bool) {
+    pub fn iterate_until_fixed_point<'a, F>(&'a self, mut op: F) where
+        F: FnMut(uint, EdgeIndex, &'a Edge<E>) -> bool,
+    {
         let mut iteration = 0;
         let mut changed = true;
         while changed {
@@ -294,7 +296,9 @@ impl<N,E> Graph<N,E> {
     }
 }
 
-pub fn each_edge_index(max_edge_index: EdgeIndex, f: |EdgeIndex| -> bool) {
+pub fn each_edge_index<F>(max_edge_index: EdgeIndex, mut f: F) where
+    F: FnMut(EdgeIndex) -> bool,
+{
     let mut i = 0;
     let n = max_edge_index.get();
     while i < n {
diff --git a/src/librustc/middle/infer/coercion.rs b/src/librustc/middle/infer/coercion.rs
index f04c519badc8c..c6422b36e384d 100644
--- a/src/librustc/middle/infer/coercion.rs
+++ b/src/librustc/middle/infer/coercion.rs
@@ -194,8 +194,9 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
         }
     }
 
-    pub fn unpack_actual_value<T>(&self, a: Ty<'tcx>, f: |&ty::sty<'tcx>| -> T)
-                                  -> T {
+    pub fn unpack_actual_value<T, F>(&self, a: Ty<'tcx>, f: F) -> T where
+        F: FnOnce(&ty::sty<'tcx>) -> T,
+    {
         match resolve_type(self.get_ref().infcx, None,
                            a, try_resolve_tvar_shallow) {
             Ok(t) => {
@@ -458,13 +459,15 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
                            || AutoUnsafe(b_mutbl, None))
     }
 
-    fn coerce_object(&self,
-                     a: Ty<'tcx>,
-                     sty_a: &ty::sty<'tcx>,
-                     b: Ty<'tcx>,
-                     b_mutbl: ast::Mutability,
-                     mk_ty: |Ty<'tcx>| -> Ty<'tcx>,
-                     mk_adjust: || -> ty::AutoRef<'tcx>) -> CoerceResult<'tcx>
+    fn coerce_object<F, G>(&self,
+                           a: Ty<'tcx>,
+                           sty_a: &ty::sty<'tcx>,
+                           b: Ty<'tcx>,
+                           b_mutbl: ast::Mutability,
+                           mk_ty: F,
+                           mk_adjust: G) -> CoerceResult<'tcx> where
+        F: FnOnce(Ty<'tcx>) -> Ty<'tcx>,
+        G: FnOnce() -> ty::AutoRef<'tcx>,
     {
         let tcx = self.get_ref().infcx.tcx;
 
diff --git a/src/librustc/middle/infer/higher_ranked/mod.rs b/src/librustc/middle/infer/higher_ranked/mod.rs
index 95805ef8b944d..be053afcca436 100644
--- a/src/librustc/middle/infer/higher_ranked/mod.rs
+++ b/src/librustc/middle/infer/higher_ranked/mod.rs
@@ -426,11 +426,9 @@ fn is_var_in_set(new_vars: &[ty::RegionVid], r: ty::Region) -> bool {
     }
 }
 
-fn fold_regions_in<'tcx, T>(tcx: &ty::ctxt<'tcx>,
-                            value: &T,
-                            fldr: |ty::Region, ty::DebruijnIndex| -> ty::Region)
-                            -> T
-    where T: HigherRankedFoldable<'tcx>
+fn fold_regions_in<'tcx, T, F>(tcx: &ty::ctxt<'tcx>, value: &T, mut fldr: F) -> T where
+    T: HigherRankedFoldable<'tcx>,
+    F: FnMut(ty::Region, ty::DebruijnIndex) -> ty::Region,
 {
     value.fold_contents(&mut ty_fold::RegionFolder::new(tcx, |region, current_depth| {
         // we should only be encountering "escaping" late-bound regions here,
diff --git a/src/librustc/middle/infer/mod.rs b/src/librustc/middle/infer/mod.rs
index 3b62b96a3e9b1..4c3b7589d76cb 100644
--- a/src/librustc/middle/infer/mod.rs
+++ b/src/librustc/middle/infer/mod.rs
@@ -477,14 +477,17 @@ pub fn resolve_region(cx: &InferCtxt, r: ty::Region, modes: uint)
 }
 
 trait then<'tcx> {
-    fn then<T:Clone>(&self, f: || -> Result<T,ty::type_err<'tcx>>)
-        -> Result<T,ty::type_err<'tcx>>;
+    fn then<T, F>(&self, f: F) -> Result<T, ty::type_err<'tcx>> where
+        T: Clone,
+        F: FnOnce() -> Result<T, ty::type_err<'tcx>>;
 }
 
 impl<'tcx> then<'tcx> for ures<'tcx> {
-    fn then<T:Clone>(&self, f: || -> Result<T,ty::type_err<'tcx>>)
-        -> Result<T,ty::type_err<'tcx>> {
-        self.and_then(|_i| f())
+    fn then<T, F>(&self, f: F) -> Result<T, ty::type_err<'tcx>> where
+        T: Clone,
+        F: FnOnce() -> Result<T, ty::type_err<'tcx>>,
+    {
+        self.and_then(move |_| f())
     }
 }
 
@@ -502,12 +505,15 @@ impl<'tcx, T> ToUres<'tcx> for cres<'tcx, T> {
 }
 
 trait CresCompare<'tcx, T> {
-    fn compare(&self, t: T, f: || -> ty::type_err<'tcx>) -> cres<'tcx, T>;
+    fn compare<F>(&self, t: T, f: F) -> cres<'tcx, T> where
+        F: FnOnce() -> ty::type_err<'tcx>;
 }
 
 impl<'tcx, T:Clone + PartialEq> CresCompare<'tcx, T> for cres<'tcx, T> {
-    fn compare(&self, t: T, f: || -> ty::type_err<'tcx>) -> cres<'tcx, T> {
-        (*self).clone().and_then(|s| {
+    fn compare<F>(&self, t: T, f: F) -> cres<'tcx, T> where
+        F: FnOnce() -> ty::type_err<'tcx>,
+    {
+        (*self).clone().and_then(move |s| {
             if s == t {
                 (*self).clone()
             } else {
@@ -616,7 +622,9 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
     }
 
     /// Execute `f` and commit the bindings
-    pub fn commit_unconditionally<R>(&self, f: || -> R) -> R {
+    pub fn commit_unconditionally<R, F>(&self, f: F) -> R where
+        F: FnOnce() -> R,
+    {
         debug!("commit()");
         let snapshot = self.start_snapshot();
         let r = f();
@@ -625,12 +633,16 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
     }
 
     /// Execute `f` and commit the bindings if successful
-    pub fn commit_if_ok<T,E>(&self, f: || -> Result<T,E>) -> Result<T,E> {
-        self.commit_unconditionally(|| self.try(|| f()))
+    pub fn commit_if_ok<T, E, F>(&self, f: F) -> Result<T, E> where
+        F: FnOnce() -> Result<T, E>
+    {
+        self.commit_unconditionally(move || self.try(move || f()))
     }
 
     /// Execute `f`, unroll bindings on panic
-    pub fn try<T,E>(&self, f: || -> Result<T,E>) -> Result<T,E> {
+    pub fn try<T, E, F>(&self, f: F) -> Result<T, E> where
+        F: FnOnce() -> Result<T, E>
+    {
         debug!("try()");
         let snapshot = self.start_snapshot();
         let r = f();
@@ -647,7 +659,9 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
     }
 
     /// Execute `f` then unroll any bindings it creates
-    pub fn probe<R>(&self, f: || -> R) -> R {
+    pub fn probe<R, F>(&self, f: F) -> R where
+        F: FnOnce() -> R,
+    {
         debug!("probe()");
         let snapshot = self.start_snapshot();
         let r = f();
@@ -902,22 +916,24 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
     // in this case. The typechecker should only ever report type errors involving mismatched
     // types using one of these four methods, and should not call span_err directly for such
     // errors.
-    pub fn type_error_message_str(&self,
-                                  sp: Span,
-                                  mk_msg: |Option<String>, String| -> String,
-                                  actual_ty: String,
-                                  err: Option<&ty::type_err<'tcx>>) {
+    pub fn type_error_message_str<M>(&self,
+                                     sp: Span,
+                                     mk_msg: M,
+                                     actual_ty: String,
+                                     err: Option<&ty::type_err<'tcx>>) where
+        M: FnOnce(Option<String>, String) -> String,
+    {
         self.type_error_message_str_with_expected(sp, mk_msg, None, actual_ty, err)
     }
 
-    pub fn type_error_message_str_with_expected(&self,
-                                                sp: Span,
-                                                mk_msg: |Option<String>,
-                                                         String|
-                                                         -> String,
-                                                expected_ty: Option<Ty<'tcx>>,
-                                                actual_ty: String,
-                                                err: Option<&ty::type_err<'tcx>>) {
+    pub fn type_error_message_str_with_expected<M>(&self,
+                                                   sp: Span,
+                                                   mk_msg: M,
+                                                   expected_ty: Option<Ty<'tcx>>,
+                                                   actual_ty: String,
+                                                   err: Option<&ty::type_err<'tcx>>) where
+        M: FnOnce(Option<String>, String) -> String,
+    {
         debug!("hi! expected_ty = {}, actual_ty = {}", expected_ty, actual_ty);
 
         let resolved_expected = expected_ty.map(|e_ty| {
@@ -942,11 +958,13 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
         }
     }
 
-    pub fn type_error_message(&self,
-                              sp: Span,
-                              mk_msg: |String| -> String,
-                              actual_ty: Ty<'tcx>,
-                              err: Option<&ty::type_err<'tcx>>) {
+    pub fn type_error_message<M>(&self,
+                                 sp: Span,
+                                 mk_msg: M,
+                                 actual_ty: Ty<'tcx>,
+                                 err: Option<&ty::type_err<'tcx>>) where
+        M: FnOnce(String) -> String,
+    {
         let actual_ty = self.resolve_type_vars_if_possible(actual_ty);
 
         // Don't report an error if actual type is ty_err.
@@ -954,7 +972,9 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
             return;
         }
 
-        self.type_error_message_str(sp, |_e, a| { mk_msg(a) }, self.ty_to_string(actual_ty), err);
+        self.type_error_message_str(sp,
+            move |_e, a| { mk_msg(a) },
+            self.ty_to_string(actual_ty), err);
     }
 
     pub fn report_mismatched_types(&self,
diff --git a/src/librustc/middle/infer/region_inference/mod.rs b/src/librustc/middle/infer/region_inference/mod.rs
index 391e37e8b9c96..98f69f66b27fc 100644
--- a/src/librustc/middle/infer/region_inference/mod.rs
+++ b/src/librustc/middle/infer/region_inference/mod.rs
@@ -569,15 +569,15 @@ impl<'a, 'tcx> RegionVarBindings<'a, 'tcx> {
         }
     }
 
-    pub fn combine_vars(&self,
-                        t: CombineMapType,
-                        a: Region,
-                        b: Region,
-                        origin: SubregionOrigin<'tcx>,
-                        relate: |this: &RegionVarBindings<'a, 'tcx>,
-                                 old_r: Region,
-                                 new_r: Region|)
-                        -> Region {
+    pub fn combine_vars<F>(&self,
+                           t: CombineMapType,
+                           a: Region,
+                           b: Region,
+                           origin: SubregionOrigin<'tcx>,
+                           mut relate: F)
+                           -> Region where
+        F: FnMut(&RegionVarBindings<'a, 'tcx>, Region, Region),
+    {
         let vars = TwoRegions { a: a, b: b };
         match self.combine_map(t).borrow().get(&vars) {
             Some(&c) => {
@@ -1539,9 +1539,9 @@ impl<'a, 'tcx> RegionVarBindings<'a, 'tcx> {
         }
     }
 
-    fn iterate_until_fixed_point(&self,
-                                 tag: &str,
-                                 body: |constraint: &Constraint| -> bool) {
+    fn iterate_until_fixed_point<F>(&self, tag: &str, mut body: F) where
+        F: FnMut(&Constraint) -> bool,
+    {
         let mut iteration = 0u;
         let mut changed = true;
         while changed {
diff --git a/src/librustc/middle/infer/skolemize.rs b/src/librustc/middle/infer/skolemize.rs
index 62bf1d0126a59..705b0ae730d49 100644
--- a/src/librustc/middle/infer/skolemize.rs
+++ b/src/librustc/middle/infer/skolemize.rs
@@ -54,11 +54,12 @@ impl<'a, 'tcx> TypeSkolemizer<'a, 'tcx> {
         }
     }
 
-    fn skolemize(&mut self,
-                 opt_ty: Option<Ty<'tcx>>,
-                 key: ty::InferTy,
-                 skolemizer: |uint| -> ty::InferTy)
-                 -> Ty<'tcx>
+    fn skolemize<F>(&mut self,
+                    opt_ty: Option<Ty<'tcx>>,
+                    key: ty::InferTy,
+                    skolemizer: F)
+                    -> Ty<'tcx> where
+        F: FnOnce(uint) -> ty::InferTy,
     {
         match opt_ty {
             Some(ty) => { return ty.fold_with(self); }
diff --git a/src/librustc/middle/liveness.rs b/src/librustc/middle/liveness.rs
index 5edbafc4e0bee..271e903bbdf17 100644
--- a/src/librustc/middle/liveness.rs
+++ b/src/librustc/middle/liveness.rs
@@ -616,9 +616,9 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
         self.ir.variable(node_id, span)
     }
 
-    fn pat_bindings(&mut self,
-                    pat: &ast::Pat,
-                    f: |&mut Liveness<'a, 'tcx>, LiveNode, Variable, Span, NodeId|) {
+    fn pat_bindings<F>(&mut self, pat: &ast::Pat, mut f: F) where
+        F: FnMut(&mut Liveness<'a, 'tcx>, LiveNode, Variable, Span, NodeId),
+    {
         pat_util::pat_bindings(&self.ir.tcx.def_map, pat, |_bm, p_id, sp, _n| {
             let ln = self.live_node(p_id, sp);
             let var = self.variable(p_id, sp);
@@ -626,9 +626,9 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
         })
     }
 
-    fn arm_pats_bindings(&mut self,
-                         pat: Option<&ast::Pat>,
-                         f: |&mut Liveness<'a, 'tcx>, LiveNode, Variable, Span, NodeId|) {
+    fn arm_pats_bindings<F>(&mut self, pat: Option<&ast::Pat>, f: F) where
+        F: FnMut(&mut Liveness<'a, 'tcx>, LiveNode, Variable, Span, NodeId),
+    {
         match pat {
             Some(pat) => {
                 self.pat_bindings(pat, f);
@@ -691,10 +691,9 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
         self.assigned_on_entry(successor, var)
     }
 
-    fn indices2(&mut self,
-                ln: LiveNode,
-                succ_ln: LiveNode,
-                op: |&mut Liveness<'a, 'tcx>, uint, uint|) {
+    fn indices2<F>(&mut self, ln: LiveNode, succ_ln: LiveNode, mut op: F) where
+        F: FnMut(&mut Liveness<'a, 'tcx>, uint, uint),
+    {
         let node_base_idx = self.idx(ln, Variable(0u));
         let succ_base_idx = self.idx(succ_ln, Variable(0u));
         for var_idx in range(0u, self.ir.num_vars) {
@@ -702,10 +701,13 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
         }
     }
 
-    fn write_vars(&self,
-                  wr: &mut io::Writer,
-                  ln: LiveNode,
-                  test: |uint| -> LiveNode) -> io::IoResult<()> {
+    fn write_vars<F>(&self,
+                     wr: &mut io::Writer,
+                     ln: LiveNode,
+                     mut test: F)
+                     -> io::IoResult<()> where
+        F: FnMut(uint) -> LiveNode,
+    {
         let node_base_idx = self.idx(ln, Variable(0));
         for var_idx in range(0u, self.ir.num_vars) {
             let idx = node_base_idx + var_idx;
@@ -1408,12 +1410,14 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
         cond_ln
     }
 
-    fn with_loop_nodes<R>(&mut self,
-                          loop_node_id: NodeId,
-                          break_ln: LiveNode,
-                          cont_ln: LiveNode,
-                          f: |&mut Liveness<'a, 'tcx>| -> R)
-                          -> R {
+    fn with_loop_nodes<R, F>(&mut self,
+                             loop_node_id: NodeId,
+                             break_ln: LiveNode,
+                             cont_ln: LiveNode,
+                             f: F)
+                             -> R where
+        F: FnOnce(&mut Liveness<'a, 'tcx>) -> R,
+    {
         debug!("with_loop_nodes: {} {}", loop_node_id, break_ln.get());
         self.loop_scope.push(loop_node_id);
         self.break_ln.insert(loop_node_id, break_ln);
diff --git a/src/librustc/middle/mem_categorization.rs b/src/librustc/middle/mem_categorization.rs
index 302fbd53dd530..d96cf4495bdde 100644
--- a/src/librustc/middle/mem_categorization.rs
+++ b/src/librustc/middle/mem_categorization.rs
@@ -1142,12 +1142,11 @@ 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|)
+                       op: |&MemCategorizationContext<'t, TYPER>, cmt<'tcx>, &ast::Pat|)
                        -> McResult<()> {
         // Here, `cmt` is the categorization for the value being
         // matched and pat is the pattern it is being matched against.
diff --git a/src/librustc/middle/pat_util.rs b/src/librustc/middle/pat_util.rs
index 8d4fbfd4cbccc..8ef8e091c9485 100644
--- a/src/librustc/middle/pat_util.rs
+++ b/src/librustc/middle/pat_util.rs
@@ -91,9 +91,9 @@ pub fn pat_is_binding_or_wild(dm: &resolve::DefMap, pat: &ast::Pat) -> bool {
 
 /// Call `it` on every "binding" in a pattern, e.g., on `a` in
 /// `match foo() { Some(a) => (), None => () }`
-pub fn pat_bindings(dm: &resolve::DefMap,
-                    pat: &ast::Pat,
-                    it: |ast::BindingMode, ast::NodeId, Span, &ast::SpannedIdent|) {
+pub fn pat_bindings<I>(dm: &resolve::DefMap, pat: &ast::Pat, mut it: I) where
+    I: FnMut(ast::BindingMode, ast::NodeId, Span, &ast::SpannedIdent),
+{
     walk_pat(pat, |p| {
         match p.node {
           ast::PatIdent(binding_mode, ref pth, _) if pat_is_binding(dm, p) => {
diff --git a/src/librustc/middle/region.rs b/src/librustc/middle/region.rs
index 370097004e92c..390729df0125d 100644
--- a/src/librustc/middle/region.rs
+++ b/src/librustc/middle/region.rs
@@ -62,7 +62,9 @@ impl CodeExtent {
 
     /// Maps this scope to a potentially new one according to the
     /// NodeId transformer `f_id`.
-    pub fn map_id(&self, f_id: |ast::NodeId| -> ast::NodeId) -> CodeExtent {
+    pub fn map_id<F>(&self, f_id: F) -> CodeExtent where
+        F: FnOnce(ast::NodeId) -> ast::NodeId,
+    {
         match *self {
             CodeExtent::Misc(node_id) => CodeExtent::Misc(f_id(node_id)),
         }
diff --git a/src/librustc/middle/resolve.rs b/src/librustc/middle/resolve.rs
index 2899f60f736af..85e0c9294a6ba 100644
--- a/src/librustc/middle/resolve.rs
+++ b/src/librustc/middle/resolve.rs
@@ -1837,10 +1837,12 @@ impl<'a> Resolver<'a> {
     }
 
     /// Constructs the reduced graph for one foreign item.
-    fn build_reduced_graph_for_foreign_item(&mut self,
-                                            foreign_item: &ForeignItem,
-                                            parent: ReducedGraphParent,
-                                            f: |&mut Resolver|) {
+    fn build_reduced_graph_for_foreign_item<F>(&mut self,
+                                               foreign_item: &ForeignItem,
+                                               parent: ReducedGraphParent,
+                                               f: F) where
+        F: FnOnce(&mut Resolver),
+    {
         let name = foreign_item.ident.name;
         let is_public = foreign_item.vis == ast::Public;
         let modifiers = if is_public { PUBLIC } else { DefModifiers::empty() } | IMPORTABLE;
@@ -3970,7 +3972,9 @@ impl<'a> Resolver<'a> {
     // generate a fake "implementation scope" containing all the
     // implementations thus found, for compatibility with old resolve pass.
 
-    fn with_scope(&mut self, name: Option<Name>, f: |&mut Resolver|) {
+    fn with_scope<F>(&mut self, name: Option<Name>, f: F) where
+        F: FnOnce(&mut Resolver),
+    {
         let orig_module = self.current_module.clone();
 
         // Move down in the graph.
@@ -4373,9 +4377,9 @@ impl<'a> Resolver<'a> {
         }
     }
 
-    fn with_type_parameter_rib(&mut self,
-                               type_parameters: TypeParameters,
-                               f: |&mut Resolver|) {
+    fn with_type_parameter_rib<F>(&mut self, type_parameters: TypeParameters, f: F) where
+        F: FnOnce(&mut Resolver),
+    {
         match type_parameters {
             HasTypeParameters(generics, space, node_id, rib_kind) => {
                 let mut function_type_rib = Rib::new(rib_kind);
@@ -4422,13 +4426,17 @@ impl<'a> Resolver<'a> {
         }
     }
 
-    fn with_label_rib(&mut self, f: |&mut Resolver|) {
+    fn with_label_rib<F>(&mut self, f: F) where
+        F: FnOnce(&mut Resolver),
+    {
         self.label_ribs.push(Rib::new(NormalRibKind));
         f(self);
         self.label_ribs.pop();
     }
 
-    fn with_constant_rib(&mut self, f: |&mut Resolver|) {
+    fn with_constant_rib<F>(&mut self, f: F) where
+        F: FnOnce(&mut Resolver),
+    {
         self.value_ribs.push(Rib::new(ConstantItemRibKind));
         self.type_ribs.push(Rib::new(ConstantItemRibKind));
         f(self);
@@ -4676,7 +4684,9 @@ impl<'a> Resolver<'a> {
                               method.pe_body());
     }
 
-    fn with_current_self_type<T>(&mut self, self_type: &Ty, f: |&mut Resolver| -> T) -> T {
+    fn with_current_self_type<T, F>(&mut self, self_type: &Ty, f: F) -> T where
+        F: FnOnce(&mut Resolver) -> T,
+    {
         // Handle nested impls (inside fn bodies)
         let previous_value = replace(&mut self.current_self_type, Some(self_type.clone()));
         let result = f(self);
@@ -4684,9 +4694,11 @@ impl<'a> Resolver<'a> {
         result
     }
 
-    fn with_optional_trait_ref<T>(&mut self, id: NodeId,
-                                  opt_trait_ref: &Option<TraitRef>,
-                                  f: |&mut Resolver| -> T) -> T {
+    fn with_optional_trait_ref<T, F>(&mut self, id: NodeId,
+                                     opt_trait_ref: &Option<TraitRef>,
+                                     f: F) -> T where
+        F: FnOnce(&mut Resolver) -> T,
+    {
         let new_val = match *opt_trait_ref {
             Some(ref trait_ref) => {
                 self.resolve_trait_reference(id, trait_ref, TraitImplementation);
@@ -5620,7 +5632,9 @@ impl<'a> Resolver<'a> {
         }
     }
 
-    fn with_no_errors<T>(&mut self, f: |&mut Resolver| -> T) -> T {
+    fn with_no_errors<T, F>(&mut self, f: F) -> T where
+        F: FnOnce(&mut Resolver) -> T,
+    {
         self.emit_errors = false;
         let rs = f(self);
         self.emit_errors = true;
diff --git a/src/librustc/middle/resolve_lifetime.rs b/src/librustc/middle/resolve_lifetime.rs
index 3ab94d3ca6619..83332d275ce99 100644
--- a/src/librustc/middle/resolve_lifetime.rs
+++ b/src/librustc/middle/resolve_lifetime.rs
@@ -247,7 +247,9 @@ impl<'a, 'v> Visitor<'v> for LifetimeContext<'a> {
 }
 
 impl<'a> LifetimeContext<'a> {
-    fn with(&mut self, wrap_scope: ScopeChain, f: |&mut LifetimeContext|) {
+    fn with<F>(&mut self, wrap_scope: ScopeChain, f: F) where
+        F: FnOnce(&mut LifetimeContext),
+    {
         let LifetimeContext {sess, ref mut named_region_map, ..} = *self;
         let mut this = LifetimeContext {
             sess: sess,
@@ -278,10 +280,12 @@ impl<'a> LifetimeContext<'a> {
     /// already in scope (for a fn item, that will be 0, but for a method it might not be). Late
     /// bound lifetimes are resolved by name and associated with a binder id (`binder_id`), so the
     /// ordering is not important there.
-    fn visit_early_late(&mut self,
-                        early_space: subst::ParamSpace,
-                        generics: &ast::Generics,
-                        walk: |&mut LifetimeContext|) {
+    fn visit_early_late<F>(&mut self,
+                           early_space: subst::ParamSpace,
+                           generics: &ast::Generics,
+                           walk: F) where
+        F: FnOnce(&mut LifetimeContext),
+    {
         let referenced_idents = early_bound_lifetime_names(generics);
 
         debug!("visit_early_late: referenced_idents={}",
@@ -290,8 +294,8 @@ impl<'a> LifetimeContext<'a> {
         let (early, late) = generics.lifetimes.clone().partition(
             |l| referenced_idents.iter().any(|&i| i == l.lifetime.name));
 
-        self.with(EarlyScope(early_space, &early, self.scope), |this| {
-            this.with(LateScope(&late, this.scope), |this| {
+        self.with(EarlyScope(early_space, &early, self.scope), move |this| {
+            this.with(LateScope(&late, this.scope), move |this| {
                 this.check_lifetime_defs(&generics.lifetimes);
                 walk(this);
             });
diff --git a/src/librustc/middle/stability.rs b/src/librustc/middle/stability.rs
index 994fe2e9e27c4..ca8029fdfca3b 100644
--- a/src/librustc/middle/stability.rs
+++ b/src/librustc/middle/stability.rs
@@ -43,7 +43,9 @@ struct Annotator {
 impl Annotator {
     // Determine the stability for a node based on its attributes and inherited
     // stability. The stability is recorded in the index and used as the parent.
-    fn annotate(&mut self, id: NodeId, attrs: &Vec<Attribute>, f: |&mut Annotator|) {
+    fn annotate<F>(&mut self, id: NodeId, attrs: &Vec<Attribute>, f: F) where
+        F: FnOnce(&mut Annotator),
+    {
         match attr::find_stability(attrs.as_slice()) {
             Some(stab) => {
                 self.index.local.insert(id, stab.clone());
diff --git a/src/librustc/middle/subst.rs b/src/librustc/middle/subst.rs
index 9791f8d2f5929..2098aa3db533a 100644
--- a/src/librustc/middle/subst.rs
+++ b/src/librustc/middle/subst.rs
@@ -167,10 +167,9 @@ impl<'tcx> Substs<'tcx> {
 }
 
 impl RegionSubsts {
-    fn map<A>(self,
-              a: A,
-              op: |VecPerParamSpace<ty::Region>, A| -> VecPerParamSpace<ty::Region>)
-              -> RegionSubsts {
+    fn map<A, F>(self, a: A, op: F) -> RegionSubsts where
+        F: FnOnce(VecPerParamSpace<ty::Region>, A) -> VecPerParamSpace<ty::Region>,
+    {
         match self {
             ErasedRegions => ErasedRegions,
             NonerasedRegions(r) => NonerasedRegions(op(r, a))
@@ -415,7 +414,9 @@ impl<T> VecPerParamSpace<T> {
         self.content.as_slice()
     }
 
-    pub fn all_vecs(&self, pred: |&[T]| -> bool) -> bool {
+    pub fn all_vecs<P>(&self, mut pred: P) -> bool where
+        P: FnMut(&[T]) -> bool,
+    {
         let spaces = [TypeSpace, SelfSpace, FnSpace];
         spaces.iter().all(|&space| { pred(self.get_slice(space)) })
     }
@@ -450,7 +451,9 @@ impl<T> VecPerParamSpace<T> {
                                        self.assoc_limit)
     }
 
-    pub fn map_move<U>(self, pred: |T| -> U) -> VecPerParamSpace<U> {
+    pub fn map_move<U, F>(self, mut pred: F) -> VecPerParamSpace<U> where
+        F: FnMut(T) -> U,
+    {
         let SeparateVecsPerParamSpace {
             types: t,
             selfs: s,
diff --git a/src/librustc/middle/traits/mod.rs b/src/librustc/middle/traits/mod.rs
index 52d3315398209..936304c5eb483 100644
--- a/src/librustc/middle/traits/mod.rs
+++ b/src/librustc/middle/traits/mod.rs
@@ -322,7 +322,9 @@ impl<'tcx, N> Vtable<'tcx, N> {
         }
     }
 
-    pub fn map_move_nested<M>(self, op: |N| -> M) -> Vtable<'tcx, M> {
+    pub fn map_move_nested<M, F>(self, op: F) -> Vtable<'tcx, M> where
+        F: FnMut(N) -> M,
+    {
         match self {
             VtableImpl(i) => VtableImpl(i.map_move_nested(op)),
             VtableFnPointer(sig) => VtableFnPointer(sig),
@@ -348,8 +350,9 @@ impl<'tcx, N> VtableImplData<'tcx, N> {
         }
     }
 
-    pub fn map_move_nested<M>(self, op: |N| -> M)
-                              -> VtableImplData<'tcx, M> {
+    pub fn map_move_nested<M, F>(self, op: F) -> VtableImplData<'tcx, M> where
+        F: FnMut(N) -> M,
+    {
         let VtableImplData { impl_def_id, substs, nested } = self;
         VtableImplData {
             impl_def_id: impl_def_id,
@@ -370,7 +373,9 @@ impl<N> VtableBuiltinData<N> {
         }
     }
 
-    pub fn map_move_nested<M>(self, op: |N| -> M) -> VtableBuiltinData<M> {
+    pub fn map_move_nested<M, F>(self, op: F) -> VtableBuiltinData<M> where
+        F: FnMut(N) -> M,
+    {
         VtableBuiltinData {
             nested: self.nested.map_move(op)
         }
diff --git a/src/librustc/middle/traits/util.rs b/src/librustc/middle/traits/util.rs
index 52154e0be7ad0..d8956246d326f 100644
--- a/src/librustc/middle/traits/util.rs
+++ b/src/librustc/middle/traits/util.rs
@@ -306,10 +306,11 @@ pub fn predicate_for_builtin_bound<'tcx>(
 /// of caller obligations), search through the trait and supertraits to find one where `test(d)` is
 /// true, where `d` is the def-id of the trait/supertrait. If any is found, return `Some(p)` where
 /// `p` is the path to that trait/supertrait. Else `None`.
-pub fn search_trait_and_supertraits_from_bound<'tcx>(tcx: &ty::ctxt<'tcx>,
-                                                     caller_bound: Rc<ty::TraitRef<'tcx>>,
-                                                     test: |ast::DefId| -> bool)
-                                                     -> Option<VtableParamData<'tcx>>
+pub fn search_trait_and_supertraits_from_bound<'tcx, F>(tcx: &ty::ctxt<'tcx>,
+                                                        caller_bound: Rc<ty::TraitRef<'tcx>>,
+                                                        mut test: F)
+                                                        -> Option<VtableParamData<'tcx>> where
+    F: FnMut(ast::DefId) -> bool,
 {
     for bound in transitive_bounds(tcx, &[caller_bound]) {
         if test(bound.def_id) {
diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs
index ffca616d76a81..8e99045cffb58 100644
--- a/src/librustc/middle/ty.rs
+++ b/src/librustc/middle/ty.rs
@@ -2420,10 +2420,13 @@ pub fn mk_param_from_def<'tcx>(cx: &ctxt<'tcx>, def: &TypeParameterDef) -> Ty<'t
 
 pub fn mk_open<'tcx>(cx: &ctxt<'tcx>, ty: Ty<'tcx>) -> Ty<'tcx> { mk_t(cx, ty_open(ty)) }
 
-pub fn walk_ty<'tcx>(ty: Ty<'tcx>, f: |Ty<'tcx>|) {
+pub fn walk_ty<'tcx, F>(ty: Ty<'tcx>, mut f: F) where
+    F: FnMut(Ty<'tcx>),
+{
     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;
@@ -2464,9 +2467,11 @@ pub fn maybe_walk_ty<'tcx>(ty: Ty<'tcx>, f: |Ty<'tcx>| -> bool) {
 }
 
 // Folds types from the bottom up.
-pub fn fold_ty<'tcx>(cx: &ctxt<'tcx>, t0: Ty<'tcx>,
-                     fldop: |Ty<'tcx>| -> Ty<'tcx>)
-                     -> Ty<'tcx> {
+pub fn fold_ty<'tcx, F>(cx: &ctxt<'tcx>, t0: Ty<'tcx>,
+                        fldop: F)
+                        -> Ty<'tcx> where
+    F: FnMut(Ty<'tcx>) -> Ty<'tcx>,
+{
     let mut f = ty_fold::BottomUpFolder {tcx: cx, fldop: fldop};
     f.fold_ty(t0)
 }
@@ -2843,7 +2848,9 @@ impl TypeContents {
         *self & TC::ReachesAll
     }
 
-    pub fn union<T>(v: &[T], f: |&T| -> TypeContents) -> TypeContents {
+    pub fn union<T, F>(v: &[T], mut f: F) -> TypeContents where
+        F: FnMut(&T) -> TypeContents,
+    {
         v.iter().fold(TC::None, |tc, ty| tc | f(ty))
     }
 
@@ -3162,10 +3169,12 @@ pub fn type_contents<'tcx>(cx: &ctxt<'tcx>, ty: Ty<'tcx>) -> TypeContents {
 
         // Iterates over all builtin bounds on the type parameter def, including
         // those inherited from traits with builtin-kind-supertraits.
-        fn each_inherited_builtin_bound<'tcx>(cx: &ctxt<'tcx>,
-                                              bounds: BuiltinBounds,
-                                              traits: &[Rc<TraitRef<'tcx>>],
-                                              f: |BuiltinBound|) {
+        fn each_inherited_builtin_bound<'tcx, F>(cx: &ctxt<'tcx>,
+                                                 bounds: BuiltinBounds,
+                                                 traits: &[Rc<TraitRef<'tcx>>],
+                                                 mut f: F) where
+            F: FnMut(BuiltinBound),
+        {
             for bound in bounds.iter() {
                 f(bound);
             }
@@ -3959,14 +3968,15 @@ pub fn local_var_name_str(cx: &ctxt, id: NodeId) -> InternedString {
 }
 
 /// See `expr_ty_adjusted`
-pub fn adjust_ty<'tcx>(cx: &ctxt<'tcx>,
-                       span: Span,
-                       expr_id: ast::NodeId,
-                       unadjusted_ty: Ty<'tcx>,
-                       adjustment: Option<&AutoAdjustment<'tcx>>,
-                       method_type: |MethodCall| -> Option<Ty<'tcx>>)
-                       -> Ty<'tcx> {
-
+pub fn adjust_ty<'tcx, F>(cx: &ctxt<'tcx>,
+                          span: Span,
+                          expr_id: ast::NodeId,
+                          unadjusted_ty: Ty<'tcx>,
+                          adjustment: Option<&AutoAdjustment<'tcx>>,
+                          mut method_type: F)
+                          -> Ty<'tcx> where
+    F: FnMut(MethodCall) -> Option<Ty<'tcx>>,
+{
     if let ty_err = unadjusted_ty.sty {
         return unadjusted_ty;
     }
@@ -4604,11 +4614,13 @@ pub fn provided_trait_methods<'tcx>(cx: &ctxt<'tcx>, id: ast::DefId)
 /// id is local, it should have been loaded into the map by the `typeck::collect` phase.  If the
 /// def-id is external, then we have to go consult the crate loading code (and cache the result for
 /// the future).
-fn lookup_locally_or_in_crate_store<V:Clone>(
-                                    descr: &str,
-                                    def_id: ast::DefId,
-                                    map: &mut DefIdMap<V>,
-                                    load_external: || -> V) -> V {
+fn lookup_locally_or_in_crate_store<V, F>(descr: &str,
+                                          def_id: ast::DefId,
+                                          map: &mut DefIdMap<V>,
+                                          load_external: F) -> V where
+    V: Clone,
+    F: FnOnce() -> V,
+{
     match map.get(&def_id).cloned() {
         Some(v) => { return v; }
         None => { }
@@ -5164,7 +5176,9 @@ pub fn predicates<'tcx>(
 /// Iterate over attributes of a definition.
 // (This should really be an iterator, but that would require csearch and
 // decoder to use iterators instead of higher-order functions.)
-pub fn each_attr(tcx: &ctxt, did: DefId, f: |&ast::Attribute| -> bool) -> bool {
+pub fn each_attr<F>(tcx: &ctxt, did: DefId, mut f: F) -> bool where
+    F: FnMut(&ast::Attribute) -> bool,
+{
     if is_local(did) {
         let item = tcx.map.expect_item(did.node);
         item.attrs.iter().all(|attr| f(attr))
@@ -5503,10 +5517,11 @@ pub fn eval_repeat_count(tcx: &ctxt, count_expr: &ast::Expr) -> uint {
 // Here, the supertraits are the transitive closure of the supertrait
 // relation on the supertraits from each bounded trait's constraint
 // list.
-pub fn each_bound_trait_and_supertraits<'tcx>(tcx: &ctxt<'tcx>,
-                                              bounds: &[Rc<TraitRef<'tcx>>],
-                                              f: |Rc<TraitRef<'tcx>>| -> bool)
-                                              -> bool
+pub fn each_bound_trait_and_supertraits<'tcx, F>(tcx: &ctxt<'tcx>,
+                                                 bounds: &[Rc<TraitRef<'tcx>>],
+                                                 mut f: F)
+                                                 -> bool where
+    F: FnMut(Rc<TraitRef<'tcx>>) -> bool,
 {
     for bound_trait_ref in traits::transitive_bounds(tcx, bounds) {
         if !f(bound_trait_ref) {
@@ -6194,7 +6209,9 @@ pub type FreevarMap = NodeMap<Vec<Freevar>>;
 
 pub type CaptureModeMap = NodeMap<ast::CaptureClause>;
 
-pub fn with_freevars<T>(tcx: &ty::ctxt, fid: ast::NodeId, f: |&[Freevar]| -> T) -> T {
+pub fn with_freevars<T, F>(tcx: &ty::ctxt, fid: ast::NodeId, f: F) -> T where
+    F: FnOnce(&[Freevar]) -> T,
+{
     match tcx.freevars.borrow().get(&fid) {
         None => f(&[]),
         Some(d) => f(d.as_slice())
@@ -6242,12 +6259,13 @@ pub fn erase_late_bound_regions<'tcx, HR>(
 }
 
 /// Replaces the late-bound-regions in `value` that are bound by `value`.
-pub fn replace_late_bound_regions<'tcx, HR>(
+pub fn replace_late_bound_regions<'tcx, HR, F>(
     tcx: &ty::ctxt<'tcx>,
     value: &HR,
-    mapf: |BoundRegion, DebruijnIndex| -> ty::Region)
-    -> (HR, FnvHashMap<ty::BoundRegion,ty::Region>)
-    where HR : HigherRankedFoldable<'tcx>
+    mut mapf: F)
+-> (HR, FnvHashMap<ty::BoundRegion, ty::Region>) where
+    HR : HigherRankedFoldable<'tcx>,
+    F: FnMut(BoundRegion, DebruijnIndex) -> ty::Region,
 {
     debug!("replace_late_bound_regions({})", value.repr(tcx));
 
diff --git a/src/librustc/middle/ty_fold.rs b/src/librustc/middle/ty_fold.rs
index 8b54a46bfb934..63ee71dc6a51a 100644
--- a/src/librustc/middle/ty_fold.rs
+++ b/src/librustc/middle/ty_fold.rs
@@ -743,12 +743,14 @@ impl<'tcx, T:HigherRankedFoldable<'tcx>> HigherRankedFoldable<'tcx> for Rc<T> {
 ///////////////////////////////////////////////////////////////////////////
 // Some sample folders
 
-pub struct BottomUpFolder<'a, 'tcx: 'a> {
+pub struct BottomUpFolder<'a, 'tcx: 'a, F> where F: FnMut(Ty<'tcx>) -> Ty<'tcx> {
     pub tcx: &'a ty::ctxt<'tcx>,
-    pub fldop: |Ty<'tcx>|: 'a -> Ty<'tcx>,
+    pub fldop: F,
 }
 
-impl<'a, 'tcx> TypeFolder<'tcx> for BottomUpFolder<'a, 'tcx> {
+impl<'a, 'tcx, F> TypeFolder<'tcx> for BottomUpFolder<'a, 'tcx, F> where
+    F: FnMut(Ty<'tcx>) -> Ty<'tcx>,
+{
     fn tcx<'a>(&'a self) -> &'a ty::ctxt<'tcx> { self.tcx }
 
     fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {
@@ -772,15 +774,14 @@ impl<'a, 'tcx> TypeFolder<'tcx> for BottomUpFolder<'a, 'tcx> {
 /// (The distinction between "free" and "bound" is represented by
 /// keeping track of each `FnSig` in the lexical context of the
 /// current position of the fold.)
-pub struct RegionFolder<'a, 'tcx: 'a> {
+pub struct RegionFolder<'a, 'tcx: 'a, F> where F: FnMut(ty::Region, uint) -> ty::Region {
     tcx: &'a ty::ctxt<'tcx>,
     current_depth: uint,
-    fld_r: |ty::Region, uint|: 'a -> ty::Region,
+    fld_r: F,
 }
 
-impl<'a, 'tcx> RegionFolder<'a, 'tcx> {
-    pub fn new(tcx: &'a ty::ctxt<'tcx>, fld_r: |ty::Region, uint|: 'a -> ty::Region)
-               -> RegionFolder<'a, 'tcx> {
+impl<'a, 'tcx, F> RegionFolder<'a, 'tcx, F> where F: FnMut(ty::Region, uint) -> ty::Region {
+    pub fn new(tcx: &'a ty::ctxt<'tcx>, fld_r: F) -> RegionFolder<'a, 'tcx, F> {
         RegionFolder {
             tcx: tcx,
             current_depth: 1,
@@ -789,7 +790,9 @@ impl<'a, 'tcx> RegionFolder<'a, 'tcx> {
     }
 }
 
-impl<'a, 'tcx> TypeFolder<'tcx> for RegionFolder<'a, 'tcx> {
+impl<'a, 'tcx, F> TypeFolder<'tcx> for RegionFolder<'a, 'tcx, F> where
+    F: FnMut(ty::Region, uint) -> ty::Region,
+{
     fn tcx<'a>(&'a self) -> &'a ty::ctxt<'tcx> { self.tcx }
 
     fn enter_region_binder(&mut self) {
diff --git a/src/librustc/util/common.rs b/src/librustc/util/common.rs
index 30318cc129cac..51e18c80d0584 100644
--- a/src/librustc/util/common.rs
+++ b/src/librustc/util/common.rs
@@ -27,7 +27,9 @@ pub struct ErrorReported;
 
 impl Copy for ErrorReported {}
 
-pub fn time<T, U>(do_it: bool, what: &str, u: U, f: |U| -> T) -> T {
+pub fn time<T, U, F>(do_it: bool, what: &str, u: U, f: F) -> T where
+    F: FnOnce(U) -> T,
+{
     thread_local!(static DEPTH: Cell<uint> = Cell::new(0));
     if !do_it { return f(u); }
 
@@ -39,9 +41,13 @@ pub fn time<T, U>(do_it: bool, what: &str, u: U, f: |U| -> T) -> T {
 
     let mut u = Some(u);
     let mut rv = None;
-    let dur = Duration::span(|| {
-        rv = Some(f(u.take().unwrap()))
-    });
+    let dur = {
+        let ref mut rvp = rv;
+
+        Duration::span(move || {
+            *rvp = Some(f(u.take().unwrap()))
+        })
+    };
     let rv = rv.unwrap();
 
     println!("{}time: {}.{:03} \t{}", "  ".repeat(old),
@@ -51,7 +57,10 @@ pub fn time<T, U>(do_it: bool, what: &str, u: U, f: |U| -> T) -> T {
     rv
 }
 
-pub fn indent<R: Show>(op: || -> R) -> R {
+pub fn indent<R, F>(op: F) -> R where
+    R: Show,
+    F: FnOnce() -> R,
+{
     // Use in conjunction with the log post-processor like `src/etc/indenter`
     // to make debug output more readable.
     debug!(">>");
@@ -73,12 +82,12 @@ pub fn indenter() -> Indenter {
     Indenter { _cannot_construct_outside_of_this_module: () }
 }
 
-struct LoopQueryVisitor<'a> {
-    p: |&ast::Expr_|: 'a -> bool,
+struct LoopQueryVisitor<P> where P: FnMut(&ast::Expr_) -> bool {
+    p: P,
     flag: bool,
 }
 
-impl<'a, 'v> Visitor<'v> for LoopQueryVisitor<'a> {
+impl<'v, P> Visitor<'v> for LoopQueryVisitor<P> where P: FnMut(&ast::Expr_) -> bool {
     fn visit_expr(&mut self, e: &ast::Expr) {
         self.flag |= (self.p)(&e.node);
         match e.node {
@@ -92,7 +101,7 @@ impl<'a, 'v> Visitor<'v> for LoopQueryVisitor<'a> {
 
 // Takes a predicate p, returns true iff p is true for any subexpressions
 // of b -- skipping any inner loops (loop, while, loop_body)
-pub fn loop_query(b: &ast::Block, p: |&ast::Expr_| -> bool) -> bool {
+pub fn loop_query<P>(b: &ast::Block, p: P) -> bool where P: FnMut(&ast::Expr_) -> bool {
     let mut v = LoopQueryVisitor {
         p: p,
         flag: false,
@@ -101,12 +110,12 @@ pub fn loop_query(b: &ast::Block, p: |&ast::Expr_| -> bool) -> bool {
     return v.flag;
 }
 
-struct BlockQueryVisitor<'a> {
-    p: |&ast::Expr|: 'a -> bool,
+struct BlockQueryVisitor<P> where P: FnMut(&ast::Expr) -> bool {
+    p: P,
     flag: bool,
 }
 
-impl<'a, 'v> Visitor<'v> for BlockQueryVisitor<'a> {
+impl<'v, P> Visitor<'v> for BlockQueryVisitor<P> where P: FnMut(&ast::Expr) -> bool {
     fn visit_expr(&mut self, e: &ast::Expr) {
         self.flag |= (self.p)(e);
         visit::walk_expr(self, e)
@@ -115,7 +124,7 @@ impl<'a, 'v> Visitor<'v> for BlockQueryVisitor<'a> {
 
 // Takes a predicate p, returns true iff p is true for any subexpressions
 // of b -- skipping any inner loops (loop, while, loop_body)
-pub fn block_query(b: &ast::Block, p: |&ast::Expr| -> bool) -> bool {
+pub fn block_query<P>(b: &ast::Block, p: P) -> bool where P: FnMut(&ast::Expr) -> bool {
     let mut v = BlockQueryVisitor {
         p: p,
         flag: false,
@@ -194,11 +203,12 @@ pub fn can_reach<S,H:Hasher<S>,T:Eq+Clone+Hash<S>>(
 /// }
 /// ```
 #[inline(always)]
-pub fn memoized<T: Clone + Hash<S> + Eq, U: Clone, S, H: Hasher<S>>(
-    cache: &RefCell<HashMap<T, U, H>>,
-    arg: T,
-    f: |T| -> U
-) -> U {
+pub fn memoized<T, U, S, H, F>(cache: &RefCell<HashMap<T, U, H>>, arg: T, f: F) -> U where
+    T: Clone + Hash<S> + Eq,
+    U: Clone,
+    H: Hasher<S>,
+    F: FnOnce(T) -> U,
+{
     let key = arg.clone();
     let result = cache.borrow().get(&key).map(|result| result.clone());
     match result {
diff --git a/src/librustc_borrowck/borrowck/check_loans.rs b/src/librustc_borrowck/borrowck/check_loans.rs
index 4244cec7534d5..3bf817b42b06d 100644
--- a/src/librustc_borrowck/borrowck/check_loans.rs
+++ b/src/librustc_borrowck/borrowck/check_loans.rs
@@ -232,8 +232,9 @@ fn compatible_borrow_kinds(borrow_kind1: ty::BorrowKind,
 impl<'a, 'tcx> CheckLoanCtxt<'a, 'tcx> {
     pub fn tcx(&self) -> &'a ty::ctxt<'tcx> { self.bccx.tcx }
 
-    pub fn each_issued_loan(&self, scope: region::CodeExtent, op: |&Loan<'tcx>| -> bool)
-                            -> bool {
+    pub fn each_issued_loan<F>(&self, scope: region::CodeExtent, mut op: F) -> bool where
+        F: FnMut(&Loan<'tcx>) -> bool,
+    {
         //! Iterates over each loan that has been issued
         //! on entrance to `scope`, regardless of whether it is
         //! actually *in scope* at that point.  Sometimes loans
@@ -246,10 +247,9 @@ impl<'a, 'tcx> CheckLoanCtxt<'a, 'tcx> {
         })
     }
 
-    pub fn each_in_scope_loan(&self,
-                              scope: region::CodeExtent,
-                              op: |&Loan<'tcx>| -> bool)
-                              -> bool {
+    pub fn each_in_scope_loan<F>(&self, scope: region::CodeExtent, mut op: F) -> bool where
+        F: FnMut(&Loan<'tcx>) -> bool,
+    {
         //! Like `each_issued_loan()`, but only considers loans that are
         //! currently in scope.
 
@@ -263,11 +263,13 @@ impl<'a, 'tcx> CheckLoanCtxt<'a, 'tcx> {
         })
     }
 
-    fn each_in_scope_loan_affecting_path(&self,
-                                         scope: region::CodeExtent,
-                                         loan_path: &LoanPath<'tcx>,
-                                         op: |&Loan<'tcx>| -> bool)
-                                         -> bool {
+    fn each_in_scope_loan_affecting_path<F>(&self,
+                                            scope: region::CodeExtent,
+                                            loan_path: &LoanPath<'tcx>,
+                                            mut op: F)
+                                            -> bool where
+        F: FnMut(&Loan<'tcx>) -> bool,
+    {
         //! Iterates through all of the in-scope loans affecting `loan_path`,
         //! calling `op`, and ceasing iteration if `false` is returned.
 
diff --git a/src/librustc_borrowck/borrowck/move_data.rs b/src/librustc_borrowck/borrowck/move_data.rs
index 681a5772849f3..00b1377af7304 100644
--- a/src/librustc_borrowck/borrowck/move_data.rs
+++ b/src/librustc_borrowck/borrowck/move_data.rs
@@ -523,8 +523,9 @@ impl<'tcx> MoveData<'tcx> {
         }
     }
 
-    fn each_base_path(&self, index: MovePathIndex, f: |MovePathIndex| -> bool)
-                      -> bool {
+    fn each_base_path<F>(&self, index: MovePathIndex, mut f: F) -> bool where
+        F: FnMut(MovePathIndex) -> bool,
+    {
         let mut p = index;
         while p != InvalidMovePathIndex {
             if !f(p) {
@@ -535,10 +536,8 @@ impl<'tcx> MoveData<'tcx> {
         return true;
     }
 
-    fn each_extending_path(&self,
-                           index: MovePathIndex,
-                           f: |MovePathIndex| -> bool)
-                           -> bool {
+    // FIXME(#19596) unbox `f`
+    fn each_extending_path(&self, index: MovePathIndex, f: |MovePathIndex| -> bool) -> bool {
         if !f(index) {
             return false;
         }
@@ -554,10 +553,9 @@ impl<'tcx> MoveData<'tcx> {
         return true;
     }
 
-    fn each_applicable_move(&self,
-                            index0: MovePathIndex,
-                            f: |MoveIndex| -> bool)
-                            -> bool {
+    fn each_applicable_move<F>(&self, index0: MovePathIndex, mut f: F) -> bool where
+        F: FnMut(MoveIndex) -> bool,
+    {
         let mut ret = true;
         self.each_extending_path(index0, |index| {
             let mut p = self.path_first_move(index);
@@ -660,11 +658,13 @@ impl<'a, 'tcx> FlowedMoveData<'a, 'tcx> {
     /// Iterates through each move of `loan_path` (or some base path of `loan_path`) that *may*
     /// have occurred on entry to `id` without an intervening assignment. In other words, any moves
     /// that would invalidate a reference to `loan_path` at location `id`.
-    pub fn each_move_of(&self,
-                        id: ast::NodeId,
-                        loan_path: &Rc<LoanPath<'tcx>>,
-                        f: |&Move, &LoanPath<'tcx>| -> bool)
-                        -> bool {
+    pub fn each_move_of<F>(&self,
+                           id: ast::NodeId,
+                           loan_path: &Rc<LoanPath<'tcx>>,
+                           mut f: F)
+                           -> bool where
+        F: FnMut(&Move, &LoanPath<'tcx>) -> bool,
+    {
         // Bad scenarios:
         //
         // 1. Move of `a.b.c`, use of `a.b.c`
@@ -715,11 +715,13 @@ impl<'a, 'tcx> FlowedMoveData<'a, 'tcx> {
 
     /// Iterates through every assignment to `loan_path` that may have occurred on entry to `id`.
     /// `loan_path` must be a single variable.
-    pub fn each_assignment_of(&self,
-                              id: ast::NodeId,
-                              loan_path: &Rc<LoanPath<'tcx>>,
-                              f: |&Assignment| -> bool)
-                              -> bool {
+    pub fn each_assignment_of<F>(&self,
+                                 id: ast::NodeId,
+                                 loan_path: &Rc<LoanPath<'tcx>>,
+                                 mut f: F)
+                                 -> bool where
+        F: FnMut(&Assignment) -> bool,
+    {
         let loan_path_index = {
             match self.move_data.existing_move_path(loan_path) {
                 Some(i) => i,
diff --git a/src/librustc_borrowck/graphviz.rs b/src/librustc_borrowck/graphviz.rs
index 36c74720be438..e09ec79166997 100644
--- a/src/librustc_borrowck/graphviz.rs
+++ b/src/librustc_borrowck/graphviz.rs
@@ -75,11 +75,13 @@ impl<'a, 'tcx> DataflowLabeller<'a, 'tcx> {
         }
     }
 
-    fn build_set<O:DataFlowOperator>(&self,
-                                     e: EntryOrExit,
-                                     cfgidx: CFGIndex,
-                                     dfcx: &DataFlowContext<'a, 'tcx, O>,
-                                     to_lp: |uint| -> Rc<LoanPath<'tcx>>) -> String {
+    fn build_set<O:DataFlowOperator, F>(&self,
+                                        e: EntryOrExit,
+                                        cfgidx: CFGIndex,
+                                        dfcx: &DataFlowContext<'a, 'tcx, O>,
+                                        mut to_lp: F) -> String where
+        F: FnMut(uint) -> Rc<LoanPath<'tcx>>,
+    {
         let mut saw_some = false;
         let mut set = "{".to_string();
         dfcx.each_bit_for_node(e, cfgidx, |index| {
@@ -98,7 +100,7 @@ impl<'a, 'tcx> DataflowLabeller<'a, 'tcx> {
 
     fn dataflow_loans_for(&self, e: EntryOrExit, cfgidx: CFGIndex) -> String {
         let dfcx = &self.analysis_data.loans;
-        let loan_index_to_path = |loan_index| {
+        let loan_index_to_path = |&mut: loan_index| {
             let all_loans = &self.analysis_data.all_loans;
             all_loans[loan_index].loan_path()
         };
@@ -107,7 +109,7 @@ impl<'a, 'tcx> DataflowLabeller<'a, 'tcx> {
 
     fn dataflow_moves_for(&self, e: EntryOrExit, cfgidx: CFGIndex) -> String {
         let dfcx = &self.analysis_data.move_data.dfcx_moves;
-        let move_index_to_path = |move_index| {
+        let move_index_to_path = |&mut: move_index| {
             let move_data = &self.analysis_data.move_data.move_data;
             let moves = move_data.moves.borrow();
             let the_move = &(*moves)[move_index];
@@ -118,7 +120,7 @@ impl<'a, 'tcx> DataflowLabeller<'a, 'tcx> {
 
     fn dataflow_assigns_for(&self, e: EntryOrExit, cfgidx: CFGIndex) -> String {
         let dfcx = &self.analysis_data.move_data.dfcx_assign;
-        let assign_index_to_path = |assign_index| {
+        let assign_index_to_path = |&mut: assign_index| {
             let move_data = &self.analysis_data.move_data.move_data;
             let assignments = move_data.var_assignments.borrow();
             let assignment = &(*assignments)[assign_index];

From 46272c18a2c69d447dc80b2cf89ea8a2e247b791 Mon Sep 17 00:00:00 2001
From: Jorge Aparicio <japaricious@gmail.com>
Date: Tue, 9 Dec 2014 08:51:04 -0500
Subject: [PATCH 83/92] librustc_typeck: fix fallout

---
 src/librustc_typeck/check/mod.rs | 12 +++++++-----
 src/librustc_typeck/lib.rs       |  1 +
 2 files changed, 8 insertions(+), 5 deletions(-)

diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs
index 573c63eb6af05..a7163b75d5249 100644
--- a/src/librustc_typeck/check/mod.rs
+++ b/src/librustc_typeck/check/mod.rs
@@ -1938,11 +1938,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         infer::mk_subr(self.infcx(), origin, sub, sup)
     }
 
-    pub fn type_error_message(&self,
-                              sp: Span,
-                              mk_msg: |String| -> String,
-                              actual_ty: Ty<'tcx>,
-                              err: Option<&ty::type_err<'tcx>>) {
+    pub fn type_error_message<M>(&self,
+                                 sp: Span,
+                                 mk_msg: M,
+                                 actual_ty: Ty<'tcx>,
+                                 err: Option<&ty::type_err<'tcx>>) where
+        M: FnOnce(String) -> String,
+    {
         self.infcx().type_error_message(sp, mk_msg, actual_ty, err);
     }
 
diff --git a/src/librustc_typeck/lib.rs b/src/librustc_typeck/lib.rs
index 41ed5b8ec3656..0cf43821c82d6 100644
--- a/src/librustc_typeck/lib.rs
+++ b/src/librustc_typeck/lib.rs
@@ -74,6 +74,7 @@ This API is completely unstable and subject to change.
 #![feature(default_type_params, globs, import_shadowing, macro_rules, phase, quote)]
 #![feature(slicing_syntax, unsafe_destructor)]
 #![feature(rustc_diagnostic_macros)]
+#![feature(unboxed_closures)]
 #![allow(non_camel_case_types)]
 
 #[phase(plugin, link)] extern crate log;

From 0d4d8b9b78daff70b2b251fb5f71954d69a3b204 Mon Sep 17 00:00:00 2001
From: Jorge Aparicio <japaricious@gmail.com>
Date: Tue, 9 Dec 2014 11:00:41 -0500
Subject: [PATCH 84/92] librustc_trans: fix fallout

---
 src/librustc_trans/back/lto.rs | 16 ++++++----------
 1 file changed, 6 insertions(+), 10 deletions(-)

diff --git a/src/librustc_trans/back/lto.rs b/src/librustc_trans/back/lto.rs
index a715849ddf62f..fb4d6de5f282c 100644
--- a/src/librustc_trans/back/lto.rs
+++ b/src/librustc_trans/back/lto.rs
@@ -81,8 +81,9 @@ pub fn run(sess: &session::Session, llmod: ModuleRef,
                     break;
                 },
             };
-            let bc_extractor = if is_versioned_bytecode_format(bc_encoded) {
-                |_| {
+
+            let bc_decoded = if is_versioned_bytecode_format(bc_encoded) {
+                time(sess.time_passes(), format!("decode {}.{}.bc", file, i).as_slice(), (), |_| {
                     // Read the version
                     let version = extract_bytecode_format_version(bc_encoded);
 
@@ -104,11 +105,11 @@ pub fn run(sess: &session::Session, llmod: ModuleRef,
                         sess.fatal(format!("Unsupported bytecode format version {}",
                                            version).as_slice())
                     }
-                }
+                })
             } else {
+                time(sess.time_passes(), format!("decode {}.{}.bc", file, i).as_slice(), (), |_| {
                 // the object must be in the old, pre-versioning format, so simply
                 // inflate everything and let LLVM decide if it can make sense of it
-                |_| {
                     match flate::inflate_bytes(bc_encoded) {
                         Some(bc) => bc,
                         None => {
@@ -116,14 +117,9 @@ pub fn run(sess: &session::Session, llmod: ModuleRef,
                                                name).as_slice())
                         }
                     }
-                }
+                })
             };
 
-            let bc_decoded = time(sess.time_passes(),
-                                  format!("decode {}.{}.bc", file, i).as_slice(),
-                                  (),
-                                  bc_extractor);
-
             let ptr = bc_decoded.as_slice().as_ptr();
             debug!("linking {}, part {}", name, i);
             time(sess.time_passes(),

From 0676c3bf0315b7cb5dd309435b6c5ead5bf2bc2f Mon Sep 17 00:00:00 2001
From: Jorge Aparicio <japaricious@gmail.com>
Date: Tue, 9 Dec 2014 13:44:51 -0500
Subject: [PATCH 85/92] librustc_trans: use unboxed closures

---
 src/librustc_trans/back/write.rs        |  8 ++-
 src/librustc_trans/save/mod.rs          |  4 +-
 src/librustc_trans/trans/_match.rs      | 17 ++---
 src/librustc_trans/trans/adt.rs         | 11 +--
 src/librustc_trans/trans/base.rs        | 33 +++++----
 src/librustc_trans/trans/cabi_x86_64.rs | 12 ++--
 src/librustc_trans/trans/callee.rs      | 18 ++---
 src/librustc_trans/trans/cleanup.rs     |  4 +-
 src/librustc_trans/trans/datum.rs       | 35 +++++-----
 src/librustc_trans/trans/debuginfo.rs   | 14 ++--
 src/librustc_trans/trans/expr.rs        | 91 ++++++++++++++-----------
 11 files changed, 140 insertions(+), 107 deletions(-)

diff --git a/src/librustc_trans/back/write.rs b/src/librustc_trans/back/write.rs
index 0ed6ae311711f..c52f31532dcd0 100644
--- a/src/librustc_trans/back/write.rs
+++ b/src/librustc_trans/back/write.rs
@@ -488,8 +488,12 @@ unsafe fn optimize_and_codegen(cgcx: &CodegenContext,
     // pass manager passed to the closure should be ensured to not
     // escape the closure itself, and the manager should only be
     // used once.
-    unsafe fn with_codegen(tm: TargetMachineRef, llmod: ModuleRef,
-                    no_builtins: bool, f: |PassManagerRef|) {
+    unsafe fn with_codegen<F>(tm: TargetMachineRef,
+                              llmod: ModuleRef,
+                              no_builtins: bool,
+                              f: F) where
+        F: FnOnce(PassManagerRef),
+    {
         let cpm = llvm::LLVMCreatePassManager();
         llvm::LLVMRustAddAnalysisPasses(tm, cpm, llmod);
         llvm::LLVMRustAddLibraryInfo(cpm, llmod, no_builtins);
diff --git a/src/librustc_trans/save/mod.rs b/src/librustc_trans/save/mod.rs
index 2a698a898fe87..329241b24e652 100644
--- a/src/librustc_trans/save/mod.rs
+++ b/src/librustc_trans/save/mod.rs
@@ -79,7 +79,9 @@ struct DxrVisitor<'l, 'tcx: 'l> {
 }
 
 impl <'l, 'tcx> DxrVisitor<'l, 'tcx> {
-    fn nest(&mut self, scope_id: NodeId, f: |&mut DxrVisitor<'l, 'tcx>|) {
+    fn nest<F>(&mut self, scope_id: NodeId, f: F) where
+        F: FnOnce(&mut DxrVisitor<'l, 'tcx>),
+    {
         let parent_scope = self.cur_scope;
         self.cur_scope = scope_id;
         f(self);
diff --git a/src/librustc_trans/trans/_match.rs b/src/librustc_trans/trans/_match.rs
index 7a7a708fcc509..b051292571980 100644
--- a/src/librustc_trans/trans/_match.rs
+++ b/src/librustc_trans/trans/_match.rs
@@ -1578,14 +1578,15 @@ pub fn store_for_loop_binding<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
     bind_irrefutable_pat(bcx, pat, llvalue, body_scope)
 }
 
-fn mk_binding_alloca<'blk, 'tcx, A>(bcx: Block<'blk, 'tcx>,
-                                    p_id: ast::NodeId,
-                                    ident: &ast::Ident,
-                                    cleanup_scope: cleanup::ScopeId,
-                                    arg: A,
-                                    populate: |A, Block<'blk, 'tcx>, ValueRef, Ty<'tcx>|
-                                              -> Block<'blk, 'tcx>)
-                                    -> Block<'blk, 'tcx> {
+fn mk_binding_alloca<'blk, 'tcx, A, F>(bcx: Block<'blk, 'tcx>,
+                                       p_id: ast::NodeId,
+                                       ident: &ast::Ident,
+                                       cleanup_scope: cleanup::ScopeId,
+                                       arg: A,
+                                       populate: F)
+                                       -> Block<'blk, 'tcx> where
+    F: FnOnce(A, Block<'blk, 'tcx>, ValueRef, Ty<'tcx>) -> Block<'blk, 'tcx>,
+{
     let var_ty = node_id_type(bcx, p_id);
 
     // Allocate memory on stack for the binding.
diff --git a/src/librustc_trans/trans/adt.rs b/src/librustc_trans/trans/adt.rs
index e273a56ce025b..991333d8f07dd 100644
--- a/src/librustc_trans/trans/adt.rs
+++ b/src/librustc_trans/trans/adt.rs
@@ -858,10 +858,13 @@ pub fn struct_field_ptr<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, st: &Struct<'tcx>, v
     GEPi(bcx, val, &[0, ix])
 }
 
-pub fn fold_variants<'blk, 'tcx>(
-        bcx: Block<'blk, 'tcx>, r: &Repr<'tcx>, value: ValueRef,
-        f: |Block<'blk, 'tcx>, &Struct<'tcx>, ValueRef| -> Block<'blk, 'tcx>)
-        -> Block<'blk, 'tcx> {
+pub fn fold_variants<'blk, 'tcx, F>(bcx: Block<'blk, 'tcx>,
+                                    r: &Repr<'tcx>,
+                                    value: ValueRef,
+                                    mut f: F)
+                                    -> Block<'blk, 'tcx> where
+    F: FnMut(Block<'blk, 'tcx>, &Struct<'tcx>, ValueRef) -> Block<'blk, 'tcx>,
+{
     let fcx = bcx.fcx;
     match *r {
         Univariant(ref st, _) => {
diff --git a/src/librustc_trans/trans/base.rs b/src/librustc_trans/trans/base.rs
index cef12616cf267..5170746404e01 100644
--- a/src/librustc_trans/trans/base.rs
+++ b/src/librustc_trans/trans/base.rs
@@ -107,9 +107,11 @@ thread_local!(static TASK_LOCAL_INSN_KEY: RefCell<Option<Vec<&'static str>>> = {
     RefCell::new(None)
 })
 
-pub fn with_insn_ctxt(blk: |&[&'static str]|) {
-    TASK_LOCAL_INSN_KEY.with(|slot| {
-        slot.borrow().as_ref().map(|s| blk(s.as_slice()));
+pub fn with_insn_ctxt<F>(blk: F) where
+    F: FnOnce(&[&'static str]),
+{
+    TASK_LOCAL_INSN_KEY.with(move |slot| {
+        slot.borrow().as_ref().map(move |s| blk(s.as_slice()));
     })
 }
 
@@ -841,12 +843,15 @@ pub fn cast_shift_const_rhs(op: ast::BinOp,
                    |a, b| unsafe { llvm::LLVMConstZExt(a, b.to_ref()) })
 }
 
-pub fn cast_shift_rhs(op: ast::BinOp,
-                      lhs: ValueRef,
-                      rhs: ValueRef,
-                      trunc: |ValueRef, Type| -> ValueRef,
-                      zext: |ValueRef, Type| -> ValueRef)
-                      -> ValueRef {
+pub fn cast_shift_rhs<F, G>(op: ast::BinOp,
+                            lhs: ValueRef,
+                            rhs: ValueRef,
+                            trunc: F,
+                            zext: G)
+                            -> ValueRef where
+    F: FnOnce(ValueRef, Type) -> ValueRef,
+    G: FnOnce(ValueRef, Type) -> ValueRef,
+{
     // Shifts may have any size int on the rhs
     unsafe {
         if ast_util::is_shift_binop(op) {
@@ -1101,10 +1106,12 @@ pub fn raw_block<'blk, 'tcx>(fcx: &'blk FunctionContext<'blk, 'tcx>,
     common::BlockS::new(llbb, is_lpad, None, fcx)
 }
 
-pub fn with_cond<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
-                             val: ValueRef,
-                             f: |Block<'blk, 'tcx>| -> Block<'blk, 'tcx>)
-                             -> Block<'blk, 'tcx> {
+pub fn with_cond<'blk, 'tcx, F>(bcx: Block<'blk, 'tcx>,
+                                val: ValueRef,
+                                f: F)
+                                -> Block<'blk, 'tcx> where
+    F: FnOnce(Block<'blk, 'tcx>) -> Block<'blk, 'tcx>,
+{
     let _icx = push_ctxt("with_cond");
     let fcx = bcx.fcx;
     let next_cx = fcx.new_temp_block("next");
diff --git a/src/librustc_trans/trans/cabi_x86_64.rs b/src/librustc_trans/trans/cabi_x86_64.rs
index 00c91ddebb38e..4a6bc58051c57 100644
--- a/src/librustc_trans/trans/cabi_x86_64.rs
+++ b/src/librustc_trans/trans/cabi_x86_64.rs
@@ -342,11 +342,13 @@ pub fn compute_abi_info(ccx: &CrateContext,
                         atys: &[Type],
                         rty: Type,
                         ret_def: bool) -> FnType {
-    fn x86_64_ty(ccx: &CrateContext,
-                 ty: Type,
-                 is_mem_cls: |cls: &[RegClass]| -> bool,
-                 ind_attr: Attribute)
-                 -> ArgType {
+    fn x86_64_ty<F>(ccx: &CrateContext,
+                    ty: Type,
+                    is_mem_cls: F,
+                    ind_attr: Attribute)
+                    -> ArgType where
+        F: FnOnce(&[RegClass]) -> bool,
+    {
         if !ty.is_reg_ty() {
             let cls = classify_ty(ty);
             if is_mem_cls(cls.as_slice()) {
diff --git a/src/librustc_trans/trans/callee.rs b/src/librustc_trans/trans/callee.rs
index ff7ab91c39a58..b8b2395dde172 100644
--- a/src/librustc_trans/trans/callee.rs
+++ b/src/librustc_trans/trans/callee.rs
@@ -781,15 +781,15 @@ pub fn trans_lang_call<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
 ///
 /// For non-lang items, `dest` is always Some, and hence the result is written into memory
 /// somewhere. Nonetheless we return the actual return value of the function.
-pub fn trans_call_inner<'a, 'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
-                                        call_info: Option<NodeInfo>,
-                                        callee_ty: Ty<'tcx>,
-                                        get_callee: |bcx: Block<'blk, 'tcx>,
-                                                     arg_cleanup_scope: cleanup::ScopeId|
-                                                     -> Callee<'blk, 'tcx>,
-                                        args: CallArgs<'a, 'tcx>,
-                                        dest: Option<expr::Dest>)
-                                        -> Result<'blk, 'tcx> {
+pub fn trans_call_inner<'a, 'blk, 'tcx, F>(bcx: Block<'blk, 'tcx>,
+                                           call_info: Option<NodeInfo>,
+                                           callee_ty: Ty<'tcx>,
+                                           get_callee: F,
+                                           args: CallArgs<'a, 'tcx>,
+                                           dest: Option<expr::Dest>)
+                                           -> Result<'blk, 'tcx> where
+    F: FnOnce(Block<'blk, 'tcx>, cleanup::ScopeId) -> Callee<'blk, 'tcx>,
+{
     // Introduce a temporary cleanup scope that will contain cleanups
     // for the arguments while they are being evaluated. The purpose
     // this cleanup is to ensure that, should a panic occur while
diff --git a/src/librustc_trans/trans/cleanup.rs b/src/librustc_trans/trans/cleanup.rs
index ba3e70fe036fc..2fd6551409e90 100644
--- a/src/librustc_trans/trans/cleanup.rs
+++ b/src/librustc_trans/trans/cleanup.rs
@@ -527,7 +527,7 @@ impl<'blk, 'tcx> CleanupHelperMethods<'blk, 'tcx> for FunctionContext<'blk, 'tcx
         self.scopes.borrow_mut().pop().unwrap()
     }
 
-    fn top_scope<R>(&self, f: |&CleanupScope<'blk, 'tcx>| -> R) -> R {
+    fn top_scope<R, F>(&self, f: F) -> R where F: FnOnce(&CleanupScope<'blk, 'tcx>) -> R {
         f(self.scopes.borrow().last().unwrap())
     }
 
@@ -1145,5 +1145,5 @@ trait CleanupHelperMethods<'blk, 'tcx> {
     fn scopes_len(&self) -> uint;
     fn push_scope(&self, scope: CleanupScope<'blk, 'tcx>);
     fn pop_scope(&self) -> CleanupScope<'blk, 'tcx>;
-    fn top_scope<R>(&self, f: |&CleanupScope<'blk, 'tcx>| -> R) -> R;
+    fn top_scope<R, F>(&self, f: F) -> R where F: FnOnce(&CleanupScope<'blk, 'tcx>) -> R;
 }
diff --git a/src/librustc_trans/trans/datum.rs b/src/librustc_trans/trans/datum.rs
index edcc8edaf7f92..531b22c8fb5f2 100644
--- a/src/librustc_trans/trans/datum.rs
+++ b/src/librustc_trans/trans/datum.rs
@@ -113,15 +113,16 @@ pub fn immediate_rvalue_bcx<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
 /// it. The memory will be dropped upon exit from `scope`. The callback `populate` should
 /// initialize the memory. If `zero` is true, the space will be zeroed when it is allocated; this
 /// is not necessary unless `bcx` does not dominate the end of `scope`.
-pub fn lvalue_scratch_datum<'blk, 'tcx, A>(bcx: Block<'blk, 'tcx>,
-                                           ty: Ty<'tcx>,
-                                           name: &str,
-                                           zero: bool,
-                                           scope: cleanup::ScopeId,
-                                           arg: A,
-                                           populate: |A, Block<'blk, 'tcx>, ValueRef|
-                                                      -> Block<'blk, 'tcx>)
-                                          -> DatumBlock<'blk, 'tcx, Lvalue> {
+pub fn lvalue_scratch_datum<'blk, 'tcx, A, F>(bcx: Block<'blk, 'tcx>,
+                                              ty: Ty<'tcx>,
+                                              name: &str,
+                                              zero: bool,
+                                              scope: cleanup::ScopeId,
+                                              arg: A,
+                                              populate: F)
+                                              -> DatumBlock<'blk, 'tcx, Lvalue> where
+    F: FnOnce(A, Block<'blk, 'tcx>, ValueRef) -> Block<'blk, 'tcx>,
+{
     let scratch = if zero {
         alloca_zeroed(bcx, ty, name)
     } else {
@@ -339,10 +340,10 @@ impl<'tcx> Datum<'tcx, Rvalue> {
 /// here since we can `match self.kind` rather than having to implement
 /// generic methods in `KindOps`.)
 impl<'tcx> Datum<'tcx, Expr> {
-    fn match_kind<R>(self,
-                     if_lvalue: |Datum<'tcx, Lvalue>| -> R,
-                     if_rvalue: |Datum<'tcx, Rvalue>| -> R)
-                     -> R {
+    fn match_kind<R, F, G>(self, if_lvalue: F, if_rvalue: G) -> R where
+        F: FnOnce(Datum<'tcx, Lvalue>) -> R,
+        G: FnOnce(Datum<'tcx, Rvalue>) -> R,
+    {
         let Datum { val, ty, kind } = self;
         match kind {
             LvalueExpr => if_lvalue(Datum::new(val, ty, Lvalue)),
@@ -455,9 +456,11 @@ impl<'tcx> Datum<'tcx, Lvalue> {
     // datum may also be unsized _without the size information_. It is the
     // callers responsibility to package the result in some way to make a valid
     // datum in that case (e.g., by making a fat pointer or opened pair).
-    pub fn get_element<'blk>(&self, bcx: Block<'blk, 'tcx>, ty: Ty<'tcx>,
-                             gep: |ValueRef| -> ValueRef)
-                             -> Datum<'tcx, Lvalue> {
+    pub fn get_element<'blk, F>(&self, bcx: Block<'blk, 'tcx>, ty: Ty<'tcx>,
+                                gep: F)
+                                -> Datum<'tcx, Lvalue> where
+        F: FnOnce(ValueRef) -> ValueRef,
+    {
         let val = match self.ty.sty {
             _ if ty::type_is_sized(bcx.tcx(), self.ty) => gep(self.val),
             ty::ty_open(_) => {
diff --git a/src/librustc_trans/trans/debuginfo.rs b/src/librustc_trans/trans/debuginfo.rs
index f6c4ba64576f7..de169fc9d62a6 100644
--- a/src/librustc_trans/trans/debuginfo.rs
+++ b/src/librustc_trans/trans/debuginfo.rs
@@ -3212,13 +3212,13 @@ fn populate_scope_map(cx: &CrateContext,
     });
 
     // local helper functions for walking the AST.
-    fn with_new_scope(cx: &CrateContext,
-                      scope_span: Span,
-                      scope_stack: &mut Vec<ScopeStackEntry> ,
-                      scope_map: &mut NodeMap<DIScope>,
-                      inner_walk: |&CrateContext,
-                                   &mut Vec<ScopeStackEntry> ,
-                                   &mut NodeMap<DIScope>|) {
+    fn with_new_scope<F>(cx: &CrateContext,
+                         scope_span: Span,
+                         scope_stack: &mut Vec<ScopeStackEntry> ,
+                         scope_map: &mut NodeMap<DIScope>,
+                         inner_walk: F) where
+        F: FnOnce(&CrateContext, &mut Vec<ScopeStackEntry>, &mut NodeMap<DIScope>),
+    {
         // Create a new lexical scope and push it onto the stack
         let loc = cx.sess().codemap().lookup_char_pos(scope_span.lo);
         let file_metadata = file_metadata(cx, loc.file.name.as_slice());
diff --git a/src/librustc_trans/trans/expr.rs b/src/librustc_trans/trans/expr.rs
index e3e6fff723410..e1769001942d5 100644
--- a/src/librustc_trans/trans/expr.rs
+++ b/src/librustc_trans/trans/expr.rs
@@ -295,6 +295,7 @@ 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,
@@ -341,27 +342,30 @@ fn apply_adjustments<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
         debug!("dest_ty={}", unsized_ty.repr(bcx.tcx()));
         // Closures for extracting and manipulating the data and payload parts of
         // the fat pointer.
-        let base = match k {
-            &ty::UnsizeStruct(..) =>
-                |bcx, val| PointerCast(bcx,
-                                       val,
-                                       type_of::type_of(bcx.ccx(), unsized_ty).ptr_to()),
-            &ty::UnsizeLength(..) =>
-                |bcx, val| GEPi(bcx, val, &[0u, 0u]),
-            &ty::UnsizeVtable(..) =>
-                |_bcx, val| PointerCast(bcx, val, Type::i8p(bcx.ccx()))
-        };
-        let info = |bcx, _val| unsized_info(bcx,
-                                            k,
-                                            expr.id,
-                                            datum_ty,
-                                            |t| ty::mk_rptr(tcx,
-                                                            ty::ReStatic,
-                                                            ty::mt{
-                                                                ty: t,
-                                                                mutbl: ast::MutImmutable
-                                                            }));
-        into_fat_ptr(bcx, expr, datum, dest_ty, base, info)
+        let info = |: bcx, _val| unsized_info(bcx,
+                                              k,
+                                              expr.id,
+                                              datum_ty,
+                                              |t| ty::mk_rptr(tcx,
+                                                              ty::ReStatic,
+                                                              ty::mt{
+                                                                  ty: t,
+                                                                  mutbl: ast::MutImmutable
+                                                              }));
+        match *k {
+            ty::UnsizeStruct(..) =>
+                into_fat_ptr(bcx, expr, datum, dest_ty, |bcx, val| {
+                    PointerCast(bcx, val, type_of::type_of(bcx.ccx(), unsized_ty).ptr_to())
+                }, info),
+            ty::UnsizeLength(..) =>
+                into_fat_ptr(bcx, expr, datum, dest_ty, |bcx, val| {
+                    GEPi(bcx, val, &[0u, 0u])
+                }, info),
+            ty::UnsizeVtable(..) =>
+                into_fat_ptr(bcx, expr, datum, dest_ty, |_bcx, val| {
+                    PointerCast(bcx, val, Type::i8p(bcx.ccx()))
+                }, info),
+        }
     }
 
     fn ref_fat_ptr<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
@@ -370,18 +374,21 @@ fn apply_adjustments<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
                                -> DatumBlock<'blk, 'tcx, Expr> {
         let tcx = bcx.tcx();
         let dest_ty = ty::close_type(tcx, datum.ty);
-        let base = |bcx, val| Load(bcx, get_dataptr(bcx, val));
-        let len = |bcx, val| Load(bcx, get_len(bcx, val));
+        let base = |: bcx, val| Load(bcx, get_dataptr(bcx, val));
+        let len = |: bcx, val| Load(bcx, get_len(bcx, val));
         into_fat_ptr(bcx, expr, datum, dest_ty, base, len)
     }
 
-    fn into_fat_ptr<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
-                                expr: &ast::Expr,
-                                datum: Datum<'tcx, Expr>,
-                                dest_ty: Ty<'tcx>,
-                                base: |Block<'blk, 'tcx>, ValueRef| -> ValueRef,
-                                info: |Block<'blk, 'tcx>, ValueRef| -> ValueRef)
-                                -> DatumBlock<'blk, 'tcx, Expr> {
+    fn into_fat_ptr<'blk, 'tcx, F, G>(bcx: Block<'blk, 'tcx>,
+                                      expr: &ast::Expr,
+                                      datum: Datum<'tcx, Expr>,
+                                      dest_ty: Ty<'tcx>,
+                                      base: F,
+                                      info: G)
+                                      -> DatumBlock<'blk, 'tcx, Expr> where
+        F: FnOnce(Block<'blk, 'tcx>, ValueRef) -> ValueRef,
+        G: FnOnce(Block<'blk, 'tcx>, ValueRef) -> ValueRef,
+    {
         let mut bcx = bcx;
 
         // Arrange cleanup
@@ -659,17 +666,19 @@ fn trans_datum_unadjusted<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
     }
 }
 
-fn trans_field<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
-                           base: &ast::Expr,
-                           get_idx: |&'blk ty::ctxt<'tcx>, &[ty::field<'tcx>]| -> uint)
-                           -> DatumBlock<'blk, 'tcx, Expr> {
+fn trans_field<'blk, 'tcx, F>(bcx: Block<'blk, 'tcx>,
+                              base: &ast::Expr,
+                              get_idx: F)
+                              -> DatumBlock<'blk, 'tcx, Expr> where
+    F: FnOnce(&'blk ty::ctxt<'tcx>, &[ty::field<'tcx>]) -> uint,
+{
     let mut bcx = bcx;
     let _icx = push_ctxt("trans_rec_field");
 
     let base_datum = unpack_datum!(bcx, trans_to_lvalue(bcx, base, "field"));
     let bare_ty = ty::unopen_type(base_datum.ty);
     let repr = adt::represent_type(bcx.ccx(), bare_ty);
-    with_field_tys(bcx.tcx(), bare_ty, None, |discr, field_tys| {
+    with_field_tys(bcx.tcx(), bare_ty, None, move |discr, field_tys| {
         let ix = get_idx(bcx.tcx(), field_tys);
         let d = base_datum.get_element(
             bcx,
@@ -1254,11 +1263,13 @@ pub fn trans_local_var<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
 /// Helper for enumerating the field types of structs, enums, or records. The optional node ID here
 /// is the node ID of the path identifying the enum variant in use. If none, this cannot possibly
 /// an enum variant (so, if it is and `node_id_opt` is none, this function panics).
-pub fn with_field_tys<'tcx, R>(tcx: &ty::ctxt<'tcx>,
-                               ty: Ty<'tcx>,
-                               node_id_opt: Option<ast::NodeId>,
-                               op: |ty::Disr, (&[ty::field<'tcx>])| -> R)
-                               -> R {
+pub fn with_field_tys<'tcx, R, F>(tcx: &ty::ctxt<'tcx>,
+                                  ty: Ty<'tcx>,
+                                  node_id_opt: Option<ast::NodeId>,
+                                  op: F)
+                                  -> R where
+    F: FnOnce(ty::Disr, &[ty::field<'tcx>]) -> R,
+{
     match ty.sty {
         ty::ty_struct(did, ref substs) => {
             op(0, struct_fields(tcx, did, substs).as_slice())

From 888f24969fc06d9aa783c71ab0d1f1b88a58f170 Mon Sep 17 00:00:00 2001
From: Jorge Aparicio <japaricious@gmail.com>
Date: Tue, 9 Dec 2014 15:22:19 -0500
Subject: [PATCH 86/92] librustdoc: use unboxed closures

---
 src/librustdoc/html/format.rs | 12 ++++++++----
 src/librustdoc/html/render.rs | 13 +++++++++----
 2 files changed, 17 insertions(+), 8 deletions(-)

diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs
index 68ff2ddbcb0e1..051e8a3568fb6 100644
--- a/src/librustdoc/html/format.rs
+++ b/src/librustdoc/html/format.rs
@@ -218,10 +218,14 @@ fn resolved_path(w: &mut fmt::Formatter, did: ast::DefId, p: &clean::Path,
         })
 }
 
-fn path(w: &mut fmt::Formatter, path: &clean::Path, print_all: bool,
-        root: |&render::Cache, &[String]| -> Option<String>,
-        info: |&render::Cache| -> Option<(Vec<String> , ItemType)>)
-    -> fmt::Result
+fn path<F, G>(w: &mut fmt::Formatter,
+              path: &clean::Path,
+              print_all: bool,
+              root: F,
+              info: G)
+              -> fmt::Result where
+    F: FnOnce(&render::Cache, &[String]) -> Option<String>,
+    G: FnOnce(&render::Cache) -> Option<(Vec<String>, ItemType)>,
 {
     // The generics will get written to both the title and link
     let mut generics = String::new();
diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs
index 38bc7d1a3c18d..63b1f5ca0497d 100644
--- a/src/librustdoc/html/render.rs
+++ b/src/librustdoc/html/render.rs
@@ -646,7 +646,9 @@ fn shortty(item: &clean::Item) -> ItemType {
 /// static HTML tree.
 // FIXME (#9639): The closure should deal with &[u8] instead of &str
 // FIXME (#9639): This is too conservative, rejecting non-UTF-8 paths
-fn clean_srcpath(src_root: &Path, src: &[u8], f: |&str|) {
+fn clean_srcpath<F>(src_root: &Path, src: &[u8], mut f: F) where
+    F: FnMut(&str),
+{
     let p = Path::new(src);
 
     // make it relative, if possible
@@ -1051,7 +1053,9 @@ impl<'a> Cache {
 impl Context {
     /// Recurse in the directory structure and change the "root path" to make
     /// sure it always points to the top (relatively)
-    fn recurse<T>(&mut self, s: String, f: |&mut Context| -> T) -> T {
+    fn recurse<T, F>(&mut self, s: String, f: F) -> T where
+        F: FnOnce(&mut Context) -> T,
+    {
         if s.len() == 0 {
             panic!("Unexpected empty destination: {}", self.current);
         }
@@ -1131,8 +1135,9 @@ impl Context {
     /// all sub-items which need to be rendered.
     ///
     /// The rendering driver uses this closure to queue up more work.
-    fn item(&mut self, item: clean::Item,
-            f: |&mut Context, clean::Item|) -> io::IoResult<()> {
+    fn item<F>(&mut self, item: clean::Item, mut f: F) -> io::IoResult<()> where
+        F: FnMut(&mut Context, clean::Item),
+    {
         fn render(w: io::File, cx: &Context, it: &clean::Item,
                   pushname: bool) -> io::IoResult<()> {
             info!("Rendering an item to {}", w.path().display());

From 521a6e62b14b2e44d58972c9e28772fc9685b6d5 Mon Sep 17 00:00:00 2001
From: Jorge Aparicio <japaricious@gmail.com>
Date: Tue, 9 Dec 2014 16:04:19 -0500
Subject: [PATCH 87/92] librustc_typeck: use unboxed closures

---
 src/librustc_typeck/check/demand.rs         | 14 ++--
 src/librustc_typeck/check/method/confirm.rs | 15 ++--
 src/librustc_typeck/check/method/probe.rs   | 10 +--
 src/librustc_typeck/check/mod.rs            | 76 +++++++++++----------
 src/librustc_typeck/lib.rs                  | 18 ++---
 5 files changed, 72 insertions(+), 61 deletions(-)

diff --git a/src/librustc_typeck/check/demand.rs b/src/librustc_typeck/check/demand.rs
index 9eb0e17b8e5be..980097eaead99 100644
--- a/src/librustc_typeck/check/demand.rs
+++ b/src/librustc_typeck/check/demand.rs
@@ -28,12 +28,14 @@ pub fn suptype<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>, sp: Span,
         |sp, e, a, s| { fcx.report_mismatched_types(sp, e, a, s) })
 }
 
-pub fn suptype_with_fn<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
-                                 sp: Span,
-                                 b_is_expected: bool,
-                                 ty_a: Ty<'tcx>,
-                                 ty_b: Ty<'tcx>,
-                                 handle_err: |Span, Ty<'tcx>, Ty<'tcx>, &ty::type_err<'tcx>|) {
+pub fn suptype_with_fn<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>,
+                                    sp: Span,
+                                    b_is_expected: bool,
+                                    ty_a: Ty<'tcx>,
+                                    ty_b: Ty<'tcx>,
+                                    handle_err: F) where
+    F: FnOnce(Span, Ty<'tcx>, Ty<'tcx>, &ty::type_err<'tcx>),
+{
     // n.b.: order of actual, expected is reversed
     match infer::mk_subty(fcx.infcx(), b_is_expected, infer::Misc(sp),
                           ty_b, ty_a) {
diff --git a/src/librustc_typeck/check/method/confirm.rs b/src/librustc_typeck/check/method/confirm.rs
index bf1f2c0ce809a..3c7cecc96a320 100644
--- a/src/librustc_typeck/check/method/confirm.rs
+++ b/src/librustc_typeck/check/method/confirm.rs
@@ -286,11 +286,8 @@ impl<'a,'tcx> ConfirmContext<'a,'tcx> {
         }
     }
 
-    fn extract_trait_ref<R>(&mut self,
-                            self_ty: Ty<'tcx>,
-                            closure: |&mut ConfirmContext<'a,'tcx>,
-                                      Ty<'tcx>, &ty::TyTrait<'tcx>| -> R)
-                            -> R
+    fn extract_trait_ref<R, F>(&mut self, self_ty: Ty<'tcx>, mut closure: F) -> R where
+        F: FnMut(&mut ConfirmContext<'a, 'tcx>, Ty<'tcx>, &ty::TyTrait<'tcx>) -> R,
     {
         // If we specified that this is an object method, then the
         // self-type ought to be something that can be dereferenced to
@@ -665,9 +662,11 @@ impl<'a,'tcx> ConfirmContext<'a,'tcx> {
     }
 }
 
-fn wrap_autoref<'tcx>(mut deref: ty::AutoDerefRef<'tcx>,
-                      base_fn: |Option<Box<ty::AutoRef<'tcx>>>| -> ty::AutoRef<'tcx>)
-                      -> ty::AutoDerefRef<'tcx> {
+fn wrap_autoref<'tcx, F>(mut deref: ty::AutoDerefRef<'tcx>,
+                         base_fn: F)
+                         -> ty::AutoDerefRef<'tcx> where
+    F: FnOnce(Option<Box<ty::AutoRef<'tcx>>>) -> ty::AutoRef<'tcx>,
+{
     let autoref = mem::replace(&mut deref.autoref, None);
     let autoref = autoref.map(|r| box r);
     deref.autoref = Some(base_fn(autoref));
diff --git a/src/librustc_typeck/check/method/probe.rs b/src/librustc_typeck/check/method/probe.rs
index f0f527f667354..adcfc491dcc4f 100644
--- a/src/librustc_typeck/check/method/probe.rs
+++ b/src/librustc_typeck/check/method/probe.rs
@@ -710,10 +710,12 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> {
                                                mutbl: m }))
     }
 
-    fn search_mutabilities(&mut self,
-                           mk_adjustment: |ast::Mutability| -> PickAdjustment,
-                           mk_autoref_ty: |ast::Mutability, ty::Region| -> Ty<'tcx>)
-                           -> Option<PickResult<'tcx>>
+    fn search_mutabilities<F, G>(&mut self,
+                                 mut mk_adjustment: F,
+                                 mut mk_autoref_ty: G)
+                                 -> Option<PickResult<'tcx>> where
+        F: FnMut(ast::Mutability) -> PickAdjustment,
+        G: FnMut(ast::Mutability, ty::Region) -> Ty<'tcx>,
     {
         // In general, during probing we erase regions. See
         // `impl_self_ty()` for an explanation.
diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs
index a7163b75d5249..18a773fb949fc 100644
--- a/src/librustc_typeck/check/mod.rs
+++ b/src/librustc_typeck/check/mod.rs
@@ -1885,9 +1885,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         self.inh.item_substs.borrow()
     }
 
-    pub fn opt_node_ty_substs(&self,
-                              id: ast::NodeId,
-                              f: |&ty::ItemSubsts<'tcx>|) {
+    pub fn opt_node_ty_substs<F>(&self,
+                                 id: ast::NodeId,
+                                 f: F) where
+        F: FnOnce(&ty::ItemSubsts<'tcx>),
+    {
         match self.inh.item_substs.borrow().get(&id) {
             Some(s) => { f(s) }
             None => { }
@@ -2027,12 +2029,14 @@ impl Copy for LvaluePreference {}
 ///
 /// Note: this method does not modify the adjustments table. The caller is responsible for
 /// inserting an AutoAdjustment record into the `fcx` using one of the suitable methods.
-pub fn autoderef<'a, 'tcx, T>(fcx: &FnCtxt<'a, 'tcx>, sp: Span,
-                              base_ty: Ty<'tcx>,
-                              expr_id: Option<ast::NodeId>,
-                              mut lvalue_pref: LvaluePreference,
-                              should_stop: |Ty<'tcx>, uint| -> Option<T>)
-                              -> (Ty<'tcx>, uint, Option<T>) {
+pub fn autoderef<'a, 'tcx, T, F>(fcx: &FnCtxt<'a, 'tcx>, sp: Span,
+                                 base_ty: Ty<'tcx>,
+                                 expr_id: Option<ast::NodeId>,
+                                 mut lvalue_pref: LvaluePreference,
+                                 mut should_stop: F)
+                                 -> (Ty<'tcx>, uint, Option<T>) where
+    F: FnMut(Ty<'tcx>, uint) -> Option<T>,
+{
     let mut t = base_ty;
     for autoderefs in range(0, fcx.tcx().sess.recursion_limit.get()) {
         let resolved_t = structurally_resolved_type(fcx, sp, t);
@@ -2194,12 +2198,13 @@ fn make_overloaded_lvalue_return_type<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
     }
 }
 
-fn autoderef_for_index<'a, 'tcx, T>(fcx: &FnCtxt<'a, 'tcx>,
-                                    base_expr: &ast::Expr,
-                                    base_ty: Ty<'tcx>,
-                                    lvalue_pref: LvaluePreference,
-                                    step: |Ty<'tcx>, ty::AutoDerefRef<'tcx>| -> Option<T>)
-                                    -> Option<T>
+fn autoderef_for_index<'a, 'tcx, T, F>(fcx: &FnCtxt<'a, 'tcx>,
+                                       base_expr: &ast::Expr,
+                                       base_ty: Ty<'tcx>,
+                                       lvalue_pref: LvaluePreference,
+                                       mut step: F)
+                                       -> Option<T> where
+    F: FnMut(Ty<'tcx>, ty::AutoDerefRef<'tcx>) -> Option<T>,
 {
     // FIXME(#18741) -- this is almost but not quite the same as the
     // autoderef that normal method probing does. They could likely be
@@ -2938,11 +2943,12 @@ enum TupleArgumentsFlag {
 /// Note that inspecting a type's structure *directly* may expose the fact
 /// that there are actually multiple representations for `ty_err`, so avoid
 /// that when err needs to be handled differently.
-fn check_expr_with_unifier<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
-                                     expr: &ast::Expr,
-                                     expected: Expectation<'tcx>,
-                                     lvalue_pref: LvaluePreference,
-                                     unifier: ||)
+fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>,
+                                        expr: &ast::Expr,
+                                        expected: Expectation<'tcx>,
+                                        lvalue_pref: LvaluePreference,
+                                        unifier: F) where
+    F: FnOnce(),
 {
     debug!(">> typechecking: expr={} expected={}",
            expr.repr(fcx.tcx()), expected.repr(fcx.tcx()));
@@ -3117,14 +3123,16 @@ fn check_expr_with_unifier<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
         fcx.write_ty(id, if_ty);
     }
 
-    fn lookup_op_method<'a, 'tcx>(fcx: &'a FnCtxt<'a, 'tcx>,
-                                  op_ex: &ast::Expr,
-                                  lhs_ty: Ty<'tcx>,
-                                  opname: ast::Name,
-                                  trait_did: Option<ast::DefId>,
-                                  lhs: &'a ast::Expr,
-                                  rhs: Option<&P<ast::Expr>>,
-                                  unbound_method: ||) -> Ty<'tcx> {
+    fn lookup_op_method<'a, 'tcx, F>(fcx: &'a FnCtxt<'a, 'tcx>,
+                                     op_ex: &ast::Expr,
+                                     lhs_ty: Ty<'tcx>,
+                                     opname: ast::Name,
+                                     trait_did: Option<ast::DefId>,
+                                     lhs: &'a ast::Expr,
+                                     rhs: Option<&P<ast::Expr>>,
+                                     unbound_method: F) -> Ty<'tcx> where
+        F: FnOnce(),
+    {
         let method = match trait_did {
             Some(trait_did) => {
                 // We do eager coercions to make using operators
@@ -4376,19 +4384,17 @@ impl<'tcx> Expectation<'tcx> {
         }
     }
 
-    fn map<'a>(self, fcx: &FnCtxt<'a, 'tcx>,
-               unpack: |&ty::sty<'tcx>| -> Expectation<'tcx>)
-               -> Expectation<'tcx> {
+    fn map<'a, F>(self, fcx: &FnCtxt<'a, 'tcx>, unpack: F) -> Expectation<'tcx> where
+        F: FnOnce(&ty::sty<'tcx>) -> Expectation<'tcx>
+    {
         match self.resolve(fcx) {
             NoExpectation => NoExpectation,
             ExpectCastableToType(t) | ExpectHasType(t) => unpack(&t.sty),
         }
     }
 
-    fn map_to_option<'a, O>(self,
-                            fcx: &FnCtxt<'a, 'tcx>,
-                            unpack: |&ty::sty<'tcx>| -> Option<O>)
-                            -> Option<O>
+    fn map_to_option<'a, O, F>(self, fcx: &FnCtxt<'a, 'tcx>, unpack: F) -> Option<O> where
+        F: FnOnce(&ty::sty<'tcx>) -> Option<O>,
     {
         match self.resolve(fcx) {
             NoExpectation => None,
diff --git a/src/librustc_typeck/lib.rs b/src/librustc_typeck/lib.rs
index 0cf43821c82d6..32c732c246716 100644
--- a/src/librustc_typeck/lib.rs
+++ b/src/librustc_typeck/lib.rs
@@ -170,14 +170,16 @@ fn no_params<'tcx>(t: Ty<'tcx>) -> ty::Polytype<'tcx> {
     }
 }
 
-fn require_same_types<'a, 'tcx>(tcx: &ty::ctxt<'tcx>,
-                                    maybe_infcx: Option<&infer::InferCtxt<'a, 'tcx>>,
-                                    t1_is_expected: bool,
-                                    span: Span,
-                                    t1: Ty<'tcx>,
-                                    t2: Ty<'tcx>,
-                                    msg: || -> String)
-                                    -> bool {
+fn require_same_types<'a, 'tcx, M>(tcx: &ty::ctxt<'tcx>,
+                                   maybe_infcx: Option<&infer::InferCtxt<'a, 'tcx>>,
+                                   t1_is_expected: bool,
+                                   span: Span,
+                                   t1: Ty<'tcx>,
+                                   t2: Ty<'tcx>,
+                                   msg: M)
+                                   -> bool where
+    M: FnOnce() -> String,
+{
     let result = match maybe_infcx {
         None => {
             let infcx = infer::new_infer_ctxt(tcx);

From 015c0fcee5779c62a6676106ccec00e2c82fefa5 Mon Sep 17 00:00:00 2001
From: Jorge Aparicio <japaricious@gmail.com>
Date: Tue, 9 Dec 2014 16:32:45 -0500
Subject: [PATCH 88/92] librustc_driver: use unboxed closures

---
 src/librustc_driver/lib.rs    |  1 +
 src/librustc_driver/pretty.rs | 16 +++++++++-------
 src/librustc_driver/test.rs   |  8 +++++---
 3 files changed, 15 insertions(+), 10 deletions(-)

diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs
index 85d9646c28211..d655b70405309 100644
--- a/src/librustc_driver/lib.rs
+++ b/src/librustc_driver/lib.rs
@@ -25,6 +25,7 @@
 #![feature(default_type_params, globs, import_shadowing, macro_rules, phase, quote)]
 #![feature(slicing_syntax, unsafe_destructor)]
 #![feature(rustc_diagnostic_macros)]
+#![feature(unboxed_closures)]
 
 extern crate arena;
 extern crate flate;
diff --git a/src/librustc_driver/pretty.rs b/src/librustc_driver/pretty.rs
index c872f831649c8..7ec05b6a0306e 100644
--- a/src/librustc_driver/pretty.rs
+++ b/src/librustc_driver/pretty.rs
@@ -99,13 +99,15 @@ pub fn parse_pretty(sess: &Session, name: &str) -> (PpMode, Option<UserIdentifie
 
 impl PpSourceMode {
     /// Constructs a `PrinterSupport` object and passes it to `f`.
-    fn call_with_pp_support<'tcx, A, B>(&self,
-                                        sess: Session,
-                                        ast_map: Option<ast_map::Map<'tcx>>,
-                                        type_arena: &'tcx TypedArena<ty::TyS<'tcx>>,
-                                        id: String,
-                                        payload: B,
-                                        f: |&PrinterSupport, B| -> A) -> A {
+    fn call_with_pp_support<'tcx, A, B, F>(&self,
+                                           sess: Session,
+                                           ast_map: Option<ast_map::Map<'tcx>>,
+                                           type_arena: &'tcx TypedArena<ty::TyS<'tcx>>,
+                                           id: String,
+                                           payload: B,
+                                           f: F) -> A where
+        F: FnOnce(&PrinterSupport, B) -> A,
+    {
         match *self {
             PpmNormal | PpmExpanded => {
                 let annotation = NoAnn { sess: sess, ast_map: ast_map };
diff --git a/src/librustc_driver/test.rs b/src/librustc_driver/test.rs
index 9404802cb681b..dda3754cf7371 100644
--- a/src/librustc_driver/test.rs
+++ b/src/librustc_driver/test.rs
@@ -93,9 +93,11 @@ fn errors(msgs: &[&str]) -> (Box<Emitter+Send>, uint) {
     (box ExpectErrorEmitter { messages: v } as Box<Emitter+Send>, msgs.len())
 }
 
-fn test_env(source_string: &str,
-            (emitter, expected_err_count): (Box<Emitter+Send>, uint),
-            body: |Env|) {
+fn test_env<F>(source_string: &str,
+               (emitter, expected_err_count): (Box<Emitter+Send>, uint),
+               body: F) where
+    F: FnOnce(Env),
+{
     let mut options =
         config::basic_options();
     options.debugging_opts |= config::VERBOSE;

From 745225d905a691c700c8a62b08a7262ed0d1edc5 Mon Sep 17 00:00:00 2001
From: Jorge Aparicio <japaricious@gmail.com>
Date: Tue, 9 Dec 2014 17:00:29 -0500
Subject: [PATCH 89/92] libtest: use unboxed closures

---
 src/libtest/lib.rs | 18 ++++++++++--------
 1 file changed, 10 insertions(+), 8 deletions(-)

diff --git a/src/libtest/lib.rs b/src/libtest/lib.rs
index ffc26738dd7b2..7436a8af30765 100644
--- a/src/libtest/lib.rs
+++ b/src/libtest/lib.rs
@@ -32,6 +32,7 @@
        html_root_url = "http://doc.rust-lang.org/nightly/")]
 
 #![feature(asm, macro_rules, phase, globs, slicing_syntax)]
+#![feature(unboxed_closures)]
 
 extern crate getopts;
 extern crate regex;
@@ -978,9 +979,11 @@ enum TestEvent {
 
 pub type MonitorMsg = (TestDesc, TestResult, Vec<u8> );
 
-fn run_tests(opts: &TestOpts,
-             tests: Vec<TestDescAndFn> ,
-             callback: |e: TestEvent| -> io::IoResult<()>) -> io::IoResult<()> {
+fn run_tests<F>(opts: &TestOpts,
+                tests: Vec<TestDescAndFn> ,
+                mut callback: F) -> io::IoResult<()> where
+    F: FnMut(TestEvent) -> io::IoResult<()>,
+{
     let filtered_tests = filter_tests(opts, tests);
     let filtered_descs = filtered_tests.iter()
                                        .map(|t| t.desc.clone())
@@ -1339,7 +1342,7 @@ pub fn black_box<T>(dummy: T) {
 
 impl Bencher {
     /// Callback for benchmark functions to run in their body.
-    pub fn iter<T>(&mut self, inner: || -> T) {
+    pub fn iter<T, F>(&mut self, mut inner: F) where F: FnMut() -> T {
         self.dur = Duration::span(|| {
             let k = self.iterations;
             for _ in range(0u64, k) {
@@ -1360,14 +1363,13 @@ impl Bencher {
         }
     }
 
-    pub fn bench_n(&mut self, n: u64, f: |&mut Bencher|) {
+    pub fn bench_n<F>(&mut self, n: u64, f: F) where F: FnOnce(&mut Bencher) {
         self.iterations = n;
         f(self);
     }
 
     // This is a more statistics-driven benchmark algorithm
-    pub fn auto_bench(&mut self, f: |&mut Bencher|) -> stats::Summary<f64> {
-
+    pub fn auto_bench<F>(&mut self, mut f: F) -> stats::Summary<f64> where F: FnMut(&mut Bencher) {
         // Initial bench run to get ballpark figure.
         let mut n = 1_u64;
         self.bench_n(n, |x| f(x));
@@ -1437,7 +1439,7 @@ pub mod bench {
     use std::time::Duration;
     use super::{Bencher, BenchSamples};
 
-    pub fn benchmark(f: |&mut Bencher|) -> BenchSamples {
+    pub fn benchmark<F>(f: F) -> BenchSamples where F: FnMut(&mut Bencher) {
         let mut bs = Bencher {
             iterations: 0,
             dur: Duration::nanoseconds(0),

From 6f28816f87ab8b6903a45cb75a13697a700cf8f2 Mon Sep 17 00:00:00 2001
From: Jorge Aparicio <japaricious@gmail.com>
Date: Sat, 13 Dec 2014 11:08:27 -0500
Subject: [PATCH 90/92] Remove some unnecessary `move` keywords

---
 src/test/bench/core-set.rs | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/src/test/bench/core-set.rs b/src/test/bench/core-set.rs
index 38c31da1a6d32..6ba642cc47b75 100644
--- a/src/test/bench/core-set.rs
+++ b/src/test/bench/core-set.rs
@@ -68,7 +68,7 @@ impl Results {
                      rand_cap: uint,
                      f: || -> T) { {
             let mut set = f();
-            timed(&mut self.sequential_ints, move || {
+            timed(&mut self.sequential_ints, || {
                 for i in range(0u, num_keys) {
                     set.insert(i);
                 }
@@ -81,7 +81,7 @@ impl Results {
 
         {
             let mut set = f();
-            timed(&mut self.random_ints, move || {
+            timed(&mut self.random_ints, || {
                 for _ in range(0, num_keys) {
                     set.insert(rng.gen::<uint>() % rand_cap);
                 }
@@ -94,7 +94,7 @@ impl Results {
                 set.insert(i);
             }
 
-            timed(&mut self.delete_ints, move || {
+            timed(&mut self.delete_ints, || {
                 for i in range(0u, num_keys) {
                     assert!(set.remove(&i));
                 }
@@ -110,7 +110,7 @@ impl Results {
                      f: || -> T) {
         {
             let mut set = f();
-            timed(&mut self.sequential_strings, move || {
+            timed(&mut self.sequential_strings, || {
                 for i in range(0u, num_keys) {
                     set.insert(i.to_string());
                 }
@@ -123,7 +123,7 @@ impl Results {
 
         {
             let mut set = f();
-            timed(&mut self.random_strings, move || {
+            timed(&mut self.random_strings, || {
                 for _ in range(0, num_keys) {
                     let s = rng.gen::<uint>().to_string();
                     set.insert(s);
@@ -136,7 +136,7 @@ impl Results {
             for i in range(0u, num_keys) {
                 set.insert(i.to_string());
             }
-            timed(&mut self.delete_strings, move || {
+            timed(&mut self.delete_strings, || {
                 for i in range(0u, num_keys) {
                     assert!(set.remove(&i.to_string()));
                 }

From db8300ce06ec7076aea338abc732525502eb2c04 Mon Sep 17 00:00:00 2001
From: Jorge Aparicio <japaricious@gmail.com>
Date: Sat, 13 Dec 2014 15:09:33 -0500
Subject: [PATCH 91/92] libstd: add missing imports

---
 src/libstd/dynamic_lib.rs | 1 +
 src/libstd/os.rs          | 1 +
 2 files changed, 2 insertions(+)

diff --git a/src/libstd/dynamic_lib.rs b/src/libstd/dynamic_lib.rs
index ebb2a491b4ace..059ad7537193f 100644
--- a/src/libstd/dynamic_lib.rs
+++ b/src/libstd/dynamic_lib.rs
@@ -290,6 +290,7 @@ pub mod dl {
     use c_str::ToCStr;
     use iter::IteratorExt;
     use libc;
+    use ops::FnOnce;
     use os;
     use ptr;
     use result::Result;
diff --git a/src/libstd/os.rs b/src/libstd/os.rs
index 38411fd6254da..a3ecfb49acee0 100644
--- a/src/libstd/os.rs
+++ b/src/libstd/os.rs
@@ -163,6 +163,7 @@ pub fn getcwd() -> IoResult<Path> {
 pub mod windoze {
     use libc::types::os::arch::extra::DWORD;
     use libc;
+    use ops::FnMut;
     use option::Option;
     use option::Option::None;
     use option;

From b8e0b81dd57621af28d7b2b5551a3217f7bd4cec Mon Sep 17 00:00:00 2001
From: Jorge Aparicio <japaricious@gmail.com>
Date: Sat, 13 Dec 2014 17:40:34 -0500
Subject: [PATCH 92/92] librustc_borrowck: add `#![feature(unboxed_closures)]`

---
 src/librustc_borrowck/lib.rs | 1 +
 1 file changed, 1 insertion(+)

diff --git a/src/librustc_borrowck/lib.rs b/src/librustc_borrowck/lib.rs
index f187c0c15300d..db19a09deba3a 100644
--- a/src/librustc_borrowck/lib.rs
+++ b/src/librustc_borrowck/lib.rs
@@ -19,6 +19,7 @@
 #![feature(default_type_params, globs, if_let, import_shadowing, macro_rules, phase, quote)]
 #![feature(slicing_syntax, tuple_indexing, unsafe_destructor)]
 #![feature(rustc_diagnostic_macros)]
+#![feature(unboxed_closures)]
 #![allow(non_camel_case_types)]
 
 #[phase(plugin, link)] extern crate log;