about summary refs log tree commit diff
path: root/src/libstd
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2014-12-13 22:57:21 +0000
committerbors <bors@rust-lang.org>2014-12-13 22:57:21 +0000
commit444fa1b7cffcd99ca5b8abb51acf979f06a25899 (patch)
tree51a8beea4fd983ce8cb46879a2fdbaf72916c13e /src/libstd
parent567b90ff095076054c98fa2f08d6c552ae60968d (diff)
parentb8e0b81dd57621af28d7b2b5551a3217f7bd4cec (diff)
downloadrust-444fa1b7cffcd99ca5b8abb51acf979f06a25899.tar.gz
rust-444fa1b7cffcd99ca5b8abb51acf979f06a25899.zip
auto merge of #19467 : japaric/rust/uc, r=alexcrichton
This PR moves almost all our current uses of closures, both in public API and internal uses, to the new "unboxed" closures system.

In most cases, downstream code that *only uses* closures will continue to work as it is. The reason is that the `|| {}` syntax can be inferred either as a boxed or an "unboxed" closure according to the context. For example the following code will continue to work:

``` rust
some_option.map(|x| x.transform_with(upvar))
```

And will get silently upgraded to an "unboxed" closure.

In some other cases, it may be necessary to "annotate" which `Fn*` trait the closure implements:

```
// Change this
|x| { /* body */}
// to either of these
|: x| { /* body */}  // closure implements the FnOnce trait
|&mut : x| { /* body */}  // FnMut
|&: x| { /* body */}  // Fn
```

This mainly occurs when the closure is assigned to a variable first, and then passed to a function/method.

``` rust
let closure = |: x| x.transform_with(upvar);
some.option.map(closure)
```

(It's very likely that in the future, an improved inference engine will make this annotation unnecessary)

Other cases that require annotation are closures that implement some trait via a blanket `impl`, for example:

- `std::finally::Finally`
- `regex::Replacer`
- `std::str::CharEq`

``` rust
string.trim_left_chars(|c: char| c.is_whitespace())
//~^ ERROR: the trait `Fn<(char,), bool>` is not implemented for the type `|char| -> bool`
string.trim_left_chars(|&: c: char| c.is_whitespace())  // OK
```

Finally, all implementations of traits that contain boxed closures in the arguments of their methods are now broken. And will need to be updated to use unboxed closures. These are the main affected traits:

- `serialize::Decoder`
- `serialize::DecoderHelpers`
- `serialize::Encoder`
- `serialize::EncoderHelpers`
- `rustrt::ToCStr`

For example, change this:

``` rust
// libserialize/json.rs
impl<'a> Encoder<io::IoError> for Encoder<'a> {
    fn emit_enum(&mut self,
                 _name: &str,
                 f: |&mut Encoder<'a>| -> EncodeResult) -> EncodeResult {
        f(self)
    }
}
```

to:

``` rust
// libserialize/json.rs
impl<'a> Encoder<io::IoError> for Encoder<'a> {
    fn emit_enum<F>(&mut self, _name: &str, f: F) -> EncodeResult where
        F: FnOnce(&mut Encoder<'a>) -> EncodeResult
    {
        f(self)
    }
}
```

[breaking-change]

---

### How the `Fn*` bound has been selected

I've chosen the bounds to make the functions/structs as "generic as possible", i.e. to let them allow the maximum amount of input.

- An `F: FnOnce` bound accepts the three kinds of closures: `|:|`, `|&mut:|` and `|&:|`.
- An `F: FnMut` bound only accepts "non-consuming" closures: `|&mut:|` and `|&:|`.
- An `F: Fn` bound only accept the "immutable environment" closures: `|&:|`.

This means that whenever possible the `FnOnce` bound has been used, if the `FnOnce` bound couldn't be used, then the `FnMut` was used. The `Fn` bound was never used in the whole repository.

The `FnMut` bound was the most used, because it resembles the semantics of the current boxed closures: the closure can modify its environment, and the closure may be called several times.

The `FnOnce` bound allows new semantics: you can move out the upvars when the closure is called. This can be effectively paired with the `move || {}` syntax to transfer ownership from the environment to the closure caller.

In the case of trait methods, is hard to select the "right" bound since we can't control how the trait may be implemented by downstream users. In these cases, I have selected the bound based on how we use these traits in the repository. For this reason the selected bounds may not be ideal, and may require tweaking before stabilization.

r? @aturon
Diffstat (limited to 'src/libstd')
-rw-r--r--src/libstd/ascii.rs5
-rw-r--r--src/libstd/collections/hash/map.rs50
-rw-r--r--src/libstd/collections/hash/set.rs45
-rw-r--r--src/libstd/dynamic_lib.rs10
-rw-r--r--src/libstd/io/extensions.rs9
-rw-r--r--src/libstd/io/mod.rs20
-rw-r--r--src/libstd/io/net/ip.rs48
-rw-r--r--src/libstd/io/net/mod.rs7
-rw-r--r--src/libstd/io/net/udp.rs5
-rw-r--r--src/libstd/io/stdio.rs10
-rw-r--r--src/libstd/lib.rs1
-rw-r--r--src/libstd/num/strconv.rs6
-rw-r--r--src/libstd/num/u16.rs2
-rw-r--r--src/libstd/num/u32.rs2
-rw-r--r--src/libstd/num/u64.rs2
-rw-r--r--src/libstd/num/u8.rs2
-rw-r--r--src/libstd/num/uint.rs2
-rw-r--r--src/libstd/num/uint_macros.rs4
-rw-r--r--src/libstd/os.rs12
-rw-r--r--src/libstd/path/posix.rs6
-rw-r--r--src/libstd/path/windows.rs13
-rw-r--r--src/libstd/sync/once.rs3
-rw-r--r--src/libstd/sys/common/helper_thread.rs7
-rw-r--r--src/libstd/sys/common/mod.rs4
-rw-r--r--src/libstd/sys/common/net.rs37
-rw-r--r--src/libstd/sys/unix/mod.rs5
-rw-r--r--src/libstd/sys/unix/pipe.rs8
-rw-r--r--src/libstd/sys/windows/mod.rs2
-rw-r--r--src/libstd/sys/windows/process.rs9
-rw-r--r--src/libstd/task.rs4
-rw-r--r--src/libstd/thread_local/mod.rs4
-rw-r--r--src/libstd/thread_local/scoped.rs8
-rw-r--r--src/libstd/time/duration.rs4
33 files changed, 227 insertions, 129 deletions
diff --git a/src/libstd/ascii.rs b/src/libstd/ascii.rs
index b5c8e271492..ad2167214a7 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 a8dce232d26..2a8d97eed05 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);
@@ -852,7 +857,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 +881,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 +955,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 +1327,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 +1450,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 b3ccfdbb47c..745a8298ee8 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};
@@ -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.
@@ -304,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.
@@ -354,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.
@@ -611,18 +618,20 @@ 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
 /// 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 {
