about summary refs log tree commit diff
path: root/src/libcore
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/libcore
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/libcore')
-rw-r--r--src/libcore/char.rs5
-rw-r--r--src/libcore/finally.rs41
-rw-r--r--src/libcore/fmt/float.rs9
-rw-r--r--src/libcore/fmt/mod.rs9
-rw-r--r--src/libcore/iter.rs200
-rw-r--r--src/libcore/option.rs16
-rw-r--r--src/libcore/result.rs14
-rw-r--r--src/libcore/slice.rs81
-rw-r--r--src/libcore/str.rs89
9 files changed, 275 insertions, 189 deletions
diff --git a/src/libcore/char.rs b/src/libcore/char.rs
index 671b4ccb9e4..75f7991df02 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);
     }
diff --git a/src/libcore/finally.rs b/src/libcore/finally.rs
index d2b7591b3ef..2b48b2bf81a 100644
--- a/src/libcore/finally.rs
+++ b/src/libcore/finally.rs
@@ -19,40 +19,34 @@
 //! # Example
 //!
 //! ```
+//! # #![feature(unboxed_closures)]
+//!
 //! use std::finally::Finally;
 //!
-//! (|| {
+//! # fn main() {
+//! (|&mut:| {
 //!     // ...
 //! }).finally(|| {
 //!     // this code is always run
 //! })
+//! # }
 //! ```
 
 #![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;
-}
-
-impl<'a,T> Finally<T> for ||: 'a -> T {
-    fn finally(&mut self, dtor: ||) -> T {
-        try_finally(&mut (), self,
-                    |_, f| (*f)(),
-                    |_| dtor())
-    }
+    fn finally<F>(&mut self, dtor: F) -> T where F: FnMut();
 }
 
-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 +80,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 +91,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);
diff --git a/src/libcore/fmt/float.rs b/src/libcore/fmt/float.rs
index 400ce76baa0..fb4d91e912a 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'
diff --git a/src/libcore/fmt/mod.rs b/src/libcore/fmt/mod.rs
index 88ea811cfd6..37a1d4d564d 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,
diff --git a/src/libcore/iter.rs b/src/libcore/iter.rs
index ddca9d36bed..8ee2a8874bb 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}
     }
 
@@ -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}
     }
 
@@ -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 }
     }
 
@@ -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}
     }
 
@@ -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}
     }
 
@@ -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}
     }
 
@@ -371,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 }
     }
 
@@ -429,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}
     }
 
@@ -518,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);
@@ -552,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
     }
@@ -570,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
     }
@@ -580,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) }
         }
@@ -590,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) {
@@ -614,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 {
@@ -641,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 {
@@ -746,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")) {
@@ -774,11 +777,17 @@ 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"]
-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 +1383,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 +1399,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 +1413,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 +1425,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()
@@ -1429,13 +1444,13 @@ impl<'a, A, B, T: RandomAccessIterator<A>> RandomAccessIterator<B> for Map<'a, A
 /// 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 {
@@ -1456,7 +1471,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() {
@@ -1471,13 +1489,16 @@ impl<'a, A, T: DoubleEndedIterator<A>> DoubleEndedIterator<A> for Filter<'a, A,
 /// 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 {
@@ -1497,8 +1518,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() {
@@ -1628,14 +1651,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 {
@@ -1657,14 +1680,14 @@ impl<'a, A, T: Iterator<A>> Iterator<A> for SkipWhile<'a, A, T> {
 /// 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 {
@@ -1816,16 +1839,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))
@@ -1843,15 +1869,19 @@ impl<'a, A, B, T: Iterator<A>, St> Iterator<B> for Scan<'a, A, B, T, St> {
 ///
 #[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 {
@@ -1880,10 +1910,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 {
@@ -1984,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 {
@@ -2002,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();
@@ -2016,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();
@@ -2026,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()
@@ -2073,19 +2108,18 @@ for Inspect<'a, A, T> {
 /// }
 /// ```
 #[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
@@ -2094,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)
@@ -2421,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;
@@ -2445,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`.
diff --git a/src/libcore/option.rs b/src/libcore/option.rs
index 5e2d6266f0e..7be47f73e9e 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()
diff --git a/src/libcore/result.rs b/src/libcore/result.rs
index 9d1ffa78911..88d33a59b38 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 {
diff --git a/src/libcore/slice.rs b/src/libcore/slice.rs
index 4e3007b55fe..27a4328ba80 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
@@ -235,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
     ///
@@ -316,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
@@ -470,7 +476,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 +485,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 +496,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,
@@ -542,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();
 
@@ -637,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,
@@ -651,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,
@@ -1271,14 +1285,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 +1318,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 +1334,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) }
@@ -1330,13 +1344,13 @@ impl<'a, T> SplitsIter<&'a [T]> for Splits<'a, T> {
 /// 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 {
@@ -1349,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; }
@@ -1382,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; }
@@ -1709,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};
 
@@ -1716,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
@@ -1728,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
diff --git a/src/libcore/str.rs b/src/libcore/str.rs
index d0c8558b55d..92f82bd9771 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) }
 
@@ -323,8 +316,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 +341,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]
@@ -1361,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();
@@ -1372,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>;
 
@@ -1382,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();
@@ -1396,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>;
 
@@ -1408,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"]);
     ///
@@ -1417,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>;
 
@@ -1432,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>;
 
@@ -1650,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;
 
@@ -1666,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;
 
@@ -1682,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;
 
@@ -1826,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>;
 
@@ -1851,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>;
 
@@ -1980,7 +2007,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 +2082,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]
@@ -2140,11 +2171,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;
@@ -2155,7 +2186,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()) }
         }
@@ -2163,7 +2194,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;