diff --git a/src/libarena/lib.rs b/src/libarena/lib.rs index 95c4dff323ef0..1f4df1fd0a5a2 100644 --- a/src/libarena/lib.rs +++ b/src/libarena/lib.rs @@ -28,6 +28,7 @@ html_root_url = "http://doc.rust-lang.org/nightly/")] #![feature(unsafe_destructor)] +#![feature(unboxed_closures)] #![allow(missing_docs)] extern crate alloc; @@ -209,7 +210,7 @@ impl Arena { } #[inline] - fn alloc_copy(&self, op: || -> T) -> &mut T { + fn alloc_copy(&self, op: F) -> &mut T where F: FnOnce() -> T { unsafe { let ptr = self.alloc_copy_inner(mem::size_of::(), mem::min_align_of::()); @@ -263,7 +264,7 @@ impl Arena { } #[inline] - fn alloc_noncopy(&self, op: || -> T) -> &mut T { + fn alloc_noncopy(&self, op: F) -> &mut T where F: FnOnce() -> T { unsafe { let tydesc = get_tydesc::(); 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(&self, op: || -> T) -> &mut T { + pub fn alloc(&self, op: F) -> &mut T where F: FnOnce() -> T { unsafe { if intrinsics::needs_drop::() { self.alloc_noncopy(op) @@ -339,7 +340,7 @@ fn test_arena_destructors_fail() { arena.alloc(|| { [0u8, 1u8, 2u8] }); } // Now, panic while allocating - arena.alloc::>(|| { + arena.alloc::, _>(|| { panic!(); }); } diff --git a/src/libcollections/bench.rs b/src/libcollections/bench.rs index a212f22f89929..3346e55158a2a 100644 --- a/src/libcollections/bench.rs +++ b/src/libcollections/bench.rs @@ -13,9 +13,14 @@ use std::rand; use std::rand::Rng; use test::Bencher; -pub fn insert_rand_n(n: uint, map: &mut M, b: &mut Bencher, - insert: |&mut M, uint|, - remove: |&mut M, uint|) { +pub fn insert_rand_n(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(n: uint, map: &mut M, b: &mut Bencher, }) } -pub fn insert_seq_n(n: uint, map: &mut M, b: &mut Bencher, - insert: |&mut M, uint|, - remove: |&mut M, uint|) { +pub fn insert_seq_n(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(n: uint, map: &mut M, b: &mut Bencher, }) } -pub fn find_rand_n(n: uint, map: &mut M, b: &mut Bencher, - insert: |&mut M, uint|, - find: |&M, uint| -> T) { +pub fn find_rand_n(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::() % n); @@ -70,9 +85,14 @@ pub fn find_rand_n(n: uint, map: &mut M, b: &mut Bencher, }) } -pub fn find_seq_n(n: uint, map: &mut M, b: &mut Bencher, - insert: |&mut M, uint|, - find: |&M, uint| -> T) { +pub fn find_seq_n(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 b401978c9c9cd..a0c4f6e7ee8c7 100644 --- a/src/libcollections/bit.rs +++ b/src/libcollections/bit.rs @@ -174,7 +174,7 @@ impl<'a> Iterator<(uint, u32)> for MaskWords<'a> { impl Bitv { #[inline] - fn process(&mut self, other: &Bitv, op: |u32, u32| -> u32) -> bool { + fn process(&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(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(&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> { + 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 3d5067d5a516b..e49a8ddbe5ab8 100644 --- a/src/libcollections/btree/map.rs +++ b/src/libcollections/btree/map.rs @@ -107,10 +107,12 @@ pub struct MoveEntries { } /// 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 BTreeMap { /// ``` #[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, _): (A, B)) -> A { a } + + self.iter().map(first) } /// Gets an iterator over the values of the map. @@ -1226,7 +1230,9 @@ impl BTreeMap { /// ``` #[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((_, b): (A, B)) -> B { b } + + self.iter().map(second) } /// Return the number of elements in the map. diff --git a/src/libcollections/btree/set.rs b/src/libcollections/btree/set.rs index 0fbc319f4ff64..cd01c008fe1bc 100644 --- a/src/libcollections/btree/set.rs +++ b/src/libcollections/btree/set.rs @@ -36,7 +36,8 @@ pub struct BTreeSet{ pub type Items<'a, T> = Keys<'a, T, ()>; /// An owning iterator over a BTreeSet's items. -pub type MoveItems = iter::Map<'static, (T, ()), T, MoveEntries>; +pub type MoveItems = + iter::Map<(T, ()), T, MoveEntries, 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 BTreeSet { /// 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 { - self.map.into_iter().map(|(k, _)| k) + fn first((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, &BTreeSet, 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(a: &[int], b: &[int], expected: &[int], f: F) where + // FIXME Replace Counter with `Box _>` + F: FnOnce(&BTreeSet, &BTreeSet, 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 d50b212c7dd9a..f49a0c037de84 100644 --- a/src/libcollections/dlist.rs +++ b/src/libcollections/dlist.rs @@ -351,18 +351,16 @@ impl DList { /// 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(&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 DList { /// 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, f: |&T, &T| -> bool) { + pub fn merge(&mut self, mut other: DList, 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 6bdfa490748fa..463e28b420d15 100644 --- a/src/libcollections/slice.rs +++ b/src/libcollections/slice.rs @@ -94,6 +94,7 @@ use core::cmp; use core::kinds::{Copy, Sized}; use core::mem::size_of; use core::mem; +use core::ops::FnMut; use core::prelude::{Clone, Greater, Iterator, IteratorExt, Less, None, Option}; use core::prelude::{Ord, Ordering, RawPtr, Some, range}; use core::ptr; @@ -296,7 +297,7 @@ pub trait CloneSliceAllocPrelude 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, Vec); + fn partitioned(&self, f: F) -> (Vec, Vec) where F: FnMut(&T) -> bool; /// Creates an iterator that yields every possible permutation of the /// vector in succession. @@ -336,7 +337,7 @@ impl CloneSliceAllocPrelude for [T] { #[inline] - fn partitioned(&self, f: |&T| -> bool) -> (Vec, Vec) { + fn partitioned(&self, mut f: F) -> (Vec, Vec) where F: FnMut(&T) -> bool { let mut lefts = Vec::new(); let mut rights = Vec::new(); @@ -361,7 +362,7 @@ impl CloneSliceAllocPrelude for [T] { } -fn insertion_sort(v: &mut [T], compare: |&T, &T| -> Ordering) { +fn insertion_sort(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(v: &mut [T], compare: |&T, &T| -> Ordering) { } } -fn merge_sort(v: &mut [T], compare: |&T, &T| -> Ordering) { +fn merge_sort(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 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(&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 for Sized? { impl SliceAllocPrelude for [T] { #[inline] - fn sort_by(&mut self, compare: |&T, &T| -> Ordering) { + fn sort_by(&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 2e96b941c08e0..bf568fd92d565 100644 --- a/src/libcollections/str.rs +++ b/src/libcollections/str.rs @@ -903,21 +903,21 @@ mod tests { #[test] fn test_find() { assert_eq!("hello".find('l'), Some(2u)); - assert_eq!("hello".find(|c:char| c == 'o'), Some(4u)); + assert_eq!("hello".find(|&: c:char| c == 'o'), Some(4u)); assert!("hello".find('x').is_none()); - assert!("hello".find(|c:char| c == 'x').is_none()); + assert!("hello".find(|&: c:char| c == 'x').is_none()); assert_eq!("ประเทศไทย中华Việt Nam".find('华'), Some(30u)); - assert_eq!("ประเทศไทย中华Việt Nam".find(|c: char| c == '华'), Some(30u)); + assert_eq!("ประเทศไทย中华Việt Nam".find(|&: c: char| c == '华'), Some(30u)); } #[test] fn test_rfind() { assert_eq!("hello".rfind('l'), Some(3u)); - assert_eq!("hello".rfind(|c:char| c == 'o'), Some(4u)); + assert_eq!("hello".rfind(|&: c:char| c == 'o'), Some(4u)); assert!("hello".rfind('x').is_none()); - assert!("hello".rfind(|c:char| c == 'x').is_none()); + assert!("hello".rfind(|&: c:char| c == 'x').is_none()); assert_eq!("ประเทศไทย中华Việt Nam".rfind('华'), Some(30u)); - assert_eq!("ประเทศไทย中华Việt Nam".rfind(|c: char| c == '华'), Some(30u)); + assert_eq!("ประเทศไทย中华Việt Nam".rfind(|&: c: char| c == '华'), Some(30u)); } #[test] @@ -1281,7 +1281,7 @@ mod tests { assert_eq!("11foo1bar11".trim_left_chars('1'), "foo1bar11"); let chars: &[char] = &['1', '2']; assert_eq!("12foo1bar12".trim_left_chars(chars), "foo1bar12"); - assert_eq!("123foo1bar123".trim_left_chars(|c: char| c.is_numeric()), "foo1bar123"); + assert_eq!("123foo1bar123".trim_left_chars(|&: c: char| c.is_numeric()), "foo1bar123"); } #[test] @@ -1296,7 +1296,7 @@ mod tests { assert_eq!("11foo1bar11".trim_right_chars('1'), "11foo1bar"); let chars: &[char] = &['1', '2']; assert_eq!("12foo1bar12".trim_right_chars(chars), "12foo1bar"); - assert_eq!("123foo1bar123".trim_right_chars(|c: char| c.is_numeric()), "123foo1bar"); + assert_eq!("123foo1bar123".trim_right_chars(|&: c: char| c.is_numeric()), "123foo1bar"); } #[test] @@ -1311,7 +1311,7 @@ mod tests { assert_eq!("11foo1bar11".trim_chars('1'), "foo1bar"); let chars: &[char] = &['1', '2']; assert_eq!("12foo1bar12".trim_chars(chars), "foo1bar"); - assert_eq!("123foo1bar123".trim_chars(|c: char| c.is_numeric()), "foo1bar"); + assert_eq!("123foo1bar123".trim_chars(|&: c: char| c.is_numeric()), "foo1bar"); } #[test] @@ -1787,14 +1787,14 @@ mod tests { let split: Vec<&str> = data.splitn(3, ' ').collect(); assert_eq!(split, vec!["\nMäry", "häd", "ä", "little lämb\nLittle lämb\n"]); - let split: Vec<&str> = data.splitn(3, |c: char| c == ' ').collect(); + let split: Vec<&str> = data.splitn(3, |&: c: char| c == ' ').collect(); assert_eq!(split, vec!["\nMäry", "häd", "ä", "little lämb\nLittle lämb\n"]); // Unicode let split: Vec<&str> = data.splitn(3, 'ä').collect(); assert_eq!(split, vec!["\nM", "ry h", "d ", " little lämb\nLittle lämb\n"]); - let split: Vec<&str> = data.splitn(3, |c: char| c == 'ä').collect(); + let split: Vec<&str> = data.splitn(3, |&: c: char| c == 'ä').collect(); assert_eq!(split, vec!["\nM", "ry h", "d ", " little lämb\nLittle lämb\n"]); } @@ -2588,7 +2588,7 @@ mod bench { let s = "Mary had a little lamb, Little lamb, little-lamb."; let len = s.split(' ').count(); - b.iter(|| assert_eq!(s.split(|c: char| c == ' ').count(), len)); + b.iter(|| assert_eq!(s.split(|&: c: char| c == ' ').count(), len)); } #[bench] diff --git a/src/libcollections/tree/map.rs b/src/libcollections/tree/map.rs index 24395ca64939c..5c2cf4a81808d 100644 --- a/src/libcollections/tree/map.rs +++ b/src/libcollections/tree/map.rs @@ -234,7 +234,9 @@ impl TreeMap { /// ``` #[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, _): (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 TreeMap { /// ``` #[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((_, 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 TreeMap { /// ``` #[inline] #[experimental = "likely to be renamed, may be removed"] - pub fn find_with(&self, f:|&K| -> Ordering) -> Option<&V> { + pub fn find_with(&self, f: F) -> Option<&V> where F: FnMut(&K) -> Ordering { tree_find_with(&self.root, f) } @@ -637,7 +641,9 @@ impl TreeMap { /// ``` #[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(node: &mut Box>) { // 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>>, - f: |&K| -> Ordering) -> Option<&'r V> { +fn tree_find_with<'r, K, V, F>( + node: &'r Option>>, + mut f: F, +) -> Option<&'r V> where + F: FnMut(&K) -> Ordering, +{ let mut current: &'r Option>> = node; loop { match *current { @@ -1143,8 +1153,12 @@ fn tree_find_with<'r, K, V>(node: &'r Option>>, } // See comments above tree_find_with -fn tree_find_with_mut<'r, K, V>(node: &'r mut Option>>, - f: |&K| -> Ordering) -> Option<&'r mut V> { +fn tree_find_with_mut<'r, K, V, F>( + node: &'r mut Option>>, + 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 3af2f3e0193a5..bd8bf5c6cb67f 100644 --- a/src/libcollections/tree/set.rs +++ b/src/libcollections/tree/set.rs @@ -205,7 +205,9 @@ impl TreeSet { #[inline] #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn into_iter(self) -> MoveSetItems { - self.map.into_iter().map(|(value, _)| value) + fn first((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 = iter::Map<'static, (T, ()), T, MoveEntries>; +pub type MoveSetItems = iter::Map<(T, ()), T, MoveEntries, 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, &TreeSet, 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(a: &[int], b: &[int], expected: &[int], f: F) where + // FIXME Replace `Counter` with `Box bool>` + F: FnOnce(&TreeSet, &TreeSet, 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 1b087d2e63dd5..a4dee8076487d 100644 --- a/src/libcollections/trie/map.rs +++ b/src/libcollections/trie/map.rs @@ -197,14 +197,18 @@ impl TrieMap { /// 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, _): (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((_, 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 46052ff2f5080..5621726dc5682 100644 --- a/src/libcollections/trie/set.rs +++ b/src/libcollections/trie/set.rs @@ -743,10 +743,23 @@ mod test { assert!(a < b && a <= b); } - fn check(a: &[uint], - b: &[uint], - expected: &[uint], - f: |&TrieSet, &TrieSet, f: |uint| -> bool| -> bool) { + struct Counter<'a, 'b> { + i: &'a mut uint, + expected: &'b [uint], + } + + impl<'a, 'b> FnMut(uint) -> bool for Counter<'a, 'b> { + extern "rust-call" fn call_mut(&mut self, (x,): (uint,)) -> bool { + assert_eq!(x, self.expected[*self.i]); + *self.i += 1; + true + } + } + + fn check(a: &[uint], b: &[uint], expected: &[uint], f: F) where + // FIXME Replace `Counter` with `Box 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 f8a971db173f8..2ed8686394c01 100644 --- a/src/libcollections/vec.rs +++ b/src/libcollections/vec.rs @@ -206,7 +206,7 @@ impl Vec { #[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 { + pub fn from_fn(length: uint, mut op: F) -> Vec where F: FnMut(uint) -> T { unsafe { let mut xs = Vec::with_capacity(length); while xs.len < length { @@ -289,7 +289,7 @@ impl Vec { /// ``` #[inline] #[experimental] - pub fn partition(self, f: |&T| -> bool) -> (Vec, Vec) { + pub fn partition(self, mut f: F) -> (Vec, Vec) where F: FnMut(&T) -> bool { let mut lefts = Vec::new(); let mut rights = Vec::new(); @@ -400,7 +400,7 @@ impl Vec { /// assert_eq!(odd, vec![1i, 3]); /// ``` #[experimental] - pub fn partitioned(&self, f: |&T| -> bool) -> (Vec, Vec) { + pub fn partitioned(&self, mut f: F) -> (Vec, Vec) where F: FnMut(&T) -> bool { let mut lefts = Vec::new(); let mut rights = Vec::new(); @@ -991,7 +991,7 @@ impl Vec { /// 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(&mut self, mut f: F) where F: FnMut(&T) -> bool { let len = self.len(); let mut del = 0u; { @@ -1023,7 +1023,7 @@ impl Vec { /// 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(&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 Vec { /// 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(self, f: |T| -> U) -> Vec { + pub fn map_in_place(self, mut f: F) -> Vec where F: FnMut(T) -> U { // FIXME: Assert statically that the types `T` and `U` have the same // size. assert!(mem::size_of::() == mem::size_of::()); diff --git a/src/libcollections/vec_map.rs b/src/libcollections/vec_map.rs index 3b8c690e04749..cc2fd0a664690 100644 --- a/src/libcollections/vec_map.rs +++ b/src/libcollections/vec_map.rs @@ -20,6 +20,7 @@ use core::fmt; use core::iter; use core::iter::{Enumerate, FilterMap}; use core::mem::replace; +use core::ops::FnOnce; use hash::{Hash, Writer}; use {vec, slice}; @@ -141,14 +142,18 @@ impl VecMap { /// 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, _): (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((_, 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 VecMap { /// ``` #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn into_iter(&mut self) -> MoveItems { - let values = replace(&mut self.v, vec!()); - values.into_iter().enumerate().filter_map(|(i, v)| { + fn filter((i, v): (uint, Option)) -> 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 VecMap { /// 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(&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 VecMap { /// 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(&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 = - FilterMap<'static, (uint, Option), (uint, V), Enumerate>>>; +pub type MoveItems = FilterMap< + (uint, Option), + (uint, V), + Enumerate>>, + fn((uint, Option)) -> Option<(uint, V)>>; #[cfg(test)] mod test_map { diff --git a/src/libcore/char.rs b/src/libcore/char.rs index 671b4ccb9e4f4..75f7991df027b 100644 --- a/src/libcore/char.rs +++ b/src/libcore/char.rs @@ -16,6 +16,7 @@ #![doc(primitive = "char")] use mem::transmute; +use ops::FnMut; use option::Option; use option::Option::{None, Some}; use iter::{range_step, Iterator, RangeStep}; @@ -165,7 +166,7 @@ pub fn from_digit(num: uint, radix: uint) -> Option { /// - 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(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(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 d2b7591b3efa1..2b48b2bf81afb 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 { /// Executes this object, unconditionally running `dtor` after this block of /// code has run. - fn finally(&mut self, dtor: ||) -> T; -} - -impl<'a,T> Finally for ||: 'a -> T { - fn finally(&mut self, dtor: ||) -> T { - try_finally(&mut (), self, - |_, f| (*f)(), - |_| dtor()) - } + fn finally(&mut self, dtor: F) -> T where F: FnMut(); } -impl Finally for fn() -> T { - fn finally(&mut self, dtor: ||) -> T { - try_finally(&mut (), (), - |_, _| (*self)(), - |_| dtor()) +impl Finally for F where F: FnMut() -> T { + fn finally(&mut self, mut dtor: G) -> T where G: FnMut() { + try_finally(&mut (), self, |_, f| (*f)(), |_| dtor()) } } @@ -86,11 +80,10 @@ impl Finally for fn() -> T { /// // use state.buffer, state.len to cleanup /// }) /// ``` -pub fn try_finally(mutate: &mut T, - drop: U, - try_fn: |&mut T, U| -> R, - finally_fn: |&mut T|) - -> R { +pub fn try_finally(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(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 400ce76baa0d2..fb4d91e912a3b 100644 --- a/src/libcore/fmt/float.rs +++ b/src/libcore/fmt/float.rs @@ -20,6 +20,7 @@ use fmt; use iter::{range, DoubleEndedIteratorExt}; use num::{Float, FPNaN, FPInfinite, ToPrimitive}; use num::cast; +use ops::FnOnce; use result::Result::Ok; use slice::{mod, SlicePrelude}; use str::StrPrelude; @@ -84,7 +85,7 @@ static DIGIT_E_RADIX: uint = ('e' as uint) - ('a' as uint) + 11u; /// between digit and exponent sign `'e'`. /// - Panics if `radix` > 25 and `exp_format` is `ExpBin` due to conflict /// between digit and exponent sign `'p'`. -pub fn float_to_str_bytes_common( +pub fn float_to_str_bytes_common( num: T, radix: uint, negative_zero: bool, @@ -92,8 +93,10 @@ pub fn float_to_str_bytes_common( 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 88ea811cfd694..37a1d4d564d84 100644 --- a/src/libcore/fmt/mod.rs +++ b/src/libcore/fmt/mod.rs @@ -19,7 +19,7 @@ use kinds::{Copy, Sized}; use mem; use option::Option; use option::Option::{Some, None}; -use ops::Deref; +use ops::{Deref, FnOnce}; use result::Result::{Ok, Err}; use result; use slice::SlicePrelude; @@ -491,10 +491,9 @@ impl<'a> Formatter<'a> { /// Runs a callback, emitting the correct padding either before or /// afterwards depending on whether right or left alignment is requested. - fn with_padding(&mut self, - padding: uint, - default: rt::Alignment, - f: |&mut Formatter| -> Result) -> Result { + fn with_padding(&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 ddca9d36bed7e..8ee2a8874bb03 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: Iterator { /// ``` #[inline] #[unstable = "waiting for unboxed closures"] - fn map<'r, B>(self, f: |A|: 'r -> B) -> Map<'r, A, B, Self> { + fn map B>(self, f: F) -> Map { Map{iter: self, f: f} } @@ -183,7 +183,7 @@ pub trait IteratorExt: Iterator { /// ``` #[inline] #[unstable = "waiting for unboxed closures"] - fn filter<'r>(self, predicate: |&A|: 'r -> bool) -> Filter<'r, A, Self> { + fn filter