diff --git a/src/libstd/dynamic_lib.rs b/src/libstd/dynamic_lib.rs
index 96b075ab569..059ad753719 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 {
@@ -287,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;
@@ -312,7 +316,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 1bdf99f6d6d..69712e39d91 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 dc212e7cab3..bad86258bb8 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 f59dd37c0da..62965c48a26 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 09e5639bea9..2056933e6df 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 a2ad365dd2a..b23921ba359 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 48c333f0733..8438c9fb441 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/lib.rs b/src/libstd/lib.rs
index f6b73f037f2..c2363c9946a 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]
diff --git a/src/libstd/num/strconv.rs b/src/libstd/num/strconv.rs
index c41f55d567f..d5c27c7fbf8 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 a83a66c23a5..6d9b177574a 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 7271203b23b..0d6d17fa007 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 25de2f3b255..ebb5d2946c5 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 22dedeecf3b..59aea214aae 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 a425aab3aa1..484d28dfed0 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 0baefb11cf8..bd6f3d4bb28 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 138296cca70..a3ecfb49ace 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;
@@ -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;
@@ -172,8 +173,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 +214,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/path/posix.rs b/src/libstd/path/posix.rs
index 470e1b4dbb7..3daba53cd86 100644
--- a/src/libstd/path/posix.rs
+++ b/src/libstd/path/posix.rs
@@ -29,11 +29,11 @@ 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> = 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 ea522536d22..e1b0d9b1395 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:
@@ -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
         };
diff --git a/src/libstd/sync/once.rs b/src/libstd/sync/once.rs
index a75088120f8..1bcdc760fc6 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 c0018c5d970..6c5fc3005ed 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 f8861c20464..73e1c7bd9e5 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 ddc6dd021c3..73da200e162 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 4effedbe3ab..107263c31a7 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 08e6f7059d8..26fd410a7a9 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 9fce308cb94..41361a0cde6 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 adbcff8a53f..356d6f02565 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 c91417e611e..5a1a5b4fb7a 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 029b8bf1138..b85b6eccb77 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 11d539c4f9f..ee742ab8375 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 7e6065129a3..34a3d6aa275 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)