diff options
| author | bors <bors@rust-lang.org> | 2014-12-13 22:57:21 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2014-12-13 22:57:21 +0000 |
| commit | 444fa1b7cffcd99ca5b8abb51acf979f06a25899 (patch) | |
| tree | 51a8beea4fd983ce8cb46879a2fdbaf72916c13e | |
| parent | 567b90ff095076054c98fa2f08d6c552ae60968d (diff) | |
| parent | b8e0b81dd57621af28d7b2b5551a3217f7bd4cec (diff) | |
| download | rust-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
194 files changed, 2534 insertions, 1761 deletions
diff --git a/src/libarena/lib.rs b/src/libarena/lib.rs index 95c4dff323e..1f4df1fd0a5 100644 --- a/src/libarena/lib.rs +++ b/src/libarena/lib.rs @@ -28,6 +28,7 @@ html_root_url = "http://doc.rust-lang.org/nightly/")] #![feature(unsafe_destructor)] +#![feature(unboxed_closures)] #![allow(missing_docs)] extern crate alloc; @@ -209,7 +210,7 @@ impl Arena { } #[inline] - fn alloc_copy<T>(&self, op: || -> T) -> &mut T { + fn alloc_copy<T, F>(&self, op: F) -> &mut T where F: FnOnce() -> T { unsafe { let ptr = self.alloc_copy_inner(mem::size_of::<T>(), mem::min_align_of::<T>()); @@ -263,7 +264,7 @@ impl Arena { } #[inline] - fn alloc_noncopy<T>(&self, op: || -> T) -> &mut T { + fn alloc_noncopy<T, F>(&self, op: F) -> &mut T where F: FnOnce() -> T { unsafe { let tydesc = get_tydesc::<T>(); let (ty_ptr, ptr) = @@ -287,7 +288,7 @@ impl Arena { /// Allocates a new item in the arena, using `op` to initialize the value, /// and returns a reference to it. #[inline] - pub fn alloc<T>(&self, op: || -> T) -> &mut T { + pub fn alloc<T, F>(&self, op: F) -> &mut T where F: FnOnce() -> T { unsafe { if intrinsics::needs_drop::<T>() { self.alloc_noncopy(op) @@ -339,7 +340,7 @@ fn test_arena_destructors_fail() { arena.alloc(|| { [0u8, 1u8, 2u8] }); } // Now, panic while allocating - arena.alloc::<Rc<int>>(|| { + arena.alloc::<Rc<int>, _>(|| { panic!(); }); } diff --git a/src/libcollections/bench.rs b/src/libcollections/bench.rs index a212f22f899..3346e55158a 100644 --- a/src/libcollections/bench.rs +++ b/src/libcollections/bench.rs @@ -13,9 +13,14 @@ use std::rand; use std::rand::Rng; use test::Bencher; -pub fn insert_rand_n<M>(n: uint, map: &mut M, b: &mut Bencher, - insert: |&mut M, uint|, - remove: |&mut M, uint|) { +pub fn insert_rand_n<M, I, R>(n: uint, + map: &mut M, + b: &mut Bencher, + mut insert: I, + mut remove: R) where + I: FnMut(&mut M, uint), + R: FnMut(&mut M, uint), +{ // setup let mut rng = rand::weak_rng(); @@ -31,9 +36,14 @@ pub fn insert_rand_n<M>(n: uint, map: &mut M, b: &mut Bencher, }) } -pub fn insert_seq_n<M>(n: uint, map: &mut M, b: &mut Bencher, - insert: |&mut M, uint|, - remove: |&mut M, uint|) { +pub fn insert_seq_n<M, I, R>(n: uint, + map: &mut M, + b: &mut Bencher, + mut insert: I, + mut remove: R) where + I: FnMut(&mut M, uint), + R: FnMut(&mut M, uint), +{ // setup for i in range(0u, n) { insert(map, i * 2); @@ -48,9 +58,14 @@ pub fn insert_seq_n<M>(n: uint, map: &mut M, b: &mut Bencher, }) } -pub fn find_rand_n<M, T>(n: uint, map: &mut M, b: &mut Bencher, - insert: |&mut M, uint|, - find: |&M, uint| -> T) { +pub fn find_rand_n<M, T, I, F>(n: uint, + map: &mut M, + b: &mut Bencher, + mut insert: I, + mut find: F) where + I: FnMut(&mut M, uint), + F: FnMut(&M, uint) -> T, +{ // setup let mut rng = rand::weak_rng(); let mut keys = Vec::from_fn(n, |_| rng.gen::<uint>() % n); @@ -70,9 +85,14 @@ pub fn find_rand_n<M, T>(n: uint, map: &mut M, b: &mut Bencher, }) } -pub fn find_seq_n<M, T>(n: uint, map: &mut M, b: &mut Bencher, - insert: |&mut M, uint|, - find: |&M, uint| -> T) { +pub fn find_seq_n<M, T, I, F>(n: uint, + map: &mut M, + b: &mut Bencher, + mut insert: I, + mut find: F) where + I: FnMut(&mut M, uint), + F: FnMut(&M, uint) -> T, +{ // setup for i in range(0u, n) { insert(map, i); diff --git a/src/libcollections/bit.rs b/src/libcollections/bit.rs index b401978c9c9..a0c4f6e7ee8 100644 --- a/src/libcollections/bit.rs +++ b/src/libcollections/bit.rs @@ -174,7 +174,7 @@ impl<'a> Iterator<(uint, u32)> for MaskWords<'a> { impl Bitv { #[inline] - fn process(&mut self, other: &Bitv, op: |u32, u32| -> u32) -> bool { + fn process<F>(&mut self, other: &Bitv, mut op: F) -> bool where F: FnMut(u32, u32) -> u32 { let len = other.storage.len(); assert_eq!(self.storage.len(), len); let mut changed = false; @@ -816,7 +816,7 @@ pub fn from_bytes(bytes: &[u8]) -> Bitv { /// let bv = from_fn(5, |i| { i % 2 == 0 }); /// assert!(bv.eq_vec(&[true, false, true, false, true])); /// ``` -pub fn from_fn(len: uint, f: |index: uint| -> bool) -> Bitv { +pub fn from_fn<F>(len: uint, mut f: F) -> Bitv where F: FnMut(uint) -> bool { let mut bitv = Bitv::with_capacity(len, false); for i in range(0u, len) { bitv.set(i, f(i)); @@ -1182,7 +1182,7 @@ impl BitvSet { } #[inline] - fn other_op(&mut self, other: &BitvSet, f: |u32, u32| -> u32) { + fn other_op<F>(&mut self, other: &BitvSet, mut f: F) where F: FnMut(u32, u32) -> u32 { // Expand the vector if necessary self.reserve(other.capacity()); @@ -1277,10 +1277,12 @@ impl BitvSet { #[inline] #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn union<'a>(&'a self, other: &'a BitvSet) -> TwoBitPositions<'a> { + fn or(w1: u32, w2: u32) -> u32 { w1 | w2 } + TwoBitPositions { set: self, other: other, - merge: |w1, w2| w1 | w2, + merge: or, current_word: 0u32, next_idx: 0u } @@ -1306,11 +1308,13 @@ impl BitvSet { #[inline] #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn intersection<'a>(&'a self, other: &'a BitvSet) -> Take<TwoBitPositions<'a>> { + fn bitand(w1: u32, w2: u32) -> u32 { w1 & w2 } + let min = cmp::min(self.capacity(), other.capacity()); TwoBitPositions { set: self, other: other, - merge: |w1, w2| w1 & w2, + merge: bitand, current_word: 0u32, next_idx: 0 }.take(min) @@ -1343,10 +1347,12 @@ impl BitvSet { #[inline] #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn difference<'a>(&'a self, other: &'a BitvSet) -> TwoBitPositions<'a> { + fn diff(w1: u32, w2: u32) -> u32 { w1 & !w2 } + TwoBitPositions { set: self, other: other, - merge: |w1, w2| w1 & !w2, + merge: diff, current_word: 0u32, next_idx: 0 } @@ -1373,10 +1379,12 @@ impl BitvSet { #[inline] #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn symmetric_difference<'a>(&'a self, other: &'a BitvSet) -> TwoBitPositions<'a> { + fn bitxor(w1: u32, w2: u32) -> u32 { w1 ^ w2 } + TwoBitPositions { set: self, other: other, - merge: |w1, w2| w1 ^ w2, + merge: bitxor, current_word: 0u32, next_idx: 0 } @@ -1614,7 +1622,7 @@ pub struct BitPositions<'a> { pub struct TwoBitPositions<'a> { set: &'a BitvSet, other: &'a BitvSet, - merge: |u32, u32|: 'a -> u32, + merge: fn(u32, u32) -> u32, current_word: u32, next_idx: uint } diff --git a/src/libcollections/btree/map.rs b/src/libcollections/btree/map.rs index 3d5067d5a51..e49a8ddbe5a 100644 --- a/src/libcollections/btree/map.rs +++ b/src/libcollections/btree/map.rs @@ -107,10 +107,12 @@ pub struct MoveEntries<K, V> { } /// An iterator over a BTreeMap's keys. -pub type Keys<'a, K, V> = iter::Map<'static, (&'a K, &'a V), &'a K, Entries<'a, K, V>>; +pub type Keys<'a, K, V> = + iter::Map<(&'a K, &'a V), &'a K, Entries<'a, K, V>, fn((&'a K, &'a V)) -> &'a K>; /// An iterator over a BTreeMap's values. -pub type Values<'a, K, V> = iter::Map<'static, (&'a K, &'a V), &'a V, Entries<'a, K, V>>; +pub type Values<'a, K, V> = + iter::Map<(&'a K, &'a V), &'a V, Entries<'a, K, V>, fn((&'a K, &'a V)) -> &'a V>; /// A view into a single entry in a map, which may either be vacant or occupied. pub enum Entry<'a, K:'a, V:'a> { @@ -1207,7 +1209,9 @@ impl<K, V> BTreeMap<K, V> { /// ``` #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn keys<'a>(&'a self) -> Keys<'a, K, V> { - self.iter().map(|(k, _)| k) + fn first<A, B>((a, _): (A, B)) -> A { a } + + self.iter().map(first) } /// Gets an iterator over the values of the map. @@ -1226,7 +1230,9 @@ impl<K, V> BTreeMap<K, V> { /// ``` #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn values<'a>(&'a self) -> Values<'a, K, V> { - self.iter().map(|(_, v)| v) + fn second<A, B>((_, b): (A, B)) -> B { b } + + self.iter().map(second) } /// Return the number of elements in the map. diff --git a/src/libcollections/btree/set.rs b/src/libcollections/btree/set.rs index 0fbc319f4ff..cd01c008fe1 100644 --- a/src/libcollections/btree/set.rs +++ b/src/libcollections/btree/set.rs @@ -36,7 +36,8 @@ pub struct BTreeSet<T>{ pub type Items<'a, T> = Keys<'a, T, ()>; /// An owning iterator over a BTreeSet's items. -pub type MoveItems<T> = iter::Map<'static, (T, ()), T, MoveEntries<T, ()>>; +pub type MoveItems<T> = + iter::Map<(T, ()), T, MoveEntries<T, ()>, fn((T, ())) -> T>; /// A lazy iterator producing elements in the set difference (in-order). pub struct DifferenceItems<'a, T:'a> { @@ -87,7 +88,9 @@ impl<T> BTreeSet<T> { /// Gets an iterator for moving out the BtreeSet's contents. #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn into_iter(self) -> MoveItems<T> { - self.map.into_iter().map(|(k, _)| k) + fn first<A, B>((a, _): (A, B)) -> A { a } + + self.map.into_iter().map(first) } } @@ -600,10 +603,23 @@ mod test { assert!(hash::hash(&x) == hash::hash(&y)); } - fn check(a: &[int], - b: &[int], - expected: &[int], - f: |&BTreeSet<int>, &BTreeSet<int>, f: |&int| -> bool| -> bool) { + struct Counter<'a, 'b> { + i: &'a mut uint, + expected: &'b [int], + } + + impl<'a, 'b> FnMut(&int) -> bool for Counter<'a, 'b> { + extern "rust-call" fn call_mut(&mut self, (&x,): (&int,)) -> bool { + assert_eq!(x, self.expected[*self.i]); + *self.i += 1; + true + } + } + + fn check<F>(a: &[int], b: &[int], expected: &[int], f: F) where + // FIXME Replace Counter with `Box<FnMut(_) -> _>` + F: FnOnce(&BTreeSet<int>, &BTreeSet<int>, Counter) -> bool, + { let mut set_a = BTreeSet::new(); let mut set_b = BTreeSet::new(); @@ -611,11 +627,7 @@ mod test { for y in b.iter() { assert!(set_b.insert(*y)) } let mut i = 0; - f(&set_a, &set_b, |x| { - assert_eq!(*x, expected[i]); - i += 1; - true - }); + f(&set_a, &set_b, Counter { i: &mut i, expected: expected }); assert_eq!(i, expected.len()); } diff --git a/src/libcollections/dlist.rs b/src/libcollections/dlist.rs index d50b212c7dd..f49a0c037de 100644 --- a/src/libcollections/dlist.rs +++ b/src/libcollections/dlist.rs @@ -351,18 +351,16 @@ impl<T> DList<T> { /// println!("{}", e); // prints 2, then 4, then 11, then 7, then 8 /// } /// ``` - pub fn insert_when(&mut self, elt: T, f: |&T, &T| -> bool) { - { - let mut it = self.iter_mut(); - loop { - match it.peek_next() { - None => break, - Some(x) => if f(x, &elt) { break } - } - it.next(); + pub fn insert_when<F>(&mut self, elt: T, mut f: F) where F: FnMut(&T, &T) -> bool { + let mut it = self.iter_mut(); + loop { + match it.peek_next() { + None => break, + Some(x) => if f(x, &elt) { break } } - it.insert_next(elt); + it.next(); } + it.insert_next(elt); } /// Merges `other` into this `DList`, using the function `f`. @@ -371,7 +369,7 @@ impl<T> DList<T> { /// put `a` in the result if `f(a, b)` is true, and otherwise `b`. /// /// This operation should compute in O(max(N, M)) time. - pub fn merge(&mut self, mut other: DList<T>, f: |&T, &T| -> bool) { + pub fn merge<F>(&mut self, mut other: DList<T>, mut f: F) where F: FnMut(&T, &T) -> bool { { let mut it = self.iter_mut(); loop { diff --git a/src/libcollections/slice.rs b/src/libcollections/slice.rs index 6bdfa490748..463e28b420d 100644 --- a/src/libcollections/slice.rs +++ b/src/libcollections/slice.rs @@ -94,6 +94,7 @@ use core::cmp; use core::kinds::{Copy, Sized}; use core::mem::size_of; use core::mem; +use core::ops::FnMut; use core::prelude::{Clone, Greater, Iterator, IteratorExt, Less, None, Option}; use core::prelude::{Ord, Ordering, RawPtr, Some, range}; use core::ptr; @@ -296,7 +297,7 @@ pub trait CloneSliceAllocPrelude<T> for Sized? { /// Partitions the vector into two vectors `(a, b)`, where all /// elements of `a` satisfy `f` and all elements of `b` do not. - fn partitioned(&self, f: |&T| -> bool) -> (Vec<T>, Vec<T>); + fn partitioned<F>(&self, f: F) -> (Vec<T>, Vec<T>) where F: FnMut(&T) -> bool; /// Creates an iterator that yields every possible permutation of the /// vector in succession. @@ -336,7 +337,7 @@ impl<T: Clone> CloneSliceAllocPrelude<T> for [T] { #[inline] - fn partitioned(&self, f: |&T| -> bool) -> (Vec<T>, Vec<T>) { + fn partitioned<F>(&self, mut f: F) -> (Vec<T>, Vec<T>) where F: FnMut(&T) -> bool { let mut lefts = Vec::new(); let mut rights = Vec::new(); @@ -361,7 +362,7 @@ impl<T: Clone> CloneSliceAllocPrelude<T> for [T] { } -fn insertion_sort<T>(v: &mut [T], compare: |&T, &T| -> Ordering) { +fn insertion_sort<T, F>(v: &mut [T], mut compare: F) where F: FnMut(&T, &T) -> Ordering { let len = v.len() as int; let buf_v = v.as_mut_ptr(); @@ -403,7 +404,7 @@ fn insertion_sort<T>(v: &mut [T], compare: |&T, &T| -> Ordering) { } } -fn merge_sort<T>(v: &mut [T], compare: |&T, &T| -> Ordering) { +fn merge_sort<T, F>(v: &mut [T], mut compare: F) where F: FnMut(&T, &T) -> Ordering { // warning: this wildly uses unsafe. static BASE_INSERTION: uint = 32; static LARGE_INSERTION: uint = 16; @@ -611,7 +612,7 @@ pub trait SliceAllocPrelude<T> for Sized? { /// v.sort_by(|a, b| b.cmp(a)); /// assert!(v == [5, 4, 3, 2, 1]); /// ``` - fn sort_by(&mut self, compare: |&T, &T| -> Ordering); + fn sort_by<F>(&mut self, compare: F) where F: FnMut(&T, &T) -> Ordering; /// Consumes `src` and moves as many elements as it can into `self` /// from the range [start,end). @@ -639,7 +640,7 @@ pub trait SliceAllocPrelude<T> for Sized? { impl<T> SliceAllocPrelude<T> for [T] { #[inline] - fn sort_by(&mut self, compare: |&T, &T| -> Ordering) { + fn sort_by<F>(&mut self, compare: F) where F: FnMut(&T, &T) -> Ordering { merge_sort(self, compare) } diff --git a/src/libcollections/str.rs b/src/libcollections/str.rs index 2e96b941c08..bf568fd92d5 100644 --- a/src/libcollections/str.rs +++ b/src/libcollections/str.rs @@ -903,21 +903,21 @@ mod tests { #[test] fn test_find() { assert_eq!("hello".find('l'), Some(2u)); - assert_eq!("hello".find(|c:char| c == 'o'), Some(4u)); + assert_eq!("hello".find(|&: c:char| c == 'o'), Some(4u)); assert!("hello".find('x').is_none()); - assert!("hello".find(|c:char| c == 'x').is_none()); + assert!("hello".find(|&: c:char| c == 'x').is_none()); assert_eq!("ประเทศไทย中华Việt Nam".find('华'), Some(30u)); - assert_eq!("ประเทศไทย中华Việt Nam".find(|c: char| c == '华'), Some(30u)); + assert_eq!("ประเทศไทย中华Việt Nam".find(|&: c: char| c == '华'), Some(30u)); } #[test] fn test_rfind() { assert_eq!("hello".rfind('l'), Some(3u)); - assert_eq!("hello".rfind(|c:char| c == 'o'), Some(4u)); + assert_eq!("hello".rfind(|&: c:char| c == 'o'), Some(4u)); assert!("hello".rfind('x').is_none()); - assert!("hello".rfind(|c:char| c == 'x').is_none()); + assert!("hello".rfind(|&: c:char| c == 'x').is_none()); assert_eq!("ประเทศไทย中华Việt Nam".rfind('华'), Some(30u)); - assert_eq!("ประเทศไทย中华Việt Nam".rfind(|c: char| c == '华'), Some(30u)); + assert_eq!("ประเทศไทย中华Việt Nam".rfind(|&: c: char| c == '华'), Some(30u)); } #[test] @@ -1281,7 +1281,7 @@ mod tests { assert_eq!("11foo1bar11".trim_left_chars('1'), "foo1bar11"); let chars: &[char] = &['1', '2']; assert_eq!("12foo1bar12".trim_left_chars(chars), "foo1bar12"); - assert_eq!("123foo1bar123".trim_left_chars(|c: char| c.is_numeric()), "foo1bar123"); + assert_eq!("123foo1bar123".trim_left_chars(|&: c: char| c.is_numeric()), "foo1bar123"); } #[test] @@ -1296,7 +1296,7 @@ mod tests { assert_eq!("11foo1bar11".trim_right_chars('1'), "11foo1bar"); let chars: &[char] = &['1', '2']; assert_eq!("12foo1bar12".trim_right_chars(chars), "12foo1bar"); - assert_eq!("123foo1bar123".trim_right_chars(|c: char| c.is_numeric()), "123foo1bar"); + assert_eq!("123foo1bar123".trim_right_chars(|&: c: char| c.is_numeric()), "123foo1bar"); } #[test] @@ -1311,7 +1311,7 @@ mod tests { assert_eq!("11foo1bar11".trim_chars('1'), "foo1bar"); let chars: &[char] = &['1', '2']; assert_eq!("12foo1bar12".trim_chars(chars), "foo1bar"); - assert_eq!("123foo1bar123".trim_chars(|c: char| c.is_numeric()), "foo1bar"); + assert_eq!("123foo1bar123".trim_chars(|&: c: char| c.is_numeric()), "foo1bar"); } #[test] @@ -1787,14 +1787,14 @@ mod tests { let split: Vec<&str> = data.splitn(3, ' ').collect(); assert_eq!(split, vec!["\nMäry", "häd", "ä", "little lämb\nLittle lämb\n"]); - let split: Vec<&str> = data.splitn(3, |c: char| c == ' ').collect(); + let split: Vec<&str> = data.splitn(3, |&: c: char| c == ' ').collect(); assert_eq!(split, vec!["\nMäry", "häd", "ä", "little lämb\nLittle lämb\n"]); // Unicode let split: Vec<&str> = data.splitn(3, 'ä').collect(); assert_eq!(split, vec!["\nM", "ry h", "d ", " little lämb\nLittle lämb\n"]); - let split: Vec<&str> = data.splitn(3, |c: char| c == 'ä').collect(); + let split: Vec<&str> = data.splitn(3, |&: c: char| c == 'ä').collect(); assert_eq!(split, vec!["\nM", "ry h", "d ", " little lämb\nLittle lämb\n"]); } @@ -2588,7 +2588,7 @@ mod bench { let s = "Mary had a little lamb, Little lamb, little-lamb."; let len = s.split(' ').count(); - b.iter(|| assert_eq!(s.split(|c: char| c == ' ').count(), len)); + b.iter(|| assert_eq!(s.split(|&: c: char| c == ' ').count(), len)); } #[bench] diff --git a/src/libcollections/tree/map.rs b/src/libcollections/tree/map.rs index 24395ca6493..5c2cf4a8180 100644 --- a/src/libcollections/tree/map.rs +++ b/src/libcollections/tree/map.rs @@ -234,7 +234,9 @@ impl<K: Ord, V> TreeMap<K, V> { /// ``` #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn keys<'a>(&'a self) -> Keys<'a, K, V> { - self.iter().map(|(k, _v)| k) + fn first<A, B>((a, _): (A, B)) -> A { a } + + self.iter().map(first) } /// Gets a lazy iterator over the values in the map, in ascending order @@ -256,7 +258,9 @@ impl<K: Ord, V> TreeMap<K, V> { /// ``` #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn values<'a>(&'a self) -> Values<'a, K, V> { - self.iter().map(|(_k, v)| v) + fn second<A, B>((_, b): (A, B)) -> B { b } + + self.iter().map(second) } /// Gets a lazy iterator over the key-value pairs in the map, in ascending order. @@ -612,7 +616,7 @@ impl<K, V> TreeMap<K, V> { /// ``` #[inline] #[experimental = "likely to be renamed, may be removed"] - pub fn find_with(&self, f:|&K| -> Ordering) -> Option<&V> { + pub fn find_with<F>(&self, f: F) -> Option<&V> where F: FnMut(&K) -> Ordering { tree_find_with(&self.root, f) } @@ -637,7 +641,9 @@ impl<K, V> TreeMap<K, V> { /// ``` #[inline] #[experimental = "likely to be renamed, may be removed"] - pub fn find_with_mut<'a>(&'a mut self, f:|&K| -> Ordering) -> Option<&'a mut V> { + pub fn find_with_mut<'a, F>(&'a mut self, f: F) -> Option<&'a mut V> where + F: FnMut(&K) -> Ordering + { tree_find_with_mut(&mut self.root, f) } } @@ -863,11 +869,11 @@ pub struct RevMutEntries<'a, K:'a, V:'a> { /// TreeMap keys iterator. pub type Keys<'a, K, V> = - iter::Map<'static, (&'a K, &'a V), &'a K, Entries<'a, K, V>>; + iter::Map<(&'a K, &'a V), &'a K, Entries<'a, K, V>, fn((&'a K, &'a V)) -> &'a K>; /// TreeMap values iterator. pub type Values<'a, K, V> = - iter::Map<'static, (&'a K, &'a V), &'a V, Entries<'a, K, V>>; + iter::Map<(&'a K, &'a V), &'a V, Entries<'a, K, V>, fn((&'a K, &'a V)) -> &'a V>; // FIXME #5846 we want to be able to choose between &x and &mut x @@ -1125,8 +1131,12 @@ fn split<K: Ord, V>(node: &mut Box<TreeNode<K, V>>) { // Next 2 functions have the same convention: comparator gets // at input current key and returns search_key cmp cur_key // (i.e. search_key.cmp(&cur_key)) -fn tree_find_with<'r, K, V>(node: &'r Option<Box<TreeNode<K, V>>>, - f: |&K| -> Ordering) -> Option<&'r V> { +fn tree_find_with<'r, K, V, F>( + node: &'r Option<Box<TreeNode<K, V>>>, + mut f: F, +) -> Option<&'r V> where + F: FnMut(&K) -> Ordering, +{ let mut current: &'r Option<Box<TreeNode<K, V>>> = node; loop { match *current { @@ -1143,8 +1153,12 @@ fn tree_find_with<'r, K, V>(node: &'r Option<Box<TreeNode<K, V>>>, } // See comments above tree_find_with -fn tree_find_with_mut<'r, K, V>(node: &'r mut Option<Box<TreeNode<K, V>>>, - f: |&K| -> Ordering) -> Option<&'r mut V> { +fn tree_find_with_mut<'r, K, V, F>( + node: &'r mut Option<Box<TreeNode<K, V>>>, + mut f: F, +) -> Option<&'r mut V> where + F: FnMut(&K) -> Ordering, +{ let mut current = node; loop { diff --git a/src/libcollections/tree/set.rs b/src/libcollections/tree/set.rs index 3af2f3e0193..bd8bf5c6cb6 100644 --- a/src/libcollections/tree/set.rs +++ b/src/libcollections/tree/set.rs @@ -205,7 +205,9 @@ impl<T: Ord> TreeSet<T> { #[inline] #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn into_iter(self) -> MoveSetItems<T> { - self.map.into_iter().map(|(value, _)| value) + fn first<A, B>((a, _): (A, B)) -> A { a } + + self.map.into_iter().map(first) } /// Gets a lazy iterator pointing to the first value not less than `v` (greater or equal). @@ -560,7 +562,7 @@ pub struct RevSetItems<'a, T:'a> { } /// A lazy forward iterator over a set that consumes the set while iterating. -pub type MoveSetItems<T> = iter::Map<'static, (T, ()), T, MoveEntries<T, ()>>; +pub type MoveSetItems<T> = iter::Map<(T, ()), T, MoveEntries<T, ()>, fn((T, ())) -> T>; /// A lazy iterator producing elements in the set difference (in-order). pub struct DifferenceItems<'a, T:'a> { @@ -934,10 +936,23 @@ mod test { assert!(hash::hash(&x) == hash::hash(&y)); } - fn check(a: &[int], - b: &[int], - expected: &[int], - f: |&TreeSet<int>, &TreeSet<int>, f: |&int| -> bool| -> bool) { + struct Counter<'a, 'b> { + i: &'a mut uint, + expected: &'b [int], + } + + impl<'a, 'b> FnMut(&int) -> bool for Counter<'a, 'b> { + extern "rust-call" fn call_mut(&mut self, (&x,): (&int,)) -> bool { + assert_eq!(x, self.expected[*self.i]); + *self.i += 1; + true + } + } + + fn check<F>(a: &[int], b: &[int], expected: &[int], f: F) where + // FIXME Replace `Counter` with `Box<FnMut(&int) -> bool>` + F: FnOnce(&TreeSet<int>, &TreeSet<int>, Counter) -> bool, + { let mut set_a = TreeSet::new(); let mut set_b = TreeSet::new(); @@ -945,11 +960,7 @@ mod test { for y in b.iter() { assert!(set_b.insert(*y)) } let mut i = 0; - f(&set_a, &set_b, |x| { - assert_eq!(*x, expected[i]); - i += 1; - true - }); + f(&set_a, &set_b, Counter { i: &mut i, expected: expected }); assert_eq!(i, expected.len()); } diff --git a/src/libcollections/trie/map.rs b/src/libcollections/trie/map.rs index 1b087d2e63d..a4dee807648 100644 --- a/src/libcollections/trie/map.rs +++ b/src/libcollections/trie/map.rs @@ -197,14 +197,18 @@ impl<T> TrieMap<T> { /// The iterator's element type is `uint`. #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn keys<'r>(&'r self) -> Keys<'r, T> { - self.iter().map(|(k, _v)| k) + fn first<A, B>((a, _): (A, B)) -> A { a } + + self.iter().map(first) } /// Gets an iterator visiting all values in ascending order by the keys. /// The iterator's element type is `&'r T`. #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn values<'r>(&'r self) -> Values<'r, T> { - self.iter().map(|(_k, v)| v) + fn second<A, B>((_, b): (A, B)) -> B { b } + + self.iter().map(second) } /// Gets an iterator over the key-value pairs in the map, ordered by keys. @@ -1091,12 +1095,11 @@ pub struct MutEntries<'a, T:'a> { } /// A forward iterator over the keys of a map. -pub type Keys<'a, T> = - iter::Map<'static, (uint, &'a T), uint, Entries<'a, T>>; +pub type Keys<'a, T> = iter::Map<(uint, &'a T), uint, Entries<'a, T>, fn((uint, &'a T)) -> uint>; /// A forward iterator over the values of a map. pub type Values<'a, T> = - iter::Map<'static, (uint, &'a T), &'a T, Entries<'a, T>>; + iter::Map<(uint, &'a T), &'a T, Entries<'a, T>, fn((uint, &'a T)) -> &'a T>; // FIXME #5846: see `addr!` above. macro_rules! item { ($i:item) => {$i}} diff --git a/src/libcollections/trie/set.rs b/src/libcollections/trie/set.rs index 46052ff2f50..5621726dc56 100644 --- a/src/libcollections/trie/set.rs +++ b/src/libcollections/trie/set.rs @@ -743,10 +743,23 @@ mod test { assert!(a < b && a <= b); } - fn check(a: &[uint], - b: &[uint], - expected: &[uint], - f: |&TrieSet, &TrieSet, f: |uint| -> bool| -> bool) { + struct Counter<'a, 'b> { + i: &'a mut uint, + expected: &'b [uint], + } + + impl<'a, 'b> FnMut(uint) -> bool for Counter<'a, 'b> { + extern "rust-call" fn call_mut(&mut self, (x,): (uint,)) -> bool { + assert_eq!(x, self.expected[*self.i]); + *self.i += 1; + true + } + } + + fn check<F>(a: &[uint], b: &[uint], expected: &[uint], f: F) where + // FIXME Replace `Counter` with `Box<FnMut(&uint) -> bool>` + F: FnOnce(&TrieSet, &TrieSet, Counter) -> bool, + { let mut set_a = TrieSet::new(); let mut set_b = TrieSet::new(); @@ -754,11 +767,7 @@ mod test { for y in b.iter() { assert!(set_b.insert(*y)) } let mut i = 0; - f(&set_a, &set_b, |x| { - assert_eq!(x, expected[i]); - i += 1; - true - }); + f(&set_a, &set_b, Counter { i: &mut i, expected: expected }); assert_eq!(i, expected.len()); } diff --git a/src/libcollections/vec.rs b/src/libcollections/vec.rs index f8a971db173..2ed8686394c 100644 --- a/src/libcollections/vec.rs +++ b/src/libcollections/vec.rs @@ -206,7 +206,7 @@ impl<T> Vec<T> { #[inline] #[unstable = "the naming is uncertain as well as this migrating to unboxed \ closures in the future"] - pub fn from_fn(length: uint, op: |uint| -> T) -> Vec<T> { + pub fn from_fn<F>(length: uint, mut op: F) -> Vec<T> where F: FnMut(uint) -> T { unsafe { let mut xs = Vec::with_capacity(length); while xs.len < length { @@ -289,7 +289,7 @@ impl<T> Vec<T> { /// ``` #[inline] #[experimental] - pub fn partition(self, f: |&T| -> bool) -> (Vec<T>, Vec<T>) { + pub fn partition<F>(self, mut f: F) -> (Vec<T>, Vec<T>) where F: FnMut(&T) -> bool { let mut lefts = Vec::new(); let mut rights = Vec::new(); @@ -400,7 +400,7 @@ impl<T: Clone> Vec<T> { /// assert_eq!(odd, vec![1i, 3]); /// ``` #[experimental] - pub fn partitioned(&self, f: |&T| -> bool) -> (Vec<T>, Vec<T>) { + pub fn partitioned<F>(&self, mut f: F) -> (Vec<T>, Vec<T>) where F: FnMut(&T) -> bool { let mut lefts = Vec::new(); let mut rights = Vec::new(); @@ -991,7 +991,7 @@ impl<T> Vec<T> { /// assert_eq!(vec, vec![2, 4]); /// ``` #[unstable = "the closure argument may become an unboxed closure"] - pub fn retain(&mut self, f: |&T| -> bool) { + pub fn retain<F>(&mut self, mut f: F) where F: FnMut(&T) -> bool { let len = self.len(); let mut del = 0u; { @@ -1023,7 +1023,7 @@ impl<T> Vec<T> { /// assert_eq!(vec, vec![0, 1, 0, 1, 2]); /// ``` #[unstable = "this function may be renamed or change to unboxed closures"] - pub fn grow_fn(&mut self, n: uint, f: |uint| -> T) { + pub fn grow_fn<F>(&mut self, n: uint, mut f: F) where F: FnMut(uint) -> T { self.reserve(n); for i in range(0u, n) { self.push(f(i)); @@ -1570,7 +1570,7 @@ impl<T> Vec<T> { /// let newtyped_bytes = bytes.map_in_place(|x| Newtype(x)); /// assert_eq!(newtyped_bytes.as_slice(), [Newtype(0x11), Newtype(0x22)].as_slice()); /// ``` - pub fn map_in_place<U>(self, f: |T| -> U) -> Vec<U> { + pub fn map_in_place<U, F>(self, mut f: F) -> Vec<U> where F: FnMut(T) -> U { // FIXME: Assert statically that the types `T` and `U` have the same // size. assert!(mem::size_of::<T>() == mem::size_of::<U>()); diff --git a/src/libcollections/vec_map.rs b/src/libcollections/vec_map.rs index 3b8c690e047..cc2fd0a6646 100644 --- a/src/libcollections/vec_map.rs +++ b/src/libcollections/vec_map.rs @@ -20,6 +20,7 @@ use core::fmt; use core::iter; use core::iter::{Enumerate, FilterMap}; use core::mem::replace; +use core::ops::FnOnce; use hash::{Hash, Writer}; use {vec, slice}; @@ -141,14 +142,18 @@ impl<V> VecMap<V> { /// The iterator's element type is `uint`. #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn keys<'r>(&'r self) -> Keys<'r, V> { - self.iter().map(|(k, _v)| k) + fn first<A, B>((a, _): (A, B)) -> A { a } + + self.iter().map(first) } /// Returns an iterator visiting all values in ascending order by the keys. /// The iterator's element type is `&'r V`. #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn values<'r>(&'r self) -> Values<'r, V> { - self.iter().map(|(_k, v)| v) + fn second<A, B>((_, b): (A, B)) -> B { b } + + self.iter().map(second) } /// Returns an iterator visiting all key-value pairs in ascending order by the keys. @@ -230,10 +235,12 @@ impl<V> VecMap<V> { /// ``` #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn into_iter(&mut self) -> MoveItems<V> { - let values = replace(&mut self.v, vec!()); - values.into_iter().enumerate().filter_map(|(i, v)| { + fn filter<A>((i, v): (uint, Option<A>)) -> Option<(uint, A)> { v.map(|v| (i, v)) - }) + } + + let values = replace(&mut self.v, vec!()); + values.into_iter().enumerate().filter_map(filter) } /// Return the number of elements in the map. @@ -446,8 +453,8 @@ impl<V:Clone> VecMap<V> { /// assert!(!map.update(1, vec![3i, 4], |mut old, new| { old.extend(new.into_iter()); old })); /// assert_eq!(map[1], vec![1i, 2, 3, 4]); /// ``` - pub fn update(&mut self, key: uint, newval: V, ff: |V, V| -> V) -> bool { - self.update_with_key(key, newval, |_k, v, v1| ff(v,v1)) + pub fn update<F>(&mut self, key: uint, newval: V, ff: F) -> bool where F: FnOnce(V, V) -> V { + self.update_with_key(key, newval, move |_k, v, v1| ff(v,v1)) } /// Updates a value in the map. If the key already exists in the map, @@ -470,11 +477,9 @@ impl<V:Clone> VecMap<V> { /// assert!(!map.update_with_key(7, 20, |key, old, new| (old + new) % key)); /// assert_eq!(map[7], 2); /// ``` - pub fn update_with_key(&mut self, - key: uint, - val: V, - ff: |uint, V, V| -> V) - -> bool { + pub fn update_with_key<F>(&mut self, key: uint, val: V, ff: F) -> bool where + F: FnOnce(uint, V, V) -> V + { let new_val = match self.get(&key) { None => val, Some(orig) => ff(key, (*orig).clone(), val) @@ -620,16 +625,18 @@ iterator!(impl MutEntries -> (uint, &'a mut V), as_mut) double_ended_iterator!(impl MutEntries -> (uint, &'a mut V), as_mut) /// Forward iterator over the keys of a map -pub type Keys<'a, V> = - iter::Map<'static, (uint, &'a V), uint, Entries<'a, V>>; +pub type Keys<'a, V> = iter::Map<(uint, &'a V), uint, Entries<'a, V>, fn((uint, &'a V)) -> uint>; /// Forward iterator over the values of a map pub type Values<'a, V> = - iter::Map<'static, (uint, &'a V), &'a V, Entries<'a, V>>; + iter::Map<(uint, &'a V), &'a V, Entries<'a, V>, fn((uint, &'a V)) -> &'a V>; /// Iterator over the key-value pairs of a map, the iterator consumes the map -pub type MoveItems<V> = - FilterMap<'static, (uint, Option<V>), (uint, V), Enumerate<vec::MoveItems<Option<V>>>>; +pub type MoveItems<V> = FilterMap< + (uint, Option<V>), + (uint, V), + Enumerate<vec::MoveItems<Option<V>>>, + fn((uint, Option<V>)) -> Option<(uint, V)>>; #[cfg(test)] mod test_map { 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; diff --git a/src/libcoretest/finally.rs b/src/libcoretest/finally.rs index 032f5f71941..2d77c1bc097 100644 --- a/src/libcoretest/finally.rs +++ b/src/libcoretest/finally.rs @@ -45,7 +45,7 @@ fn test_fail() { #[test] fn test_retval() { - let mut closure: || -> int = || 10; + let mut closure = |&mut:| 10i; let i = closure.finally(|| { }); assert_eq!(i, 10); } diff --git a/src/libcoretest/iter.rs b/src/libcoretest/iter.rs index d046faa82d4..acc2eab60e7 100644 --- a/src/libcoretest/iter.rs +++ b/src/libcoretest/iter.rs @@ -221,7 +221,7 @@ fn test_iterator_flat_map() { #[test] fn test_inspect() { let xs = [1u, 2, 3, 4]; - let mut n = 0; + let mut n = 0u; let ys = xs.iter() .map(|&x| x) diff --git a/src/libcoretest/lib.rs b/src/libcoretest/lib.rs index 5f31ed35f1b..089a2cc880e 100644 --- a/src/libcoretest/lib.rs +++ b/src/libcoretest/lib.rs @@ -8,6 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. #![feature(globs, unsafe_destructor, macro_rules, slicing_syntax)] +#![feature(unboxed_closures)] extern crate core; extern crate test; diff --git a/src/libcoretest/str.rs b/src/libcoretest/str.rs index 9574aeb3762..763fcccdbfd 100644 --- a/src/libcoretest/str.rs +++ b/src/libcoretest/str.rs @@ -54,7 +54,7 @@ fn test_rsplitn_char_iterator() { split.reverse(); assert_eq!(split, vec!["\nMäry häd ä", "little", "lämb\nLittle", "lämb\n"]); - let mut split: Vec<&str> = data.rsplitn(3, |c: char| c == ' ').collect(); + let mut split: Vec<&str> = data.rsplitn(3, |&: c: char| c == ' ').collect(); split.reverse(); assert_eq!(split, vec!["\nMäry häd ä", "little", "lämb\nLittle", "lämb\n"]); @@ -63,7 +63,7 @@ fn test_rsplitn_char_iterator() { split.reverse(); assert_eq!(split, vec!["\nMäry häd ", " little l", "mb\nLittle l", "mb\n"]); - let mut split: Vec<&str> = data.rsplitn(3, |c: char| c == 'ä').collect(); + let mut split: Vec<&str> = data.rsplitn(3, |&: c: char| c == 'ä').collect(); split.reverse(); assert_eq!(split, vec!["\nMäry häd ", " little l", "mb\nLittle l", "mb\n"]); } @@ -79,10 +79,10 @@ fn test_split_char_iterator() { rsplit.reverse(); assert_eq!(rsplit, vec!["\nMäry", "häd", "ä", "little", "lämb\nLittle", "lämb\n"]); - let split: Vec<&str> = data.split(|c: char| c == ' ').collect(); + let split: Vec<&str> = data.split(|&: c: char| c == ' ').collect(); assert_eq!( split, vec!["\nMäry", "häd", "ä", "little", "lämb\nLittle", "lämb\n"]); - let mut rsplit: Vec<&str> = data.split(|c: char| c == ' ').rev().collect(); + let mut rsplit: Vec<&str> = data.split(|&: c: char| c == ' ').rev().collect(); rsplit.reverse(); assert_eq!(rsplit, vec!["\nMäry", "häd", "ä", "little", "lämb\nLittle", "lämb\n"]); @@ -94,10 +94,10 @@ fn test_split_char_iterator() { rsplit.reverse(); assert_eq!(rsplit, vec!["\nM", "ry h", "d ", " little l", "mb\nLittle l", "mb\n"]); - let split: Vec<&str> = data.split(|c: char| c == 'ä').collect(); + let split: Vec<&str> = data.split(|&: c: char| c == 'ä').collect(); assert_eq!( split, vec!["\nM", "ry h", "d ", " little l", "mb\nLittle l", "mb\n"]); - let mut rsplit: Vec<&str> = data.split(|c: char| c == 'ä').rev().collect(); + let mut rsplit: Vec<&str> = data.split(|&: c: char| c == 'ä').rev().collect(); rsplit.reverse(); assert_eq!(rsplit, vec!["\nM", "ry h", "d ", " little l", "mb\nLittle l", "mb\n"]); } diff --git a/src/libgetopts/lib.rs b/src/libgetopts/lib.rs index a47fab124c3..79c435f01e4 100644 --- a/src/libgetopts/lib.rs +++ b/src/libgetopts/lib.rs @@ -87,6 +87,7 @@ html_playground_url = "http://play.rust-lang.org/")] #![feature(globs, phase)] #![feature(import_shadowing)] +#![feature(unboxed_closures)] #![deny(missing_docs)] #[cfg(test)] #[phase(plugin, link)] extern crate log; @@ -867,8 +868,9 @@ impl Copy for LengthLimit {} /// /// Panics during iteration if the string contains a non-whitespace /// sequence longer than the limit. -fn each_split_within<'a>(ss: &'a str, lim: uint, it: |&'a str| -> bool) - -> bool { +fn each_split_within<F>(ss: &str, lim: uint, mut it: F) -> bool where + F: FnMut(&str) -> bool +{ // Just for fun, let's write this as a state machine: let mut slice_start = 0; diff --git a/src/libgraphviz/lib.rs b/src/libgraphviz/lib.rs index c1c397db213..8ebb3ae365c 100644 --- a/src/libgraphviz/lib.rs +++ b/src/libgraphviz/lib.rs @@ -269,6 +269,7 @@ html_favicon_url = "http://www.rust-lang.org/favicon.ico", html_root_url = "http://doc.rust-lang.org/nightly/")] #![feature(globs, slicing_syntax)] +#![feature(unboxed_closures)] pub use self::LabelText::*; @@ -420,7 +421,7 @@ pub trait Labeller<'a,N,E> { } impl<'a> LabelText<'a> { - fn escape_char(c: char, f: |char|) { + fn escape_char<F>(c: char, mut f: F) where F: FnMut(char) { match c { // not escaping \\, since Graphviz escString needs to // interpret backslashes; see EscStr above. diff --git a/src/libgraphviz/maybe_owned_vec.rs b/src/libgraphviz/maybe_owned_vec.rs index 05932db6632..7ebf9b63352 100644 --- a/src/libgraphviz/maybe_owned_vec.rs +++ b/src/libgraphviz/maybe_owned_vec.rs @@ -142,7 +142,7 @@ impl<'a,T:Clone> CloneSliceAllocPrelude<T> for MaybeOwnedVector<'a,T> { self.as_slice().to_vec() } - fn partitioned(&self, f: |&T| -> bool) -> (Vec<T>, Vec<T>) { + fn partitioned<F>(&self, f: F) -> (Vec<T>, Vec<T>) where F: FnMut(&T) -> bool { self.as_slice().partitioned(f) } diff --git a/src/librand/distributions/mod.rs b/src/librand/distributions/mod.rs index 0fa989bf0b2..a44197c9859 100644 --- a/src/librand/distributions/mod.rs +++ b/src/librand/distributions/mod.rs @@ -208,14 +208,14 @@ mod ziggurat_tables; // the perf improvement (25-50%) is definitely worth the extra code // size from force-inlining. #[inline(always)] -fn ziggurat<R:Rng>( +fn ziggurat<R: Rng, P, Z>( rng: &mut R, symmetric: bool, x_tab: ziggurat_tables::ZigTable, f_tab: ziggurat_tables::ZigTable, - pdf: |f64|: 'static -> f64, - zero_case: |&mut R, f64|: 'static -> f64) - -> f64 { + mut pdf: P, + mut zero_case: Z) + -> f64 where P: FnMut(f64) -> f64, Z: FnMut(&mut R, f64) -> f64 { static SCALE: f64 = (1u64 << 53) as f64; loop { // reimplement the f64 generation as an optimisation suggested diff --git a/src/librand/lib.rs b/src/librand/lib.rs index d357f247f1b..4fba3707703 100644 --- a/src/librand/lib.rs +++ b/src/librand/lib.rs @@ -24,6 +24,7 @@ html_playground_url = "http://play.rust-lang.org/")] #![feature(macro_rules, phase, globs)] +#![feature(unboxed_closures)] #![no_std] #![experimental] diff --git a/src/librbml/lib.rs b/src/librbml/lib.rs index 426a987d25d..28d5e1812f0 100644 --- a/src/librbml/lib.rs +++ b/src/librbml/lib.rs @@ -25,6 +25,7 @@ html_playground_url = "http://play.rust-lang.org/")] #![allow(unknown_features)] #![feature(macro_rules, phase, slicing_syntax, globs)] +#![feature(unboxed_closures)] #![allow(missing_docs)] extern crate serialize; @@ -259,7 +260,9 @@ pub mod reader { } } - pub fn docs<'a>(d: Doc<'a>, it: |uint, Doc<'a>| -> bool) -> bool { + pub fn docs<F>(d: Doc, mut it: F) -> bool where + F: FnMut(uint, Doc) -> bool, + { let mut pos = d.start; while pos < d.end { let elt_tag = try_or!(vuint_at(d.data, pos), false); @@ -273,7 +276,9 @@ pub mod reader { return true; } - pub fn tagged_docs<'a>(d: Doc<'a>, tg: uint, it: |Doc<'a>| -> bool) -> bool { + pub fn tagged_docs<F>(d: Doc, tg: uint, mut it: F) -> bool where + F: FnMut(Doc) -> bool, + { let mut pos = d.start; while pos < d.end { let elt_tag = try_or!(vuint_at(d.data, pos), false); @@ -290,7 +295,9 @@ pub mod reader { return true; } - pub fn with_doc_data<'a, T>(d: Doc<'a>, f: |x: &'a [u8]| -> T) -> T { + pub fn with_doc_data<T, F>(d: Doc, f: F) -> T where + F: FnOnce(&[u8]) -> T, + { f(d.data[d.start..d.end]) } @@ -378,8 +385,9 @@ pub mod reader { Ok(r_doc) } - fn push_doc<T>(&mut self, exp_tag: EbmlEncoderTag, - f: |&mut Decoder<'doc>| -> DecodeResult<T>) -> DecodeResult<T> { + fn push_doc<T, F>(&mut self, exp_tag: EbmlEncoderTag, f: F) -> DecodeResult<T> where + F: FnOnce(&mut Decoder<'doc>) -> DecodeResult<T>, + { let d = try!(self.next_doc(exp_tag)); let old_parent = self.parent; let old_pos = self.pos; @@ -397,8 +405,9 @@ pub mod reader { Ok(r as uint) } - pub fn read_opaque<R>(&mut self, - op: |&mut Decoder<'doc>, Doc| -> DecodeResult<R>) -> DecodeResult<R> { + pub fn read_opaque<R, F>(&mut self, op: F) -> DecodeResult<R> where + F: FnOnce(&mut Decoder, Doc) -> DecodeResult<R>, + { let doc = try!(self.next_doc(EsOpaque)); let (old_parent, old_pos) = (self.parent, self.pos); @@ -471,9 +480,9 @@ pub mod reader { } // Compound types: - fn read_enum<T>(&mut self, - name: &str, - f: |&mut Decoder<'doc>| -> DecodeResult<T>) -> DecodeResult<T> { + fn read_enum<T, F>(&mut self, name: &str, f: F) -> DecodeResult<T> where + F: FnOnce(&mut Decoder<'doc>) -> DecodeResult<T>, + { debug!("read_enum({})", name); try!(self._check_label(name)); @@ -490,10 +499,9 @@ pub mod reader { Ok(result) } - fn read_enum_variant<T>(&mut self, - _: &[&str], - f: |&mut Decoder<'doc>, uint| -> DecodeResult<T>) - -> DecodeResult<T> { + fn read_enum_variant<T, F>(&mut self, _: &[&str], f: F) -> DecodeResult<T> where + F: FnOnce(&mut Decoder<'doc>, uint) -> DecodeResult<T>, + { debug!("read_enum_variant()"); let idx = try!(self._next_uint(EsEnumVid)); debug!(" idx={}", idx); @@ -511,17 +519,16 @@ pub mod reader { Ok(result) } - fn read_enum_variant_arg<T>(&mut self, - idx: uint, - f: |&mut Decoder<'doc>| -> DecodeResult<T>) -> DecodeResult<T> { + fn read_enum_variant_arg<T, F>(&mut self, idx: uint, f: F) -> DecodeResult<T> where + F: FnOnce(&mut Decoder<'doc>) -> DecodeResult<T>, + { debug!("read_enum_variant_arg(idx={})", idx); f(self) } - fn read_enum_struct_variant<T>(&mut self, - _: &[&str], - f: |&mut Decoder<'doc>, uint| -> DecodeResult<T>) - -> DecodeResult<T> { + fn read_enum_struct_variant<T, F>(&mut self, _: &[&str], f: F) -> DecodeResult<T> where + F: FnOnce(&mut Decoder<'doc>, uint) -> DecodeResult<T>, + { debug!("read_enum_struct_variant()"); let idx = try!(self._next_uint(EsEnumVid)); debug!(" idx={}", idx); @@ -539,39 +546,37 @@ pub mod reader { Ok(result) } - fn read_enum_struct_variant_field<T>(&mut self, - name: &str, - idx: uint, - f: |&mut Decoder<'doc>| -> DecodeResult<T>) - -> DecodeResult<T> { - debug!("read_enum_struct_variant_arg(name={}, idx={})", name, idx); + fn read_enum_struct_variant_field<T, F>(&mut self, + name: &str, + idx: uint, + f: F) + -> DecodeResult<T> where + F: FnOnce(&mut Decoder<'doc>) -> DecodeResult<T>, + { + debug!("read_enum_struct_variant_arg(name={}, idx={})", name, idx); f(self) } - fn read_struct<T>(&mut self, - name: &str, - _: uint, - f: |&mut Decoder<'doc>| -> DecodeResult<T>) - -> DecodeResult<T> { + fn read_struct<T, F>(&mut self, name: &str, _: uint, f: F) -> DecodeResult<T> where + F: FnOnce(&mut Decoder<'doc>) -> DecodeResult<T>, + { debug!("read_struct(name={})", name); f(self) } - fn read_struct_field<T>(&mut self, - name: &str, - idx: uint, - f: |&mut Decoder<'doc>| -> DecodeResult<T>) - -> DecodeResult<T> { + fn read_struct_field<T, F>(&mut self, name: &str, idx: uint, f: F) -> DecodeResult<T> where + F: FnOnce(&mut Decoder<'doc>) -> DecodeResult<T>, + { debug!("read_struct_field(name={}, idx={})", name, idx); try!(self._check_label(name)); f(self) } - fn read_tuple<T>(&mut self, - tuple_len: uint, - f: |&mut Decoder<'doc>| -> DecodeResult<T>) -> DecodeResult<T> { + fn read_tuple<T, F>(&mut self, tuple_len: uint, f: F) -> DecodeResult<T> where + F: FnOnce(&mut Decoder<'doc>) -> DecodeResult<T>, + { debug!("read_tuple()"); - self.read_seq(|d, len| { + self.read_seq(move |d, len| { if len == tuple_len { f(d) } else { @@ -581,34 +586,36 @@ pub mod reader { }) } - fn read_tuple_arg<T>(&mut self, idx: uint, f: |&mut Decoder<'doc>| -> DecodeResult<T>) - -> DecodeResult<T> { + fn read_tuple_arg<T, F>(&mut self, idx: uint, f: F) -> DecodeResult<T> where + F: FnOnce(&mut Decoder<'doc>) -> DecodeResult<T>, + { debug!("read_tuple_arg(idx={})", idx); self.read_seq_elt(idx, f) } - fn read_tuple_struct<T>(&mut self, - name: &str, - len: uint, - f: |&mut Decoder<'doc>| -> DecodeResult<T>) - -> DecodeResult<T> { + fn read_tuple_struct<T, F>(&mut self, name: &str, len: uint, f: F) -> DecodeResult<T> where + F: FnOnce(&mut Decoder<'doc>) -> DecodeResult<T>, + { debug!("read_tuple_struct(name={})", name); self.read_tuple(len, f) } - fn read_tuple_struct_arg<T>(&mut self, - idx: uint, - f: |&mut Decoder<'doc>| -> DecodeResult<T>) - -> DecodeResult<T> { + fn read_tuple_struct_arg<T, F>(&mut self, + idx: uint, + f: F) + -> DecodeResult<T> where + F: FnOnce(&mut Decoder<'doc>) -> DecodeResult<T>, + { debug!("read_tuple_struct_arg(idx={})", idx); self.read_tuple_arg(idx, f) } - fn read_option<T>(&mut self, - f: |&mut Decoder<'doc>, bool| -> DecodeResult<T>) -> DecodeResult<T> { + fn read_option<T, F>(&mut self, f: F) -> DecodeResult<T> where + F: FnOnce(&mut Decoder<'doc>, bool) -> DecodeResult<T>, + { debug!("read_option()"); - self.read_enum("Option", |this| { - this.read_enum_variant(&["None", "Some"], |this, idx| { + self.read_enum("Option", move |this| { + this.read_enum_variant(&["None", "Some"], move |this, idx| { match idx { 0 => f(this, false), 1 => f(this, true), @@ -620,40 +627,45 @@ pub mod reader { }) } - fn read_seq<T>(&mut self, - f: |&mut Decoder<'doc>, uint| -> DecodeResult<T>) -> DecodeResult<T> { + fn read_seq<T, F>(&mut self, f: F) -> DecodeResult<T> where + F: FnOnce(&mut Decoder<'doc>, uint) -> DecodeResult<T>, + { debug!("read_seq()"); - self.push_doc(EsVec, |d| { + self.push_doc(EsVec, move |d| { let len = try!(d._next_uint(EsVecLen)); debug!(" len={}", len); f(d, len) }) } - fn read_seq_elt<T>(&mut self, idx: uint, f: |&mut Decoder<'doc>| -> DecodeResult<T>) - -> DecodeResult<T> { + fn read_seq_elt<T, F>(&mut self, idx: uint, f: F) -> DecodeResult<T> where + F: FnOnce(&mut Decoder<'doc>) -> DecodeResult<T>, + { debug!("read_seq_elt(idx={})", idx); self.push_doc(EsVecElt, f) } - fn read_map<T>(&mut self, - f: |&mut Decoder<'doc>, uint| -> DecodeResult<T>) -> DecodeResult<T> { + fn read_map<T, F>(&mut self, f: F) -> DecodeResult<T> where + F: FnOnce(&mut Decoder<'doc>, uint) -> DecodeResult<T>, + { debug!("read_map()"); - self.push_doc(EsMap, |d| { + self.push_doc(EsMap, move |d| { let len = try!(d._next_uint(EsMapLen)); debug!(" len={}", len); f(d, len) }) } - fn read_map_elt_key<T>(&mut self, idx: uint, f: |&mut Decoder<'doc>| -> DecodeResult<T>) - -> DecodeResult<T> { + fn read_map_elt_key<T, F>(&mut self, idx: uint, f: F) -> DecodeResult<T> where + F: FnOnce(&mut Decoder<'doc>) -> DecodeResult<T>, + { debug!("read_map_elt_key(idx={})", idx); self.push_doc(EsMapKey, f) } - fn read_map_elt_val<T>(&mut self, idx: uint, f: |&mut Decoder<'doc>| -> DecodeResult<T>) - -> DecodeResult<T> { + fn read_map_elt_val<T, F>(&mut self, idx: uint, f: F) -> DecodeResult<T> where + F: FnOnce(&mut Decoder<'doc>) -> DecodeResult<T>, + { debug!("read_map_elt_val(idx={})", idx); self.push_doc(EsMapVal, f) } @@ -756,7 +768,9 @@ pub mod writer { Ok(r) } - pub fn wr_tag(&mut self, tag_id: uint, blk: || -> EncodeResult) -> EncodeResult { + pub fn wr_tag<F>(&mut self, tag_id: uint, blk: F) -> EncodeResult where + F: FnOnce() -> EncodeResult, + { try!(self.start_tag(tag_id)); try!(blk()); self.end_tag() @@ -852,7 +866,9 @@ pub mod writer { else { Ok(()) } } - pub fn emit_opaque(&mut self, f: |&mut Encoder<W>| -> EncodeResult) -> EncodeResult { + pub fn emit_opaque<F>(&mut self, f: F) -> EncodeResult where + F: FnOnce(&mut Encoder<W>) -> EncodeResult, + { try!(self.start_tag(EsOpaque as uint)); try!(f(self)); self.end_tag() @@ -916,102 +932,106 @@ pub mod writer { self.wr_tagged_str(EsStr as uint, v) } - fn emit_enum(&mut self, - name: &str, - f: |&mut Encoder<'a, W>| -> EncodeResult) -> EncodeResult { + fn emit_enum<F>(&mut self, name: &str, f: F) -> EncodeResult where + F: FnOnce(&mut Encoder<'a, W>) -> EncodeResult, + { try!(self._emit_label(name)); try!(self.start_tag(EsEnum as uint)); try!(f(self)); self.end_tag() } - fn emit_enum_variant(&mut self, - _: &str, - v_id: uint, - _: uint, - f: |&mut Encoder<'a, W>| -> EncodeResult) -> EncodeResult { + fn emit_enum_variant<F>(&mut self, + _: &str, + v_id: uint, + _: uint, + f: F) -> EncodeResult where + F: FnOnce(&mut Encoder<'a, W>) -> EncodeResult, + { try!(self._emit_tagged_uint(EsEnumVid, v_id)); try!(self.start_tag(EsEnumBody as uint)); try!(f(self)); self.end_tag() } - fn emit_enum_variant_arg(&mut self, - _: uint, - f: |&mut Encoder<'a, W>| -> EncodeResult) -> EncodeResult { + fn emit_enum_variant_arg<F>(&mut self, _: uint, f: F) -> EncodeResult where + F: FnOnce(&mut Encoder<'a, W>) -> EncodeResult, + { f(self) } - fn emit_enum_struct_variant(&mut self, - v_name: &str, - v_id: uint, - cnt: uint, - f: |&mut Encoder<'a, W>| -> EncodeResult) -> EncodeResult { + fn emit_enum_struct_variant<F>(&mut self, + v_name: &str, + v_id: uint, + cnt: uint, + f: F) -> EncodeResult where + F: FnOnce(&mut Encoder<'a, W>) -> EncodeResult, + { self.emit_enum_variant(v_name, v_id, cnt, f) } - fn emit_enum_struct_variant_field(&mut self, - _: &str, - idx: uint, - f: |&mut Encoder<'a, W>| -> EncodeResult) - -> EncodeResult { + fn emit_enum_struct_variant_field<F>(&mut self, + _: &str, + idx: uint, + f: F) -> EncodeResult where + F: FnOnce(&mut Encoder<'a, W>) -> EncodeResult, + { self.emit_enum_variant_arg(idx, f) } - fn emit_struct(&mut self, - _: &str, - _len: uint, - f: |&mut Encoder<'a, W>| -> EncodeResult) -> EncodeResult { + fn emit_struct<F>(&mut self, _: &str, _len: uint, f: F) -> EncodeResult where + F: FnOnce(&mut Encoder<'a, W>) -> EncodeResult, + { f(self) } - fn emit_struct_field(&mut self, - name: &str, - _: uint, - f: |&mut Encoder<'a, W>| -> EncodeResult) -> EncodeResult { + fn emit_struct_field<F>(&mut self, name: &str, _: uint, f: F) -> EncodeResult where + F: FnOnce(&mut Encoder<'a, W>) -> EncodeResult, + { try!(self._emit_label(name)); f(self) } - fn emit_tuple(&mut self, - len: uint, - f: |&mut Encoder<'a, W>| -> EncodeResult) -> EncodeResult { + fn emit_tuple<F>(&mut self, len: uint, f: F) -> EncodeResult where + F: FnOnce(&mut Encoder<'a, W>) -> EncodeResult, + { self.emit_seq(len, f) } - fn emit_tuple_arg(&mut self, - idx: uint, - f: |&mut Encoder<'a, W>| -> EncodeResult) -> EncodeResult { + fn emit_tuple_arg<F>(&mut self, idx: uint, f: F) -> EncodeResult where + F: FnOnce(&mut Encoder<'a, W>) -> EncodeResult, + { self.emit_seq_elt(idx, f) } - fn emit_tuple_struct(&mut self, - _: &str, - len: uint, - f: |&mut Encoder<'a, W>| -> EncodeResult) -> EncodeResult { + fn emit_tuple_struct<F>(&mut self, _: &str, len: uint, f: F) -> EncodeResult where + F: FnOnce(&mut Encoder<'a, W>) -> EncodeResult, + { self.emit_seq(len, f) } - fn emit_tuple_struct_arg(&mut self, - idx: uint, - f: |&mut Encoder<'a, W>| -> EncodeResult) -> EncodeResult { + fn emit_tuple_struct_arg<F>(&mut self, idx: uint, f: F) -> EncodeResult where + F: FnOnce(&mut Encoder<'a, W>) -> EncodeResult, + { self.emit_seq_elt(idx, f) } - fn emit_option(&mut self, - f: |&mut Encoder<'a, W>| -> EncodeResult) -> EncodeResult { + fn emit_option<F>(&mut self, f: F) -> EncodeResult where + F: FnOnce(&mut Encoder<'a, W>) -> EncodeResult, + { self.emit_enum("Option", f) } fn emit_option_none(&mut self) -> EncodeResult { self.emit_enum_variant("None", 0, 0, |_| Ok(())) } - fn emit_option_some(&mut self, - f: |&mut Encoder<'a, W>| -> EncodeResult) -> EncodeResult { + fn emit_option_some<F>(&mut self, f: F) -> EncodeResult where + F: FnOnce(&mut Encoder<'a, W>) -> EncodeResult, + { self.emit_enum_variant("Some", 1, 1, f) } - fn emit_seq(&mut self, - len: uint, - f: |&mut Encoder<'a, W>| -> EncodeResult) -> EncodeResult { + fn emit_seq<F>(&mut self, len: uint, f: F) -> EncodeResult where + F: FnOnce(&mut Encoder<'a, W>) -> EncodeResult, + { try!(self.start_tag(EsVec as uint)); try!(self._emit_tagged_uint(EsVecLen, len)); @@ -1019,18 +1039,18 @@ pub mod writer { self.end_tag() } - fn emit_seq_elt(&mut self, - _idx: uint, - f: |&mut Encoder<'a, W>| -> EncodeResult) -> EncodeResult { + fn emit_seq_elt<F>(&mut self, _idx: uint, f: F) -> EncodeResult where + F: FnOnce(&mut Encoder<'a, W>) -> EncodeResult, + { try!(self.start_tag(EsVecElt as uint)); try!(f(self)); self.end_tag() } - fn emit_map(&mut self, - len: uint, - f: |&mut Encoder<'a, W>| -> EncodeResult) -> EncodeResult { + fn emit_map<F>(&mut self, len: uint, f: F) -> EncodeResult where + F: FnOnce(&mut Encoder<'a, W>) -> EncodeResult, + { try!(self.start_tag(EsMap as uint)); try!(self._emit_tagged_uint(EsMapLen, len)); @@ -1038,18 +1058,18 @@ pub mod writer { self.end_tag() } - fn emit_map_elt_key(&mut self, - _idx: uint, - f: |&mut Encoder<'a, W>| -> EncodeResult) -> EncodeResult { + fn emit_map_elt_key<F>(&mut self, _idx: uint, mut f: F) -> EncodeResult where + F: FnMut(&mut Encoder<'a, W>) -> EncodeResult, + { try!(self.start_tag(EsMapKey as uint)); try!(f(self)); self.end_tag() } - fn emit_map_elt_val(&mut self, - _idx: uint, - f: |&mut Encoder<'a, W>| -> EncodeResult) -> EncodeResult { + fn emit_map_elt_val<F>(&mut self, _idx: uint, f: F) -> EncodeResult where + F: FnOnce(&mut Encoder<'a, W>) -> EncodeResult, + { try!(self.start_tag(EsMapVal as uint)); try!(f(self)); self.end_tag() diff --git a/src/libregex/lib.rs b/src/libregex/lib.rs index b35c3879783..05f853a851e 100644 --- a/src/libregex/lib.rs +++ b/src/libregex/lib.rs @@ -370,6 +370,7 @@ #![allow(unknown_features)] #![feature(macro_rules, phase, slicing_syntax, globs)] +#![feature(unboxed_closures)] #![deny(missing_docs)] #[cfg(test)] diff --git a/src/libregex/parse.rs b/src/libregex/parse.rs index 55e533aadee..ccbd53c4f2a 100644 --- a/src/libregex/parse.rs +++ b/src/libregex/parse.rs @@ -838,8 +838,9 @@ impl<'a> Parser<'a> { // Otherwise, an error will be returned. // Generally, `allow_start` is only true when you're *not* expecting an // opening parenthesis. - fn pos_last(&self, allow_start: bool, pred: |&BuildAst| -> bool) - -> Result<uint, Error> { + fn pos_last<P>(&self, allow_start: bool, pred: P) -> Result<uint, Error> where + P: FnMut(&BuildAst) -> bool, + { let from = match self.stack.iter().rev().position(pred) { Some(i) => i, None => { @@ -887,8 +888,9 @@ impl<'a> Parser<'a> { // build_from combines all AST elements starting at 'from' in the // parser's stack using 'mk' to combine them. If any such element is not an // AST then it is popped off the stack and ignored. - fn build_from(&mut self, from: uint, mk: |Ast, Ast| -> Ast) - -> Result<Ast, Error> { + fn build_from<F>(&mut self, from: uint, mut mk: F) -> Result<Ast, Error> where + F: FnMut(Ast, Ast) -> Ast, + { if from >= self.stack.len() { return self.err("Empty group or alternate not allowed.") } diff --git a/src/libregex/re.rs b/src/libregex/re.rs index 2a1fda06431..1504e191985 100644 --- a/src/libregex/re.rs +++ b/src/libregex/re.rs @@ -429,10 +429,11 @@ impl Regex { /// /// ```rust /// # #![feature(phase)] + /// # #![feature(unboxed_closures)] /// # extern crate regex; #[phase(plugin)] extern crate regex_macros; /// # use regex::Captures; fn main() { /// let re = regex!(r"([^,\s]+),\s+(\S+)"); - /// let result = re.replace("Springsteen, Bruce", |caps: &Captures| { + /// let result = re.replace("Springsteen, Bruce", |&: caps: &Captures| { /// format!("{} {}", caps.at(2), caps.at(1)) /// }); /// assert_eq!(result.as_slice(), "Bruce Springsteen"); @@ -585,7 +586,7 @@ impl<'t> Replacer for &'t str { } } -impl<'t> Replacer for |&Captures|: 't -> String { +impl<F> Replacer for F where F: FnMut(&Captures) -> String { fn reg_replace<'a>(&'a mut self, caps: &Captures) -> CowString<'a> { (*self)(caps).into_cow() } @@ -767,7 +768,7 @@ impl<'t> Captures<'t> { // How evil can you get? // FIXME: Don't use regexes for this. It's completely unnecessary. let re = Regex::new(r"(^|[^$]|\b)\$(\w+)").unwrap(); - let text = re.replace_all(text, |refs: &Captures| -> String { + let text = re.replace_all(text, |&mut: refs: &Captures| -> String { let (pre, name) = (refs.at(1), refs.at(2)); format!("{}{}", pre, match from_str::<uint>(name.as_slice()) { diff --git a/src/libregex_macros/lib.rs b/src/libregex_macros/lib.rs index 4df88197743..c1e8677fa8f 100644 --- a/src/libregex_macros/lib.rs +++ b/src/libregex_macros/lib.rs @@ -19,6 +19,7 @@ html_root_url = "http://doc.rust-lang.org/nightly/")] #![feature(plugin_registrar, quote)] +#![feature(unboxed_closures)] extern crate regex; extern crate syntax; @@ -601,9 +602,10 @@ fn exec<'t>(which: ::regex::native::MatchKind, input: &'t str, // Converts `xs` to a `[x1, x2, .., xN]` expression by calling `to_expr` // on each element in `xs`. - fn vec_expr<T, It: Iterator<T>>(&self, xs: It, - to_expr: |&ExtCtxt, T| -> P<ast::Expr>) - -> P<ast::Expr> { + fn vec_expr<T, It, F>(&self, xs: It, mut to_expr: F) -> P<ast::Expr> where + It: Iterator<T>, + F: FnMut(&ExtCtxt, T) -> P<ast::Expr>, + { let exprs = xs.map(|x| to_expr(self.cx, x)).collect(); self.cx.expr_vec(self.sp, exprs) } diff --git a/src/librustc/lib.rs b/src/librustc/lib.rs index 51cb7e193ff..404c7edeb88 100644 --- a/src/librustc/lib.rs +++ b/src/librustc/lib.rs @@ -25,6 +25,7 @@ #![feature(default_type_params, globs, import_shadowing, macro_rules, phase, quote)] #![feature(slicing_syntax, unsafe_destructor)] #![feature(rustc_diagnostic_macros)] +#![feature(unboxed_closures)] extern crate arena; extern crate flate; diff --git a/src/librustc/lint/context.rs b/src/librustc/lint/context.rs index 153a00e5617..9f9e266c6c7 100644 --- a/src/librustc/lint/context.rs +++ b/src/librustc/lint/context.rs @@ -464,9 +464,11 @@ impl<'a, 'tcx> Context<'a, 'tcx> { /// Merge the lints specified by any lint attributes into the /// current lint context, call the provided function, then reset the /// lints in effect to their previous state. - fn with_lint_attrs(&mut self, - attrs: &[ast::Attribute], - f: |&mut Context|) { + fn with_lint_attrs<F>(&mut self, + attrs: &[ast::Attribute], + f: F) where + F: FnOnce(&mut Context), + { // Parse all of the lint attributes, and then add them all to the // current dictionary of lint information. Along the way, keep a history // of what we changed so we can roll everything back after invoking the @@ -528,7 +530,9 @@ impl<'a, 'tcx> Context<'a, 'tcx> { } } - fn visit_ids(&mut self, f: |&mut ast_util::IdVisitor<Context>|) { + fn visit_ids<F>(&mut self, f: F) where + F: FnOnce(&mut ast_util::IdVisitor<Context>) + { let mut v = ast_util::IdVisitor { operation: self, pass_through_items: false, diff --git a/src/librustc/metadata/csearch.rs b/src/librustc/metadata/csearch.rs index 7ce9893afc8..4cbb1babf9a 100644 --- a/src/librustc/metadata/csearch.rs +++ b/src/librustc/metadata/csearch.rs @@ -47,20 +47,22 @@ pub fn get_symbol(cstore: &cstore::CStore, def: ast::DefId) -> String { } /// Iterates over all the language items in the given crate. -pub fn each_lang_item(cstore: &cstore::CStore, - cnum: ast::CrateNum, - f: |ast::NodeId, uint| -> bool) - -> bool { +pub fn each_lang_item<F>(cstore: &cstore::CStore, + cnum: ast::CrateNum, + f: F) + -> bool where + F: FnMut(ast::NodeId, uint) -> bool, +{ let crate_data = cstore.get_crate_data(cnum); decoder::each_lang_item(&*crate_data, f) } /// Iterates over each child of the given item. -pub fn each_child_of_item(cstore: &cstore::CStore, - def_id: ast::DefId, - callback: |decoder::DefLike, - ast::Name, - ast::Visibility|) { +pub fn each_child_of_item<F>(cstore: &cstore::CStore, + def_id: ast::DefId, + callback: F) where + F: FnMut(decoder::DefLike, ast::Name, ast::Visibility), +{ let crate_data = cstore.get_crate_data(def_id.krate); let get_crate_data: decoder::GetCrateDataCb = |cnum| { cstore.get_crate_data(cnum) @@ -73,11 +75,11 @@ pub fn each_child_of_item(cstore: &cstore::CStore, } /// Iterates over each top-level crate item. -pub fn each_top_level_item_of_crate(cstore: &cstore::CStore, - cnum: ast::CrateNum, - callback: |decoder::DefLike, - ast::Name, - ast::Visibility|) { +pub fn each_top_level_item_of_crate<F>(cstore: &cstore::CStore, + cnum: ast::CrateNum, + callback: F) where + F: FnMut(decoder::DefLike, ast::Name, ast::Visibility), +{ let crate_data = cstore.get_crate_data(cnum); let get_crate_data: decoder::GetCrateDataCb = |cnum| { cstore.get_crate_data(cnum) @@ -195,9 +197,11 @@ pub fn get_methods_if_impl(cstore: &cstore::CStore, decoder::get_methods_if_impl(cstore.intr.clone(), &*cdata, def.node) } -pub fn get_item_attrs(cstore: &cstore::CStore, - def_id: ast::DefId, - f: |Vec<ast::Attribute>|) { +pub fn get_item_attrs<F>(cstore: &cstore::CStore, + def_id: ast::DefId, + f: F) where + F: FnOnce(Vec<ast::Attribute>), +{ let cdata = cstore.get_crate_data(def_id.krate); decoder::get_item_attrs(&*cdata, def_id.node, f) } @@ -279,23 +283,29 @@ pub fn get_native_libraries(cstore: &cstore::CStore, crate_num: ast::CrateNum) decoder::get_native_libraries(&*cdata) } -pub fn each_impl(cstore: &cstore::CStore, - crate_num: ast::CrateNum, - callback: |ast::DefId|) { +pub fn each_impl<F>(cstore: &cstore::CStore, + crate_num: ast::CrateNum, + callback: F) where + F: FnMut(ast::DefId), +{ let cdata = cstore.get_crate_data(crate_num); decoder::each_impl(&*cdata, callback) } -pub fn each_implementation_for_type(cstore: &cstore::CStore, - def_id: ast::DefId, - callback: |ast::DefId|) { +pub fn each_implementation_for_type<F>(cstore: &cstore::CStore, + def_id: ast::DefId, + callback: F) where + F: FnMut(ast::DefId), +{ let cdata = cstore.get_crate_data(def_id.krate); decoder::each_implementation_for_type(&*cdata, def_id.node, callback) } -pub fn each_implementation_for_trait(cstore: &cstore::CStore, - def_id: ast::DefId, - callback: |ast::DefId|) { +pub fn each_implementation_for_trait<F>(cstore: &cstore::CStore, + def_id: ast::DefId, + callback: F) where + F: FnMut(ast::DefId), +{ let cdata = cstore.get_crate_data(def_id.krate); decoder::each_implementation_for_trait(&*cdata, def_id.node, callback) } diff --git a/src/librustc/metadata/cstore.rs b/src/librustc/metadata/cstore.rs index bb1c75b075c..c0642f29abc 100644 --- a/src/librustc/metadata/cstore.rs +++ b/src/librustc/metadata/cstore.rs @@ -113,16 +113,18 @@ impl CStore { self.metas.borrow_mut().insert(cnum, data); } - pub fn iter_crate_data(&self, i: |ast::CrateNum, &crate_metadata|) { + pub fn iter_crate_data<I>(&self, mut i: I) where + I: FnMut(ast::CrateNum, &crate_metadata), + { for (&k, v) in self.metas.borrow().iter() { i(k, &**v); } } /// Like `iter_crate_data`, but passes source paths (if available) as well. - pub fn iter_crate_data_origins(&self, i: |ast::CrateNum, - &crate_metadata, - Option<CrateSource>|) { + pub fn iter_crate_data_origins<I>(&self, mut i: I) where + I: FnMut(ast::CrateNum, &crate_metadata, Option<CrateSource>), + { for (&k, v) in self.metas.borrow().iter() { let origin = self.get_used_crate_source(k); origin.as_ref().map(|cs| { assert!(k == cs.cnum); }); diff --git a/src/librustc/metadata/decoder.rs b/src/librustc/metadata/decoder.rs index 898f5d2ef93..4e892f53186 100644 --- a/src/librustc/metadata/decoder.rs +++ b/src/librustc/metadata/decoder.rs @@ -60,8 +60,9 @@ pub type Cmd<'a> = &'a crate_metadata; // what crate that's in and give us a def_id that makes sense for the current // build. -fn lookup_hash<'a>(d: rbml::Doc<'a>, eq_fn: |&[u8]| -> bool, - hash: u64) -> Option<rbml::Doc<'a>> { +fn lookup_hash<'a, F>(d: rbml::Doc<'a>, mut eq_fn: F, hash: u64) -> Option<rbml::Doc<'a>> where + F: FnMut(&[u8]) -> bool, +{ let index = reader::get_doc(d, tag_index); let table = reader::get_doc(index, tag_index_table); let hash_pos = table.start + (hash % 256 * 4) as uint; @@ -212,7 +213,9 @@ fn get_provided_source(d: rbml::Doc, cdata: Cmd) -> Option<ast::DefId> { }) } -fn each_reexport(d: rbml::Doc, f: |rbml::Doc| -> bool) -> bool { +fn each_reexport<F>(d: rbml::Doc, f: F) -> bool where + F: FnMut(rbml::Doc) -> bool, +{ reader::tagged_docs(d, tag_items_data_item_reexport, f) } @@ -446,7 +449,9 @@ pub enum DefLike { impl Copy for DefLike {} /// Iterates over the language items in the given crate. -pub fn each_lang_item(cdata: Cmd, f: |ast::NodeId, uint| -> bool) -> bool { +pub fn each_lang_item<F>(cdata: Cmd, mut f: F) -> bool where + F: FnMut(ast::NodeId, uint) -> bool, +{ let root = rbml::Doc::new(cdata.data()); let lang_items = reader::get_doc(root, tag_lang_items); reader::tagged_docs(lang_items, tag_lang_items_item, |item_doc| { @@ -462,13 +467,13 @@ pub fn each_lang_item(cdata: Cmd, f: |ast::NodeId, uint| -> bool) -> bool { pub type GetCrateDataCb<'a> = |ast::CrateNum|: 'a -> Rc<crate_metadata>; -fn each_child_of_item_or_crate(intr: Rc<IdentInterner>, - cdata: Cmd, - item_doc: rbml::Doc, - get_crate_data: GetCrateDataCb, - callback: |DefLike, - ast::Name, - ast::Visibility|) { +fn each_child_of_item_or_crate<F>(intr: Rc<IdentInterner>, + cdata: Cmd, + item_doc: rbml::Doc, + get_crate_data: GetCrateDataCb, + mut callback: F) where + F: FnMut(DefLike, ast::Name, ast::Visibility), +{ // Iterate over all children. let _ = reader::tagged_docs(item_doc, tag_mod_child, |child_info_doc| { let child_def_id = reader::with_doc_data(child_info_doc, @@ -581,11 +586,13 @@ fn each_child_of_item_or_crate(intr: Rc<IdentInterner>, } /// Iterates over each child of the given item. -pub fn each_child_of_item(intr: Rc<IdentInterner>, - cdata: Cmd, - id: ast::NodeId, - get_crate_data: GetCrateDataCb, - callback: |DefLike, ast::Name, ast::Visibility|) { +pub fn each_child_of_item<F>(intr: Rc<IdentInterner>, + cdata: Cmd, + id: ast::NodeId, + get_crate_data: GetCrateDataCb, + callback: F) where + F: FnMut(DefLike, ast::Name, ast::Visibility), +{ // Find the item. let root_doc = rbml::Doc::new(cdata.data()); let items = reader::get_doc(root_doc, tag_items); @@ -602,12 +609,12 @@ pub fn each_child_of_item(intr: Rc<IdentInterner>, } /// Iterates over all the top-level crate items. -pub fn each_top_level_item_of_crate(intr: Rc<IdentInterner>, - cdata: Cmd, - get_crate_data: GetCrateDataCb, - callback: |DefLike, - ast::Name, - ast::Visibility|) { +pub fn each_top_level_item_of_crate<F>(intr: Rc<IdentInterner>, + cdata: Cmd, + get_crate_data: GetCrateDataCb, + callback: F) where + F: FnMut(DefLike, ast::Name, ast::Visibility), +{ let root_doc = rbml::Doc::new(cdata.data()); let misc_info_doc = reader::get_doc(root_doc, tag_misc_info); let crate_items_doc = reader::get_doc(misc_info_doc, @@ -980,9 +987,11 @@ pub fn get_tuple_struct_definition_if_ctor(cdata: Cmd, ret } -pub fn get_item_attrs(cdata: Cmd, - orig_node_id: ast::NodeId, - f: |Vec<ast::Attribute>|) { +pub fn get_item_attrs<F>(cdata: Cmd, + orig_node_id: ast::NodeId, + f: F) where + F: FnOnce(Vec<ast::Attribute>), +{ // The attributes for a tuple struct are attached to the definition, not the ctor; // we assume that someone passing in a tuple struct ctor is actually wanting to // look at the definition @@ -1222,7 +1231,9 @@ pub fn translate_def_id(cdata: Cmd, did: ast::DefId) -> ast::DefId { } } -pub fn each_impl(cdata: Cmd, callback: |ast::DefId|) { +pub fn each_impl<F>(cdata: Cmd, mut callback: F) where + F: FnMut(ast::DefId), +{ let impls_doc = reader::get_doc(rbml::Doc::new(cdata.data()), tag_impls); let _ = reader::tagged_docs(impls_doc, tag_impls_impl, |impl_doc| { callback(item_def_id(impl_doc, cdata)); @@ -1230,9 +1241,11 @@ pub fn each_impl(cdata: Cmd, callback: |ast::DefId|) { }); } -pub fn each_implementation_for_type(cdata: Cmd, +pub fn each_implementation_for_type<F>(cdata: Cmd, id: ast::NodeId, - callback: |ast::DefId|) { + mut callback: F) where + F: FnMut(ast::DefId), +{ let item_doc = lookup_item(id, cdata.data()); reader::tagged_docs(item_doc, tag_items_data_item_inherent_impl, @@ -1243,9 +1256,11 @@ pub fn each_implementation_for_type(cdata: Cmd, }); } -pub fn each_implementation_for_trait(cdata: Cmd, - id: ast::NodeId, - callback: |ast::DefId|) { +pub fn each_implementation_for_trait<F>(cdata: Cmd, + id: ast::NodeId, + mut callback: F) where + F: FnMut(ast::DefId), +{ let item_doc = lookup_item(id, cdata.data()); let _ = reader::tagged_docs(item_doc, diff --git a/src/librustc/metadata/encoder.rs b/src/librustc/metadata/encoder.rs index 48d1284f507..9804e3c20aa 100644 --- a/src/librustc/metadata/encoder.rs +++ b/src/librustc/metadata/encoder.rs @@ -493,7 +493,9 @@ fn encode_reexported_static_methods(ecx: &EncodeContext, /// top-level items that are sub-items of the given item. Specifically: /// /// * For newtype structs, iterates through the node ID of the constructor. -fn each_auxiliary_node_id(item: &ast::Item, callback: |NodeId| -> bool) -> bool { +fn each_auxiliary_node_id<F>(item: &ast::Item, callback: F) -> bool where + F: FnOnce(NodeId) -> bool, +{ let mut continue_ = true; match item.node { ast::ItemStruct(ref struct_def, _) => { @@ -1579,8 +1581,10 @@ fn encode_info_for_items(ecx: &EncodeContext, // Path and definition ID indexing -fn encode_index<T: Hash>(rbml_w: &mut Encoder, index: Vec<entry<T>>, - write_fn: |&mut SeekableMemWriter, &T|) { +fn encode_index<T, F>(rbml_w: &mut Encoder, index: Vec<entry<T>>, mut write_fn: F) where + F: FnMut(&mut SeekableMemWriter, &T), + T: Hash, +{ let mut buckets: Vec<Vec<entry<T>>> = Vec::from_fn(256, |_| Vec::new()); for elt in index.into_iter() { let h = hash::hash(&elt.val) as uint; diff --git a/src/librustc/metadata/filesearch.rs b/src/librustc/metadata/filesearch.rs index 2d23a61813a..507fb751303 100644 --- a/src/librustc/metadata/filesearch.rs +++ b/src/librustc/metadata/filesearch.rs @@ -42,7 +42,9 @@ pub struct FileSearch<'a> { } impl<'a> FileSearch<'a> { - pub fn for_each_lib_search_path(&self, f: |&Path| -> FileMatch) { + pub fn for_each_lib_search_path<F>(&self, mut f: F) where + F: FnMut(&Path) -> FileMatch, + { let mut visited_dirs = HashSet::new(); let mut found = false; diff --git a/src/librustc/metadata/tydecode.rs b/src/librustc/metadata/tydecode.rs index 37d790df37f..7358b3bc9c9 100644 --- a/src/librustc/metadata/tydecode.rs +++ b/src/librustc/metadata/tydecode.rs @@ -89,7 +89,10 @@ fn next_byte(st: &mut PState) -> u8 { return b; } -fn scan<R>(st: &mut PState, is_last: |char| -> bool, op: |&[u8]| -> R) -> R { +fn scan<R, F, G>(st: &mut PState, mut is_last: F, op: G) -> R where + F: FnMut(char) -> bool, + G: FnOnce(&[u8]) -> R, +{ let start_pos = st.pos; debug!("scan: '{}' (start)", st.data[st.pos] as char); while !is_last(st.data[st.pos] as char) { @@ -110,7 +113,9 @@ pub fn parse_name(st: &mut PState, last: char) -> ast::Name { parse_name_(st, |a| is_last(last, a) ) } -fn parse_name_(st: &mut PState, is_last: |char| -> bool) -> ast::Name { +fn parse_name_<F>(st: &mut PState, is_last: F) -> ast::Name where + F: FnMut(char) -> bool, +{ scan(st, is_last, |bytes| { token::intern(str::from_utf8(bytes).unwrap()) }) @@ -234,9 +239,10 @@ fn parse_trait_store(st: &mut PState, conv: conv_did) -> ty::TraitStore { } } -fn parse_vec_per_param_space<'a, 'tcx, T>(st: &mut PState<'a, 'tcx>, - f: |&mut PState<'a, 'tcx>| -> T) - -> VecPerParamSpace<T> +fn parse_vec_per_param_space<'a, 'tcx, T, F>(st: &mut PState<'a, 'tcx>, + mut f: F) + -> VecPerParamSpace<T> where + F: FnMut(&mut PState<'a, 'tcx>) -> T, { let mut r = VecPerParamSpace::empty(); for &space in subst::ParamSpace::all().iter() { @@ -350,8 +356,9 @@ fn parse_scope(st: &mut PState) -> region::CodeExtent { } } -fn parse_opt<'a, 'tcx, T>(st: &mut PState<'a, 'tcx>, f: |&mut PState<'a, 'tcx>| -> T) - -> Option<T> { +fn parse_opt<'a, 'tcx, T, F>(st: &mut PState<'a, 'tcx>, f: F) -> Option<T> where + F: FnOnce(&mut PState<'a, 'tcx>) -> T, +{ match next(st) { 'n' => None, 's' => Some(f(st)), diff --git a/src/librustc/metadata/tyencode.rs b/src/librustc/metadata/tyencode.rs index 5c7d15e1601..54376cd7b90 100644 --- a/src/librustc/metadata/tyencode.rs +++ b/src/librustc/metadata/tyencode.rs @@ -86,7 +86,9 @@ fn enc_mt<'a, 'tcx>(w: &mut SeekableMemWriter, cx: &ctxt<'a, 'tcx>, enc_ty(w, cx, mt.ty); } -fn enc_opt<T>(w: &mut SeekableMemWriter, t: Option<T>, enc_f: |&mut SeekableMemWriter, T|) { +fn enc_opt<T, F>(w: &mut SeekableMemWriter, t: Option<T>, enc_f: F) where + F: FnOnce(&mut SeekableMemWriter, T), +{ match t { None => mywrite!(w, "n"), Some(v) => { @@ -96,10 +98,12 @@ fn enc_opt<T>(w: &mut SeekableMemWriter, t: Option<T>, enc_f: |&mut SeekableMemW } } -fn enc_vec_per_param_space<'a, 'tcx, T>(w: &mut SeekableMemWriter, - cx: &ctxt<'a, 'tcx>, - v: &VecPerParamSpace<T>, - op: |&mut SeekableMemWriter, &ctxt<'a, 'tcx>, &T|) { +fn enc_vec_per_param_space<'a, 'tcx, T, F>(w: &mut SeekableMemWriter, + cx: &ctxt<'a, 'tcx>, + v: &VecPerParamSpace<T>, + mut op: F) where + F: FnMut(&mut SeekableMemWriter, &ctxt<'a, 'tcx>, &T), +{ for &space in subst::ParamSpace::all().iter() { mywrite!(w, "["); for t in v.get_slice(space).iter() { diff --git a/src/librustc/middle/astencode.rs b/src/librustc/middle/astencode.rs index 50337ec25bd..26d70502a5b 100644 --- a/src/librustc/middle/astencode.rs +++ b/src/librustc/middle/astencode.rs @@ -680,9 +680,8 @@ pub fn encode_unboxed_closure_kind(ebml_w: &mut Encoder, } pub trait vtable_decoder_helpers<'tcx> { - fn read_vec_per_param_space<T>(&mut self, - f: |&mut Self| -> T) - -> VecPerParamSpace<T>; + fn read_vec_per_param_space<T, F>(&mut self, f: F) -> VecPerParamSpace<T> where + F: FnMut(&mut Self) -> T; fn read_vtable_res_with_key(&mut self, tcx: &ty::ctxt<'tcx>, cdata: &cstore::crate_metadata) @@ -699,9 +698,8 @@ pub trait vtable_decoder_helpers<'tcx> { } impl<'tcx, 'a> vtable_decoder_helpers<'tcx> for reader::Decoder<'a> { - fn read_vec_per_param_space<T>(&mut self, - f: |&mut reader::Decoder<'a>| -> T) - -> VecPerParamSpace<T> + fn read_vec_per_param_space<T, F>(&mut self, mut f: F) -> VecPerParamSpace<T> where + F: FnMut(&mut reader::Decoder<'a>) -> T, { let types = self.read_to_vec(|this| Ok(f(this))).unwrap(); let selfs = self.read_to_vec(|this| Ok(f(this))).unwrap(); @@ -793,9 +791,11 @@ impl<'tcx, 'a> vtable_decoder_helpers<'tcx> for reader::Decoder<'a> { // ___________________________________________________________________________ // -fn encode_vec_per_param_space<T>(rbml_w: &mut Encoder, - v: &subst::VecPerParamSpace<T>, - f: |&mut Encoder, &T|) { +fn encode_vec_per_param_space<T, F>(rbml_w: &mut Encoder, + v: &subst::VecPerParamSpace<T>, + mut f: F) where + F: FnMut(&mut Encoder, &T), +{ for &space in subst::ParamSpace::all().iter() { rbml_w.emit_from_vec(v.get_slice(space), |rbml_w, n| Ok(f(rbml_w, n))).unwrap(); @@ -1124,14 +1124,16 @@ impl<'a, 'tcx> rbml_writer_helpers<'tcx> for Encoder<'a> { } trait write_tag_and_id { - fn tag(&mut self, tag_id: c::astencode_tag, f: |&mut Self|); + fn tag<F>(&mut self, tag_id: c::astencode_tag, f: F) where F: FnOnce(&mut Self); fn id(&mut self, id: ast::NodeId); } impl<'a> write_tag_and_id for Encoder<'a> { - fn tag(&mut self, - tag_id: c::astencode_tag, - f: |&mut Encoder<'a>|) { + fn tag<F>(&mut self, + tag_id: c::astencode_tag, + f: F) where + F: FnOnce(&mut Encoder<'a>), + { self.start_tag(tag_id as uint); f(self); self.end_tag(); diff --git a/src/librustc/middle/check_const.rs b/src/librustc/middle/check_const.rs index de140fd5c30..a91ea8bfef8 100644 --- a/src/librustc/middle/check_const.rs +++ b/src/librustc/middle/check_const.rs @@ -24,16 +24,22 @@ struct CheckCrateVisitor<'a, 'tcx: 'a> { } impl<'a, 'tcx> CheckCrateVisitor<'a, 'tcx> { - fn with_const(&mut self, in_const: bool, f: |&mut CheckCrateVisitor<'a, 'tcx>|) { + fn with_const<F>(&mut self, in_const: bool, f: F) where + F: FnOnce(&mut CheckCrateVisitor<'a, 'tcx>), + { let was_const = self.in_const; self.in_const = in_const; f(self); self.in_const = was_const; } - fn inside_const(&mut self, f: |&mut CheckCrateVisitor<'a, 'tcx>|) { + fn inside_const<F>(&mut self, f: F) where + F: FnOnce(&mut CheckCrateVisitor<'a, 'tcx>), + { self.with_const(true, f); } - fn outside_const(&mut self, f: |&mut CheckCrateVisitor<'a, 'tcx>|) { + fn outside_const<F>(&mut self, f: F) where + F: FnOnce(&mut CheckCrateVisitor<'a, 'tcx>), + { self.with_const(false, f); } } diff --git a/src/librustc/middle/check_loop.rs b/src/librustc/middle/check_loop.rs index eb073e07b02..fee2d810fcb 100644 --- a/src/librustc/middle/check_loop.rs +++ b/src/librustc/middle/check_loop.rs @@ -64,7 +64,9 @@ impl<'a, 'v> Visitor<'v> for CheckLoopVisitor<'a> { } impl<'a> CheckLoopVisitor<'a> { - fn with_context(&mut self, cx: Context, f: |&mut CheckLoopVisitor<'a>|) { + fn with_context<F>(&mut self, cx: Context, f: F) where + F: FnOnce(&mut CheckLoopVisitor<'a>), + { let old_cx = self.cx; self.cx = cx; f(self); diff --git a/src/librustc/middle/check_match.rs b/src/librustc/middle/check_match.rs index 2c437ae046b..ea3ef2af739 100644 --- a/src/librustc/middle/check_match.rs +++ b/src/librustc/middle/check_match.rs @@ -980,7 +980,9 @@ fn check_fn(cx: &mut MatchCheckCtxt, } } -fn is_refutable<A>(cx: &MatchCheckCtxt, pat: &Pat, refutable: |&Pat| -> A) -> Option<A> { +fn is_refutable<A, F>(cx: &MatchCheckCtxt, pat: &Pat, refutable: F) -> Option<A> where + F: FnOnce(&Pat) -> A, +{ let pats = Matrix(vec!(vec!(pat))); match is_useful(cx, &pats, &[DUMMY_WILD_PAT], ConstructWitness) { UsefulWithWitness(pats) => { diff --git a/src/librustc/middle/check_static.rs b/src/librustc/middle/check_static.rs index 5a53979d719..65412ff8eff 100644 --- a/src/librustc/middle/check_static.rs +++ b/src/librustc/middle/check_static.rs @@ -85,7 +85,9 @@ pub fn check_crate(tcx: &ty::ctxt) { } impl<'a, 'tcx> CheckStaticVisitor<'a, 'tcx> { - fn with_mode(&mut self, mode: Mode, f: |&mut CheckStaticVisitor<'a, 'tcx>|) { + fn with_mode<F>(&mut self, mode: Mode, f: F) where + F: FnOnce(&mut CheckStaticVisitor<'a, 'tcx>), + { let old = self.mode; self.mode = mode; f(self); diff --git a/src/librustc/middle/dataflow.rs b/src/librustc/middle/dataflow.rs index db8fd999f38..9373a5704b2 100644 --- a/src/librustc/middle/dataflow.rs +++ b/src/librustc/middle/dataflow.rs @@ -280,10 +280,9 @@ impl<'a, 'tcx, O:DataFlowOperator> DataFlowContext<'a, 'tcx, O> { } - pub fn each_bit_on_entry(&self, - id: ast::NodeId, - f: |uint| -> bool) - -> bool { + pub fn each_bit_on_entry<F>(&self, id: ast::NodeId, f: F) -> bool where + F: FnMut(uint) -> bool, + { //! Iterates through each bit that is set on entry to `id`. //! Only useful after `propagate()` has been called. if !self.has_bitset_for_nodeid(id) { @@ -293,11 +292,9 @@ impl<'a, 'tcx, O:DataFlowOperator> DataFlowContext<'a, 'tcx, O> { self.each_bit_for_node(Entry, cfgidx, f) } - pub fn each_bit_for_node(&self, - e: EntryOrExit, - cfgidx: CFGIndex, - f: |uint| -> bool) - -> bool { + pub fn each_bit_for_node<F>(&self, e: EntryOrExit, cfgidx: CFGIndex, f: F) -> bool where + F: FnMut(uint) -> bool, + { //! Iterates through each bit that is set on entry/exit to `cfgidx`. //! Only useful after `propagate()` has been called. @@ -324,8 +321,9 @@ impl<'a, 'tcx, O:DataFlowOperator> DataFlowContext<'a, 'tcx, O> { self.each_bit(slice, f) } - pub fn each_gen_bit(&self, id: ast::NodeId, f: |uint| -> bool) - -> bool { + pub fn each_gen_bit<F>(&self, id: ast::NodeId, f: F) -> bool where + F: FnMut(uint) -> bool, + { //! Iterates through each bit in the gen set for `id`. if !self.has_bitset_for_nodeid(id) { return true; @@ -345,7 +343,9 @@ impl<'a, 'tcx, O:DataFlowOperator> DataFlowContext<'a, 'tcx, O> { self.each_bit(gens, f) } - fn each_bit(&self, words: &[uint], f: |uint| -> bool) -> bool { + fn each_bit<F>(&self, words: &[uint], mut f: F) -> bool where + F: FnMut(uint) -> bool, + { //! Helper for iterating over the bits in a bit set. //! Returns false on the first call to `f` that returns false; //! if all calls to `f` return true, then returns true. diff --git a/src/librustc/middle/def.rs b/src/librustc/middle/def.rs index b3e4dd25adc..ca60ac45e26 100644 --- a/src/librustc/middle/def.rs +++ b/src/librustc/middle/def.rs @@ -61,7 +61,9 @@ pub enum MethodProvenance { } impl MethodProvenance { - pub fn map(self, f: |ast::DefId| -> ast::DefId) -> MethodProvenance { + pub fn map<F>(self, f: F) -> MethodProvenance where + F: FnOnce(ast::DefId) -> ast::DefId, + { match self { FromTrait(did) => FromTrait(f(did)), FromImpl(did) => FromImpl(f(did)) diff --git a/src/librustc/middle/graph.rs b/src/librustc/middle/graph.rs index e45232a3c30..4c03ed2a480 100644 --- a/src/librustc/middle/graph.rs +++ b/src/librustc/middle/graph.rs @@ -221,39 +221,43 @@ impl<N,E> Graph<N,E> { /////////////////////////////////////////////////////////////////////////// // Iterating over nodes, edges - pub fn each_node<'a>(&'a self, f: |NodeIndex, &'a Node<N>| -> bool) -> bool { + pub fn each_node<'a, F>(&'a self, mut f: F) -> bool where + F: FnMut(NodeIndex, &'a Node<N>) -> bool, + { //! Iterates over all edges defined in the graph. self.nodes.iter().enumerate().all(|(i, node)| f(NodeIndex(i), node)) } - pub fn each_edge<'a>(&'a self, f: |EdgeIndex, &'a Edge<E>| -> bool) -> bool { + pub fn each_edge<'a, F>(&'a self, mut f: F) -> bool where + F: FnMut(EdgeIndex, &'a Edge<E>) -> bool, + { //! Iterates over all edges defined in the graph self.edges.iter().enumerate().all(|(i, edge)| f(EdgeIndex(i), edge)) } - pub fn each_outgoing_edge<'a>(&'a self, - source: NodeIndex, - f: |EdgeIndex, &'a Edge<E>| -> bool) - -> bool { + pub fn each_outgoing_edge<'a, F>(&'a self, source: NodeIndex, f: F) -> bool where + F: FnMut(EdgeIndex, &'a Edge<E>) -> bool, + { //! Iterates over all outgoing edges from the node `from` self.each_adjacent_edge(source, Outgoing, f) } - pub fn each_incoming_edge<'a>(&'a self, - target: NodeIndex, - f: |EdgeIndex, &'a Edge<E>| -> bool) - -> bool { + pub fn each_incoming_edge<'a, F>(&'a self, target: NodeIndex, f: F) -> bool where + F: FnMut(EdgeIndex, &'a Edge<E>) -> bool, + { //! Iterates over all incoming edges to the node `target` self.each_adjacent_edge(target, Incoming, f) } - pub fn each_adjacent_edge<'a>(&'a self, - node: NodeIndex, - dir: Direction, - f: |EdgeIndex, &'a Edge<E>| -> bool) - -> bool { + pub fn each_adjacent_edge<'a, F>(&'a self, + node: NodeIndex, + dir: Direction, + mut f: F) + -> bool where + F: FnMut(EdgeIndex, &'a Edge<E>) -> bool, + { //! Iterates over all edges adjacent to the node `node` //! in the direction `dir` (either `Outgoing` or `Incoming) @@ -277,11 +281,9 @@ impl<N,E> Graph<N,E> { // variables or other bitsets. This method facilitates such a // computation. - pub fn iterate_until_fixed_point<'a>(&'a self, - op: |iter_index: uint, - edge_index: EdgeIndex, - edge: &'a Edge<E>| - -> bool) { + pub fn iterate_until_fixed_point<'a, F>(&'a self, mut op: F) where + F: FnMut(uint, EdgeIndex, &'a Edge<E>) -> bool, + { let mut iteration = 0; let mut changed = true; while changed { @@ -294,7 +296,9 @@ impl<N,E> Graph<N,E> { } } -pub fn each_edge_index(max_edge_index: EdgeIndex, f: |EdgeIndex| -> bool) { +pub fn each_edge_index<F>(max_edge_index: EdgeIndex, mut f: F) where + F: FnMut(EdgeIndex) -> bool, +{ let mut i = 0; let n = max_edge_index.get(); while i < n { diff --git a/src/librustc/middle/infer/coercion.rs b/src/librustc/middle/infer/coercion.rs index f04c519badc..c6422b36e38 100644 --- a/src/librustc/middle/infer/coercion.rs +++ b/src/librustc/middle/infer/coercion.rs @@ -194,8 +194,9 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> { } } - pub fn unpack_actual_value<T>(&self, a: Ty<'tcx>, f: |&ty::sty<'tcx>| -> T) - -> T { + pub fn unpack_actual_value<T, F>(&self, a: Ty<'tcx>, f: F) -> T where + F: FnOnce(&ty::sty<'tcx>) -> T, + { match resolve_type(self.get_ref().infcx, None, a, try_resolve_tvar_shallow) { Ok(t) => { @@ -458,13 +459,15 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> { || AutoUnsafe(b_mutbl, None)) } - fn coerce_object(&self, - a: Ty<'tcx>, - sty_a: &ty::sty<'tcx>, - b: Ty<'tcx>, - b_mutbl: ast::Mutability, - mk_ty: |Ty<'tcx>| -> Ty<'tcx>, - mk_adjust: || -> ty::AutoRef<'tcx>) -> CoerceResult<'tcx> + fn coerce_object<F, G>(&self, + a: Ty<'tcx>, + sty_a: &ty::sty<'tcx>, + b: Ty<'tcx>, + b_mutbl: ast::Mutability, + mk_ty: F, + mk_adjust: G) -> CoerceResult<'tcx> where + F: FnOnce(Ty<'tcx>) -> Ty<'tcx>, + G: FnOnce() -> ty::AutoRef<'tcx>, { let tcx = self.get_ref().infcx.tcx; diff --git a/src/librustc/middle/infer/higher_ranked/mod.rs b/src/librustc/middle/infer/higher_ranked/mod.rs index 95805ef8b94..be053afcca4 100644 --- a/src/librustc/middle/infer/higher_ranked/mod.rs +++ b/src/librustc/middle/infer/higher_ranked/mod.rs @@ -426,11 +426,9 @@ fn is_var_in_set(new_vars: &[ty::RegionVid], r: ty::Region) -> bool { } } -fn fold_regions_in<'tcx, T>(tcx: &ty::ctxt<'tcx>, - value: &T, - fldr: |ty::Region, ty::DebruijnIndex| -> ty::Region) - -> T - where T: HigherRankedFoldable<'tcx> +fn fold_regions_in<'tcx, T, F>(tcx: &ty::ctxt<'tcx>, value: &T, mut fldr: F) -> T where + T: HigherRankedFoldable<'tcx>, + F: FnMut(ty::Region, ty::DebruijnIndex) -> ty::Region, { value.fold_contents(&mut ty_fold::RegionFolder::new(tcx, |region, current_depth| { // we should only be encountering "escaping" late-bound regions here, diff --git a/src/librustc/middle/infer/mod.rs b/src/librustc/middle/infer/mod.rs index 3b62b96a3e9..4c3b7589d76 100644 --- a/src/librustc/middle/infer/mod.rs +++ b/src/librustc/middle/infer/mod.rs @@ -477,14 +477,17 @@ pub fn resolve_region(cx: &InferCtxt, r: ty::Region, modes: uint) } trait then<'tcx> { - fn then<T:Clone>(&self, f: || -> Result<T,ty::type_err<'tcx>>) - -> Result<T,ty::type_err<'tcx>>; + fn then<T, F>(&self, f: F) -> Result<T, ty::type_err<'tcx>> where + T: Clone, + F: FnOnce() -> Result<T, ty::type_err<'tcx>>; } impl<'tcx> then<'tcx> for ures<'tcx> { - fn then<T:Clone>(&self, f: || -> Result<T,ty::type_err<'tcx>>) - -> Result<T,ty::type_err<'tcx>> { - self.and_then(|_i| f()) + fn then<T, F>(&self, f: F) -> Result<T, ty::type_err<'tcx>> where + T: Clone, + F: FnOnce() -> Result<T, ty::type_err<'tcx>>, + { + self.and_then(move |_| f()) } } @@ -502,12 +505,15 @@ impl<'tcx, T> ToUres<'tcx> for cres<'tcx, T> { } trait CresCompare<'tcx, T> { - fn compare(&self, t: T, f: || -> ty::type_err<'tcx>) -> cres<'tcx, T>; + fn compare<F>(&self, t: T, f: F) -> cres<'tcx, T> where + F: FnOnce() -> ty::type_err<'tcx>; } impl<'tcx, T:Clone + PartialEq> CresCompare<'tcx, T> for cres<'tcx, T> { - fn compare(&self, t: T, f: || -> ty::type_err<'tcx>) -> cres<'tcx, T> { - (*self).clone().and_then(|s| { + fn compare<F>(&self, t: T, f: F) -> cres<'tcx, T> where + F: FnOnce() -> ty::type_err<'tcx>, + { + (*self).clone().and_then(move |s| { if s == t { (*self).clone() } else { @@ -616,7 +622,9 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { } /// Execute `f` and commit the bindings - pub fn commit_unconditionally<R>(&self, f: || -> R) -> R { + pub fn commit_unconditionally<R, F>(&self, f: F) -> R where + F: FnOnce() -> R, + { debug!("commit()"); let snapshot = self.start_snapshot(); let r = f(); @@ -625,12 +633,16 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { } /// Execute `f` and commit the bindings if successful - pub fn commit_if_ok<T,E>(&self, f: || -> Result<T,E>) -> Result<T,E> { - self.commit_unconditionally(|| self.try(|| f())) + pub fn commit_if_ok<T, E, F>(&self, f: F) -> Result<T, E> where + F: FnOnce() -> Result<T, E> + { + self.commit_unconditionally(move || self.try(move || f())) } /// Execute `f`, unroll bindings on panic - pub fn try<T,E>(&self, f: || -> Result<T,E>) -> Result<T,E> { + pub fn try<T, E, F>(&self, f: F) -> Result<T, E> where + F: FnOnce() -> Result<T, E> + { debug!("try()"); let snapshot = self.start_snapshot(); let r = f(); @@ -647,7 +659,9 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { } /// Execute `f` then unroll any bindings it creates - pub fn probe<R>(&self, f: || -> R) -> R { + pub fn probe<R, F>(&self, f: F) -> R where + F: FnOnce() -> R, + { debug!("probe()"); let snapshot = self.start_snapshot(); let r = f(); @@ -902,22 +916,24 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { // in this case. The typechecker should only ever report type errors involving mismatched // types using one of these four methods, and should not call span_err directly for such // errors. - pub fn type_error_message_str(&self, - sp: Span, - mk_msg: |Option<String>, String| -> String, - actual_ty: String, - err: Option<&ty::type_err<'tcx>>) { + pub fn type_error_message_str<M>(&self, + sp: Span, + mk_msg: M, + actual_ty: String, + err: Option<&ty::type_err<'tcx>>) where + M: FnOnce(Option<String>, String) -> String, + { self.type_error_message_str_with_expected(sp, mk_msg, None, actual_ty, err) } - pub fn type_error_message_str_with_expected(&self, - sp: Span, - mk_msg: |Option<String>, - String| - -> String, - expected_ty: Option<Ty<'tcx>>, - actual_ty: String, - err: Option<&ty::type_err<'tcx>>) { + pub fn type_error_message_str_with_expected<M>(&self, + sp: Span, + mk_msg: M, + expected_ty: Option<Ty<'tcx>>, + actual_ty: String, + err: Option<&ty::type_err<'tcx>>) where + M: FnOnce(Option<String>, String) -> String, + { debug!("hi! expected_ty = {}, actual_ty = {}", expected_ty, actual_ty); let resolved_expected = expected_ty.map(|e_ty| { @@ -942,11 +958,13 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { } } - pub fn type_error_message(&self, - sp: Span, - mk_msg: |String| -> String, - actual_ty: Ty<'tcx>, - err: Option<&ty::type_err<'tcx>>) { + pub fn type_error_message<M>(&self, + sp: Span, + mk_msg: M, + actual_ty: Ty<'tcx>, + err: Option<&ty::type_err<'tcx>>) where + M: FnOnce(String) -> String, + { let actual_ty = self.resolve_type_vars_if_possible(actual_ty); // Don't report an error if actual type is ty_err. @@ -954,7 +972,9 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { return; } - self.type_error_message_str(sp, |_e, a| { mk_msg(a) }, self.ty_to_string(actual_ty), err); + self.type_error_message_str(sp, + move |_e, a| { mk_msg(a) }, + self.ty_to_string(actual_ty), err); } pub fn report_mismatched_types(&self, diff --git a/src/librustc/middle/infer/region_inference/mod.rs b/src/librustc/middle/infer/region_inference/mod.rs index 391e37e8b9c..98f69f66b27 100644 --- a/src/librustc/middle/infer/region_inference/mod.rs +++ b/src/librustc/middle/infer/region_inference/mod.rs @@ -569,15 +569,15 @@ impl<'a, 'tcx> RegionVarBindings<'a, 'tcx> { } } - pub fn combine_vars(&self, - t: CombineMapType, - a: Region, - b: Region, - origin: SubregionOrigin<'tcx>, - relate: |this: &RegionVarBindings<'a, 'tcx>, - old_r: Region, - new_r: Region|) - -> Region { + pub fn combine_vars<F>(&self, + t: CombineMapType, + a: Region, + b: Region, + origin: SubregionOrigin<'tcx>, + mut relate: F) + -> Region where + F: FnMut(&RegionVarBindings<'a, 'tcx>, Region, Region), + { let vars = TwoRegions { a: a, b: b }; match self.combine_map(t).borrow().get(&vars) { Some(&c) => { @@ -1539,9 +1539,9 @@ impl<'a, 'tcx> RegionVarBindings<'a, 'tcx> { } } - fn iterate_until_fixed_point(&self, - tag: &str, - body: |constraint: &Constraint| -> bool) { + fn iterate_until_fixed_point<F>(&self, tag: &str, mut body: F) where + F: FnMut(&Constraint) -> bool, + { let mut iteration = 0u; let mut changed = true; while changed { diff --git a/src/librustc/middle/infer/skolemize.rs b/src/librustc/middle/infer/skolemize.rs index 62bf1d0126a..705b0ae730d 100644 --- a/src/librustc/middle/infer/skolemize.rs +++ b/src/librustc/middle/infer/skolemize.rs @@ -54,11 +54,12 @@ impl<'a, 'tcx> TypeSkolemizer<'a, 'tcx> { } } - fn skolemize(&mut self, - opt_ty: Option<Ty<'tcx>>, - key: ty::InferTy, - skolemizer: |uint| -> ty::InferTy) - -> Ty<'tcx> + fn skolemize<F>(&mut self, + opt_ty: Option<Ty<'tcx>>, + key: ty::InferTy, + skolemizer: F) + -> Ty<'tcx> where + F: FnOnce(uint) -> ty::InferTy, { match opt_ty { Some(ty) => { return ty.fold_with(self); } diff --git a/src/librustc/middle/liveness.rs b/src/librustc/middle/liveness.rs index 5edbafc4e0b..271e903bbdf 100644 --- a/src/librustc/middle/liveness.rs +++ b/src/librustc/middle/liveness.rs @@ -616,9 +616,9 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> { self.ir.variable(node_id, span) } - fn pat_bindings(&mut self, - pat: &ast::Pat, - f: |&mut Liveness<'a, 'tcx>, LiveNode, Variable, Span, NodeId|) { + fn pat_bindings<F>(&mut self, pat: &ast::Pat, mut f: F) where + F: FnMut(&mut Liveness<'a, 'tcx>, LiveNode, Variable, Span, NodeId), + { pat_util::pat_bindings(&self.ir.tcx.def_map, pat, |_bm, p_id, sp, _n| { let ln = self.live_node(p_id, sp); let var = self.variable(p_id, sp); @@ -626,9 +626,9 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> { }) } - fn arm_pats_bindings(&mut self, - pat: Option<&ast::Pat>, - f: |&mut Liveness<'a, 'tcx>, LiveNode, Variable, Span, NodeId|) { + fn arm_pats_bindings<F>(&mut self, pat: Option<&ast::Pat>, f: F) where + F: FnMut(&mut Liveness<'a, 'tcx>, LiveNode, Variable, Span, NodeId), + { match pat { Some(pat) => { self.pat_bindings(pat, f); @@ -691,10 +691,9 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> { self.assigned_on_entry(successor, var) } - fn indices2(&mut self, - ln: LiveNode, - succ_ln: LiveNode, - op: |&mut Liveness<'a, 'tcx>, uint, uint|) { + fn indices2<F>(&mut self, ln: LiveNode, succ_ln: LiveNode, mut op: F) where + F: FnMut(&mut Liveness<'a, 'tcx>, uint, uint), + { let node_base_idx = self.idx(ln, Variable(0u)); let succ_base_idx = self.idx(succ_ln, Variable(0u)); for var_idx in range(0u, self.ir.num_vars) { @@ -702,10 +701,13 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> { } } - fn write_vars(&self, - wr: &mut io::Writer, - ln: LiveNode, - test: |uint| -> LiveNode) -> io::IoResult<()> { + fn write_vars<F>(&self, + wr: &mut io::Writer, + ln: LiveNode, + mut test: F) + -> io::IoResult<()> where + F: FnMut(uint) -> LiveNode, + { let node_base_idx = self.idx(ln, Variable(0)); for var_idx in range(0u, self.ir.num_vars) { let idx = node_base_idx + var_idx; @@ -1408,12 +1410,14 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> { cond_ln } - fn with_loop_nodes<R>(&mut self, - loop_node_id: NodeId, - break_ln: LiveNode, - cont_ln: LiveNode, - f: |&mut Liveness<'a, 'tcx>| -> R) - -> R { + fn with_loop_nodes<R, F>(&mut self, + loop_node_id: NodeId, + break_ln: LiveNode, + cont_ln: LiveNode, + f: F) + -> R where + F: FnOnce(&mut Liveness<'a, 'tcx>) -> R, + { debug!("with_loop_nodes: {} {}", loop_node_id, break_ln.get()); self.loop_scope.push(loop_node_id); self.break_ln.insert(loop_node_id, break_ln); diff --git a/src/librustc/middle/mem_categorization.rs b/src/librustc/middle/mem_categorization.rs index 302fbd53dd5..d96cf4495bd 100644 --- a/src/librustc/middle/mem_categorization.rs +++ b/src/librustc/middle/mem_categorization.rs @@ -1142,12 +1142,11 @@ impl<'t,'tcx,TYPER:Typer<'tcx>> MemCategorizationContext<'t,TYPER> { }) } + // FIXME(#19596) unbox `op` pub fn cat_pattern(&self, cmt: cmt<'tcx>, pat: &ast::Pat, - op: |&MemCategorizationContext<'t,TYPER>, - cmt<'tcx>, - &ast::Pat|) + op: |&MemCategorizationContext<'t, TYPER>, cmt<'tcx>, &ast::Pat|) -> McResult<()> { // Here, `cmt` is the categorization for the value being // matched and pat is the pattern it is being matched against. diff --git a/src/librustc/middle/pat_util.rs b/src/librustc/middle/pat_util.rs index 8d4fbfd4cbc..8ef8e091c94 100644 --- a/src/librustc/middle/pat_util.rs +++ b/src/librustc/middle/pat_util.rs @@ -91,9 +91,9 @@ pub fn pat_is_binding_or_wild(dm: &resolve::DefMap, pat: &ast::Pat) -> bool { /// Call `it` on every "binding" in a pattern, e.g., on `a` in /// `match foo() { Some(a) => (), None => () }` -pub fn pat_bindings(dm: &resolve::DefMap, - pat: &ast::Pat, - it: |ast::BindingMode, ast::NodeId, Span, &ast::SpannedIdent|) { +pub fn pat_bindings<I>(dm: &resolve::DefMap, pat: &ast::Pat, mut it: I) where + I: FnMut(ast::BindingMode, ast::NodeId, Span, &ast::SpannedIdent), +{ walk_pat(pat, |p| { match p.node { ast::PatIdent(binding_mode, ref pth, _) if pat_is_binding(dm, p) => { diff --git a/src/librustc/middle/region.rs b/src/librustc/middle/region.rs index 370097004e9..390729df012 100644 --- a/src/librustc/middle/region.rs +++ b/src/librustc/middle/region.rs @@ -62,7 +62,9 @@ impl CodeExtent { /// Maps this scope to a potentially new one according to the /// NodeId transformer `f_id`. - pub fn map_id(&self, f_id: |ast::NodeId| -> ast::NodeId) -> CodeExtent { + pub fn map_id<F>(&self, f_id: F) -> CodeExtent where + F: FnOnce(ast::NodeId) -> ast::NodeId, + { match *self { CodeExtent::Misc(node_id) => CodeExtent::Misc(f_id(node_id)), } diff --git a/src/librustc/middle/resolve.rs b/src/librustc/middle/resolve.rs index 2899f60f736..85e0c9294a6 100644 --- a/src/librustc/middle/resolve.rs +++ b/src/librustc/middle/resolve.rs @@ -1837,10 +1837,12 @@ impl<'a> Resolver<'a> { } /// Constructs the reduced graph for one foreign item. - fn build_reduced_graph_for_foreign_item(&mut self, - foreign_item: &ForeignItem, - parent: ReducedGraphParent, - f: |&mut Resolver|) { + fn build_reduced_graph_for_foreign_item<F>(&mut self, + foreign_item: &ForeignItem, + parent: ReducedGraphParent, + f: F) where + F: FnOnce(&mut Resolver), + { let name = foreign_item.ident.name; let is_public = foreign_item.vis == ast::Public; let modifiers = if is_public { PUBLIC } else { DefModifiers::empty() } | IMPORTABLE; @@ -3970,7 +3972,9 @@ impl<'a> Resolver<'a> { // generate a fake "implementation scope" containing all the // implementations thus found, for compatibility with old resolve pass. - fn with_scope(&mut self, name: Option<Name>, f: |&mut Resolver|) { + fn with_scope<F>(&mut self, name: Option<Name>, f: F) where + F: FnOnce(&mut Resolver), + { let orig_module = self.current_module.clone(); // Move down in the graph. @@ -4373,9 +4377,9 @@ impl<'a> Resolver<'a> { } } - fn with_type_parameter_rib(&mut self, - type_parameters: TypeParameters, - f: |&mut Resolver|) { + fn with_type_parameter_rib<F>(&mut self, type_parameters: TypeParameters, f: F) where + F: FnOnce(&mut Resolver), + { match type_parameters { HasTypeParameters(generics, space, node_id, rib_kind) => { let mut function_type_rib = Rib::new(rib_kind); @@ -4422,13 +4426,17 @@ impl<'a> Resolver<'a> { } } - fn with_label_rib(&mut self, f: |&mut Resolver|) { + fn with_label_rib<F>(&mut self, f: F) where + F: FnOnce(&mut Resolver), + { self.label_ribs.push(Rib::new(NormalRibKind)); f(self); self.label_ribs.pop(); } - fn with_constant_rib(&mut self, f: |&mut Resolver|) { + fn with_constant_rib<F>(&mut self, f: F) where + F: FnOnce(&mut Resolver), + { self.value_ribs.push(Rib::new(ConstantItemRibKind)); self.type_ribs.push(Rib::new(ConstantItemRibKind)); f(self); @@ -4676,7 +4684,9 @@ impl<'a> Resolver<'a> { method.pe_body()); } - fn with_current_self_type<T>(&mut self, self_type: &Ty, f: |&mut Resolver| -> T) -> T { + fn with_current_self_type<T, F>(&mut self, self_type: &Ty, f: F) -> T where + F: FnOnce(&mut Resolver) -> T, + { // Handle nested impls (inside fn bodies) let previous_value = replace(&mut self.current_self_type, Some(self_type.clone())); let result = f(self); @@ -4684,9 +4694,11 @@ impl<'a> Resolver<'a> { result } - fn with_optional_trait_ref<T>(&mut self, id: NodeId, - opt_trait_ref: &Option<TraitRef>, - f: |&mut Resolver| -> T) -> T { + fn with_optional_trait_ref<T, F>(&mut self, id: NodeId, + opt_trait_ref: &Option<TraitRef>, + f: F) -> T where + F: FnOnce(&mut Resolver) -> T, + { let new_val = match *opt_trait_ref { Some(ref trait_ref) => { self.resolve_trait_reference(id, trait_ref, TraitImplementation); @@ -5620,7 +5632,9 @@ impl<'a> Resolver<'a> { } } - fn with_no_errors<T>(&mut self, f: |&mut Resolver| -> T) -> T { + fn with_no_errors<T, F>(&mut self, f: F) -> T where + F: FnOnce(&mut Resolver) -> T, + { self.emit_errors = false; let rs = f(self); self.emit_errors = true; diff --git a/src/librustc/middle/resolve_lifetime.rs b/src/librustc/middle/resolve_lifetime.rs index 3ab94d3ca66..83332d275ce 100644 --- a/src/librustc/middle/resolve_lifetime.rs +++ b/src/librustc/middle/resolve_lifetime.rs @@ -247,7 +247,9 @@ impl<'a, 'v> Visitor<'v> for LifetimeContext<'a> { } impl<'a> LifetimeContext<'a> { - fn with(&mut self, wrap_scope: ScopeChain, f: |&mut LifetimeContext|) { + fn with<F>(&mut self, wrap_scope: ScopeChain, f: F) where + F: FnOnce(&mut LifetimeContext), + { let LifetimeContext {sess, ref mut named_region_map, ..} = *self; let mut this = LifetimeContext { sess: sess, @@ -278,10 +280,12 @@ impl<'a> LifetimeContext<'a> { /// already in scope (for a fn item, that will be 0, but for a method it might not be). Late /// bound lifetimes are resolved by name and associated with a binder id (`binder_id`), so the /// ordering is not important there. - fn visit_early_late(&mut self, - early_space: subst::ParamSpace, - generics: &ast::Generics, - walk: |&mut LifetimeContext|) { + fn visit_early_late<F>(&mut self, + early_space: subst::ParamSpace, + generics: &ast::Generics, + walk: F) where + F: FnOnce(&mut LifetimeContext), + { let referenced_idents = early_bound_lifetime_names(generics); debug!("visit_early_late: referenced_idents={}", @@ -290,8 +294,8 @@ impl<'a> LifetimeContext<'a> { let (early, late) = generics.lifetimes.clone().partition( |l| referenced_idents.iter().any(|&i| i == l.lifetime.name)); - self.with(EarlyScope(early_space, &early, self.scope), |this| { - this.with(LateScope(&late, this.scope), |this| { + self.with(EarlyScope(early_space, &early, self.scope), move |this| { + this.with(LateScope(&late, this.scope), move |this| { this.check_lifetime_defs(&generics.lifetimes); walk(this); }); diff --git a/src/librustc/middle/stability.rs b/src/librustc/middle/stability.rs index 994fe2e9e27..ca8029fdfca 100644 --- a/src/librustc/middle/stability.rs +++ b/src/librustc/middle/stability.rs @@ -43,7 +43,9 @@ struct Annotator { impl Annotator { // Determine the stability for a node based on its attributes and inherited // stability. The stability is recorded in the index and used as the parent. - fn annotate(&mut self, id: NodeId, attrs: &Vec<Attribute>, f: |&mut Annotator|) { + fn annotate<F>(&mut self, id: NodeId, attrs: &Vec<Attribute>, f: F) where + F: FnOnce(&mut Annotator), + { match attr::find_stability(attrs.as_slice()) { Some(stab) => { self.index.local.insert(id, stab.clone()); diff --git a/src/librustc/middle/subst.rs b/src/librustc/middle/subst.rs index d3b1c2d2afc..2098aa3db53 100644 --- a/src/librustc/middle/subst.rs +++ b/src/librustc/middle/subst.rs @@ -167,10 +167,9 @@ impl<'tcx> Substs<'tcx> { } impl RegionSubsts { - fn map<A>(self, - a: A, - op: |VecPerParamSpace<ty::Region>, A| -> VecPerParamSpace<ty::Region>) - -> RegionSubsts { + fn map<A, F>(self, a: A, op: F) -> RegionSubsts where + F: FnOnce(VecPerParamSpace<ty::Region>, A) -> VecPerParamSpace<ty::Region>, + { match self { ErasedRegions => ErasedRegions, NonerasedRegions(r) => NonerasedRegions(op(r, a)) @@ -415,16 +414,18 @@ impl<T> VecPerParamSpace<T> { self.content.as_slice() } - pub fn all_vecs(&self, pred: |&[T]| -> bool) -> bool { + pub fn all_vecs<P>(&self, mut pred: P) -> bool where + P: FnMut(&[T]) -> bool, + { let spaces = [TypeSpace, SelfSpace, FnSpace]; spaces.iter().all(|&space| { pred(self.get_slice(space)) }) } - pub fn all(&self, pred: |&T| -> bool) -> bool { + pub fn all<P>(&self, pred: P) -> bool where P: FnMut(&T) -> bool { self.iter().all(pred) } - pub fn any(&self, pred: |&T| -> bool) -> bool { + pub fn any<P>(&self, pred: P) -> bool where P: FnMut(&T) -> bool { self.iter().any(pred) } @@ -432,7 +433,7 @@ impl<T> VecPerParamSpace<T> { self.all_vecs(|v| v.is_empty()) } - pub fn map<U>(&self, pred: |&T| -> U) -> VecPerParamSpace<U> { + pub fn map<U, P>(&self, pred: P) -> VecPerParamSpace<U> where P: FnMut(&T) -> U { let result = self.iter().map(pred).collect(); VecPerParamSpace::new_internal(result, self.type_limit, @@ -440,7 +441,9 @@ impl<T> VecPerParamSpace<T> { self.assoc_limit) } - pub fn map_enumerated<U>(&self, pred: |(ParamSpace, uint, &T)| -> U) -> VecPerParamSpace<U> { + pub fn map_enumerated<U, P>(&self, pred: P) -> VecPerParamSpace<U> where + P: FnMut((ParamSpace, uint, &T)) -> U, + { let result = self.iter_enumerated().map(pred).collect(); VecPerParamSpace::new_internal(result, self.type_limit, @@ -448,7 +451,9 @@ impl<T> VecPerParamSpace<T> { self.assoc_limit) } - pub fn map_move<U>(self, pred: |T| -> U) -> VecPerParamSpace<U> { + pub fn map_move<U, F>(self, mut pred: F) -> VecPerParamSpace<U> where + F: FnMut(T) -> U, + { let SeparateVecsPerParamSpace { types: t, selfs: s, diff --git a/src/librustc/middle/traits/mod.rs b/src/librustc/middle/traits/mod.rs index 604a0607c0b..936304c5eb4 100644 --- a/src/librustc/middle/traits/mod.rs +++ b/src/librustc/middle/traits/mod.rs @@ -312,7 +312,7 @@ impl<'tcx, N> Vtable<'tcx, N> { } } - pub fn map_nested<M>(&self, op: |&N| -> M) -> Vtable<'tcx, M> { + pub fn map_nested<M, F>(&self, op: F) -> Vtable<'tcx, M> where F: FnMut(&N) -> M { match *self { VtableImpl(ref i) => VtableImpl(i.map_nested(op)), VtableFnPointer(ref sig) => VtableFnPointer((*sig).clone()), @@ -322,7 +322,9 @@ impl<'tcx, N> Vtable<'tcx, N> { } } - pub fn map_move_nested<M>(self, op: |N| -> M) -> Vtable<'tcx, M> { + pub fn map_move_nested<M, F>(self, op: F) -> Vtable<'tcx, M> where + F: FnMut(N) -> M, + { match self { VtableImpl(i) => VtableImpl(i.map_move_nested(op)), VtableFnPointer(sig) => VtableFnPointer(sig), @@ -338,9 +340,8 @@ impl<'tcx, N> VtableImplData<'tcx, N> { self.nested.iter() } - pub fn map_nested<M>(&self, - op: |&N| -> M) - -> VtableImplData<'tcx, M> + pub fn map_nested<M, F>(&self, op: F) -> VtableImplData<'tcx, M> where + F: FnMut(&N) -> M, { VtableImplData { impl_def_id: self.impl_def_id, @@ -349,8 +350,9 @@ impl<'tcx, N> VtableImplData<'tcx, N> { } } - pub fn map_move_nested<M>(self, op: |N| -> M) - -> VtableImplData<'tcx, M> { + pub fn map_move_nested<M, F>(self, op: F) -> VtableImplData<'tcx, M> where + F: FnMut(N) -> M, + { let VtableImplData { impl_def_id, substs, nested } = self; VtableImplData { impl_def_id: impl_def_id, @@ -365,16 +367,15 @@ impl<N> VtableBuiltinData<N> { self.nested.iter() } - pub fn map_nested<M>(&self, - op: |&N| -> M) - -> VtableBuiltinData<M> - { + pub fn map_nested<M, F>(&self, op: F) -> VtableBuiltinData<M> where F: FnMut(&N) -> M { VtableBuiltinData { nested: self.nested.map(op) } } - pub fn map_move_nested<M>(self, op: |N| -> M) -> VtableBuiltinData<M> { + pub fn map_move_nested<M, F>(self, op: F) -> VtableBuiltinData<M> where + F: FnMut(N) -> M, + { VtableBuiltinData { nested: self.nested.map_move(op) } diff --git a/src/librustc/middle/traits/util.rs b/src/librustc/middle/traits/util.rs index 52154e0be7a..d8956246d32 100644 --- a/src/librustc/middle/traits/util.rs +++ b/src/librustc/middle/traits/util.rs @@ -306,10 +306,11 @@ pub fn predicate_for_builtin_bound<'tcx>( /// of caller obligations), search through the trait and supertraits to find one where `test(d)` is /// true, where `d` is the def-id of the trait/supertrait. If any is found, return `Some(p)` where /// `p` is the path to that trait/supertrait. Else `None`. -pub fn search_trait_and_supertraits_from_bound<'tcx>(tcx: &ty::ctxt<'tcx>, - caller_bound: Rc<ty::TraitRef<'tcx>>, - test: |ast::DefId| -> bool) - -> Option<VtableParamData<'tcx>> +pub fn search_trait_and_supertraits_from_bound<'tcx, F>(tcx: &ty::ctxt<'tcx>, + caller_bound: Rc<ty::TraitRef<'tcx>>, + mut test: F) + -> Option<VtableParamData<'tcx>> where + F: FnMut(ast::DefId) -> bool, { for bound in transitive_bounds(tcx, &[caller_bound]) { if test(bound.def_id) { diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs index ddbf69685cd..8e99045cffb 100644 --- a/src/librustc/middle/ty.rs +++ b/src/librustc/middle/ty.rs @@ -2420,10 +2420,13 @@ pub fn mk_param_from_def<'tcx>(cx: &ctxt<'tcx>, def: &TypeParameterDef) -> Ty<'t pub fn mk_open<'tcx>(cx: &ctxt<'tcx>, ty: Ty<'tcx>) -> Ty<'tcx> { mk_t(cx, ty_open(ty)) } -pub fn walk_ty<'tcx>(ty: Ty<'tcx>, f: |Ty<'tcx>|) { +pub fn walk_ty<'tcx, F>(ty: Ty<'tcx>, mut f: F) where + F: FnMut(Ty<'tcx>), +{ maybe_walk_ty(ty, |ty| { f(ty); true }); } +// FIXME(#19596) unbox `f` pub fn maybe_walk_ty<'tcx>(ty: Ty<'tcx>, f: |Ty<'tcx>| -> bool) { if !f(ty) { return; @@ -2464,9 +2467,11 @@ pub fn maybe_walk_ty<'tcx>(ty: Ty<'tcx>, f: |Ty<'tcx>| -> bool) { } // Folds types from the bottom up. -pub fn fold_ty<'tcx>(cx: &ctxt<'tcx>, t0: Ty<'tcx>, - fldop: |Ty<'tcx>| -> Ty<'tcx>) - -> Ty<'tcx> { +pub fn fold_ty<'tcx, F>(cx: &ctxt<'tcx>, t0: Ty<'tcx>, + fldop: F) + -> Ty<'tcx> where + F: FnMut(Ty<'tcx>) -> Ty<'tcx>, +{ let mut f = ty_fold::BottomUpFolder {tcx: cx, fldop: fldop}; f.fold_ty(t0) } @@ -2843,7 +2848,9 @@ impl TypeContents { *self & TC::ReachesAll } - pub fn union<T>(v: &[T], f: |&T| -> TypeContents) -> TypeContents { + pub fn union<T, F>(v: &[T], mut f: F) -> TypeContents where + F: FnMut(&T) -> TypeContents, + { v.iter().fold(TC::None, |tc, ty| tc | f(ty)) } @@ -3162,10 +3169,12 @@ pub fn type_contents<'tcx>(cx: &ctxt<'tcx>, ty: Ty<'tcx>) -> TypeContents { // Iterates over all builtin bounds on the type parameter def, including // those inherited from traits with builtin-kind-supertraits. - fn each_inherited_builtin_bound<'tcx>(cx: &ctxt<'tcx>, - bounds: BuiltinBounds, - traits: &[Rc<TraitRef<'tcx>>], - f: |BuiltinBound|) { + fn each_inherited_builtin_bound<'tcx, F>(cx: &ctxt<'tcx>, + bounds: BuiltinBounds, + traits: &[Rc<TraitRef<'tcx>>], + mut f: F) where + F: FnMut(BuiltinBound), + { for bound in bounds.iter() { f(bound); } @@ -3959,14 +3968,15 @@ pub fn local_var_name_str(cx: &ctxt, id: NodeId) -> InternedString { } /// See `expr_ty_adjusted` -pub fn adjust_ty<'tcx>(cx: &ctxt<'tcx>, - span: Span, - expr_id: ast::NodeId, - unadjusted_ty: Ty<'tcx>, - adjustment: Option<&AutoAdjustment<'tcx>>, - method_type: |MethodCall| -> Option<Ty<'tcx>>) - -> Ty<'tcx> { - +pub fn adjust_ty<'tcx, F>(cx: &ctxt<'tcx>, + span: Span, + expr_id: ast::NodeId, + unadjusted_ty: Ty<'tcx>, + adjustment: Option<&AutoAdjustment<'tcx>>, + mut method_type: F) + -> Ty<'tcx> where + F: FnMut(MethodCall) -> Option<Ty<'tcx>>, +{ if let ty_err = unadjusted_ty.sty { return unadjusted_ty; } @@ -4604,11 +4614,13 @@ pub fn provided_trait_methods<'tcx>(cx: &ctxt<'tcx>, id: ast::DefId) /// id is local, it should have been loaded into the map by the `typeck::collect` phase. If the /// def-id is external, then we have to go consult the crate loading code (and cache the result for /// the future). -fn lookup_locally_or_in_crate_store<V:Clone>( - descr: &str, - def_id: ast::DefId, - map: &mut DefIdMap<V>, - load_external: || -> V) -> V { +fn lookup_locally_or_in_crate_store<V, F>(descr: &str, + def_id: ast::DefId, + map: &mut DefIdMap<V>, + load_external: F) -> V where + V: Clone, + F: FnOnce() -> V, +{ match map.get(&def_id).cloned() { Some(v) => { return v; } None => { } @@ -4916,7 +4928,9 @@ pub fn has_dtor(cx: &ctxt, struct_id: DefId) -> bool { cx.destructor_for_type.borrow().contains_key(&struct_id) } -pub fn with_path<T>(cx: &ctxt, id: ast::DefId, f: |ast_map::PathElems| -> T) -> T { +pub fn with_path<T, F>(cx: &ctxt, id: ast::DefId, f: F) -> T where + F: FnOnce(ast_map::PathElems) -> T, +{ if id.krate == ast::LOCAL_CRATE { cx.map.with_path(id.node, f) } else { @@ -5162,7 +5176,9 @@ pub fn predicates<'tcx>( /// Iterate over attributes of a definition. // (This should really be an iterator, but that would require csearch and // decoder to use iterators instead of higher-order functions.) -pub fn each_attr(tcx: &ctxt, did: DefId, f: |&ast::Attribute| -> bool) -> bool { +pub fn each_attr<F>(tcx: &ctxt, did: DefId, mut f: F) -> bool where + F: FnMut(&ast::Attribute) -> bool, +{ if is_local(did) { let item = tcx.map.expect_item(did.node); item.attrs.iter().all(|attr| f(attr)) @@ -5501,10 +5517,11 @@ pub fn eval_repeat_count(tcx: &ctxt, count_expr: &ast::Expr) -> uint { // Here, the supertraits are the transitive closure of the supertrait // relation on the supertraits from each bounded trait's constraint // list. -pub fn each_bound_trait_and_supertraits<'tcx>(tcx: &ctxt<'tcx>, - bounds: &[Rc<TraitRef<'tcx>>], - f: |Rc<TraitRef<'tcx>>| -> bool) - -> bool +pub fn each_bound_trait_and_supertraits<'tcx, F>(tcx: &ctxt<'tcx>, + bounds: &[Rc<TraitRef<'tcx>>], + mut f: F) + -> bool where + F: FnMut(Rc<TraitRef<'tcx>>) -> bool, { for bound_trait_ref in traits::transitive_bounds(tcx, bounds) { if !f(bound_trait_ref) { @@ -6192,7 +6209,9 @@ pub type FreevarMap = NodeMap<Vec<Freevar>>; pub type CaptureModeMap = NodeMap<ast::CaptureClause>; -pub fn with_freevars<T>(tcx: &ty::ctxt, fid: ast::NodeId, f: |&[Freevar]| -> T) -> T { +pub fn with_freevars<T, F>(tcx: &ty::ctxt, fid: ast::NodeId, f: F) -> T where + F: FnOnce(&[Freevar]) -> T, +{ match tcx.freevars.borrow().get(&fid) { None => f(&[]), Some(d) => f(d.as_slice()) @@ -6240,12 +6259,13 @@ pub fn erase_late_bound_regions<'tcx, HR>( } /// Replaces the late-bound-regions in `value` that are bound by `value`. -pub fn replace_late_bound_regions<'tcx, HR>( +pub fn replace_late_bound_regions<'tcx, HR, F>( tcx: &ty::ctxt<'tcx>, value: &HR, - mapf: |BoundRegion, DebruijnIndex| -> ty::Region) - -> (HR, FnvHashMap<ty::BoundRegion,ty::Region>) - where HR : HigherRankedFoldable<'tcx> + mut mapf: F) +-> (HR, FnvHashMap<ty::BoundRegion, ty::Region>) where + HR : HigherRankedFoldable<'tcx>, + F: FnMut(BoundRegion, DebruijnIndex) -> ty::Region, { debug!("replace_late_bound_regions({})", value.repr(tcx)); diff --git a/src/librustc/middle/ty_fold.rs b/src/librustc/middle/ty_fold.rs index 8b54a46bfb9..63ee71dc6a5 100644 --- a/src/librustc/middle/ty_fold.rs +++ b/src/librustc/middle/ty_fold.rs @@ -743,12 +743,14 @@ impl<'tcx, T:HigherRankedFoldable<'tcx>> HigherRankedFoldable<'tcx> for Rc<T> { /////////////////////////////////////////////////////////////////////////// // Some sample folders -pub struct BottomUpFolder<'a, 'tcx: 'a> { +pub struct BottomUpFolder<'a, 'tcx: 'a, F> where F: FnMut(Ty<'tcx>) -> Ty<'tcx> { pub tcx: &'a ty::ctxt<'tcx>, - pub fldop: |Ty<'tcx>|: 'a -> Ty<'tcx>, + pub fldop: F, } -impl<'a, 'tcx> TypeFolder<'tcx> for BottomUpFolder<'a, 'tcx> { +impl<'a, 'tcx, F> TypeFolder<'tcx> for BottomUpFolder<'a, 'tcx, F> where + F: FnMut(Ty<'tcx>) -> Ty<'tcx>, +{ fn tcx<'a>(&'a self) -> &'a ty::ctxt<'tcx> { self.tcx } fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> { @@ -772,15 +774,14 @@ impl<'a, 'tcx> TypeFolder<'tcx> for BottomUpFolder<'a, 'tcx> { /// (The distinction between "free" and "bound" is represented by /// keeping track of each `FnSig` in the lexical context of the /// current position of the fold.) -pub struct RegionFolder<'a, 'tcx: 'a> { +pub struct RegionFolder<'a, 'tcx: 'a, F> where F: FnMut(ty::Region, uint) -> ty::Region { tcx: &'a ty::ctxt<'tcx>, current_depth: uint, - fld_r: |ty::Region, uint|: 'a -> ty::Region, + fld_r: F, } -impl<'a, 'tcx> RegionFolder<'a, 'tcx> { - pub fn new(tcx: &'a ty::ctxt<'tcx>, fld_r: |ty::Region, uint|: 'a -> ty::Region) - -> RegionFolder<'a, 'tcx> { +impl<'a, 'tcx, F> RegionFolder<'a, 'tcx, F> where F: FnMut(ty::Region, uint) -> ty::Region { + pub fn new(tcx: &'a ty::ctxt<'tcx>, fld_r: F) -> RegionFolder<'a, 'tcx, F> { RegionFolder { tcx: tcx, current_depth: 1, @@ -789,7 +790,9 @@ impl<'a, 'tcx> RegionFolder<'a, 'tcx> { } } -impl<'a, 'tcx> TypeFolder<'tcx> for RegionFolder<'a, 'tcx> { +impl<'a, 'tcx, F> TypeFolder<'tcx> for RegionFolder<'a, 'tcx, F> where + F: FnMut(ty::Region, uint) -> ty::Region, +{ fn tcx<'a>(&'a self) -> &'a ty::ctxt<'tcx> { self.tcx } fn enter_region_binder(&mut self) { diff --git a/src/librustc/session/mod.rs b/src/librustc/session/mod.rs index e4d34e09d33..8516ece202c 100644 --- a/src/librustc/session/mod.rs +++ b/src/librustc/session/mod.rs @@ -288,7 +288,9 @@ pub fn build_session_(sopts: config::Options, } // Seems out of place, but it uses session, so I'm putting it here -pub fn expect<T>(sess: &Session, opt: Option<T>, msg: || -> String) -> T { +pub fn expect<T, M>(sess: &Session, opt: Option<T>, msg: M) -> T where + M: FnOnce() -> String, +{ diagnostic::expect(sess.diagnostic(), opt, msg) } diff --git a/src/librustc/util/common.rs b/src/librustc/util/common.rs index 30318cc129c..51e18c80d05 100644 --- a/src/librustc/util/common.rs +++ b/src/librustc/util/common.rs @@ -27,7 +27,9 @@ pub struct ErrorReported; impl Copy for ErrorReported {} -pub fn time<T, U>(do_it: bool, what: &str, u: U, f: |U| -> T) -> T { +pub fn time<T, U, F>(do_it: bool, what: &str, u: U, f: F) -> T where + F: FnOnce(U) -> T, +{ thread_local!(static DEPTH: Cell<uint> = Cell::new(0)); if !do_it { return f(u); } @@ -39,9 +41,13 @@ pub fn time<T, U>(do_it: bool, what: &str, u: U, f: |U| -> T) -> T { let mut u = Some(u); let mut rv = None; - let dur = Duration::span(|| { - rv = Some(f(u.take().unwrap())) - }); + let dur = { + let ref mut rvp = rv; + + Duration::span(move || { + *rvp = Some(f(u.take().unwrap())) + }) + }; let rv = rv.unwrap(); println!("{}time: {}.{:03} \t{}", " ".repeat(old), @@ -51,7 +57,10 @@ pub fn time<T, U>(do_it: bool, what: &str, u: U, f: |U| -> T) -> T { rv } -pub fn indent<R: Show>(op: || -> R) -> R { +pub fn indent<R, F>(op: F) -> R where + R: Show, + F: FnOnce() -> R, +{ // Use in conjunction with the log post-processor like `src/etc/indenter` // to make debug output more readable. debug!(">>"); @@ -73,12 +82,12 @@ pub fn indenter() -> Indenter { Indenter { _cannot_construct_outside_of_this_module: () } } -struct LoopQueryVisitor<'a> { - p: |&ast::Expr_|: 'a -> bool, +struct LoopQueryVisitor<P> where P: FnMut(&ast::Expr_) -> bool { + p: P, flag: bool, } -impl<'a, 'v> Visitor<'v> for LoopQueryVisitor<'a> { +impl<'v, P> Visitor<'v> for LoopQueryVisitor<P> where P: FnMut(&ast::Expr_) -> bool { fn visit_expr(&mut self, e: &ast::Expr) { self.flag |= (self.p)(&e.node); match e.node { @@ -92,7 +101,7 @@ impl<'a, 'v> Visitor<'v> for LoopQueryVisitor<'a> { // Takes a predicate p, returns true iff p is true for any subexpressions // of b -- skipping any inner loops (loop, while, loop_body) -pub fn loop_query(b: &ast::Block, p: |&ast::Expr_| -> bool) -> bool { +pub fn loop_query<P>(b: &ast::Block, p: P) -> bool where P: FnMut(&ast::Expr_) -> bool { let mut v = LoopQueryVisitor { p: p, flag: false, @@ -101,12 +110,12 @@ pub fn loop_query(b: &ast::Block, p: |&ast::Expr_| -> bool) -> bool { return v.flag; } -struct BlockQueryVisitor<'a> { - p: |&ast::Expr|: 'a -> bool, +struct BlockQueryVisitor<P> where P: FnMut(&ast::Expr) -> bool { + p: P, flag: bool, } -impl<'a, 'v> Visitor<'v> for BlockQueryVisitor<'a> { +impl<'v, P> Visitor<'v> for BlockQueryVisitor<P> where P: FnMut(&ast::Expr) -> bool { fn visit_expr(&mut self, e: &ast::Expr) { self.flag |= (self.p)(e); visit::walk_expr(self, e) @@ -115,7 +124,7 @@ impl<'a, 'v> Visitor<'v> for BlockQueryVisitor<'a> { // Takes a predicate p, returns true iff p is true for any subexpressions // of b -- skipping any inner loops (loop, while, loop_body) -pub fn block_query(b: &ast::Block, p: |&ast::Expr| -> bool) -> bool { +pub fn block_query<P>(b: &ast::Block, p: P) -> bool where P: FnMut(&ast::Expr) -> bool { let mut v = BlockQueryVisitor { p: p, flag: false, @@ -194,11 +203,12 @@ pub fn can_reach<S,H:Hasher<S>,T:Eq+Clone+Hash<S>>( /// } /// ``` #[inline(always)] -pub fn memoized<T: Clone + Hash<S> + Eq, U: Clone, S, H: Hasher<S>>( - cache: &RefCell<HashMap<T, U, H>>, - arg: T, - f: |T| -> U -) -> U { +pub fn memoized<T, U, S, H, F>(cache: &RefCell<HashMap<T, U, H>>, arg: T, f: F) -> U where + T: Clone + Hash<S> + Eq, + U: Clone, + H: Hasher<S>, + F: FnOnce(T) -> U, +{ let key = arg.clone(); let result = cache.borrow().get(&key).map(|result| result.clone()); match result { diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs index 7a14ed9cca8..5dbf3208595 100644 --- a/src/librustc/util/ppaux.rs +++ b/src/librustc/util/ppaux.rs @@ -241,7 +241,9 @@ pub fn trait_store_to_string(cx: &ctxt, s: ty::TraitStore) -> String { } } -pub fn vec_map_to_string<T>(ts: &[T], f: |t: &T| -> String) -> String { +pub fn vec_map_to_string<T, F>(ts: &[T], f: F) -> String where + F: FnMut(&T) -> String, +{ let tstrs = ts.iter().map(f).collect::<Vec<String>>(); format!("[{}]", tstrs.connect(", ")) } diff --git a/src/librustc_back/archive.rs b/src/librustc_back/archive.rs index a88bcafaa64..3a451070316 100644 --- a/src/librustc_back/archive.rs +++ b/src/librustc_back/archive.rs @@ -279,8 +279,9 @@ impl<'a> ArchiveBuilder<'a> { self.archive } - fn add_archive(&mut self, archive: &Path, name: &str, - skip: |&str| -> bool) -> io::IoResult<()> { + fn add_archive<F>(&mut self, archive: &Path, name: &str, mut skip: F) -> io::IoResult<()> where + F: FnMut(&str) -> bool, + { let loc = TempDir::new("rsar").unwrap(); // First, extract the contents of the archive to a temporary directory. diff --git a/src/librustc_back/lib.rs b/src/librustc_back/lib.rs index fc98a5cd6b5..cb547df7d9c 100644 --- a/src/librustc_back/lib.rs +++ b/src/librustc_back/lib.rs @@ -31,6 +31,7 @@ #![allow(unknown_features)] #![feature(globs, phase, macro_rules, slicing_syntax)] +#![feature(unboxed_closures)] #[phase(plugin, link)] extern crate log; diff --git a/src/librustc_back/rpath.rs b/src/librustc_back/rpath.rs index a90b49ba101..1f8549098d9 100644 --- a/src/librustc_back/rpath.rs +++ b/src/librustc_back/rpath.rs @@ -14,17 +14,22 @@ use std::os; use std::io::IoError; use syntax::ast; -pub struct RPathConfig<'a> { +pub struct RPathConfig<F, G> where + F: FnOnce() -> Path, + G: FnMut(&Path) -> Result<Path, IoError>, +{ pub used_crates: Vec<(ast::CrateNum, Option<Path>)>, pub out_filename: Path, pub is_like_osx: bool, pub has_rpath: bool, - pub get_install_prefix_lib_path: ||:'a -> Path, - pub realpath: |&Path|:'a -> Result<Path, IoError> + pub get_install_prefix_lib_path: F, + pub realpath: G, } -pub fn get_rpath_flags(config: RPathConfig) -> Vec<String> { - +pub fn get_rpath_flags<F, G>(config: RPathConfig<F, G>) -> Vec<String> where + F: FnOnce() -> Path, + G: FnMut(&Path) -> Result<Path, IoError>, +{ // No rpath on windows if !config.has_rpath { return Vec::new(); @@ -52,8 +57,10 @@ fn rpaths_to_flags(rpaths: &[String]) -> Vec<String> { return ret; } -fn get_rpaths(mut config: RPathConfig, - libs: &[Path]) -> Vec<String> { +fn get_rpaths<F, G>(mut config: RPathConfig<F, G>, libs: &[Path]) -> Vec<String> where + F: FnOnce() -> Path, + G: FnMut(&Path) -> Result<Path, IoError>, +{ debug!("output: {}", config.out_filename.display()); debug!("libs:"); for libpath in libs.iter() { @@ -86,13 +93,18 @@ fn get_rpaths(mut config: RPathConfig, return rpaths; } -fn get_rpaths_relative_to_output(config: &mut RPathConfig, - libs: &[Path]) -> Vec<String> { +fn get_rpaths_relative_to_output<F, G>(config: &mut RPathConfig<F, G>, + libs: &[Path]) -> Vec<String> where + F: FnOnce() -> Path, + G: FnMut(&Path) -> Result<Path, IoError>, +{ libs.iter().map(|a| get_rpath_relative_to_output(config, a)).collect() } -fn get_rpath_relative_to_output(config: &mut RPathConfig, - lib: &Path) -> String { +fn get_rpath_relative_to_output<F, G>(config: &mut RPathConfig<F, G>, lib: &Path) -> String where + F: FnOnce() -> Path, + G: FnMut(&Path) -> Result<Path, IoError>, +{ use std::os; // Mac doesn't appear to support $ORIGIN @@ -114,7 +126,10 @@ fn get_rpath_relative_to_output(config: &mut RPathConfig, relative.as_str().expect("non-utf8 component in path")) } -fn get_install_prefix_rpath(config: RPathConfig) -> String { +fn get_install_prefix_rpath<F, G>(config: RPathConfig<F, G>) -> String where + F: FnOnce() -> Path, + G: FnMut(&Path) -> Result<Path, IoError>, +{ let path = (config.get_install_prefix_lib_path)(); let path = os::make_absolute(&path).unwrap(); // FIXME (#9639): This needs to handle non-utf8 paths diff --git a/src/librustc_back/sha2.rs b/src/librustc_back/sha2.rs index 1b662ef1787..1587104ca49 100644 --- a/src/librustc_back/sha2.rs +++ b/src/librustc_back/sha2.rs @@ -82,7 +82,8 @@ fn add_bytes_to_bits<T: Int + ToBits>(bits: T, bytes: T) -> T { trait FixedBuffer { /// Input a vector of bytes. If the buffer becomes full, process it with the provided /// function and then clear the buffer. - fn input(&mut self, input: &[u8], func: |&[u8]|); + fn input<F>(&mut self, input: &[u8], func: F) where + F: FnMut(&[u8]); /// Reset the buffer. fn reset(&mut self); @@ -125,7 +126,9 @@ impl FixedBuffer64 { } impl FixedBuffer for FixedBuffer64 { - fn input(&mut self, input: &[u8], func: |&[u8]|) { + fn input<F>(&mut self, input: &[u8], mut func: F) where + F: FnMut(&[u8]), + { let mut i = 0; let size = self.size(); @@ -201,11 +204,11 @@ trait StandardPadding { /// guaranteed to have exactly rem remaining bytes when it returns. If there are not at least /// rem bytes available, the buffer will be zero padded, processed, cleared, and then filled /// with zeros again until only rem bytes are remaining. - fn standard_padding(&mut self, rem: uint, func: |&[u8]|); + fn standard_padding<F>(&mut self, rem: uint, func: F) where F: FnMut(&[u8]); } impl <T: FixedBuffer> StandardPadding for T { - fn standard_padding(&mut self, rem: uint, func: |&[u8]|) { + fn standard_padding<F>(&mut self, rem: uint, mut func: F) where F: FnMut(&[u8]) { let size = self.size(); self.next(1)[0] = 128; diff --git a/src/librustc_borrowck/borrowck/check_loans.rs b/src/librustc_borrowck/borrowck/check_loans.rs index 4244cec7534..3bf817b42b0 100644 --- a/src/librustc_borrowck/borrowck/check_loans.rs +++ b/src/librustc_borrowck/borrowck/check_loans.rs @@ -232,8 +232,9 @@ fn compatible_borrow_kinds(borrow_kind1: ty::BorrowKind, impl<'a, 'tcx> CheckLoanCtxt<'a, 'tcx> { pub fn tcx(&self) -> &'a ty::ctxt<'tcx> { self.bccx.tcx } - pub fn each_issued_loan(&self, scope: region::CodeExtent, op: |&Loan<'tcx>| -> bool) - -> bool { + pub fn each_issued_loan<F>(&self, scope: region::CodeExtent, mut op: F) -> bool where + F: FnMut(&Loan<'tcx>) -> bool, + { //! Iterates over each loan that has been issued //! on entrance to `scope`, regardless of whether it is //! actually *in scope* at that point. Sometimes loans @@ -246,10 +247,9 @@ impl<'a, 'tcx> CheckLoanCtxt<'a, 'tcx> { }) } - pub fn each_in_scope_loan(&self, - scope: region::CodeExtent, - op: |&Loan<'tcx>| -> bool) - -> bool { + pub fn each_in_scope_loan<F>(&self, scope: region::CodeExtent, mut op: F) -> bool where + F: FnMut(&Loan<'tcx>) -> bool, + { //! Like `each_issued_loan()`, but only considers loans that are //! currently in scope. @@ -263,11 +263,13 @@ impl<'a, 'tcx> CheckLoanCtxt<'a, 'tcx> { }) } - fn each_in_scope_loan_affecting_path(&self, - scope: region::CodeExtent, - loan_path: &LoanPath<'tcx>, - op: |&Loan<'tcx>| -> bool) - -> bool { + fn each_in_scope_loan_affecting_path<F>(&self, + scope: region::CodeExtent, + loan_path: &LoanPath<'tcx>, + mut op: F) + -> bool where + F: FnMut(&Loan<'tcx>) -> bool, + { //! Iterates through all of the in-scope loans affecting `loan_path`, //! calling `op`, and ceasing iteration if `false` is returned. diff --git a/src/librustc_borrowck/borrowck/move_data.rs b/src/librustc_borrowck/borrowck/move_data.rs index 681a5772849..00b1377af73 100644 --- a/src/librustc_borrowck/borrowck/move_data.rs +++ b/src/librustc_borrowck/borrowck/move_data.rs @@ -523,8 +523,9 @@ impl<'tcx> MoveData<'tcx> { } } - fn each_base_path(&self, index: MovePathIndex, f: |MovePathIndex| -> bool) - -> bool { + fn each_base_path<F>(&self, index: MovePathIndex, mut f: F) -> bool where + F: FnMut(MovePathIndex) -> bool, + { let mut p = index; while p != InvalidMovePathIndex { if !f(p) { @@ -535,10 +536,8 @@ impl<'tcx> MoveData<'tcx> { return true; } - fn each_extending_path(&self, - index: MovePathIndex, - f: |MovePathIndex| -> bool) - -> bool { + // FIXME(#19596) unbox `f` + fn each_extending_path(&self, index: MovePathIndex, f: |MovePathIndex| -> bool) -> bool { if !f(index) { return false; } @@ -554,10 +553,9 @@ impl<'tcx> MoveData<'tcx> { return true; } - fn each_applicable_move(&self, - index0: MovePathIndex, - f: |MoveIndex| -> bool) - -> bool { + fn each_applicable_move<F>(&self, index0: MovePathIndex, mut f: F) -> bool where + F: FnMut(MoveIndex) -> bool, + { let mut ret = true; self.each_extending_path(index0, |index| { let mut p = self.path_first_move(index); @@ -660,11 +658,13 @@ impl<'a, 'tcx> FlowedMoveData<'a, 'tcx> { /// Iterates through each move of `loan_path` (or some base path of `loan_path`) that *may* /// have occurred on entry to `id` without an intervening assignment. In other words, any moves /// that would invalidate a reference to `loan_path` at location `id`. - pub fn each_move_of(&self, - id: ast::NodeId, - loan_path: &Rc<LoanPath<'tcx>>, - f: |&Move, &LoanPath<'tcx>| -> bool) - -> bool { + pub fn each_move_of<F>(&self, + id: ast::NodeId, + loan_path: &Rc<LoanPath<'tcx>>, + mut f: F) + -> bool where + F: FnMut(&Move, &LoanPath<'tcx>) -> bool, + { // Bad scenarios: // // 1. Move of `a.b.c`, use of `a.b.c` @@ -715,11 +715,13 @@ impl<'a, 'tcx> FlowedMoveData<'a, 'tcx> { /// Iterates through every assignment to `loan_path` that may have occurred on entry to `id`. /// `loan_path` must be a single variable. - pub fn each_assignment_of(&self, - id: ast::NodeId, - loan_path: &Rc<LoanPath<'tcx>>, - f: |&Assignment| -> bool) - -> bool { + pub fn each_assignment_of<F>(&self, + id: ast::NodeId, + loan_path: &Rc<LoanPath<'tcx>>, + mut f: F) + -> bool where + F: FnMut(&Assignment) -> bool, + { let loan_path_index = { match self.move_data.existing_move_path(loan_path) { Some(i) => i, diff --git a/src/librustc_borrowck/graphviz.rs b/src/librustc_borrowck/graphviz.rs index 36c74720be4..e09ec791669 100644 --- a/src/librustc_borrowck/graphviz.rs +++ b/src/librustc_borrowck/graphviz.rs @@ -75,11 +75,13 @@ impl<'a, 'tcx> DataflowLabeller<'a, 'tcx> { } } - fn build_set<O:DataFlowOperator>(&self, - e: EntryOrExit, - cfgidx: CFGIndex, - dfcx: &DataFlowContext<'a, 'tcx, O>, - to_lp: |uint| -> Rc<LoanPath<'tcx>>) -> String { + fn build_set<O:DataFlowOperator, F>(&self, + e: EntryOrExit, + cfgidx: CFGIndex, + dfcx: &DataFlowContext<'a, 'tcx, O>, + mut to_lp: F) -> String where + F: FnMut(uint) -> Rc<LoanPath<'tcx>>, + { let mut saw_some = false; let mut set = "{".to_string(); dfcx.each_bit_for_node(e, cfgidx, |index| { @@ -98,7 +100,7 @@ impl<'a, 'tcx> DataflowLabeller<'a, 'tcx> { fn dataflow_loans_for(&self, e: EntryOrExit, cfgidx: CFGIndex) -> String { let dfcx = &self.analysis_data.loans; - let loan_index_to_path = |loan_index| { + let loan_index_to_path = |&mut: loan_index| { let all_loans = &self.analysis_data.all_loans; all_loans[loan_index].loan_path() }; @@ -107,7 +109,7 @@ impl<'a, 'tcx> DataflowLabeller<'a, 'tcx> { fn dataflow_moves_for(&self, e: EntryOrExit, cfgidx: CFGIndex) -> String { let dfcx = &self.analysis_data.move_data.dfcx_moves; - let move_index_to_path = |move_index| { + let move_index_to_path = |&mut: move_index| { let move_data = &self.analysis_data.move_data.move_data; let moves = move_data.moves.borrow(); let the_move = &(*moves)[move_index]; @@ -118,7 +120,7 @@ impl<'a, 'tcx> DataflowLabeller<'a, 'tcx> { fn dataflow_assigns_for(&self, e: EntryOrExit, cfgidx: CFGIndex) -> String { let dfcx = &self.analysis_data.move_data.dfcx_assign; - let assign_index_to_path = |assign_index| { + let assign_index_to_path = |&mut: assign_index| { let move_data = &self.analysis_data.move_data.move_data; let assignments = move_data.var_assignments.borrow(); let assignment = &(*assignments)[assign_index]; diff --git a/src/librustc_borrowck/lib.rs b/src/librustc_borrowck/lib.rs index f187c0c1530..db19a09deba 100644 --- a/src/librustc_borrowck/lib.rs +++ b/src/librustc_borrowck/lib.rs @@ -19,6 +19,7 @@ #![feature(default_type_params, globs, if_let, import_shadowing, macro_rules, phase, quote)] #![feature(slicing_syntax, tuple_indexing, unsafe_destructor)] #![feature(rustc_diagnostic_macros)] +#![feature(unboxed_closures)] #![allow(non_camel_case_types)] #[phase(plugin, link)] extern crate log; diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs index 85d9646c282..d655b704053 100644 --- a/src/librustc_driver/lib.rs +++ b/src/librustc_driver/lib.rs @@ -25,6 +25,7 @@ #![feature(default_type_params, globs, import_shadowing, macro_rules, phase, quote)] #![feature(slicing_syntax, unsafe_destructor)] #![feature(rustc_diagnostic_macros)] +#![feature(unboxed_closures)] extern crate arena; extern crate flate; diff --git a/src/librustc_driver/pretty.rs b/src/librustc_driver/pretty.rs index 971379b8dd2..7ec05b6a030 100644 --- a/src/librustc_driver/pretty.rs +++ b/src/librustc_driver/pretty.rs @@ -78,7 +78,7 @@ pub fn parse_pretty(sess: &Session, name: &str) -> (PpMode, Option<UserIdentifie or `expanded,identified`; got {}", name).as_slice()); } }; - let opt_second = opt_second.and_then::<UserIdentifiedItem>(from_str); + let opt_second = opt_second.and_then::<UserIdentifiedItem, _>(from_str); (first, opt_second) } @@ -99,13 +99,15 @@ pub fn parse_pretty(sess: &Session, name: &str) -> (PpMode, Option<UserIdentifie impl PpSourceMode { /// Constructs a `PrinterSupport` object and passes it to `f`. - fn call_with_pp_support<'tcx, A, B>(&self, - sess: Session, - ast_map: Option<ast_map::Map<'tcx>>, - type_arena: &'tcx TypedArena<ty::TyS<'tcx>>, - id: String, - payload: B, - f: |&PrinterSupport, B| -> A) -> A { + fn call_with_pp_support<'tcx, A, B, F>(&self, + sess: Session, + ast_map: Option<ast_map::Map<'tcx>>, + type_arena: &'tcx TypedArena<ty::TyS<'tcx>>, + id: String, + payload: B, + f: F) -> A where + F: FnOnce(&PrinterSupport, B) -> A, + { match *self { PpmNormal | PpmExpanded => { let annotation = NoAnn { sess: sess, ast_map: ast_map }; @@ -313,14 +315,12 @@ pub enum UserIdentifiedItem { impl FromStr for UserIdentifiedItem { fn from_str(s: &str) -> Option<UserIdentifiedItem> { - let extract_path_parts = || { + from_str(s).map(ItemViaNode).or_else(|| { let v : Vec<_> = s.split_str("::") .map(|x|x.to_string()) .collect(); Some(ItemViaPath(v)) - }; - - from_str(s).map(ItemViaNode).or_else(extract_path_parts) + }) } } diff --git a/src/librustc_driver/test.rs b/src/librustc_driver/test.rs index 9404802cb68..dda3754cf73 100644 --- a/src/librustc_driver/test.rs +++ b/src/librustc_driver/test.rs @@ -93,9 +93,11 @@ fn errors(msgs: &[&str]) -> (Box<Emitter+Send>, uint) { (box ExpectErrorEmitter { messages: v } as Box<Emitter+Send>, msgs.len()) } -fn test_env(source_string: &str, - (emitter, expected_err_count): (Box<Emitter+Send>, uint), - body: |Env|) { +fn test_env<F>(source_string: &str, + (emitter, expected_err_count): (Box<Emitter+Send>, uint), + body: F) where + F: FnOnce(Env), +{ let mut options = config::basic_options(); options.debugging_opts |= config::VERBOSE; diff --git a/src/librustc_llvm/lib.rs b/src/librustc_llvm/lib.rs index 23dad21e530..7d8338ba976 100644 --- a/src/librustc_llvm/lib.rs +++ b/src/librustc_llvm/lib.rs @@ -23,6 +23,7 @@ #![feature(globs)] #![feature(link_args)] +#![feature(unboxed_closures)] extern crate libc; @@ -2206,7 +2207,7 @@ pub unsafe extern "C" fn rust_llvm_string_write_impl(sr: RustStringRef, (*sr).borrow_mut().push_all(slice); } -pub fn build_string(f: |RustStringRef|) -> Option<String> { +pub fn build_string<F>(f: F) -> Option<String> where F: FnOnce(RustStringRef){ let mut buf = RefCell::new(Vec::new()); f(&mut buf as RustStringRepr as RustStringRef); String::from_utf8(buf.into_inner()).ok() diff --git a/src/librustc_trans/back/link.rs b/src/librustc_trans/back/link.rs index 62f8177ed75..5617110bfec 100644 --- a/src/librustc_trans/back/link.rs +++ b/src/librustc_trans/back/link.rs @@ -1002,7 +1002,7 @@ fn link_args(cmd: &mut Command, if sess.opts.cg.rpath { let sysroot = sess.sysroot(); let target_triple = sess.opts.target_triple.as_slice(); - let get_install_prefix_lib_path = || { + let get_install_prefix_lib_path = |:| { let install_prefix = option_env!("CFG_PREFIX").expect("CFG_PREFIX"); let tlib = filesearch::relative_target_lib_path(sysroot, target_triple); let mut path = Path::new(install_prefix); diff --git a/src/librustc_trans/back/lto.rs b/src/librustc_trans/back/lto.rs index a715849ddf6..fb4d6de5f28 100644 --- a/src/librustc_trans/back/lto.rs +++ b/src/librustc_trans/back/lto.rs @@ -81,8 +81,9 @@ pub fn run(sess: &session::Session, llmod: ModuleRef, break; }, }; - let bc_extractor = if is_versioned_bytecode_format(bc_encoded) { - |_| { + + let bc_decoded = if is_versioned_bytecode_format(bc_encoded) { + time(sess.time_passes(), format!("decode {}.{}.bc", file, i).as_slice(), (), |_| { // Read the version let version = extract_bytecode_format_version(bc_encoded); @@ -104,11 +105,11 @@ pub fn run(sess: &session::Session, llmod: ModuleRef, sess.fatal(format!("Unsupported bytecode format version {}", version).as_slice()) } - } + }) } else { + time(sess.time_passes(), format!("decode {}.{}.bc", file, i).as_slice(), (), |_| { // the object must be in the old, pre-versioning format, so simply // inflate everything and let LLVM decide if it can make sense of it - |_| { match flate::inflate_bytes(bc_encoded) { Some(bc) => bc, None => { @@ -116,14 +117,9 @@ pub fn run(sess: &session::Session, llmod: ModuleRef, name).as_slice()) } } - } + }) }; - let bc_decoded = time(sess.time_passes(), - format!("decode {}.{}.bc", file, i).as_slice(), - (), - bc_extractor); - let ptr = bc_decoded.as_slice().as_ptr(); debug!("linking {}, part {}", name, i); time(sess.time_passes(), diff --git a/src/librustc_trans/back/write.rs b/src/librustc_trans/back/write.rs index 0ed6ae31171..c52f31532dc 100644 --- a/src/librustc_trans/back/write.rs +++ b/src/librustc_trans/back/write.rs @@ -488,8 +488,12 @@ unsafe fn optimize_and_codegen(cgcx: &CodegenContext, // pass manager passed to the closure should be ensured to not // escape the closure itself, and the manager should only be // used once. - unsafe fn with_codegen(tm: TargetMachineRef, llmod: ModuleRef, - no_builtins: bool, f: |PassManagerRef|) { + unsafe fn with_codegen<F>(tm: TargetMachineRef, + llmod: ModuleRef, + no_builtins: bool, + f: F) where + F: FnOnce(PassManagerRef), + { let cpm = llvm::LLVMCreatePassManager(); llvm::LLVMRustAddAnalysisPasses(tm, cpm, llmod); llvm::LLVMRustAddLibraryInfo(cpm, llmod, no_builtins); diff --git a/src/librustc_trans/lib.rs b/src/librustc_trans/lib.rs index 2421b39b8bb..05b1a86b72b 100644 --- a/src/librustc_trans/lib.rs +++ b/src/librustc_trans/lib.rs @@ -25,6 +25,7 @@ #![feature(default_type_params, globs, import_shadowing, macro_rules, phase, quote)] #![feature(slicing_syntax, unsafe_destructor)] #![feature(rustc_diagnostic_macros)] +#![feature(unboxed_closures)] extern crate arena; extern crate flate; diff --git a/src/librustc_trans/save/mod.rs b/src/librustc_trans/save/mod.rs index 2a698a898fe..329241b24e6 100644 --- a/src/librustc_trans/save/mod.rs +++ b/src/librustc_trans/save/mod.rs @@ -79,7 +79,9 @@ struct DxrVisitor<'l, 'tcx: 'l> { } impl <'l, 'tcx> DxrVisitor<'l, 'tcx> { - fn nest(&mut self, scope_id: NodeId, f: |&mut DxrVisitor<'l, 'tcx>|) { + fn nest<F>(&mut self, scope_id: NodeId, f: F) where + F: FnOnce(&mut DxrVisitor<'l, 'tcx>), + { let parent_scope = self.cur_scope; self.cur_scope = scope_id; f(self); diff --git a/src/librustc_trans/trans/_match.rs b/src/librustc_trans/trans/_match.rs index 1ed06938e95..b0512925719 100644 --- a/src/librustc_trans/trans/_match.rs +++ b/src/librustc_trans/trans/_match.rs @@ -771,7 +771,7 @@ fn pick_column_to_specialize(def_map: &DefMap, m: &[Match]) -> Option<uint> { } }; - let column_contains_any_nonwild_patterns: |&uint| -> bool = |&col| { + let column_contains_any_nonwild_patterns = |&: &col: &uint| -> bool { m.iter().any(|row| match row.pats[col].node { ast::PatWild(_) => false, _ => true @@ -1578,14 +1578,15 @@ pub fn store_for_loop_binding<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, bind_irrefutable_pat(bcx, pat, llvalue, body_scope) } -fn mk_binding_alloca<'blk, 'tcx, A>(bcx: Block<'blk, 'tcx>, - p_id: ast::NodeId, - ident: &ast::Ident, - cleanup_scope: cleanup::ScopeId, - arg: A, - populate: |A, Block<'blk, 'tcx>, ValueRef, Ty<'tcx>| - -> Block<'blk, 'tcx>) - -> Block<'blk, 'tcx> { +fn mk_binding_alloca<'blk, 'tcx, A, F>(bcx: Block<'blk, 'tcx>, + p_id: ast::NodeId, + ident: &ast::Ident, + cleanup_scope: cleanup::ScopeId, + arg: A, + populate: F) + -> Block<'blk, 'tcx> where + F: FnOnce(A, Block<'blk, 'tcx>, ValueRef, Ty<'tcx>) -> Block<'blk, 'tcx>, +{ let var_ty = node_id_type(bcx, p_id); // Allocate memory on stack for the binding. diff --git a/src/librustc_trans/trans/adt.rs b/src/librustc_trans/trans/adt.rs index e273a56ce02..991333d8f07 100644 --- a/src/librustc_trans/trans/adt.rs +++ b/src/librustc_trans/trans/adt.rs @@ -858,10 +858,13 @@ pub fn struct_field_ptr<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, st: &Struct<'tcx>, v GEPi(bcx, val, &[0, ix]) } -pub fn fold_variants<'blk, 'tcx>( - bcx: Block<'blk, 'tcx>, r: &Repr<'tcx>, value: ValueRef, - f: |Block<'blk, 'tcx>, &Struct<'tcx>, ValueRef| -> Block<'blk, 'tcx>) - -> Block<'blk, 'tcx> { +pub fn fold_variants<'blk, 'tcx, F>(bcx: Block<'blk, 'tcx>, + r: &Repr<'tcx>, + value: ValueRef, + mut f: F) + -> Block<'blk, 'tcx> where + F: FnMut(Block<'blk, 'tcx>, &Struct<'tcx>, ValueRef) -> Block<'blk, 'tcx>, +{ let fcx = bcx.fcx; match *r { Univariant(ref st, _) => { diff --git a/src/librustc_trans/trans/base.rs b/src/librustc_trans/trans/base.rs index cef12616cf2..5170746404e 100644 --- a/src/librustc_trans/trans/base.rs +++ b/src/librustc_trans/trans/base.rs @@ -107,9 +107,11 @@ thread_local!(static TASK_LOCAL_INSN_KEY: RefCell<Option<Vec<&'static str>>> = { RefCell::new(None) }) -pub fn with_insn_ctxt(blk: |&[&'static str]|) { - TASK_LOCAL_INSN_KEY.with(|slot| { - slot.borrow().as_ref().map(|s| blk(s.as_slice())); +pub fn with_insn_ctxt<F>(blk: F) where + F: FnOnce(&[&'static str]), +{ + TASK_LOCAL_INSN_KEY.with(move |slot| { + slot.borrow().as_ref().map(move |s| blk(s.as_slice())); }) } @@ -841,12 +843,15 @@ pub fn cast_shift_const_rhs(op: ast::BinOp, |a, b| unsafe { llvm::LLVMConstZExt(a, b.to_ref()) }) } -pub fn cast_shift_rhs(op: ast::BinOp, - lhs: ValueRef, - rhs: ValueRef, - trunc: |ValueRef, Type| -> ValueRef, - zext: |ValueRef, Type| -> ValueRef) - -> ValueRef { +pub fn cast_shift_rhs<F, G>(op: ast::BinOp, + lhs: ValueRef, + rhs: ValueRef, + trunc: F, + zext: G) + -> ValueRef where + F: FnOnce(ValueRef, Type) -> ValueRef, + G: FnOnce(ValueRef, Type) -> ValueRef, +{ // Shifts may have any size int on the rhs unsafe { if ast_util::is_shift_binop(op) { @@ -1101,10 +1106,12 @@ pub fn raw_block<'blk, 'tcx>(fcx: &'blk FunctionContext<'blk, 'tcx>, common::BlockS::new(llbb, is_lpad, None, fcx) } -pub fn with_cond<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, - val: ValueRef, - f: |Block<'blk, 'tcx>| -> Block<'blk, 'tcx>) - -> Block<'blk, 'tcx> { +pub fn with_cond<'blk, 'tcx, F>(bcx: Block<'blk, 'tcx>, + val: ValueRef, + f: F) + -> Block<'blk, 'tcx> where + F: FnOnce(Block<'blk, 'tcx>) -> Block<'blk, 'tcx>, +{ let _icx = push_ctxt("with_cond"); let fcx = bcx.fcx; let next_cx = fcx.new_temp_block("next"); diff --git a/src/librustc_trans/trans/basic_block.rs b/src/librustc_trans/trans/basic_block.rs index b55c268d9a9..dca106a3897 100644 --- a/src/librustc_trans/trans/basic_block.rs +++ b/src/librustc_trans/trans/basic_block.rs @@ -17,7 +17,12 @@ pub struct BasicBlock(pub BasicBlockRef); impl Copy for BasicBlock {} -pub type Preds<'a> = Map<'a, Value, BasicBlock, Filter<'a, Value, Users>>; +pub type Preds = Map< + Value, + BasicBlock, + Filter<Value, Users, fn(&Value) -> bool>, + fn(Value) -> BasicBlock, +>; /// Wrapper for LLVM BasicBlockRef impl BasicBlock { @@ -31,10 +36,13 @@ impl BasicBlock { } } - pub fn pred_iter(self) -> Preds<'static> { + pub fn pred_iter(self) -> Preds { + fn is_a_terminator_inst(user: &Value) -> bool { user.is_a_terminator_inst() } + fn get_parent(user: Value) -> BasicBlock { user.get_parent().unwrap() } + self.as_value().user_iter() - .filter(|user| user.is_a_terminator_inst()) - .map(|user| user.get_parent().unwrap()) + .filter(is_a_terminator_inst) + .map(get_parent) } pub fn get_single_predecessor(self) -> Option<BasicBlock> { diff --git a/src/librustc_trans/trans/cabi_x86_64.rs b/src/librustc_trans/trans/cabi_x86_64.rs index 00c91ddebb3..4a6bc58051c 100644 --- a/src/librustc_trans/trans/cabi_x86_64.rs +++ b/src/librustc_trans/trans/cabi_x86_64.rs @@ -342,11 +342,13 @@ pub fn compute_abi_info(ccx: &CrateContext, atys: &[Type], rty: Type, ret_def: bool) -> FnType { - fn x86_64_ty(ccx: &CrateContext, - ty: Type, - is_mem_cls: |cls: &[RegClass]| -> bool, - ind_attr: Attribute) - -> ArgType { + fn x86_64_ty<F>(ccx: &CrateContext, + ty: Type, + is_mem_cls: F, + ind_attr: Attribute) + -> ArgType where + F: FnOnce(&[RegClass]) -> bool, + { if !ty.is_reg_ty() { let cls = classify_ty(ty); if is_mem_cls(cls.as_slice()) { diff --git a/src/librustc_trans/trans/callee.rs b/src/librustc_trans/trans/callee.rs index ff7ab91c39a..b8b2395dde1 100644 --- a/src/librustc_trans/trans/callee.rs +++ b/src/librustc_trans/trans/callee.rs @@ -781,15 +781,15 @@ pub fn trans_lang_call<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, /// /// For non-lang items, `dest` is always Some, and hence the result is written into memory /// somewhere. Nonetheless we return the actual return value of the function. -pub fn trans_call_inner<'a, 'blk, 'tcx>(bcx: Block<'blk, 'tcx>, - call_info: Option<NodeInfo>, - callee_ty: Ty<'tcx>, - get_callee: |bcx: Block<'blk, 'tcx>, - arg_cleanup_scope: cleanup::ScopeId| - -> Callee<'blk, 'tcx>, - args: CallArgs<'a, 'tcx>, - dest: Option<expr::Dest>) - -> Result<'blk, 'tcx> { +pub fn trans_call_inner<'a, 'blk, 'tcx, F>(bcx: Block<'blk, 'tcx>, + call_info: Option<NodeInfo>, + callee_ty: Ty<'tcx>, + get_callee: F, + args: CallArgs<'a, 'tcx>, + dest: Option<expr::Dest>) + -> Result<'blk, 'tcx> where + F: FnOnce(Block<'blk, 'tcx>, cleanup::ScopeId) -> Callee<'blk, 'tcx>, +{ // Introduce a temporary cleanup scope that will contain cleanups // for the arguments while they are being evaluated. The purpose // this cleanup is to ensure that, should a panic occur while diff --git a/src/librustc_trans/trans/cleanup.rs b/src/librustc_trans/trans/cleanup.rs index ba3e70fe036..2fd6551409e 100644 --- a/src/librustc_trans/trans/cleanup.rs +++ b/src/librustc_trans/trans/cleanup.rs @@ -527,7 +527,7 @@ impl<'blk, 'tcx> CleanupHelperMethods<'blk, 'tcx> for FunctionContext<'blk, 'tcx self.scopes.borrow_mut().pop().unwrap() } - fn top_scope<R>(&self, f: |&CleanupScope<'blk, 'tcx>| -> R) -> R { + fn top_scope<R, F>(&self, f: F) -> R where F: FnOnce(&CleanupScope<'blk, 'tcx>) -> R { f(self.scopes.borrow().last().unwrap()) } @@ -1145,5 +1145,5 @@ trait CleanupHelperMethods<'blk, 'tcx> { fn scopes_len(&self) -> uint; fn push_scope(&self, scope: CleanupScope<'blk, 'tcx>); fn pop_scope(&self) -> CleanupScope<'blk, 'tcx>; - fn top_scope<R>(&self, f: |&CleanupScope<'blk, 'tcx>| -> R) -> R; + fn top_scope<R, F>(&self, f: F) -> R where F: FnOnce(&CleanupScope<'blk, 'tcx>) -> R; } diff --git a/src/librustc_trans/trans/datum.rs b/src/librustc_trans/trans/datum.rs index edcc8edaf7f..531b22c8fb5 100644 --- a/src/librustc_trans/trans/datum.rs +++ b/src/librustc_trans/trans/datum.rs @@ -113,15 +113,16 @@ pub fn immediate_rvalue_bcx<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, /// it. The memory will be dropped upon exit from `scope`. The callback `populate` should /// initialize the memory. If `zero` is true, the space will be zeroed when it is allocated; this /// is not necessary unless `bcx` does not dominate the end of `scope`. -pub fn lvalue_scratch_datum<'blk, 'tcx, A>(bcx: Block<'blk, 'tcx>, - ty: Ty<'tcx>, - name: &str, - zero: bool, - scope: cleanup::ScopeId, - arg: A, - populate: |A, Block<'blk, 'tcx>, ValueRef| - -> Block<'blk, 'tcx>) - -> DatumBlock<'blk, 'tcx, Lvalue> { +pub fn lvalue_scratch_datum<'blk, 'tcx, A, F>(bcx: Block<'blk, 'tcx>, + ty: Ty<'tcx>, + name: &str, + zero: bool, + scope: cleanup::ScopeId, + arg: A, + populate: F) + -> DatumBlock<'blk, 'tcx, Lvalue> where + F: FnOnce(A, Block<'blk, 'tcx>, ValueRef) -> Block<'blk, 'tcx>, +{ let scratch = if zero { alloca_zeroed(bcx, ty, name) } else { @@ -339,10 +340,10 @@ impl<'tcx> Datum<'tcx, Rvalue> { /// here since we can `match self.kind` rather than having to implement /// generic methods in `KindOps`.) impl<'tcx> Datum<'tcx, Expr> { - fn match_kind<R>(self, - if_lvalue: |Datum<'tcx, Lvalue>| -> R, - if_rvalue: |Datum<'tcx, Rvalue>| -> R) - -> R { + fn match_kind<R, F, G>(self, if_lvalue: F, if_rvalue: G) -> R where + F: FnOnce(Datum<'tcx, Lvalue>) -> R, + G: FnOnce(Datum<'tcx, Rvalue>) -> R, + { let Datum { val, ty, kind } = self; match kind { LvalueExpr => if_lvalue(Datum::new(val, ty, Lvalue)), @@ -455,9 +456,11 @@ impl<'tcx> Datum<'tcx, Lvalue> { // datum may also be unsized _without the size information_. It is the // callers responsibility to package the result in some way to make a valid // datum in that case (e.g., by making a fat pointer or opened pair). - pub fn get_element<'blk>(&self, bcx: Block<'blk, 'tcx>, ty: Ty<'tcx>, - gep: |ValueRef| -> ValueRef) - -> Datum<'tcx, Lvalue> { + pub fn get_element<'blk, F>(&self, bcx: Block<'blk, 'tcx>, ty: Ty<'tcx>, + gep: F) + -> Datum<'tcx, Lvalue> where + F: FnOnce(ValueRef) -> ValueRef, + { let val = match self.ty.sty { _ if ty::type_is_sized(bcx.tcx(), self.ty) => gep(self.val), ty::ty_open(_) => { diff --git a/src/librustc_trans/trans/debuginfo.rs b/src/librustc_trans/trans/debuginfo.rs index f6c4ba64576..de169fc9d62 100644 --- a/src/librustc_trans/trans/debuginfo.rs +++ b/src/librustc_trans/trans/debuginfo.rs @@ -3212,13 +3212,13 @@ fn populate_scope_map(cx: &CrateContext, }); // local helper functions for walking the AST. - fn with_new_scope(cx: &CrateContext, - scope_span: Span, - scope_stack: &mut Vec<ScopeStackEntry> , - scope_map: &mut NodeMap<DIScope>, - inner_walk: |&CrateContext, - &mut Vec<ScopeStackEntry> , - &mut NodeMap<DIScope>|) { + fn with_new_scope<F>(cx: &CrateContext, + scope_span: Span, + scope_stack: &mut Vec<ScopeStackEntry> , + scope_map: &mut NodeMap<DIScope>, + inner_walk: F) where + F: FnOnce(&CrateContext, &mut Vec<ScopeStackEntry>, &mut NodeMap<DIScope>), + { // Create a new lexical scope and push it onto the stack let loc = cx.sess().codemap().lookup_char_pos(scope_span.lo); let file_metadata = file_metadata(cx, loc.file.name.as_slice()); diff --git a/src/librustc_trans/trans/expr.rs b/src/librustc_trans/trans/expr.rs index e3e6fff7234..e1769001942 100644 --- a/src/librustc_trans/trans/expr.rs +++ b/src/librustc_trans/trans/expr.rs @@ -295,6 +295,7 @@ fn apply_adjustments<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, // into a type to be destructed. If we want to end up with a Box pointer, // then mk_ty should make a Box pointer (T -> Box<T>), if we want a // borrowed reference then it should be T -> &T. + // FIXME(#19596) unbox `mk_ty` fn unsized_info<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, kind: &ty::UnsizeKind<'tcx>, id: ast::NodeId, @@ -341,27 +342,30 @@ fn apply_adjustments<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, debug!("dest_ty={}", unsized_ty.repr(bcx.tcx())); // Closures for extracting and manipulating the data and payload parts of // the fat pointer. - let base = match k { - &ty::UnsizeStruct(..) => - |bcx, val| PointerCast(bcx, - val, - type_of::type_of(bcx.ccx(), unsized_ty).ptr_to()), - &ty::UnsizeLength(..) => - |bcx, val| GEPi(bcx, val, &[0u, 0u]), - &ty::UnsizeVtable(..) => - |_bcx, val| PointerCast(bcx, val, Type::i8p(bcx.ccx())) - }; - let info = |bcx, _val| unsized_info(bcx, - k, - expr.id, - datum_ty, - |t| ty::mk_rptr(tcx, - ty::ReStatic, - ty::mt{ - ty: t, - mutbl: ast::MutImmutable - })); - into_fat_ptr(bcx, expr, datum, dest_ty, base, info) + let info = |: bcx, _val| unsized_info(bcx, + k, + expr.id, + datum_ty, + |t| ty::mk_rptr(tcx, + ty::ReStatic, + ty::mt{ + ty: t, + mutbl: ast::MutImmutable + })); + match *k { + ty::UnsizeStruct(..) => + into_fat_ptr(bcx, expr, datum, dest_ty, |bcx, val| { + PointerCast(bcx, val, type_of::type_of(bcx.ccx(), unsized_ty).ptr_to()) + }, info), + ty::UnsizeLength(..) => + into_fat_ptr(bcx, expr, datum, dest_ty, |bcx, val| { + GEPi(bcx, val, &[0u, 0u]) + }, info), + ty::UnsizeVtable(..) => + into_fat_ptr(bcx, expr, datum, dest_ty, |_bcx, val| { + PointerCast(bcx, val, Type::i8p(bcx.ccx())) + }, info), + } } fn ref_fat_ptr<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, @@ -370,18 +374,21 @@ fn apply_adjustments<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, -> DatumBlock<'blk, 'tcx, Expr> { let tcx = bcx.tcx(); let dest_ty = ty::close_type(tcx, datum.ty); - let base = |bcx, val| Load(bcx, get_dataptr(bcx, val)); - let len = |bcx, val| Load(bcx, get_len(bcx, val)); + let base = |: bcx, val| Load(bcx, get_dataptr(bcx, val)); + let len = |: bcx, val| Load(bcx, get_len(bcx, val)); into_fat_ptr(bcx, expr, datum, dest_ty, base, len) } - fn into_fat_ptr<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, - expr: &ast::Expr, - datum: Datum<'tcx, Expr>, - dest_ty: Ty<'tcx>, - base: |Block<'blk, 'tcx>, ValueRef| -> ValueRef, - info: |Block<'blk, 'tcx>, ValueRef| -> ValueRef) - -> DatumBlock<'blk, 'tcx, Expr> { + fn into_fat_ptr<'blk, 'tcx, F, G>(bcx: Block<'blk, 'tcx>, + expr: &ast::Expr, + datum: Datum<'tcx, Expr>, + dest_ty: Ty<'tcx>, + base: F, + info: G) + -> DatumBlock<'blk, 'tcx, Expr> where + F: FnOnce(Block<'blk, 'tcx>, ValueRef) -> ValueRef, + G: FnOnce(Block<'blk, 'tcx>, ValueRef) -> ValueRef, + { let mut bcx = bcx; // Arrange cleanup @@ -659,17 +666,19 @@ fn trans_datum_unadjusted<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, } } -fn trans_field<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, - base: &ast::Expr, - get_idx: |&'blk ty::ctxt<'tcx>, &[ty::field<'tcx>]| -> uint) - -> DatumBlock<'blk, 'tcx, Expr> { +fn trans_field<'blk, 'tcx, F>(bcx: Block<'blk, 'tcx>, + base: &ast::Expr, + get_idx: F) + -> DatumBlock<'blk, 'tcx, Expr> where + F: FnOnce(&'blk ty::ctxt<'tcx>, &[ty::field<'tcx>]) -> uint, +{ let mut bcx = bcx; let _icx = push_ctxt("trans_rec_field"); let base_datum = unpack_datum!(bcx, trans_to_lvalue(bcx, base, "field")); let bare_ty = ty::unopen_type(base_datum.ty); let repr = adt::represent_type(bcx.ccx(), bare_ty); - with_field_tys(bcx.tcx(), bare_ty, None, |discr, field_tys| { + with_field_tys(bcx.tcx(), bare_ty, None, move |discr, field_tys| { let ix = get_idx(bcx.tcx(), field_tys); let d = base_datum.get_element( bcx, @@ -1254,11 +1263,13 @@ pub fn trans_local_var<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, /// Helper for enumerating the field types of structs, enums, or records. The optional node ID here /// is the node ID of the path identifying the enum variant in use. If none, this cannot possibly /// an enum variant (so, if it is and `node_id_opt` is none, this function panics). -pub fn with_field_tys<'tcx, R>(tcx: &ty::ctxt<'tcx>, - ty: Ty<'tcx>, - node_id_opt: Option<ast::NodeId>, - op: |ty::Disr, (&[ty::field<'tcx>])| -> R) - -> R { +pub fn with_field_tys<'tcx, R, F>(tcx: &ty::ctxt<'tcx>, + ty: Ty<'tcx>, + node_id_opt: Option<ast::NodeId>, + op: F) + -> R where + F: FnOnce(ty::Disr, &[ty::field<'tcx>]) -> R, +{ match ty.sty { ty::ty_struct(did, ref substs) => { op(0, struct_fields(tcx, did, substs).as_slice()) diff --git a/src/librustc_typeck/check/demand.rs b/src/librustc_typeck/check/demand.rs index 9eb0e17b8e5..980097eaead 100644 --- a/src/librustc_typeck/check/demand.rs +++ b/src/librustc_typeck/check/demand.rs @@ -28,12 +28,14 @@ pub fn suptype<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>, sp: Span, |sp, e, a, s| { fcx.report_mismatched_types(sp, e, a, s) }) } -pub fn suptype_with_fn<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>, - sp: Span, - b_is_expected: bool, - ty_a: Ty<'tcx>, - ty_b: Ty<'tcx>, - handle_err: |Span, Ty<'tcx>, Ty<'tcx>, &ty::type_err<'tcx>|) { +pub fn suptype_with_fn<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>, + sp: Span, + b_is_expected: bool, + ty_a: Ty<'tcx>, + ty_b: Ty<'tcx>, + handle_err: F) where + F: FnOnce(Span, Ty<'tcx>, Ty<'tcx>, &ty::type_err<'tcx>), +{ // n.b.: order of actual, expected is reversed match infer::mk_subty(fcx.infcx(), b_is_expected, infer::Misc(sp), ty_b, ty_a) { diff --git a/src/librustc_typeck/check/method/confirm.rs b/src/librustc_typeck/check/method/confirm.rs index bf1f2c0ce80..3c7cecc96a3 100644 --- a/src/librustc_typeck/check/method/confirm.rs +++ b/src/librustc_typeck/check/method/confirm.rs @@ -286,11 +286,8 @@ impl<'a,'tcx> ConfirmContext<'a,'tcx> { } } - fn extract_trait_ref<R>(&mut self, - self_ty: Ty<'tcx>, - closure: |&mut ConfirmContext<'a,'tcx>, - Ty<'tcx>, &ty::TyTrait<'tcx>| -> R) - -> R + fn extract_trait_ref<R, F>(&mut self, self_ty: Ty<'tcx>, mut closure: F) -> R where + F: FnMut(&mut ConfirmContext<'a, 'tcx>, Ty<'tcx>, &ty::TyTrait<'tcx>) -> R, { // If we specified that this is an object method, then the // self-type ought to be something that can be dereferenced to @@ -665,9 +662,11 @@ impl<'a,'tcx> ConfirmContext<'a,'tcx> { } } -fn wrap_autoref<'tcx>(mut deref: ty::AutoDerefRef<'tcx>, - base_fn: |Option<Box<ty::AutoRef<'tcx>>>| -> ty::AutoRef<'tcx>) - -> ty::AutoDerefRef<'tcx> { +fn wrap_autoref<'tcx, F>(mut deref: ty::AutoDerefRef<'tcx>, + base_fn: F) + -> ty::AutoDerefRef<'tcx> where + F: FnOnce(Option<Box<ty::AutoRef<'tcx>>>) -> ty::AutoRef<'tcx>, +{ let autoref = mem::replace(&mut deref.autoref, None); let autoref = autoref.map(|r| box r); deref.autoref = Some(base_fn(autoref)); diff --git a/src/librustc_typeck/check/method/probe.rs b/src/librustc_typeck/check/method/probe.rs index f0f527f6673..adcfc491dcc 100644 --- a/src/librustc_typeck/check/method/probe.rs +++ b/src/librustc_typeck/check/method/probe.rs @@ -710,10 +710,12 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> { mutbl: m })) } - fn search_mutabilities(&mut self, - mk_adjustment: |ast::Mutability| -> PickAdjustment, - mk_autoref_ty: |ast::Mutability, ty::Region| -> Ty<'tcx>) - -> Option<PickResult<'tcx>> + fn search_mutabilities<F, G>(&mut self, + mut mk_adjustment: F, + mut mk_autoref_ty: G) + -> Option<PickResult<'tcx>> where + F: FnMut(ast::Mutability) -> PickAdjustment, + G: FnMut(ast::Mutability, ty::Region) -> Ty<'tcx>, { // In general, during probing we erase regions. See // `impl_self_ty()` for an explanation. diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 573c63eb6af..18a773fb949 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -1885,9 +1885,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self.inh.item_substs.borrow() } - pub fn opt_node_ty_substs(&self, - id: ast::NodeId, - f: |&ty::ItemSubsts<'tcx>|) { + pub fn opt_node_ty_substs<F>(&self, + id: ast::NodeId, + f: F) where + F: FnOnce(&ty::ItemSubsts<'tcx>), + { match self.inh.item_substs.borrow().get(&id) { Some(s) => { f(s) } None => { } @@ -1938,11 +1940,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { infer::mk_subr(self.infcx(), origin, sub, sup) } - pub fn type_error_message(&self, - sp: Span, - mk_msg: |String| -> String, - actual_ty: Ty<'tcx>, - err: Option<&ty::type_err<'tcx>>) { + pub fn type_error_message<M>(&self, + sp: Span, + mk_msg: M, + actual_ty: Ty<'tcx>, + err: Option<&ty::type_err<'tcx>>) where + M: FnOnce(String) -> String, + { self.infcx().type_error_message(sp, mk_msg, actual_ty, err); } @@ -2025,12 +2029,14 @@ impl Copy for LvaluePreference {} /// /// Note: this method does not modify the adjustments table. The caller is responsible for /// inserting an AutoAdjustment record into the `fcx` using one of the suitable methods. -pub fn autoderef<'a, 'tcx, T>(fcx: &FnCtxt<'a, 'tcx>, sp: Span, - base_ty: Ty<'tcx>, - expr_id: Option<ast::NodeId>, - mut lvalue_pref: LvaluePreference, - should_stop: |Ty<'tcx>, uint| -> Option<T>) - -> (Ty<'tcx>, uint, Option<T>) { +pub fn autoderef<'a, 'tcx, T, F>(fcx: &FnCtxt<'a, 'tcx>, sp: Span, + base_ty: Ty<'tcx>, + expr_id: Option<ast::NodeId>, + mut lvalue_pref: LvaluePreference, + mut should_stop: F) + -> (Ty<'tcx>, uint, Option<T>) where + F: FnMut(Ty<'tcx>, uint) -> Option<T>, +{ let mut t = base_ty; for autoderefs in range(0, fcx.tcx().sess.recursion_limit.get()) { let resolved_t = structurally_resolved_type(fcx, sp, t); @@ -2192,12 +2198,13 @@ fn make_overloaded_lvalue_return_type<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>, } } -fn autoderef_for_index<'a, 'tcx, T>(fcx: &FnCtxt<'a, 'tcx>, - base_expr: &ast::Expr, - base_ty: Ty<'tcx>, - lvalue_pref: LvaluePreference, - step: |Ty<'tcx>, ty::AutoDerefRef<'tcx>| -> Option<T>) - -> Option<T> +fn autoderef_for_index<'a, 'tcx, T, F>(fcx: &FnCtxt<'a, 'tcx>, + base_expr: &ast::Expr, + base_ty: Ty<'tcx>, + lvalue_pref: LvaluePreference, + mut step: F) + -> Option<T> where + F: FnMut(Ty<'tcx>, ty::AutoDerefRef<'tcx>) -> Option<T>, { // FIXME(#18741) -- this is almost but not quite the same as the // autoderef that normal method probing does. They could likely be @@ -2936,11 +2943,12 @@ enum TupleArgumentsFlag { /// Note that inspecting a type's structure *directly* may expose the fact /// that there are actually multiple representations for `ty_err`, so avoid /// that when err needs to be handled differently. -fn check_expr_with_unifier<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>, - expr: &ast::Expr, - expected: Expectation<'tcx>, - lvalue_pref: LvaluePreference, - unifier: ||) +fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>, + expr: &ast::Expr, + expected: Expectation<'tcx>, + lvalue_pref: LvaluePreference, + unifier: F) where + F: FnOnce(), { debug!(">> typechecking: expr={} expected={}", expr.repr(fcx.tcx()), expected.repr(fcx.tcx())); @@ -3115,14 +3123,16 @@ fn check_expr_with_unifier<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>, fcx.write_ty(id, if_ty); } - fn lookup_op_method<'a, 'tcx>(fcx: &'a FnCtxt<'a, 'tcx>, - op_ex: &ast::Expr, - lhs_ty: Ty<'tcx>, - opname: ast::Name, - trait_did: Option<ast::DefId>, - lhs: &'a ast::Expr, - rhs: Option<&P<ast::Expr>>, - unbound_method: ||) -> Ty<'tcx> { + fn lookup_op_method<'a, 'tcx, F>(fcx: &'a FnCtxt<'a, 'tcx>, + op_ex: &ast::Expr, + lhs_ty: Ty<'tcx>, + opname: ast::Name, + trait_did: Option<ast::DefId>, + lhs: &'a ast::Expr, + rhs: Option<&P<ast::Expr>>, + unbound_method: F) -> Ty<'tcx> where + F: FnOnce(), + { let method = match trait_did { Some(trait_did) => { // We do eager coercions to make using operators @@ -4374,19 +4384,17 @@ impl<'tcx> Expectation<'tcx> { } } - fn map<'a>(self, fcx: &FnCtxt<'a, 'tcx>, - unpack: |&ty::sty<'tcx>| -> Expectation<'tcx>) - -> Expectation<'tcx> { + fn map<'a, F>(self, fcx: &FnCtxt<'a, 'tcx>, unpack: F) -> Expectation<'tcx> where + F: FnOnce(&ty::sty<'tcx>) -> Expectation<'tcx> + { match self.resolve(fcx) { NoExpectation => NoExpectation, ExpectCastableToType(t) | ExpectHasType(t) => unpack(&t.sty), } } - fn map_to_option<'a, O>(self, - fcx: &FnCtxt<'a, 'tcx>, - unpack: |&ty::sty<'tcx>| -> Option<O>) - -> Option<O> + fn map_to_option<'a, O, F>(self, fcx: &FnCtxt<'a, 'tcx>, unpack: F) -> Option<O> where + F: FnOnce(&ty::sty<'tcx>) -> Option<O>, { match self.resolve(fcx) { NoExpectation => None, diff --git a/src/librustc_typeck/lib.rs b/src/librustc_typeck/lib.rs index 41ed5b8ec36..32c732c2467 100644 --- a/src/librustc_typeck/lib.rs +++ b/src/librustc_typeck/lib.rs @@ -74,6 +74,7 @@ This API is completely unstable and subject to change. #![feature(default_type_params, globs, import_shadowing, macro_rules, phase, quote)] #![feature(slicing_syntax, unsafe_destructor)] #![feature(rustc_diagnostic_macros)] +#![feature(unboxed_closures)] #![allow(non_camel_case_types)] #[phase(plugin, link)] extern crate log; @@ -169,14 +170,16 @@ fn no_params<'tcx>(t: Ty<'tcx>) -> ty::Polytype<'tcx> { } } -fn require_same_types<'a, 'tcx>(tcx: &ty::ctxt<'tcx>, - maybe_infcx: Option<&infer::InferCtxt<'a, 'tcx>>, - t1_is_expected: bool, - span: Span, - t1: Ty<'tcx>, - t2: Ty<'tcx>, - msg: || -> String) - -> bool { +fn require_same_types<'a, 'tcx, M>(tcx: &ty::ctxt<'tcx>, + maybe_infcx: Option<&infer::InferCtxt<'a, 'tcx>>, + t1_is_expected: bool, + span: Span, + t1: Ty<'tcx>, + t2: Ty<'tcx>, + msg: M) + -> bool where + M: FnOnce() -> String, +{ let result = match maybe_infcx { None => { let infcx = infer::new_infer_ctxt(tcx); diff --git a/src/librustdoc/fold.rs b/src/librustdoc/fold.rs index 173b50dfc5f..5623c0f0e53 100644 --- a/src/librustdoc/fold.rs +++ b/src/librustdoc/fold.rs @@ -79,8 +79,7 @@ pub trait DocFolder { StructVariant(mut j) => { let mut foo = Vec::new(); swap(&mut foo, &mut j.fields); let num_fields = foo.len(); - let c = |x| self.fold_item(x); - j.fields.extend(foo.into_iter().filter_map(c)); + j.fields.extend(foo.into_iter().filter_map(|x| self.fold_item(x))); j.fields_stripped |= num_fields != j.fields.len(); VariantItem(Variant {kind: StructVariant(j), ..i2}) }, diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs index 68ff2ddbcb0..051e8a3568f 100644 --- a/src/librustdoc/html/format.rs +++ b/src/librustdoc/html/format.rs @@ -218,10 +218,14 @@ fn resolved_path(w: &mut fmt::Formatter, did: ast::DefId, p: &clean::Path, }) } -fn path(w: &mut fmt::Formatter, path: &clean::Path, print_all: bool, - root: |&render::Cache, &[String]| -> Option<String>, - info: |&render::Cache| -> Option<(Vec<String> , ItemType)>) - -> fmt::Result +fn path<F, G>(w: &mut fmt::Formatter, + path: &clean::Path, + print_all: bool, + root: F, + info: G) + -> fmt::Result where + F: FnOnce(&render::Cache, &[String]) -> Option<String>, + G: FnOnce(&render::Cache) -> Option<(Vec<String>, ItemType)>, { // The generics will get written to both the title and link let mut generics = String::new(); diff --git a/src/librustdoc/html/markdown.rs b/src/librustdoc/html/markdown.rs index 10563c61e14..cba58db7c7f 100644 --- a/src/librustdoc/html/markdown.rs +++ b/src/librustdoc/html/markdown.rs @@ -393,7 +393,7 @@ impl LangString { let mut seen_other_tags = false; let mut data = LangString::all_false(); - let mut tokens = string.split(|c: char| + let mut tokens = string.split(|&: c: char| !(c == '_' || c == '-' || c.is_alphanumeric()) ); diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs index 38bc7d1a3c1..63b1f5ca049 100644 --- a/src/librustdoc/html/render.rs +++ b/src/librustdoc/html/render.rs @@ -646,7 +646,9 @@ fn shortty(item: &clean::Item) -> ItemType { /// static HTML tree. // FIXME (#9639): The closure should deal with &[u8] instead of &str // FIXME (#9639): This is too conservative, rejecting non-UTF-8 paths -fn clean_srcpath(src_root: &Path, src: &[u8], f: |&str|) { +fn clean_srcpath<F>(src_root: &Path, src: &[u8], mut f: F) where + F: FnMut(&str), +{ let p = Path::new(src); // make it relative, if possible @@ -1051,7 +1053,9 @@ impl<'a> Cache { impl Context { /// Recurse in the directory structure and change the "root path" to make /// sure it always points to the top (relatively) - fn recurse<T>(&mut self, s: String, f: |&mut Context| -> T) -> T { + fn recurse<T, F>(&mut self, s: String, f: F) -> T where + F: FnOnce(&mut Context) -> T, + { if s.len() == 0 { panic!("Unexpected empty destination: {}", self.current); } @@ -1131,8 +1135,9 @@ impl Context { /// all sub-items which need to be rendered. /// /// The rendering driver uses this closure to queue up more work. - fn item(&mut self, item: clean::Item, - f: |&mut Context, clean::Item|) -> io::IoResult<()> { + fn item<F>(&mut self, item: clean::Item, mut f: F) -> io::IoResult<()> where + F: FnMut(&mut Context, clean::Item), + { fn render(w: io::File, cx: &Context, it: &clean::Item, pushname: bool) -> io::IoResult<()> { info!("Rendering an item to {}", w.path().display()); diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs index 80629162854..6da7ec40f34 100644 --- a/src/librustdoc/lib.rs +++ b/src/librustdoc/lib.rs @@ -19,6 +19,7 @@ #![allow(unknown_features)] #![feature(globs, macro_rules, phase, slicing_syntax)] +#![feature(unboxed_closures)] extern crate arena; extern crate getopts; diff --git a/src/librustrt/args.rs b/src/librustrt/args.rs index d94f731e75c..c1b48e989a1 100644 --- a/src/librustrt/args.rs +++ b/src/librustrt/args.rs @@ -89,7 +89,7 @@ mod imp { }) } - fn with_lock<T>(f: || -> T) -> T { + fn with_lock<T, F>(f: F) -> T where F: FnOnce() -> T { unsafe { let _guard = LOCK.lock(); f() @@ -128,7 +128,7 @@ mod imp { assert!(take() == Some(expected.clone())); assert!(take() == None); - (|| { + (|&mut:| { }).finally(|| { // Restore the actual global state. match saved_value { diff --git a/src/librustrt/c_str.rs b/src/librustrt/c_str.rs index 07094f08c5d..865c1af1d14 100644 --- a/src/librustrt/c_str.rs +++ b/src/librustrt/c_str.rs @@ -72,6 +72,7 @@ use collections::hash; use core::fmt; use core::kinds::{Sized, marker}; use core::mem; +use core::ops::{FnMut, FnOnce}; use core::prelude::{Clone, Drop, Eq, Iterator}; use core::prelude::{SlicePrelude, None, Option, Ordering, PartialEq}; use core::prelude::{PartialOrd, RawPtr, Some, StrPrelude, range}; @@ -319,14 +320,18 @@ pub trait ToCStr for Sized? { /// /// Panics the task if the receiver has an interior null. #[inline] - fn with_c_str<T>(&self, f: |*const libc::c_char| -> T) -> T { + fn with_c_str<T, F>(&self, f: F) -> T where + F: FnOnce(*const libc::c_char) -> T, + { let c_str = self.to_c_str(); f(c_str.as_ptr()) } /// Unsafe variant of `with_c_str()` that doesn't check for nulls. #[inline] - unsafe fn with_c_str_unchecked<T>(&self, f: |*const libc::c_char| -> T) -> T { + unsafe fn with_c_str_unchecked<T, F>(&self, f: F) -> T where + F: FnOnce(*const libc::c_char) -> T, + { let c_str = self.to_c_str_unchecked(); f(c_str.as_ptr()) } @@ -344,12 +349,16 @@ impl ToCStr for str { } #[inline] - fn with_c_str<T>(&self, f: |*const libc::c_char| -> T) -> T { + fn with_c_str<T, F>(&self, f: F) -> T where + F: FnOnce(*const libc::c_char) -> T, + { self.as_bytes().with_c_str(f) } #[inline] - unsafe fn with_c_str_unchecked<T>(&self, f: |*const libc::c_char| -> T) -> T { + unsafe fn with_c_str_unchecked<T, F>(&self, f: F) -> T where + F: FnOnce(*const libc::c_char) -> T, + { self.as_bytes().with_c_str_unchecked(f) } } @@ -366,12 +375,16 @@ impl ToCStr for String { } #[inline] - fn with_c_str<T>(&self, f: |*const libc::c_char| -> T) -> T { + fn with_c_str<T, F>(&self, f: F) -> T where + F: FnOnce(*const libc::c_char) -> T, + { self.as_bytes().with_c_str(f) } #[inline] - unsafe fn with_c_str_unchecked<T>(&self, f: |*const libc::c_char| -> T) -> T { + unsafe fn with_c_str_unchecked<T, F>(&self, f: F) -> T where + F: FnOnce(*const libc::c_char) -> T, + { self.as_bytes().with_c_str_unchecked(f) } } @@ -397,11 +410,15 @@ impl ToCStr for [u8] { CString::new(buf as *const libc::c_char, true) } - fn with_c_str<T>(&self, f: |*const libc::c_char| -> T) -> T { + fn with_c_str<T, F>(&self, f: F) -> T where + F: FnOnce(*const libc::c_char) -> T, + { unsafe { with_c_str(self, true, f) } } - unsafe fn with_c_str_unchecked<T>(&self, f: |*const libc::c_char| -> T) -> T { + unsafe fn with_c_str_unchecked<T, F>(&self, f: F) -> T where + F: FnOnce(*const libc::c_char) -> T, + { with_c_str(self, false, f) } } @@ -418,19 +435,24 @@ impl<'a, Sized? T: ToCStr> ToCStr for &'a T { } #[inline] - fn with_c_str<T>(&self, f: |*const libc::c_char| -> T) -> T { + fn with_c_str<T, F>(&self, f: F) -> T where + F: FnOnce(*const libc::c_char) -> T, + { (**self).with_c_str(f) } #[inline] - unsafe fn with_c_str_unchecked<T>(&self, f: |*const libc::c_char| -> T) -> T { + unsafe fn with_c_str_unchecked<T, F>(&self, f: F) -> T where + F: FnOnce(*const libc::c_char) -> T, + { (**self).with_c_str_unchecked(f) } } // Unsafe function that handles possibly copying the &[u8] into a stack array. -unsafe fn with_c_str<T>(v: &[u8], checked: bool, - f: |*const libc::c_char| -> T) -> T { +unsafe fn with_c_str<T, F>(v: &[u8], checked: bool, f: F) -> T where + F: FnOnce(*const libc::c_char) -> T, +{ let c_str = if v.len() < BUF_LEN { let mut buf: [u8, .. BUF_LEN] = mem::uninitialized(); slice::bytes::copy_memory(&mut buf, v); @@ -489,9 +511,12 @@ impl<'a> Iterator<libc::c_char> for CChars<'a> { /// /// The specified closure is invoked with each string that /// is found, and the number of strings found is returned. -pub unsafe fn from_c_multistring(buf: *const libc::c_char, - count: Option<uint>, - f: |&CString|) -> uint { +pub unsafe fn from_c_multistring<F>(buf: *const libc::c_char, + count: Option<uint>, + mut f: F) + -> uint where + F: FnMut(&CString), +{ let mut curr_ptr: uint = buf as uint; let mut ctr = 0; @@ -678,7 +703,7 @@ mod tests { #[test] fn test_clone_noleak() { - fn foo(f: |c: &CString|) { + fn foo<F>(f: F) where F: FnOnce(&CString) { let s = "test".to_string(); let c = s.to_c_str(); // give the closure a non-owned CString diff --git a/src/librustrt/lib.rs b/src/librustrt/lib.rs index 066e8c51aef..c2ee91d6acc 100644 --- a/src/librustrt/lib.rs +++ b/src/librustrt/lib.rs @@ -19,6 +19,7 @@ #![feature(macro_rules, phase, globs, thread_local, asm)] #![feature(linkage, lang_items, unsafe_destructor, default_type_params)] #![feature(import_shadowing, slicing_syntax)] +#![feature(unboxed_closures)] #![no_std] #![experimental] diff --git a/src/librustrt/task.rs b/src/librustrt/task.rs index 325bdc284ac..7e657d3aef3 100644 --- a/src/librustrt/task.rs +++ b/src/librustrt/task.rs @@ -22,6 +22,7 @@ use core::atomic::{AtomicUint, SeqCst}; use core::iter::{IteratorExt, Take}; use core::kinds::marker; use core::mem; +use core::ops::FnMut; use core::prelude::{Clone, Drop, Err, Iterator, None, Ok, Option, Send, Some}; use core::prelude::{drop}; @@ -297,9 +298,9 @@ impl Task { // `awoken` field which indicates whether we were actually woken up via some // invocation of `reawaken`. This flag is only ever accessed inside the // lock, so there's no need to make it atomic. - pub fn deschedule(mut self: Box<Task>, - times: uint, - f: |BlockedTask| -> ::core::result::Result<(), BlockedTask>) { + pub fn deschedule<F>(mut self: Box<Task>, times: uint, mut f: F) where + F: FnMut(BlockedTask) -> ::core::result::Result<(), BlockedTask>, + { unsafe { let me = &mut *self as *mut Task; let task = BlockedTask::block(self); diff --git a/src/libserialize/json.rs b/src/libserialize/json.rs index 7919ac0eff1..d34828ccee3 100644 --- a/src/libserialize/json.rs +++ b/src/libserialize/json.rs @@ -458,17 +458,19 @@ impl<'a> ::Encoder<io::IoError> for Encoder<'a> { escape_str(self.writer, v) } - fn emit_enum(&mut self, - _name: &str, - f: |&mut Encoder<'a>| -> EncodeResult) -> EncodeResult { + fn emit_enum<F>(&mut self, _name: &str, f: F) -> EncodeResult where + F: FnOnce(&mut Encoder<'a>) -> EncodeResult, + { f(self) } - fn emit_enum_variant(&mut self, - name: &str, - _id: uint, - cnt: uint, - f: |&mut Encoder<'a>| -> EncodeResult) -> EncodeResult { + fn emit_enum_variant<F>(&mut self, + name: &str, + _id: uint, + cnt: uint, + f: F) -> EncodeResult where + F: FnOnce(&mut Encoder<'a>) -> EncodeResult, + { // enums are encoded as strings or objects // Bunny => "Bunny" // Kangaroo(34,"William") => {"variant": "Kangaroo", "fields": [34,"William"]} @@ -483,100 +485,113 @@ impl<'a> ::Encoder<io::IoError> for Encoder<'a> { } } - fn emit_enum_variant_arg(&mut self, - idx: uint, - f: |&mut Encoder<'a>| -> EncodeResult) -> EncodeResult { + fn emit_enum_variant_arg<F>(&mut self, idx: uint, f: F) -> EncodeResult where + F: FnOnce(&mut Encoder<'a>) -> EncodeResult, + { if idx != 0 { try!(write!(self.writer, ",")); } f(self) } - fn emit_enum_struct_variant(&mut self, - name: &str, - id: uint, - cnt: uint, - f: |&mut Encoder<'a>| -> EncodeResult) -> EncodeResult { + fn emit_enum_struct_variant<F>(&mut self, + name: &str, + id: uint, + cnt: uint, + f: F) -> EncodeResult where + F: FnOnce(&mut Encoder<'a>) -> EncodeResult, + { self.emit_enum_variant(name, id, cnt, f) } - fn emit_enum_struct_variant_field(&mut self, - _: &str, - idx: uint, - f: |&mut Encoder<'a>| -> EncodeResult) -> EncodeResult { + fn emit_enum_struct_variant_field<F>(&mut self, + _: &str, + idx: uint, + f: F) -> EncodeResult where + F: FnOnce(&mut Encoder<'a>) -> EncodeResult, + { self.emit_enum_variant_arg(idx, f) } - fn emit_struct(&mut self, - _: &str, - _: uint, - f: |&mut Encoder<'a>| -> EncodeResult) -> EncodeResult { + fn emit_struct<F>(&mut self, _: &str, _: uint, f: F) -> EncodeResult where + F: FnOnce(&mut Encoder<'a>) -> EncodeResult, + { try!(write!(self.writer, "{{")); try!(f(self)); write!(self.writer, "}}") } - fn emit_struct_field(&mut self, - name: &str, - idx: uint, - f: |&mut Encoder<'a>| -> EncodeResult) -> EncodeResult { + fn emit_struct_field<F>(&mut self, name: &str, idx: uint, f: F) -> EncodeResult where + F: FnOnce(&mut Encoder<'a>) -> EncodeResult, + { if idx != 0 { try!(write!(self.writer, ",")); } try!(escape_str(self.writer, name)); try!(write!(self.writer, ":")); f(self) } - fn emit_tuple(&mut self, len: uint, f: |&mut Encoder<'a>| -> EncodeResult) -> EncodeResult { + fn emit_tuple<F>(&mut self, len: uint, f: F) -> EncodeResult where + F: FnOnce(&mut Encoder<'a>) -> EncodeResult, + { self.emit_seq(len, f) } - fn emit_tuple_arg(&mut self, - idx: uint, - f: |&mut Encoder<'a>| -> EncodeResult) -> EncodeResult { + fn emit_tuple_arg<F>(&mut self, idx: uint, f: F) -> EncodeResult where + F: FnOnce(&mut Encoder<'a>) -> EncodeResult, + { self.emit_seq_elt(idx, f) } - fn emit_tuple_struct(&mut self, - _name: &str, - len: uint, - f: |&mut Encoder<'a>| -> EncodeResult) -> EncodeResult { + fn emit_tuple_struct<F>(&mut self, _name: &str, len: uint, f: F) -> EncodeResult where + F: FnOnce(&mut Encoder<'a>) -> EncodeResult, + { self.emit_seq(len, f) } - fn emit_tuple_struct_arg(&mut self, - idx: uint, - f: |&mut Encoder<'a>| -> EncodeResult) -> EncodeResult { + fn emit_tuple_struct_arg<F>(&mut self, idx: uint, f: F) -> EncodeResult where + F: FnOnce(&mut Encoder<'a>) -> EncodeResult, + { self.emit_seq_elt(idx, f) } - fn emit_option(&mut self, f: |&mut Encoder<'a>| -> EncodeResult) -> EncodeResult { + fn emit_option<F>(&mut self, f: F) -> EncodeResult where + F: FnOnce(&mut Encoder<'a>) -> EncodeResult, + { f(self) } fn emit_option_none(&mut self) -> EncodeResult { self.emit_nil() } - fn emit_option_some(&mut self, f: |&mut Encoder<'a>| -> EncodeResult) -> EncodeResult { + fn emit_option_some<F>(&mut self, f: F) -> EncodeResult where + F: FnOnce(&mut Encoder<'a>) -> EncodeResult, + { f(self) } - fn emit_seq(&mut self, _len: uint, f: |&mut Encoder<'a>| -> EncodeResult) -> EncodeResult { + fn emit_seq<F>(&mut self, _len: uint, f: F) -> EncodeResult where + F: FnOnce(&mut Encoder<'a>) -> EncodeResult, + { try!(write!(self.writer, "[")); try!(f(self)); write!(self.writer, "]") } - fn emit_seq_elt(&mut self, idx: uint, f: |&mut Encoder<'a>| -> EncodeResult) -> EncodeResult { + fn emit_seq_elt<F>(&mut self, idx: uint, f: F) -> EncodeResult where + F: FnOnce(&mut Encoder<'a>) -> EncodeResult, + { if idx != 0 { try!(write!(self.writer, ",")); } f(self) } - fn emit_map(&mut self, _len: uint, f: |&mut Encoder<'a>| -> EncodeResult) -> EncodeResult { + fn emit_map<F>(&mut self, _len: uint, f: F) -> EncodeResult where + F: FnOnce(&mut Encoder<'a>) -> EncodeResult, + { try!(write!(self.writer, "{{")); try!(f(self)); write!(self.writer, "}}") } - fn emit_map_elt_key(&mut self, - idx: uint, - f: |&mut Encoder<'a>| -> EncodeResult) -> EncodeResult { + fn emit_map_elt_key<F>(&mut self, idx: uint, mut f: F) -> EncodeResult where + F: FnMut(&mut Encoder<'a>) -> EncodeResult, + { if idx != 0 { try!(write!(self.writer, ",")) } // ref #12967, make sure to wrap a key in double quotes, // in the event that its of a type that omits them (eg numbers) @@ -594,9 +609,9 @@ impl<'a> ::Encoder<io::IoError> for Encoder<'a> { Ok(()) } - fn emit_map_elt_val(&mut self, - _idx: uint, - f: |&mut Encoder<'a>| -> EncodeResult) -> EncodeResult { + fn emit_map_elt_val<F>(&mut self, _idx: uint, f: F) -> EncodeResult where + F: FnOnce(&mut Encoder<'a>) -> EncodeResult, + { try!(write!(self.writer, ":")); f(self) } @@ -663,17 +678,20 @@ impl<'a> ::Encoder<io::IoError> for PrettyEncoder<'a> { escape_str(self.writer, v) } - fn emit_enum(&mut self, - _name: &str, - f: |&mut PrettyEncoder<'a>| -> EncodeResult) -> EncodeResult { + fn emit_enum<F>(&mut self, _name: &str, f: F) -> EncodeResult where + F: FnOnce(&mut PrettyEncoder<'a>) -> EncodeResult, + { f(self) } - fn emit_enum_variant(&mut self, - name: &str, - _id: uint, - cnt: uint, - f: |&mut PrettyEncoder<'a>| -> EncodeResult) -> EncodeResult { + fn emit_enum_variant<F>(&mut self, + name: &str, + _id: uint, + cnt: uint, + f: F) + -> EncodeResult where + F: FnOnce(&mut PrettyEncoder<'a>) -> EncodeResult, + { if cnt == 0 { escape_str(self.writer, name) } else { @@ -697,9 +715,9 @@ impl<'a> ::Encoder<io::IoError> for PrettyEncoder<'a> { } } - fn emit_enum_variant_arg(&mut self, - idx: uint, - f: |&mut PrettyEncoder<'a>| -> EncodeResult) -> EncodeResult { + fn emit_enum_variant_arg<F>(&mut self, idx: uint, f: F) -> EncodeResult where + F: FnOnce(&mut PrettyEncoder<'a>) -> EncodeResult, + { if idx != 0 { try!(write!(self.writer, ",\n")); } @@ -707,26 +725,29 @@ impl<'a> ::Encoder<io::IoError> for PrettyEncoder<'a> { f(self) } - fn emit_enum_struct_variant(&mut self, - name: &str, - id: uint, - cnt: uint, - f: |&mut PrettyEncoder<'a>| -> EncodeResult) -> EncodeResult { + fn emit_enum_struct_variant<F>(&mut self, + name: &str, + id: uint, + cnt: uint, + f: F) -> EncodeResult where + F: FnOnce(&mut PrettyEncoder<'a>) -> EncodeResult, + { self.emit_enum_variant(name, id, cnt, f) } - fn emit_enum_struct_variant_field(&mut self, - _: &str, - idx: uint, - f: |&mut PrettyEncoder<'a>| -> EncodeResult) -> EncodeResult { + fn emit_enum_struct_variant_field<F>(&mut self, + _: &str, + idx: uint, + f: F) -> EncodeResult where + F: FnOnce(&mut PrettyEncoder<'a>) -> EncodeResult, + { self.emit_enum_variant_arg(idx, f) } - fn emit_struct(&mut self, - _: &str, - len: uint, - f: |&mut PrettyEncoder<'a>| -> EncodeResult) -> EncodeResult { + fn emit_struct<F>(&mut self, _: &str, len: uint, f: F) -> EncodeResult where + F: FnOnce(&mut PrettyEncoder<'a>) -> EncodeResult, + { if len == 0 { write!(self.writer, "{{}}") } else { @@ -740,10 +761,9 @@ impl<'a> ::Encoder<io::IoError> for PrettyEncoder<'a> { } } - fn emit_struct_field(&mut self, - name: &str, - idx: uint, - f: |&mut PrettyEncoder<'a>| -> EncodeResult) -> EncodeResult { + fn emit_struct_field<F>(&mut self, name: &str, idx: uint, f: F) -> EncodeResult where + F: FnOnce(&mut PrettyEncoder<'a>) -> EncodeResult, + { if idx == 0 { try!(write!(self.writer, "\n")); } else { @@ -755,40 +775,43 @@ impl<'a> ::Encoder<io::IoError> for PrettyEncoder<'a> { f(self) } - fn emit_tuple(&mut self, - len: uint, - f: |&mut PrettyEncoder<'a>| -> EncodeResult) -> EncodeResult { + fn emit_tuple<F>(&mut self, len: uint, f: F) -> EncodeResult where + F: FnOnce(&mut PrettyEncoder<'a>) -> EncodeResult, + { self.emit_seq(len, f) } - fn emit_tuple_arg(&mut self, - idx: uint, - f: |&mut PrettyEncoder<'a>| -> EncodeResult) -> EncodeResult { + fn emit_tuple_arg<F>(&mut self, idx: uint, f: F) -> EncodeResult where + F: FnOnce(&mut PrettyEncoder<'a>) -> EncodeResult, + { self.emit_seq_elt(idx, f) } - fn emit_tuple_struct(&mut self, - _: &str, - len: uint, - f: |&mut PrettyEncoder<'a>| -> EncodeResult) -> EncodeResult { + fn emit_tuple_struct<F>(&mut self, _: &str, len: uint, f: F) -> EncodeResult where + F: FnOnce(&mut PrettyEncoder<'a>) -> EncodeResult, + { self.emit_seq(len, f) } - fn emit_tuple_struct_arg(&mut self, - idx: uint, - f: |&mut PrettyEncoder<'a>| -> EncodeResult) -> EncodeResult { + fn emit_tuple_struct_arg<F>(&mut self, idx: uint, f: F) -> EncodeResult where + F: FnOnce(&mut PrettyEncoder<'a>) -> EncodeResult, + { self.emit_seq_elt(idx, f) } - fn emit_option(&mut self, f: |&mut PrettyEncoder<'a>| -> EncodeResult) -> EncodeResult { + fn emit_option<F>(&mut self, f: F) -> EncodeResult where + F: FnOnce(&mut PrettyEncoder<'a>) -> EncodeResult, + { f(self) } fn emit_option_none(&mut self) -> EncodeResult { self.emit_nil() } - fn emit_option_some(&mut self, f: |&mut PrettyEncoder<'a>| -> EncodeResult) -> EncodeResult { + fn emit_option_some<F>(&mut self, f: F) -> EncodeResult where + F: FnOnce(&mut PrettyEncoder<'a>) -> EncodeResult, + { f(self) } - fn emit_seq(&mut self, - len: uint, - f: |&mut PrettyEncoder<'a>| -> EncodeResult) -> EncodeResult { + fn emit_seq<F>(&mut self, len: uint, f: F) -> EncodeResult where + F: FnOnce(&mut PrettyEncoder<'a>) -> EncodeResult, + { if len == 0 { write!(self.writer, "[]") } else { @@ -802,9 +825,9 @@ impl<'a> ::Encoder<io::IoError> for PrettyEncoder<'a> { } } - fn emit_seq_elt(&mut self, - idx: uint, - f: |&mut PrettyEncoder<'a>| -> EncodeResult) -> EncodeResult { + fn emit_seq_elt<F>(&mut self, idx: uint, f: F) -> EncodeResult where + F: FnOnce(&mut PrettyEncoder<'a>) -> EncodeResult, + { if idx == 0 { try!(write!(self.writer, "\n")); } else { @@ -814,9 +837,9 @@ impl<'a> ::Encoder<io::IoError> for PrettyEncoder<'a> { f(self) } - fn emit_map(&mut self, - len: uint, - f: |&mut PrettyEncoder<'a>| -> EncodeResult) -> EncodeResult { + fn emit_map<F>(&mut self, len: uint, f: F) -> EncodeResult where + F: FnOnce(&mut PrettyEncoder<'a>) -> EncodeResult, + { if len == 0 { write!(self.writer, "{{}}") } else { @@ -830,9 +853,9 @@ impl<'a> ::Encoder<io::IoError> for PrettyEncoder<'a> { } } - fn emit_map_elt_key(&mut self, - idx: uint, - f: |&mut PrettyEncoder<'a>| -> EncodeResult) -> EncodeResult { + fn emit_map_elt_key<F>(&mut self, idx: uint, mut f: F) -> EncodeResult where + F: FnMut(&mut PrettyEncoder<'a>) -> EncodeResult, + { if idx == 0 { try!(write!(self.writer, "\n")); } else { @@ -855,9 +878,9 @@ impl<'a> ::Encoder<io::IoError> for PrettyEncoder<'a> { Ok(()) } - fn emit_map_elt_val(&mut self, - _idx: uint, - f: |&mut PrettyEncoder<'a>| -> EncodeResult) -> EncodeResult { + fn emit_map_elt_val<F>(&mut self, _idx: uint, f: F) -> EncodeResult where + F: FnOnce(&mut PrettyEncoder<'a>) -> EncodeResult, + { try!(write!(self.writer, ": ")); f(self) } @@ -2052,17 +2075,16 @@ impl ::Decoder<DecoderError> for Decoder { expect!(self.pop(), String) } - fn read_enum<T>(&mut self, - name: &str, - f: |&mut Decoder| -> DecodeResult<T>) -> DecodeResult<T> { + fn read_enum<T, F>(&mut self, name: &str, f: F) -> DecodeResult<T> where + F: FnOnce(&mut Decoder) -> DecodeResult<T>, + { debug!("read_enum({})", name); f(self) } - fn read_enum_variant<T>(&mut self, - names: &[&str], - f: |&mut Decoder, uint| -> DecodeResult<T>) - -> DecodeResult<T> { + fn read_enum_variant<T, F>(&mut self, names: &[&str], f: F) -> DecodeResult<T> where + F: FnOnce(&mut Decoder, uint) -> DecodeResult<T>, + { debug!("read_enum_variant(names={})", names); let name = match self.pop() { Json::String(s) => s, @@ -2103,46 +2125,48 @@ impl ::Decoder<DecoderError> for Decoder { f(self, idx) } - fn read_enum_variant_arg<T>(&mut self, idx: uint, f: |&mut Decoder| -> DecodeResult<T>) - -> DecodeResult<T> { + fn read_enum_variant_arg<T, F>(&mut self, idx: uint, f: F) -> DecodeResult<T> where + F: FnOnce(&mut Decoder) -> DecodeResult<T>, + { debug!("read_enum_variant_arg(idx={})", idx); f(self) } - fn read_enum_struct_variant<T>(&mut self, - names: &[&str], - f: |&mut Decoder, uint| -> DecodeResult<T>) - -> DecodeResult<T> { + fn read_enum_struct_variant<T, F>(&mut self, names: &[&str], f: F) -> DecodeResult<T> where + F: FnOnce(&mut Decoder, uint) -> DecodeResult<T>, + { debug!("read_enum_struct_variant(names={})", names); self.read_enum_variant(names, f) } - fn read_enum_struct_variant_field<T>(&mut self, + fn read_enum_struct_variant_field<T, F>(&mut self, name: &str, idx: uint, - f: |&mut Decoder| -> DecodeResult<T>) - -> DecodeResult<T> { + f: F) + -> DecodeResult<T> where + F: FnOnce(&mut Decoder) -> DecodeResult<T>, + { debug!("read_enum_struct_variant_field(name={}, idx={})", name, idx); self.read_enum_variant_arg(idx, f) } - fn read_struct<T>(&mut self, - name: &str, - len: uint, - f: |&mut Decoder| -> DecodeResult<T>) - -> DecodeResult<T> { + fn read_struct<T, F>(&mut self, name: &str, len: uint, f: F) -> DecodeResult<T> where + F: FnOnce(&mut Decoder) -> DecodeResult<T>, + { debug!("read_struct(name={}, len={})", name, len); let value = try!(f(self)); self.pop(); Ok(value) } - fn read_struct_field<T>(&mut self, - name: &str, - idx: uint, - f: |&mut Decoder| -> DecodeResult<T>) - -> DecodeResult<T> { + fn read_struct_field<T, F>(&mut self, + name: &str, + idx: uint, + f: F) + -> DecodeResult<T> where + F: FnOnce(&mut Decoder) -> DecodeResult<T>, + { debug!("read_struct_field(name={}, idx={})", name, idx); let mut obj = try!(expect!(self.pop(), Object)); @@ -2165,12 +2189,11 @@ impl ::Decoder<DecoderError> for Decoder { Ok(value) } - fn read_tuple<T>(&mut self, - tuple_len: uint, - f: |&mut Decoder| -> DecodeResult<T>) - -> DecodeResult<T> { + fn read_tuple<T, F>(&mut self, tuple_len: uint, f: F) -> DecodeResult<T> where + F: FnOnce(&mut Decoder) -> DecodeResult<T>, + { debug!("read_tuple()"); - self.read_seq(|d, len| { + self.read_seq(move |d, len| { if len == tuple_len { f(d) } else { @@ -2179,31 +2202,37 @@ impl ::Decoder<DecoderError> for Decoder { }) } - fn read_tuple_arg<T>(&mut self, - idx: uint, - f: |&mut Decoder| -> DecodeResult<T>) -> DecodeResult<T> { + fn read_tuple_arg<T, F>(&mut self, idx: uint, f: F) -> DecodeResult<T> where + F: FnOnce(&mut Decoder) -> DecodeResult<T>, + { debug!("read_tuple_arg(idx={})", idx); self.read_seq_elt(idx, f) } - fn read_tuple_struct<T>(&mut self, - name: &str, - len: uint, - f: |&mut Decoder| -> DecodeResult<T>) - -> DecodeResult<T> { + fn read_tuple_struct<T, F>(&mut self, + name: &str, + len: uint, + f: F) + -> DecodeResult<T> where + F: FnOnce(&mut Decoder) -> DecodeResult<T>, + { debug!("read_tuple_struct(name={})", name); self.read_tuple(len, f) } - fn read_tuple_struct_arg<T>(&mut self, - idx: uint, - f: |&mut Decoder| -> DecodeResult<T>) - -> DecodeResult<T> { + fn read_tuple_struct_arg<T, F>(&mut self, + idx: uint, + f: F) + -> DecodeResult<T> where + F: FnOnce(&mut Decoder) -> DecodeResult<T>, + { debug!("read_tuple_struct_arg(idx={})", idx); self.read_tuple_arg(idx, f) } - fn read_option<T>(&mut self, f: |&mut Decoder, bool| -> DecodeResult<T>) -> DecodeResult<T> { + fn read_option<T, F>(&mut self, f: F) -> DecodeResult<T> where + F: FnOnce(&mut Decoder, bool) -> DecodeResult<T>, + { debug!("read_option()"); match self.pop() { Json::Null => f(self, false), @@ -2211,7 +2240,9 @@ impl ::Decoder<DecoderError> for Decoder { } } - fn read_seq<T>(&mut self, f: |&mut Decoder, uint| -> DecodeResult<T>) -> DecodeResult<T> { + fn read_seq<T, F>(&mut self, f: F) -> DecodeResult<T> where + F: FnOnce(&mut Decoder, uint) -> DecodeResult<T>, + { debug!("read_seq()"); let array = try!(expect!(self.pop(), Array)); let len = array.len(); @@ -2221,14 +2252,16 @@ impl ::Decoder<DecoderError> for Decoder { f(self, len) } - fn read_seq_elt<T>(&mut self, - idx: uint, - f: |&mut Decoder| -> DecodeResult<T>) -> DecodeResult<T> { + fn read_seq_elt<T, F>(&mut self, idx: uint, f: F) -> DecodeResult<T> where + F: FnOnce(&mut Decoder) -> DecodeResult<T>, + { debug!("read_seq_elt(idx={})", idx); f(self) } - fn read_map<T>(&mut self, f: |&mut Decoder, uint| -> DecodeResult<T>) -> DecodeResult<T> { + fn read_map<T, F>(&mut self, f: F) -> DecodeResult<T> where + F: FnOnce(&mut Decoder, uint) -> DecodeResult<T>, + { debug!("read_map()"); let obj = try!(expect!(self.pop(), Object)); let len = obj.len(); @@ -2239,14 +2272,16 @@ impl ::Decoder<DecoderError> for Decoder { f(self, len) } - fn read_map_elt_key<T>(&mut self, idx: uint, f: |&mut Decoder| -> DecodeResult<T>) - -> DecodeResult<T> { + fn read_map_elt_key<T, F>(&mut self, idx: uint, f: F) -> DecodeResult<T> where + F: FnOnce(&mut Decoder) -> DecodeResult<T>, + { debug!("read_map_elt_key(idx={})", idx); f(self) } - fn read_map_elt_val<T>(&mut self, idx: uint, f: |&mut Decoder| -> DecodeResult<T>) - -> DecodeResult<T> { + fn read_map_elt_val<T, F>(&mut self, idx: uint, f: F) -> DecodeResult<T> where + F: FnOnce(&mut Decoder) -> DecodeResult<T>, + { debug!("read_map_elt_val(idx={})", idx); f(self) } @@ -2645,7 +2680,7 @@ mod tests { from_str(a.to_pretty_str().as_slice()).unwrap()); } - fn with_str_writer(f: |&mut io::Writer|) -> string::String { + fn with_str_writer<F>(f: F) -> string::String where F: FnOnce(&mut io::Writer){ use std::str; let mut m = Vec::new(); diff --git a/src/libserialize/lib.rs b/src/libserialize/lib.rs index 9711d5c7209..390b3976562 100644 --- a/src/libserialize/lib.rs +++ b/src/libserialize/lib.rs @@ -24,6 +24,7 @@ Core encoding and decoding interfaces. html_playground_url = "http://play.rust-lang.org/")] #![allow(unknown_features)] #![feature(macro_rules, default_type_params, phase, slicing_syntax, globs)] +#![feature(unboxed_closures)] // test harness access #[cfg(test)] diff --git a/src/libserialize/serialize.rs b/src/libserialize/serialize.rs index 7539a6dc348..98bd2f6bc93 100644 --- a/src/libserialize/serialize.rs +++ b/src/libserialize/serialize.rs @@ -39,58 +39,61 @@ pub trait Encoder<E> { fn emit_str(&mut self, v: &str) -> Result<(), E>; // Compound types: - fn emit_enum(&mut self, name: &str, f: |&mut Self| -> Result<(), E>) -> Result<(), E>; - - fn emit_enum_variant(&mut self, - v_name: &str, - v_id: uint, - len: uint, - f: |&mut Self| -> Result<(), E>) -> Result<(), E>; - fn emit_enum_variant_arg(&mut self, - a_idx: uint, - f: |&mut Self| -> Result<(), E>) -> Result<(), E>; - - fn emit_enum_struct_variant(&mut self, - v_name: &str, - v_id: uint, - len: uint, - f: |&mut Self| -> Result<(), E>) -> Result<(), E>; - fn emit_enum_struct_variant_field(&mut self, - f_name: &str, - f_idx: uint, - f: |&mut Self| -> Result<(), E>) -> Result<(), E>; - - fn emit_struct(&mut self, - name: &str, - len: uint, - f: |&mut Self| -> Result<(), E>) -> Result<(), E>; - fn emit_struct_field(&mut self, - f_name: &str, - f_idx: uint, - f: |&mut Self| -> Result<(), E>) -> Result<(), E>; - - fn emit_tuple(&mut self, len: uint, f: |&mut Self| -> Result<(), E>) -> Result<(), E>; - fn emit_tuple_arg(&mut self, idx: uint, f: |&mut Self| -> Result<(), E>) -> Result<(), E>; - - fn emit_tuple_struct(&mut self, - name: &str, - len: uint, - f: |&mut Self| -> Result<(), E>) -> Result<(), E>; - fn emit_tuple_struct_arg(&mut self, - f_idx: uint, - f: |&mut Self| -> Result<(), E>) -> Result<(), E>; + fn emit_enum<F>(&mut self, name: &str, f: F) -> Result<(), E> where + F: FnOnce(&mut Self) -> Result<(), E>; + + fn emit_enum_variant<F>(&mut self, v_name: &str, + v_id: uint, + len: uint, + f: F) -> Result<(), E> where + F: FnOnce(&mut Self) -> Result<(), E>; + fn emit_enum_variant_arg<F>(&mut self, a_idx: uint, f: F) -> Result<(), E> where + F: FnOnce(&mut Self) -> Result<(), E>; + + fn emit_enum_struct_variant<F>(&mut self, v_name: &str, + v_id: uint, + len: uint, + f: F) -> Result<(), E> where + F: FnOnce(&mut Self) -> Result<(), E>; + fn emit_enum_struct_variant_field<F>(&mut self, + f_name: &str, + f_idx: uint, + f: F) -> Result<(), E> where + F: FnOnce(&mut Self) -> Result<(), E>; + + fn emit_struct<F>(&mut self, name: &str, len: uint, f: F) -> Result<(), E> where + F: FnOnce(&mut Self) -> Result<(), E>; + fn emit_struct_field<F>(&mut self, f_name: &str, f_idx: uint, f: F) -> Result<(), E> where + F: FnOnce(&mut Self) -> Result<(), E>; + + fn emit_tuple<F>(&mut self, len: uint, f: F) -> Result<(), E> where + F: FnOnce(&mut Self) -> Result<(), E>; + fn emit_tuple_arg<F>(&mut self, idx: uint, f: F) -> Result<(), E> where + F: FnOnce(&mut Self) -> Result<(), E>; + + fn emit_tuple_struct<F>(&mut self, name: &str, len: uint, f: F) -> Result<(), E> where + F: FnOnce(&mut Self) -> Result<(), E>; + fn emit_tuple_struct_arg<F>(&mut self, f_idx: uint, f: F) -> Result<(), E> where + F: FnOnce(&mut Self) -> Result<(), E>; // Specialized types: - fn emit_option(&mut self, f: |&mut Self| -> Result<(), E>) -> Result<(), E>; + fn emit_option<F>(&mut self, f: F) -> Result<(), E> where + F: FnOnce(&mut Self) -> Result<(), E>; fn emit_option_none(&mut self) -> Result<(), E>; - fn emit_option_some(&mut self, f: |&mut Self| -> Result<(), E>) -> Result<(), E>; + fn emit_option_some<F>(&mut self, f: F) -> Result<(), E> where + F: FnOnce(&mut Self) -> Result<(), E>; - fn emit_seq(&mut self, len: uint, f: |this: &mut Self| -> Result<(), E>) -> Result<(), E>; - fn emit_seq_elt(&mut self, idx: uint, f: |this: &mut Self| -> Result<(), E>) -> Result<(), E>; + fn emit_seq<F>(&mut self, len: uint, f: F) -> Result<(), E> where + F: FnOnce(&mut Self) -> Result<(), E>; + fn emit_seq_elt<F>(&mut self, idx: uint, f: F) -> Result<(), E> where + F: FnOnce(&mut Self) -> Result<(), E>; - fn emit_map(&mut self, len: uint, f: |&mut Self| -> Result<(), E>) -> Result<(), E>; - fn emit_map_elt_key(&mut self, idx: uint, f: |&mut Self| -> Result<(), E>) -> Result<(), E>; - fn emit_map_elt_val(&mut self, idx: uint, f: |&mut Self| -> Result<(), E>) -> Result<(), E>; + fn emit_map<F>(&mut self, len: uint, f: F) -> Result<(), E> where + F: FnOnce(&mut Self) -> Result<(), E>; + fn emit_map_elt_key<F>(&mut self, idx: uint, f: F) -> Result<(), E> where + F: FnMut(&mut Self) -> Result<(), E>; + fn emit_map_elt_val<F>(&mut self, idx: uint, f: F) -> Result<(), E> where + F: FnOnce(&mut Self) -> Result<(), E>; } pub trait Decoder<E> { @@ -113,57 +116,57 @@ pub trait Decoder<E> { fn read_str(&mut self) -> Result<String, E>; // Compound types: - fn read_enum<T>(&mut self, name: &str, f: |&mut Self| -> Result<T, E>) -> Result<T, E>; - - fn read_enum_variant<T>(&mut self, - names: &[&str], - f: |&mut Self, uint| -> Result<T, E>) - -> Result<T, E>; - fn read_enum_variant_arg<T>(&mut self, - a_idx: uint, - f: |&mut Self| -> Result<T, E>) - -> Result<T, E>; - - fn read_enum_struct_variant<T>(&mut self, - names: &[&str], - f: |&mut Self, uint| -> Result<T, E>) - -> Result<T, E>; - fn read_enum_struct_variant_field<T>(&mut self, - &f_name: &str, - f_idx: uint, - f: |&mut Self| -> Result<T, E>) - -> Result<T, E>; - - fn read_struct<T>(&mut self, s_name: &str, len: uint, f: |&mut Self| -> Result<T, E>) - -> Result<T, E>; - fn read_struct_field<T>(&mut self, - f_name: &str, - f_idx: uint, - f: |&mut Self| -> Result<T, E>) - -> Result<T, E>; - - fn read_tuple<T>(&mut self, len: uint, f: |&mut Self| -> Result<T, E>) -> Result<T, E>; - fn read_tuple_arg<T>(&mut self, a_idx: uint, f: |&mut Self| -> Result<T, E>) -> Result<T, E>; - - fn read_tuple_struct<T>(&mut self, - s_name: &str, - len: uint, - f: |&mut Self| -> Result<T, E>) - -> Result<T, E>; - fn read_tuple_struct_arg<T>(&mut self, - a_idx: uint, - f: |&mut Self| -> Result<T, E>) - -> Result<T, E>; + fn read_enum<T, F>(&mut self, name: &str, f: F) -> Result<T, E> where + F: FnOnce(&mut Self) -> Result<T, E>; + + fn read_enum_variant<T, F>(&mut self, names: &[&str], f: F) -> Result<T, E> where + F: FnOnce(&mut Self, uint) -> Result<T, E>; + fn read_enum_variant_arg<T, F>(&mut self, a_idx: uint, f: F) -> Result<T, E> where + F: FnOnce(&mut Self) -> Result<T, E>; + + fn read_enum_struct_variant<T, F>(&mut self, names: &[&str], f: F) -> Result<T, E> where + F: FnOnce(&mut Self, uint) -> Result<T, E>; + fn read_enum_struct_variant_field<T, F>(&mut self, + &f_name: &str, + f_idx: uint, + f: F) + -> Result<T, E> where + F: FnOnce(&mut Self) -> Result<T, E>; + + fn read_struct<T, F>(&mut self, s_name: &str, len: uint, f: F) -> Result<T, E> where + F: FnOnce(&mut Self) -> Result<T, E>; + fn read_struct_field<T, F>(&mut self, + f_name: &str, + f_idx: uint, + f: F) + -> Result<T, E> where + F: FnOnce(&mut Self) -> Result<T, E>; + + fn read_tuple<T, F>(&mut self, len: uint, f: F) -> Result<T, E> where + F: FnOnce(&mut Self) -> Result<T, E>; + fn read_tuple_arg<T, F>(&mut self, a_idx: uint, f: F) -> Result<T, E> where + F: FnOnce(&mut Self) -> Result<T, E>; + + fn read_tuple_struct<T, F>(&mut self, s_name: &str, len: uint, f: F) -> Result<T, E> where + F: FnOnce(&mut Self) -> Result<T, E>; + fn read_tuple_struct_arg<T, F>(&mut self, a_idx: uint, f: F) -> Result<T, E> where + F: FnOnce(&mut Self) -> Result<T, E>; // Specialized types: - fn read_option<T>(&mut self, f: |&mut Self, bool| -> Result<T, E>) -> Result<T, E>; + fn read_option<T, F>(&mut self, f: F) -> Result<T, E> where + F: FnOnce(&mut Self, bool) -> Result<T, E>; - fn read_seq<T>(&mut self, f: |&mut Self, uint| -> Result<T, E>) -> Result<T, E>; - fn read_seq_elt<T>(&mut self, idx: uint, f: |&mut Self| -> Result<T, E>) -> Result<T, E>; + fn read_seq<T, F>(&mut self, f: F) -> Result<T, E> where + F: FnOnce(&mut Self, uint) -> Result<T, E>; + fn read_seq_elt<T, F>(&mut self, idx: uint, f: F) -> Result<T, E> where + F: FnOnce(&mut Self) -> Result<T, E>; - fn read_map<T>(&mut self, f: |&mut Self, uint| -> Result<T, E>) -> Result<T, E>; - fn read_map_elt_key<T>(&mut self, idx: uint, f: |&mut Self| -> Result<T, E>) -> Result<T, E>; - fn read_map_elt_val<T>(&mut self, idx: uint, f: |&mut Self| -> Result<T, E>) -> Result<T, E>; + fn read_map<T, F>(&mut self, f: F) -> Result<T, E> where + F: FnOnce(&mut Self, uint) -> Result<T, E>; + fn read_map_elt_key<T, F>(&mut self, idx: uint, f: F) -> Result<T, E> where + F: FnOnce(&mut Self) -> Result<T, E>; + fn read_map_elt_val<T, F>(&mut self, idx: uint, f: F) -> Result<T, E> where + F: FnOnce(&mut Self) -> Result<T, E>; // Failure fn error(&mut self, err: &str) -> E; @@ -585,13 +588,14 @@ impl<E, D:Decoder<E>,T:Decodable<D, E>+Send+Sync> Decodable<D, E> for Arc<T> { // Helper routines pub trait EncoderHelpers<E> { - fn emit_from_vec<T>(&mut self, - v: &[T], - f: |&mut Self, v: &T| -> Result<(), E>) -> Result<(), E>; + fn emit_from_vec<T, F>(&mut self, v: &[T], f: F) -> Result<(), E> where + F: FnMut(&mut Self, &T) -> Result<(), E>; } impl<E, S:Encoder<E>> EncoderHelpers<E> for S { - fn emit_from_vec<T>(&mut self, v: &[T], f: |&mut S, &T| -> Result<(), E>) -> Result<(), E> { + fn emit_from_vec<T, F>(&mut self, v: &[T], mut f: F) -> Result<(), E> where + F: FnMut(&mut S, &T) -> Result<(), E>, + { self.emit_seq(v.len(), |this| { for (i, e) in v.iter().enumerate() { try!(this.emit_seq_elt(i, |this| { @@ -604,11 +608,14 @@ impl<E, S:Encoder<E>> EncoderHelpers<E> for S { } pub trait DecoderHelpers<E> { - fn read_to_vec<T>(&mut self, f: |&mut Self| -> Result<T, E>) -> Result<Vec<T>, E>; + fn read_to_vec<T, F>(&mut self, f: F) -> Result<Vec<T>, E> where + F: FnMut(&mut Self) -> Result<T, E>; } impl<E, D:Decoder<E>> DecoderHelpers<E> for D { - fn read_to_vec<T>(&mut self, f: |&mut D| -> Result<T, E>) -> Result<Vec<T>, E> { + fn read_to_vec<T, F>(&mut self, mut f: F) -> Result<Vec<T>, E> where F: + FnMut(&mut D) -> Result<T, E>, + { self.read_seq(|this, len| { let mut v = Vec::with_capacity(len); for i in range(0, len) { 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) diff --git a/src/libsyntax/ast_map/blocks.rs b/src/libsyntax/ast_map/blocks.rs index 639a33a8063..75f69f2f6d0 100644 --- a/src/libsyntax/ast_map/blocks.rs +++ b/src/libsyntax/ast_map/blocks.rs @@ -181,22 +181,23 @@ impl<'a> FnLikeNode<'a> { } pub fn kind(self) -> visit::FnKind<'a> { - let item = |p: ItemFnParts<'a>| -> visit::FnKind<'a> { + let item = |: p: ItemFnParts<'a>| -> visit::FnKind<'a> { visit::FkItemFn(p.ident, p.generics, p.style, p.abi) }; - let closure = |_: ClosureParts| { + let closure = |: _: ClosureParts| { visit::FkFnBlock }; - let method = |m: &'a ast::Method| { + let method = |: m: &'a ast::Method| { visit::FkMethod(m.pe_ident(), m.pe_generics(), m) }; self.handle(item, method, closure) } - fn handle<A>(self, - item_fn: |ItemFnParts<'a>| -> A, - method: |&'a ast::Method| -> A, - closure: |ClosureParts<'a>| -> A) -> A { + fn handle<A, I, M, C>(self, item_fn: I, method: M, closure: C) -> A where + I: FnOnce(ItemFnParts<'a>) -> A, + M: FnOnce(&'a ast::Method) -> A, + C: FnOnce(ClosureParts<'a>) -> A, + { match self.node { ast_map::NodeItem(i) => match i.node { ast::ItemFn(ref decl, style, abi, ref generics, ref block) => diff --git a/src/libsyntax/ast_map/mod.rs b/src/libsyntax/ast_map/mod.rs index 2c985f403f8..907ac6b19fc 100644 --- a/src/libsyntax/ast_map/mod.rs +++ b/src/libsyntax/ast_map/mod.rs @@ -424,7 +424,9 @@ impl<'ast> Map<'ast> { } } - pub fn with_path<T>(&self, id: NodeId, f: |PathElems| -> T) -> T { + pub fn with_path<T, F>(&self, id: NodeId, f: F) -> T where + F: FnOnce(PathElems) -> T, + { self.with_path_next(id, None, f) } @@ -438,7 +440,9 @@ impl<'ast> Map<'ast> { }) } - fn with_path_next<T>(&self, id: NodeId, next: LinkedPath, f: |PathElems| -> T) -> T { + fn with_path_next<T, F>(&self, id: NodeId, next: LinkedPath, f: F) -> T where + F: FnOnce(PathElems) -> T, + { let parent = self.get_parent(id); let parent = match self.find_entry(id) { Some(EntryForeignItem(..)) | Some(EntryVariant(..)) => { @@ -470,7 +474,9 @@ impl<'ast> Map<'ast> { /// Given a node ID and a closure, apply the closure to the array /// of attributes associated with the AST corresponding to the Node ID - pub fn with_attrs<T>(&self, id: NodeId, f: |Option<&[Attribute]>| -> T) -> T { + pub fn with_attrs<T, F>(&self, id: NodeId, f: F) -> T where + F: FnOnce(Option<&[Attribute]>) -> T, + { let attrs = match self.get(id) { NodeItem(i) => Some(i.attrs.as_slice()), NodeForeignItem(fi) => Some(fi.attrs.as_slice()), diff --git a/src/libsyntax/ast_util.rs b/src/libsyntax/ast_util.rs index eec3f69ee64..7579972c6d8 100644 --- a/src/libsyntax/ast_util.rs +++ b/src/libsyntax/ast_util.rs @@ -602,6 +602,7 @@ pub fn compute_id_range_for_fn_body(fk: visit::FnKind, id_visitor.operation.result } +// FIXME(#19596) unbox `it` pub fn walk_pat(pat: &Pat, it: |&Pat| -> bool) -> bool { if !it(pat) { return false; @@ -632,21 +633,21 @@ pub fn walk_pat(pat: &Pat, it: |&Pat| -> bool) -> bool { } pub trait EachViewItem { - fn each_view_item(&self, f: |&ast::ViewItem| -> bool) -> bool; + fn each_view_item<F>(&self, f: F) -> bool where F: FnMut(&ast::ViewItem) -> bool; } -struct EachViewItemData<'a> { - callback: |&ast::ViewItem|: 'a -> bool, +struct EachViewItemData<F> where F: FnMut(&ast::ViewItem) -> bool { + callback: F, } -impl<'a, 'v> Visitor<'v> for EachViewItemData<'a> { +impl<'v, F> Visitor<'v> for EachViewItemData<F> where F: FnMut(&ast::ViewItem) -> bool { fn visit_view_item(&mut self, view_item: &ast::ViewItem) { let _ = (self.callback)(view_item); } } impl EachViewItem for ast::Crate { - fn each_view_item(&self, f: |&ast::ViewItem| -> bool) -> bool { + fn each_view_item<F>(&self, f: F) -> bool where F: FnMut(&ast::ViewItem) -> bool { let mut visit = EachViewItemData { callback: f, }; diff --git a/src/libsyntax/attr.rs b/src/libsyntax/attr.rs index 5894a88ece6..8248eae4b8c 100644 --- a/src/libsyntax/attr.rs +++ b/src/libsyntax/attr.rs @@ -115,7 +115,8 @@ impl AttrMetaMethods for P<MetaItem> { pub trait AttributeMethods { fn meta<'a>(&'a self) -> &'a MetaItem; - fn with_desugared_doc<T>(&self, f: |&Attribute| -> T) -> T; + fn with_desugared_doc<T, F>(&self, f: F) -> T where + F: FnOnce(&Attribute) -> T; } impl AttributeMethods for Attribute { @@ -127,7 +128,9 @@ impl AttributeMethods for Attribute { /// Convert self to a normal #[doc="foo"] comment, if it is a /// comment like `///` or `/** */`. (Returns self unchanged for /// non-sugared doc attributes.) - fn with_desugared_doc<T>(&self, f: |&Attribute| -> T) -> T { + fn with_desugared_doc<T, F>(&self, f: F) -> T where + F: FnOnce(&Attribute) -> T, + { if self.node.is_sugared_doc { let comment = self.value_str().unwrap(); let meta = mk_name_value_item_str( diff --git a/src/libsyntax/codemap.rs b/src/libsyntax/codemap.rs index 7f2becf8201..d2fe667339c 100644 --- a/src/libsyntax/codemap.rs +++ b/src/libsyntax/codemap.rs @@ -568,7 +568,9 @@ impl CodeMap { ExpnId(expansions.len().to_u32().expect("too many ExpnInfo's!") - 1) } - pub fn with_expn_info<T>(&self, id: ExpnId, f: |Option<&ExpnInfo>| -> T) -> T { + pub fn with_expn_info<T, F>(&self, id: ExpnId, f: F) -> T where + F: FnOnce(Option<&ExpnInfo>) -> T, + { match id { NO_EXPANSION => f(None), ExpnId(i) => f(Some(&(*self.expansions.borrow())[i as uint])) diff --git a/src/libsyntax/config.rs b/src/libsyntax/config.rs index 4f718555d53..87426dce918 100644 --- a/src/libsyntax/config.rs +++ b/src/libsyntax/config.rs @@ -19,8 +19,8 @@ use util::small_vector::SmallVector; /// A folder that strips out items that do not belong in the current /// configuration. -struct Context<'a> { - in_cfg: |attrs: &[ast::Attribute]|: 'a -> bool, +struct Context<F> where F: FnMut(&[ast::Attribute]) -> bool { + in_cfg: F, } // Support conditional compilation by transforming the AST, stripping out @@ -30,7 +30,7 @@ pub fn strip_unconfigured_items(diagnostic: &SpanHandler, krate: ast::Crate) -> strip_items(krate, |attrs| in_cfg(diagnostic, config.as_slice(), attrs)) } -impl<'a> fold::Folder for Context<'a> { +impl<F> fold::Folder for Context<F> where F: FnMut(&[ast::Attribute]) -> bool { fn fold_mod(&mut self, module: ast::Mod) -> ast::Mod { fold_mod(self, module) } @@ -54,16 +54,20 @@ impl<'a> fold::Folder for Context<'a> { } } -pub fn strip_items(krate: ast::Crate, - in_cfg: |attrs: &[ast::Attribute]| -> bool) - -> ast::Crate { +pub fn strip_items<F>(krate: ast::Crate, in_cfg: F) -> ast::Crate where + F: FnMut(&[ast::Attribute]) -> bool, +{ let mut ctxt = Context { in_cfg: in_cfg, }; ctxt.fold_crate(krate) } -fn filter_view_item(cx: &mut Context, view_item: ast::ViewItem) -> Option<ast::ViewItem> { +fn filter_view_item<F>(cx: &mut Context<F>, + view_item: ast::ViewItem) + -> Option<ast::ViewItem> where + F: FnMut(&[ast::Attribute]) -> bool +{ if view_item_in_cfg(cx, &view_item) { Some(view_item) } else { @@ -71,7 +75,11 @@ fn filter_view_item(cx: &mut Context, view_item: ast::ViewItem) -> Option<ast::V } } -fn fold_mod(cx: &mut Context, ast::Mod {inner, view_items, items}: ast::Mod) -> ast::Mod { +fn fold_mod<F>(cx: &mut Context<F>, + ast::Mod {inner, + view_items, items}: ast::Mod) -> ast::Mod where + F: FnMut(&[ast::Attribute]) -> bool +{ ast::Mod { inner: inner, view_items: view_items.into_iter().filter_map(|a| { @@ -83,8 +91,11 @@ fn fold_mod(cx: &mut Context, ast::Mod {inner, view_items, items}: ast::Mod) -> } } -fn filter_foreign_item(cx: &mut Context, item: P<ast::ForeignItem>) - -> Option<P<ast::ForeignItem>> { +fn filter_foreign_item<F>(cx: &mut Context<F>, + item: P<ast::ForeignItem>) + -> Option<P<ast::ForeignItem>> where + F: FnMut(&[ast::Attribute]) -> bool +{ if foreign_item_in_cfg(cx, &*item) { Some(item) } else { @@ -92,8 +103,11 @@ fn filter_foreign_item(cx: &mut Context, item: P<ast::ForeignItem>) } } -fn fold_foreign_mod(cx: &mut Context, ast::ForeignMod {abi, view_items, items}: ast::ForeignMod) - -> ast::ForeignMod { +fn fold_foreign_mod<F>(cx: &mut Context<F>, + ast::ForeignMod {abi, view_items, items}: ast::ForeignMod) + -> ast::ForeignMod where + F: FnMut(&[ast::Attribute]) -> bool +{ ast::ForeignMod { abi: abi, view_items: view_items.into_iter().filter_map(|a| { @@ -105,7 +119,9 @@ fn fold_foreign_mod(cx: &mut Context, ast::ForeignMod {abi, view_items, items}: } } -fn fold_item(cx: &mut Context, item: P<ast::Item>) -> SmallVector<P<ast::Item>> { +fn fold_item<F>(cx: &mut Context<F>, item: P<ast::Item>) -> SmallVector<P<ast::Item>> where + F: FnMut(&[ast::Attribute]) -> bool +{ if item_in_cfg(cx, &*item) { SmallVector::one(item.map(|i| cx.fold_item_simple(i))) } else { @@ -113,7 +129,9 @@ fn fold_item(cx: &mut Context, item: P<ast::Item>) -> SmallVector<P<ast::Item>> } } -fn fold_item_underscore(cx: &mut Context, item: ast::Item_) -> ast::Item_ { +fn fold_item_underscore<F>(cx: &mut Context<F>, item: ast::Item_) -> ast::Item_ where + F: FnMut(&[ast::Attribute]) -> bool +{ let item = match item { ast::ItemImpl(a, b, c, impl_items) => { let impl_items = impl_items.into_iter() @@ -166,7 +184,9 @@ fn fold_item_underscore(cx: &mut Context, item: ast::Item_) -> ast::Item_ { fold::noop_fold_item_underscore(item, cx) } -fn fold_struct(cx: &mut Context, def: P<ast::StructDef>) -> P<ast::StructDef> { +fn fold_struct<F>(cx: &mut Context<F>, def: P<ast::StructDef>) -> P<ast::StructDef> where + F: FnMut(&[ast::Attribute]) -> bool +{ def.map(|ast::StructDef { fields, ctor_id }| { ast::StructDef { fields: fields.into_iter().filter(|m| { @@ -177,7 +197,9 @@ fn fold_struct(cx: &mut Context, def: P<ast::StructDef>) -> P<ast::StructDef> { }) } -fn retain_stmt(cx: &mut Context, stmt: &ast::Stmt) -> bool { +fn retain_stmt<F>(cx: &mut Context<F>, stmt: &ast::Stmt) -> bool where + F: FnMut(&[ast::Attribute]) -> bool +{ match stmt.node { ast::StmtDecl(ref decl, _) => { match decl.node { @@ -191,7 +213,9 @@ fn retain_stmt(cx: &mut Context, stmt: &ast::Stmt) -> bool { } } -fn fold_block(cx: &mut Context, b: P<ast::Block>) -> P<ast::Block> { +fn fold_block<F>(cx: &mut Context<F>, b: P<ast::Block>) -> P<ast::Block> where + F: FnMut(&[ast::Attribute]) -> bool +{ b.map(|ast::Block {id, view_items, stmts, expr, rules, span}| { let resulting_stmts: Vec<P<ast::Stmt>> = stmts.into_iter().filter(|a| retain_stmt(cx, &**a)).collect(); @@ -212,7 +236,9 @@ fn fold_block(cx: &mut Context, b: P<ast::Block>) -> P<ast::Block> { }) } -fn fold_expr(cx: &mut Context, expr: P<ast::Expr>) -> P<ast::Expr> { +fn fold_expr<F>(cx: &mut Context<F>, expr: P<ast::Expr>) -> P<ast::Expr> where + F: FnMut(&[ast::Attribute]) -> bool +{ expr.map(|ast::Expr {id, span, node}| { fold::noop_fold_expr(ast::Expr { id: id, @@ -229,19 +255,27 @@ fn fold_expr(cx: &mut Context, expr: P<ast::Expr>) -> P<ast::Expr> { }) } -fn item_in_cfg(cx: &mut Context, item: &ast::Item) -> bool { +fn item_in_cfg<F>(cx: &mut Context<F>, item: &ast::Item) -> bool where + F: FnMut(&[ast::Attribute]) -> bool +{ return (cx.in_cfg)(item.attrs.as_slice()); } -fn foreign_item_in_cfg(cx: &mut Context, item: &ast::ForeignItem) -> bool { +fn foreign_item_in_cfg<F>(cx: &mut Context<F>, item: &ast::ForeignItem) -> bool where + F: FnMut(&[ast::Attribute]) -> bool +{ return (cx.in_cfg)(item.attrs.as_slice()); } -fn view_item_in_cfg(cx: &mut Context, item: &ast::ViewItem) -> bool { +fn view_item_in_cfg<F>(cx: &mut Context<F>, item: &ast::ViewItem) -> bool where + F: FnMut(&[ast::Attribute]) -> bool +{ return (cx.in_cfg)(item.attrs.as_slice()); } -fn trait_method_in_cfg(cx: &mut Context, meth: &ast::TraitItem) -> bool { +fn trait_method_in_cfg<F>(cx: &mut Context<F>, meth: &ast::TraitItem) -> bool where + F: FnMut(&[ast::Attribute]) -> bool +{ match *meth { ast::RequiredMethod(ref meth) => (cx.in_cfg)(meth.attrs.as_slice()), ast::ProvidedMethod(ref meth) => (cx.in_cfg)(meth.attrs.as_slice()), @@ -249,7 +283,9 @@ fn trait_method_in_cfg(cx: &mut Context, meth: &ast::TraitItem) -> bool { } } -fn impl_item_in_cfg(cx: &mut Context, impl_item: &ast::ImplItem) -> bool { +fn impl_item_in_cfg<F>(cx: &mut Context<F>, impl_item: &ast::ImplItem) -> bool where + F: FnMut(&[ast::Attribute]) -> bool +{ match *impl_item { ast::MethodImplItem(ref meth) => (cx.in_cfg)(meth.attrs.as_slice()), ast::TypeImplItem(ref typ) => (cx.in_cfg)(typ.attrs.as_slice()), diff --git a/src/libsyntax/diagnostic.rs b/src/libsyntax/diagnostic.rs index bbda80bd96c..3a816987922 100644 --- a/src/libsyntax/diagnostic.rs +++ b/src/libsyntax/diagnostic.rs @@ -581,7 +581,9 @@ fn print_macro_backtrace(w: &mut EmitterWriter, cs.map_or(Ok(()), |call_site| print_macro_backtrace(w, cm, call_site)) } -pub fn expect<T>(diag: &SpanHandler, opt: Option<T>, msg: || -> String) -> T { +pub fn expect<T, M>(diag: &SpanHandler, opt: Option<T>, msg: M) -> T where + M: FnOnce() -> String, +{ match opt { Some(t) => t, None => diag.handler().bug(msg().as_slice()), diff --git a/src/libsyntax/diagnostics/plugin.rs b/src/libsyntax/diagnostics/plugin.rs index 2be11a236d3..cb2a1f8acd8 100644 --- a/src/libsyntax/diagnostics/plugin.rs +++ b/src/libsyntax/diagnostics/plugin.rs @@ -25,14 +25,18 @@ thread_local!(static USED_DIAGNOSTICS: RefCell<HashMap<Name, Span>> = { RefCell::new(HashMap::new()) }) -fn with_registered_diagnostics<T>(f: |&mut HashMap<Name, Option<Name>>| -> T) -> T { - REGISTERED_DIAGNOSTICS.with(|slot| { +fn with_registered_diagnostics<T, F>(f: F) -> T where + F: FnOnce(&mut HashMap<Name, Option<Name>>) -> T, +{ + REGISTERED_DIAGNOSTICS.with(move |slot| { f(&mut *slot.borrow_mut()) }) } -fn with_used_diagnostics<T>(f: |&mut HashMap<Name, Span>| -> T) -> T { - USED_DIAGNOSTICS.with(|slot| { +fn with_used_diagnostics<T, F>(f: F) -> T where + F: FnOnce(&mut HashMap<Name, Span>) -> T, +{ + USED_DIAGNOSTICS.with(move |slot| { f(&mut *slot.borrow_mut()) }) } diff --git a/src/libsyntax/ext/deriving/bounds.rs b/src/libsyntax/ext/deriving/bounds.rs index 0595b0bc7f4..3145b3bb1a4 100644 --- a/src/libsyntax/ext/deriving/bounds.rs +++ b/src/libsyntax/ext/deriving/bounds.rs @@ -15,12 +15,13 @@ use ext::deriving::generic::*; use ext::deriving::generic::ty::*; use ptr::P; -pub fn expand_deriving_bound(cx: &mut ExtCtxt, - span: Span, - mitem: &MetaItem, - item: &Item, - push: |P<Item>|) { - +pub fn expand_deriving_bound<F>(cx: &mut ExtCtxt, + span: Span, + mitem: &MetaItem, + item: &Item, + push: F) where + F: FnOnce(P<Item>), +{ let name = match mitem.node { MetaWord(ref tname) => { match tname.get() { diff --git a/src/libsyntax/ext/deriving/clone.rs b/src/libsyntax/ext/deriving/clone.rs index fccc67bf220..a34764221b3 100644 --- a/src/libsyntax/ext/deriving/clone.rs +++ b/src/libsyntax/ext/deriving/clone.rs @@ -17,11 +17,13 @@ use ext::deriving::generic::ty::*; use parse::token::InternedString; use ptr::P; -pub fn expand_deriving_clone(cx: &mut ExtCtxt, - span: Span, - mitem: &MetaItem, - item: &Item, - push: |P<Item>|) { +pub fn expand_deriving_clone<F>(cx: &mut ExtCtxt, + span: Span, + mitem: &MetaItem, + item: &Item, + push: F) where + F: FnOnce(P<Item>), +{ let inline = cx.meta_word(span, InternedString::new("inline")); let attrs = vec!(cx.attribute(span, inline)); let trait_def = TraitDef { @@ -60,7 +62,7 @@ fn cs_clone( cx.ident_of("Clone"), cx.ident_of("clone"), ]; - let subcall = |field: &FieldInfo| { + let subcall = |&: field: &FieldInfo| { let args = vec![cx.expr_addr_of(field.span, field.self_.clone())]; cx.expr_call_global(field.span, fn_path.clone(), args) diff --git a/src/libsyntax/ext/deriving/cmp/eq.rs b/src/libsyntax/ext/deriving/cmp/eq.rs index 7727bb824db..c8bf5ec326c 100644 --- a/src/libsyntax/ext/deriving/cmp/eq.rs +++ b/src/libsyntax/ext/deriving/cmp/eq.rs @@ -17,11 +17,13 @@ use ext::deriving::generic::ty::*; use parse::token::InternedString; use ptr::P; -pub fn expand_deriving_eq(cx: &mut ExtCtxt, - span: Span, - mitem: &MetaItem, - item: &Item, - push: |P<Item>|) { +pub fn expand_deriving_eq<F>(cx: &mut ExtCtxt, + span: Span, + mitem: &MetaItem, + item: &Item, + push: F) where + F: FnOnce(P<Item>), +{ // structures are equal if all fields are equal, and non equal, if // any fields are not equal or if the enum variants are different fn cs_eq(cx: &mut ExtCtxt, span: Span, substr: &Substructure) -> P<Expr> { diff --git a/src/libsyntax/ext/deriving/cmp/ord.rs b/src/libsyntax/ext/deriving/cmp/ord.rs index 1bd55b5d504..bd1962de56e 100644 --- a/src/libsyntax/ext/deriving/cmp/ord.rs +++ b/src/libsyntax/ext/deriving/cmp/ord.rs @@ -20,11 +20,13 @@ use ext::deriving::generic::ty::*; use parse::token::InternedString; use ptr::P; -pub fn expand_deriving_ord(cx: &mut ExtCtxt, - span: Span, - mitem: &MetaItem, - item: &Item, - push: |P<Item>|) { +pub fn expand_deriving_ord<F>(cx: &mut ExtCtxt, + span: Span, + mitem: &MetaItem, + item: &Item, + push: F) where + F: FnOnce(P<Item>), +{ macro_rules! md ( ($name:expr, $op:expr, $equal:expr) => { { let inline = cx.meta_word(span, InternedString::new("inline")); diff --git a/src/libsyntax/ext/deriving/cmp/totaleq.rs b/src/libsyntax/ext/deriving/cmp/totaleq.rs index ecee2008254..2b986bea122 100644 --- a/src/libsyntax/ext/deriving/cmp/totaleq.rs +++ b/src/libsyntax/ext/deriving/cmp/totaleq.rs @@ -17,11 +17,13 @@ use ext::deriving::generic::ty::*; use parse::token::InternedString; use ptr::P; -pub fn expand_deriving_totaleq(cx: &mut ExtCtxt, - span: Span, - mitem: &MetaItem, - item: &Item, - push: |P<Item>|) { +pub fn expand_deriving_totaleq<F>(cx: &mut ExtCtxt, + span: Span, + mitem: &MetaItem, + item: &Item, + push: F) where + F: FnOnce(P<Item>), +{ fn cs_total_eq_assert(cx: &mut ExtCtxt, span: Span, substr: &Substructure) -> P<Expr> { cs_same_method(|cx, span, exprs| { // create `a.<method>(); b.<method>(); c.<method>(); ...` diff --git a/src/libsyntax/ext/deriving/cmp/totalord.rs b/src/libsyntax/ext/deriving/cmp/totalord.rs index 6900773f44d..a2bf46f41fc 100644 --- a/src/libsyntax/ext/deriving/cmp/totalord.rs +++ b/src/libsyntax/ext/deriving/cmp/totalord.rs @@ -18,11 +18,13 @@ use ext::deriving::generic::ty::*; use parse::token::InternedString; use ptr::P; -pub fn expand_deriving_totalord(cx: &mut ExtCtxt, - span: Span, - mitem: &MetaItem, - item: &Item, - push: |P<Item>|) { +pub fn expand_deriving_totalord<F>(cx: &mut ExtCtxt, + span: Span, + mitem: &MetaItem, + item: &Item, + push: F) where + F: FnOnce(P<Item>), +{ let inline = cx.meta_word(span, InternedString::new("inline")); let attrs = vec!(cx.attribute(span, inline)); let trait_def = TraitDef { diff --git a/src/libsyntax/ext/deriving/decodable.rs b/src/libsyntax/ext/deriving/decodable.rs index e3cf2b68752..0a8d59da896 100644 --- a/src/libsyntax/ext/deriving/decodable.rs +++ b/src/libsyntax/ext/deriving/decodable.rs @@ -21,11 +21,13 @@ use parse::token::InternedString; use parse::token; use ptr::P; -pub fn expand_deriving_decodable(cx: &mut ExtCtxt, - span: Span, - mitem: &MetaItem, - item: &Item, - push: |P<Item>|) { +pub fn expand_deriving_decodable<F>(cx: &mut ExtCtxt, + span: Span, + mitem: &MetaItem, + item: &Item, + push: F) where + F: FnOnce(P<Item>), +{ let trait_def = TraitDef { span: span, attributes: Vec::new(), @@ -155,12 +157,14 @@ fn decodable_substructure(cx: &mut ExtCtxt, trait_span: Span, /// Create a decoder for a single enum variant/struct: /// - `outer_pat_path` is the path to this enum variant/struct /// - `getarg` should retrieve the `uint`-th field with name `@str`. -fn decode_static_fields(cx: &mut ExtCtxt, - trait_span: Span, - outer_pat_path: ast::Path, - fields: &StaticFields, - getarg: |&mut ExtCtxt, Span, InternedString, uint| -> P<Expr>) - -> P<Expr> { +fn decode_static_fields<F>(cx: &mut ExtCtxt, + trait_span: Span, + outer_pat_path: ast::Path, + fields: &StaticFields, + mut getarg: F) + -> P<Expr> where + F: FnMut(&mut ExtCtxt, Span, InternedString, uint) -> P<Expr>, +{ match *fields { Unnamed(ref fields) => { let path_expr = cx.expr_path(outer_pat_path); diff --git a/src/libsyntax/ext/deriving/default.rs b/src/libsyntax/ext/deriving/default.rs index f4a66414d89..b3621490ce3 100644 --- a/src/libsyntax/ext/deriving/default.rs +++ b/src/libsyntax/ext/deriving/default.rs @@ -17,11 +17,13 @@ use ext::deriving::generic::ty::*; use parse::token::InternedString; use ptr::P; -pub fn expand_deriving_default(cx: &mut ExtCtxt, - span: Span, - mitem: &MetaItem, - item: &Item, - push: |P<Item>|) { +pub fn expand_deriving_default<F>(cx: &mut ExtCtxt, + span: Span, + mitem: &MetaItem, + item: &Item, + push: F) where + F: FnOnce(P<Item>), +{ let inline = cx.meta_word(span, InternedString::new("inline")); let attrs = vec!(cx.attribute(span, inline)); let trait_def = TraitDef { diff --git a/src/libsyntax/ext/deriving/encodable.rs b/src/libsyntax/ext/deriving/encodable.rs index 62f3b5d01b4..30851ebeaae 100644 --- a/src/libsyntax/ext/deriving/encodable.rs +++ b/src/libsyntax/ext/deriving/encodable.rs @@ -97,11 +97,13 @@ use ext::deriving::generic::ty::*; use parse::token; use ptr::P; -pub fn expand_deriving_encodable(cx: &mut ExtCtxt, - span: Span, - mitem: &MetaItem, - item: &Item, - push: |P<Item>|) { +pub fn expand_deriving_encodable<F>(cx: &mut ExtCtxt, + span: Span, + mitem: &MetaItem, + item: &Item, + push: F) where + F: FnOnce(P<Item>), +{ let trait_def = TraitDef { span: span, attributes: Vec::new(), diff --git a/src/libsyntax/ext/deriving/generic/mod.rs b/src/libsyntax/ext/deriving/generic/mod.rs index cf3b3ad9051..a75be40604e 100644 --- a/src/libsyntax/ext/deriving/generic/mod.rs +++ b/src/libsyntax/ext/deriving/generic/mod.rs @@ -333,11 +333,13 @@ pub fn combine_substructure<'a>(f: CombineSubstructureFunc<'a>) impl<'a> TraitDef<'a> { - pub fn expand(&self, - cx: &mut ExtCtxt, - mitem: &ast::MetaItem, - item: &ast::Item, - push: |P<ast::Item>|) { + pub fn expand<F>(&self, + cx: &mut ExtCtxt, + mitem: &ast::MetaItem, + item: &ast::Item, + push: F) where + F: FnOnce(P<ast::Item>), + { let newitem = match item.node { ast::ItemStruct(ref struct_def, ref generics) => { self.expand_struct_def(cx, @@ -1309,14 +1311,16 @@ impl<'a> TraitDef<'a> { /// Fold the fields. `use_foldl` controls whether this is done /// left-to-right (`true`) or right-to-left (`false`). -pub fn cs_fold(use_foldl: bool, - f: |&mut ExtCtxt, Span, P<Expr>, P<Expr>, &[P<Expr>]| -> P<Expr>, - base: P<Expr>, - enum_nonmatch_f: EnumNonMatchCollapsedFunc, - cx: &mut ExtCtxt, - trait_span: Span, - substructure: &Substructure) - -> P<Expr> { +pub fn cs_fold<F>(use_foldl: bool, + mut f: F, + base: P<Expr>, + enum_nonmatch_f: EnumNonMatchCollapsedFunc, + cx: &mut ExtCtxt, + trait_span: Span, + substructure: &Substructure) + -> P<Expr> where + F: FnMut(&mut ExtCtxt, Span, P<Expr>, P<Expr>, &[P<Expr>]) -> P<Expr>, +{ match *substructure.fields { EnumMatching(_, _, ref all_fields) | Struct(ref all_fields) => { if use_foldl { @@ -1355,12 +1359,14 @@ pub fn cs_fold(use_foldl: bool, /// self_2.method(__arg_1_2, __arg_2_2)]) /// ``` #[inline] -pub fn cs_same_method(f: |&mut ExtCtxt, Span, Vec<P<Expr>>| -> P<Expr>, - enum_nonmatch_f: EnumNonMatchCollapsedFunc, - cx: &mut ExtCtxt, - trait_span: Span, - substructure: &Substructure) - -> P<Expr> { +pub fn cs_same_method<F>(f: F, + enum_nonmatch_f: EnumNonMatchCollapsedFunc, + cx: &mut ExtCtxt, + trait_span: Span, + substructure: &Substructure) + -> P<Expr> where + F: FnOnce(&mut ExtCtxt, Span, Vec<P<Expr>>) -> P<Expr>, +{ match *substructure.fields { EnumMatching(_, _, ref all_fields) | Struct(ref all_fields) => { // call self_n.method(other_1_n, other_2_n, ...) @@ -1388,14 +1394,16 @@ pub fn cs_same_method(f: |&mut ExtCtxt, Span, Vec<P<Expr>>| -> P<Expr>, /// fields. `use_foldl` controls whether this is done left-to-right /// (`true`) or right-to-left (`false`). #[inline] -pub fn cs_same_method_fold(use_foldl: bool, - f: |&mut ExtCtxt, Span, P<Expr>, P<Expr>| -> P<Expr>, - base: P<Expr>, - enum_nonmatch_f: EnumNonMatchCollapsedFunc, - cx: &mut ExtCtxt, - trait_span: Span, - substructure: &Substructure) - -> P<Expr> { +pub fn cs_same_method_fold<F>(use_foldl: bool, + mut f: F, + base: P<Expr>, + enum_nonmatch_f: EnumNonMatchCollapsedFunc, + cx: &mut ExtCtxt, + trait_span: Span, + substructure: &Substructure) + -> P<Expr> where + F: FnMut(&mut ExtCtxt, Span, P<Expr>, P<Expr>) -> P<Expr>, +{ cs_same_method( |cx, span, vals| { if use_foldl { diff --git a/src/libsyntax/ext/deriving/hash.rs b/src/libsyntax/ext/deriving/hash.rs index b7f11c25825..4e59124a129 100644 --- a/src/libsyntax/ext/deriving/hash.rs +++ b/src/libsyntax/ext/deriving/hash.rs @@ -17,11 +17,13 @@ use ext::deriving::generic::ty::*; use parse::token::InternedString; use ptr::P; -pub fn expand_deriving_hash(cx: &mut ExtCtxt, - span: Span, - mitem: &MetaItem, - item: &Item, - push: |P<Item>|) { +pub fn expand_deriving_hash<F>(cx: &mut ExtCtxt, + span: Span, + mitem: &MetaItem, + item: &Item, + push: F) where + F: FnOnce(P<Item>), +{ let (path, generics, args) = if cx.ecfg.deriving_hash_type_parameter { (Path::new_(vec!("std", "hash", "Hash"), None, diff --git a/src/libsyntax/ext/deriving/primitive.rs b/src/libsyntax/ext/deriving/primitive.rs index cd2d98b70f1..8abd846373a 100644 --- a/src/libsyntax/ext/deriving/primitive.rs +++ b/src/libsyntax/ext/deriving/primitive.rs @@ -18,11 +18,13 @@ use ext::deriving::generic::ty::*; use parse::token::InternedString; use ptr::P; -pub fn expand_deriving_from_primitive(cx: &mut ExtCtxt, - span: Span, - mitem: &MetaItem, - item: &Item, - push: |P<Item>|) { +pub fn expand_deriving_from_primitive<F>(cx: &mut ExtCtxt, + span: Span, + mitem: &MetaItem, + item: &Item, + push: F) where + F: FnOnce(P<Item>), +{ let inline = cx.meta_word(span, InternedString::new("inline")); let attrs = vec!(cx.attribute(span, inline)); let trait_def = TraitDef { diff --git a/src/libsyntax/ext/deriving/rand.rs b/src/libsyntax/ext/deriving/rand.rs index c4e64d58c29..4f6e4d1fb3c 100644 --- a/src/libsyntax/ext/deriving/rand.rs +++ b/src/libsyntax/ext/deriving/rand.rs @@ -17,11 +17,13 @@ use ext::deriving::generic::*; use ext::deriving::generic::ty::*; use ptr::P; -pub fn expand_deriving_rand(cx: &mut ExtCtxt, - span: Span, - mitem: &MetaItem, - item: &Item, - push: |P<Item>|) { +pub fn expand_deriving_rand<F>(cx: &mut ExtCtxt, + span: Span, + mitem: &MetaItem, + item: &Item, + push: F) where + F: FnOnce(P<Item>), +{ let trait_def = TraitDef { span: span, attributes: Vec::new(), @@ -64,7 +66,7 @@ fn rand_substructure(cx: &mut ExtCtxt, trait_span: Span, substr: &Substructure) cx.ident_of("Rand"), cx.ident_of("rand") ); - let rand_call = |cx: &mut ExtCtxt, span| { + let mut rand_call = |&mut: cx: &mut ExtCtxt, span| { cx.expr_call_global(span, rand_ident.clone(), vec!(rng.clone())) @@ -133,12 +135,14 @@ fn rand_substructure(cx: &mut ExtCtxt, trait_span: Span, substr: &Substructure) _ => cx.bug("Non-static method in `deriving(Rand)`") }; - fn rand_thing(cx: &mut ExtCtxt, - trait_span: Span, - ctor_path: ast::Path, - summary: &StaticFields, - rand_call: |&mut ExtCtxt, Span| -> P<Expr>) - -> P<Expr> { + fn rand_thing<F>(cx: &mut ExtCtxt, + trait_span: Span, + ctor_path: ast::Path, + summary: &StaticFields, + mut rand_call: F) + -> P<Expr> where + F: FnMut(&mut ExtCtxt, Span) -> P<Expr>, + { let path = cx.expr_path(ctor_path.clone()); match *summary { Unnamed(ref fields) => { diff --git a/src/libsyntax/ext/deriving/show.rs b/src/libsyntax/ext/deriving/show.rs index 322a84eaa2b..a68b521bbc9 100644 --- a/src/libsyntax/ext/deriving/show.rs +++ b/src/libsyntax/ext/deriving/show.rs @@ -21,11 +21,13 @@ use ptr::P; use std::collections::HashMap; -pub fn expand_deriving_show(cx: &mut ExtCtxt, - span: Span, - mitem: &MetaItem, - item: &Item, - push: |P<Item>|) { +pub fn expand_deriving_show<F>(cx: &mut ExtCtxt, + span: Span, + mitem: &MetaItem, + item: &Item, + push: F) where + F: FnOnce(P<Item>), +{ // &mut ::std::fmt::Formatter let fmtr = Ptr(box Literal(Path::new(vec!("std", "fmt", "Formatter"))), Borrowed(None, ast::MutMutable)); diff --git a/src/libsyntax/ext/deriving/zero.rs b/src/libsyntax/ext/deriving/zero.rs index 7f265b529ff..ea32549cad2 100644 --- a/src/libsyntax/ext/deriving/zero.rs +++ b/src/libsyntax/ext/deriving/zero.rs @@ -17,11 +17,13 @@ use ext::deriving::generic::ty::*; use parse::token::InternedString; use ptr::P; -pub fn expand_deriving_zero(cx: &mut ExtCtxt, - span: Span, - mitem: &MetaItem, - item: &Item, - push: |P<Item>|) { +pub fn expand_deriving_zero<F>(cx: &mut ExtCtxt, + span: Span, + mitem: &MetaItem, + item: &Item, + push: F) where + F: FnOnce(P<Item>), +{ let inline = cx.meta_word(span, InternedString::new("inline")); let attrs = vec!(cx.attribute(span, inline)); let trait_def = TraitDef { diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index a697d332d16..9c4e85f16ff 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -238,11 +238,13 @@ pub fn expand_expr(e: P<ast::Expr>, fld: &mut MacroExpander) -> P<ast::Expr> { /// of expansion and the mark which must be applied to the result. /// Our current interface doesn't allow us to apply the mark to the /// result until after calling make_expr, make_items, etc. -fn expand_mac_invoc<T>(mac: ast::Mac, span: codemap::Span, - parse_thunk: |Box<MacResult>|->Option<T>, - mark_thunk: |T,Mrk|->T, - fld: &mut MacroExpander) - -> Option<T> +fn expand_mac_invoc<T, F, G>(mac: ast::Mac, span: codemap::Span, + parse_thunk: F, + mark_thunk: G, + fld: &mut MacroExpander) + -> Option<T> where + F: FnOnce(Box<MacResult>) -> Option<T>, + G: FnOnce(T, Mrk) -> T, { match mac.node { // it would almost certainly be cleaner to pass the whole diff --git a/src/libsyntax/ext/mtwt.rs b/src/libsyntax/ext/mtwt.rs index 48120b575ac..a4e06aeaf63 100644 --- a/src/libsyntax/ext/mtwt.rs +++ b/src/libsyntax/ext/mtwt.rs @@ -105,9 +105,11 @@ pub fn apply_renames(renames: &RenameList, ctxt: SyntaxContext) -> SyntaxContext } /// Fetch the SCTable from TLS, create one if it doesn't yet exist. -pub fn with_sctable<T>(op: |&SCTable| -> T) -> T { +pub fn with_sctable<T, F>(op: F) -> T where + F: FnOnce(&SCTable) -> T, +{ thread_local!(static SCTABLE_KEY: SCTable = new_sctable_internal()) - SCTABLE_KEY.with(|slot| op(slot)) + SCTABLE_KEY.with(move |slot| op(slot)) } // Make a fresh syntax context table with EmptyCtxt in slot zero @@ -167,12 +169,14 @@ type ResolveTable = HashMap<(Name,SyntaxContext),Name>; // okay, I admit, putting this in TLS is not so nice: // fetch the SCTable from TLS, create one if it doesn't yet exist. -fn with_resolve_table_mut<T>(op: |&mut ResolveTable| -> T) -> T { +fn with_resolve_table_mut<T, F>(op: F) -> T where + F: FnOnce(&mut ResolveTable) -> T, +{ thread_local!(static RESOLVE_TABLE_KEY: RefCell<ResolveTable> = { RefCell::new(HashMap::new()) }) - RESOLVE_TABLE_KEY.with(|slot| op(&mut *slot.borrow_mut())) + RESOLVE_TABLE_KEY.with(move |slot| op(&mut *slot.borrow_mut())) } /// Resolve a syntax object to a name, per MTWT. diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs index 69e311c57f5..0318dd5b0cd 100644 --- a/src/libsyntax/fold.rs +++ b/src/libsyntax/fold.rs @@ -32,11 +32,11 @@ use std::rc::Rc; // This could have a better place to live. pub trait MoveMap<T> { - fn move_map(self, f: |T| -> T) -> Self; + fn move_map<F>(self, f: F) -> Self where F: FnMut(T) -> T; } impl<T> MoveMap<T> for Vec<T> { - fn move_map(mut self, f: |T| -> T) -> Vec<T> { + fn move_map<F>(mut self, mut f: F) -> Vec<T> where F: FnMut(T) -> T { for p in self.iter_mut() { unsafe { // FIXME(#5016) this shouldn't need to zero to be safe. @@ -48,7 +48,7 @@ impl<T> MoveMap<T> for Vec<T> { } impl<T> MoveMap<T> for OwnedSlice<T> { - fn move_map(self, f: |T| -> T) -> OwnedSlice<T> { + fn move_map<F>(self, f: F) -> OwnedSlice<T> where F: FnMut(T) -> T { OwnedSlice::from_vec(self.into_vec().move_map(f)) } } diff --git a/src/libsyntax/lib.rs b/src/libsyntax/lib.rs index ea305642f66..5d5b56d444f 100644 --- a/src/libsyntax/lib.rs +++ b/src/libsyntax/lib.rs @@ -25,6 +25,7 @@ #![allow(unknown_features)] #![feature(macro_rules, globs, default_type_params, phase, slicing_syntax)] #![feature(quote, unsafe_destructor, import_shadowing)] +#![feature(unboxed_closures)] extern crate arena; extern crate fmt_macros; diff --git a/src/libsyntax/owned_slice.rs b/src/libsyntax/owned_slice.rs index 43b428b5a1c..8e418e46921 100644 --- a/src/libsyntax/owned_slice.rs +++ b/src/libsyntax/owned_slice.rs @@ -49,7 +49,7 @@ impl<T> OwnedSlice<T> { self.into_vec().into_iter() } - pub fn map<U>(&self, f: |&T| -> U) -> OwnedSlice<U> { + pub fn map<U, F: FnMut(&T) -> U>(&self, f: F) -> OwnedSlice<U> { self.iter().map(f).collect() } } diff --git a/src/libsyntax/parse/lexer/mod.rs b/src/libsyntax/parse/lexer/mod.rs index 4c15fae9feb..50c7258fe1c 100644 --- a/src/libsyntax/parse/lexer/mod.rs +++ b/src/libsyntax/parse/lexer/mod.rs @@ -244,7 +244,9 @@ impl<'a> StringReader<'a> { /// Calls `f` with a string slice of the source text spanning from `start` /// up to but excluding `self.last_pos`, meaning the slice does not include /// the character `self.curr`. - pub fn with_str_from<T>(&self, start: BytePos, f: |s: &str| -> T) -> T { + pub fn with_str_from<T, F>(&self, start: BytePos, f: F) -> T where + F: FnOnce(&str) -> T, + { self.with_str_from_to(start, self.last_pos, f) } @@ -264,7 +266,9 @@ impl<'a> StringReader<'a> { /// Calls `f` with a string slice of the source text spanning from `start` /// up to but excluding `end`. - fn with_str_from_to<T>(&self, start: BytePos, end: BytePos, f: |s: &str| -> T) -> T { + fn with_str_from_to<T, F>(&self, start: BytePos, end: BytePos, f: F) -> T where + F: FnOnce(&str) -> T, + { f(self.filemap.src.slice( self.byte_offset(start).to_uint(), self.byte_offset(end).to_uint())) diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 92c7380a61d..8c44f9fdf26 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -718,11 +718,12 @@ impl<'a> Parser<'a> { } /// Parse a sequence bracketed by `|` and `|`, stopping before the `|`. - fn parse_seq_to_before_or<T>( - &mut self, - sep: &token::Token, - f: |&mut Parser| -> T) - -> Vec<T> { + fn parse_seq_to_before_or<T, F>(&mut self, + sep: &token::Token, + mut f: F) + -> Vec<T> where + F: FnMut(&mut Parser) -> T, + { let mut first = true; let mut vector = Vec::new(); while self.token != token::BinOp(token::Or) && @@ -769,10 +770,12 @@ impl<'a> Parser<'a> { } } - pub fn parse_seq_to_before_gt_or_return<T>(&mut self, - sep: Option<token::Token>, - f: |&mut Parser| -> Option<T>) - -> (OwnedSlice<T>, bool) { + pub fn parse_seq_to_before_gt_or_return<T, F>(&mut self, + sep: Option<token::Token>, + mut f: F) + -> (OwnedSlice<T>, bool) where + F: FnMut(&mut Parser) -> Option<T>, + { let mut v = Vec::new(); // This loop works by alternating back and forth between parsing types // and commas. For example, given a string `A, B,>`, the parser would @@ -802,28 +805,34 @@ impl<'a> Parser<'a> { /// Parse a sequence bracketed by '<' and '>', stopping /// before the '>'. - pub fn parse_seq_to_before_gt<T>(&mut self, - sep: Option<token::Token>, - f: |&mut Parser| -> T) - -> OwnedSlice<T> { + pub fn parse_seq_to_before_gt<T, F>(&mut self, + sep: Option<token::Token>, + mut f: F) + -> OwnedSlice<T> where + F: FnMut(&mut Parser) -> T, + { let (result, returned) = self.parse_seq_to_before_gt_or_return(sep, |p| Some(f(p))); assert!(!returned); return result; } - pub fn parse_seq_to_gt<T>(&mut self, - sep: Option<token::Token>, - f: |&mut Parser| -> T) - -> OwnedSlice<T> { + pub fn parse_seq_to_gt<T, F>(&mut self, + sep: Option<token::Token>, + f: F) + -> OwnedSlice<T> where + F: FnMut(&mut Parser) -> T, + { let v = self.parse_seq_to_before_gt(sep, f); self.expect_gt(); return v; } - pub fn parse_seq_to_gt_or_return<T>(&mut self, - sep: Option<token::Token>, - f: |&mut Parser| -> Option<T>) - -> (OwnedSlice<T>, bool) { + pub fn parse_seq_to_gt_or_return<T, F>(&mut self, + sep: Option<token::Token>, + f: F) + -> (OwnedSlice<T>, bool) where + F: FnMut(&mut Parser) -> Option<T>, + { let (v, returned) = self.parse_seq_to_before_gt_or_return(sep, f); if !returned { self.expect_gt(); @@ -834,12 +843,13 @@ impl<'a> Parser<'a> { /// Parse a sequence, including the closing delimiter. The function /// f must consume tokens until reaching the next separator or /// closing bracket. - pub fn parse_seq_to_end<T>( - &mut self, - ket: &token::Token, - sep: SeqSep, - f: |&mut Parser| -> T) - -> Vec<T> { + pub fn parse_seq_to_end<T, F>(&mut self, + ket: &token::Token, + sep: SeqSep, + f: F) + -> Vec<T> where + F: FnMut(&mut Parser) -> T, + { let val = self.parse_seq_to_before_end(ket, sep, f); self.bump(); val @@ -848,12 +858,13 @@ impl<'a> Parser<'a> { /// Parse a sequence, not including the closing delimiter. The function /// f must consume tokens until reaching the next separator or /// closing bracket. - pub fn parse_seq_to_before_end<T>( - &mut self, - ket: &token::Token, - sep: SeqSep, - f: |&mut Parser| -> T) - -> Vec<T> { + pub fn parse_seq_to_before_end<T, F>(&mut self, + ket: &token::Token, + sep: SeqSep, + mut f: F) + -> Vec<T> where + F: FnMut(&mut Parser) -> T, + { let mut first: bool = true; let mut v = vec!(); while self.token != *ket { @@ -873,13 +884,14 @@ impl<'a> Parser<'a> { /// Parse a sequence, including the closing delimiter. The function /// f must consume tokens until reaching the next separator or /// closing bracket. - pub fn parse_unspanned_seq<T>( - &mut self, - bra: &token::Token, - ket: &token::Token, - sep: SeqSep, - f: |&mut Parser| -> T) - -> Vec<T> { + pub fn parse_unspanned_seq<T, F>(&mut self, + bra: &token::Token, + ket: &token::Token, + sep: SeqSep, + f: F) + -> Vec<T> where + F: FnMut(&mut Parser) -> T, + { self.expect(bra); let result = self.parse_seq_to_before_end(ket, sep, f); self.bump(); @@ -888,13 +900,14 @@ impl<'a> Parser<'a> { /// Parse a sequence parameter of enum variant. For consistency purposes, /// these should not be empty. - pub fn parse_enum_variant_seq<T>( - &mut self, - bra: &token::Token, - ket: &token::Token, - sep: SeqSep, - f: |&mut Parser| -> T) - -> Vec<T> { + pub fn parse_enum_variant_seq<T, F>(&mut self, + bra: &token::Token, + ket: &token::Token, + sep: SeqSep, + f: F) + -> Vec<T> where + F: FnMut(&mut Parser) -> T, + { let result = self.parse_unspanned_seq(bra, ket, sep, f); if result.is_empty() { let last_span = self.last_span; @@ -906,13 +919,14 @@ impl<'a> Parser<'a> { // NB: Do not use this function unless you actually plan to place the // spanned list in the AST. - pub fn parse_seq<T>( - &mut self, - bra: &token::Token, - ket: &token::Token, - sep: SeqSep, - f: |&mut Parser| -> T) - -> Spanned<Vec<T> > { + pub fn parse_seq<T, F>(&mut self, + bra: &token::Token, + ket: &token::Token, + sep: SeqSep, + f: F) + -> Spanned<Vec<T>> where + F: FnMut(&mut Parser) -> T, + { let lo = self.span.lo; self.expect(bra); let result = self.parse_seq_to_before_end(ket, sep, f); @@ -972,8 +986,9 @@ impl<'a> Parser<'a> { } return (4 - self.buffer_start) + self.buffer_end; } - pub fn look_ahead<R>(&mut self, distance: uint, f: |&token::Token| -> R) - -> R { + pub fn look_ahead<R, F>(&mut self, distance: uint, f: F) -> R where + F: FnOnce(&token::Token) -> R, + { let dist = distance as int; while self.buffer_length() < dist { self.buffer[self.buffer_end as uint] = self.reader.real_token(); @@ -4285,8 +4300,9 @@ impl<'a> Parser<'a> { /// Parse the argument list and result type of a function /// that may have a self type. - fn parse_fn_decl_with_self(&mut self, parse_arg_fn: |&mut Parser| -> Arg) - -> (ExplicitSelf, P<FnDecl>) { + fn parse_fn_decl_with_self<F>(&mut self, parse_arg_fn: F) -> (ExplicitSelf, P<FnDecl>) where + F: FnMut(&mut Parser) -> Arg, + { fn maybe_parse_borrowed_explicit_self(this: &mut Parser) -> ast::ExplicitSelf_ { // The following things are possible to see here: diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index 26373d00aaf..6d8b8dcb8ba 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -165,7 +165,9 @@ impl<'a> State<'a> { } } -pub fn to_string(f: |&mut State| -> IoResult<()>) -> String { +pub fn to_string<F>(f: F) -> String where + F: FnOnce(&mut State) -> IoResult<()>, +{ use std::raw::TraitObject; let mut s = rust_printer(box Vec::new()); f(&mut s).unwrap(); @@ -426,8 +428,10 @@ pub mod with_hygiene { // This function is the trick that all the rest of the routines // hang on. - pub fn to_string_hyg(f: |&mut super::State| -> IoResult<()>) -> String { - super::to_string(|s| { + pub fn to_string_hyg<F>(f: F) -> String where + F: FnOnce(&mut super::State) -> IoResult<()>, + { + super::to_string(move |s| { s.encode_idents_with_hygiene = true; f(s) }) @@ -580,9 +584,9 @@ impl<'a> State<'a> { word(&mut self.s, "*/") } - pub fn commasep<T>(&mut self, b: Breaks, elts: &[T], - op: |&mut State, &T| -> IoResult<()>) - -> IoResult<()> { + pub fn commasep<T, F>(&mut self, b: Breaks, elts: &[T], mut op: F) -> IoResult<()> where + F: FnMut(&mut State, &T) -> IoResult<()>, + { try!(self.rbox(0u, b)); let mut first = true; for elt in elts.iter() { @@ -593,12 +597,14 @@ impl<'a> State<'a> { } - pub fn commasep_cmnt<T>( - &mut self, - b: Breaks, - elts: &[T], - op: |&mut State, &T| -> IoResult<()>, - get_span: |&T| -> codemap::Span) -> IoResult<()> { + pub fn commasep_cmnt<T, F, G>(&mut self, + b: Breaks, + elts: &[T], + mut op: F, + mut get_span: G) -> IoResult<()> where + F: FnMut(&mut State, &T) -> IoResult<()>, + G: FnMut(&T) -> codemap::Span, + { try!(self.rbox(0u, b)); let len = elts.len(); let mut i = 0u; diff --git a/src/libsyntax/ptr.rs b/src/libsyntax/ptr.rs index 1b231ed861b..1b3ebde2461 100644 --- a/src/libsyntax/ptr.rs +++ b/src/libsyntax/ptr.rs @@ -56,12 +56,16 @@ pub fn P<T: 'static>(value: T) -> P<T> { impl<T: 'static> P<T> { /// Move out of the pointer. /// Intended for chaining transformations not covered by `map`. - pub fn and_then<U>(self, f: |T| -> U) -> U { + pub fn and_then<U, F>(self, f: F) -> U where + F: FnOnce(T) -> U, + { f(*self.ptr) } /// Transform the inner value, consuming `self` and producing a new `P<T>`. - pub fn map(mut self, f: |T| -> T) -> P<T> { + pub fn map<F>(mut self, f: F) -> P<T> where + F: FnOnce(T) -> T, + { unsafe { let p = &mut *self.ptr; // FIXME(#5016) this shouldn't need to zero to be safe. diff --git a/src/libsyntax/util/parser_testing.rs b/src/libsyntax/util/parser_testing.rs index c1ea8f60b82..83bbff8473d 100644 --- a/src/libsyntax/util/parser_testing.rs +++ b/src/libsyntax/util/parser_testing.rs @@ -31,7 +31,9 @@ pub fn string_to_parser<'a>(ps: &'a ParseSess, source_str: String) -> Parser<'a> source_str) } -fn with_error_checking_parse<T>(s: String, f: |&mut Parser| -> T) -> T { +fn with_error_checking_parse<T, F>(s: String, f: F) -> T where + F: FnOnce(&mut Parser) -> T, +{ let ps = new_parse_sess(); let mut p = string_to_parser(&ps, s); let x = f(&mut p); diff --git a/src/libsyntax/util/small_vector.rs b/src/libsyntax/util/small_vector.rs index d56e4f70449..8d050e34abf 100644 --- a/src/libsyntax/util/small_vector.rs +++ b/src/libsyntax/util/small_vector.rs @@ -171,7 +171,7 @@ impl<T> Iterator<T> for MoveItems<T> { } impl<T> MoveMap<T> for SmallVector<T> { - fn move_map(self, f: |T| -> T) -> SmallVector<T> { + fn move_map<F>(self, mut f: F) -> SmallVector<T> where F: FnMut(T) -> T { let repr = match self.repr { Zero => Zero, One(v) => One(f(v)), diff --git a/src/libtest/lib.rs b/src/libtest/lib.rs index ffc26738dd7..7436a8af307 100644 --- a/src/libtest/lib.rs +++ b/src/libtest/lib.rs @@ -32,6 +32,7 @@ html_root_url = "http://doc.rust-lang.org/nightly/")] #![feature(asm, macro_rules, phase, globs, slicing_syntax)] +#![feature(unboxed_closures)] extern crate getopts; extern crate regex; @@ -978,9 +979,11 @@ enum TestEvent { pub type MonitorMsg = (TestDesc, TestResult, Vec<u8> ); -fn run_tests(opts: &TestOpts, - tests: Vec<TestDescAndFn> , - callback: |e: TestEvent| -> io::IoResult<()>) -> io::IoResult<()> { +fn run_tests<F>(opts: &TestOpts, + tests: Vec<TestDescAndFn> , + mut callback: F) -> io::IoResult<()> where + F: FnMut(TestEvent) -> io::IoResult<()>, +{ let filtered_tests = filter_tests(opts, tests); let filtered_descs = filtered_tests.iter() .map(|t| t.desc.clone()) @@ -1339,7 +1342,7 @@ pub fn black_box<T>(dummy: T) { impl Bencher { /// Callback for benchmark functions to run in their body. - pub fn iter<T>(&mut self, inner: || -> T) { + pub fn iter<T, F>(&mut self, mut inner: F) where F: FnMut() -> T { self.dur = Duration::span(|| { let k = self.iterations; for _ in range(0u64, k) { @@ -1360,14 +1363,13 @@ impl Bencher { } } - pub fn bench_n(&mut self, n: u64, f: |&mut Bencher|) { + pub fn bench_n<F>(&mut self, n: u64, f: F) where F: FnOnce(&mut Bencher) { self.iterations = n; f(self); } // This is a more statistics-driven benchmark algorithm - pub fn auto_bench(&mut self, f: |&mut Bencher|) -> stats::Summary<f64> { - + pub fn auto_bench<F>(&mut self, mut f: F) -> stats::Summary<f64> where F: FnMut(&mut Bencher) { // Initial bench run to get ballpark figure. let mut n = 1_u64; self.bench_n(n, |x| f(x)); @@ -1437,7 +1439,7 @@ pub mod bench { use std::time::Duration; use super::{Bencher, BenchSamples}; - pub fn benchmark(f: |&mut Bencher|) -> BenchSamples { + pub fn benchmark<F>(f: F) -> BenchSamples where F: FnMut(&mut Bencher) { let mut bs = Bencher { iterations: 0, dur: Duration::nanoseconds(0), diff --git a/src/libunicode/lib.rs b/src/libunicode/lib.rs index 66cd22dfb08..1f75daa7bde 100644 --- a/src/libunicode/lib.rs +++ b/src/libunicode/lib.rs @@ -29,6 +29,7 @@ html_playground_url = "http://play.rust-lang.org/")] #![no_std] #![feature(globs)] +#![feature(unboxed_closures)] extern crate core; diff --git a/src/libunicode/u_str.rs b/src/libunicode/u_str.rs index f3aaad549c9..80311137b01 100644 --- a/src/libunicode/u_str.rs +++ b/src/libunicode/u_str.rs @@ -29,8 +29,7 @@ use tables::grapheme::GraphemeCat; /// An iterator over the words of a string, separated by a sequence of whitespace /// FIXME: This should be opaque -pub type Words<'a> = - Filter<'a, &'a str, CharSplits<'a, |char|:'a -> bool>>; +pub type Words<'a> = Filter<&'a str, CharSplits<'a, fn(char) -> bool>, fn(&&str) -> bool>; /// Methods for Unicode string slices pub trait UnicodeStrPrelude for Sized? { @@ -143,8 +142,10 @@ impl UnicodeStrPrelude for str { #[inline] fn words(&self) -> Words { - let f = |c: char| c.is_whitespace(); - self.split(f).filter(|s| !s.is_empty()) + fn is_not_empty(s: &&str) -> bool { !s.is_empty() } + fn is_whitespace(c: char) -> bool { c.is_whitespace() } + + self.split(is_whitespace).filter(is_not_empty) } #[inline] @@ -165,12 +166,12 @@ impl UnicodeStrPrelude for str { #[inline] fn trim_left(&self) -> &str { - self.trim_left_chars(|c: char| c.is_whitespace()) + self.trim_left_chars(|&: c: char| c.is_whitespace()) } #[inline] fn trim_right(&self) -> &str { - self.trim_right_chars(|c: char| c.is_whitespace()) + self.trim_right_chars(|&: c: char| c.is_whitespace()) } } diff --git a/src/test/bench/core-map.rs b/src/test/bench/core-map.rs index bbbd878e8b8..112d4fd0912 100644 --- a/src/test/bench/core-map.rs +++ b/src/test/bench/core-map.rs @@ -8,13 +8,15 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +#![feature(unboxed_closures)] + use std::collections::{TrieMap, TreeMap, HashMap, HashSet}; use std::os; use std::rand::{Rng, IsaacRng, SeedableRng}; use std::time::Duration; use std::uint; -fn timed(label: &str, f: ||) { +fn timed<F>(label: &str, f: F) where F: FnMut() { println!(" {}: {}", label, Duration::span(f)); } diff --git a/src/test/bench/core-set.rs b/src/test/bench/core-set.rs index 07300b73c85..6ba642cc47b 100644 --- a/src/test/bench/core-set.rs +++ b/src/test/bench/core-set.rs @@ -10,6 +10,8 @@ // ignore-pretty very bad with line comments +#![feature(unboxed_closures)] + extern crate collections; extern crate rand; @@ -31,7 +33,7 @@ struct Results { delete_strings: Duration, } -fn timed(result: &mut Duration, op: ||) { +fn timed<F>(result: &mut Duration, op: F) where F: FnOnce() { *result = Duration::span(op); } diff --git a/src/test/bench/core-std.rs b/src/test/bench/core-std.rs index 24bd26b0288..6e2cd508291 100644 --- a/src/test/bench/core-std.rs +++ b/src/test/bench/core-std.rs @@ -12,6 +12,7 @@ // Microbenchmarks for various functions in std and extra #![feature(macro_rules)] +#![feature(unboxed_closures)] use std::io::File; use std::mem::swap; @@ -41,7 +42,7 @@ fn main() { bench!(is_utf8_multibyte); } -fn maybe_run_test(argv: &[String], name: String, test: ||) { +fn maybe_run_test<F>(argv: &[String], name: String, test: F) where F: FnOnce() { let mut run_test = false; if os::getenv("RUST_BENCH").is_some() { diff --git a/src/test/compile-fail/coerce-unsafe-to-closure.rs b/src/test/compile-fail/coerce-unsafe-to-closure.rs index d9fbc08b321..fe7635f065c 100644 --- a/src/test/compile-fail/coerce-unsafe-to-closure.rs +++ b/src/test/compile-fail/coerce-unsafe-to-closure.rs @@ -10,5 +10,5 @@ fn main() { let x: Option<&[u8]> = Some("foo").map(std::mem::transmute); - //~^ ERROR: mismatched types + //~^ ERROR: is not implemented for the type } diff --git a/src/test/run-pass/assignability-trait.rs b/src/test/run-pass/assignability-trait.rs index f822da4cdcf..f623b7911ce 100644 --- a/src/test/run-pass/assignability-trait.rs +++ b/src/test/run-pass/assignability-trait.rs @@ -12,19 +12,20 @@ // making method calls, but only if there aren't any matches without // it. +#![feature(unboxed_closures)] trait iterable<A> { - fn iterate(&self, blk: |x: &A| -> bool) -> bool; + fn iterate<F>(&self, blk: F) -> bool where F: FnMut(&A) -> bool; } impl<'a,A> iterable<A> for &'a [A] { - fn iterate(&self, f: |x: &A| -> bool) -> bool { + fn iterate<F>(&self, f: F) -> bool where F: FnMut(&A) -> bool { self.iter().all(f) } } impl<A> iterable<A> for Vec<A> { - fn iterate(&self, f: |x: &A| -> bool) -> bool { + fn iterate<F>(&self, f: F) -> bool where F: FnMut(&A) -> bool { self.iter().all(f) } } diff --git a/src/test/run-pass/backtrace.rs b/src/test/run-pass/backtrace.rs index a267b8dcc86..da5fa19f816 100644 --- a/src/test/run-pass/backtrace.rs +++ b/src/test/run-pass/backtrace.rs @@ -10,6 +10,9 @@ // no-pretty-expanded FIXME #15189 // ignore-windows FIXME #13259 + +#![feature(unboxed_closures)] + use std::os; use std::io::process::Command; use std::finally::Finally; @@ -25,7 +28,7 @@ fn foo() { #[inline(never)] fn double() { - (|| { + (|&mut:| { panic!("once"); }).finally(|| { panic!("twice"); |