(self, predicate: P) -> Filter where P: FnMut(&A) -> bool { Filter{iter: self, predicate: predicate} } @@ -201,7 +201,7 @@ pub trait IteratorExt: Iterator { /// ``` #[inline] #[unstable = "waiting for unboxed closures"] - fn filter_map<'r, B>(self, f: |A|: 'r -> Option) -> FilterMap<'r, A, B, Self> { + fn filter_map(self, f: F) -> FilterMap where F: FnMut(A) -> Option { FilterMap { iter: self, f: f } } @@ -264,7 +264,7 @@ pub trait IteratorExt: Iterator { /// ``` #[inline] #[unstable = "waiting for unboxed closures"] - fn skip_while<'r>(self, predicate: |&A|: 'r -> bool) -> SkipWhile<'r, A, Self> { + fn skip_while

(self, predicate: P) -> SkipWhile where P: FnMut(&A) -> bool { SkipWhile{iter: self, flag: false, predicate: predicate} } @@ -283,7 +283,7 @@ pub trait IteratorExt: Iterator { /// ``` #[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

(self, predicate: P) -> TakeWhile where P: FnMut(&A) -> bool { TakeWhile{iter: self, flag: false, predicate: predicate} } @@ -346,8 +346,9 @@ pub trait IteratorExt: Iterator { /// ``` #[inline] #[unstable = "waiting for unboxed closures"] - fn scan<'r, St, B>(self, initial_state: St, f: |&mut St, A|: 'r -> Option) - -> Scan<'r, A, B, Self, St> { + fn scan(self, initial_state: St, f: F) -> Scan where + F: FnMut(&mut St, A) -> Option, + { Scan{iter: self, f: f, state: initial_state} } @@ -371,8 +372,10 @@ pub trait IteratorExt: Iterator { /// ``` #[inline] #[unstable = "waiting for unboxed closures"] - fn flat_map<'r, B, U: Iterator>(self, f: |A|: 'r -> U) - -> FlatMap<'r, A, Self, U> { + fn flat_map(self, f: F) -> FlatMap where + U: Iterator, + F: FnMut(A) -> U, + { FlatMap{iter: self, f: f, frontiter: None, backiter: None } } @@ -429,7 +432,7 @@ pub trait IteratorExt: Iterator { /// ``` #[inline] #[unstable = "waiting for unboxed closures"] - fn inspect<'r>(self, f: |&A|: 'r) -> Inspect<'r, A, Self> { + fn inspect(self, f: F) -> Inspect where F: FnMut(&A) { Inspect{iter: self, f: f} } @@ -518,7 +521,7 @@ pub trait IteratorExt: Iterator { /// ``` #[inline] #[unstable = "waiting for unboxed closures, just changed to take self by value"] - fn fold(mut self, init: B, f: |B, A| -> B) -> B { + fn fold(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: Iterator { /// ``` #[inline] #[unstable = "waiting for unboxed closures, just changed to take self by value"] - fn all(mut self, f: |A| -> bool) -> bool { + fn all(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: Iterator { /// ``` #[inline] #[unstable = "waiting for unboxed closures"] - fn any(&mut self, f: |A| -> bool) -> bool { + fn any(&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: Iterator { /// Does not consume the iterator past the first found element. #[inline] #[unstable = "waiting for unboxed closures"] - fn find(&mut self, predicate: |&A| -> bool) -> Option { + fn find

(&mut self, mut predicate: P) -> Option where P: FnMut(&A) -> bool { for x in *self { if predicate(&x) { return Some(x) } } @@ -590,7 +593,7 @@ pub trait IteratorExt: Iterator { /// 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 { + fn position

(&mut self, mut predicate: P) -> Option where P: FnMut(A) -> bool { let mut i = 0; for x in *self { if predicate(x) { @@ -614,7 +617,7 @@ pub trait IteratorExt: Iterator { /// ``` #[inline] #[unstable = "waiting for unboxed closures, just changed to take self by value"] - fn max_by(self, f: |&A| -> B) -> Option { + fn max_by(self, mut f: F) -> Option 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: Iterator { /// ``` #[inline] #[unstable = "waiting for unboxed closures, just changed to take self by value"] - fn min_by(self, f: |&A| -> B) -> Option { + fn min_by(self, mut f: F) -> Option 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 : DoubleEndedIterator { /// /// If no element matches, None is returned. #[inline] - fn rposition(&mut self, predicate: |A| -> bool) -> Option { + fn rposition

(&mut self, mut predicate: P) -> Option 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 : DoubleEndedIterator { #[unstable = "trait is unstable"] impl> ExactSizeIterator<(uint, A)> for Enumerate {} #[unstable = "trait is unstable"] -impl<'a, A, T: ExactSizeIterator> ExactSizeIterator for Inspect<'a, A, T> {} +impl ExactSizeIterator for Inspect where + I: ExactSizeIterator, + F: FnMut(&A), +{} #[unstable = "trait is unstable"] impl> ExactSizeIterator for Rev {} #[unstable = "trait is unstable"] -impl<'a, A, B, T: ExactSizeIterator> ExactSizeIterator for Map<'a, A, B, T> {} +impl ExactSizeIterator for Map where + I: ExactSizeIterator, + F: FnMut(A) -> B, +{} #[unstable = "trait is unstable"] impl ExactSizeIterator<(A, B)> for Zip where T: ExactSizeIterator, U: ExactSizeIterator {} @@ -1374,12 +1383,12 @@ RandomAccessIterator<(A, B)> for Zip { /// 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, F: FnMut(A) -> B> { + iter: I, + f: F, } -impl<'a, A, B, T> Map<'a, A, B, T> { +impl Map where I: Iterator, F: FnMut(A) -> B { #[inline] fn do_map(&mut self, elt: Option) -> Option { 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> Iterator for Map<'a, A, B, T> { +impl Iterator for Map where I: Iterator, F: FnMut(A) -> B { #[inline] fn next(&mut self) -> Option { let next = self.iter.next(); @@ -1404,7 +1413,10 @@ impl<'a, A, B, T: Iterator> Iterator for Map<'a, A, B, T> { } #[unstable = "trait is unstable"] -impl<'a, A, B, T: DoubleEndedIterator> DoubleEndedIterator for Map<'a, A, B, T> { +impl DoubleEndedIterator for Map where + I: DoubleEndedIterator, + F: FnMut(A) -> B, +{ #[inline] fn next_back(&mut self) -> Option { let next = self.iter.next_back(); @@ -1413,7 +1425,10 @@ impl<'a, A, B, T: DoubleEndedIterator> DoubleEndedIterator for Map<'a, A, } #[experimental = "trait is experimental"] -impl<'a, A, B, T: RandomAccessIterator> RandomAccessIterator for Map<'a, A, B, T> { +impl RandomAccessIterator for Map where + I: RandomAccessIterator, + F: FnMut(A) -> B, +{ #[inline] fn indexable(&self) -> uint { self.iter.indexable() @@ -1429,13 +1444,13 @@ impl<'a, A, B, T: RandomAccessIterator> RandomAccessIterator 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 where I: Iterator, P: FnMut(&A) -> bool { + iter: I, + predicate: P, } #[unstable = "trait is unstable"] -impl<'a, A, T: Iterator> Iterator for Filter<'a, A, T> { +impl Iterator for Filter where I: Iterator, P: FnMut(&A) -> bool { #[inline] fn next(&mut self) -> Option { for x in self.iter { @@ -1456,7 +1471,10 @@ impl<'a, A, T: Iterator> Iterator for Filter<'a, A, T> { } #[unstable = "trait is unstable"] -impl<'a, A, T: DoubleEndedIterator> DoubleEndedIterator for Filter<'a, A, T> { +impl DoubleEndedIterator for Filter where + I: DoubleEndedIterator, + P: FnMut(&A) -> bool, +{ #[inline] fn next_back(&mut self) -> Option { for x in self.iter.by_ref().rev() { @@ -1471,13 +1489,16 @@ impl<'a, A, T: DoubleEndedIterator> DoubleEndedIterator 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 +pub struct FilterMap where I: Iterator, F: FnMut(A) -> Option { + iter: I, + f: F, } #[unstable = "trait is unstable"] -impl<'a, A, B, T: Iterator> Iterator for FilterMap<'a, A, B, T> { +impl Iterator for FilterMap where + I: Iterator, + F: FnMut(A) -> Option, +{ #[inline] fn next(&mut self) -> Option { for x in self.iter { @@ -1497,8 +1518,10 @@ impl<'a, A, B, T: Iterator> Iterator for FilterMap<'a, A, B, T> { } #[unstable = "trait is unstable"] -impl<'a, A, B, T: DoubleEndedIterator> DoubleEndedIterator -for FilterMap<'a, A, B, T> { +impl DoubleEndedIterator for FilterMap where + I: DoubleEndedIterator, + F: FnMut(A) -> Option, +{ #[inline] fn next_back(&mut self) -> Option { for x in self.iter.by_ref().rev() { @@ -1628,14 +1651,14 @@ impl<'a, A, T: Iterator> Peekable { /// 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 where I: Iterator, P: FnMut(&A) -> bool { + iter: I, flag: bool, - predicate: |&A|: 'a -> bool + predicate: P, } #[unstable = "trait is unstable"] -impl<'a, A, T: Iterator> Iterator for SkipWhile<'a, A, T> { +impl Iterator for SkipWhile where I: Iterator, P: FnMut(&A) -> bool { #[inline] fn next(&mut self) -> Option { for x in self.iter { @@ -1657,14 +1680,14 @@ impl<'a, A, T: Iterator> Iterator 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 where I: Iterator, P: FnMut(&A) -> bool { + iter: I, flag: bool, - predicate: |&A|: 'a -> bool + predicate: P, } #[unstable = "trait is unstable"] -impl<'a, A, T: Iterator> Iterator for TakeWhile<'a, A, T> { +impl Iterator for TakeWhile where I: Iterator, P: FnMut(&A) -> bool { #[inline] fn next(&mut self) -> Option { if self.flag { @@ -1816,16 +1839,19 @@ impl> RandomAccessIterator for Take { /// 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, +pub struct Scan where I: Iterator, F: FnMut(&mut St, A) -> Option { + 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, St> Iterator for Scan<'a, A, B, T, St> { +impl Iterator for Scan where + I: Iterator, + F: FnMut(&mut St, A) -> Option, +{ #[inline] fn next(&mut self) -> Option { self.iter.next().and_then(|a| (self.f)(&mut self.state, a)) @@ -1843,15 +1869,19 @@ impl<'a, A, B, T: Iterator, St> Iterator 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 where I: Iterator, U: Iterator, F: FnMut(A) -> U { + iter: I, + f: F, frontiter: Option, backiter: Option, } #[unstable = "trait is unstable"] -impl<'a, A, T: Iterator, B, U: Iterator> Iterator for FlatMap<'a, A, T, U> { +impl Iterator for FlatMap where + I: Iterator, + U: Iterator, + F: FnMut(A) -> U, +{ #[inline] fn next(&mut self) -> Option { loop { @@ -1880,10 +1910,11 @@ impl<'a, A, T: Iterator, B, U: Iterator> Iterator for FlatMap<'a, A, T, } #[unstable = "trait is unstable"] -impl<'a, - A, T: DoubleEndedIterator, - B, U: DoubleEndedIterator> DoubleEndedIterator - for FlatMap<'a, A, T, U> { +impl DoubleEndedIterator for FlatMap where + I: DoubleEndedIterator, + U: DoubleEndedIterator, + F: FnMut(A) -> U, +{ #[inline] fn next_back(&mut self) -> Option { loop { @@ -1984,12 +2015,12 @@ impl Fuse { /// 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 where I: Iterator, F: FnMut(&A) { + iter: I, + f: F, } -impl<'a, A, T> Inspect<'a, A, T> { +impl Inspect where I: Iterator, F: FnMut(&A) { #[inline] fn do_inspect(&mut self, elt: Option) -> Option { match elt { @@ -2002,7 +2033,7 @@ impl<'a, A, T> Inspect<'a, A, T> { } #[unstable = "trait is unstable"] -impl<'a, A, T: Iterator> Iterator for Inspect<'a, A, T> { +impl Iterator for Inspect where I: Iterator, F: FnMut(&A) { #[inline] fn next(&mut self) -> Option { let next = self.iter.next(); @@ -2016,8 +2047,10 @@ impl<'a, A, T: Iterator> Iterator for Inspect<'a, A, T> { } #[unstable = "trait is unstable"] -impl<'a, A, T: DoubleEndedIterator> DoubleEndedIterator -for Inspect<'a, A, T> { +impl DoubleEndedIterator for Inspect where + I: DoubleEndedIterator, + F: FnMut(&A), +{ #[inline] fn next_back(&mut self) -> Option { let next = self.iter.next_back(); @@ -2026,8 +2059,10 @@ for Inspect<'a, A, T> { } #[experimental = "trait is experimental"] -impl<'a, A, T: RandomAccessIterator> RandomAccessIterator -for Inspect<'a, A, T> { +impl RandomAccessIterator for Inspect where + I: RandomAccessIterator, + 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, +pub struct Unfold where F: FnMut(&mut St) -> Option { + 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 Unfold where F: FnMut(&mut St) -> Option { /// 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) - -> Unfold<'a, A, St> { + pub fn new(initial_state: St, f: F) -> Unfold { Unfold { f: f, state: initial_state @@ -2094,7 +2128,7 @@ impl<'a, A, St> Unfold<'a, A, St> { } #[experimental] -impl<'a, A, St> Iterator for Unfold<'a, A, St> { +impl Iterator for Unfold where F: FnMut(&mut St) -> Option { #[inline] fn next(&mut self) -> Option { (self.f)(&mut self.state) @@ -2421,18 +2455,24 @@ impl RandomAccessIterator for Repeat { fn idx(&mut self, _: uint) -> Option { Some(self.element.clone()) } } -type IterateState<'a, T> = (|T|: 'a -> T, Option, bool); +type IterateState = (F, Option, 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 = Unfold, fn(&mut IterateState) -> Option>; /// 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(seed: T, f: F) -> Iterate where + T: Clone, + F: FnMut(T) -> T, +{ + fn next(st: &mut IterateState) -> Option 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 5e2d6266f0ec3..7be47f73e9ee7 100644 --- a/src/libcore/option.rs +++ b/src/libcore/option.rs @@ -156,7 +156,7 @@ use result::Result::{Ok, Err}; use slice; use slice::AsSlice; use clone::Clone; -use ops::Deref; +use ops::{Deref, FnOnce}; // Note that this is not a lang item per se, but it has a hidden dependency on // `Iterator`, which is one. The compiler assumes that the `next` method of @@ -389,7 +389,7 @@ impl Option { /// ``` #[inline] #[unstable = "waiting for conventions"] - pub fn unwrap_or_else(self, f: || -> T) -> T { + pub fn unwrap_or_else T>(self, f: F) -> T { match self { Some(x) => x, None => f() @@ -413,7 +413,7 @@ impl Option { /// ``` #[inline] #[unstable = "waiting for unboxed closures"] - pub fn map(self, f: |T| -> U) -> Option { + pub fn map U>(self, f: F) -> Option { match self { Some(x) => Some(f(x)), None => None @@ -433,7 +433,7 @@ impl Option { /// ``` #[inline] #[unstable = "waiting for unboxed closures"] - pub fn map_or(self, def: U, f: |T| -> U) -> U { + pub fn map_or U>(self, def: U, f: F) -> U { match self { Some(t) => f(t), None => def @@ -455,7 +455,7 @@ impl Option { /// ``` #[inline] #[unstable = "waiting for unboxed closures"] - pub fn map_or_else(self, def: || -> U, f: |T| -> U) -> U { + pub fn map_or_else U, F: FnOnce(T) -> U>(self, def: D, f: F) -> U { match self { Some(t) => f(t), None => def() @@ -497,7 +497,7 @@ impl Option { /// ``` #[inline] #[experimental] - pub fn ok_or_else(self, err: || -> E) -> Result { + pub fn ok_or_else E>(self, err: F) -> Result { match self { Some(v) => Ok(v), None => Err(err()), @@ -615,7 +615,7 @@ impl Option { /// ``` #[inline] #[unstable = "waiting for unboxed closures"] - pub fn and_then(self, f: |T| -> Option) -> Option { + pub fn and_then Option>(self, f: F) -> Option { match self { Some(x) => f(x), None => None, @@ -667,7 +667,7 @@ impl Option { /// ``` #[inline] #[unstable = "waiting for unboxed closures"] - pub fn or_else(self, f: || -> Option) -> Option { + pub fn or_else Option>(self, f: F) -> Option { match self { Some(_) => self, None => f() diff --git a/src/libcore/result.rs b/src/libcore/result.rs index 9d1ffa7891116..88d33a59b38bd 100644 --- a/src/libcore/result.rs +++ b/src/libcore/result.rs @@ -239,6 +239,7 @@ use slice::AsSlice; use iter::{Iterator, IteratorExt, DoubleEndedIterator, FromIterator, ExactSizeIterator}; use option::Option; use option::Option::{None, Some}; +use ops::{FnMut, FnOnce}; /// `Result` is a type that represents either success (`Ok`) or failure (`Err`). /// @@ -466,7 +467,7 @@ impl Result { /// ``` #[inline] #[unstable = "waiting for unboxed closures"] - pub fn map(self, op: |T| -> U) -> Result { + pub fn map U>(self, op: F) -> Result { match self { Ok(t) => Ok(op(t)), Err(e) => Err(e) @@ -492,7 +493,7 @@ impl Result { /// ``` #[inline] #[unstable = "waiting for unboxed closures"] - pub fn map_err(self, op: |E| -> F) -> Result { + pub fn map_err F>(self, op: O) -> Result { match self { Ok(t) => Ok(t), Err(e) => Err(op(e)) @@ -612,7 +613,7 @@ impl Result { /// ``` #[inline] #[unstable = "waiting for unboxed closures"] - pub fn and_then(self, op: |T| -> Result) -> Result { + pub fn and_then Result>(self, op: F) -> Result { match self { Ok(t) => op(t), Err(e) => Err(e), @@ -666,7 +667,7 @@ impl Result { /// ``` #[inline] #[unstable = "waiting for unboxed closures"] - pub fn or_else(self, op: |E| -> Result) -> Result { + pub fn or_else Result>(self, op: O) -> Result { match self { Ok(t) => Ok(t), Err(e) => op(e), @@ -708,7 +709,7 @@ impl Result { /// ``` #[inline] #[unstable = "waiting for conventions"] - pub fn unwrap_or_else(self, op: |E| -> T) -> T { + pub fn unwrap_or_else T>(self, op: F) -> T { match self { Ok(t) => t, Err(e) => op(e) @@ -904,10 +905,11 @@ impl> FromIterator> for Result { pub fn fold V, Iter: Iterator>>( mut iterator: Iter, mut init: V, - f: |V, T| -> V) + mut f: F) -> Result { for t in iterator { match t { diff --git a/src/libcore/slice.rs b/src/libcore/slice.rs index 4e3007b55fe04..27a4328ba8017 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 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>; + fn splitn<'a, P>(&'a self, n: uint, pred: P) -> SplitsN> 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>; + fn rsplitn<'a, P>(&'a self, n: uint, pred: P) -> SplitsN> 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 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(&self, f: F) -> BinarySearchResult where F: FnMut(&T) -> Ordering; /// Return the number of elements in the slice /// @@ -316,20 +319,23 @@ pub trait SlicePrelude 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>; + fn splitn_mut<'a, P>(&'a mut self, n: uint, pred: P) -> SplitsN> 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>; + fn rsplitn_mut<'a, P>(&'a mut self, n: uint, pred: P) -> SplitsN> 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 SlicePrelude 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 SlicePrelude for [T] { } #[inline] - fn splitn<'a>(&'a self, n: uint, pred: |&T|: 'a -> bool) -> SplitsN> { + fn splitn<'a, P>(&'a self, n: uint, pred: P) -> SplitsN> where + P: FnMut(&T) -> bool, + { SplitsN { iter: self.split(pred), count: n, @@ -488,7 +496,9 @@ impl SlicePrelude for [T] { } #[inline] - fn rsplitn<'a>(&'a self, n: uint, pred: |&T|: 'a -> bool) -> SplitsN> { + fn rsplitn<'a, P>(&'a self, n: uint, pred: P) -> SplitsN> where + P: FnMut(&T) -> bool, + { SplitsN { iter: self.split(pred), count: n, @@ -542,7 +552,7 @@ impl SlicePrelude for [T] { } #[unstable] - fn binary_search(&self, f: |&T| -> Ordering) -> BinarySearchResult { + fn binary_search(&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 SlicePrelude 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> { + fn splitn_mut<'a, P>(&'a mut self, n: uint, pred: P) -> SplitsN> where + P: FnMut(&T) -> bool + { SplitsN { iter: self.split_mut(pred), count: n, @@ -651,7 +663,9 @@ impl SlicePrelude for [T] { } #[inline] - fn rsplitn_mut<'a>(&'a mut self, n: uint, pred: |&T|: 'a -> bool) -> SplitsN> { + fn rsplitn_mut<'a, P>(&'a mut self, n: uint, pred: P) -> SplitsN> where + P: FnMut(&T) -> bool, + { SplitsN { iter: self.split_mut(pred), count: n, @@ -1271,14 +1285,14 @@ trait SplitsIter: DoubleEndedIterator { /// 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(p: *const T, len: uint, f: |v: &[T]| -> U) - -> U { + pub unsafe fn buf_as_slice(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( - p: *mut T, - len: uint, - f: |v: &mut [T]| -> U) - -> U { + pub unsafe fn mut_buf_as_slice(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 d0c8558b55d07..92f82bd977114 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 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(&self, search: C) -> Option; @@ -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(&self, search: C) -> Option; @@ -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(&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(&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(&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 032f5f7194117..2d77c1bc0978c 100644 --- a/src/libcoretest/finally.rs +++ b/src/libcoretest/finally.rs @@ -45,7 +45,7 @@ fn test_fail() { #[test] fn test_retval() { - let mut closure: || -> int = || 10; + let mut closure = |&mut:| 10i; let i = closure.finally(|| { }); assert_eq!(i, 10); } diff --git a/src/libcoretest/iter.rs b/src/libcoretest/iter.rs index d046faa82d405..acc2eab60e778 100644 --- a/src/libcoretest/iter.rs +++ b/src/libcoretest/iter.rs @@ -221,7 +221,7 @@ fn test_iterator_flat_map() { #[test] fn test_inspect() { let xs = [1u, 2, 3, 4]; - let mut n = 0; + let mut n = 0u; let ys = xs.iter() .map(|&x| x) diff --git a/src/libcoretest/lib.rs b/src/libcoretest/lib.rs index 5f31ed35f1b60..089a2cc880eb6 100644 --- a/src/libcoretest/lib.rs +++ b/src/libcoretest/lib.rs @@ -8,6 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. #![feature(globs, unsafe_destructor, macro_rules, slicing_syntax)] +#![feature(unboxed_closures)] extern crate core; extern crate test; diff --git a/src/libcoretest/str.rs b/src/libcoretest/str.rs index 9574aeb3762de..763fcccdbfdc8 100644 --- a/src/libcoretest/str.rs +++ b/src/libcoretest/str.rs @@ -54,7 +54,7 @@ fn test_rsplitn_char_iterator() { split.reverse(); assert_eq!(split, vec!["\nMäry häd ä", "little", "lämb\nLittle", "lämb\n"]); - let mut split: Vec<&str> = data.rsplitn(3, |c: char| c == ' ').collect(); + let mut split: Vec<&str> = data.rsplitn(3, |&: c: char| c == ' ').collect(); split.reverse(); assert_eq!(split, vec!["\nMäry häd ä", "little", "lämb\nLittle", "lämb\n"]); @@ -63,7 +63,7 @@ fn test_rsplitn_char_iterator() { split.reverse(); assert_eq!(split, vec!["\nMäry häd ", " little l", "mb\nLittle l", "mb\n"]); - let mut split: Vec<&str> = data.rsplitn(3, |c: char| c == 'ä').collect(); + let mut split: Vec<&str> = data.rsplitn(3, |&: c: char| c == 'ä').collect(); split.reverse(); assert_eq!(split, vec!["\nMäry häd ", " little l", "mb\nLittle l", "mb\n"]); } @@ -79,10 +79,10 @@ fn test_split_char_iterator() { rsplit.reverse(); assert_eq!(rsplit, vec!["\nMäry", "häd", "ä", "little", "lämb\nLittle", "lämb\n"]); - let split: Vec<&str> = data.split(|c: char| c == ' ').collect(); + let split: Vec<&str> = data.split(|&: c: char| c == ' ').collect(); assert_eq!( split, vec!["\nMäry", "häd", "ä", "little", "lämb\nLittle", "lämb\n"]); - let mut rsplit: Vec<&str> = data.split(|c: char| c == ' ').rev().collect(); + let mut rsplit: Vec<&str> = data.split(|&: c: char| c == ' ').rev().collect(); rsplit.reverse(); assert_eq!(rsplit, vec!["\nMäry", "häd", "ä", "little", "lämb\nLittle", "lämb\n"]); @@ -94,10 +94,10 @@ fn test_split_char_iterator() { rsplit.reverse(); assert_eq!(rsplit, vec!["\nM", "ry h", "d ", " little l", "mb\nLittle l", "mb\n"]); - let split: Vec<&str> = data.split(|c: char| c == 'ä').collect(); + let split: Vec<&str> = data.split(|&: c: char| c == 'ä').collect(); assert_eq!( split, vec!["\nM", "ry h", "d ", " little l", "mb\nLittle l", "mb\n"]); - let mut rsplit: Vec<&str> = data.split(|c: char| c == 'ä').rev().collect(); + let mut rsplit: Vec<&str> = data.split(|&: c: char| c == 'ä').rev().collect(); rsplit.reverse(); assert_eq!(rsplit, vec!["\nM", "ry h", "d ", " little l", "mb\nLittle l", "mb\n"]); } diff --git a/src/libgetopts/lib.rs b/src/libgetopts/lib.rs index a47fab124c3b1..79c435f01e4e6 100644 --- a/src/libgetopts/lib.rs +++ b/src/libgetopts/lib.rs @@ -87,6 +87,7 @@ html_playground_url = "http://play.rust-lang.org/")] #![feature(globs, phase)] #![feature(import_shadowing)] +#![feature(unboxed_closures)] #![deny(missing_docs)] #[cfg(test)] #[phase(plugin, link)] extern crate log; @@ -867,8 +868,9 @@ impl Copy for LengthLimit {} /// /// Panics during iteration if the string contains a non-whitespace /// sequence longer than the limit. -fn each_split_within<'a>(ss: &'a str, lim: uint, it: |&'a str| -> bool) - -> bool { +fn each_split_within(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 c1c397db213f6..8ebb3ae365c07 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(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 05932db6632ff..7ebf9b6335208 100644 --- a/src/libgraphviz/maybe_owned_vec.rs +++ b/src/libgraphviz/maybe_owned_vec.rs @@ -142,7 +142,7 @@ impl<'a,T:Clone> CloneSliceAllocPrelude for MaybeOwnedVector<'a,T> { self.as_slice().to_vec() } - fn partitioned(&self, f: |&T| -> bool) -> (Vec, Vec) { + fn partitioned(&self, f: F) -> (Vec, Vec) 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 0fa989bf0b2b9..a44197c98590c 100644 --- a/src/librand/distributions/mod.rs +++ b/src/librand/distributions/mod.rs @@ -208,14 +208,14 @@ mod ziggurat_tables; // the perf improvement (25-50%) is definitely worth the extra code // size from force-inlining. #[inline(always)] -fn ziggurat( +fn ziggurat( rng: &mut R, symmetric: bool, x_tab: ziggurat_tables::ZigTable, f_tab: ziggurat_tables::ZigTable, - pdf: |f64|: 'static -> f64, - zero_case: |&mut R, f64|: 'static -> f64) - -> f64 { + mut pdf: P, + mut zero_case: Z) + -> f64 where P: FnMut(f64) -> f64, Z: FnMut(&mut R, f64) -> f64 { static SCALE: f64 = (1u64 << 53) as f64; loop { // reimplement the f64 generation as an optimisation suggested diff --git a/src/librand/lib.rs b/src/librand/lib.rs index d357f247f1b74..4fba3707703a5 100644 --- a/src/librand/lib.rs +++ b/src/librand/lib.rs @@ -24,6 +24,7 @@ html_playground_url = "http://play.rust-lang.org/")] #![feature(macro_rules, phase, globs)] +#![feature(unboxed_closures)] #![no_std] #![experimental] diff --git a/src/librbml/lib.rs b/src/librbml/lib.rs index 426a987d25d1c..28d5e1812f090 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(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(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(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(&mut self, exp_tag: EbmlEncoderTag, - f: |&mut Decoder<'doc>| -> DecodeResult) -> DecodeResult { + fn push_doc(&mut self, exp_tag: EbmlEncoderTag, f: F) -> DecodeResult where + F: FnOnce(&mut Decoder<'doc>) -> DecodeResult, + { 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(&mut self, - op: |&mut Decoder<'doc>, Doc| -> DecodeResult) -> DecodeResult { + pub fn read_opaque(&mut self, op: F) -> DecodeResult where + F: FnOnce(&mut Decoder, Doc) -> DecodeResult, + { 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(&mut self, - name: &str, - f: |&mut Decoder<'doc>| -> DecodeResult) -> DecodeResult { + fn read_enum(&mut self, name: &str, f: F) -> DecodeResult where + F: FnOnce(&mut Decoder<'doc>) -> DecodeResult, + { debug!("read_enum({})", name); try!(self._check_label(name)); @@ -490,10 +499,9 @@ pub mod reader { Ok(result) } - fn read_enum_variant(&mut self, - _: &[&str], - f: |&mut Decoder<'doc>, uint| -> DecodeResult) - -> DecodeResult { + fn read_enum_variant(&mut self, _: &[&str], f: F) -> DecodeResult where + F: FnOnce(&mut Decoder<'doc>, uint) -> DecodeResult, + { 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(&mut self, - idx: uint, - f: |&mut Decoder<'doc>| -> DecodeResult) -> DecodeResult { + fn read_enum_variant_arg(&mut self, idx: uint, f: F) -> DecodeResult where + F: FnOnce(&mut Decoder<'doc>) -> DecodeResult, + { debug!("read_enum_variant_arg(idx={})", idx); f(self) } - fn read_enum_struct_variant(&mut self, - _: &[&str], - f: |&mut Decoder<'doc>, uint| -> DecodeResult) - -> DecodeResult { + fn read_enum_struct_variant(&mut self, _: &[&str], f: F) -> DecodeResult where + F: FnOnce(&mut Decoder<'doc>, uint) -> DecodeResult, + { 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(&mut self, - name: &str, - idx: uint, - f: |&mut Decoder<'doc>| -> DecodeResult) - -> DecodeResult { - debug!("read_enum_struct_variant_arg(name={}, idx={})", name, idx); + fn read_enum_struct_variant_field(&mut self, + name: &str, + idx: uint, + f: F) + -> DecodeResult where + F: FnOnce(&mut Decoder<'doc>) -> DecodeResult, + { + debug!("read_enum_struct_variant_arg(name={}, idx={})", name, idx); f(self) } - fn read_struct(&mut self, - name: &str, - _: uint, - f: |&mut Decoder<'doc>| -> DecodeResult) - -> DecodeResult { + fn read_struct(&mut self, name: &str, _: uint, f: F) -> DecodeResult where + F: FnOnce(&mut Decoder<'doc>) -> DecodeResult, + { debug!("read_struct(name={})", name); f(self) } - fn read_struct_field(&mut self, - name: &str, - idx: uint, - f: |&mut Decoder<'doc>| -> DecodeResult) - -> DecodeResult { + fn read_struct_field(&mut self, name: &str, idx: uint, f: F) -> DecodeResult where + F: FnOnce(&mut Decoder<'doc>) -> DecodeResult, + { debug!("read_struct_field(name={}, idx={})", name, idx); try!(self._check_label(name)); f(self) } - fn read_tuple(&mut self, - tuple_len: uint, - f: |&mut Decoder<'doc>| -> DecodeResult) -> DecodeResult { + fn read_tuple(&mut self, tuple_len: uint, f: F) -> DecodeResult where + F: FnOnce(&mut Decoder<'doc>) -> DecodeResult, + { 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(&mut self, idx: uint, f: |&mut Decoder<'doc>| -> DecodeResult) - -> DecodeResult { + fn read_tuple_arg(&mut self, idx: uint, f: F) -> DecodeResult where + F: FnOnce(&mut Decoder<'doc>) -> DecodeResult, + { debug!("read_tuple_arg(idx={})", idx); self.read_seq_elt(idx, f) } - fn read_tuple_struct(&mut self, - name: &str, - len: uint, - f: |&mut Decoder<'doc>| -> DecodeResult) - -> DecodeResult { + fn read_tuple_struct(&mut self, name: &str, len: uint, f: F) -> DecodeResult where + F: FnOnce(&mut Decoder<'doc>) -> DecodeResult, + { debug!("read_tuple_struct(name={})", name); self.read_tuple(len, f) } - fn read_tuple_struct_arg(&mut self, - idx: uint, - f: |&mut Decoder<'doc>| -> DecodeResult) - -> DecodeResult { + fn read_tuple_struct_arg(&mut self, + idx: uint, + f: F) + -> DecodeResult where + F: FnOnce(&mut Decoder<'doc>) -> DecodeResult, + { debug!("read_tuple_struct_arg(idx={})", idx); self.read_tuple_arg(idx, f) } - fn read_option(&mut self, - f: |&mut Decoder<'doc>, bool| -> DecodeResult) -> DecodeResult { + fn read_option(&mut self, f: F) -> DecodeResult where + F: FnOnce(&mut Decoder<'doc>, bool) -> DecodeResult, + { 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(&mut self, - f: |&mut Decoder<'doc>, uint| -> DecodeResult) -> DecodeResult { + fn read_seq(&mut self, f: F) -> DecodeResult where + F: FnOnce(&mut Decoder<'doc>, uint) -> DecodeResult, + { 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(&mut self, idx: uint, f: |&mut Decoder<'doc>| -> DecodeResult) - -> DecodeResult { + fn read_seq_elt(&mut self, idx: uint, f: F) -> DecodeResult where + F: FnOnce(&mut Decoder<'doc>) -> DecodeResult, + { debug!("read_seq_elt(idx={})", idx); self.push_doc(EsVecElt, f) } - fn read_map(&mut self, - f: |&mut Decoder<'doc>, uint| -> DecodeResult) -> DecodeResult { + fn read_map(&mut self, f: F) -> DecodeResult where + F: FnOnce(&mut Decoder<'doc>, uint) -> DecodeResult, + { 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(&mut self, idx: uint, f: |&mut Decoder<'doc>| -> DecodeResult) - -> DecodeResult { + fn read_map_elt_key(&mut self, idx: uint, f: F) -> DecodeResult where + F: FnOnce(&mut Decoder<'doc>) -> DecodeResult, + { debug!("read_map_elt_key(idx={})", idx); self.push_doc(EsMapKey, f) } - fn read_map_elt_val(&mut self, idx: uint, f: |&mut Decoder<'doc>| -> DecodeResult) - -> DecodeResult { + fn read_map_elt_val(&mut self, idx: uint, f: F) -> DecodeResult where + F: FnOnce(&mut Decoder<'doc>) -> DecodeResult, + { 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(&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| -> EncodeResult) -> EncodeResult { + pub fn emit_opaque(&mut self, f: F) -> EncodeResult where + F: FnOnce(&mut Encoder) -> 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(&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(&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(&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(&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(&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(&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(&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(&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(&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(&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(&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(&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(&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(&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(&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(&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(&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(&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 b35c3879783a0..05f853a851ea7 100644 --- a/src/libregex/lib.rs +++ b/src/libregex/lib.rs @@ -370,6 +370,7 @@ #![allow(unknown_features)] #![feature(macro_rules, phase, slicing_syntax, globs)] +#![feature(unboxed_closures)] #![deny(missing_docs)] #[cfg(test)] diff --git a/src/libregex/parse.rs b/src/libregex/parse.rs index 55e533aadee7f..ccbd53c4f2a88 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 { + fn pos_last

(&self, allow_start: bool, pred: P) -> Result 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 { + fn build_from(&mut self, from: uint, mut mk: F) -> Result 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 2a1fda06431c8..1504e1919852d 100644 --- a/src/libregex/re.rs +++ b/src/libregex/re.rs @@ -429,10 +429,11 @@ impl Regex { /// /// ```rust /// # #![feature(phase)] + /// # #![feature(unboxed_closures)] /// # extern crate regex; #[phase(plugin)] extern crate regex_macros; /// # use regex::Captures; fn main() { /// let re = regex!(r"([^,\s]+),\s+(\S+)"); - /// let result = re.replace("Springsteen, Bruce", |caps: &Captures| { + /// let result = re.replace("Springsteen, Bruce", |&: caps: &Captures| { /// format!("{} {}", caps.at(2), caps.at(1)) /// }); /// assert_eq!(result.as_slice(), "Bruce Springsteen"); @@ -585,7 +586,7 @@ impl<'t> Replacer for &'t str { } } -impl<'t> Replacer for |&Captures|: 't -> String { +impl 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::(name.as_slice()) { diff --git a/src/libregex_macros/lib.rs b/src/libregex_macros/lib.rs index 4df8819774319..c1e8677fa8f3d 100644 --- a/src/libregex_macros/lib.rs +++ b/src/libregex_macros/lib.rs @@ -19,6 +19,7 @@ html_root_url = "http://doc.rust-lang.org/nightly/")] #![feature(plugin_registrar, quote)] +#![feature(unboxed_closures)] extern crate regex; extern crate syntax; @@ -601,9 +602,10 @@ fn exec<'t>(which: ::regex::native::MatchKind, input: &'t str, // Converts `xs` to a `[x1, x2, .., xN]` expression by calling `to_expr` // on each element in `xs`. - fn vec_expr>(&self, xs: It, - to_expr: |&ExtCtxt, T| -> P) - -> P { + fn vec_expr(&self, xs: It, mut to_expr: F) -> P where + It: Iterator, + F: FnMut(&ExtCtxt, T) -> P, + { 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 51cb7e193ffb8..404c7edeb88d6 100644 --- a/src/librustc/lib.rs +++ b/src/librustc/lib.rs @@ -25,6 +25,7 @@ #![feature(default_type_params, globs, import_shadowing, macro_rules, phase, quote)] #![feature(slicing_syntax, unsafe_destructor)] #![feature(rustc_diagnostic_macros)] +#![feature(unboxed_closures)] extern crate arena; extern crate flate; diff --git a/src/librustc/lint/context.rs b/src/librustc/lint/context.rs index 153a00e561776..9f9e266c6c74b 100644 --- a/src/librustc/lint/context.rs +++ b/src/librustc/lint/context.rs @@ -464,9 +464,11 @@ impl<'a, 'tcx> Context<'a, 'tcx> { /// Merge the lints specified by any lint attributes into the /// current lint context, call the provided function, then reset the /// lints in effect to their previous state. - fn with_lint_attrs(&mut self, - attrs: &[ast::Attribute], - f: |&mut Context|) { + fn with_lint_attrs(&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|) { + fn visit_ids(&mut self, f: F) where + F: FnOnce(&mut ast_util::IdVisitor) + { let mut v = ast_util::IdVisitor { operation: self, pass_through_items: false, diff --git a/src/librustc/metadata/csearch.rs b/src/librustc/metadata/csearch.rs index 7ce9893afc8b1..4cbb1babf9a2c 100644 --- a/src/librustc/metadata/csearch.rs +++ b/src/librustc/metadata/csearch.rs @@ -47,20 +47,22 @@ pub fn get_symbol(cstore: &cstore::CStore, def: ast::DefId) -> String { } /// Iterates over all the language items in the given crate. -pub fn each_lang_item(cstore: &cstore::CStore, - cnum: ast::CrateNum, - f: |ast::NodeId, uint| -> bool) - -> bool { +pub fn each_lang_item(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(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(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|) { +pub fn get_item_attrs(cstore: &cstore::CStore, + def_id: ast::DefId, + f: F) where + F: FnOnce(Vec), +{ 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(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(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(cstore: &cstore::CStore, + def_id: ast::DefId, + callback: F) where + F: FnMut(ast::DefId), +{ let cdata = cstore.get_crate_data(def_id.krate); decoder::each_implementation_for_trait(&*cdata, def_id.node, callback) } diff --git a/src/librustc/metadata/cstore.rs b/src/librustc/metadata/cstore.rs index bb1c75b075c2b..c0642f29abc90 100644 --- a/src/librustc/metadata/cstore.rs +++ b/src/librustc/metadata/cstore.rs @@ -113,16 +113,18 @@ impl CStore { self.metas.borrow_mut().insert(cnum, data); } - pub fn iter_crate_data(&self, i: |ast::CrateNum, &crate_metadata|) { + pub fn iter_crate_data(&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|) { + pub fn iter_crate_data_origins(&self, mut i: I) where + I: FnMut(ast::CrateNum, &crate_metadata, Option), + { 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 898f5d2ef93ca..4e892f53186bc 100644 --- a/src/librustc/metadata/decoder.rs +++ b/src/librustc/metadata/decoder.rs @@ -60,8 +60,9 @@ pub type Cmd<'a> = &'a crate_metadata; // what crate that's in and give us a def_id that makes sense for the current // build. -fn lookup_hash<'a>(d: rbml::Doc<'a>, eq_fn: |&[u8]| -> bool, - hash: u64) -> Option> { +fn lookup_hash<'a, F>(d: rbml::Doc<'a>, mut eq_fn: F, hash: u64) -> Option> 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 { }) } -fn each_reexport(d: rbml::Doc, f: |rbml::Doc| -> bool) -> bool { +fn each_reexport(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(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; -fn each_child_of_item_or_crate(intr: Rc, - cdata: Cmd, - item_doc: rbml::Doc, - get_crate_data: GetCrateDataCb, - callback: |DefLike, - ast::Name, - ast::Visibility|) { +fn each_child_of_item_or_crate(intr: Rc, + 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, } /// Iterates over each child of the given item. -pub fn each_child_of_item(intr: Rc, - cdata: Cmd, - id: ast::NodeId, - get_crate_data: GetCrateDataCb, - callback: |DefLike, ast::Name, ast::Visibility|) { +pub fn each_child_of_item(intr: Rc, + 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, } /// Iterates over all the top-level crate items. -pub fn each_top_level_item_of_crate(intr: Rc, - cdata: Cmd, - get_crate_data: GetCrateDataCb, - callback: |DefLike, - ast::Name, - ast::Visibility|) { +pub fn each_top_level_item_of_crate(intr: Rc, + 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|) { +pub fn get_item_attrs(cdata: Cmd, + orig_node_id: ast::NodeId, + f: F) where + F: FnOnce(Vec), +{ // 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(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(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(cdata: Cmd, + id: ast::NodeId, + mut callback: F) where + F: FnMut(ast::DefId), +{ let item_doc = lookup_item(id, cdata.data()); let _ = reader::tagged_docs(item_doc, diff --git a/src/librustc/metadata/encoder.rs b/src/librustc/metadata/encoder.rs index 48d1284f50787..9804e3c20aa35 100644 --- a/src/librustc/metadata/encoder.rs +++ b/src/librustc/metadata/encoder.rs @@ -493,7 +493,9 @@ fn encode_reexported_static_methods(ecx: &EncodeContext, /// top-level items that are sub-items of the given item. Specifically: /// /// * For newtype structs, iterates through the node ID of the constructor. -fn each_auxiliary_node_id(item: &ast::Item, callback: |NodeId| -> bool) -> bool { +fn each_auxiliary_node_id(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(rbml_w: &mut Encoder, index: Vec>, - write_fn: |&mut SeekableMemWriter, &T|) { +fn encode_index(rbml_w: &mut Encoder, index: Vec>, mut write_fn: F) where + F: FnMut(&mut SeekableMemWriter, &T), + T: Hash, +{ let mut buckets: Vec>> = Vec::from_fn(256, |_| Vec::new()); for elt in index.into_iter() { let h = hash::hash(&elt.val) as uint; diff --git a/src/librustc/metadata/filesearch.rs b/src/librustc/metadata/filesearch.rs index 2d23a61813a9c..507fb751303f9 100644 --- a/src/librustc/metadata/filesearch.rs +++ b/src/librustc/metadata/filesearch.rs @@ -42,7 +42,9 @@ pub struct FileSearch<'a> { } impl<'a> FileSearch<'a> { - pub fn for_each_lib_search_path(&self, f: |&Path| -> FileMatch) { + pub fn for_each_lib_search_path(&self, mut f: F) where + F: FnMut(&Path) -> FileMatch, + { let mut visited_dirs = HashSet::new(); let mut found = false; diff --git a/src/librustc/metadata/tydecode.rs b/src/librustc/metadata/tydecode.rs index 37d790df37f46..7358b3bc9c969 100644 --- a/src/librustc/metadata/tydecode.rs +++ b/src/librustc/metadata/tydecode.rs @@ -89,7 +89,10 @@ fn next_byte(st: &mut PState) -> u8 { return b; } -fn scan(st: &mut PState, is_last: |char| -> bool, op: |&[u8]| -> R) -> R { +fn scan(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_(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 +fn parse_vec_per_param_space<'a, 'tcx, T, F>(st: &mut PState<'a, 'tcx>, + mut f: F) + -> VecPerParamSpace 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 { +fn parse_opt<'a, 'tcx, T, F>(st: &mut PState<'a, 'tcx>, f: F) -> Option where + F: FnOnce(&mut PState<'a, 'tcx>) -> T, +{ match next(st) { 'n' => None, 's' => Some(f(st)), diff --git a/src/librustc/metadata/tyencode.rs b/src/librustc/metadata/tyencode.rs index 5c7d15e16018b..54376cd7b9078 100644 --- a/src/librustc/metadata/tyencode.rs +++ b/src/librustc/metadata/tyencode.rs @@ -86,7 +86,9 @@ fn enc_mt<'a, 'tcx>(w: &mut SeekableMemWriter, cx: &ctxt<'a, 'tcx>, enc_ty(w, cx, mt.ty); } -fn enc_opt(w: &mut SeekableMemWriter, t: Option, enc_f: |&mut SeekableMemWriter, T|) { +fn enc_opt(w: &mut SeekableMemWriter, t: Option, enc_f: F) where + F: FnOnce(&mut SeekableMemWriter, T), +{ match t { None => mywrite!(w, "n"), Some(v) => { @@ -96,10 +98,12 @@ fn enc_opt(w: &mut SeekableMemWriter, t: Option, enc_f: |&mut SeekableMemW } } -fn enc_vec_per_param_space<'a, 'tcx, T>(w: &mut SeekableMemWriter, - cx: &ctxt<'a, 'tcx>, - v: &VecPerParamSpace, - 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, + mut op: F) where + F: FnMut(&mut SeekableMemWriter, &ctxt<'a, 'tcx>, &T), +{ for &space in subst::ParamSpace::all().iter() { mywrite!(w, "["); for t in v.get_slice(space).iter() { diff --git a/src/librustc/middle/astencode.rs b/src/librustc/middle/astencode.rs index 50337ec25bd19..26d70502a5b16 100644 --- a/src/librustc/middle/astencode.rs +++ b/src/librustc/middle/astencode.rs @@ -680,9 +680,8 @@ pub fn encode_unboxed_closure_kind(ebml_w: &mut Encoder, } pub trait vtable_decoder_helpers<'tcx> { - fn read_vec_per_param_space(&mut self, - f: |&mut Self| -> T) - -> VecPerParamSpace; + fn read_vec_per_param_space(&mut self, f: F) -> VecPerParamSpace 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(&mut self, - f: |&mut reader::Decoder<'a>| -> T) - -> VecPerParamSpace + fn read_vec_per_param_space(&mut self, mut f: F) -> VecPerParamSpace 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(rbml_w: &mut Encoder, - v: &subst::VecPerParamSpace, - f: |&mut Encoder, &T|) { +fn encode_vec_per_param_space(rbml_w: &mut Encoder, + v: &subst::VecPerParamSpace, + 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(&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(&mut self, + tag_id: c::astencode_tag, + f: F) where + F: FnOnce(&mut Encoder<'a>), + { self.start_tag(tag_id as uint); f(self); self.end_tag(); diff --git a/src/librustc/middle/check_const.rs b/src/librustc/middle/check_const.rs index de140fd5c306c..a91ea8bfef8c7 100644 --- a/src/librustc/middle/check_const.rs +++ b/src/librustc/middle/check_const.rs @@ -24,16 +24,22 @@ struct CheckCrateVisitor<'a, 'tcx: 'a> { } impl<'a, 'tcx> CheckCrateVisitor<'a, 'tcx> { - fn with_const(&mut self, in_const: bool, f: |&mut CheckCrateVisitor<'a, 'tcx>|) { + fn with_const(&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(&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(&mut self, f: F) where + F: FnOnce(&mut CheckCrateVisitor<'a, 'tcx>), + { self.with_const(false, f); } } diff --git a/src/librustc/middle/check_loop.rs b/src/librustc/middle/check_loop.rs index eb073e07b02f1..fee2d810fcb3d 100644 --- a/src/librustc/middle/check_loop.rs +++ b/src/librustc/middle/check_loop.rs @@ -64,7 +64,9 @@ impl<'a, 'v> Visitor<'v> for CheckLoopVisitor<'a> { } impl<'a> CheckLoopVisitor<'a> { - fn with_context(&mut self, cx: Context, f: |&mut CheckLoopVisitor<'a>|) { + fn with_context(&mut self, cx: Context, f: F) where + F: FnOnce(&mut CheckLoopVisitor<'a>), + { let old_cx = self.cx; self.cx = cx; f(self); diff --git a/src/librustc/middle/check_match.rs b/src/librustc/middle/check_match.rs index 2c437ae046b46..ea3ef2af73906 100644 --- a/src/librustc/middle/check_match.rs +++ b/src/librustc/middle/check_match.rs @@ -980,7 +980,9 @@ fn check_fn(cx: &mut MatchCheckCtxt, } } -fn is_refutable(cx: &MatchCheckCtxt, pat: &Pat, refutable: |&Pat| -> A) -> Option { +fn is_refutable(cx: &MatchCheckCtxt, pat: &Pat, refutable: F) -> Option where + F: FnOnce(&Pat) -> A, +{ let pats = Matrix(vec!(vec!(pat))); match is_useful(cx, &pats, &[DUMMY_WILD_PAT], ConstructWitness) { UsefulWithWitness(pats) => { diff --git a/src/librustc/middle/check_static.rs b/src/librustc/middle/check_static.rs index 5a53979d71932..65412ff8effc9 100644 --- a/src/librustc/middle/check_static.rs +++ b/src/librustc/middle/check_static.rs @@ -85,7 +85,9 @@ pub fn check_crate(tcx: &ty::ctxt) { } impl<'a, 'tcx> CheckStaticVisitor<'a, 'tcx> { - fn with_mode(&mut self, mode: Mode, f: |&mut CheckStaticVisitor<'a, 'tcx>|) { + fn with_mode(&mut self, mode: Mode, f: F) where + F: FnOnce(&mut CheckStaticVisitor<'a, 'tcx>), + { let old = self.mode; self.mode = mode; f(self); diff --git a/src/librustc/middle/dataflow.rs b/src/librustc/middle/dataflow.rs index db8fd999f380b..9373a5704b2b0 100644 --- a/src/librustc/middle/dataflow.rs +++ b/src/librustc/middle/dataflow.rs @@ -280,10 +280,9 @@ impl<'a, 'tcx, O:DataFlowOperator> DataFlowContext<'a, 'tcx, O> { } - pub fn each_bit_on_entry(&self, - id: ast::NodeId, - f: |uint| -> bool) - -> bool { + pub fn each_bit_on_entry(&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(&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(&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(&self, words: &[uint], mut f: F) -> bool where + F: FnMut(uint) -> bool, + { //! Helper for iterating over the bits in a bit set. //! Returns false on the first call to `f` that returns false; //! if all calls to `f` return true, then returns true. diff --git a/src/librustc/middle/def.rs b/src/librustc/middle/def.rs index b3e4dd25adc7a..ca60ac45e266a 100644 --- a/src/librustc/middle/def.rs +++ b/src/librustc/middle/def.rs @@ -61,7 +61,9 @@ pub enum MethodProvenance { } impl MethodProvenance { - pub fn map(self, f: |ast::DefId| -> ast::DefId) -> MethodProvenance { + pub fn map(self, f: F) -> MethodProvenance where + F: FnOnce(ast::DefId) -> ast::DefId, + { match self { FromTrait(did) => FromTrait(f(did)), FromImpl(did) => FromImpl(f(did)) diff --git a/src/librustc/middle/graph.rs b/src/librustc/middle/graph.rs index e45232a3c3038..4c03ed2a480ef 100644 --- a/src/librustc/middle/graph.rs +++ b/src/librustc/middle/graph.rs @@ -221,39 +221,43 @@ impl Graph { /////////////////////////////////////////////////////////////////////////// // Iterating over nodes, edges - pub fn each_node<'a>(&'a self, f: |NodeIndex, &'a Node| -> bool) -> bool { + pub fn each_node<'a, F>(&'a self, mut f: F) -> bool where + F: FnMut(NodeIndex, &'a Node) -> 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| -> bool) -> bool { + pub fn each_edge<'a, F>(&'a self, mut f: F) -> bool where + F: FnMut(EdgeIndex, &'a Edge) -> 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| -> bool) - -> bool { + pub fn each_outgoing_edge<'a, F>(&'a self, source: NodeIndex, f: F) -> bool where + F: FnMut(EdgeIndex, &'a Edge) -> 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| -> bool) - -> bool { + pub fn each_incoming_edge<'a, F>(&'a self, target: NodeIndex, f: F) -> bool where + F: FnMut(EdgeIndex, &'a Edge) -> 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| -> 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) -> bool, + { //! Iterates over all edges adjacent to the node `node` //! in the direction `dir` (either `Outgoing` or `Incoming) @@ -277,11 +281,9 @@ impl Graph { // 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| - -> bool) { + pub fn iterate_until_fixed_point<'a, F>(&'a self, mut op: F) where + F: FnMut(uint, EdgeIndex, &'a Edge) -> bool, + { let mut iteration = 0; let mut changed = true; while changed { @@ -294,7 +296,9 @@ impl Graph { } } -pub fn each_edge_index(max_edge_index: EdgeIndex, f: |EdgeIndex| -> bool) { +pub fn each_edge_index(max_edge_index: EdgeIndex, mut f: F) where + F: FnMut(EdgeIndex) -> bool, +{ let mut i = 0; let n = max_edge_index.get(); while i < n { diff --git a/src/librustc/middle/infer/coercion.rs b/src/librustc/middle/infer/coercion.rs index f04c519badc8c..c6422b36e384d 100644 --- a/src/librustc/middle/infer/coercion.rs +++ b/src/librustc/middle/infer/coercion.rs @@ -194,8 +194,9 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> { } } - pub fn unpack_actual_value(&self, a: Ty<'tcx>, f: |&ty::sty<'tcx>| -> T) - -> T { + pub fn unpack_actual_value(&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(&self, + a: Ty<'tcx>, + sty_a: &ty::sty<'tcx>, + b: Ty<'tcx>, + b_mutbl: ast::Mutability, + mk_ty: F, + mk_adjust: G) -> CoerceResult<'tcx> where + F: FnOnce(Ty<'tcx>) -> Ty<'tcx>, + G: FnOnce() -> ty::AutoRef<'tcx>, { let tcx = self.get_ref().infcx.tcx; diff --git a/src/librustc/middle/infer/higher_ranked/mod.rs b/src/librustc/middle/infer/higher_ranked/mod.rs index 95805ef8b944d..be053afcca436 100644 --- a/src/librustc/middle/infer/higher_ranked/mod.rs +++ b/src/librustc/middle/infer/higher_ranked/mod.rs @@ -426,11 +426,9 @@ fn is_var_in_set(new_vars: &[ty::RegionVid], r: ty::Region) -> bool { } } -fn fold_regions_in<'tcx, T>(tcx: &ty::ctxt<'tcx>, - value: &T, - fldr: |ty::Region, ty::DebruijnIndex| -> ty::Region) - -> T - where T: HigherRankedFoldable<'tcx> +fn fold_regions_in<'tcx, T, F>(tcx: &ty::ctxt<'tcx>, value: &T, mut fldr: F) -> T where + T: HigherRankedFoldable<'tcx>, + F: FnMut(ty::Region, ty::DebruijnIndex) -> ty::Region, { value.fold_contents(&mut ty_fold::RegionFolder::new(tcx, |region, current_depth| { // we should only be encountering "escaping" late-bound regions here, diff --git a/src/librustc/middle/infer/mod.rs b/src/librustc/middle/infer/mod.rs index 3b62b96a3e9b1..4c3b7589d76cb 100644 --- a/src/librustc/middle/infer/mod.rs +++ b/src/librustc/middle/infer/mod.rs @@ -477,14 +477,17 @@ pub fn resolve_region(cx: &InferCtxt, r: ty::Region, modes: uint) } trait then<'tcx> { - fn then(&self, f: || -> Result>) - -> Result>; + fn then(&self, f: F) -> Result> where + T: Clone, + F: FnOnce() -> Result>; } impl<'tcx> then<'tcx> for ures<'tcx> { - fn then(&self, f: || -> Result>) - -> Result> { - self.and_then(|_i| f()) + fn then(&self, f: F) -> Result> where + T: Clone, + F: FnOnce() -> Result>, + { + 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(&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(&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(&self, f: || -> R) -> R { + pub fn commit_unconditionally(&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(&self, f: || -> Result) -> Result { - self.commit_unconditionally(|| self.try(|| f())) + pub fn commit_if_ok(&self, f: F) -> Result where + F: FnOnce() -> Result + { + self.commit_unconditionally(move || self.try(move || f())) } /// Execute `f`, unroll bindings on panic - pub fn try(&self, f: || -> Result) -> Result { + pub fn try(&self, f: F) -> Result where + F: FnOnce() -> Result + { 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(&self, f: || -> R) -> R { + pub fn probe(&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, - actual_ty: String, - err: Option<&ty::type_err<'tcx>>) { + pub fn type_error_message_str(&self, + sp: Span, + mk_msg: M, + actual_ty: String, + err: Option<&ty::type_err<'tcx>>) where + M: FnOnce(Option, 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, - expected_ty: Option>, - actual_ty: String, - err: Option<&ty::type_err<'tcx>>) { + pub fn type_error_message_str_with_expected(&self, + sp: Span, + mk_msg: M, + expected_ty: Option>, + actual_ty: String, + err: Option<&ty::type_err<'tcx>>) where + M: FnOnce(Option, 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(&self, + sp: Span, + mk_msg: M, + actual_ty: Ty<'tcx>, + err: Option<&ty::type_err<'tcx>>) where + M: FnOnce(String) -> String, + { let actual_ty = self.resolve_type_vars_if_possible(actual_ty); // Don't report an error if actual type is ty_err. @@ -954,7 +972,9 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { return; } - self.type_error_message_str(sp, |_e, a| { mk_msg(a) }, self.ty_to_string(actual_ty), err); + self.type_error_message_str(sp, + move |_e, a| { mk_msg(a) }, + self.ty_to_string(actual_ty), err); } pub fn report_mismatched_types(&self, diff --git a/src/librustc/middle/infer/region_inference/mod.rs b/src/librustc/middle/infer/region_inference/mod.rs index 391e37e8b9c96..98f69f66b27fc 100644 --- a/src/librustc/middle/infer/region_inference/mod.rs +++ b/src/librustc/middle/infer/region_inference/mod.rs @@ -569,15 +569,15 @@ impl<'a, 'tcx> RegionVarBindings<'a, 'tcx> { } } - pub fn combine_vars(&self, - t: CombineMapType, - a: Region, - b: Region, - origin: SubregionOrigin<'tcx>, - relate: |this: &RegionVarBindings<'a, 'tcx>, - old_r: Region, - new_r: Region|) - -> Region { + pub fn combine_vars(&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(&self, tag: &str, mut body: F) where + F: FnMut(&Constraint) -> bool, + { let mut iteration = 0u; let mut changed = true; while changed { diff --git a/src/librustc/middle/infer/skolemize.rs b/src/librustc/middle/infer/skolemize.rs index 62bf1d0126a59..705b0ae730d49 100644 --- a/src/librustc/middle/infer/skolemize.rs +++ b/src/librustc/middle/infer/skolemize.rs @@ -54,11 +54,12 @@ impl<'a, 'tcx> TypeSkolemizer<'a, 'tcx> { } } - fn skolemize(&mut self, - opt_ty: Option>, - key: ty::InferTy, - skolemizer: |uint| -> ty::InferTy) - -> Ty<'tcx> + fn skolemize(&mut self, + opt_ty: Option>, + key: ty::InferTy, + skolemizer: F) + -> Ty<'tcx> where + F: FnOnce(uint) -> ty::InferTy, { match opt_ty { Some(ty) => { return ty.fold_with(self); } diff --git a/src/librustc/middle/liveness.rs b/src/librustc/middle/liveness.rs index 5edbafc4e0bee..271e903bbdf17 100644 --- a/src/librustc/middle/liveness.rs +++ b/src/librustc/middle/liveness.rs @@ -616,9 +616,9 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> { self.ir.variable(node_id, span) } - fn pat_bindings(&mut self, - pat: &ast::Pat, - f: |&mut Liveness<'a, 'tcx>, LiveNode, Variable, Span, NodeId|) { + fn pat_bindings(&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(&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(&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(&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(&mut self, - loop_node_id: NodeId, - break_ln: LiveNode, - cont_ln: LiveNode, - f: |&mut Liveness<'a, 'tcx>| -> R) - -> R { + fn with_loop_nodes(&mut self, + loop_node_id: NodeId, + break_ln: LiveNode, + cont_ln: LiveNode, + f: F) + -> R where + F: FnOnce(&mut Liveness<'a, 'tcx>) -> R, + { debug!("with_loop_nodes: {} {}", loop_node_id, break_ln.get()); self.loop_scope.push(loop_node_id); self.break_ln.insert(loop_node_id, break_ln); diff --git a/src/librustc/middle/mem_categorization.rs b/src/librustc/middle/mem_categorization.rs index 302fbd53dd530..d96cf4495bdde 100644 --- a/src/librustc/middle/mem_categorization.rs +++ b/src/librustc/middle/mem_categorization.rs @@ -1142,12 +1142,11 @@ impl<'t,'tcx,TYPER:Typer<'tcx>> MemCategorizationContext<'t,TYPER> { }) } + // FIXME(#19596) unbox `op` pub fn cat_pattern(&self, cmt: cmt<'tcx>, pat: &ast::Pat, - op: |&MemCategorizationContext<'t,TYPER>, - cmt<'tcx>, - &ast::Pat|) + op: |&MemCategorizationContext<'t, TYPER>, cmt<'tcx>, &ast::Pat|) -> McResult<()> { // Here, `cmt` is the categorization for the value being // matched and pat is the pattern it is being matched against. diff --git a/src/librustc/middle/pat_util.rs b/src/librustc/middle/pat_util.rs index 8d4fbfd4cbccc..8ef8e091c9485 100644 --- a/src/librustc/middle/pat_util.rs +++ b/src/librustc/middle/pat_util.rs @@ -91,9 +91,9 @@ pub fn pat_is_binding_or_wild(dm: &resolve::DefMap, pat: &ast::Pat) -> bool { /// Call `it` on every "binding" in a pattern, e.g., on `a` in /// `match foo() { Some(a) => (), None => () }` -pub fn pat_bindings(dm: &resolve::DefMap, - pat: &ast::Pat, - it: |ast::BindingMode, ast::NodeId, Span, &ast::SpannedIdent|) { +pub fn pat_bindings(dm: &resolve::DefMap, pat: &ast::Pat, mut it: I) where + I: FnMut(ast::BindingMode, ast::NodeId, Span, &ast::SpannedIdent), +{ walk_pat(pat, |p| { match p.node { ast::PatIdent(binding_mode, ref pth, _) if pat_is_binding(dm, p) => { diff --git a/src/librustc/middle/region.rs b/src/librustc/middle/region.rs index 370097004e92c..390729df0125d 100644 --- a/src/librustc/middle/region.rs +++ b/src/librustc/middle/region.rs @@ -62,7 +62,9 @@ impl CodeExtent { /// Maps this scope to a potentially new one according to the /// NodeId transformer `f_id`. - pub fn map_id(&self, f_id: |ast::NodeId| -> ast::NodeId) -> CodeExtent { + pub fn map_id(&self, f_id: F) -> CodeExtent where + F: FnOnce(ast::NodeId) -> ast::NodeId, + { match *self { CodeExtent::Misc(node_id) => CodeExtent::Misc(f_id(node_id)), } diff --git a/src/librustc/middle/resolve.rs b/src/librustc/middle/resolve.rs index 2899f60f736af..85e0c9294a6ba 100644 --- a/src/librustc/middle/resolve.rs +++ b/src/librustc/middle/resolve.rs @@ -1837,10 +1837,12 @@ impl<'a> Resolver<'a> { } /// Constructs the reduced graph for one foreign item. - fn build_reduced_graph_for_foreign_item(&mut self, - foreign_item: &ForeignItem, - parent: ReducedGraphParent, - f: |&mut Resolver|) { + fn build_reduced_graph_for_foreign_item(&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, f: |&mut Resolver|) { + fn with_scope(&mut self, name: Option, 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(&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(&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(&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(&mut self, self_type: &Ty, f: |&mut Resolver| -> T) -> T { + fn with_current_self_type(&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(&mut self, id: NodeId, - opt_trait_ref: &Option, - f: |&mut Resolver| -> T) -> T { + fn with_optional_trait_ref(&mut self, id: NodeId, + opt_trait_ref: &Option, + 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(&mut self, f: |&mut Resolver| -> T) -> T { + fn with_no_errors(&mut self, f: F) -> T where + F: FnOnce(&mut Resolver) -> T, + { self.emit_errors = false; let rs = f(self); self.emit_errors = true; diff --git a/src/librustc/middle/resolve_lifetime.rs b/src/librustc/middle/resolve_lifetime.rs index 3ab94d3ca6619..83332d275ce99 100644 --- a/src/librustc/middle/resolve_lifetime.rs +++ b/src/librustc/middle/resolve_lifetime.rs @@ -247,7 +247,9 @@ impl<'a, 'v> Visitor<'v> for LifetimeContext<'a> { } impl<'a> LifetimeContext<'a> { - fn with(&mut self, wrap_scope: ScopeChain, f: |&mut LifetimeContext|) { + fn with(&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(&mut self, + early_space: subst::ParamSpace, + generics: &ast::Generics, + walk: F) where + F: FnOnce(&mut LifetimeContext), + { let referenced_idents = early_bound_lifetime_names(generics); debug!("visit_early_late: referenced_idents={}", @@ -290,8 +294,8 @@ impl<'a> LifetimeContext<'a> { let (early, late) = generics.lifetimes.clone().partition( |l| referenced_idents.iter().any(|&i| i == l.lifetime.name)); - self.with(EarlyScope(early_space, &early, self.scope), |this| { - this.with(LateScope(&late, this.scope), |this| { + self.with(EarlyScope(early_space, &early, self.scope), move |this| { + this.with(LateScope(&late, this.scope), move |this| { this.check_lifetime_defs(&generics.lifetimes); walk(this); }); diff --git a/src/librustc/middle/stability.rs b/src/librustc/middle/stability.rs index 994fe2e9e27c4..ca8029fdfca3b 100644 --- a/src/librustc/middle/stability.rs +++ b/src/librustc/middle/stability.rs @@ -43,7 +43,9 @@ struct Annotator { impl Annotator { // Determine the stability for a node based on its attributes and inherited // stability. The stability is recorded in the index and used as the parent. - fn annotate(&mut self, id: NodeId, attrs: &Vec, f: |&mut Annotator|) { + fn annotate(&mut self, id: NodeId, attrs: &Vec, 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 d3b1c2d2afc4d..2098aa3db533a 100644 --- a/src/librustc/middle/subst.rs +++ b/src/librustc/middle/subst.rs @@ -167,10 +167,9 @@ impl<'tcx> Substs<'tcx> { } impl RegionSubsts { - fn map(self, - a: A, - op: |VecPerParamSpace, A| -> VecPerParamSpace) - -> RegionSubsts { + fn map(self, a: A, op: F) -> RegionSubsts where + F: FnOnce(VecPerParamSpace, A) -> VecPerParamSpace, + { match self { ErasedRegions => ErasedRegions, NonerasedRegions(r) => NonerasedRegions(op(r, a)) @@ -415,16 +414,18 @@ impl VecPerParamSpace { self.content.as_slice() } - pub fn all_vecs(&self, pred: |&[T]| -> bool) -> bool { + pub fn all_vecs

(&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

(&self, pred: P) -> bool where P: FnMut(&T) -> bool { self.iter().all(pred) } - pub fn any(&self, pred: |&T| -> bool) -> bool { + pub fn any

(&self, pred: P) -> bool where P: FnMut(&T) -> bool { self.iter().any(pred) } @@ -432,7 +433,7 @@ impl VecPerParamSpace { self.all_vecs(|v| v.is_empty()) } - pub fn map(&self, pred: |&T| -> U) -> VecPerParamSpace { + pub fn map(&self, pred: P) -> VecPerParamSpace where P: FnMut(&T) -> U { let result = self.iter().map(pred).collect(); VecPerParamSpace::new_internal(result, self.type_limit, @@ -440,7 +441,9 @@ impl VecPerParamSpace { self.assoc_limit) } - pub fn map_enumerated(&self, pred: |(ParamSpace, uint, &T)| -> U) -> VecPerParamSpace { + pub fn map_enumerated(&self, pred: P) -> VecPerParamSpace 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 VecPerParamSpace { self.assoc_limit) } - pub fn map_move(self, pred: |T| -> U) -> VecPerParamSpace { + pub fn map_move(self, mut pred: F) -> VecPerParamSpace 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 604a0607c0b4c..936304c5eb483 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(&self, op: |&N| -> M) -> Vtable<'tcx, M> { + pub fn map_nested(&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(self, op: |N| -> M) -> Vtable<'tcx, M> { + pub fn map_move_nested(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(&self, - op: |&N| -> M) - -> VtableImplData<'tcx, M> + pub fn map_nested(&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(self, op: |N| -> M) - -> VtableImplData<'tcx, M> { + pub fn map_move_nested(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 VtableBuiltinData { self.nested.iter() } - pub fn map_nested(&self, - op: |&N| -> M) - -> VtableBuiltinData - { + pub fn map_nested(&self, op: F) -> VtableBuiltinData where F: FnMut(&N) -> M { VtableBuiltinData { nested: self.nested.map(op) } } - pub fn map_move_nested(self, op: |N| -> M) -> VtableBuiltinData { + pub fn map_move_nested(self, op: F) -> VtableBuiltinData where + F: FnMut(N) -> M, + { VtableBuiltinData { nested: self.nested.map_move(op) } diff --git a/src/librustc/middle/traits/util.rs b/src/librustc/middle/traits/util.rs index 52154e0be7ad0..d8956246d326f 100644 --- a/src/librustc/middle/traits/util.rs +++ b/src/librustc/middle/traits/util.rs @@ -306,10 +306,11 @@ pub fn predicate_for_builtin_bound<'tcx>( /// of caller obligations), search through the trait and supertraits to find one where `test(d)` is /// true, where `d` is the def-id of the trait/supertrait. If any is found, return `Some(p)` where /// `p` is the path to that trait/supertrait. Else `None`. -pub fn search_trait_and_supertraits_from_bound<'tcx>(tcx: &ty::ctxt<'tcx>, - caller_bound: Rc>, - test: |ast::DefId| -> bool) - -> Option> +pub fn search_trait_and_supertraits_from_bound<'tcx, F>(tcx: &ty::ctxt<'tcx>, + caller_bound: Rc>, + mut test: F) + -> Option> 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 ddbf69685cd91..8e99045cffb58 100644 --- a/src/librustc/middle/ty.rs +++ b/src/librustc/middle/ty.rs @@ -2420,10 +2420,13 @@ pub fn mk_param_from_def<'tcx>(cx: &ctxt<'tcx>, def: &TypeParameterDef) -> Ty<'t pub fn mk_open<'tcx>(cx: &ctxt<'tcx>, ty: Ty<'tcx>) -> Ty<'tcx> { mk_t(cx, ty_open(ty)) } -pub fn walk_ty<'tcx>(ty: Ty<'tcx>, f: |Ty<'tcx>|) { +pub fn walk_ty<'tcx, F>(ty: Ty<'tcx>, mut f: F) where + F: FnMut(Ty<'tcx>), +{ maybe_walk_ty(ty, |ty| { f(ty); true }); } +// FIXME(#19596) unbox `f` pub fn maybe_walk_ty<'tcx>(ty: Ty<'tcx>, f: |Ty<'tcx>| -> bool) { if !f(ty) { return; @@ -2464,9 +2467,11 @@ pub fn maybe_walk_ty<'tcx>(ty: Ty<'tcx>, f: |Ty<'tcx>| -> bool) { } // Folds types from the bottom up. -pub fn fold_ty<'tcx>(cx: &ctxt<'tcx>, t0: Ty<'tcx>, - fldop: |Ty<'tcx>| -> Ty<'tcx>) - -> Ty<'tcx> { +pub fn fold_ty<'tcx, F>(cx: &ctxt<'tcx>, t0: Ty<'tcx>, + fldop: F) + -> Ty<'tcx> where + F: FnMut(Ty<'tcx>) -> Ty<'tcx>, +{ let mut f = ty_fold::BottomUpFolder {tcx: cx, fldop: fldop}; f.fold_ty(t0) } @@ -2843,7 +2848,9 @@ impl TypeContents { *self & TC::ReachesAll } - pub fn union(v: &[T], f: |&T| -> TypeContents) -> TypeContents { + pub fn union(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>], - f: |BuiltinBound|) { + fn each_inherited_builtin_bound<'tcx, F>(cx: &ctxt<'tcx>, + bounds: BuiltinBounds, + traits: &[Rc>], + 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> { - +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>, +{ 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( - descr: &str, - def_id: ast::DefId, - map: &mut DefIdMap, - load_external: || -> V) -> V { +fn lookup_locally_or_in_crate_store(descr: &str, + def_id: ast::DefId, + map: &mut DefIdMap, + 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(cx: &ctxt, id: ast::DefId, f: |ast_map::PathElems| -> T) -> T { +pub fn with_path(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(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>], - f: |Rc>| -> bool) - -> bool +pub fn each_bound_trait_and_supertraits<'tcx, F>(tcx: &ctxt<'tcx>, + bounds: &[Rc>], + mut f: F) + -> bool where + F: FnMut(Rc>) -> bool, { for bound_trait_ref in traits::transitive_bounds(tcx, bounds) { if !f(bound_trait_ref) { @@ -6192,7 +6209,9 @@ pub type FreevarMap = NodeMap>; pub type CaptureModeMap = NodeMap; -pub fn with_freevars(tcx: &ty::ctxt, fid: ast::NodeId, f: |&[Freevar]| -> T) -> T { +pub fn with_freevars(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) - where HR : HigherRankedFoldable<'tcx> + mut mapf: F) +-> (HR, FnvHashMap) where + HR : HigherRankedFoldable<'tcx>, + F: FnMut(BoundRegion, DebruijnIndex) -> ty::Region, { debug!("replace_late_bound_regions({})", value.repr(tcx)); diff --git a/src/librustc/middle/ty_fold.rs b/src/librustc/middle/ty_fold.rs index 8b54a46bfb934..63ee71dc6a51a 100644 --- a/src/librustc/middle/ty_fold.rs +++ b/src/librustc/middle/ty_fold.rs @@ -743,12 +743,14 @@ impl<'tcx, T:HigherRankedFoldable<'tcx>> HigherRankedFoldable<'tcx> for Rc { /////////////////////////////////////////////////////////////////////////// // 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 e4d34e09d330a..8516ece202c75 100644 --- a/src/librustc/session/mod.rs +++ b/src/librustc/session/mod.rs @@ -288,7 +288,9 @@ pub fn build_session_(sopts: config::Options, } // Seems out of place, but it uses session, so I'm putting it here -pub fn expect(sess: &Session, opt: Option, msg: || -> String) -> T { +pub fn expect(sess: &Session, opt: Option, 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 30318cc129cac..51e18c80d0584 100644 --- a/src/librustc/util/common.rs +++ b/src/librustc/util/common.rs @@ -27,7 +27,9 @@ pub struct ErrorReported; impl Copy for ErrorReported {} -pub fn time(do_it: bool, what: &str, u: U, f: |U| -> T) -> T { +pub fn time(do_it: bool, what: &str, u: U, f: F) -> T where + F: FnOnce(U) -> T, +{ thread_local!(static DEPTH: Cell = Cell::new(0)); if !do_it { return f(u); } @@ -39,9 +41,13 @@ pub fn time(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(do_it: bool, what: &str, u: U, f: |U| -> T) -> T { rv } -pub fn indent(op: || -> R) -> R { +pub fn indent(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

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

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

(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

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

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

(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,T:Eq+Clone+Hash>( /// } /// ``` #[inline(always)] -pub fn memoized + Eq, U: Clone, S, H: Hasher>( - cache: &RefCell>, - arg: T, - f: |T| -> U -) -> U { +pub fn memoized(cache: &RefCell>, arg: T, f: F) -> U where + T: Clone + Hash + Eq, + U: Clone, + H: Hasher, + 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 7a14ed9cca8c9..5dbf3208595ed 100644 --- a/src/librustc/util/ppaux.rs +++ b/src/librustc/util/ppaux.rs @@ -241,7 +241,9 @@ pub fn trait_store_to_string(cx: &ctxt, s: ty::TraitStore) -> String { } } -pub fn vec_map_to_string(ts: &[T], f: |t: &T| -> String) -> String { +pub fn vec_map_to_string(ts: &[T], f: F) -> String where + F: FnMut(&T) -> String, +{ let tstrs = ts.iter().map(f).collect::>(); format!("[{}]", tstrs.connect(", ")) } diff --git a/src/librustc_back/archive.rs b/src/librustc_back/archive.rs index a88bcafaa64b3..3a4510703166c 100644 --- a/src/librustc_back/archive.rs +++ b/src/librustc_back/archive.rs @@ -279,8 +279,9 @@ impl<'a> ArchiveBuilder<'a> { self.archive } - fn add_archive(&mut self, archive: &Path, name: &str, - skip: |&str| -> bool) -> io::IoResult<()> { + fn add_archive(&mut self, archive: &Path, name: &str, mut skip: F) -> io::IoResult<()> where + F: FnMut(&str) -> bool, + { let loc = TempDir::new("rsar").unwrap(); // First, extract the contents of the archive to a temporary directory. diff --git a/src/librustc_back/lib.rs b/src/librustc_back/lib.rs index fc98a5cd6b559..cb547df7d9cd8 100644 --- a/src/librustc_back/lib.rs +++ b/src/librustc_back/lib.rs @@ -31,6 +31,7 @@ #![allow(unknown_features)] #![feature(globs, phase, macro_rules, slicing_syntax)] +#![feature(unboxed_closures)] #[phase(plugin, link)] extern crate log; diff --git a/src/librustc_back/rpath.rs b/src/librustc_back/rpath.rs index a90b49ba101fa..1f8549098d949 100644 --- a/src/librustc_back/rpath.rs +++ b/src/librustc_back/rpath.rs @@ -14,17 +14,22 @@ use std::os; use std::io::IoError; use syntax::ast; -pub struct RPathConfig<'a> { +pub struct RPathConfig where + F: FnOnce() -> Path, + G: FnMut(&Path) -> Result, +{ pub used_crates: Vec<(ast::CrateNum, Option)>, 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 + pub get_install_prefix_lib_path: F, + pub realpath: G, } -pub fn get_rpath_flags(config: RPathConfig) -> Vec { - +pub fn get_rpath_flags(config: RPathConfig) -> Vec where + F: FnOnce() -> Path, + G: FnMut(&Path) -> Result, +{ // No rpath on windows if !config.has_rpath { return Vec::new(); @@ -52,8 +57,10 @@ fn rpaths_to_flags(rpaths: &[String]) -> Vec { return ret; } -fn get_rpaths(mut config: RPathConfig, - libs: &[Path]) -> Vec { +fn get_rpaths(mut config: RPathConfig, libs: &[Path]) -> Vec where + F: FnOnce() -> Path, + G: FnMut(&Path) -> Result, +{ 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 { +fn get_rpaths_relative_to_output(config: &mut RPathConfig, + libs: &[Path]) -> Vec where + F: FnOnce() -> Path, + G: FnMut(&Path) -> Result, +{ 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(config: &mut RPathConfig, lib: &Path) -> String where + F: FnOnce() -> Path, + G: FnMut(&Path) -> Result, +{ 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(config: RPathConfig) -> String where + F: FnOnce() -> Path, + G: FnMut(&Path) -> Result, +{ let path = (config.get_install_prefix_lib_path)(); let path = os::make_absolute(&path).unwrap(); // FIXME (#9639): This needs to handle non-utf8 paths diff --git a/src/librustc_back/sha2.rs b/src/librustc_back/sha2.rs index 1b662ef178760..1587104ca49d1 100644 --- a/src/librustc_back/sha2.rs +++ b/src/librustc_back/sha2.rs @@ -82,7 +82,8 @@ fn add_bytes_to_bits(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(&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(&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(&mut self, rem: uint, func: F) where F: FnMut(&[u8]); } impl StandardPadding for T { - fn standard_padding(&mut self, rem: uint, func: |&[u8]|) { + fn standard_padding(&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 4244cec7534d5..3bf817b42b06d 100644 --- a/src/librustc_borrowck/borrowck/check_loans.rs +++ b/src/librustc_borrowck/borrowck/check_loans.rs @@ -232,8 +232,9 @@ fn compatible_borrow_kinds(borrow_kind1: ty::BorrowKind, impl<'a, 'tcx> CheckLoanCtxt<'a, 'tcx> { pub fn tcx(&self) -> &'a ty::ctxt<'tcx> { self.bccx.tcx } - pub fn each_issued_loan(&self, scope: region::CodeExtent, op: |&Loan<'tcx>| -> bool) - -> bool { + pub fn each_issued_loan(&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(&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(&self, + scope: region::CodeExtent, + loan_path: &LoanPath<'tcx>, + mut op: F) + -> bool where + F: FnMut(&Loan<'tcx>) -> bool, + { //! Iterates through all of the in-scope loans affecting `loan_path`, //! calling `op`, and ceasing iteration if `false` is returned. diff --git a/src/librustc_borrowck/borrowck/move_data.rs b/src/librustc_borrowck/borrowck/move_data.rs index 681a5772849f3..00b1377af7304 100644 --- a/src/librustc_borrowck/borrowck/move_data.rs +++ b/src/librustc_borrowck/borrowck/move_data.rs @@ -523,8 +523,9 @@ impl<'tcx> MoveData<'tcx> { } } - fn each_base_path(&self, index: MovePathIndex, f: |MovePathIndex| -> bool) - -> bool { + fn each_base_path(&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(&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>, - f: |&Move, &LoanPath<'tcx>| -> bool) - -> bool { + pub fn each_move_of(&self, + id: ast::NodeId, + loan_path: &Rc>, + 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>, - f: |&Assignment| -> bool) - -> bool { + pub fn each_assignment_of(&self, + id: ast::NodeId, + loan_path: &Rc>, + mut f: F) + -> bool where + F: FnMut(&Assignment) -> bool, + { let loan_path_index = { match self.move_data.existing_move_path(loan_path) { Some(i) => i, diff --git a/src/librustc_borrowck/graphviz.rs b/src/librustc_borrowck/graphviz.rs index 36c74720be438..e09ec79166997 100644 --- a/src/librustc_borrowck/graphviz.rs +++ b/src/librustc_borrowck/graphviz.rs @@ -75,11 +75,13 @@ impl<'a, 'tcx> DataflowLabeller<'a, 'tcx> { } } - fn build_set(&self, - e: EntryOrExit, - cfgidx: CFGIndex, - dfcx: &DataFlowContext<'a, 'tcx, O>, - to_lp: |uint| -> Rc>) -> String { + fn build_set(&self, + e: EntryOrExit, + cfgidx: CFGIndex, + dfcx: &DataFlowContext<'a, 'tcx, O>, + mut to_lp: F) -> String where + F: FnMut(uint) -> Rc>, + { 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 f187c0c15300d..db19a09deba3a 100644 --- a/src/librustc_borrowck/lib.rs +++ b/src/librustc_borrowck/lib.rs @@ -19,6 +19,7 @@ #![feature(default_type_params, globs, if_let, import_shadowing, macro_rules, phase, quote)] #![feature(slicing_syntax, tuple_indexing, unsafe_destructor)] #![feature(rustc_diagnostic_macros)] +#![feature(unboxed_closures)] #![allow(non_camel_case_types)] #[phase(plugin, link)] extern crate log; diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs index 85d9646c28211..d655b70405309 100644 --- a/src/librustc_driver/lib.rs +++ b/src/librustc_driver/lib.rs @@ -25,6 +25,7 @@ #![feature(default_type_params, globs, import_shadowing, macro_rules, phase, quote)] #![feature(slicing_syntax, unsafe_destructor)] #![feature(rustc_diagnostic_macros)] +#![feature(unboxed_closures)] extern crate arena; extern crate flate; diff --git a/src/librustc_driver/pretty.rs b/src/librustc_driver/pretty.rs index 971379b8dd296..7ec05b6a0306e 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(from_str); + let opt_second = opt_second.and_then::(from_str); (first, opt_second) } @@ -99,13 +99,15 @@ pub fn parse_pretty(sess: &Session, name: &str) -> (PpMode, Option(&self, - sess: Session, - ast_map: Option>, - type_arena: &'tcx TypedArena>, - id: String, - payload: B, - f: |&PrinterSupport, B| -> A) -> A { + fn call_with_pp_support<'tcx, A, B, F>(&self, + sess: Session, + ast_map: Option>, + type_arena: &'tcx TypedArena>, + 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 { - 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 9404802cb681b..dda3754cf7371 100644 --- a/src/librustc_driver/test.rs +++ b/src/librustc_driver/test.rs @@ -93,9 +93,11 @@ fn errors(msgs: &[&str]) -> (Box, uint) { (box ExpectErrorEmitter { messages: v } as Box, msgs.len()) } -fn test_env(source_string: &str, - (emitter, expected_err_count): (Box, uint), - body: |Env|) { +fn test_env(source_string: &str, + (emitter, expected_err_count): (Box, 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 23dad21e5303f..7d8338ba976dd 100644 --- a/src/librustc_llvm/lib.rs +++ b/src/librustc_llvm/lib.rs @@ -23,6 +23,7 @@ #![feature(globs)] #![feature(link_args)] +#![feature(unboxed_closures)] extern crate libc; @@ -2206,7 +2207,7 @@ pub unsafe extern "C" fn rust_llvm_string_write_impl(sr: RustStringRef, (*sr).borrow_mut().push_all(slice); } -pub fn build_string(f: |RustStringRef|) -> Option { +pub fn build_string(f: F) -> Option 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 62f8177ed758d..5617110bfecf7 100644 --- a/src/librustc_trans/back/link.rs +++ b/src/librustc_trans/back/link.rs @@ -1002,7 +1002,7 @@ fn link_args(cmd: &mut Command, if sess.opts.cg.rpath { let sysroot = sess.sysroot(); let target_triple = sess.opts.target_triple.as_slice(); - let get_install_prefix_lib_path = || { + let get_install_prefix_lib_path = |:| { let install_prefix = option_env!("CFG_PREFIX").expect("CFG_PREFIX"); let tlib = filesearch::relative_target_lib_path(sysroot, target_triple); let mut path = Path::new(install_prefix); diff --git a/src/librustc_trans/back/lto.rs b/src/librustc_trans/back/lto.rs index a715849ddf62f..fb4d6de5f282c 100644 --- a/src/librustc_trans/back/lto.rs +++ b/src/librustc_trans/back/lto.rs @@ -81,8 +81,9 @@ pub fn run(sess: &session::Session, llmod: ModuleRef, break; }, }; - let bc_extractor = if is_versioned_bytecode_format(bc_encoded) { - |_| { + + let bc_decoded = if is_versioned_bytecode_format(bc_encoded) { + time(sess.time_passes(), format!("decode {}.{}.bc", file, i).as_slice(), (), |_| { // Read the version let version = extract_bytecode_format_version(bc_encoded); @@ -104,11 +105,11 @@ pub fn run(sess: &session::Session, llmod: ModuleRef, sess.fatal(format!("Unsupported bytecode format version {}", version).as_slice()) } - } + }) } else { + time(sess.time_passes(), format!("decode {}.{}.bc", file, i).as_slice(), (), |_| { // the object must be in the old, pre-versioning format, so simply // inflate everything and let LLVM decide if it can make sense of it - |_| { match flate::inflate_bytes(bc_encoded) { Some(bc) => bc, None => { @@ -116,14 +117,9 @@ pub fn run(sess: &session::Session, llmod: ModuleRef, name).as_slice()) } } - } + }) }; - let bc_decoded = time(sess.time_passes(), - format!("decode {}.{}.bc", file, i).as_slice(), - (), - bc_extractor); - let ptr = bc_decoded.as_slice().as_ptr(); debug!("linking {}, part {}", name, i); time(sess.time_passes(), diff --git a/src/librustc_trans/back/write.rs b/src/librustc_trans/back/write.rs index 0ed6ae311711f..c52f31532dcd0 100644 --- a/src/librustc_trans/back/write.rs +++ b/src/librustc_trans/back/write.rs @@ -488,8 +488,12 @@ unsafe fn optimize_and_codegen(cgcx: &CodegenContext, // pass manager passed to the closure should be ensured to not // escape the closure itself, and the manager should only be // used once. - unsafe fn with_codegen(tm: TargetMachineRef, llmod: ModuleRef, - no_builtins: bool, f: |PassManagerRef|) { + unsafe fn with_codegen(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 2421b39b8bb15..05b1a86b72b05 100644 --- a/src/librustc_trans/lib.rs +++ b/src/librustc_trans/lib.rs @@ -25,6 +25,7 @@ #![feature(default_type_params, globs, import_shadowing, macro_rules, phase, quote)] #![feature(slicing_syntax, unsafe_destructor)] #![feature(rustc_diagnostic_macros)] +#![feature(unboxed_closures)] extern crate arena; extern crate flate; diff --git a/src/librustc_trans/save/mod.rs b/src/librustc_trans/save/mod.rs index 2a698a898fe87..329241b24e652 100644 --- a/src/librustc_trans/save/mod.rs +++ b/src/librustc_trans/save/mod.rs @@ -79,7 +79,9 @@ struct DxrVisitor<'l, 'tcx: 'l> { } impl <'l, 'tcx> DxrVisitor<'l, 'tcx> { - fn nest(&mut self, scope_id: NodeId, f: |&mut DxrVisitor<'l, 'tcx>|) { + fn nest(&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 1ed06938e95c8..b051292571980 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 { } }; - 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 e273a56ce025b..991333d8f07dd 100644 --- a/src/librustc_trans/trans/adt.rs +++ b/src/librustc_trans/trans/adt.rs @@ -858,10 +858,13 @@ pub fn struct_field_ptr<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, st: &Struct<'tcx>, v GEPi(bcx, val, &[0, ix]) } -pub fn fold_variants<'blk, 'tcx>( - bcx: Block<'blk, 'tcx>, r: &Repr<'tcx>, value: ValueRef, - f: |Block<'blk, 'tcx>, &Struct<'tcx>, ValueRef| -> Block<'blk, 'tcx>) - -> Block<'blk, 'tcx> { +pub fn fold_variants<'blk, 'tcx, F>(bcx: Block<'blk, 'tcx>, + r: &Repr<'tcx>, + value: ValueRef, + mut f: F) + -> Block<'blk, 'tcx> where + F: FnMut(Block<'blk, 'tcx>, &Struct<'tcx>, ValueRef) -> Block<'blk, 'tcx>, +{ let fcx = bcx.fcx; match *r { Univariant(ref st, _) => { diff --git a/src/librustc_trans/trans/base.rs b/src/librustc_trans/trans/base.rs index cef12616cf267..5170746404e01 100644 --- a/src/librustc_trans/trans/base.rs +++ b/src/librustc_trans/trans/base.rs @@ -107,9 +107,11 @@ thread_local!(static TASK_LOCAL_INSN_KEY: RefCell>> = { 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(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(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 b55c268d9a909..dca106a3897fb 100644 --- a/src/librustc_trans/trans/basic_block.rs +++ b/src/librustc_trans/trans/basic_block.rs @@ -17,7 +17,12 @@ pub struct BasicBlock(pub BasicBlockRef); impl Copy for BasicBlock {} -pub type Preds<'a> = Map<'a, Value, BasicBlock, Filter<'a, Value, Users>>; +pub type Preds = Map< + Value, + BasicBlock, + Filter 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 { diff --git a/src/librustc_trans/trans/cabi_x86_64.rs b/src/librustc_trans/trans/cabi_x86_64.rs index 00c91ddebb38e..4a6bc58051c57 100644 --- a/src/librustc_trans/trans/cabi_x86_64.rs +++ b/src/librustc_trans/trans/cabi_x86_64.rs @@ -342,11 +342,13 @@ pub fn compute_abi_info(ccx: &CrateContext, atys: &[Type], rty: Type, ret_def: bool) -> FnType { - fn x86_64_ty(ccx: &CrateContext, - ty: Type, - is_mem_cls: |cls: &[RegClass]| -> bool, - ind_attr: Attribute) - -> ArgType { + fn x86_64_ty(ccx: &CrateContext, + ty: Type, + is_mem_cls: F, + ind_attr: Attribute) + -> ArgType where + F: FnOnce(&[RegClass]) -> bool, + { if !ty.is_reg_ty() { let cls = classify_ty(ty); if is_mem_cls(cls.as_slice()) { diff --git a/src/librustc_trans/trans/callee.rs b/src/librustc_trans/trans/callee.rs index ff7ab91c39a58..b8b2395dde172 100644 --- a/src/librustc_trans/trans/callee.rs +++ b/src/librustc_trans/trans/callee.rs @@ -781,15 +781,15 @@ pub fn trans_lang_call<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, /// /// For non-lang items, `dest` is always Some, and hence the result is written into memory /// somewhere. Nonetheless we return the actual return value of the function. -pub fn trans_call_inner<'a, 'blk, 'tcx>(bcx: Block<'blk, 'tcx>, - call_info: Option, - callee_ty: Ty<'tcx>, - get_callee: |bcx: Block<'blk, 'tcx>, - arg_cleanup_scope: cleanup::ScopeId| - -> Callee<'blk, 'tcx>, - args: CallArgs<'a, 'tcx>, - dest: Option) - -> Result<'blk, 'tcx> { +pub fn trans_call_inner<'a, 'blk, 'tcx, F>(bcx: Block<'blk, 'tcx>, + call_info: Option, + callee_ty: Ty<'tcx>, + get_callee: F, + args: CallArgs<'a, 'tcx>, + dest: Option) + -> Result<'blk, 'tcx> where + F: FnOnce(Block<'blk, 'tcx>, cleanup::ScopeId) -> Callee<'blk, 'tcx>, +{ // Introduce a temporary cleanup scope that will contain cleanups // for the arguments while they are being evaluated. The purpose // this cleanup is to ensure that, should a panic occur while diff --git a/src/librustc_trans/trans/cleanup.rs b/src/librustc_trans/trans/cleanup.rs index ba3e70fe036fc..2fd6551409e90 100644 --- a/src/librustc_trans/trans/cleanup.rs +++ b/src/librustc_trans/trans/cleanup.rs @@ -527,7 +527,7 @@ impl<'blk, 'tcx> CleanupHelperMethods<'blk, 'tcx> for FunctionContext<'blk, 'tcx self.scopes.borrow_mut().pop().unwrap() } - fn top_scope(&self, f: |&CleanupScope<'blk, 'tcx>| -> R) -> R { + fn top_scope(&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(&self, f: |&CleanupScope<'blk, 'tcx>| -> R) -> R; + fn top_scope(&self, f: F) -> R where F: FnOnce(&CleanupScope<'blk, 'tcx>) -> R; } diff --git a/src/librustc_trans/trans/datum.rs b/src/librustc_trans/trans/datum.rs index edcc8edaf7f92..531b22c8fb5f2 100644 --- a/src/librustc_trans/trans/datum.rs +++ b/src/librustc_trans/trans/datum.rs @@ -113,15 +113,16 @@ pub fn immediate_rvalue_bcx<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, /// it. The memory will be dropped upon exit from `scope`. The callback `populate` should /// initialize the memory. If `zero` is true, the space will be zeroed when it is allocated; this /// is not necessary unless `bcx` does not dominate the end of `scope`. -pub fn lvalue_scratch_datum<'blk, 'tcx, A>(bcx: Block<'blk, 'tcx>, - ty: Ty<'tcx>, - name: &str, - zero: bool, - scope: cleanup::ScopeId, - arg: A, - populate: |A, Block<'blk, 'tcx>, ValueRef| - -> Block<'blk, 'tcx>) - -> DatumBlock<'blk, 'tcx, Lvalue> { +pub fn lvalue_scratch_datum<'blk, 'tcx, A, F>(bcx: Block<'blk, 'tcx>, + ty: Ty<'tcx>, + name: &str, + zero: bool, + scope: cleanup::ScopeId, + arg: A, + populate: F) + -> DatumBlock<'blk, 'tcx, Lvalue> where + F: FnOnce(A, Block<'blk, 'tcx>, ValueRef) -> Block<'blk, 'tcx>, +{ let scratch = if zero { alloca_zeroed(bcx, ty, name) } else { @@ -339,10 +340,10 @@ impl<'tcx> Datum<'tcx, Rvalue> { /// here since we can `match self.kind` rather than having to implement /// generic methods in `KindOps`.) impl<'tcx> Datum<'tcx, Expr> { - fn match_kind(self, - if_lvalue: |Datum<'tcx, Lvalue>| -> R, - if_rvalue: |Datum<'tcx, Rvalue>| -> R) - -> R { + fn match_kind(self, if_lvalue: F, if_rvalue: G) -> R where + F: FnOnce(Datum<'tcx, Lvalue>) -> R, + G: FnOnce(Datum<'tcx, Rvalue>) -> R, + { let Datum { val, ty, kind } = self; match kind { LvalueExpr => if_lvalue(Datum::new(val, ty, Lvalue)), @@ -455,9 +456,11 @@ impl<'tcx> Datum<'tcx, Lvalue> { // datum may also be unsized _without the size information_. It is the // callers responsibility to package the result in some way to make a valid // datum in that case (e.g., by making a fat pointer or opened pair). - pub fn get_element<'blk>(&self, bcx: Block<'blk, 'tcx>, ty: Ty<'tcx>, - gep: |ValueRef| -> ValueRef) - -> Datum<'tcx, Lvalue> { + pub fn get_element<'blk, F>(&self, bcx: Block<'blk, 'tcx>, ty: Ty<'tcx>, + gep: F) + -> Datum<'tcx, Lvalue> where + F: FnOnce(ValueRef) -> ValueRef, + { let val = match self.ty.sty { _ if ty::type_is_sized(bcx.tcx(), self.ty) => gep(self.val), ty::ty_open(_) => { diff --git a/src/librustc_trans/trans/debuginfo.rs b/src/librustc_trans/trans/debuginfo.rs index f6c4ba64576f7..de169fc9d62a6 100644 --- a/src/librustc_trans/trans/debuginfo.rs +++ b/src/librustc_trans/trans/debuginfo.rs @@ -3212,13 +3212,13 @@ fn populate_scope_map(cx: &CrateContext, }); // local helper functions for walking the AST. - fn with_new_scope(cx: &CrateContext, - scope_span: Span, - scope_stack: &mut Vec , - scope_map: &mut NodeMap, - inner_walk: |&CrateContext, - &mut Vec , - &mut NodeMap|) { + fn with_new_scope(cx: &CrateContext, + scope_span: Span, + scope_stack: &mut Vec , + scope_map: &mut NodeMap, + inner_walk: F) where + F: FnOnce(&CrateContext, &mut Vec, &mut NodeMap), + { // Create a new lexical scope and push it onto the stack let loc = cx.sess().codemap().lookup_char_pos(scope_span.lo); let file_metadata = file_metadata(cx, loc.file.name.as_slice()); diff --git a/src/librustc_trans/trans/expr.rs b/src/librustc_trans/trans/expr.rs index e3e6fff723410..e1769001942d5 100644 --- a/src/librustc_trans/trans/expr.rs +++ b/src/librustc_trans/trans/expr.rs @@ -295,6 +295,7 @@ fn apply_adjustments<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, // into a type to be destructed. If we want to end up with a Box pointer, // then mk_ty should make a Box pointer (T -> Box), 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, - 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, + 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 9eb0e17b8e5be..980097eaead99 100644 --- a/src/librustc_typeck/check/demand.rs +++ b/src/librustc_typeck/check/demand.rs @@ -28,12 +28,14 @@ pub fn suptype<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>, sp: Span, |sp, e, a, s| { fcx.report_mismatched_types(sp, e, a, s) }) } -pub fn suptype_with_fn<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>, - sp: Span, - b_is_expected: bool, - ty_a: Ty<'tcx>, - ty_b: Ty<'tcx>, - handle_err: |Span, Ty<'tcx>, Ty<'tcx>, &ty::type_err<'tcx>|) { +pub fn suptype_with_fn<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>, + sp: Span, + b_is_expected: bool, + ty_a: Ty<'tcx>, + ty_b: Ty<'tcx>, + handle_err: F) where + F: FnOnce(Span, Ty<'tcx>, Ty<'tcx>, &ty::type_err<'tcx>), +{ // n.b.: order of actual, expected is reversed match infer::mk_subty(fcx.infcx(), b_is_expected, infer::Misc(sp), ty_b, ty_a) { diff --git a/src/librustc_typeck/check/method/confirm.rs b/src/librustc_typeck/check/method/confirm.rs index bf1f2c0ce809a..3c7cecc96a320 100644 --- a/src/librustc_typeck/check/method/confirm.rs +++ b/src/librustc_typeck/check/method/confirm.rs @@ -286,11 +286,8 @@ impl<'a,'tcx> ConfirmContext<'a,'tcx> { } } - fn extract_trait_ref(&mut self, - self_ty: Ty<'tcx>, - closure: |&mut ConfirmContext<'a,'tcx>, - Ty<'tcx>, &ty::TyTrait<'tcx>| -> R) - -> R + fn extract_trait_ref(&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>>| -> 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>>) -> ty::AutoRef<'tcx>, +{ let autoref = mem::replace(&mut deref.autoref, None); let autoref = autoref.map(|r| box r); deref.autoref = Some(base_fn(autoref)); diff --git a/src/librustc_typeck/check/method/probe.rs b/src/librustc_typeck/check/method/probe.rs index f0f527f667354..adcfc491dcc4f 100644 --- a/src/librustc_typeck/check/method/probe.rs +++ b/src/librustc_typeck/check/method/probe.rs @@ -710,10 +710,12 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> { mutbl: m })) } - fn search_mutabilities(&mut self, - mk_adjustment: |ast::Mutability| -> PickAdjustment, - mk_autoref_ty: |ast::Mutability, ty::Region| -> Ty<'tcx>) - -> Option> + fn search_mutabilities(&mut self, + mut mk_adjustment: F, + mut mk_autoref_ty: G) + -> Option> 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 573c63eb6af05..18a773fb949fc 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -1885,9 +1885,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self.inh.item_substs.borrow() } - pub fn opt_node_ty_substs(&self, - id: ast::NodeId, - f: |&ty::ItemSubsts<'tcx>|) { + pub fn opt_node_ty_substs(&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(&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, - mut lvalue_pref: LvaluePreference, - should_stop: |Ty<'tcx>, uint| -> Option) - -> (Ty<'tcx>, uint, Option) { +pub fn autoderef<'a, 'tcx, T, F>(fcx: &FnCtxt<'a, 'tcx>, sp: Span, + base_ty: Ty<'tcx>, + expr_id: Option, + mut lvalue_pref: LvaluePreference, + mut should_stop: F) + -> (Ty<'tcx>, uint, Option) where + F: FnMut(Ty<'tcx>, uint) -> Option, +{ 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) - -> Option +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 where + F: FnMut(Ty<'tcx>, ty::AutoDerefRef<'tcx>) -> Option, { // 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, - lhs: &'a ast::Expr, - rhs: Option<&P>, - 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, + lhs: &'a ast::Expr, + rhs: Option<&P>, + 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) - -> Option + fn map_to_option<'a, O, F>(self, fcx: &FnCtxt<'a, 'tcx>, unpack: F) -> Option where + F: FnOnce(&ty::sty<'tcx>) -> Option, { match self.resolve(fcx) { NoExpectation => None, diff --git a/src/librustc_typeck/lib.rs b/src/librustc_typeck/lib.rs index 41ed5b8ec3656..32c732c246716 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 173b50dfc5ff0..5623c0f0e535f 100644 --- a/src/librustdoc/fold.rs +++ b/src/librustdoc/fold.rs @@ -79,8 +79,7 @@ pub trait DocFolder { StructVariant(mut j) => { let mut foo = Vec::new(); swap(&mut foo, &mut j.fields); let num_fields = foo.len(); - let c = |x| self.fold_item(x); - j.fields.extend(foo.into_iter().filter_map(c)); + j.fields.extend(foo.into_iter().filter_map(|x| self.fold_item(x))); j.fields_stripped |= num_fields != j.fields.len(); VariantItem(Variant {kind: StructVariant(j), ..i2}) }, diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs index 68ff2ddbcb0e1..051e8a3568fb6 100644 --- a/src/librustdoc/html/format.rs +++ b/src/librustdoc/html/format.rs @@ -218,10 +218,14 @@ fn resolved_path(w: &mut fmt::Formatter, did: ast::DefId, p: &clean::Path, }) } -fn path(w: &mut fmt::Formatter, path: &clean::Path, print_all: bool, - root: |&render::Cache, &[String]| -> Option, - info: |&render::Cache| -> Option<(Vec , ItemType)>) - -> fmt::Result +fn path(w: &mut fmt::Formatter, + path: &clean::Path, + print_all: bool, + root: F, + info: G) + -> fmt::Result where + F: FnOnce(&render::Cache, &[String]) -> Option, + G: FnOnce(&render::Cache) -> Option<(Vec, 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 10563c61e1465..cba58db7c7f73 100644 --- a/src/librustdoc/html/markdown.rs +++ b/src/librustdoc/html/markdown.rs @@ -393,7 +393,7 @@ impl LangString { let mut seen_other_tags = false; let mut data = LangString::all_false(); - let mut tokens = string.split(|c: char| + let mut tokens = string.split(|&: c: char| !(c == '_' || c == '-' || c.is_alphanumeric()) ); diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs index 38bc7d1a3c18d..63b1f5ca0497d 100644 --- a/src/librustdoc/html/render.rs +++ b/src/librustdoc/html/render.rs @@ -646,7 +646,9 @@ fn shortty(item: &clean::Item) -> ItemType { /// static HTML tree. // FIXME (#9639): The closure should deal with &[u8] instead of &str // FIXME (#9639): This is too conservative, rejecting non-UTF-8 paths -fn clean_srcpath(src_root: &Path, src: &[u8], f: |&str|) { +fn clean_srcpath(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(&mut self, s: String, f: |&mut Context| -> T) -> T { + fn recurse(&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(&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 8062916285496..6da7ec40f3472 100644 --- a/src/librustdoc/lib.rs +++ b/src/librustdoc/lib.rs @@ -19,6 +19,7 @@ #![allow(unknown_features)] #![feature(globs, macro_rules, phase, slicing_syntax)] +#![feature(unboxed_closures)] extern crate arena; extern crate getopts; diff --git a/src/librustrt/args.rs b/src/librustrt/args.rs index d94f731e75c64..c1b48e989a1c1 100644 --- a/src/librustrt/args.rs +++ b/src/librustrt/args.rs @@ -89,7 +89,7 @@ mod imp { }) } - fn with_lock(f: || -> T) -> T { + fn with_lock(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 07094f08c5de9..865c1af1d1427 100644 --- a/src/librustrt/c_str.rs +++ b/src/librustrt/c_str.rs @@ -72,6 +72,7 @@ use collections::hash; use core::fmt; use core::kinds::{Sized, marker}; use core::mem; +use core::ops::{FnMut, FnOnce}; use core::prelude::{Clone, Drop, Eq, Iterator}; use core::prelude::{SlicePrelude, None, Option, Ordering, PartialEq}; use core::prelude::{PartialOrd, RawPtr, Some, StrPrelude, range}; @@ -319,14 +320,18 @@ pub trait ToCStr for Sized? { /// /// Panics the task if the receiver has an interior null. #[inline] - fn with_c_str(&self, f: |*const libc::c_char| -> T) -> T { + fn with_c_str(&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(&self, f: |*const libc::c_char| -> T) -> T { + unsafe fn with_c_str_unchecked(&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(&self, f: |*const libc::c_char| -> T) -> T { + fn with_c_str(&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(&self, f: |*const libc::c_char| -> T) -> T { + unsafe fn with_c_str_unchecked(&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(&self, f: |*const libc::c_char| -> T) -> T { + fn with_c_str(&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(&self, f: |*const libc::c_char| -> T) -> T { + unsafe fn with_c_str_unchecked(&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(&self, f: |*const libc::c_char| -> T) -> T { + fn with_c_str(&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(&self, f: |*const libc::c_char| -> T) -> T { + unsafe fn with_c_str_unchecked(&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(&self, f: |*const libc::c_char| -> T) -> T { + fn with_c_str(&self, f: F) -> T where + F: FnOnce(*const libc::c_char) -> T, + { (**self).with_c_str(f) } #[inline] - unsafe fn with_c_str_unchecked(&self, f: |*const libc::c_char| -> T) -> T { + unsafe fn with_c_str_unchecked(&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(v: &[u8], checked: bool, - f: |*const libc::c_char| -> T) -> T { +unsafe fn with_c_str(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 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, - f: |&CString|) -> uint { +pub unsafe fn from_c_multistring(buf: *const libc::c_char, + count: Option, + 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) 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 066e8c51aef0b..c2ee91d6acca2 100644 --- a/src/librustrt/lib.rs +++ b/src/librustrt/lib.rs @@ -19,6 +19,7 @@ #![feature(macro_rules, phase, globs, thread_local, asm)] #![feature(linkage, lang_items, unsafe_destructor, default_type_params)] #![feature(import_shadowing, slicing_syntax)] +#![feature(unboxed_closures)] #![no_std] #![experimental] diff --git a/src/librustrt/task.rs b/src/librustrt/task.rs index 325bdc284acfc..7e657d3aef391 100644 --- a/src/librustrt/task.rs +++ b/src/librustrt/task.rs @@ -22,6 +22,7 @@ use core::atomic::{AtomicUint, SeqCst}; use core::iter::{IteratorExt, Take}; use core::kinds::marker; use core::mem; +use core::ops::FnMut; use core::prelude::{Clone, Drop, Err, Iterator, None, Ok, Option, Send, Some}; use core::prelude::{drop}; @@ -297,9 +298,9 @@ impl Task { // `awoken` field which indicates whether we were actually woken up via some // invocation of `reawaken`. This flag is only ever accessed inside the // lock, so there's no need to make it atomic. - pub fn deschedule(mut self: Box, - times: uint, - f: |BlockedTask| -> ::core::result::Result<(), BlockedTask>) { + pub fn deschedule(mut self: Box, 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 7919ac0eff16c..d34828ccee328 100644 --- a/src/libserialize/json.rs +++ b/src/libserialize/json.rs @@ -458,17 +458,19 @@ impl<'a> ::Encoder for Encoder<'a> { escape_str(self.writer, v) } - fn emit_enum(&mut self, - _name: &str, - f: |&mut Encoder<'a>| -> EncodeResult) -> EncodeResult { + fn emit_enum(&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(&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 for Encoder<'a> { } } - fn emit_enum_variant_arg(&mut self, - idx: uint, - f: |&mut Encoder<'a>| -> EncodeResult) -> EncodeResult { + fn emit_enum_variant_arg(&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(&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(&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(&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(&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(&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(&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(&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(&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(&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(&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(&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(&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(&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(&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 for Encoder<'a> { Ok(()) } - fn emit_map_elt_val(&mut self, - _idx: uint, - f: |&mut Encoder<'a>| -> EncodeResult) -> EncodeResult { + fn emit_map_elt_val(&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 for PrettyEncoder<'a> { escape_str(self.writer, v) } - fn emit_enum(&mut self, - _name: &str, - f: |&mut PrettyEncoder<'a>| -> EncodeResult) -> EncodeResult { + fn emit_enum(&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(&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 for PrettyEncoder<'a> { } } - fn emit_enum_variant_arg(&mut self, - idx: uint, - f: |&mut PrettyEncoder<'a>| -> EncodeResult) -> EncodeResult { + fn emit_enum_variant_arg(&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 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(&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(&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(&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 for PrettyEncoder<'a> { } } - fn emit_struct_field(&mut self, - name: &str, - idx: uint, - f: |&mut PrettyEncoder<'a>| -> EncodeResult) -> EncodeResult { + fn emit_struct_field(&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 for PrettyEncoder<'a> { f(self) } - fn emit_tuple(&mut self, - len: uint, - f: |&mut PrettyEncoder<'a>| -> EncodeResult) -> EncodeResult { + fn emit_tuple(&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(&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(&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(&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(&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(&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(&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 for PrettyEncoder<'a> { } } - fn emit_seq_elt(&mut self, - idx: uint, - f: |&mut PrettyEncoder<'a>| -> EncodeResult) -> EncodeResult { + fn emit_seq_elt(&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 for PrettyEncoder<'a> { f(self) } - fn emit_map(&mut self, - len: uint, - f: |&mut PrettyEncoder<'a>| -> EncodeResult) -> EncodeResult { + fn emit_map(&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 for PrettyEncoder<'a> { } } - fn emit_map_elt_key(&mut self, - idx: uint, - f: |&mut PrettyEncoder<'a>| -> EncodeResult) -> EncodeResult { + fn emit_map_elt_key(&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 for PrettyEncoder<'a> { Ok(()) } - fn emit_map_elt_val(&mut self, - _idx: uint, - f: |&mut PrettyEncoder<'a>| -> EncodeResult) -> EncodeResult { + fn emit_map_elt_val(&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 for Decoder { expect!(self.pop(), String) } - fn read_enum(&mut self, - name: &str, - f: |&mut Decoder| -> DecodeResult) -> DecodeResult { + fn read_enum(&mut self, name: &str, f: F) -> DecodeResult where + F: FnOnce(&mut Decoder) -> DecodeResult, + { debug!("read_enum({})", name); f(self) } - fn read_enum_variant(&mut self, - names: &[&str], - f: |&mut Decoder, uint| -> DecodeResult) - -> DecodeResult { + fn read_enum_variant(&mut self, names: &[&str], f: F) -> DecodeResult where + F: FnOnce(&mut Decoder, uint) -> DecodeResult, + { debug!("read_enum_variant(names={})", names); let name = match self.pop() { Json::String(s) => s, @@ -2103,46 +2125,48 @@ impl ::Decoder for Decoder { f(self, idx) } - fn read_enum_variant_arg(&mut self, idx: uint, f: |&mut Decoder| -> DecodeResult) - -> DecodeResult { + fn read_enum_variant_arg(&mut self, idx: uint, f: F) -> DecodeResult where + F: FnOnce(&mut Decoder) -> DecodeResult, + { debug!("read_enum_variant_arg(idx={})", idx); f(self) } - fn read_enum_struct_variant(&mut self, - names: &[&str], - f: |&mut Decoder, uint| -> DecodeResult) - -> DecodeResult { + fn read_enum_struct_variant(&mut self, names: &[&str], f: F) -> DecodeResult where + F: FnOnce(&mut Decoder, uint) -> DecodeResult, + { debug!("read_enum_struct_variant(names={})", names); self.read_enum_variant(names, f) } - fn read_enum_struct_variant_field(&mut self, + fn read_enum_struct_variant_field(&mut self, name: &str, idx: uint, - f: |&mut Decoder| -> DecodeResult) - -> DecodeResult { + f: F) + -> DecodeResult where + F: FnOnce(&mut Decoder) -> DecodeResult, + { debug!("read_enum_struct_variant_field(name={}, idx={})", name, idx); self.read_enum_variant_arg(idx, f) } - fn read_struct(&mut self, - name: &str, - len: uint, - f: |&mut Decoder| -> DecodeResult) - -> DecodeResult { + fn read_struct(&mut self, name: &str, len: uint, f: F) -> DecodeResult where + F: FnOnce(&mut Decoder) -> DecodeResult, + { debug!("read_struct(name={}, len={})", name, len); let value = try!(f(self)); self.pop(); Ok(value) } - fn read_struct_field(&mut self, - name: &str, - idx: uint, - f: |&mut Decoder| -> DecodeResult) - -> DecodeResult { + fn read_struct_field(&mut self, + name: &str, + idx: uint, + f: F) + -> DecodeResult where + F: FnOnce(&mut Decoder) -> DecodeResult, + { debug!("read_struct_field(name={}, idx={})", name, idx); let mut obj = try!(expect!(self.pop(), Object)); @@ -2165,12 +2189,11 @@ impl ::Decoder for Decoder { Ok(value) } - fn read_tuple(&mut self, - tuple_len: uint, - f: |&mut Decoder| -> DecodeResult) - -> DecodeResult { + fn read_tuple(&mut self, tuple_len: uint, f: F) -> DecodeResult where + F: FnOnce(&mut Decoder) -> DecodeResult, + { 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 for Decoder { }) } - fn read_tuple_arg(&mut self, - idx: uint, - f: |&mut Decoder| -> DecodeResult) -> DecodeResult { + fn read_tuple_arg(&mut self, idx: uint, f: F) -> DecodeResult where + F: FnOnce(&mut Decoder) -> DecodeResult, + { debug!("read_tuple_arg(idx={})", idx); self.read_seq_elt(idx, f) } - fn read_tuple_struct(&mut self, - name: &str, - len: uint, - f: |&mut Decoder| -> DecodeResult) - -> DecodeResult { + fn read_tuple_struct(&mut self, + name: &str, + len: uint, + f: F) + -> DecodeResult where + F: FnOnce(&mut Decoder) -> DecodeResult, + { debug!("read_tuple_struct(name={})", name); self.read_tuple(len, f) } - fn read_tuple_struct_arg(&mut self, - idx: uint, - f: |&mut Decoder| -> DecodeResult) - -> DecodeResult { + fn read_tuple_struct_arg(&mut self, + idx: uint, + f: F) + -> DecodeResult where + F: FnOnce(&mut Decoder) -> DecodeResult, + { debug!("read_tuple_struct_arg(idx={})", idx); self.read_tuple_arg(idx, f) } - fn read_option(&mut self, f: |&mut Decoder, bool| -> DecodeResult) -> DecodeResult { + fn read_option(&mut self, f: F) -> DecodeResult where + F: FnOnce(&mut Decoder, bool) -> DecodeResult, + { debug!("read_option()"); match self.pop() { Json::Null => f(self, false), @@ -2211,7 +2240,9 @@ impl ::Decoder for Decoder { } } - fn read_seq(&mut self, f: |&mut Decoder, uint| -> DecodeResult) -> DecodeResult { + fn read_seq(&mut self, f: F) -> DecodeResult where + F: FnOnce(&mut Decoder, uint) -> DecodeResult, + { debug!("read_seq()"); let array = try!(expect!(self.pop(), Array)); let len = array.len(); @@ -2221,14 +2252,16 @@ impl ::Decoder for Decoder { f(self, len) } - fn read_seq_elt(&mut self, - idx: uint, - f: |&mut Decoder| -> DecodeResult) -> DecodeResult { + fn read_seq_elt(&mut self, idx: uint, f: F) -> DecodeResult where + F: FnOnce(&mut Decoder) -> DecodeResult, + { debug!("read_seq_elt(idx={})", idx); f(self) } - fn read_map(&mut self, f: |&mut Decoder, uint| -> DecodeResult) -> DecodeResult { + fn read_map(&mut self, f: F) -> DecodeResult where + F: FnOnce(&mut Decoder, uint) -> DecodeResult, + { debug!("read_map()"); let obj = try!(expect!(self.pop(), Object)); let len = obj.len(); @@ -2239,14 +2272,16 @@ impl ::Decoder for Decoder { f(self, len) } - fn read_map_elt_key(&mut self, idx: uint, f: |&mut Decoder| -> DecodeResult) - -> DecodeResult { + fn read_map_elt_key(&mut self, idx: uint, f: F) -> DecodeResult where + F: FnOnce(&mut Decoder) -> DecodeResult, + { debug!("read_map_elt_key(idx={})", idx); f(self) } - fn read_map_elt_val(&mut self, idx: uint, f: |&mut Decoder| -> DecodeResult) - -> DecodeResult { + fn read_map_elt_val(&mut self, idx: uint, f: F) -> DecodeResult where + F: FnOnce(&mut Decoder) -> DecodeResult, + { 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) -> 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 9711d5c7209be..390b3976562ff 100644 --- a/src/libserialize/lib.rs +++ b/src/libserialize/lib.rs @@ -24,6 +24,7 @@ Core encoding and decoding interfaces. html_playground_url = "http://play.rust-lang.org/")] #![allow(unknown_features)] #![feature(macro_rules, default_type_params, phase, slicing_syntax, globs)] +#![feature(unboxed_closures)] // test harness access #[cfg(test)] diff --git a/src/libserialize/serialize.rs b/src/libserialize/serialize.rs index 7539a6dc3486b..98bd2f6bc930f 100644 --- a/src/libserialize/serialize.rs +++ b/src/libserialize/serialize.rs @@ -39,58 +39,61 @@ pub trait Encoder { 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(&mut self, name: &str, f: F) -> Result<(), E> where + F: FnOnce(&mut Self) -> Result<(), E>; + + fn emit_enum_variant(&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(&mut self, a_idx: uint, f: F) -> Result<(), E> where + F: FnOnce(&mut Self) -> Result<(), E>; + + fn emit_enum_struct_variant(&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(&mut self, + f_name: &str, + f_idx: uint, + f: F) -> Result<(), E> where + F: FnOnce(&mut Self) -> Result<(), E>; + + fn emit_struct(&mut self, name: &str, len: uint, f: F) -> Result<(), E> where + F: FnOnce(&mut Self) -> Result<(), E>; + fn emit_struct_field(&mut self, f_name: &str, f_idx: uint, f: F) -> Result<(), E> where + F: FnOnce(&mut Self) -> Result<(), E>; + + fn emit_tuple(&mut self, len: uint, f: F) -> Result<(), E> where + F: FnOnce(&mut Self) -> Result<(), E>; + fn emit_tuple_arg(&mut self, idx: uint, f: F) -> Result<(), E> where + F: FnOnce(&mut Self) -> Result<(), E>; + + fn emit_tuple_struct(&mut self, name: &str, len: uint, f: F) -> Result<(), E> where + F: FnOnce(&mut Self) -> Result<(), E>; + fn emit_tuple_struct_arg(&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(&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(&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(&mut self, len: uint, f: F) -> Result<(), E> where + F: FnOnce(&mut Self) -> Result<(), E>; + fn emit_seq_elt(&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(&mut self, len: uint, f: F) -> Result<(), E> where + F: FnOnce(&mut Self) -> Result<(), E>; + fn emit_map_elt_key(&mut self, idx: uint, f: F) -> Result<(), E> where + F: FnMut(&mut Self) -> Result<(), E>; + fn emit_map_elt_val(&mut self, idx: uint, f: F) -> Result<(), E> where + F: FnOnce(&mut Self) -> Result<(), E>; } pub trait Decoder { @@ -113,57 +116,57 @@ pub trait Decoder { fn read_str(&mut self) -> Result; // Compound types: - fn read_enum(&mut self, name: &str, f: |&mut Self| -> Result) -> Result; - - fn read_enum_variant(&mut self, - names: &[&str], - f: |&mut Self, uint| -> Result) - -> Result; - fn read_enum_variant_arg(&mut self, - a_idx: uint, - f: |&mut Self| -> Result) - -> Result; - - fn read_enum_struct_variant(&mut self, - names: &[&str], - f: |&mut Self, uint| -> Result) - -> Result; - fn read_enum_struct_variant_field(&mut self, - &f_name: &str, - f_idx: uint, - f: |&mut Self| -> Result) - -> Result; - - fn read_struct(&mut self, s_name: &str, len: uint, f: |&mut Self| -> Result) - -> Result; - fn read_struct_field(&mut self, - f_name: &str, - f_idx: uint, - f: |&mut Self| -> Result) - -> Result; - - fn read_tuple(&mut self, len: uint, f: |&mut Self| -> Result) -> Result; - fn read_tuple_arg(&mut self, a_idx: uint, f: |&mut Self| -> Result) -> Result; - - fn read_tuple_struct(&mut self, - s_name: &str, - len: uint, - f: |&mut Self| -> Result) - -> Result; - fn read_tuple_struct_arg(&mut self, - a_idx: uint, - f: |&mut Self| -> Result) - -> Result; + fn read_enum(&mut self, name: &str, f: F) -> Result where + F: FnOnce(&mut Self) -> Result; + + fn read_enum_variant(&mut self, names: &[&str], f: F) -> Result where + F: FnOnce(&mut Self, uint) -> Result; + fn read_enum_variant_arg(&mut self, a_idx: uint, f: F) -> Result where + F: FnOnce(&mut Self) -> Result; + + fn read_enum_struct_variant(&mut self, names: &[&str], f: F) -> Result where + F: FnOnce(&mut Self, uint) -> Result; + fn read_enum_struct_variant_field(&mut self, + &f_name: &str, + f_idx: uint, + f: F) + -> Result where + F: FnOnce(&mut Self) -> Result; + + fn read_struct(&mut self, s_name: &str, len: uint, f: F) -> Result where + F: FnOnce(&mut Self) -> Result; + fn read_struct_field(&mut self, + f_name: &str, + f_idx: uint, + f: F) + -> Result where + F: FnOnce(&mut Self) -> Result; + + fn read_tuple(&mut self, len: uint, f: F) -> Result where + F: FnOnce(&mut Self) -> Result; + fn read_tuple_arg(&mut self, a_idx: uint, f: F) -> Result where + F: FnOnce(&mut Self) -> Result; + + fn read_tuple_struct(&mut self, s_name: &str, len: uint, f: F) -> Result where + F: FnOnce(&mut Self) -> Result; + fn read_tuple_struct_arg(&mut self, a_idx: uint, f: F) -> Result where + F: FnOnce(&mut Self) -> Result; // Specialized types: - fn read_option(&mut self, f: |&mut Self, bool| -> Result) -> Result; + fn read_option(&mut self, f: F) -> Result where + F: FnOnce(&mut Self, bool) -> Result; - fn read_seq(&mut self, f: |&mut Self, uint| -> Result) -> Result; - fn read_seq_elt(&mut self, idx: uint, f: |&mut Self| -> Result) -> Result; + fn read_seq(&mut self, f: F) -> Result where + F: FnOnce(&mut Self, uint) -> Result; + fn read_seq_elt(&mut self, idx: uint, f: F) -> Result where + F: FnOnce(&mut Self) -> Result; - fn read_map(&mut self, f: |&mut Self, uint| -> Result) -> Result; - fn read_map_elt_key(&mut self, idx: uint, f: |&mut Self| -> Result) -> Result; - fn read_map_elt_val(&mut self, idx: uint, f: |&mut Self| -> Result) -> Result; + fn read_map(&mut self, f: F) -> Result where + F: FnOnce(&mut Self, uint) -> Result; + fn read_map_elt_key(&mut self, idx: uint, f: F) -> Result where + F: FnOnce(&mut Self) -> Result; + fn read_map_elt_val(&mut self, idx: uint, f: F) -> Result where + F: FnOnce(&mut Self) -> Result; // Failure fn error(&mut self, err: &str) -> E; @@ -585,13 +588,14 @@ impl,T:Decodable+Send+Sync> Decodable for Arc { // Helper routines pub trait EncoderHelpers { - fn emit_from_vec(&mut self, - v: &[T], - f: |&mut Self, v: &T| -> Result<(), E>) -> Result<(), E>; + fn emit_from_vec(&mut self, v: &[T], f: F) -> Result<(), E> where + F: FnMut(&mut Self, &T) -> Result<(), E>; } impl> EncoderHelpers for S { - fn emit_from_vec(&mut self, v: &[T], f: |&mut S, &T| -> Result<(), E>) -> Result<(), E> { + fn emit_from_vec(&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> EncoderHelpers for S { } pub trait DecoderHelpers { - fn read_to_vec(&mut self, f: |&mut Self| -> Result) -> Result, E>; + fn read_to_vec(&mut self, f: F) -> Result, E> where + F: FnMut(&mut Self) -> Result; } impl> DecoderHelpers for D { - fn read_to_vec(&mut self, f: |&mut D| -> Result) -> Result, E> { + fn read_to_vec(&mut self, mut f: F) -> Result, E> where F: + FnMut(&mut D) -> Result, + { 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 b5c8e271492ea..ad2167214a7d4 100644 --- a/src/libstd/ascii.rs +++ b/src/libstd/ascii.rs @@ -20,6 +20,7 @@ use fmt; use iter::IteratorExt; use kinds::Copy; use mem; +use ops::FnMut; use option::Option; use option::Option::{Some, None}; use slice::{SlicePrelude, AsSlice}; @@ -527,7 +528,9 @@ impl OwnedAsciiExt for Vec { /// - 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(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 a8dce232d26d5..2a8d97eed05bc 100644 --- a/src/libstd/collections/hash/map.rs +++ b/src/libstd/collections/hash/map.rs @@ -24,7 +24,7 @@ use iter::{mod, Iterator, IteratorExt, FromIterator, Extend}; use kinds::Sized; use mem::{mod, replace}; use num::{Int, UnsignedInt}; -use ops::{Deref, Index, IndexMut}; +use ops::{Deref, FnMut, Index, IndexMut}; use option::Option; use option::Option::{Some, None}; use result::Result; @@ -296,10 +296,13 @@ pub struct HashMap { } /// Search for a pre-hashed key. -fn search_hashed>>(table: M, - hash: &SafeHash, - is_match: |&K| -> bool) - -> SearchResult { +fn search_hashed(table: M, + hash: &SafeHash, + mut is_match: F) + -> SearchResult where + M: Deref>, + F: FnMut(&K) -> bool, +{ let size = table.size(); let mut probe = Bucket::new(table, hash); let ib = probe.index(); @@ -749,12 +752,14 @@ impl, V, S, H: Hasher> HashMap { 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, V, S, H: Hasher> HashMap { /// ``` #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn keys(&self) -> Keys { - self.iter().map(|(k, _v)| k) + fn first((a, _): (A, B)) -> A { a } + + self.iter().map(first) } /// An iterator visiting all values in arbitrary order. @@ -874,7 +881,9 @@ impl, V, S, H: Hasher> HashMap { /// ``` #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn values(&self) -> Values { - self.iter().map(|(_k, v)| v) + fn second((_, b): (A, B)) -> B { b } + + self.iter().map(second) } /// An iterator visiting all key-value pairs in arbitrary order. @@ -946,8 +955,10 @@ impl, V, S, H: Hasher> HashMap { /// ``` #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn into_iter(self) -> MoveEntries { + fn last_two((_, 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 { - inner: iter::Map<'static, (SafeHash, K, V), (K, V), table::MoveEntries> + inner: iter::Map< + (SafeHash, K, V), + (K, V), + table::MoveEntries, + 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, V, S, H: Hasher + Default> FromIterator<(K, V)> for HashMap { fn from_iter>(iter: T) -> HashMap { diff --git a/src/libstd/collections/hash/set.rs b/src/libstd/collections/hash/set.rs index b3ccfdbb47cce..745a8298ee8a5 100644 --- a/src/libstd/collections/hash/set.rs +++ b/src/libstd/collections/hash/set.rs @@ -19,7 +19,7 @@ use fmt; use hash::{Hash, Hasher, RandomSipHasher}; use iter::{Iterator, IteratorExt, FromIterator, FilterMap, Chain, Repeat, Zip, Extend, repeat}; use iter; -use option::Option::{Some, None}; +use option::Option::{Some, None, mod}; use result::Result::{Ok, Err}; use super::map::{HashMap, Entries, MoveEntries, INITIAL_CAPACITY}; @@ -277,7 +277,9 @@ impl, S, H: Hasher> HashSet { /// ``` #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn into_iter(self) -> SetMoveItems { - self.map.into_iter().map(|(k, _)| k) + fn first((a, _): (A, B)) -> A { a } + + self.map.into_iter().map(first) } /// Visit the values representing the difference. @@ -304,10 +306,13 @@ impl, S, H: Hasher> HashSet { /// ``` #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn difference<'a>(&'a self, other: &'a HashSet) -> 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, &'a T)) -> Option<&'a T> where + T: Eq + Hash, H: Hasher + { + 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, S, H: Hasher> HashSet { /// 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) - -> 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) -> SetAlgebraItems<'a, T, H> { + fn filter<'a, T, S, H>((other, elt): (&HashSet, &'a T)) -> Option<&'a T> where + T: Eq + Hash, H: Hasher + { + 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, S, H: Hasher + Default> Default for HashSet { /// 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 = - iter::Map<'static, (K, ()), K, MoveEntries>; +pub type SetMoveItems = iter::Map<(K, ()), K, MoveEntries, 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, &'a T), &'a T, - Zip>, SetItems<'a, T>>>; +pub type SetAlgebraItems<'a, T, H> = FilterMap< + (&'a HashSet, &'a T), + &'a T, + Zip>, SetItems<'a, T>>, + for<'b> fn((&HashSet, &'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 96b075ab569bf..059ad7537193f 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(f: || -> T) -> Result { + pub fn check_for_errors_in(f: F) -> Result 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(f: || -> T) -> Result { + pub fn check_for_errors_in(f: F) -> Result where + F: FnOnce() -> T, + { unsafe { SetLastError(0); diff --git a/src/libstd/io/extensions.rs b/src/libstd/io/extensions.rs index 1bdf99f6d6dce..69712e39d9108 100644 --- a/src/libstd/io/extensions.rs +++ b/src/libstd/io/extensions.rs @@ -19,6 +19,7 @@ use io::{IoError, IoResult, Reader}; use io; use iter::Iterator; use num::Int; +use ops::FnOnce; use option::Option; use option::Option::{Some, None}; use ptr::RawPtr; @@ -76,7 +77,9 @@ impl<'r, R: Reader> Iterator> 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(n: u64, size: uint, f: |v: &[u8]| -> T) -> T { +pub fn u64_to_le_bytes(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(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(n: u64, size: uint, f: |v: &[u8]| -> T) -> T { +pub fn u64_to_be_bytes(n: u64, size: uint, f: F) -> T where + F: FnOnce(&[u8]) -> T, +{ use mem::transmute; // LLVM fails to properly optimize this when using shifts instead of the to_be* intrinsics diff --git a/src/libstd/io/mod.rs b/src/libstd/io/mod.rs index dc212e7cab3ae..bad86258bb85d 100644 --- a/src/libstd/io/mod.rs +++ b/src/libstd/io/mod.rs @@ -233,7 +233,7 @@ use int; use iter::{Iterator, IteratorExt}; use kinds::Copy; use mem::transmute; -use ops::{BitOr, BitXor, BitAnd, Sub, Not}; +use ops::{BitOr, BitXor, BitAnd, Sub, Not, FnOnce}; use option::Option; use option::Option::{Some, None}; use os; @@ -426,18 +426,22 @@ impl Copy for IoErrorKind {} /// A trait that lets you add a `detail` to an IoError easily trait UpdateIoError { /// Returns an IoError with updated description and detail - fn update_err(self, desc: &'static str, detail: |&IoError| -> String) -> Self; + fn update_err(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(self, detail: D) -> Self where + D: FnOnce(&IoError) -> String; /// Returns an IoError with update description fn update_desc(self, desc: &'static str) -> Self; } impl UpdateIoError for IoResult { - fn update_err(self, desc: &'static str, detail: |&IoError| -> String) -> IoResult { - self.map_err(|mut e| { + fn update_err(self, desc: &'static str, detail: D) -> IoResult 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 UpdateIoError for IoResult { }) } - fn update_detail(self, detail: |&IoError| -> String) -> IoResult { - self.map_err(|mut e| { e.detail = Some(detail(&e)); e }) + fn update_detail(self, detail: D) -> IoResult 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 { diff --git a/src/libstd/io/net/ip.rs b/src/libstd/io/net/ip.rs index f59dd37c0da16..62965c48a2680 100644 --- a/src/libstd/io/net/ip.rs +++ b/src/libstd/io/net/ip.rs @@ -22,6 +22,7 @@ use kinds::Copy; use io::{mod, IoResult, IoError}; use io::net; use iter::{Iterator, IteratorExt}; +use ops::FnOnce; use option::Option; use option::Option::{None, Some}; use result::Result::{Ok, Err}; @@ -100,8 +101,9 @@ impl<'a> Parser<'a> { } // Commit only if parser returns Some - fn read_atomically(&mut self, cb: |&mut Parser| -> Option) - -> Option { + fn read_atomically(&mut self, cb: F) -> Option where + F: FnOnce(&mut Parser) -> Option, + { 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(&mut self, cb: |&mut Parser| -> Option) - -> Option { - self.read_atomically(|p| { + fn read_till_eof(&mut self, cb: F) -> Option where + F: FnOnce(&mut Parser) -> Option, + { + 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( - &mut self, - pa: |&mut Parser| -> Option, - pb: |&mut Parser| -> Option, - pc: |&mut Parser| -> Option) - -> Option<(A, B, C)> { - self.read_atomically(|p| { + fn read_seq_3(&mut self, + pa: PA, + pb: PB, + pc: PC) + -> Option<(A, B, C)> where + PA: FnOnce(&mut Parser) -> Option, + PB: FnOnce(&mut Parser) -> Option, + PC: FnOnce(&mut Parser) -> Option, + { + 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 { - 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::(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::(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::(ip_addr, colon, port) + self.read_seq_3::(ip_addr, colon, port) .map(|t| match t { (ip, _, port) => SocketAddr { ip: ip, port: port } }) } } diff --git a/src/libstd/io/net/mod.rs b/src/libstd/io/net/mod.rs index 09e5639bea944..2056933e6df6f 100644 --- a/src/libstd/io/net/mod.rs +++ b/src/libstd/io/net/mod.rs @@ -11,6 +11,7 @@ //! Networking I/O use io::{IoError, IoResult, InvalidInput}; +use ops::FnMut; use option::Option::None; use result::Result::{Ok, Err}; use self::ip::{SocketAddr, ToSocketAddr}; @@ -23,8 +24,10 @@ pub mod udp; pub mod ip; pub mod pipe; -fn with_addresses(addr: A, action: |SocketAddr| -> IoResult) - -> IoResult { +fn with_addresses(addr: A, mut action: F) -> IoResult where + A: ToSocketAddr, + F: FnMut(SocketAddr) -> IoResult, +{ const DEFAULT_ERROR: IoError = IoError { kind: InvalidInput, desc: "no addresses found for hostname", diff --git a/src/libstd/io/net/udp.rs b/src/libstd/io/net/udp.rs index a2ad365dd2a0e..b23921ba3594d 100644 --- a/src/libstd/io/net/udp.rs +++ b/src/libstd/io/net/udp.rs @@ -18,6 +18,7 @@ use clone::Clone; use io::net::ip::{SocketAddr, IpAddr, ToSocketAddr}; use io::{Reader, Writer, IoResult}; +use ops::FnOnce; use option::Option; use result::Result::{Ok, Err}; use sys::udp::UdpSocket as UdpSocketImp; @@ -210,7 +211,9 @@ impl UdpStream { /// Allows access to the underlying UDP socket owned by this stream. This /// is useful to, for example, use the socket to send data to hosts other /// than the one that this stream is connected to. - pub fn as_socket(&mut self, f: |&mut UdpSocket| -> T) -> T { + pub fn as_socket(&mut self, f: F) -> T where + F: FnOnce(&mut UdpSocket) -> T, + { f(&mut self.socket) } diff --git a/src/libstd/io/stdio.rs b/src/libstd/io/stdio.rs index 48c333f0733a5..8438c9fb441ed 100644 --- a/src/libstd/io/stdio.rs +++ b/src/libstd/io/stdio.rs @@ -39,7 +39,7 @@ use libc; use mem; use option::Option; use option::Option::{Some, None}; -use ops::{Deref, DerefMut}; +use ops::{Deref, DerefMut, FnOnce}; use result::Result::{Ok, Err}; use rustrt; use rustrt::local::Local; @@ -85,7 +85,9 @@ enum StdSource { File(fs::FileDesc), } -fn src(fd: libc::c_int, _readable: bool, f: |StdSource| -> T) -> T { +fn src(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) -> Option> { // // io1 aliases io2 // }) // }) -fn with_task_stdout(f: |&mut Writer| -> IoResult<()>) { +fn with_task_stdout(f: F) where + F: FnOnce(&mut Writer) -> IoResult<()>, +{ let result = if Local::exists(None::) { 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 f6b73f037f25b..c2363c9946a96 100644 --- a/src/libstd/lib.rs +++ b/src/libstd/lib.rs @@ -107,6 +107,7 @@ #![feature(macro_rules, globs, linkage)] #![feature(default_type_params, phase, lang_items, unsafe_destructor)] #![feature(import_shadowing, slicing_syntax)] +#![feature(unboxed_closures)] // Don't link to std. We are std. #![no_std] diff --git a/src/libstd/num/strconv.rs b/src/libstd/num/strconv.rs index c41f55d567ff6..d5c27c7fbf82a 100644 --- a/src/libstd/num/strconv.rs +++ b/src/libstd/num/strconv.rs @@ -21,6 +21,7 @@ use char::Char; use kinds::Copy; use num; use num::{Int, Float, FPNaN, FPInfinite, ToPrimitive}; +use ops::FnMut; use slice::{SlicePrelude, CloneSliceAllocPrelude}; use str::StrPrelude; use string::String; @@ -93,7 +94,10 @@ impl Copy for SignFormat {} /// # Panics /// /// - Panics if `radix` < 2 or `radix` > 36. -fn int_to_str_bytes_common(num: T, radix: uint, sign: SignFormat, f: |u8|) { +fn int_to_str_bytes_common(num: T, radix: uint, sign: SignFormat, mut f: F) where + T: Int, + F: FnMut(u8), +{ assert!(2 <= radix && radix <= 36); let _0: T = Int::zero(); diff --git a/src/libstd/num/u16.rs b/src/libstd/num/u16.rs index a83a66c23a526..6d9b177574afc 100644 --- a/src/libstd/num/u16.rs +++ b/src/libstd/num/u16.rs @@ -15,4 +15,6 @@ pub use core::u16::{BITS, BYTES, MIN, MAX}; +use ops::FnOnce; + uint_module!(u16) diff --git a/src/libstd/num/u32.rs b/src/libstd/num/u32.rs index 7271203b23b6c..0d6d17fa007bf 100644 --- a/src/libstd/num/u32.rs +++ b/src/libstd/num/u32.rs @@ -15,4 +15,6 @@ pub use core::u32::{BITS, BYTES, MIN, MAX}; +use ops::FnOnce; + uint_module!(u32) diff --git a/src/libstd/num/u64.rs b/src/libstd/num/u64.rs index 25de2f3b25565..ebb5d2946c531 100644 --- a/src/libstd/num/u64.rs +++ b/src/libstd/num/u64.rs @@ -15,4 +15,6 @@ pub use core::u64::{BITS, BYTES, MIN, MAX}; +use ops::FnOnce; + uint_module!(u64) diff --git a/src/libstd/num/u8.rs b/src/libstd/num/u8.rs index 22dedeecf3b10..59aea214aae0c 100644 --- a/src/libstd/num/u8.rs +++ b/src/libstd/num/u8.rs @@ -15,4 +15,6 @@ pub use core::u8::{BITS, BYTES, MIN, MAX}; +use ops::FnOnce; + uint_module!(u8) diff --git a/src/libstd/num/uint.rs b/src/libstd/num/uint.rs index a425aab3aa10c..484d28dfed058 100644 --- a/src/libstd/num/uint.rs +++ b/src/libstd/num/uint.rs @@ -15,4 +15,6 @@ pub use core::uint::{BITS, BYTES, MIN, MAX}; +use ops::FnOnce; + uint_module!(uint) diff --git a/src/libstd/num/uint_macros.rs b/src/libstd/num/uint_macros.rs index 0baefb11cf8f2..bd6f3d4bb286b 100644 --- a/src/libstd/num/uint_macros.rs +++ b/src/libstd/num/uint_macros.rs @@ -32,7 +32,9 @@ macro_rules! uint_module (($T:ty) => ( /// ``` #[inline] #[deprecated = "just use .to_string(), or a BufWriter with write! if you mustn't allocate"] -pub fn to_str_bytes(n: $T, radix: uint, f: |v: &[u8]| -> U) -> U { +pub fn to_str_bytes(n: $T, radix: uint, f: F) -> U where + F: FnOnce(&[u8]) -> U, +{ use io::{Writer, Seek}; // The radix can be as low as 2, so we need at least 64 characters for a // base 2 number, and then we need another for a possible '-' character. diff --git a/src/libstd/os.rs b/src/libstd/os.rs index 138296cca70d2..a3ecfb49acee0 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 { 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 { + pub fn fill_utf16_buf_and_decode(mut f: F) -> Option 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(f: || -> T) -> T { +fn with_env_lock(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 470e1b4dbb7af..3daba53cd866e 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 ea522536d22fd..e1b0d9b139542 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, &'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 { } 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 a75088120f869..1bcdc760fc680 100644 --- a/src/libstd/sync/once.rs +++ b/src/libstd/sync/once.rs @@ -15,6 +15,7 @@ use int; use mem::drop; +use ops::FnOnce; use sync::atomic; use sync::{StaticMutex, MUTEX_INIT}; @@ -57,7 +58,7 @@ impl Once { /// /// When this function returns, it is guaranteed that some initialization /// has run and completed (it may not be the closure specified). - pub fn doit(&'static self, f: ||) { + pub fn doit(&'static self, f: F) where F: FnOnce() { // Optimize common path: load is much cheaper than fetch_add. if self.cnt.load(atomic::SeqCst) < 0 { return diff --git a/src/libstd/sys/common/helper_thread.rs b/src/libstd/sys/common/helper_thread.rs index c0018c5d97042..6c5fc3005edd2 100644 --- a/src/libstd/sys/common/helper_thread.rs +++ b/src/libstd/sys/common/helper_thread.rs @@ -70,9 +70,10 @@ impl Helper { /// passed to the helper thread in a separate task. /// /// This function is safe to be called many times. - pub fn boot(&'static self, - f: || -> T, - helper: fn(helper_signal::signal, Receiver, T)) { + pub fn boot(&'static self, f: F, helper: fn(helper_signal::signal, Receiver, T)) where + T: Send, + F: FnOnce() -> T, + { unsafe { let _guard = self.lock.lock(); if !*self.initialized.get() { diff --git a/src/libstd/sys/common/mod.rs b/src/libstd/sys/common/mod.rs index f8861c20464dd..73e1c7bd9e5e0 100644 --- a/src/libstd/sys/common/mod.rs +++ b/src/libstd/sys/common/mod.rs @@ -69,7 +69,9 @@ pub fn mkerr_libc(ret: T) -> IoResult<()> { } } -pub fn keep_going(data: &[u8], f: |*const u8, uint| -> i64) -> i64 { +pub fn keep_going(data: &[u8], mut f: F) -> i64 where + F: FnMut(*const u8, uint) -> i64, +{ let origamt = data.len(); let mut data = data.as_ptr(); let mut amt = origamt; diff --git a/src/libstd/sys/common/net.rs b/src/libstd/sys/common/net.rs index ddc6dd021c30f..73da200e16238 100644 --- a/src/libstd/sys/common/net.rs +++ b/src/libstd/sys/common/net.rs @@ -344,10 +344,10 @@ pub fn get_host_addresses(host: Option<&str>, servname: Option<&str>, // [1] http://twistedmatrix.com/pipermail/twisted-commits/2012-April/034692.html // [2] http://stackoverflow.com/questions/19819198/does-send-msg-dontwait -pub fn read(fd: sock_t, - deadline: u64, - lock: || -> T, - read: |bool| -> libc::c_int) -> IoResult { +pub fn read(fd: sock_t, deadline: u64, mut lock: L, mut read: R) -> IoResult 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(fd: sock_t, } } -pub fn write(fd: sock_t, - deadline: u64, - buf: &[u8], - write_everything: bool, - lock: || -> T, - write: |bool, *const u8, uint| -> i64) -> IoResult { +pub fn write(fd: sock_t, + deadline: u64, + buf: &[u8], + write_everything: bool, + mut lock: L, + mut write: W) -> IoResult 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 { 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::() as libc::socklen_t; - let dolock = || self.lock_nonblocking(); + let dolock = |&:| self.lock_nonblocking(); let n = try!(read(fd, self.read_deadline, dolock, |nb| unsafe { let flags = if nb {c::MSG_DONTWAIT} else {0}; libc::recvfrom(fd, @@ -843,8 +846,8 @@ impl UdpSocket { let dstp = &storage as *const _ as *const libc::sockaddr; let fd = self.fd(); - let dolock = || self.lock_nonblocking(); - let dowrite = |nb, buf: *const u8, len: uint| unsafe { + let dolock = |&: | self.lock_nonblocking(); + let dowrite = |&mut: nb, buf: *const u8, len: uint| unsafe { let flags = if nb {c::MSG_DONTWAIT} else {0}; libc::sendto(fd, buf as *const libc::c_void, diff --git a/src/libstd/sys/unix/mod.rs b/src/libstd/sys/unix/mod.rs index 4effedbe3abd8..107263c31a766 100644 --- a/src/libstd/sys/unix/mod.rs +++ b/src/libstd/sys/unix/mod.rs @@ -125,7 +125,10 @@ pub fn decode_error_detailed(errno: i32) -> IoError { } #[inline] -pub fn retry (f: || -> T) -> T { +pub fn retry (mut f: F) -> T where + T: SignedInt, + F: FnMut() -> T, +{ let one: T = Int::one(); loop { let n = f(); diff --git a/src/libstd/sys/unix/pipe.rs b/src/libstd/sys/unix/pipe.rs index 08e6f7059d8c6..26fd410a7a9b6 100644 --- a/src/libstd/sys/unix/pipe.rs +++ b/src/libstd/sys/unix/pipe.rs @@ -149,8 +149,8 @@ impl UnixStream { pub fn read(&mut self, buf: &mut [u8]) -> IoResult { let fd = self.fd(); - let dolock = || self.lock_nonblocking(); - let doread = |nb| unsafe { + let dolock = |&:| self.lock_nonblocking(); + let doread = |&mut: nb| unsafe { let flags = if nb {c::MSG_DONTWAIT} else {0}; libc::recv(fd, buf.as_mut_ptr() as *mut libc::c_void, @@ -162,8 +162,8 @@ impl UnixStream { pub fn write(&mut self, buf: &[u8]) -> IoResult<()> { let fd = self.fd(); - let dolock = || self.lock_nonblocking(); - let dowrite = |nb: bool, buf: *const u8, len: uint| unsafe { + let dolock = |&: | self.lock_nonblocking(); + let dowrite = |&: nb: bool, buf: *const u8, len: uint| unsafe { let flags = if nb {c::MSG_DONTWAIT} else {0}; libc::send(fd, buf as *const _, diff --git a/src/libstd/sys/windows/mod.rs b/src/libstd/sys/windows/mod.rs index 9fce308cb9468..41361a0cde695 100644 --- a/src/libstd/sys/windows/mod.rs +++ b/src/libstd/sys/windows/mod.rs @@ -138,7 +138,7 @@ pub fn decode_error_detailed(errno: i32) -> IoError { } #[inline] -pub fn retry (f: || -> I) -> I { f() } // PR rust-lang/rust/#17020 +pub fn retry(f: F) -> I where F: FnOnce() -> I { f() } // PR rust-lang/rust/#17020 pub fn ms_to_timeval(ms: u64) -> libc::timeval { libc::timeval { diff --git a/src/libstd/sys/windows/process.rs b/src/libstd/sys/windows/process.rs index adbcff8a53f6e..356d6f02565ed 100644 --- a/src/libstd/sys/windows/process.rs +++ b/src/libstd/sys/windows/process.rs @@ -418,9 +418,8 @@ fn make_command_line(prog: &CString, args: &[CString]) -> String { } } -fn with_envp(env: Option<&collections::HashMap>, - cb: |*mut c_void| -> T) -> T - where K: BytesContainer + Eq + Hash, V: BytesContainer +fn with_envp(env: Option<&collections::HashMap>, 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(env: Option<&collections::HashMap>, } } -fn with_dirp(d: Option<&CString>, cb: |*const u16| -> T) -> T { +fn with_dirp(d: Option<&CString>, cb: F) -> T where + F: FnOnce(*const u16) -> T, +{ match d { Some(dir) => { let dir_str = dir.as_str() diff --git a/src/libstd/task.rs b/src/libstd/task.rs index c91417e611ed1..5a1a5b4fb7a10 100644 --- a/src/libstd/task.rs +++ b/src/libstd/task.rs @@ -381,7 +381,9 @@ mod test { rx.recv(); } - fn avoid_copying_the_body(spawnfn: |v: proc():Send|) { + fn avoid_copying_the_body(spawnfn: F) where + F: FnOnce(proc():Send), + { let (tx, rx) = channel::(); let x = box 1; diff --git a/src/libstd/thread_local/mod.rs b/src/libstd/thread_local/mod.rs index 029b8bf113877..b85b6eccb7718 100644 --- a/src/libstd/thread_local/mod.rs +++ b/src/libstd/thread_local/mod.rs @@ -218,7 +218,9 @@ impl Key { /// 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(&'static self, f: |&T| -> R) -> R { + pub fn with(&'static self, f: F) -> R where + F: FnOnce(&T) -> R, + { let slot = (self.inner)(); unsafe { let slot = slot.get().expect("cannot access a TLS value during or \ diff --git a/src/libstd/thread_local/scoped.rs b/src/libstd/thread_local/scoped.rs index 11d539c4f9fa8..ee742ab83751d 100644 --- a/src/libstd/thread_local/scoped.rs +++ b/src/libstd/thread_local/scoped.rs @@ -135,7 +135,9 @@ impl Key { /// assert_eq!(val, 100); /// }); /// ``` - pub fn set(&'static self, t: &T, cb: || -> R) -> R { + pub fn set(&'static self, t: &T, cb: F) -> R where + F: FnOnce() -> R, + { struct Reset<'a, T: 'a> { key: &'a KeyInner, val: *mut T, @@ -175,7 +177,9 @@ impl Key { /// // work with `slot` /// }); /// ``` - pub fn with(&'static self, cb: |&T| -> R) -> R { + pub fn with(&'static self, cb: F) -> R where + F: FnOnce(&T) -> R + { unsafe { let ptr = self.inner.get(); assert!(!ptr.is_null(), "cannot access a scoped thread local \ diff --git a/src/libstd/time/duration.rs b/src/libstd/time/duration.rs index 7e6065129a384..34a3d6aa27536 100644 --- a/src/libstd/time/duration.rs +++ b/src/libstd/time/duration.rs @@ -14,7 +14,7 @@ use {fmt, i64}; use kinds::Copy; -use ops::{Add, Sub, Mul, Div, Neg}; +use ops::{Add, Sub, Mul, Div, Neg, FnOnce}; use option::Option; use option::Option::{Some, None}; use num::Int; @@ -141,7 +141,7 @@ impl Duration { /// Runs a closure, returning the duration of time it took to run the /// closure. - pub fn span(f: ||) -> Duration { + pub fn span(f: F) -> 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 639a33a806395..75f69f2f6d062 100644 --- a/src/libsyntax/ast_map/blocks.rs +++ b/src/libsyntax/ast_map/blocks.rs @@ -181,22 +181,23 @@ impl<'a> FnLikeNode<'a> { } pub fn kind(self) -> visit::FnKind<'a> { - let item = |p: ItemFnParts<'a>| -> visit::FnKind<'a> { + let item = |: p: ItemFnParts<'a>| -> visit::FnKind<'a> { visit::FkItemFn(p.ident, p.generics, p.style, p.abi) }; - let closure = |_: ClosureParts| { + let closure = |: _: ClosureParts| { visit::FkFnBlock }; - let method = |m: &'a ast::Method| { + let method = |: m: &'a ast::Method| { visit::FkMethod(m.pe_ident(), m.pe_generics(), m) }; self.handle(item, method, closure) } - fn handle(self, - item_fn: |ItemFnParts<'a>| -> A, - method: |&'a ast::Method| -> A, - closure: |ClosureParts<'a>| -> A) -> A { + fn handle(self, item_fn: I, method: M, closure: C) -> A where + I: FnOnce(ItemFnParts<'a>) -> A, + M: FnOnce(&'a ast::Method) -> A, + C: FnOnce(ClosureParts<'a>) -> A, + { match self.node { ast_map::NodeItem(i) => match i.node { ast::ItemFn(ref decl, style, abi, ref generics, ref block) => diff --git a/src/libsyntax/ast_map/mod.rs b/src/libsyntax/ast_map/mod.rs index 2c985f403f851..907ac6b19fc0d 100644 --- a/src/libsyntax/ast_map/mod.rs +++ b/src/libsyntax/ast_map/mod.rs @@ -424,7 +424,9 @@ impl<'ast> Map<'ast> { } } - pub fn with_path(&self, id: NodeId, f: |PathElems| -> T) -> T { + pub fn with_path(&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(&self, id: NodeId, next: LinkedPath, f: |PathElems| -> T) -> T { + fn with_path_next(&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(&self, id: NodeId, f: |Option<&[Attribute]>| -> T) -> T { + pub fn with_attrs(&self, id: NodeId, f: F) -> T where + F: FnOnce(Option<&[Attribute]>) -> T, + { let attrs = match self.get(id) { NodeItem(i) => Some(i.attrs.as_slice()), NodeForeignItem(fi) => Some(fi.attrs.as_slice()), diff --git a/src/libsyntax/ast_util.rs b/src/libsyntax/ast_util.rs index eec3f69ee64de..7579972c6d843 100644 --- a/src/libsyntax/ast_util.rs +++ b/src/libsyntax/ast_util.rs @@ -602,6 +602,7 @@ pub fn compute_id_range_for_fn_body(fk: visit::FnKind, id_visitor.operation.result } +// FIXME(#19596) unbox `it` pub fn walk_pat(pat: &Pat, it: |&Pat| -> bool) -> bool { if !it(pat) { return false; @@ -632,21 +633,21 @@ pub fn walk_pat(pat: &Pat, it: |&Pat| -> bool) -> bool { } pub trait EachViewItem { - fn each_view_item(&self, f: |&ast::ViewItem| -> bool) -> bool; + fn each_view_item(&self, f: F) -> bool where F: FnMut(&ast::ViewItem) -> bool; } -struct EachViewItemData<'a> { - callback: |&ast::ViewItem|: 'a -> bool, +struct EachViewItemData where F: FnMut(&ast::ViewItem) -> bool { + callback: F, } -impl<'a, 'v> Visitor<'v> for EachViewItemData<'a> { +impl<'v, F> Visitor<'v> for EachViewItemData 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(&self, f: F) -> bool where F: FnMut(&ast::ViewItem) -> bool { let mut visit = EachViewItemData { callback: f, }; diff --git a/src/libsyntax/attr.rs b/src/libsyntax/attr.rs index 5894a88ece65a..8248eae4b8cdd 100644 --- a/src/libsyntax/attr.rs +++ b/src/libsyntax/attr.rs @@ -115,7 +115,8 @@ impl AttrMetaMethods for P { pub trait AttributeMethods { fn meta<'a>(&'a self) -> &'a MetaItem; - fn with_desugared_doc(&self, f: |&Attribute| -> T) -> T; + fn with_desugared_doc(&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(&self, f: |&Attribute| -> T) -> T { + fn with_desugared_doc(&self, f: F) -> T where + F: FnOnce(&Attribute) -> T, + { if self.node.is_sugared_doc { let comment = self.value_str().unwrap(); let meta = mk_name_value_item_str( diff --git a/src/libsyntax/codemap.rs b/src/libsyntax/codemap.rs index 7f2becf820147..d2fe667339c84 100644 --- a/src/libsyntax/codemap.rs +++ b/src/libsyntax/codemap.rs @@ -568,7 +568,9 @@ impl CodeMap { ExpnId(expansions.len().to_u32().expect("too many ExpnInfo's!") - 1) } - pub fn with_expn_info(&self, id: ExpnId, f: |Option<&ExpnInfo>| -> T) -> T { + pub fn with_expn_info(&self, id: ExpnId, f: F) -> T where + F: FnOnce(Option<&ExpnInfo>) -> T, + { match id { NO_EXPANSION => f(None), ExpnId(i) => f(Some(&(*self.expansions.borrow())[i as uint])) diff --git a/src/libsyntax/config.rs b/src/libsyntax/config.rs index 4f718555d5331..87426dce91817 100644 --- a/src/libsyntax/config.rs +++ b/src/libsyntax/config.rs @@ -19,8 +19,8 @@ use util::small_vector::SmallVector; /// A folder that strips out items that do not belong in the current /// configuration. -struct Context<'a> { - in_cfg: |attrs: &[ast::Attribute]|: 'a -> bool, +struct Context 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 fold::Folder for Context 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(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 { +fn filter_view_item(cx: &mut Context, + view_item: ast::ViewItem) + -> Option 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::Mod { +fn fold_mod(cx: &mut Context, + 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) - -> Option> { +fn filter_foreign_item(cx: &mut Context, + item: P) + -> Option> 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) } } -fn fold_foreign_mod(cx: &mut Context, ast::ForeignMod {abi, view_items, items}: ast::ForeignMod) - -> ast::ForeignMod { +fn fold_foreign_mod(cx: &mut Context, + 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) -> SmallVector> { +fn fold_item(cx: &mut Context, item: P) -> SmallVector> 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) -> SmallVector> } } -fn fold_item_underscore(cx: &mut Context, item: ast::Item_) -> ast::Item_ { +fn fold_item_underscore(cx: &mut Context, 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) -> P { +fn fold_struct(cx: &mut Context, def: P) -> P 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) -> P { }) } -fn retain_stmt(cx: &mut Context, stmt: &ast::Stmt) -> bool { +fn retain_stmt(cx: &mut Context, 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) -> P { +fn fold_block(cx: &mut Context, b: P) -> P where + F: FnMut(&[ast::Attribute]) -> bool +{ b.map(|ast::Block {id, view_items, stmts, expr, rules, span}| { let resulting_stmts: Vec> = stmts.into_iter().filter(|a| retain_stmt(cx, &**a)).collect(); @@ -212,7 +236,9 @@ fn fold_block(cx: &mut Context, b: P) -> P { }) } -fn fold_expr(cx: &mut Context, expr: P) -> P { +fn fold_expr(cx: &mut Context, expr: P) -> P 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) -> P { }) } -fn item_in_cfg(cx: &mut Context, item: &ast::Item) -> bool { +fn item_in_cfg(cx: &mut Context, 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(cx: &mut Context, 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(cx: &mut Context, 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(cx: &mut Context, 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(cx: &mut Context, impl_item: &ast::ImplItem) -> bool where + F: FnMut(&[ast::Attribute]) -> bool +{ match *impl_item { ast::MethodImplItem(ref meth) => (cx.in_cfg)(meth.attrs.as_slice()), ast::TypeImplItem(ref typ) => (cx.in_cfg)(typ.attrs.as_slice()), diff --git a/src/libsyntax/diagnostic.rs b/src/libsyntax/diagnostic.rs index bbda80bd96c33..3a81698792264 100644 --- a/src/libsyntax/diagnostic.rs +++ b/src/libsyntax/diagnostic.rs @@ -581,7 +581,9 @@ fn print_macro_backtrace(w: &mut EmitterWriter, cs.map_or(Ok(()), |call_site| print_macro_backtrace(w, cm, call_site)) } -pub fn expect(diag: &SpanHandler, opt: Option, msg: || -> String) -> T { +pub fn expect(diag: &SpanHandler, opt: Option, msg: M) -> T where + M: FnOnce() -> String, +{ match opt { Some(t) => t, None => diag.handler().bug(msg().as_slice()), diff --git a/src/libsyntax/diagnostics/plugin.rs b/src/libsyntax/diagnostics/plugin.rs index 2be11a236d3b7..cb2a1f8acd8bf 100644 --- a/src/libsyntax/diagnostics/plugin.rs +++ b/src/libsyntax/diagnostics/plugin.rs @@ -25,14 +25,18 @@ thread_local!(static USED_DIAGNOSTICS: RefCell> = { RefCell::new(HashMap::new()) }) -fn with_registered_diagnostics(f: |&mut HashMap>| -> T) -> T { - REGISTERED_DIAGNOSTICS.with(|slot| { +fn with_registered_diagnostics(f: F) -> T where + F: FnOnce(&mut HashMap>) -> T, +{ + REGISTERED_DIAGNOSTICS.with(move |slot| { f(&mut *slot.borrow_mut()) }) } -fn with_used_diagnostics(f: |&mut HashMap| -> T) -> T { - USED_DIAGNOSTICS.with(|slot| { +fn with_used_diagnostics(f: F) -> T where + F: FnOnce(&mut HashMap) -> T, +{ + USED_DIAGNOSTICS.with(move |slot| { f(&mut *slot.borrow_mut()) }) } diff --git a/src/libsyntax/ext/deriving/bounds.rs b/src/libsyntax/ext/deriving/bounds.rs index 0595b0bc7f440..3145b3bb1a4fe 100644 --- a/src/libsyntax/ext/deriving/bounds.rs +++ b/src/libsyntax/ext/deriving/bounds.rs @@ -15,12 +15,13 @@ use ext::deriving::generic::*; use ext::deriving::generic::ty::*; use ptr::P; -pub fn expand_deriving_bound(cx: &mut ExtCtxt, - span: Span, - mitem: &MetaItem, - item: &Item, - push: |P|) { - +pub fn expand_deriving_bound(cx: &mut ExtCtxt, + span: Span, + mitem: &MetaItem, + item: &Item, + push: F) where + F: FnOnce(P), +{ 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 fccc67bf22093..a34764221b3b6 100644 --- a/src/libsyntax/ext/deriving/clone.rs +++ b/src/libsyntax/ext/deriving/clone.rs @@ -17,11 +17,13 @@ use ext::deriving::generic::ty::*; use parse::token::InternedString; use ptr::P; -pub fn expand_deriving_clone(cx: &mut ExtCtxt, - span: Span, - mitem: &MetaItem, - item: &Item, - push: |P|) { +pub fn expand_deriving_clone(cx: &mut ExtCtxt, + span: Span, + mitem: &MetaItem, + item: &Item, + push: F) where + F: FnOnce(P), +{ 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 7727bb824db3a..c8bf5ec326cd9 100644 --- a/src/libsyntax/ext/deriving/cmp/eq.rs +++ b/src/libsyntax/ext/deriving/cmp/eq.rs @@ -17,11 +17,13 @@ use ext::deriving::generic::ty::*; use parse::token::InternedString; use ptr::P; -pub fn expand_deriving_eq(cx: &mut ExtCtxt, - span: Span, - mitem: &MetaItem, - item: &Item, - push: |P|) { +pub fn expand_deriving_eq(cx: &mut ExtCtxt, + span: Span, + mitem: &MetaItem, + item: &Item, + push: F) where + F: FnOnce(P), +{ // 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 { diff --git a/src/libsyntax/ext/deriving/cmp/ord.rs b/src/libsyntax/ext/deriving/cmp/ord.rs index 1bd55b5d50451..bd1962de56ed9 100644 --- a/src/libsyntax/ext/deriving/cmp/ord.rs +++ b/src/libsyntax/ext/deriving/cmp/ord.rs @@ -20,11 +20,13 @@ use ext::deriving::generic::ty::*; use parse::token::InternedString; use ptr::P; -pub fn expand_deriving_ord(cx: &mut ExtCtxt, - span: Span, - mitem: &MetaItem, - item: &Item, - push: |P|) { +pub fn expand_deriving_ord(cx: &mut ExtCtxt, + span: Span, + mitem: &MetaItem, + item: &Item, + push: F) where + F: FnOnce(P), +{ macro_rules! md ( ($name:expr, $op:expr, $equal:expr) => { { let inline = cx.meta_word(span, InternedString::new("inline")); diff --git a/src/libsyntax/ext/deriving/cmp/totaleq.rs b/src/libsyntax/ext/deriving/cmp/totaleq.rs index ecee2008254dd..2b986bea1221e 100644 --- a/src/libsyntax/ext/deriving/cmp/totaleq.rs +++ b/src/libsyntax/ext/deriving/cmp/totaleq.rs @@ -17,11 +17,13 @@ use ext::deriving::generic::ty::*; use parse::token::InternedString; use ptr::P; -pub fn expand_deriving_totaleq(cx: &mut ExtCtxt, - span: Span, - mitem: &MetaItem, - item: &Item, - push: |P|) { +pub fn expand_deriving_totaleq(cx: &mut ExtCtxt, + span: Span, + mitem: &MetaItem, + item: &Item, + push: F) where + F: FnOnce(P), +{ fn cs_total_eq_assert(cx: &mut ExtCtxt, span: Span, substr: &Substructure) -> P { cs_same_method(|cx, span, exprs| { // create `a.(); b.(); c.(); ...` diff --git a/src/libsyntax/ext/deriving/cmp/totalord.rs b/src/libsyntax/ext/deriving/cmp/totalord.rs index 6900773f44d4b..a2bf46f41fc96 100644 --- a/src/libsyntax/ext/deriving/cmp/totalord.rs +++ b/src/libsyntax/ext/deriving/cmp/totalord.rs @@ -18,11 +18,13 @@ use ext::deriving::generic::ty::*; use parse::token::InternedString; use ptr::P; -pub fn expand_deriving_totalord(cx: &mut ExtCtxt, - span: Span, - mitem: &MetaItem, - item: &Item, - push: |P|) { +pub fn expand_deriving_totalord(cx: &mut ExtCtxt, + span: Span, + mitem: &MetaItem, + item: &Item, + push: F) where + F: FnOnce(P), +{ let inline = cx.meta_word(span, InternedString::new("inline")); let attrs = vec!(cx.attribute(span, inline)); let trait_def = TraitDef { diff --git a/src/libsyntax/ext/deriving/decodable.rs b/src/libsyntax/ext/deriving/decodable.rs index e3cf2b68752fd..0a8d59da89677 100644 --- a/src/libsyntax/ext/deriving/decodable.rs +++ b/src/libsyntax/ext/deriving/decodable.rs @@ -21,11 +21,13 @@ use parse::token::InternedString; use parse::token; use ptr::P; -pub fn expand_deriving_decodable(cx: &mut ExtCtxt, - span: Span, - mitem: &MetaItem, - item: &Item, - push: |P|) { +pub fn expand_deriving_decodable(cx: &mut ExtCtxt, + span: Span, + mitem: &MetaItem, + item: &Item, + push: F) where + F: FnOnce(P), +{ 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) - -> P { +fn decode_static_fields(cx: &mut ExtCtxt, + trait_span: Span, + outer_pat_path: ast::Path, + fields: &StaticFields, + mut getarg: F) + -> P where + F: FnMut(&mut ExtCtxt, Span, InternedString, uint) -> P, +{ match *fields { Unnamed(ref fields) => { let path_expr = cx.expr_path(outer_pat_path); diff --git a/src/libsyntax/ext/deriving/default.rs b/src/libsyntax/ext/deriving/default.rs index f4a66414d89bd..b3621490ce3bf 100644 --- a/src/libsyntax/ext/deriving/default.rs +++ b/src/libsyntax/ext/deriving/default.rs @@ -17,11 +17,13 @@ use ext::deriving::generic::ty::*; use parse::token::InternedString; use ptr::P; -pub fn expand_deriving_default(cx: &mut ExtCtxt, - span: Span, - mitem: &MetaItem, - item: &Item, - push: |P|) { +pub fn expand_deriving_default(cx: &mut ExtCtxt, + span: Span, + mitem: &MetaItem, + item: &Item, + push: F) where + F: FnOnce(P), +{ let inline = cx.meta_word(span, InternedString::new("inline")); let attrs = vec!(cx.attribute(span, inline)); let trait_def = TraitDef { diff --git a/src/libsyntax/ext/deriving/encodable.rs b/src/libsyntax/ext/deriving/encodable.rs index 62f3b5d01b41a..30851ebeaaef3 100644 --- a/src/libsyntax/ext/deriving/encodable.rs +++ b/src/libsyntax/ext/deriving/encodable.rs @@ -97,11 +97,13 @@ use ext::deriving::generic::ty::*; use parse::token; use ptr::P; -pub fn expand_deriving_encodable(cx: &mut ExtCtxt, - span: Span, - mitem: &MetaItem, - item: &Item, - push: |P|) { +pub fn expand_deriving_encodable(cx: &mut ExtCtxt, + span: Span, + mitem: &MetaItem, + item: &Item, + push: F) where + F: FnOnce(P), +{ let trait_def = TraitDef { span: span, attributes: Vec::new(), diff --git a/src/libsyntax/ext/deriving/generic/mod.rs b/src/libsyntax/ext/deriving/generic/mod.rs index cf3b3ad9051aa..a75be40604ea6 100644 --- a/src/libsyntax/ext/deriving/generic/mod.rs +++ b/src/libsyntax/ext/deriving/generic/mod.rs @@ -333,11 +333,13 @@ pub fn combine_substructure<'a>(f: CombineSubstructureFunc<'a>) impl<'a> TraitDef<'a> { - pub fn expand(&self, - cx: &mut ExtCtxt, - mitem: &ast::MetaItem, - item: &ast::Item, - push: |P|) { + pub fn expand(&self, + cx: &mut ExtCtxt, + mitem: &ast::MetaItem, + item: &ast::Item, + push: F) where + F: FnOnce(P), + { 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, P, &[P]| -> P, - base: P, - enum_nonmatch_f: EnumNonMatchCollapsedFunc, - cx: &mut ExtCtxt, - trait_span: Span, - substructure: &Substructure) - -> P { +pub fn cs_fold(use_foldl: bool, + mut f: F, + base: P, + enum_nonmatch_f: EnumNonMatchCollapsedFunc, + cx: &mut ExtCtxt, + trait_span: Span, + substructure: &Substructure) + -> P where + F: FnMut(&mut ExtCtxt, Span, P, P, &[P]) -> P, +{ 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, - enum_nonmatch_f: EnumNonMatchCollapsedFunc, - cx: &mut ExtCtxt, - trait_span: Span, - substructure: &Substructure) - -> P { +pub fn cs_same_method(f: F, + enum_nonmatch_f: EnumNonMatchCollapsedFunc, + cx: &mut ExtCtxt, + trait_span: Span, + substructure: &Substructure) + -> P where + F: FnOnce(&mut ExtCtxt, Span, Vec>) -> P, +{ 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, /// 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, P| -> P, - base: P, - enum_nonmatch_f: EnumNonMatchCollapsedFunc, - cx: &mut ExtCtxt, - trait_span: Span, - substructure: &Substructure) - -> P { +pub fn cs_same_method_fold(use_foldl: bool, + mut f: F, + base: P, + enum_nonmatch_f: EnumNonMatchCollapsedFunc, + cx: &mut ExtCtxt, + trait_span: Span, + substructure: &Substructure) + -> P where + F: FnMut(&mut ExtCtxt, Span, P, P) -> P, +{ cs_same_method( |cx, span, vals| { if use_foldl { diff --git a/src/libsyntax/ext/deriving/hash.rs b/src/libsyntax/ext/deriving/hash.rs index b7f11c2582548..4e59124a1294f 100644 --- a/src/libsyntax/ext/deriving/hash.rs +++ b/src/libsyntax/ext/deriving/hash.rs @@ -17,11 +17,13 @@ use ext::deriving::generic::ty::*; use parse::token::InternedString; use ptr::P; -pub fn expand_deriving_hash(cx: &mut ExtCtxt, - span: Span, - mitem: &MetaItem, - item: &Item, - push: |P|) { +pub fn expand_deriving_hash(cx: &mut ExtCtxt, + span: Span, + mitem: &MetaItem, + item: &Item, + push: F) where + F: FnOnce(P), +{ let (path, generics, args) = if cx.ecfg.deriving_hash_type_parameter { (Path::new_(vec!("std", "hash", "Hash"), None, diff --git a/src/libsyntax/ext/deriving/primitive.rs b/src/libsyntax/ext/deriving/primitive.rs index cd2d98b70f105..8abd846373ae1 100644 --- a/src/libsyntax/ext/deriving/primitive.rs +++ b/src/libsyntax/ext/deriving/primitive.rs @@ -18,11 +18,13 @@ use ext::deriving::generic::ty::*; use parse::token::InternedString; use ptr::P; -pub fn expand_deriving_from_primitive(cx: &mut ExtCtxt, - span: Span, - mitem: &MetaItem, - item: &Item, - push: |P|) { +pub fn expand_deriving_from_primitive(cx: &mut ExtCtxt, + span: Span, + mitem: &MetaItem, + item: &Item, + push: F) where + F: FnOnce(P), +{ let inline = cx.meta_word(span, InternedString::new("inline")); let attrs = vec!(cx.attribute(span, inline)); let trait_def = TraitDef { diff --git a/src/libsyntax/ext/deriving/rand.rs b/src/libsyntax/ext/deriving/rand.rs index c4e64d58c2932..4f6e4d1fb3c10 100644 --- a/src/libsyntax/ext/deriving/rand.rs +++ b/src/libsyntax/ext/deriving/rand.rs @@ -17,11 +17,13 @@ use ext::deriving::generic::*; use ext::deriving::generic::ty::*; use ptr::P; -pub fn expand_deriving_rand(cx: &mut ExtCtxt, - span: Span, - mitem: &MetaItem, - item: &Item, - push: |P|) { +pub fn expand_deriving_rand(cx: &mut ExtCtxt, + span: Span, + mitem: &MetaItem, + item: &Item, + push: F) where + F: FnOnce(P), +{ 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) - -> P { + fn rand_thing(cx: &mut ExtCtxt, + trait_span: Span, + ctor_path: ast::Path, + summary: &StaticFields, + mut rand_call: F) + -> P where + F: FnMut(&mut ExtCtxt, Span) -> P, + { let path = cx.expr_path(ctor_path.clone()); match *summary { Unnamed(ref fields) => { diff --git a/src/libsyntax/ext/deriving/show.rs b/src/libsyntax/ext/deriving/show.rs index 322a84eaa2be0..a68b521bbc9a2 100644 --- a/src/libsyntax/ext/deriving/show.rs +++ b/src/libsyntax/ext/deriving/show.rs @@ -21,11 +21,13 @@ use ptr::P; use std::collections::HashMap; -pub fn expand_deriving_show(cx: &mut ExtCtxt, - span: Span, - mitem: &MetaItem, - item: &Item, - push: |P|) { +pub fn expand_deriving_show(cx: &mut ExtCtxt, + span: Span, + mitem: &MetaItem, + item: &Item, + push: F) where + F: FnOnce(P), +{ // &mut ::std::fmt::Formatter let fmtr = Ptr(box Literal(Path::new(vec!("std", "fmt", "Formatter"))), Borrowed(None, ast::MutMutable)); diff --git a/src/libsyntax/ext/deriving/zero.rs b/src/libsyntax/ext/deriving/zero.rs index 7f265b529ffea..ea32549cad266 100644 --- a/src/libsyntax/ext/deriving/zero.rs +++ b/src/libsyntax/ext/deriving/zero.rs @@ -17,11 +17,13 @@ use ext::deriving::generic::ty::*; use parse::token::InternedString; use ptr::P; -pub fn expand_deriving_zero(cx: &mut ExtCtxt, - span: Span, - mitem: &MetaItem, - item: &Item, - push: |P|) { +pub fn expand_deriving_zero(cx: &mut ExtCtxt, + span: Span, + mitem: &MetaItem, + item: &Item, + push: F) where + F: FnOnce(P), +{ let inline = cx.meta_word(span, InternedString::new("inline")); let attrs = vec!(cx.attribute(span, inline)); let trait_def = TraitDef { diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index a697d332d16af..9c4e85f16ff85 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -238,11 +238,13 @@ pub fn expand_expr(e: P, fld: &mut MacroExpander) -> P { /// 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(mac: ast::Mac, span: codemap::Span, - parse_thunk: |Box|->Option, - mark_thunk: |T,Mrk|->T, - fld: &mut MacroExpander) - -> Option +fn expand_mac_invoc(mac: ast::Mac, span: codemap::Span, + parse_thunk: F, + mark_thunk: G, + fld: &mut MacroExpander) + -> Option where + F: FnOnce(Box) -> Option, + G: FnOnce(T, Mrk) -> T, { match mac.node { // it would almost certainly be cleaner to pass the whole diff --git a/src/libsyntax/ext/mtwt.rs b/src/libsyntax/ext/mtwt.rs index 48120b575acd2..a4e06aeaf63b9 100644 --- a/src/libsyntax/ext/mtwt.rs +++ b/src/libsyntax/ext/mtwt.rs @@ -105,9 +105,11 @@ pub fn apply_renames(renames: &RenameList, ctxt: SyntaxContext) -> SyntaxContext } /// Fetch the SCTable from TLS, create one if it doesn't yet exist. -pub fn with_sctable(op: |&SCTable| -> T) -> T { +pub fn with_sctable(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(op: |&mut ResolveTable| -> T) -> T { +fn with_resolve_table_mut(op: F) -> T where + F: FnOnce(&mut ResolveTable) -> T, +{ thread_local!(static RESOLVE_TABLE_KEY: RefCell = { RefCell::new(HashMap::new()) }) - RESOLVE_TABLE_KEY.with(|slot| op(&mut *slot.borrow_mut())) + RESOLVE_TABLE_KEY.with(move |slot| op(&mut *slot.borrow_mut())) } /// Resolve a syntax object to a name, per MTWT. diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs index 69e311c57f5ab..0318dd5b0cd2d 100644 --- a/src/libsyntax/fold.rs +++ b/src/libsyntax/fold.rs @@ -32,11 +32,11 @@ use std::rc::Rc; // This could have a better place to live. pub trait MoveMap { - fn move_map(self, f: |T| -> T) -> Self; + fn move_map(self, f: F) -> Self where F: FnMut(T) -> T; } impl MoveMap for Vec { - fn move_map(mut self, f: |T| -> T) -> Vec { + fn move_map(mut self, mut f: F) -> Vec 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 MoveMap for Vec { } impl MoveMap for OwnedSlice { - fn move_map(self, f: |T| -> T) -> OwnedSlice { + fn move_map(self, f: F) -> OwnedSlice 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 ea305642f6655..5d5b56d444f8e 100644 --- a/src/libsyntax/lib.rs +++ b/src/libsyntax/lib.rs @@ -25,6 +25,7 @@ #![allow(unknown_features)] #![feature(macro_rules, globs, default_type_params, phase, slicing_syntax)] #![feature(quote, unsafe_destructor, import_shadowing)] +#![feature(unboxed_closures)] extern crate arena; extern crate fmt_macros; diff --git a/src/libsyntax/owned_slice.rs b/src/libsyntax/owned_slice.rs index 43b428b5a1c41..8e418e46921ff 100644 --- a/src/libsyntax/owned_slice.rs +++ b/src/libsyntax/owned_slice.rs @@ -49,7 +49,7 @@ impl OwnedSlice { self.into_vec().into_iter() } - pub fn map(&self, f: |&T| -> U) -> OwnedSlice { + pub fn map U>(&self, f: F) -> OwnedSlice { self.iter().map(f).collect() } } diff --git a/src/libsyntax/parse/lexer/mod.rs b/src/libsyntax/parse/lexer/mod.rs index 4c15fae9feb87..50c7258fe1c7b 100644 --- a/src/libsyntax/parse/lexer/mod.rs +++ b/src/libsyntax/parse/lexer/mod.rs @@ -244,7 +244,9 @@ impl<'a> StringReader<'a> { /// Calls `f` with a string slice of the source text spanning from `start` /// up to but excluding `self.last_pos`, meaning the slice does not include /// the character `self.curr`. - pub fn with_str_from(&self, start: BytePos, f: |s: &str| -> T) -> T { + pub fn with_str_from(&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(&self, start: BytePos, end: BytePos, f: |s: &str| -> T) -> T { + fn with_str_from_to(&self, start: BytePos, end: BytePos, f: F) -> T where + F: FnOnce(&str) -> T, + { f(self.filemap.src.slice( self.byte_offset(start).to_uint(), self.byte_offset(end).to_uint())) diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 92c7380a61ded..8c44f9fdf26b7 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -718,11 +718,12 @@ impl<'a> Parser<'a> { } /// Parse a sequence bracketed by `|` and `|`, stopping before the `|`. - fn parse_seq_to_before_or( - &mut self, - sep: &token::Token, - f: |&mut Parser| -> T) - -> Vec { + fn parse_seq_to_before_or(&mut self, + sep: &token::Token, + mut f: F) + -> Vec 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(&mut self, - sep: Option, - f: |&mut Parser| -> Option) - -> (OwnedSlice, bool) { + pub fn parse_seq_to_before_gt_or_return(&mut self, + sep: Option, + mut f: F) + -> (OwnedSlice, bool) where + F: FnMut(&mut Parser) -> Option, + { 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(&mut self, - sep: Option, - f: |&mut Parser| -> T) - -> OwnedSlice { + pub fn parse_seq_to_before_gt(&mut self, + sep: Option, + mut f: F) + -> OwnedSlice 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(&mut self, - sep: Option, - f: |&mut Parser| -> T) - -> OwnedSlice { + pub fn parse_seq_to_gt(&mut self, + sep: Option, + f: F) + -> OwnedSlice 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(&mut self, - sep: Option, - f: |&mut Parser| -> Option) - -> (OwnedSlice, bool) { + pub fn parse_seq_to_gt_or_return(&mut self, + sep: Option, + f: F) + -> (OwnedSlice, bool) where + F: FnMut(&mut Parser) -> Option, + { 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( - &mut self, - ket: &token::Token, - sep: SeqSep, - f: |&mut Parser| -> T) - -> Vec { + pub fn parse_seq_to_end(&mut self, + ket: &token::Token, + sep: SeqSep, + f: F) + -> Vec 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( - &mut self, - ket: &token::Token, - sep: SeqSep, - f: |&mut Parser| -> T) - -> Vec { + pub fn parse_seq_to_before_end(&mut self, + ket: &token::Token, + sep: SeqSep, + mut f: F) + -> Vec 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( - &mut self, - bra: &token::Token, - ket: &token::Token, - sep: SeqSep, - f: |&mut Parser| -> T) - -> Vec { + pub fn parse_unspanned_seq(&mut self, + bra: &token::Token, + ket: &token::Token, + sep: SeqSep, + f: F) + -> Vec 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( - &mut self, - bra: &token::Token, - ket: &token::Token, - sep: SeqSep, - f: |&mut Parser| -> T) - -> Vec { + pub fn parse_enum_variant_seq(&mut self, + bra: &token::Token, + ket: &token::Token, + sep: SeqSep, + f: F) + -> Vec 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( - &mut self, - bra: &token::Token, - ket: &token::Token, - sep: SeqSep, - f: |&mut Parser| -> T) - -> Spanned > { + pub fn parse_seq(&mut self, + bra: &token::Token, + ket: &token::Token, + sep: SeqSep, + f: F) + -> Spanned> 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(&mut self, distance: uint, f: |&token::Token| -> R) - -> R { + pub fn look_ahead(&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) { + fn parse_fn_decl_with_self(&mut self, parse_arg_fn: F) -> (ExplicitSelf, P) where + F: FnMut(&mut Parser) -> Arg, + { fn maybe_parse_borrowed_explicit_self(this: &mut Parser) -> ast::ExplicitSelf_ { // The following things are possible to see here: diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index 26373d00aaf60..6d8b8dcb8ba5d 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -165,7 +165,9 @@ impl<'a> State<'a> { } } -pub fn to_string(f: |&mut State| -> IoResult<()>) -> String { +pub fn to_string(f: F) -> 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) -> 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(&mut self, b: Breaks, elts: &[T], - op: |&mut State, &T| -> IoResult<()>) - -> IoResult<()> { + pub fn commasep(&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( - &mut self, - b: Breaks, - elts: &[T], - op: |&mut State, &T| -> IoResult<()>, - get_span: |&T| -> codemap::Span) -> IoResult<()> { + pub fn commasep_cmnt(&mut self, + b: Breaks, + elts: &[T], + mut op: F, + mut get_span: G) -> IoResult<()> where + F: FnMut(&mut State, &T) -> IoResult<()>, + G: FnMut(&T) -> codemap::Span, + { try!(self.rbox(0u, b)); let len = elts.len(); let mut i = 0u; diff --git a/src/libsyntax/ptr.rs b/src/libsyntax/ptr.rs index 1b231ed861b89..1b3ebde2461e6 100644 --- a/src/libsyntax/ptr.rs +++ b/src/libsyntax/ptr.rs @@ -56,12 +56,16 @@ pub fn P(value: T) -> P { impl P { /// Move out of the pointer. /// Intended for chaining transformations not covered by `map`. - pub fn and_then(self, f: |T| -> U) -> U { + pub fn and_then(self, f: F) -> U where + F: FnOnce(T) -> U, + { f(*self.ptr) } /// Transform the inner value, consuming `self` and producing a new `P`. - pub fn map(mut self, f: |T| -> T) -> P { + pub fn map(mut self, f: F) -> P where + F: FnOnce(T) -> T, + { unsafe { let p = &mut *self.ptr; // FIXME(#5016) this shouldn't need to zero to be safe. diff --git a/src/libsyntax/util/parser_testing.rs b/src/libsyntax/util/parser_testing.rs index c1ea8f60b8201..83bbff8473d04 100644 --- a/src/libsyntax/util/parser_testing.rs +++ b/src/libsyntax/util/parser_testing.rs @@ -31,7 +31,9 @@ pub fn string_to_parser<'a>(ps: &'a ParseSess, source_str: String) -> Parser<'a> source_str) } -fn with_error_checking_parse(s: String, f: |&mut Parser| -> T) -> T { +fn with_error_checking_parse(s: String, f: F) -> T where + F: FnOnce(&mut Parser) -> T, +{ let ps = new_parse_sess(); let mut p = string_to_parser(&ps, s); let x = f(&mut p); diff --git a/src/libsyntax/util/small_vector.rs b/src/libsyntax/util/small_vector.rs index d56e4f704499e..8d050e34abf4c 100644 --- a/src/libsyntax/util/small_vector.rs +++ b/src/libsyntax/util/small_vector.rs @@ -171,7 +171,7 @@ impl Iterator for MoveItems { } impl MoveMap for SmallVector { - fn move_map(self, f: |T| -> T) -> SmallVector { + fn move_map(self, mut f: F) -> SmallVector 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 ffc26738dd7b2..7436a8af30765 100644 --- a/src/libtest/lib.rs +++ b/src/libtest/lib.rs @@ -32,6 +32,7 @@ html_root_url = "http://doc.rust-lang.org/nightly/")] #![feature(asm, macro_rules, phase, globs, slicing_syntax)] +#![feature(unboxed_closures)] extern crate getopts; extern crate regex; @@ -978,9 +979,11 @@ enum TestEvent { pub type MonitorMsg = (TestDesc, TestResult, Vec ); -fn run_tests(opts: &TestOpts, - tests: Vec , - callback: |e: TestEvent| -> io::IoResult<()>) -> io::IoResult<()> { +fn run_tests(opts: &TestOpts, + tests: Vec , + 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(dummy: T) { impl Bencher { /// Callback for benchmark functions to run in their body. - pub fn iter(&mut self, inner: || -> T) { + pub fn iter(&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(&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 { - + pub fn auto_bench(&mut self, mut f: F) -> stats::Summary 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) -> 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 66cd22dfb08c2..1f75daa7bdecd 100644 --- a/src/libunicode/lib.rs +++ b/src/libunicode/lib.rs @@ -29,6 +29,7 @@ html_playground_url = "http://play.rust-lang.org/")] #![no_std] #![feature(globs)] +#![feature(unboxed_closures)] extern crate core; diff --git a/src/libunicode/u_str.rs b/src/libunicode/u_str.rs index f3aaad549c9aa..80311137b0165 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 bbbd878e8b8ad..112d4fd0912d4 100644 --- a/src/test/bench/core-map.rs +++ b/src/test/bench/core-map.rs @@ -8,13 +8,15 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +#![feature(unboxed_closures)] + use std::collections::{TrieMap, TreeMap, HashMap, HashSet}; use std::os; use std::rand::{Rng, IsaacRng, SeedableRng}; use std::time::Duration; use std::uint; -fn timed(label: &str, f: ||) { +fn timed(label: &str, f: F) where F: FnMut() { println!(" {}: {}", label, Duration::span(f)); } diff --git a/src/test/bench/core-set.rs b/src/test/bench/core-set.rs index 07300b73c85a7..6ba642cc47b75 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(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 24bd26b028813..6e2cd508291e0 100644 --- a/src/test/bench/core-std.rs +++ b/src/test/bench/core-std.rs @@ -12,6 +12,7 @@ // Microbenchmarks for various functions in std and extra #![feature(macro_rules)] +#![feature(unboxed_closures)] use std::io::File; use std::mem::swap; @@ -41,7 +42,7 @@ fn main() { bench!(is_utf8_multibyte); } -fn maybe_run_test(argv: &[String], name: String, test: ||) { +fn maybe_run_test(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 d9fbc08b3211d..fe7635f065cdc 100644 --- a/src/test/compile-fail/coerce-unsafe-to-closure.rs +++ b/src/test/compile-fail/coerce-unsafe-to-closure.rs @@ -10,5 +10,5 @@ fn main() { let x: Option<&[u8]> = Some("foo").map(std::mem::transmute); - //~^ ERROR: mismatched types + //~^ ERROR: is not implemented for the type } diff --git a/src/test/run-pass/assignability-trait.rs b/src/test/run-pass/assignability-trait.rs index f822da4cdcfcf..f623b7911ce6d 100644 --- a/src/test/run-pass/assignability-trait.rs +++ b/src/test/run-pass/assignability-trait.rs @@ -12,19 +12,20 @@ // making method calls, but only if there aren't any matches without // it. +#![feature(unboxed_closures)] trait iterable { - fn iterate(&self, blk: |x: &A| -> bool) -> bool; + fn iterate(&self, blk: F) -> bool where F: FnMut(&A) -> bool; } impl<'a,A> iterable for &'a [A] { - fn iterate(&self, f: |x: &A| -> bool) -> bool { + fn iterate(&self, f: F) -> bool where F: FnMut(&A) -> bool { self.iter().all(f) } } impl iterable for Vec { - fn iterate(&self, f: |x: &A| -> bool) -> bool { + fn iterate(&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 a267b8dcc86d2..da5fa19f816f7 100644 --- a/src/test/run-pass/backtrace.rs +++ b/src/test/run-pass/backtrace.rs @@ -10,6 +10,9 @@ // no-pretty-expanded FIXME #15189 // ignore-windows FIXME #13259 + +#![feature(unboxed_closures)] + use std::os; use std::io::process::Command; use std::finally::Finally; @@ -25,7 +28,7 @@ fn foo() { #[inline(never)] fn double() { - (|| { + (|&mut:| { panic!("once"); }).finally(|| { panic!("twice");