auto merge of #19467 : japaric/rust/uc, r=alexcrichton
This PR moves almost all our current uses of closures, both in public API and internal uses, to the new "unboxed" closures system.
In most cases, downstream code that *only uses* closures will continue to work as it is. The reason is that the `|| {}` syntax can be inferred either as a boxed or an "unboxed" closure according to the context. For example the following code will continue to work:
``` rust
some_option.map(|x| x.transform_with(upvar))
```
And will get silently upgraded to an "unboxed" closure.
In some other cases, it may be necessary to "annotate" which `Fn*` trait the closure implements:
```
// Change this
|x| { /* body */}
// to either of these
|: x| { /* body */} // closure implements the FnOnce trait
|&mut : x| { /* body */} // FnMut
|&: x| { /* body */} // Fn
```
This mainly occurs when the closure is assigned to a variable first, and then passed to a function/method.
``` rust
let closure = |: x| x.transform_with(upvar);
some.option.map(closure)
```
(It's very likely that in the future, an improved inference engine will make this annotation unnecessary)
Other cases that require annotation are closures that implement some trait via a blanket `impl`, for example:
- `std::finally::Finally`
- `regex::Replacer`
- `std::str::CharEq`
``` rust
string.trim_left_chars(|c: char| c.is_whitespace())
//~^ ERROR: the trait `Fn<(char,), bool>` is not implemented for the type `|char| -> bool`
string.trim_left_chars(|&: c: char| c.is_whitespace()) // OK
```
Finally, all implementations of traits that contain boxed closures in the arguments of their methods are now broken. And will need to be updated to use unboxed closures. These are the main affected traits:
- `serialize::Decoder`
- `serialize::DecoderHelpers`
- `serialize::Encoder`
- `serialize::EncoderHelpers`
- `rustrt::ToCStr`
For example, change this:
``` rust
// libserialize/json.rs
impl<'a> Encoder<io::IoError> for Encoder<'a> {
fn emit_enum(&mut self,
_name: &str,
f: |&mut Encoder<'a>| -> EncodeResult) -> EncodeResult {
f(self)
}
}
```
to:
``` rust
// libserialize/json.rs
impl<'a> Encoder<io::IoError> for Encoder<'a> {
fn emit_enum<F>(&mut self, _name: &str, f: F) -> EncodeResult where
F: FnOnce(&mut Encoder<'a>) -> EncodeResult
{
f(self)
}
}
```
[breaking-change]
---
### How the `Fn*` bound has been selected
I've chosen the bounds to make the functions/structs as "generic as possible", i.e. to let them allow the maximum amount of input.
- An `F: FnOnce` bound accepts the three kinds of closures: `|:|`, `|&mut:|` and `|&:|`.
- An `F: FnMut` bound only accepts "non-consuming" closures: `|&mut:|` and `|&:|`.
- An `F: Fn` bound only accept the "immutable environment" closures: `|&:|`.
This means that whenever possible the `FnOnce` bound has been used, if the `FnOnce` bound couldn't be used, then the `FnMut` was used. The `Fn` bound was never used in the whole repository.
The `FnMut` bound was the most used, because it resembles the semantics of the current boxed closures: the closure can modify its environment, and the closure may be called several times.
The `FnOnce` bound allows new semantics: you can move out the upvars when the closure is called. This can be effectively paired with the `move || {}` syntax to transfer ownership from the environment to the closure caller.
In the case of trait methods, is hard to select the "right" bound since we can't control how the trait may be implemented by downstream users. In these cases, I have selected the bound based on how we use these traits in the repository. For this reason the selected bounds may not be ideal, and may require tweaking before stabilization.
r? @aturon
This commit is contained in:
commit
444fa1b7cf
194 changed files with 2524 additions and 1751 deletions
|
|
@ -28,6 +28,7 @@
|
|||
html_root_url = "http://doc.rust-lang.org/nightly/")]
|
||||
|
||||
#![feature(unsafe_destructor)]
|
||||
#![feature(unboxed_closures)]
|
||||
#![allow(missing_docs)]
|
||||
|
||||
extern crate alloc;
|
||||
|
|
@ -209,7 +210,7 @@ impl Arena {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
fn alloc_copy<T>(&self, op: || -> T) -> &mut T {
|
||||
fn alloc_copy<T, F>(&self, op: F) -> &mut T where F: FnOnce() -> T {
|
||||
unsafe {
|
||||
let ptr = self.alloc_copy_inner(mem::size_of::<T>(),
|
||||
mem::min_align_of::<T>());
|
||||
|
|
@ -263,7 +264,7 @@ impl Arena {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
fn alloc_noncopy<T>(&self, op: || -> T) -> &mut T {
|
||||
fn alloc_noncopy<T, F>(&self, op: F) -> &mut T where F: FnOnce() -> T {
|
||||
unsafe {
|
||||
let tydesc = get_tydesc::<T>();
|
||||
let (ty_ptr, ptr) =
|
||||
|
|
@ -287,7 +288,7 @@ impl Arena {
|
|||
/// Allocates a new item in the arena, using `op` to initialize the value,
|
||||
/// and returns a reference to it.
|
||||
#[inline]
|
||||
pub fn alloc<T>(&self, op: || -> T) -> &mut T {
|
||||
pub fn alloc<T, F>(&self, op: F) -> &mut T where F: FnOnce() -> T {
|
||||
unsafe {
|
||||
if intrinsics::needs_drop::<T>() {
|
||||
self.alloc_noncopy(op)
|
||||
|
|
@ -339,7 +340,7 @@ fn test_arena_destructors_fail() {
|
|||
arena.alloc(|| { [0u8, 1u8, 2u8] });
|
||||
}
|
||||
// Now, panic while allocating
|
||||
arena.alloc::<Rc<int>>(|| {
|
||||
arena.alloc::<Rc<int>, _>(|| {
|
||||
panic!();
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,9 +13,14 @@ use std::rand;
|
|||
use std::rand::Rng;
|
||||
use test::Bencher;
|
||||
|
||||
pub fn insert_rand_n<M>(n: uint, map: &mut M, b: &mut Bencher,
|
||||
insert: |&mut M, uint|,
|
||||
remove: |&mut M, uint|) {
|
||||
pub fn insert_rand_n<M, I, R>(n: uint,
|
||||
map: &mut M,
|
||||
b: &mut Bencher,
|
||||
mut insert: I,
|
||||
mut remove: R) where
|
||||
I: FnMut(&mut M, uint),
|
||||
R: FnMut(&mut M, uint),
|
||||
{
|
||||
// setup
|
||||
let mut rng = rand::weak_rng();
|
||||
|
||||
|
|
@ -31,9 +36,14 @@ pub fn insert_rand_n<M>(n: uint, map: &mut M, b: &mut Bencher,
|
|||
})
|
||||
}
|
||||
|
||||
pub fn insert_seq_n<M>(n: uint, map: &mut M, b: &mut Bencher,
|
||||
insert: |&mut M, uint|,
|
||||
remove: |&mut M, uint|) {
|
||||
pub fn insert_seq_n<M, I, R>(n: uint,
|
||||
map: &mut M,
|
||||
b: &mut Bencher,
|
||||
mut insert: I,
|
||||
mut remove: R) where
|
||||
I: FnMut(&mut M, uint),
|
||||
R: FnMut(&mut M, uint),
|
||||
{
|
||||
// setup
|
||||
for i in range(0u, n) {
|
||||
insert(map, i * 2);
|
||||
|
|
@ -48,9 +58,14 @@ pub fn insert_seq_n<M>(n: uint, map: &mut M, b: &mut Bencher,
|
|||
})
|
||||
}
|
||||
|
||||
pub fn find_rand_n<M, T>(n: uint, map: &mut M, b: &mut Bencher,
|
||||
insert: |&mut M, uint|,
|
||||
find: |&M, uint| -> T) {
|
||||
pub fn find_rand_n<M, T, I, F>(n: uint,
|
||||
map: &mut M,
|
||||
b: &mut Bencher,
|
||||
mut insert: I,
|
||||
mut find: F) where
|
||||
I: FnMut(&mut M, uint),
|
||||
F: FnMut(&M, uint) -> T,
|
||||
{
|
||||
// setup
|
||||
let mut rng = rand::weak_rng();
|
||||
let mut keys = Vec::from_fn(n, |_| rng.gen::<uint>() % n);
|
||||
|
|
@ -70,9 +85,14 @@ pub fn find_rand_n<M, T>(n: uint, map: &mut M, b: &mut Bencher,
|
|||
})
|
||||
}
|
||||
|
||||
pub fn find_seq_n<M, T>(n: uint, map: &mut M, b: &mut Bencher,
|
||||
insert: |&mut M, uint|,
|
||||
find: |&M, uint| -> T) {
|
||||
pub fn find_seq_n<M, T, I, F>(n: uint,
|
||||
map: &mut M,
|
||||
b: &mut Bencher,
|
||||
mut insert: I,
|
||||
mut find: F) where
|
||||
I: FnMut(&mut M, uint),
|
||||
F: FnMut(&M, uint) -> T,
|
||||
{
|
||||
// setup
|
||||
for i in range(0u, n) {
|
||||
insert(map, i);
|
||||
|
|
|
|||
|
|
@ -174,7 +174,7 @@ impl<'a> Iterator<(uint, u32)> for MaskWords<'a> {
|
|||
|
||||
impl Bitv {
|
||||
#[inline]
|
||||
fn process(&mut self, other: &Bitv, op: |u32, u32| -> u32) -> bool {
|
||||
fn process<F>(&mut self, other: &Bitv, mut op: F) -> bool where F: FnMut(u32, u32) -> u32 {
|
||||
let len = other.storage.len();
|
||||
assert_eq!(self.storage.len(), len);
|
||||
let mut changed = false;
|
||||
|
|
@ -816,7 +816,7 @@ pub fn from_bytes(bytes: &[u8]) -> Bitv {
|
|||
/// let bv = from_fn(5, |i| { i % 2 == 0 });
|
||||
/// assert!(bv.eq_vec(&[true, false, true, false, true]));
|
||||
/// ```
|
||||
pub fn from_fn(len: uint, f: |index: uint| -> bool) -> Bitv {
|
||||
pub fn from_fn<F>(len: uint, mut f: F) -> Bitv where F: FnMut(uint) -> bool {
|
||||
let mut bitv = Bitv::with_capacity(len, false);
|
||||
for i in range(0u, len) {
|
||||
bitv.set(i, f(i));
|
||||
|
|
@ -1182,7 +1182,7 @@ impl BitvSet {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
fn other_op(&mut self, other: &BitvSet, f: |u32, u32| -> u32) {
|
||||
fn other_op<F>(&mut self, other: &BitvSet, mut f: F) where F: FnMut(u32, u32) -> u32 {
|
||||
// Expand the vector if necessary
|
||||
self.reserve(other.capacity());
|
||||
|
||||
|
|
@ -1277,10 +1277,12 @@ impl BitvSet {
|
|||
#[inline]
|
||||
#[unstable = "matches collection reform specification, waiting for dust to settle"]
|
||||
pub fn union<'a>(&'a self, other: &'a BitvSet) -> TwoBitPositions<'a> {
|
||||
fn or(w1: u32, w2: u32) -> u32 { w1 | w2 }
|
||||
|
||||
TwoBitPositions {
|
||||
set: self,
|
||||
other: other,
|
||||
merge: |w1, w2| w1 | w2,
|
||||
merge: or,
|
||||
current_word: 0u32,
|
||||
next_idx: 0u
|
||||
}
|
||||
|
|
@ -1306,11 +1308,13 @@ impl BitvSet {
|
|||
#[inline]
|
||||
#[unstable = "matches collection reform specification, waiting for dust to settle"]
|
||||
pub fn intersection<'a>(&'a self, other: &'a BitvSet) -> Take<TwoBitPositions<'a>> {
|
||||
fn bitand(w1: u32, w2: u32) -> u32 { w1 & w2 }
|
||||
|
||||
let min = cmp::min(self.capacity(), other.capacity());
|
||||
TwoBitPositions {
|
||||
set: self,
|
||||
other: other,
|
||||
merge: |w1, w2| w1 & w2,
|
||||
merge: bitand,
|
||||
current_word: 0u32,
|
||||
next_idx: 0
|
||||
}.take(min)
|
||||
|
|
@ -1343,10 +1347,12 @@ impl BitvSet {
|
|||
#[inline]
|
||||
#[unstable = "matches collection reform specification, waiting for dust to settle"]
|
||||
pub fn difference<'a>(&'a self, other: &'a BitvSet) -> TwoBitPositions<'a> {
|
||||
fn diff(w1: u32, w2: u32) -> u32 { w1 & !w2 }
|
||||
|
||||
TwoBitPositions {
|
||||
set: self,
|
||||
other: other,
|
||||
merge: |w1, w2| w1 & !w2,
|
||||
merge: diff,
|
||||
current_word: 0u32,
|
||||
next_idx: 0
|
||||
}
|
||||
|
|
@ -1373,10 +1379,12 @@ impl BitvSet {
|
|||
#[inline]
|
||||
#[unstable = "matches collection reform specification, waiting for dust to settle"]
|
||||
pub fn symmetric_difference<'a>(&'a self, other: &'a BitvSet) -> TwoBitPositions<'a> {
|
||||
fn bitxor(w1: u32, w2: u32) -> u32 { w1 ^ w2 }
|
||||
|
||||
TwoBitPositions {
|
||||
set: self,
|
||||
other: other,
|
||||
merge: |w1, w2| w1 ^ w2,
|
||||
merge: bitxor,
|
||||
current_word: 0u32,
|
||||
next_idx: 0
|
||||
}
|
||||
|
|
@ -1614,7 +1622,7 @@ pub struct BitPositions<'a> {
|
|||
pub struct TwoBitPositions<'a> {
|
||||
set: &'a BitvSet,
|
||||
other: &'a BitvSet,
|
||||
merge: |u32, u32|: 'a -> u32,
|
||||
merge: fn(u32, u32) -> u32,
|
||||
current_word: u32,
|
||||
next_idx: uint
|
||||
}
|
||||
|
|
|
|||
|
|
@ -107,10 +107,12 @@ pub struct MoveEntries<K, V> {
|
|||
}
|
||||
|
||||
/// An iterator over a BTreeMap's keys.
|
||||
pub type Keys<'a, K, V> = iter::Map<'static, (&'a K, &'a V), &'a K, Entries<'a, K, V>>;
|
||||
pub type Keys<'a, K, V> =
|
||||
iter::Map<(&'a K, &'a V), &'a K, Entries<'a, K, V>, fn((&'a K, &'a V)) -> &'a K>;
|
||||
|
||||
/// An iterator over a BTreeMap's values.
|
||||
pub type Values<'a, K, V> = iter::Map<'static, (&'a K, &'a V), &'a V, Entries<'a, K, V>>;
|
||||
pub type Values<'a, K, V> =
|
||||
iter::Map<(&'a K, &'a V), &'a V, Entries<'a, K, V>, fn((&'a K, &'a V)) -> &'a V>;
|
||||
|
||||
/// A view into a single entry in a map, which may either be vacant or occupied.
|
||||
pub enum Entry<'a, K:'a, V:'a> {
|
||||
|
|
@ -1207,7 +1209,9 @@ impl<K, V> BTreeMap<K, V> {
|
|||
/// ```
|
||||
#[unstable = "matches collection reform specification, waiting for dust to settle"]
|
||||
pub fn keys<'a>(&'a self) -> Keys<'a, K, V> {
|
||||
self.iter().map(|(k, _)| k)
|
||||
fn first<A, B>((a, _): (A, B)) -> A { a }
|
||||
|
||||
self.iter().map(first)
|
||||
}
|
||||
|
||||
/// Gets an iterator over the values of the map.
|
||||
|
|
@ -1226,7 +1230,9 @@ impl<K, V> BTreeMap<K, V> {
|
|||
/// ```
|
||||
#[unstable = "matches collection reform specification, waiting for dust to settle"]
|
||||
pub fn values<'a>(&'a self) -> Values<'a, K, V> {
|
||||
self.iter().map(|(_, v)| v)
|
||||
fn second<A, B>((_, b): (A, B)) -> B { b }
|
||||
|
||||
self.iter().map(second)
|
||||
}
|
||||
|
||||
/// Return the number of elements in the map.
|
||||
|
|
|
|||
|
|
@ -36,7 +36,8 @@ pub struct BTreeSet<T>{
|
|||
pub type Items<'a, T> = Keys<'a, T, ()>;
|
||||
|
||||
/// An owning iterator over a BTreeSet's items.
|
||||
pub type MoveItems<T> = iter::Map<'static, (T, ()), T, MoveEntries<T, ()>>;
|
||||
pub type MoveItems<T> =
|
||||
iter::Map<(T, ()), T, MoveEntries<T, ()>, fn((T, ())) -> T>;
|
||||
|
||||
/// A lazy iterator producing elements in the set difference (in-order).
|
||||
pub struct DifferenceItems<'a, T:'a> {
|
||||
|
|
@ -87,7 +88,9 @@ impl<T> BTreeSet<T> {
|
|||
/// Gets an iterator for moving out the BtreeSet's contents.
|
||||
#[unstable = "matches collection reform specification, waiting for dust to settle"]
|
||||
pub fn into_iter(self) -> MoveItems<T> {
|
||||
self.map.into_iter().map(|(k, _)| k)
|
||||
fn first<A, B>((a, _): (A, B)) -> A { a }
|
||||
|
||||
self.map.into_iter().map(first)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -600,10 +603,23 @@ mod test {
|
|||
assert!(hash::hash(&x) == hash::hash(&y));
|
||||
}
|
||||
|
||||
fn check(a: &[int],
|
||||
b: &[int],
|
||||
expected: &[int],
|
||||
f: |&BTreeSet<int>, &BTreeSet<int>, f: |&int| -> bool| -> bool) {
|
||||
struct Counter<'a, 'b> {
|
||||
i: &'a mut uint,
|
||||
expected: &'b [int],
|
||||
}
|
||||
|
||||
impl<'a, 'b> FnMut(&int) -> bool for Counter<'a, 'b> {
|
||||
extern "rust-call" fn call_mut(&mut self, (&x,): (&int,)) -> bool {
|
||||
assert_eq!(x, self.expected[*self.i]);
|
||||
*self.i += 1;
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
fn check<F>(a: &[int], b: &[int], expected: &[int], f: F) where
|
||||
// FIXME Replace Counter with `Box<FnMut(_) -> _>`
|
||||
F: FnOnce(&BTreeSet<int>, &BTreeSet<int>, Counter) -> bool,
|
||||
{
|
||||
let mut set_a = BTreeSet::new();
|
||||
let mut set_b = BTreeSet::new();
|
||||
|
||||
|
|
@ -611,11 +627,7 @@ mod test {
|
|||
for y in b.iter() { assert!(set_b.insert(*y)) }
|
||||
|
||||
let mut i = 0;
|
||||
f(&set_a, &set_b, |x| {
|
||||
assert_eq!(*x, expected[i]);
|
||||
i += 1;
|
||||
true
|
||||
});
|
||||
f(&set_a, &set_b, Counter { i: &mut i, expected: expected });
|
||||
assert_eq!(i, expected.len());
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -351,18 +351,16 @@ impl<T> DList<T> {
|
|||
/// println!("{}", e); // prints 2, then 4, then 11, then 7, then 8
|
||||
/// }
|
||||
/// ```
|
||||
pub fn insert_when(&mut self, elt: T, f: |&T, &T| -> bool) {
|
||||
{
|
||||
let mut it = self.iter_mut();
|
||||
loop {
|
||||
match it.peek_next() {
|
||||
None => break,
|
||||
Some(x) => if f(x, &elt) { break }
|
||||
}
|
||||
it.next();
|
||||
pub fn insert_when<F>(&mut self, elt: T, mut f: F) where F: FnMut(&T, &T) -> bool {
|
||||
let mut it = self.iter_mut();
|
||||
loop {
|
||||
match it.peek_next() {
|
||||
None => break,
|
||||
Some(x) => if f(x, &elt) { break }
|
||||
}
|
||||
it.insert_next(elt);
|
||||
it.next();
|
||||
}
|
||||
it.insert_next(elt);
|
||||
}
|
||||
|
||||
/// Merges `other` into this `DList`, using the function `f`.
|
||||
|
|
@ -371,7 +369,7 @@ impl<T> DList<T> {
|
|||
/// put `a` in the result if `f(a, b)` is true, and otherwise `b`.
|
||||
///
|
||||
/// This operation should compute in O(max(N, M)) time.
|
||||
pub fn merge(&mut self, mut other: DList<T>, f: |&T, &T| -> bool) {
|
||||
pub fn merge<F>(&mut self, mut other: DList<T>, mut f: F) where F: FnMut(&T, &T) -> bool {
|
||||
{
|
||||
let mut it = self.iter_mut();
|
||||
loop {
|
||||
|
|
|
|||
|
|
@ -94,6 +94,7 @@ use core::cmp;
|
|||
use core::kinds::{Copy, Sized};
|
||||
use core::mem::size_of;
|
||||
use core::mem;
|
||||
use core::ops::FnMut;
|
||||
use core::prelude::{Clone, Greater, Iterator, IteratorExt, Less, None, Option};
|
||||
use core::prelude::{Ord, Ordering, RawPtr, Some, range};
|
||||
use core::ptr;
|
||||
|
|
@ -296,7 +297,7 @@ pub trait CloneSliceAllocPrelude<T> for Sized? {
|
|||
|
||||
/// Partitions the vector into two vectors `(a, b)`, where all
|
||||
/// elements of `a` satisfy `f` and all elements of `b` do not.
|
||||
fn partitioned(&self, f: |&T| -> bool) -> (Vec<T>, Vec<T>);
|
||||
fn partitioned<F>(&self, f: F) -> (Vec<T>, Vec<T>) where F: FnMut(&T) -> bool;
|
||||
|
||||
/// Creates an iterator that yields every possible permutation of the
|
||||
/// vector in succession.
|
||||
|
|
@ -336,7 +337,7 @@ impl<T: Clone> CloneSliceAllocPrelude<T> for [T] {
|
|||
|
||||
|
||||
#[inline]
|
||||
fn partitioned(&self, f: |&T| -> bool) -> (Vec<T>, Vec<T>) {
|
||||
fn partitioned<F>(&self, mut f: F) -> (Vec<T>, Vec<T>) where F: FnMut(&T) -> bool {
|
||||
let mut lefts = Vec::new();
|
||||
let mut rights = Vec::new();
|
||||
|
||||
|
|
@ -361,7 +362,7 @@ impl<T: Clone> CloneSliceAllocPrelude<T> for [T] {
|
|||
|
||||
}
|
||||
|
||||
fn insertion_sort<T>(v: &mut [T], compare: |&T, &T| -> Ordering) {
|
||||
fn insertion_sort<T, F>(v: &mut [T], mut compare: F) where F: FnMut(&T, &T) -> Ordering {
|
||||
let len = v.len() as int;
|
||||
let buf_v = v.as_mut_ptr();
|
||||
|
||||
|
|
@ -403,7 +404,7 @@ fn insertion_sort<T>(v: &mut [T], compare: |&T, &T| -> Ordering) {
|
|||
}
|
||||
}
|
||||
|
||||
fn merge_sort<T>(v: &mut [T], compare: |&T, &T| -> Ordering) {
|
||||
fn merge_sort<T, F>(v: &mut [T], mut compare: F) where F: FnMut(&T, &T) -> Ordering {
|
||||
// warning: this wildly uses unsafe.
|
||||
static BASE_INSERTION: uint = 32;
|
||||
static LARGE_INSERTION: uint = 16;
|
||||
|
|
@ -611,7 +612,7 @@ pub trait SliceAllocPrelude<T> for Sized? {
|
|||
/// v.sort_by(|a, b| b.cmp(a));
|
||||
/// assert!(v == [5, 4, 3, 2, 1]);
|
||||
/// ```
|
||||
fn sort_by(&mut self, compare: |&T, &T| -> Ordering);
|
||||
fn sort_by<F>(&mut self, compare: F) where F: FnMut(&T, &T) -> Ordering;
|
||||
|
||||
/// Consumes `src` and moves as many elements as it can into `self`
|
||||
/// from the range [start,end).
|
||||
|
|
@ -639,7 +640,7 @@ pub trait SliceAllocPrelude<T> for Sized? {
|
|||
|
||||
impl<T> SliceAllocPrelude<T> for [T] {
|
||||
#[inline]
|
||||
fn sort_by(&mut self, compare: |&T, &T| -> Ordering) {
|
||||
fn sort_by<F>(&mut self, compare: F) where F: FnMut(&T, &T) -> Ordering {
|
||||
merge_sort(self, compare)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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]
|
||||
|
|
|
|||
|
|
@ -234,7 +234,9 @@ impl<K: Ord, V> TreeMap<K, V> {
|
|||
/// ```
|
||||
#[unstable = "matches collection reform specification, waiting for dust to settle"]
|
||||
pub fn keys<'a>(&'a self) -> Keys<'a, K, V> {
|
||||
self.iter().map(|(k, _v)| k)
|
||||
fn first<A, B>((a, _): (A, B)) -> A { a }
|
||||
|
||||
self.iter().map(first)
|
||||
}
|
||||
|
||||
/// Gets a lazy iterator over the values in the map, in ascending order
|
||||
|
|
@ -256,7 +258,9 @@ impl<K: Ord, V> TreeMap<K, V> {
|
|||
/// ```
|
||||
#[unstable = "matches collection reform specification, waiting for dust to settle"]
|
||||
pub fn values<'a>(&'a self) -> Values<'a, K, V> {
|
||||
self.iter().map(|(_k, v)| v)
|
||||
fn second<A, B>((_, b): (A, B)) -> B { b }
|
||||
|
||||
self.iter().map(second)
|
||||
}
|
||||
|
||||
/// Gets a lazy iterator over the key-value pairs in the map, in ascending order.
|
||||
|
|
@ -612,7 +616,7 @@ impl<K, V> TreeMap<K, V> {
|
|||
/// ```
|
||||
#[inline]
|
||||
#[experimental = "likely to be renamed, may be removed"]
|
||||
pub fn find_with(&self, f:|&K| -> Ordering) -> Option<&V> {
|
||||
pub fn find_with<F>(&self, f: F) -> Option<&V> where F: FnMut(&K) -> Ordering {
|
||||
tree_find_with(&self.root, f)
|
||||
}
|
||||
|
||||
|
|
@ -637,7 +641,9 @@ impl<K, V> TreeMap<K, V> {
|
|||
/// ```
|
||||
#[inline]
|
||||
#[experimental = "likely to be renamed, may be removed"]
|
||||
pub fn find_with_mut<'a>(&'a mut self, f:|&K| -> Ordering) -> Option<&'a mut V> {
|
||||
pub fn find_with_mut<'a, F>(&'a mut self, f: F) -> Option<&'a mut V> where
|
||||
F: FnMut(&K) -> Ordering
|
||||
{
|
||||
tree_find_with_mut(&mut self.root, f)
|
||||
}
|
||||
}
|
||||
|
|
@ -863,11 +869,11 @@ pub struct RevMutEntries<'a, K:'a, V:'a> {
|
|||
|
||||
/// TreeMap keys iterator.
|
||||
pub type Keys<'a, K, V> =
|
||||
iter::Map<'static, (&'a K, &'a V), &'a K, Entries<'a, K, V>>;
|
||||
iter::Map<(&'a K, &'a V), &'a K, Entries<'a, K, V>, fn((&'a K, &'a V)) -> &'a K>;
|
||||
|
||||
/// TreeMap values iterator.
|
||||
pub type Values<'a, K, V> =
|
||||
iter::Map<'static, (&'a K, &'a V), &'a V, Entries<'a, K, V>>;
|
||||
iter::Map<(&'a K, &'a V), &'a V, Entries<'a, K, V>, fn((&'a K, &'a V)) -> &'a V>;
|
||||
|
||||
|
||||
// FIXME #5846 we want to be able to choose between &x and &mut x
|
||||
|
|
@ -1125,8 +1131,12 @@ fn split<K: Ord, V>(node: &mut Box<TreeNode<K, V>>) {
|
|||
// Next 2 functions have the same convention: comparator gets
|
||||
// at input current key and returns search_key cmp cur_key
|
||||
// (i.e. search_key.cmp(&cur_key))
|
||||
fn tree_find_with<'r, K, V>(node: &'r Option<Box<TreeNode<K, V>>>,
|
||||
f: |&K| -> Ordering) -> Option<&'r V> {
|
||||
fn tree_find_with<'r, K, V, F>(
|
||||
node: &'r Option<Box<TreeNode<K, V>>>,
|
||||
mut f: F,
|
||||
) -> Option<&'r V> where
|
||||
F: FnMut(&K) -> Ordering,
|
||||
{
|
||||
let mut current: &'r Option<Box<TreeNode<K, V>>> = node;
|
||||
loop {
|
||||
match *current {
|
||||
|
|
@ -1143,8 +1153,12 @@ fn tree_find_with<'r, K, V>(node: &'r Option<Box<TreeNode<K, V>>>,
|
|||
}
|
||||
|
||||
// See comments above tree_find_with
|
||||
fn tree_find_with_mut<'r, K, V>(node: &'r mut Option<Box<TreeNode<K, V>>>,
|
||||
f: |&K| -> Ordering) -> Option<&'r mut V> {
|
||||
fn tree_find_with_mut<'r, K, V, F>(
|
||||
node: &'r mut Option<Box<TreeNode<K, V>>>,
|
||||
mut f: F,
|
||||
) -> Option<&'r mut V> where
|
||||
F: FnMut(&K) -> Ordering,
|
||||
{
|
||||
|
||||
let mut current = node;
|
||||
loop {
|
||||
|
|
|
|||
|
|
@ -205,7 +205,9 @@ impl<T: Ord> TreeSet<T> {
|
|||
#[inline]
|
||||
#[unstable = "matches collection reform specification, waiting for dust to settle"]
|
||||
pub fn into_iter(self) -> MoveSetItems<T> {
|
||||
self.map.into_iter().map(|(value, _)| value)
|
||||
fn first<A, B>((a, _): (A, B)) -> A { a }
|
||||
|
||||
self.map.into_iter().map(first)
|
||||
}
|
||||
|
||||
/// Gets a lazy iterator pointing to the first value not less than `v` (greater or equal).
|
||||
|
|
@ -560,7 +562,7 @@ pub struct RevSetItems<'a, T:'a> {
|
|||
}
|
||||
|
||||
/// A lazy forward iterator over a set that consumes the set while iterating.
|
||||
pub type MoveSetItems<T> = iter::Map<'static, (T, ()), T, MoveEntries<T, ()>>;
|
||||
pub type MoveSetItems<T> = iter::Map<(T, ()), T, MoveEntries<T, ()>, fn((T, ())) -> T>;
|
||||
|
||||
/// A lazy iterator producing elements in the set difference (in-order).
|
||||
pub struct DifferenceItems<'a, T:'a> {
|
||||
|
|
@ -934,10 +936,23 @@ mod test {
|
|||
assert!(hash::hash(&x) == hash::hash(&y));
|
||||
}
|
||||
|
||||
fn check(a: &[int],
|
||||
b: &[int],
|
||||
expected: &[int],
|
||||
f: |&TreeSet<int>, &TreeSet<int>, f: |&int| -> bool| -> bool) {
|
||||
struct Counter<'a, 'b> {
|
||||
i: &'a mut uint,
|
||||
expected: &'b [int],
|
||||
}
|
||||
|
||||
impl<'a, 'b> FnMut(&int) -> bool for Counter<'a, 'b> {
|
||||
extern "rust-call" fn call_mut(&mut self, (&x,): (&int,)) -> bool {
|
||||
assert_eq!(x, self.expected[*self.i]);
|
||||
*self.i += 1;
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
fn check<F>(a: &[int], b: &[int], expected: &[int], f: F) where
|
||||
// FIXME Replace `Counter` with `Box<FnMut(&int) -> bool>`
|
||||
F: FnOnce(&TreeSet<int>, &TreeSet<int>, Counter) -> bool,
|
||||
{
|
||||
let mut set_a = TreeSet::new();
|
||||
let mut set_b = TreeSet::new();
|
||||
|
||||
|
|
@ -945,11 +960,7 @@ mod test {
|
|||
for y in b.iter() { assert!(set_b.insert(*y)) }
|
||||
|
||||
let mut i = 0;
|
||||
f(&set_a, &set_b, |x| {
|
||||
assert_eq!(*x, expected[i]);
|
||||
i += 1;
|
||||
true
|
||||
});
|
||||
f(&set_a, &set_b, Counter { i: &mut i, expected: expected });
|
||||
assert_eq!(i, expected.len());
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -197,14 +197,18 @@ impl<T> TrieMap<T> {
|
|||
/// The iterator's element type is `uint`.
|
||||
#[unstable = "matches collection reform specification, waiting for dust to settle"]
|
||||
pub fn keys<'r>(&'r self) -> Keys<'r, T> {
|
||||
self.iter().map(|(k, _v)| k)
|
||||
fn first<A, B>((a, _): (A, B)) -> A { a }
|
||||
|
||||
self.iter().map(first)
|
||||
}
|
||||
|
||||
/// Gets an iterator visiting all values in ascending order by the keys.
|
||||
/// The iterator's element type is `&'r T`.
|
||||
#[unstable = "matches collection reform specification, waiting for dust to settle"]
|
||||
pub fn values<'r>(&'r self) -> Values<'r, T> {
|
||||
self.iter().map(|(_k, v)| v)
|
||||
fn second<A, B>((_, b): (A, B)) -> B { b }
|
||||
|
||||
self.iter().map(second)
|
||||
}
|
||||
|
||||
/// Gets an iterator over the key-value pairs in the map, ordered by keys.
|
||||
|
|
@ -1091,12 +1095,11 @@ pub struct MutEntries<'a, T:'a> {
|
|||
}
|
||||
|
||||
/// A forward iterator over the keys of a map.
|
||||
pub type Keys<'a, T> =
|
||||
iter::Map<'static, (uint, &'a T), uint, Entries<'a, T>>;
|
||||
pub type Keys<'a, T> = iter::Map<(uint, &'a T), uint, Entries<'a, T>, fn((uint, &'a T)) -> uint>;
|
||||
|
||||
/// A forward iterator over the values of a map.
|
||||
pub type Values<'a, T> =
|
||||
iter::Map<'static, (uint, &'a T), &'a T, Entries<'a, T>>;
|
||||
iter::Map<(uint, &'a T), &'a T, Entries<'a, T>, fn((uint, &'a T)) -> &'a T>;
|
||||
|
||||
// FIXME #5846: see `addr!` above.
|
||||
macro_rules! item { ($i:item) => {$i}}
|
||||
|
|
|
|||
|
|
@ -743,10 +743,23 @@ mod test {
|
|||
assert!(a < b && a <= b);
|
||||
}
|
||||
|
||||
fn check(a: &[uint],
|
||||
b: &[uint],
|
||||
expected: &[uint],
|
||||
f: |&TrieSet, &TrieSet, f: |uint| -> bool| -> bool) {
|
||||
struct Counter<'a, 'b> {
|
||||
i: &'a mut uint,
|
||||
expected: &'b [uint],
|
||||
}
|
||||
|
||||
impl<'a, 'b> FnMut(uint) -> bool for Counter<'a, 'b> {
|
||||
extern "rust-call" fn call_mut(&mut self, (x,): (uint,)) -> bool {
|
||||
assert_eq!(x, self.expected[*self.i]);
|
||||
*self.i += 1;
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
fn check<F>(a: &[uint], b: &[uint], expected: &[uint], f: F) where
|
||||
// FIXME Replace `Counter` with `Box<FnMut(&uint) -> bool>`
|
||||
F: FnOnce(&TrieSet, &TrieSet, Counter) -> bool,
|
||||
{
|
||||
let mut set_a = TrieSet::new();
|
||||
let mut set_b = TrieSet::new();
|
||||
|
||||
|
|
@ -754,11 +767,7 @@ mod test {
|
|||
for y in b.iter() { assert!(set_b.insert(*y)) }
|
||||
|
||||
let mut i = 0;
|
||||
f(&set_a, &set_b, |x| {
|
||||
assert_eq!(x, expected[i]);
|
||||
i += 1;
|
||||
true
|
||||
});
|
||||
f(&set_a, &set_b, Counter { i: &mut i, expected: expected });
|
||||
assert_eq!(i, expected.len());
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -206,7 +206,7 @@ impl<T> Vec<T> {
|
|||
#[inline]
|
||||
#[unstable = "the naming is uncertain as well as this migrating to unboxed \
|
||||
closures in the future"]
|
||||
pub fn from_fn(length: uint, op: |uint| -> T) -> Vec<T> {
|
||||
pub fn from_fn<F>(length: uint, mut op: F) -> Vec<T> where F: FnMut(uint) -> T {
|
||||
unsafe {
|
||||
let mut xs = Vec::with_capacity(length);
|
||||
while xs.len < length {
|
||||
|
|
@ -289,7 +289,7 @@ impl<T> Vec<T> {
|
|||
/// ```
|
||||
#[inline]
|
||||
#[experimental]
|
||||
pub fn partition(self, f: |&T| -> bool) -> (Vec<T>, Vec<T>) {
|
||||
pub fn partition<F>(self, mut f: F) -> (Vec<T>, Vec<T>) where F: FnMut(&T) -> bool {
|
||||
let mut lefts = Vec::new();
|
||||
let mut rights = Vec::new();
|
||||
|
||||
|
|
@ -400,7 +400,7 @@ impl<T: Clone> Vec<T> {
|
|||
/// assert_eq!(odd, vec![1i, 3]);
|
||||
/// ```
|
||||
#[experimental]
|
||||
pub fn partitioned(&self, f: |&T| -> bool) -> (Vec<T>, Vec<T>) {
|
||||
pub fn partitioned<F>(&self, mut f: F) -> (Vec<T>, Vec<T>) where F: FnMut(&T) -> bool {
|
||||
let mut lefts = Vec::new();
|
||||
let mut rights = Vec::new();
|
||||
|
||||
|
|
@ -991,7 +991,7 @@ impl<T> Vec<T> {
|
|||
/// assert_eq!(vec, vec![2, 4]);
|
||||
/// ```
|
||||
#[unstable = "the closure argument may become an unboxed closure"]
|
||||
pub fn retain(&mut self, f: |&T| -> bool) {
|
||||
pub fn retain<F>(&mut self, mut f: F) where F: FnMut(&T) -> bool {
|
||||
let len = self.len();
|
||||
let mut del = 0u;
|
||||
{
|
||||
|
|
@ -1023,7 +1023,7 @@ impl<T> Vec<T> {
|
|||
/// assert_eq!(vec, vec![0, 1, 0, 1, 2]);
|
||||
/// ```
|
||||
#[unstable = "this function may be renamed or change to unboxed closures"]
|
||||
pub fn grow_fn(&mut self, n: uint, f: |uint| -> T) {
|
||||
pub fn grow_fn<F>(&mut self, n: uint, mut f: F) where F: FnMut(uint) -> T {
|
||||
self.reserve(n);
|
||||
for i in range(0u, n) {
|
||||
self.push(f(i));
|
||||
|
|
@ -1570,7 +1570,7 @@ impl<T> Vec<T> {
|
|||
/// let newtyped_bytes = bytes.map_in_place(|x| Newtype(x));
|
||||
/// assert_eq!(newtyped_bytes.as_slice(), [Newtype(0x11), Newtype(0x22)].as_slice());
|
||||
/// ```
|
||||
pub fn map_in_place<U>(self, f: |T| -> U) -> Vec<U> {
|
||||
pub fn map_in_place<U, F>(self, mut f: F) -> Vec<U> where F: FnMut(T) -> U {
|
||||
// FIXME: Assert statically that the types `T` and `U` have the same
|
||||
// size.
|
||||
assert!(mem::size_of::<T>() == mem::size_of::<U>());
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ use core::fmt;
|
|||
use core::iter;
|
||||
use core::iter::{Enumerate, FilterMap};
|
||||
use core::mem::replace;
|
||||
use core::ops::FnOnce;
|
||||
|
||||
use hash::{Hash, Writer};
|
||||
use {vec, slice};
|
||||
|
|
@ -141,14 +142,18 @@ impl<V> VecMap<V> {
|
|||
/// The iterator's element type is `uint`.
|
||||
#[unstable = "matches collection reform specification, waiting for dust to settle"]
|
||||
pub fn keys<'r>(&'r self) -> Keys<'r, V> {
|
||||
self.iter().map(|(k, _v)| k)
|
||||
fn first<A, B>((a, _): (A, B)) -> A { a }
|
||||
|
||||
self.iter().map(first)
|
||||
}
|
||||
|
||||
/// Returns an iterator visiting all values in ascending order by the keys.
|
||||
/// The iterator's element type is `&'r V`.
|
||||
#[unstable = "matches collection reform specification, waiting for dust to settle"]
|
||||
pub fn values<'r>(&'r self) -> Values<'r, V> {
|
||||
self.iter().map(|(_k, v)| v)
|
||||
fn second<A, B>((_, b): (A, B)) -> B { b }
|
||||
|
||||
self.iter().map(second)
|
||||
}
|
||||
|
||||
/// Returns an iterator visiting all key-value pairs in ascending order by the keys.
|
||||
|
|
@ -230,10 +235,12 @@ impl<V> VecMap<V> {
|
|||
/// ```
|
||||
#[unstable = "matches collection reform specification, waiting for dust to settle"]
|
||||
pub fn into_iter(&mut self) -> MoveItems<V> {
|
||||
let values = replace(&mut self.v, vec!());
|
||||
values.into_iter().enumerate().filter_map(|(i, v)| {
|
||||
fn filter<A>((i, v): (uint, Option<A>)) -> Option<(uint, A)> {
|
||||
v.map(|v| (i, v))
|
||||
})
|
||||
}
|
||||
|
||||
let values = replace(&mut self.v, vec!());
|
||||
values.into_iter().enumerate().filter_map(filter)
|
||||
}
|
||||
|
||||
/// Return the number of elements in the map.
|
||||
|
|
@ -446,8 +453,8 @@ impl<V:Clone> VecMap<V> {
|
|||
/// assert!(!map.update(1, vec![3i, 4], |mut old, new| { old.extend(new.into_iter()); old }));
|
||||
/// assert_eq!(map[1], vec![1i, 2, 3, 4]);
|
||||
/// ```
|
||||
pub fn update(&mut self, key: uint, newval: V, ff: |V, V| -> V) -> bool {
|
||||
self.update_with_key(key, newval, |_k, v, v1| ff(v,v1))
|
||||
pub fn update<F>(&mut self, key: uint, newval: V, ff: F) -> bool where F: FnOnce(V, V) -> V {
|
||||
self.update_with_key(key, newval, move |_k, v, v1| ff(v,v1))
|
||||
}
|
||||
|
||||
/// Updates a value in the map. If the key already exists in the map,
|
||||
|
|
@ -470,11 +477,9 @@ impl<V:Clone> VecMap<V> {
|
|||
/// assert!(!map.update_with_key(7, 20, |key, old, new| (old + new) % key));
|
||||
/// assert_eq!(map[7], 2);
|
||||
/// ```
|
||||
pub fn update_with_key(&mut self,
|
||||
key: uint,
|
||||
val: V,
|
||||
ff: |uint, V, V| -> V)
|
||||
-> bool {
|
||||
pub fn update_with_key<F>(&mut self, key: uint, val: V, ff: F) -> bool where
|
||||
F: FnOnce(uint, V, V) -> V
|
||||
{
|
||||
let new_val = match self.get(&key) {
|
||||
None => val,
|
||||
Some(orig) => ff(key, (*orig).clone(), val)
|
||||
|
|
@ -620,16 +625,18 @@ iterator!(impl MutEntries -> (uint, &'a mut V), as_mut)
|
|||
double_ended_iterator!(impl MutEntries -> (uint, &'a mut V), as_mut)
|
||||
|
||||
/// Forward iterator over the keys of a map
|
||||
pub type Keys<'a, V> =
|
||||
iter::Map<'static, (uint, &'a V), uint, Entries<'a, V>>;
|
||||
pub type Keys<'a, V> = iter::Map<(uint, &'a V), uint, Entries<'a, V>, fn((uint, &'a V)) -> uint>;
|
||||
|
||||
/// Forward iterator over the values of a map
|
||||
pub type Values<'a, V> =
|
||||
iter::Map<'static, (uint, &'a V), &'a V, Entries<'a, V>>;
|
||||
iter::Map<(uint, &'a V), &'a V, Entries<'a, V>, fn((uint, &'a V)) -> &'a V>;
|
||||
|
||||
/// Iterator over the key-value pairs of a map, the iterator consumes the map
|
||||
pub type MoveItems<V> =
|
||||
FilterMap<'static, (uint, Option<V>), (uint, V), Enumerate<vec::MoveItems<Option<V>>>>;
|
||||
pub type MoveItems<V> = FilterMap<
|
||||
(uint, Option<V>),
|
||||
(uint, V),
|
||||
Enumerate<vec::MoveItems<Option<V>>>,
|
||||
fn((uint, Option<V>)) -> Option<(uint, V)>>;
|
||||
|
||||
#[cfg(test)]
|
||||
mod test_map {
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@
|
|||
#![doc(primitive = "char")]
|
||||
|
||||
use mem::transmute;
|
||||
use ops::FnMut;
|
||||
use option::Option;
|
||||
use option::Option::{None, Some};
|
||||
use iter::{range_step, Iterator, RangeStep};
|
||||
|
|
@ -165,7 +166,7 @@ pub fn from_digit(num: uint, radix: uint) -> Option<char> {
|
|||
/// - chars above 0x10000 get 8-digit escapes: `\\u{{NNN}NNNNN}`
|
||||
///
|
||||
#[deprecated = "use the Char::escape_unicode method"]
|
||||
pub fn escape_unicode(c: char, f: |char|) {
|
||||
pub fn escape_unicode<F>(c: char, mut f: F) where F: FnMut(char) {
|
||||
for char in c.escape_unicode() {
|
||||
f(char);
|
||||
}
|
||||
|
|
@ -184,7 +185,7 @@ pub fn escape_unicode(c: char, f: |char|) {
|
|||
/// - Any other chars are given hex Unicode escapes; see `escape_unicode`.
|
||||
///
|
||||
#[deprecated = "use the Char::escape_default method"]
|
||||
pub fn escape_default(c: char, f: |char|) {
|
||||
pub fn escape_default<F>(c: char, mut f: F) where F: FnMut(char) {
|
||||
for c in c.escape_default() {
|
||||
f(c);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,40 +19,34 @@
|
|||
//! # Example
|
||||
//!
|
||||
//! ```
|
||||
//! # #![feature(unboxed_closures)]
|
||||
//!
|
||||
//! use std::finally::Finally;
|
||||
//!
|
||||
//! (|| {
|
||||
//! # fn main() {
|
||||
//! (|&mut:| {
|
||||
//! // ...
|
||||
//! }).finally(|| {
|
||||
//! // this code is always run
|
||||
//! })
|
||||
//! # }
|
||||
//! ```
|
||||
|
||||
#![experimental]
|
||||
|
||||
use ops::Drop;
|
||||
use ops::{Drop, FnMut, FnOnce};
|
||||
|
||||
/// A trait for executing a destructor unconditionally after a block of code,
|
||||
/// regardless of whether the blocked fails.
|
||||
pub trait Finally<T> {
|
||||
/// Executes this object, unconditionally running `dtor` after this block of
|
||||
/// code has run.
|
||||
fn finally(&mut self, dtor: ||) -> T;
|
||||
fn finally<F>(&mut self, dtor: F) -> T where F: FnMut();
|
||||
}
|
||||
|
||||
impl<'a,T> Finally<T> for ||: 'a -> T {
|
||||
fn finally(&mut self, dtor: ||) -> T {
|
||||
try_finally(&mut (), self,
|
||||
|_, f| (*f)(),
|
||||
|_| dtor())
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> Finally<T> for fn() -> T {
|
||||
fn finally(&mut self, dtor: ||) -> T {
|
||||
try_finally(&mut (), (),
|
||||
|_, _| (*self)(),
|
||||
|_| dtor())
|
||||
impl<T, F> Finally<T> for F where F: FnMut() -> T {
|
||||
fn finally<G>(&mut self, mut dtor: G) -> T where G: FnMut() {
|
||||
try_finally(&mut (), self, |_, f| (*f)(), |_| dtor())
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -86,11 +80,10 @@ impl<T> Finally<T> for fn() -> T {
|
|||
/// // use state.buffer, state.len to cleanup
|
||||
/// })
|
||||
/// ```
|
||||
pub fn try_finally<T,U,R>(mutate: &mut T,
|
||||
drop: U,
|
||||
try_fn: |&mut T, U| -> R,
|
||||
finally_fn: |&mut T|)
|
||||
-> R {
|
||||
pub fn try_finally<T, U, R, F, G>(mutate: &mut T, drop: U, try_fn: F, finally_fn: G) -> R where
|
||||
F: FnOnce(&mut T, U) -> R,
|
||||
G: FnMut(&mut T),
|
||||
{
|
||||
let f = Finallyalizer {
|
||||
mutate: mutate,
|
||||
dtor: finally_fn,
|
||||
|
|
@ -98,13 +91,13 @@ pub fn try_finally<T,U,R>(mutate: &mut T,
|
|||
try_fn(&mut *f.mutate, drop)
|
||||
}
|
||||
|
||||
struct Finallyalizer<'a,A:'a> {
|
||||
struct Finallyalizer<'a, A:'a, F> where F: FnMut(&mut A) {
|
||||
mutate: &'a mut A,
|
||||
dtor: |&mut A|: 'a
|
||||
dtor: F,
|
||||
}
|
||||
|
||||
#[unsafe_destructor]
|
||||
impl<'a,A> Drop for Finallyalizer<'a,A> {
|
||||
impl<'a, A, F> Drop for Finallyalizer<'a, A, F> where F: FnMut(&mut A) {
|
||||
#[inline]
|
||||
fn drop(&mut self) {
|
||||
(self.dtor)(self.mutate);
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ use fmt;
|
|||
use iter::{range, DoubleEndedIteratorExt};
|
||||
use num::{Float, FPNaN, FPInfinite, ToPrimitive};
|
||||
use num::cast;
|
||||
use ops::FnOnce;
|
||||
use result::Result::Ok;
|
||||
use slice::{mod, SlicePrelude};
|
||||
use str::StrPrelude;
|
||||
|
|
@ -84,7 +85,7 @@ static DIGIT_E_RADIX: uint = ('e' as uint) - ('a' as uint) + 11u;
|
|||
/// between digit and exponent sign `'e'`.
|
||||
/// - Panics if `radix` > 25 and `exp_format` is `ExpBin` due to conflict
|
||||
/// between digit and exponent sign `'p'`.
|
||||
pub fn float_to_str_bytes_common<T: Float, U>(
|
||||
pub fn float_to_str_bytes_common<T: Float, U, F>(
|
||||
num: T,
|
||||
radix: uint,
|
||||
negative_zero: bool,
|
||||
|
|
@ -92,8 +93,10 @@ pub fn float_to_str_bytes_common<T: Float, U>(
|
|||
digits: SignificantDigits,
|
||||
exp_format: ExponentFormat,
|
||||
exp_upper: bool,
|
||||
f: |&[u8]| -> U
|
||||
) -> U {
|
||||
f: F
|
||||
) -> U where
|
||||
F: FnOnce(&[u8]) -> U,
|
||||
{
|
||||
assert!(2 <= radix && radix <= 36);
|
||||
match exp_format {
|
||||
ExpDec if radix >= DIGIT_E_RADIX // decimal exponent 'e'
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ use kinds::{Copy, Sized};
|
|||
use mem;
|
||||
use option::Option;
|
||||
use option::Option::{Some, None};
|
||||
use ops::Deref;
|
||||
use ops::{Deref, FnOnce};
|
||||
use result::Result::{Ok, Err};
|
||||
use result;
|
||||
use slice::SlicePrelude;
|
||||
|
|
@ -491,10 +491,9 @@ impl<'a> Formatter<'a> {
|
|||
|
||||
/// Runs a callback, emitting the correct padding either before or
|
||||
/// afterwards depending on whether right or left alignment is requested.
|
||||
fn with_padding(&mut self,
|
||||
padding: uint,
|
||||
default: rt::Alignment,
|
||||
f: |&mut Formatter| -> Result) -> Result {
|
||||
fn with_padding<F>(&mut self, padding: uint, default: rt::Alignment, f: F) -> Result where
|
||||
F: FnOnce(&mut Formatter) -> Result,
|
||||
{
|
||||
use char::Char;
|
||||
let align = match self.align {
|
||||
rt::AlignUnknown => default,
|
||||
|
|
|
|||
|
|
@ -62,7 +62,7 @@ use cmp::Ord;
|
|||
use kinds::Copy;
|
||||
use mem;
|
||||
use num::{ToPrimitive, Int};
|
||||
use ops::{Add, Deref};
|
||||
use ops::{Add, Deref, FnMut};
|
||||
use option::Option;
|
||||
use option::Option::{Some, None};
|
||||
use uint;
|
||||
|
|
@ -165,7 +165,7 @@ pub trait IteratorExt<A>: Iterator<A> {
|
|||
/// ```
|
||||
#[inline]
|
||||
#[unstable = "waiting for unboxed closures"]
|
||||
fn map<'r, B>(self, f: |A|: 'r -> B) -> Map<'r, A, B, Self> {
|
||||
fn map<B, F: FnMut(A) -> B>(self, f: F) -> Map<A, B, Self, F> {
|
||||
Map{iter: self, f: f}
|
||||
}
|
||||
|
||||
|
|
@ -183,7 +183,7 @@ pub trait IteratorExt<A>: Iterator<A> {
|
|||
/// ```
|
||||
#[inline]
|
||||
#[unstable = "waiting for unboxed closures"]
|
||||
fn filter<'r>(self, predicate: |&A|: 'r -> bool) -> Filter<'r, A, Self> {
|
||||
fn filter<P>(self, predicate: P) -> Filter<A, Self, P> where P: FnMut(&A) -> bool {
|
||||
Filter{iter: self, predicate: predicate}
|
||||
}
|
||||
|
||||
|
|
@ -201,7 +201,7 @@ pub trait IteratorExt<A>: Iterator<A> {
|
|||
/// ```
|
||||
#[inline]
|
||||
#[unstable = "waiting for unboxed closures"]
|
||||
fn filter_map<'r, B>(self, f: |A|: 'r -> Option<B>) -> FilterMap<'r, A, B, Self> {
|
||||
fn filter_map<B, F>(self, f: F) -> FilterMap<A, B, Self, F> where F: FnMut(A) -> Option<B> {
|
||||
FilterMap { iter: self, f: f }
|
||||
}
|
||||
|
||||
|
|
@ -264,7 +264,7 @@ pub trait IteratorExt<A>: Iterator<A> {
|
|||
/// ```
|
||||
#[inline]
|
||||
#[unstable = "waiting for unboxed closures"]
|
||||
fn skip_while<'r>(self, predicate: |&A|: 'r -> bool) -> SkipWhile<'r, A, Self> {
|
||||
fn skip_while<P>(self, predicate: P) -> SkipWhile<A, Self, P> where P: FnMut(&A) -> bool {
|
||||
SkipWhile{iter: self, flag: false, predicate: predicate}
|
||||
}
|
||||
|
||||
|
|
@ -283,7 +283,7 @@ pub trait IteratorExt<A>: Iterator<A> {
|
|||
/// ```
|
||||
#[inline]
|
||||
#[unstable = "waiting for unboxed closures, may want to require peek"]
|
||||
fn take_while<'r>(self, predicate: |&A|: 'r -> bool) -> TakeWhile<'r, A, Self> {
|
||||
fn take_while<P>(self, predicate: P) -> TakeWhile<A, Self, P> where P: FnMut(&A) -> bool {
|
||||
TakeWhile{iter: self, flag: false, predicate: predicate}
|
||||
}
|
||||
|
||||
|
|
@ -346,8 +346,9 @@ pub trait IteratorExt<A>: Iterator<A> {
|
|||
/// ```
|
||||
#[inline]
|
||||
#[unstable = "waiting for unboxed closures"]
|
||||
fn scan<'r, St, B>(self, initial_state: St, f: |&mut St, A|: 'r -> Option<B>)
|
||||
-> Scan<'r, A, B, Self, St> {
|
||||
fn scan<St, B, F>(self, initial_state: St, f: F) -> Scan<A, B, Self, St, F> where
|
||||
F: FnMut(&mut St, A) -> Option<B>,
|
||||
{
|
||||
Scan{iter: self, f: f, state: initial_state}
|
||||
}
|
||||
|
||||
|
|
@ -371,8 +372,10 @@ pub trait IteratorExt<A>: Iterator<A> {
|
|||
/// ```
|
||||
#[inline]
|
||||
#[unstable = "waiting for unboxed closures"]
|
||||
fn flat_map<'r, B, U: Iterator<B>>(self, f: |A|: 'r -> U)
|
||||
-> FlatMap<'r, A, Self, U> {
|
||||
fn flat_map<B, U, F>(self, f: F) -> FlatMap<A, B, Self, U, F> where
|
||||
U: Iterator<B>,
|
||||
F: FnMut(A) -> U,
|
||||
{
|
||||
FlatMap{iter: self, f: f, frontiter: None, backiter: None }
|
||||
}
|
||||
|
||||
|
|
@ -429,7 +432,7 @@ pub trait IteratorExt<A>: Iterator<A> {
|
|||
/// ```
|
||||
#[inline]
|
||||
#[unstable = "waiting for unboxed closures"]
|
||||
fn inspect<'r>(self, f: |&A|: 'r) -> Inspect<'r, A, Self> {
|
||||
fn inspect<F>(self, f: F) -> Inspect<A, Self, F> where F: FnMut(&A) {
|
||||
Inspect{iter: self, f: f}
|
||||
}
|
||||
|
||||
|
|
@ -518,7 +521,7 @@ pub trait IteratorExt<A>: Iterator<A> {
|
|||
/// ```
|
||||
#[inline]
|
||||
#[unstable = "waiting for unboxed closures, just changed to take self by value"]
|
||||
fn fold<B>(mut self, init: B, f: |B, A| -> B) -> B {
|
||||
fn fold<B, F>(mut self, init: B, mut f: F) -> B where F: FnMut(B, A) -> B {
|
||||
let mut accum = init;
|
||||
for x in self {
|
||||
accum = f(accum, x);
|
||||
|
|
@ -552,7 +555,7 @@ pub trait IteratorExt<A>: Iterator<A> {
|
|||
/// ```
|
||||
#[inline]
|
||||
#[unstable = "waiting for unboxed closures, just changed to take self by value"]
|
||||
fn all(mut self, f: |A| -> bool) -> bool {
|
||||
fn all<F>(mut self, mut f: F) -> bool where F: FnMut(A) -> bool {
|
||||
for x in self { if !f(x) { return false; } }
|
||||
true
|
||||
}
|
||||
|
|
@ -570,7 +573,7 @@ pub trait IteratorExt<A>: Iterator<A> {
|
|||
/// ```
|
||||
#[inline]
|
||||
#[unstable = "waiting for unboxed closures"]
|
||||
fn any(&mut self, f: |A| -> bool) -> bool {
|
||||
fn any<F>(&mut self, mut f: F) -> bool where F: FnMut(A) -> bool {
|
||||
for x in *self { if f(x) { return true; } }
|
||||
false
|
||||
}
|
||||
|
|
@ -580,7 +583,7 @@ pub trait IteratorExt<A>: Iterator<A> {
|
|||
/// Does not consume the iterator past the first found element.
|
||||
#[inline]
|
||||
#[unstable = "waiting for unboxed closures"]
|
||||
fn find(&mut self, predicate: |&A| -> bool) -> Option<A> {
|
||||
fn find<P>(&mut self, mut predicate: P) -> Option<A> where P: FnMut(&A) -> bool {
|
||||
for x in *self {
|
||||
if predicate(&x) { return Some(x) }
|
||||
}
|
||||
|
|
@ -590,7 +593,7 @@ pub trait IteratorExt<A>: Iterator<A> {
|
|||
/// Return the index of the first element satisfying the specified predicate
|
||||
#[inline]
|
||||
#[unstable = "waiting for unboxed closures"]
|
||||
fn position(&mut self, predicate: |A| -> bool) -> Option<uint> {
|
||||
fn position<P>(&mut self, mut predicate: P) -> Option<uint> where P: FnMut(A) -> bool {
|
||||
let mut i = 0;
|
||||
for x in *self {
|
||||
if predicate(x) {
|
||||
|
|
@ -614,7 +617,7 @@ pub trait IteratorExt<A>: Iterator<A> {
|
|||
/// ```
|
||||
#[inline]
|
||||
#[unstable = "waiting for unboxed closures, just changed to take self by value"]
|
||||
fn max_by<B: Ord>(self, f: |&A| -> B) -> Option<A> {
|
||||
fn max_by<B: Ord, F>(self, mut f: F) -> Option<A> where F: FnMut(&A) -> B {
|
||||
self.fold(None, |max: Option<(A, B)>, x| {
|
||||
let x_val = f(&x);
|
||||
match max {
|
||||
|
|
@ -641,7 +644,7 @@ pub trait IteratorExt<A>: Iterator<A> {
|
|||
/// ```
|
||||
#[inline]
|
||||
#[unstable = "waiting for unboxed closures, just changed to take self by value"]
|
||||
fn min_by<B: Ord>(self, f: |&A| -> B) -> Option<A> {
|
||||
fn min_by<B: Ord, F>(self, mut f: F) -> Option<A> where F: FnMut(&A) -> B {
|
||||
self.fold(None, |min: Option<(A, B)>, x| {
|
||||
let x_val = f(&x);
|
||||
match min {
|
||||
|
|
@ -746,7 +749,7 @@ pub trait ExactSizeIterator<A> : DoubleEndedIterator<A> {
|
|||
///
|
||||
/// If no element matches, None is returned.
|
||||
#[inline]
|
||||
fn rposition(&mut self, predicate: |A| -> bool) -> Option<uint> {
|
||||
fn rposition<P>(&mut self, mut predicate: P) -> Option<uint> where P: FnMut(A) -> bool {
|
||||
let len = self.len();
|
||||
for i in range(0, len).rev() {
|
||||
if predicate(self.next_back().expect("rposition: incorrect ExactSizeIterator")) {
|
||||
|
|
@ -774,11 +777,17 @@ pub trait ExactSizeIterator<A> : DoubleEndedIterator<A> {
|
|||
#[unstable = "trait is unstable"]
|
||||
impl<A, T: ExactSizeIterator<A>> ExactSizeIterator<(uint, A)> for Enumerate<T> {}
|
||||
#[unstable = "trait is unstable"]
|
||||
impl<'a, A, T: ExactSizeIterator<A>> ExactSizeIterator<A> for Inspect<'a, A, T> {}
|
||||
impl<A, I, F> ExactSizeIterator<A> for Inspect<A, I, F> where
|
||||
I: ExactSizeIterator<A>,
|
||||
F: FnMut(&A),
|
||||
{}
|
||||
#[unstable = "trait is unstable"]
|
||||
impl<A, T: ExactSizeIterator<A>> ExactSizeIterator<A> for Rev<T> {}
|
||||
#[unstable = "trait is unstable"]
|
||||
impl<'a, A, B, T: ExactSizeIterator<A>> ExactSizeIterator<B> for Map<'a, A, B, T> {}
|
||||
impl<A, B, I, F> ExactSizeIterator<B> for Map<A, B, I, F> where
|
||||
I: ExactSizeIterator<A>,
|
||||
F: FnMut(A) -> B,
|
||||
{}
|
||||
#[unstable = "trait is unstable"]
|
||||
impl<A, B, T, U> ExactSizeIterator<(A, B)> for Zip<T, U>
|
||||
where T: ExactSizeIterator<A>, U: ExactSizeIterator<B> {}
|
||||
|
|
@ -1374,12 +1383,12 @@ RandomAccessIterator<(A, B)> for Zip<T, U> {
|
|||
/// An iterator which maps the values of `iter` with `f`
|
||||
#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
|
||||
#[stable]
|
||||
pub struct Map<'a, A, B, T> {
|
||||
iter: T,
|
||||
f: |A|: 'a -> B
|
||||
pub struct Map<A, B, I: Iterator<A>, F: FnMut(A) -> B> {
|
||||
iter: I,
|
||||
f: F,
|
||||
}
|
||||
|
||||
impl<'a, A, B, T> Map<'a, A, B, T> {
|
||||
impl<A, B, I, F> Map<A, B, I, F> where I: Iterator<A>, F: FnMut(A) -> B {
|
||||
#[inline]
|
||||
fn do_map(&mut self, elt: Option<A>) -> Option<B> {
|
||||
match elt {
|
||||
|
|
@ -1390,7 +1399,7 @@ impl<'a, A, B, T> Map<'a, A, B, T> {
|
|||
}
|
||||
|
||||
#[unstable = "trait is unstable"]
|
||||
impl<'a, A, B, T: Iterator<A>> Iterator<B> for Map<'a, A, B, T> {
|
||||
impl<A, B, I, F> Iterator<B> for Map<A, B, I, F> where I: Iterator<A>, F: FnMut(A) -> B {
|
||||
#[inline]
|
||||
fn next(&mut self) -> Option<B> {
|
||||
let next = self.iter.next();
|
||||
|
|
@ -1404,7 +1413,10 @@ impl<'a, A, B, T: Iterator<A>> Iterator<B> for Map<'a, A, B, T> {
|
|||
}
|
||||
|
||||
#[unstable = "trait is unstable"]
|
||||
impl<'a, A, B, T: DoubleEndedIterator<A>> DoubleEndedIterator<B> for Map<'a, A, B, T> {
|
||||
impl<A, B, I, F> DoubleEndedIterator<B> for Map<A, B, I, F> where
|
||||
I: DoubleEndedIterator<A>,
|
||||
F: FnMut(A) -> B,
|
||||
{
|
||||
#[inline]
|
||||
fn next_back(&mut self) -> Option<B> {
|
||||
let next = self.iter.next_back();
|
||||
|
|
@ -1413,7 +1425,10 @@ impl<'a, A, B, T: DoubleEndedIterator<A>> DoubleEndedIterator<B> for Map<'a, A,
|
|||
}
|
||||
|
||||
#[experimental = "trait is experimental"]
|
||||
impl<'a, A, B, T: RandomAccessIterator<A>> RandomAccessIterator<B> for Map<'a, A, B, T> {
|
||||
impl<A, B, I, F> RandomAccessIterator<B> for Map<A, B, I, F> where
|
||||
I: RandomAccessIterator<A>,
|
||||
F: FnMut(A) -> B,
|
||||
{
|
||||
#[inline]
|
||||
fn indexable(&self) -> uint {
|
||||
self.iter.indexable()
|
||||
|
|
@ -1429,13 +1444,13 @@ impl<'a, A, B, T: RandomAccessIterator<A>> RandomAccessIterator<B> for Map<'a, A
|
|||
/// An iterator which filters the elements of `iter` with `predicate`
|
||||
#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
|
||||
#[stable]
|
||||
pub struct Filter<'a, A, T> {
|
||||
iter: T,
|
||||
predicate: |&A|: 'a -> bool
|
||||
pub struct Filter<A, I, P> where I: Iterator<A>, P: FnMut(&A) -> bool {
|
||||
iter: I,
|
||||
predicate: P,
|
||||
}
|
||||
|
||||
#[unstable = "trait is unstable"]
|
||||
impl<'a, A, T: Iterator<A>> Iterator<A> for Filter<'a, A, T> {
|
||||
impl<A, I, P> Iterator<A> for Filter<A, I, P> where I: Iterator<A>, P: FnMut(&A) -> bool {
|
||||
#[inline]
|
||||
fn next(&mut self) -> Option<A> {
|
||||
for x in self.iter {
|
||||
|
|
@ -1456,7 +1471,10 @@ impl<'a, A, T: Iterator<A>> Iterator<A> for Filter<'a, A, T> {
|
|||
}
|
||||
|
||||
#[unstable = "trait is unstable"]
|
||||
impl<'a, A, T: DoubleEndedIterator<A>> DoubleEndedIterator<A> for Filter<'a, A, T> {
|
||||
impl<A, I, P> DoubleEndedIterator<A> for Filter<A, I, P> where
|
||||
I: DoubleEndedIterator<A>,
|
||||
P: FnMut(&A) -> bool,
|
||||
{
|
||||
#[inline]
|
||||
fn next_back(&mut self) -> Option<A> {
|
||||
for x in self.iter.by_ref().rev() {
|
||||
|
|
@ -1471,13 +1489,16 @@ impl<'a, A, T: DoubleEndedIterator<A>> DoubleEndedIterator<A> for Filter<'a, A,
|
|||
/// An iterator which uses `f` to both filter and map elements from `iter`
|
||||
#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
|
||||
#[stable]
|
||||
pub struct FilterMap<'a, A, B, T> {
|
||||
iter: T,
|
||||
f: |A|: 'a -> Option<B>
|
||||
pub struct FilterMap<A, B, I, F> where I: Iterator<A>, F: FnMut(A) -> Option<B> {
|
||||
iter: I,
|
||||
f: F,
|
||||
}
|
||||
|
||||
#[unstable = "trait is unstable"]
|
||||
impl<'a, A, B, T: Iterator<A>> Iterator<B> for FilterMap<'a, A, B, T> {
|
||||
impl<A, B, I, F> Iterator<B> for FilterMap<A, B, I, F> where
|
||||
I: Iterator<A>,
|
||||
F: FnMut(A) -> Option<B>,
|
||||
{
|
||||
#[inline]
|
||||
fn next(&mut self) -> Option<B> {
|
||||
for x in self.iter {
|
||||
|
|
@ -1497,8 +1518,10 @@ impl<'a, A, B, T: Iterator<A>> Iterator<B> for FilterMap<'a, A, B, T> {
|
|||
}
|
||||
|
||||
#[unstable = "trait is unstable"]
|
||||
impl<'a, A, B, T: DoubleEndedIterator<A>> DoubleEndedIterator<B>
|
||||
for FilterMap<'a, A, B, T> {
|
||||
impl<A, B, I, F> DoubleEndedIterator<B> for FilterMap<A, B, I, F> where
|
||||
I: DoubleEndedIterator<A>,
|
||||
F: FnMut(A) -> Option<B>,
|
||||
{
|
||||
#[inline]
|
||||
fn next_back(&mut self) -> Option<B> {
|
||||
for x in self.iter.by_ref().rev() {
|
||||
|
|
@ -1628,14 +1651,14 @@ impl<'a, A, T: Iterator<A>> Peekable<A, T> {
|
|||
/// An iterator which rejects elements while `predicate` is true
|
||||
#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
|
||||
#[stable]
|
||||
pub struct SkipWhile<'a, A, T> {
|
||||
iter: T,
|
||||
pub struct SkipWhile<A, I, P> where I: Iterator<A>, P: FnMut(&A) -> bool {
|
||||
iter: I,
|
||||
flag: bool,
|
||||
predicate: |&A|: 'a -> bool
|
||||
predicate: P,
|
||||
}
|
||||
|
||||
#[unstable = "trait is unstable"]
|
||||
impl<'a, A, T: Iterator<A>> Iterator<A> for SkipWhile<'a, A, T> {
|
||||
impl<A, I, P> Iterator<A> for SkipWhile<A, I, P> where I: Iterator<A>, P: FnMut(&A) -> bool {
|
||||
#[inline]
|
||||
fn next(&mut self) -> Option<A> {
|
||||
for x in self.iter {
|
||||
|
|
@ -1657,14 +1680,14 @@ impl<'a, A, T: Iterator<A>> Iterator<A> for SkipWhile<'a, A, T> {
|
|||
/// An iterator which only accepts elements while `predicate` is true
|
||||
#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
|
||||
#[stable]
|
||||
pub struct TakeWhile<'a, A, T> {
|
||||
iter: T,
|
||||
pub struct TakeWhile<A, I, P> where I: Iterator<A>, P: FnMut(&A) -> bool {
|
||||
iter: I,
|
||||
flag: bool,
|
||||
predicate: |&A|: 'a -> bool
|
||||
predicate: P,
|
||||
}
|
||||
|
||||
#[unstable = "trait is unstable"]
|
||||
impl<'a, A, T: Iterator<A>> Iterator<A> for TakeWhile<'a, A, T> {
|
||||
impl<A, I, P> Iterator<A> for TakeWhile<A, I, P> where I: Iterator<A>, P: FnMut(&A) -> bool {
|
||||
#[inline]
|
||||
fn next(&mut self) -> Option<A> {
|
||||
if self.flag {
|
||||
|
|
@ -1816,16 +1839,19 @@ impl<A, T: RandomAccessIterator<A>> RandomAccessIterator<A> for Take<T> {
|
|||
/// An iterator to maintain state while iterating another iterator
|
||||
#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
|
||||
#[unstable = "waiting for unboxed closures"]
|
||||
pub struct Scan<'a, A, B, T, St> {
|
||||
iter: T,
|
||||
f: |&mut St, A|: 'a -> Option<B>,
|
||||
pub struct Scan<A, B, I, St, F> where I: Iterator<A>, F: FnMut(&mut St, A) -> Option<B> {
|
||||
iter: I,
|
||||
f: F,
|
||||
|
||||
/// The current internal state to be passed to the closure next.
|
||||
pub state: St,
|
||||
}
|
||||
|
||||
#[unstable = "trait is unstable"]
|
||||
impl<'a, A, B, T: Iterator<A>, St> Iterator<B> for Scan<'a, A, B, T, St> {
|
||||
impl<A, B, I, St, F> Iterator<B> for Scan<A, B, I, St, F> where
|
||||
I: Iterator<A>,
|
||||
F: FnMut(&mut St, A) -> Option<B>,
|
||||
{
|
||||
#[inline]
|
||||
fn next(&mut self) -> Option<B> {
|
||||
self.iter.next().and_then(|a| (self.f)(&mut self.state, a))
|
||||
|
|
@ -1843,15 +1869,19 @@ impl<'a, A, B, T: Iterator<A>, St> Iterator<B> for Scan<'a, A, B, T, St> {
|
|||
///
|
||||
#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
|
||||
#[unstable = "waiting for unboxed closures"]
|
||||
pub struct FlatMap<'a, A, T, U> {
|
||||
iter: T,
|
||||
f: |A|: 'a -> U,
|
||||
pub struct FlatMap<A, B, I, U, F> where I: Iterator<A>, U: Iterator<B>, F: FnMut(A) -> U {
|
||||
iter: I,
|
||||
f: F,
|
||||
frontiter: Option<U>,
|
||||
backiter: Option<U>,
|
||||
}
|
||||
|
||||
#[unstable = "trait is unstable"]
|
||||
impl<'a, A, T: Iterator<A>, B, U: Iterator<B>> Iterator<B> for FlatMap<'a, A, T, U> {
|
||||
impl<A, B, I, U, F> Iterator<B> for FlatMap<A, B, I, U, F> where
|
||||
I: Iterator<A>,
|
||||
U: Iterator<B>,
|
||||
F: FnMut(A) -> U,
|
||||
{
|
||||
#[inline]
|
||||
fn next(&mut self) -> Option<B> {
|
||||
loop {
|
||||
|
|
@ -1880,10 +1910,11 @@ impl<'a, A, T: Iterator<A>, B, U: Iterator<B>> Iterator<B> for FlatMap<'a, A, T,
|
|||
}
|
||||
|
||||
#[unstable = "trait is unstable"]
|
||||
impl<'a,
|
||||
A, T: DoubleEndedIterator<A>,
|
||||
B, U: DoubleEndedIterator<B>> DoubleEndedIterator<B>
|
||||
for FlatMap<'a, A, T, U> {
|
||||
impl<A, B, I, U, F> DoubleEndedIterator<B> for FlatMap<A, B, I, U, F> where
|
||||
I: DoubleEndedIterator<A>,
|
||||
U: DoubleEndedIterator<B>,
|
||||
F: FnMut(A) -> U,
|
||||
{
|
||||
#[inline]
|
||||
fn next_back(&mut self) -> Option<B> {
|
||||
loop {
|
||||
|
|
@ -1984,12 +2015,12 @@ impl<T> Fuse<T> {
|
|||
/// element before yielding it.
|
||||
#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
|
||||
#[unstable = "waiting for unboxed closures"]
|
||||
pub struct Inspect<'a, A, T> {
|
||||
iter: T,
|
||||
f: |&A|: 'a
|
||||
pub struct Inspect<A, I, F> where I: Iterator<A>, F: FnMut(&A) {
|
||||
iter: I,
|
||||
f: F,
|
||||
}
|
||||
|
||||
impl<'a, A, T> Inspect<'a, A, T> {
|
||||
impl<A, I, F> Inspect<A, I, F> where I: Iterator<A>, F: FnMut(&A) {
|
||||
#[inline]
|
||||
fn do_inspect(&mut self, elt: Option<A>) -> Option<A> {
|
||||
match elt {
|
||||
|
|
@ -2002,7 +2033,7 @@ impl<'a, A, T> Inspect<'a, A, T> {
|
|||
}
|
||||
|
||||
#[unstable = "trait is unstable"]
|
||||
impl<'a, A, T: Iterator<A>> Iterator<A> for Inspect<'a, A, T> {
|
||||
impl<A, I, F> Iterator<A> for Inspect<A, I, F> where I: Iterator<A>, F: FnMut(&A) {
|
||||
#[inline]
|
||||
fn next(&mut self) -> Option<A> {
|
||||
let next = self.iter.next();
|
||||
|
|
@ -2016,8 +2047,10 @@ impl<'a, A, T: Iterator<A>> Iterator<A> for Inspect<'a, A, T> {
|
|||
}
|
||||
|
||||
#[unstable = "trait is unstable"]
|
||||
impl<'a, A, T: DoubleEndedIterator<A>> DoubleEndedIterator<A>
|
||||
for Inspect<'a, A, T> {
|
||||
impl<A, I, F> DoubleEndedIterator<A> for Inspect<A, I, F> where
|
||||
I: DoubleEndedIterator<A>,
|
||||
F: FnMut(&A),
|
||||
{
|
||||
#[inline]
|
||||
fn next_back(&mut self) -> Option<A> {
|
||||
let next = self.iter.next_back();
|
||||
|
|
@ -2026,8 +2059,10 @@ for Inspect<'a, A, T> {
|
|||
}
|
||||
|
||||
#[experimental = "trait is experimental"]
|
||||
impl<'a, A, T: RandomAccessIterator<A>> RandomAccessIterator<A>
|
||||
for Inspect<'a, A, T> {
|
||||
impl<A, I, F> RandomAccessIterator<A> for Inspect<A, I, F> where
|
||||
I: RandomAccessIterator<A>,
|
||||
F: FnMut(&A),
|
||||
{
|
||||
#[inline]
|
||||
fn indexable(&self) -> uint {
|
||||
self.iter.indexable()
|
||||
|
|
@ -2073,19 +2108,18 @@ for Inspect<'a, A, T> {
|
|||
/// }
|
||||
/// ```
|
||||
#[experimental]
|
||||
pub struct Unfold<'a, A, St> {
|
||||
f: |&mut St|: 'a -> Option<A>,
|
||||
pub struct Unfold<A, St, F> where F: FnMut(&mut St) -> Option<A> {
|
||||
f: F,
|
||||
/// Internal state that will be passed to the closure on the next iteration
|
||||
pub state: St,
|
||||
}
|
||||
|
||||
#[experimental]
|
||||
impl<'a, A, St> Unfold<'a, A, St> {
|
||||
impl<A, St, F> Unfold<A, St, F> where F: FnMut(&mut St) -> Option<A> {
|
||||
/// Creates a new iterator with the specified closure as the "iterator
|
||||
/// function" and an initial state to eventually pass to the closure
|
||||
#[inline]
|
||||
pub fn new<'a>(initial_state: St, f: |&mut St|: 'a -> Option<A>)
|
||||
-> Unfold<'a, A, St> {
|
||||
pub fn new(initial_state: St, f: F) -> Unfold<A, St, F> {
|
||||
Unfold {
|
||||
f: f,
|
||||
state: initial_state
|
||||
|
|
@ -2094,7 +2128,7 @@ impl<'a, A, St> Unfold<'a, A, St> {
|
|||
}
|
||||
|
||||
#[experimental]
|
||||
impl<'a, A, St> Iterator<A> for Unfold<'a, A, St> {
|
||||
impl<A, St, F> Iterator<A> for Unfold<A, St, F> where F: FnMut(&mut St) -> Option<A> {
|
||||
#[inline]
|
||||
fn next(&mut self) -> Option<A> {
|
||||
(self.f)(&mut self.state)
|
||||
|
|
@ -2421,18 +2455,24 @@ impl<A: Clone> RandomAccessIterator<A> for Repeat<A> {
|
|||
fn idx(&mut self, _: uint) -> Option<A> { Some(self.element.clone()) }
|
||||
}
|
||||
|
||||
type IterateState<'a, T> = (|T|: 'a -> T, Option<T>, bool);
|
||||
type IterateState<T, F> = (F, Option<T>, bool);
|
||||
|
||||
/// An iterator that repeatedly applies a given function, starting
|
||||
/// from a given seed value.
|
||||
#[experimental]
|
||||
pub type Iterate<'a, T> = Unfold<'a, T, IterateState<'a, T>>;
|
||||
pub type Iterate<T, F> = Unfold<T, IterateState<T, F>, fn(&mut IterateState<T, F>) -> Option<T>>;
|
||||
|
||||
/// Create a new iterator that produces an infinite sequence of
|
||||
/// repeated applications of the given function `f`.
|
||||
#[experimental]
|
||||
pub fn iterate<'a, T: Clone>(seed: T, f: |T|: 'a -> T) -> Iterate<'a, T> {
|
||||
Unfold::new((f, Some(seed), true), |st| {
|
||||
pub fn iterate<T, F>(seed: T, f: F) -> Iterate<T, F> where
|
||||
T: Clone,
|
||||
F: FnMut(T) -> T,
|
||||
{
|
||||
fn next<T, F>(st: &mut IterateState<T, F>) -> Option<T> where
|
||||
T: Clone,
|
||||
F: FnMut(T) -> T,
|
||||
{
|
||||
let &(ref mut f, ref mut val, ref mut first) = st;
|
||||
if *first {
|
||||
*first = false;
|
||||
|
|
@ -2445,7 +2485,9 @@ pub fn iterate<'a, T: Clone>(seed: T, f: |T|: 'a -> T) -> Iterate<'a, T> {
|
|||
}
|
||||
}
|
||||
val.clone()
|
||||
})
|
||||
}
|
||||
|
||||
Unfold::new((f, Some(seed), true), next)
|
||||
}
|
||||
|
||||
/// Create a new iterator that endlessly repeats the element `elt`.
|
||||
|
|
|
|||
|
|
@ -156,7 +156,7 @@ use result::Result::{Ok, Err};
|
|||
use slice;
|
||||
use slice::AsSlice;
|
||||
use clone::Clone;
|
||||
use ops::Deref;
|
||||
use ops::{Deref, FnOnce};
|
||||
|
||||
// Note that this is not a lang item per se, but it has a hidden dependency on
|
||||
// `Iterator`, which is one. The compiler assumes that the `next` method of
|
||||
|
|
@ -389,7 +389,7 @@ impl<T> Option<T> {
|
|||
/// ```
|
||||
#[inline]
|
||||
#[unstable = "waiting for conventions"]
|
||||
pub fn unwrap_or_else(self, f: || -> T) -> T {
|
||||
pub fn unwrap_or_else<F: FnOnce() -> T>(self, f: F) -> T {
|
||||
match self {
|
||||
Some(x) => x,
|
||||
None => f()
|
||||
|
|
@ -413,7 +413,7 @@ impl<T> Option<T> {
|
|||
/// ```
|
||||
#[inline]
|
||||
#[unstable = "waiting for unboxed closures"]
|
||||
pub fn map<U>(self, f: |T| -> U) -> Option<U> {
|
||||
pub fn map<U, F: FnOnce(T) -> U>(self, f: F) -> Option<U> {
|
||||
match self {
|
||||
Some(x) => Some(f(x)),
|
||||
None => None
|
||||
|
|
@ -433,7 +433,7 @@ impl<T> Option<T> {
|
|||
/// ```
|
||||
#[inline]
|
||||
#[unstable = "waiting for unboxed closures"]
|
||||
pub fn map_or<U>(self, def: U, f: |T| -> U) -> U {
|
||||
pub fn map_or<U, F: FnOnce(T) -> U>(self, def: U, f: F) -> U {
|
||||
match self {
|
||||
Some(t) => f(t),
|
||||
None => def
|
||||
|
|
@ -455,7 +455,7 @@ impl<T> Option<T> {
|
|||
/// ```
|
||||
#[inline]
|
||||
#[unstable = "waiting for unboxed closures"]
|
||||
pub fn map_or_else<U>(self, def: || -> U, f: |T| -> U) -> U {
|
||||
pub fn map_or_else<U, D: FnOnce() -> U, F: FnOnce(T) -> U>(self, def: D, f: F) -> U {
|
||||
match self {
|
||||
Some(t) => f(t),
|
||||
None => def()
|
||||
|
|
@ -497,7 +497,7 @@ impl<T> Option<T> {
|
|||
/// ```
|
||||
#[inline]
|
||||
#[experimental]
|
||||
pub fn ok_or_else<E>(self, err: || -> E) -> Result<T, E> {
|
||||
pub fn ok_or_else<E, F: FnOnce() -> E>(self, err: F) -> Result<T, E> {
|
||||
match self {
|
||||
Some(v) => Ok(v),
|
||||
None => Err(err()),
|
||||
|
|
@ -615,7 +615,7 @@ impl<T> Option<T> {
|
|||
/// ```
|
||||
#[inline]
|
||||
#[unstable = "waiting for unboxed closures"]
|
||||
pub fn and_then<U>(self, f: |T| -> Option<U>) -> Option<U> {
|
||||
pub fn and_then<U, F: FnOnce(T) -> Option<U>>(self, f: F) -> Option<U> {
|
||||
match self {
|
||||
Some(x) => f(x),
|
||||
None => None,
|
||||
|
|
@ -667,7 +667,7 @@ impl<T> Option<T> {
|
|||
/// ```
|
||||
#[inline]
|
||||
#[unstable = "waiting for unboxed closures"]
|
||||
pub fn or_else(self, f: || -> Option<T>) -> Option<T> {
|
||||
pub fn or_else<F: FnOnce() -> Option<T>>(self, f: F) -> Option<T> {
|
||||
match self {
|
||||
Some(_) => self,
|
||||
None => f()
|
||||
|
|
|
|||
|
|
@ -239,6 +239,7 @@ use slice::AsSlice;
|
|||
use iter::{Iterator, IteratorExt, DoubleEndedIterator, FromIterator, ExactSizeIterator};
|
||||
use option::Option;
|
||||
use option::Option::{None, Some};
|
||||
use ops::{FnMut, FnOnce};
|
||||
|
||||
/// `Result` is a type that represents either success (`Ok`) or failure (`Err`).
|
||||
///
|
||||
|
|
@ -466,7 +467,7 @@ impl<T, E> Result<T, E> {
|
|||
/// ```
|
||||
#[inline]
|
||||
#[unstable = "waiting for unboxed closures"]
|
||||
pub fn map<U>(self, op: |T| -> U) -> Result<U,E> {
|
||||
pub fn map<U, F: FnOnce(T) -> U>(self, op: F) -> Result<U,E> {
|
||||
match self {
|
||||
Ok(t) => Ok(op(t)),
|
||||
Err(e) => Err(e)
|
||||
|
|
@ -492,7 +493,7 @@ impl<T, E> Result<T, E> {
|
|||
/// ```
|
||||
#[inline]
|
||||
#[unstable = "waiting for unboxed closures"]
|
||||
pub fn map_err<F>(self, op: |E| -> F) -> Result<T,F> {
|
||||
pub fn map_err<F, O: FnOnce(E) -> F>(self, op: O) -> Result<T,F> {
|
||||
match self {
|
||||
Ok(t) => Ok(t),
|
||||
Err(e) => Err(op(e))
|
||||
|
|
@ -612,7 +613,7 @@ impl<T, E> Result<T, E> {
|
|||
/// ```
|
||||
#[inline]
|
||||
#[unstable = "waiting for unboxed closures"]
|
||||
pub fn and_then<U>(self, op: |T| -> Result<U, E>) -> Result<U, E> {
|
||||
pub fn and_then<U, F: FnOnce(T) -> Result<U, E>>(self, op: F) -> Result<U, E> {
|
||||
match self {
|
||||
Ok(t) => op(t),
|
||||
Err(e) => Err(e),
|
||||
|
|
@ -666,7 +667,7 @@ impl<T, E> Result<T, E> {
|
|||
/// ```
|
||||
#[inline]
|
||||
#[unstable = "waiting for unboxed closures"]
|
||||
pub fn or_else<F>(self, op: |E| -> Result<T, F>) -> Result<T, F> {
|
||||
pub fn or_else<F, O: FnOnce(E) -> Result<T, F>>(self, op: O) -> Result<T, F> {
|
||||
match self {
|
||||
Ok(t) => Ok(t),
|
||||
Err(e) => op(e),
|
||||
|
|
@ -708,7 +709,7 @@ impl<T, E> Result<T, E> {
|
|||
/// ```
|
||||
#[inline]
|
||||
#[unstable = "waiting for conventions"]
|
||||
pub fn unwrap_or_else(self, op: |E| -> T) -> T {
|
||||
pub fn unwrap_or_else<F: FnOnce(E) -> T>(self, op: F) -> T {
|
||||
match self {
|
||||
Ok(t) => t,
|
||||
Err(e) => op(e)
|
||||
|
|
@ -904,10 +905,11 @@ impl<A, E, V: FromIterator<A>> FromIterator<Result<A, E>> for Result<V, E> {
|
|||
pub fn fold<T,
|
||||
V,
|
||||
E,
|
||||
F: FnMut(V, T) -> V,
|
||||
Iter: Iterator<Result<T, E>>>(
|
||||
mut iterator: Iter,
|
||||
mut init: V,
|
||||
f: |V, T| -> V)
|
||||
mut f: F)
|
||||
-> Result<V, E> {
|
||||
for t in iterator {
|
||||
match t {
|
||||
|
|
|
|||
|
|
@ -43,7 +43,7 @@ use default::Default;
|
|||
use iter::*;
|
||||
use kinds::Copy;
|
||||
use num::Int;
|
||||
use ops;
|
||||
use ops::{FnMut, mod};
|
||||
use option::Option;
|
||||
use option::Option::{None, Some};
|
||||
use ptr;
|
||||
|
|
@ -105,20 +105,23 @@ pub trait SlicePrelude<T> for Sized? {
|
|||
/// Returns an iterator over subslices separated by elements that match
|
||||
/// `pred`. The matched element is not contained in the subslices.
|
||||
#[unstable = "iterator type may change, waiting on unboxed closures"]
|
||||
fn split<'a>(&'a self, pred: |&T|: 'a -> bool) -> Splits<'a, T>;
|
||||
fn split<'a, P>(&'a self, pred: P) -> Splits<'a, T, P> where
|
||||
P: FnMut(&T) -> bool;
|
||||
|
||||
/// Returns an iterator over subslices separated by elements that match
|
||||
/// `pred`, limited to splitting at most `n` times. The matched element is
|
||||
/// not contained in the subslices.
|
||||
#[unstable = "iterator type may change"]
|
||||
fn splitn<'a>(&'a self, n: uint, pred: |&T|: 'a -> bool) -> SplitsN<Splits<'a, T>>;
|
||||
fn splitn<'a, P>(&'a self, n: uint, pred: P) -> SplitsN<Splits<'a, T, P>> where
|
||||
P: FnMut(&T) -> bool;
|
||||
|
||||
/// Returns an iterator over subslices separated by elements that match
|
||||
/// `pred` limited to splitting at most `n` times. This starts at the end of
|
||||
/// the slice and works backwards. The matched element is not contained in
|
||||
/// the subslices.
|
||||
#[unstable = "iterator type may change"]
|
||||
fn rsplitn<'a>(&'a self, n: uint, pred: |&T|: 'a -> bool) -> SplitsN<Splits<'a, T>>;
|
||||
fn rsplitn<'a, P>(&'a self, n: uint, pred: P) -> SplitsN<Splits<'a, T, P>> where
|
||||
P: FnMut(&T) -> bool;
|
||||
|
||||
/// Returns an iterator over all contiguous windows of length
|
||||
/// `size`. The windows overlap. If the slice is shorter than
|
||||
|
|
@ -235,7 +238,7 @@ pub trait SlicePrelude<T> for Sized? {
|
|||
/// assert!(match r { Found(1...4) => true, _ => false, });
|
||||
/// ```
|
||||
#[unstable = "waiting on unboxed closures"]
|
||||
fn binary_search(&self, f: |&T| -> Ordering) -> BinarySearchResult;
|
||||
fn binary_search<F>(&self, f: F) -> BinarySearchResult where F: FnMut(&T) -> Ordering;
|
||||
|
||||
/// Return the number of elements in the slice
|
||||
///
|
||||
|
|
@ -316,20 +319,23 @@ pub trait SlicePrelude<T> for Sized? {
|
|||
/// Returns an iterator over mutable subslices separated by elements that
|
||||
/// match `pred`. The matched element is not contained in the subslices.
|
||||
#[unstable = "waiting on unboxed closures, iterator type name conventions"]
|
||||
fn split_mut<'a>(&'a mut self, pred: |&T|: 'a -> bool) -> MutSplits<'a, T>;
|
||||
fn split_mut<'a, P>(&'a mut self, pred: P) -> MutSplits<'a, T, P> where
|
||||
P: FnMut(&T) -> bool;
|
||||
|
||||
/// Returns an iterator over subslices separated by elements that match
|
||||
/// `pred`, limited to splitting at most `n` times. The matched element is
|
||||
/// not contained in the subslices.
|
||||
#[unstable = "waiting on unboxed closures, iterator type name conventions"]
|
||||
fn splitn_mut<'a>(&'a mut self, n: uint, pred: |&T|: 'a -> bool) -> SplitsN<MutSplits<'a, T>>;
|
||||
fn splitn_mut<'a, P>(&'a mut self, n: uint, pred: P) -> SplitsN<MutSplits<'a, T, P>> where
|
||||
P: FnMut(&T) -> bool;
|
||||
|
||||
/// Returns an iterator over subslices separated by elements that match
|
||||
/// `pred` limited to splitting at most `n` times. This starts at the end of
|
||||
/// the slice and works backwards. The matched element is not contained in
|
||||
/// the subslices.
|
||||
#[unstable = "waiting on unboxed closures, iterator type name conventions"]
|
||||
fn rsplitn_mut<'a>(&'a mut self, n: uint, pred: |&T|: 'a -> bool) -> SplitsN<MutSplits<'a, T>>;
|
||||
fn rsplitn_mut<'a, P>(&'a mut self, n: uint, pred: P) -> SplitsN<MutSplits<'a, T, P>> where
|
||||
P: FnMut(&T) -> bool;
|
||||
|
||||
/// Returns an iterator over `chunk_size` elements of the slice at a time.
|
||||
/// The chunks are mutable and do not overlap. If `chunk_size` does
|
||||
|
|
@ -470,7 +476,7 @@ impl<T> SlicePrelude<T> for [T] {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
fn split<'a>(&'a self, pred: |&T|: 'a -> bool) -> Splits<'a, T> {
|
||||
fn split<'a, P>(&'a self, pred: P) -> Splits<'a, T, P> where P: FnMut(&T) -> bool {
|
||||
Splits {
|
||||
v: self,
|
||||
pred: pred,
|
||||
|
|
@ -479,7 +485,9 @@ impl<T> SlicePrelude<T> for [T] {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
fn splitn<'a>(&'a self, n: uint, pred: |&T|: 'a -> bool) -> SplitsN<Splits<'a, T>> {
|
||||
fn splitn<'a, P>(&'a self, n: uint, pred: P) -> SplitsN<Splits<'a, T, P>> where
|
||||
P: FnMut(&T) -> bool,
|
||||
{
|
||||
SplitsN {
|
||||
iter: self.split(pred),
|
||||
count: n,
|
||||
|
|
@ -488,7 +496,9 @@ impl<T> SlicePrelude<T> for [T] {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
fn rsplitn<'a>(&'a self, n: uint, pred: |&T|: 'a -> bool) -> SplitsN<Splits<'a, T>> {
|
||||
fn rsplitn<'a, P>(&'a self, n: uint, pred: P) -> SplitsN<Splits<'a, T, P>> where
|
||||
P: FnMut(&T) -> bool,
|
||||
{
|
||||
SplitsN {
|
||||
iter: self.split(pred),
|
||||
count: n,
|
||||
|
|
@ -542,7 +552,7 @@ impl<T> SlicePrelude<T> for [T] {
|
|||
}
|
||||
|
||||
#[unstable]
|
||||
fn binary_search(&self, f: |&T| -> Ordering) -> BinarySearchResult {
|
||||
fn binary_search<F>(&self, mut f: F) -> BinarySearchResult where F: FnMut(&T) -> Ordering {
|
||||
let mut base : uint = 0;
|
||||
let mut lim : uint = self.len();
|
||||
|
||||
|
|
@ -637,12 +647,14 @@ impl<T> SlicePrelude<T> for [T] {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
fn split_mut<'a>(&'a mut self, pred: |&T|: 'a -> bool) -> MutSplits<'a, T> {
|
||||
fn split_mut<'a, P>(&'a mut self, pred: P) -> MutSplits<'a, T, P> where P: FnMut(&T) -> bool {
|
||||
MutSplits { v: self, pred: pred, finished: false }
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn splitn_mut<'a>(&'a mut self, n: uint, pred: |&T|: 'a -> bool) -> SplitsN<MutSplits<'a, T>> {
|
||||
fn splitn_mut<'a, P>(&'a mut self, n: uint, pred: P) -> SplitsN<MutSplits<'a, T, P>> where
|
||||
P: FnMut(&T) -> bool
|
||||
{
|
||||
SplitsN {
|
||||
iter: self.split_mut(pred),
|
||||
count: n,
|
||||
|
|
@ -651,7 +663,9 @@ impl<T> SlicePrelude<T> for [T] {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
fn rsplitn_mut<'a>(&'a mut self, n: uint, pred: |&T|: 'a -> bool) -> SplitsN<MutSplits<'a, T>> {
|
||||
fn rsplitn_mut<'a, P>(&'a mut self, n: uint, pred: P) -> SplitsN<MutSplits<'a, T, P>> where
|
||||
P: FnMut(&T) -> bool,
|
||||
{
|
||||
SplitsN {
|
||||
iter: self.split_mut(pred),
|
||||
count: n,
|
||||
|
|
@ -1271,14 +1285,14 @@ trait SplitsIter<E>: DoubleEndedIterator<E> {
|
|||
/// An iterator over subslices separated by elements that match a predicate
|
||||
/// function.
|
||||
#[experimental = "needs review"]
|
||||
pub struct Splits<'a, T:'a> {
|
||||
pub struct Splits<'a, T:'a, P> where P: FnMut(&T) -> bool {
|
||||
v: &'a [T],
|
||||
pred: |t: &T|: 'a -> bool,
|
||||
pred: P,
|
||||
finished: bool
|
||||
}
|
||||
|
||||
#[experimental = "needs review"]
|
||||
impl<'a, T> Iterator<&'a [T]> for Splits<'a, T> {
|
||||
impl<'a, T, P> Iterator<&'a [T]> for Splits<'a, T, P> where P: FnMut(&T) -> bool {
|
||||
#[inline]
|
||||
fn next(&mut self) -> Option<&'a [T]> {
|
||||
if self.finished { return None; }
|
||||
|
|
@ -1304,7 +1318,7 @@ impl<'a, T> Iterator<&'a [T]> for Splits<'a, T> {
|
|||
}
|
||||
|
||||
#[experimental = "needs review"]
|
||||
impl<'a, T> DoubleEndedIterator<&'a [T]> for Splits<'a, T> {
|
||||
impl<'a, T, P> DoubleEndedIterator<&'a [T]> for Splits<'a, T, P> where P: FnMut(&T) -> bool {
|
||||
#[inline]
|
||||
fn next_back(&mut self) -> Option<&'a [T]> {
|
||||
if self.finished { return None; }
|
||||
|
|
@ -1320,7 +1334,7 @@ impl<'a, T> DoubleEndedIterator<&'a [T]> for Splits<'a, T> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'a, T> SplitsIter<&'a [T]> for Splits<'a, T> {
|
||||
impl<'a, T, P> SplitsIter<&'a [T]> for Splits<'a, T, P> where P: FnMut(&T) -> bool {
|
||||
#[inline]
|
||||
fn finish(&mut self) -> Option<&'a [T]> {
|
||||
if self.finished { None } else { self.finished = true; Some(self.v) }
|
||||
|
|
@ -1330,13 +1344,13 @@ impl<'a, T> SplitsIter<&'a [T]> for Splits<'a, T> {
|
|||
/// An iterator over the subslices of the vector which are separated
|
||||
/// by elements that match `pred`.
|
||||
#[experimental = "needs review"]
|
||||
pub struct MutSplits<'a, T:'a> {
|
||||
pub struct MutSplits<'a, T:'a, P> where P: FnMut(&T) -> bool {
|
||||
v: &'a mut [T],
|
||||
pred: |t: &T|: 'a -> bool,
|
||||
pred: P,
|
||||
finished: bool
|
||||
}
|
||||
|
||||
impl<'a, T> SplitsIter<&'a mut [T]> for MutSplits<'a, T> {
|
||||
impl<'a, T, P> SplitsIter<&'a mut [T]> for MutSplits<'a, T, P> where P: FnMut(&T) -> bool {
|
||||
#[inline]
|
||||
fn finish(&mut self) -> Option<&'a mut [T]> {
|
||||
if self.finished {
|
||||
|
|
@ -1349,7 +1363,7 @@ impl<'a, T> SplitsIter<&'a mut [T]> for MutSplits<'a, T> {
|
|||
}
|
||||
|
||||
#[experimental = "needs review"]
|
||||
impl<'a, T> Iterator<&'a mut [T]> for MutSplits<'a, T> {
|
||||
impl<'a, T, P> Iterator<&'a mut [T]> for MutSplits<'a, T, P> where P: FnMut(&T) -> bool {
|
||||
#[inline]
|
||||
fn next(&mut self) -> Option<&'a mut [T]> {
|
||||
if self.finished { return None; }
|
||||
|
|
@ -1382,7 +1396,9 @@ impl<'a, T> Iterator<&'a mut [T]> for MutSplits<'a, T> {
|
|||
}
|
||||
|
||||
#[experimental = "needs review"]
|
||||
impl<'a, T> DoubleEndedIterator<&'a mut [T]> for MutSplits<'a, T> {
|
||||
impl<'a, T, P> DoubleEndedIterator<&'a mut [T]> for MutSplits<'a, T, P> where
|
||||
P: FnMut(&T) -> bool,
|
||||
{
|
||||
#[inline]
|
||||
fn next_back(&mut self) -> Option<&'a mut [T]> {
|
||||
if self.finished { return None; }
|
||||
|
|
@ -1709,6 +1725,7 @@ pub mod raw {
|
|||
use mem::transmute;
|
||||
use ptr::RawPtr;
|
||||
use raw::Slice;
|
||||
use ops::FnOnce;
|
||||
use option::Option;
|
||||
use option::Option::{None, Some};
|
||||
|
||||
|
|
@ -1716,8 +1733,9 @@ pub mod raw {
|
|||
/// not bytes).
|
||||
#[inline]
|
||||
#[deprecated = "renamed to slice::from_raw_buf"]
|
||||
pub unsafe fn buf_as_slice<T,U>(p: *const T, len: uint, f: |v: &[T]| -> U)
|
||||
-> U {
|
||||
pub unsafe fn buf_as_slice<T, U, F>(p: *const T, len: uint, f: F) -> U where
|
||||
F: FnOnce(&[T]) -> U,
|
||||
{
|
||||
f(transmute(Slice {
|
||||
data: p,
|
||||
len: len
|
||||
|
|
@ -1728,12 +1746,9 @@ pub mod raw {
|
|||
/// not bytes).
|
||||
#[inline]
|
||||
#[deprecated = "renamed to slice::from_raw_mut_buf"]
|
||||
pub unsafe fn mut_buf_as_slice<T,
|
||||
U>(
|
||||
p: *mut T,
|
||||
len: uint,
|
||||
f: |v: &mut [T]| -> U)
|
||||
-> U {
|
||||
pub unsafe fn mut_buf_as_slice<T, U, F>(p: *mut T, len: uint, f: F) -> U where
|
||||
F: FnOnce(&mut [T]) -> U,
|
||||
{
|
||||
f(transmute(Slice {
|
||||
data: p as *const T,
|
||||
len: len
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@ use mem;
|
|||
use num::Int;
|
||||
use option::Option;
|
||||
use option::Option::{None, Some};
|
||||
use ops::FnMut;
|
||||
use ptr::RawPtr;
|
||||
use raw::{Repr, Slice};
|
||||
use slice::{mod, SlicePrelude};
|
||||
|
|
@ -136,15 +137,7 @@ impl CharEq for char {
|
|||
fn only_ascii(&self) -> bool { (*self as uint) < 128 }
|
||||
}
|
||||
|
||||
impl<'a> CharEq for |char|: 'a -> bool {
|
||||
#[inline]
|
||||
fn matches(&mut self, c: char) -> bool { (*self)(c) }
|
||||
|
||||
#[inline]
|
||||
fn only_ascii(&self) -> bool { false }
|
||||
}
|
||||
|
||||
impl CharEq for extern "Rust" fn(char) -> bool {
|
||||
impl<F> CharEq for F where F: FnMut(char) -> bool {
|
||||
#[inline]
|
||||
fn matches(&mut self, c: char) -> bool { (*self)(c) }
|
||||
|
||||
|
|
@ -323,8 +316,7 @@ impl<'a> DoubleEndedIterator<(uint, char)> for CharOffsets<'a> {
|
|||
|
||||
/// External iterator for a string's bytes.
|
||||
/// Use with the `std::iter` module.
|
||||
pub type Bytes<'a> =
|
||||
Map<'a, &'a u8, u8, slice::Items<'a, u8>>;
|
||||
pub type Bytes<'a> = Map<&'a u8, u8, slice::Items<'a, u8>, fn(&u8) -> u8>;
|
||||
|
||||
/// An iterator over the substrings of a string, separated by `sep`.
|
||||
#[deriving(Clone)]
|
||||
|
|
@ -349,8 +341,7 @@ pub struct CharSplitsN<'a, Sep> {
|
|||
}
|
||||
|
||||
/// An iterator over the lines of a string, separated by either `\n` or (`\r\n`).
|
||||
pub type AnyLines<'a> =
|
||||
Map<'a, &'a str, &'a str, CharSplits<'a, char>>;
|
||||
pub type AnyLines<'a> = Map<&'a str, &'a str, CharSplits<'a, char>, fn(&str) -> &str>;
|
||||
|
||||
impl<'a, Sep> CharSplits<'a, Sep> {
|
||||
#[inline]
|
||||
|
|
@ -1361,10 +1352,13 @@ pub trait StrPrelude for Sized? {
|
|||
/// # Example
|
||||
///
|
||||
/// ```rust
|
||||
/// # #![feature(unboxed_closures)]
|
||||
///
|
||||
/// # fn main() {
|
||||
/// let v: Vec<&str> = "Mary had a little lamb".split(' ').collect();
|
||||
/// assert_eq!(v, vec!["Mary", "had", "a", "little", "lamb"]);
|
||||
///
|
||||
/// let v: Vec<&str> = "abc1def2ghi".split(|c: char| c.is_numeric()).collect();
|
||||
/// let v: Vec<&str> = "abc1def2ghi".split(|&: c: char| c.is_numeric()).collect();
|
||||
/// assert_eq!(v, vec!["abc", "def", "ghi"]);
|
||||
///
|
||||
/// let v: Vec<&str> = "lionXXtigerXleopard".split('X').collect();
|
||||
|
|
@ -1372,6 +1366,7 @@ pub trait StrPrelude for Sized? {
|
|||
///
|
||||
/// let v: Vec<&str> = "".split('X').collect();
|
||||
/// assert_eq!(v, vec![""]);
|
||||
/// # }
|
||||
/// ```
|
||||
fn split<'a, Sep: CharEq>(&'a self, sep: Sep) -> CharSplits<'a, Sep>;
|
||||
|
||||
|
|
@ -1382,10 +1377,13 @@ pub trait StrPrelude for Sized? {
|
|||
/// # Example
|
||||
///
|
||||
/// ```rust
|
||||
/// # #![feature(unboxed_closures)]
|
||||
///
|
||||
/// # fn main() {
|
||||
/// let v: Vec<&str> = "Mary had a little lambda".splitn(2, ' ').collect();
|
||||
/// assert_eq!(v, vec!["Mary", "had", "a little lambda"]);
|
||||
///
|
||||
/// let v: Vec<&str> = "abc1def2ghi".splitn(1, |c: char| c.is_numeric()).collect();
|
||||
/// let v: Vec<&str> = "abc1def2ghi".splitn(1, |&: c: char| c.is_numeric()).collect();
|
||||
/// assert_eq!(v, vec!["abc", "def2ghi"]);
|
||||
///
|
||||
/// let v: Vec<&str> = "lionXXtigerXleopard".splitn(2, 'X').collect();
|
||||
|
|
@ -1396,6 +1394,7 @@ pub trait StrPrelude for Sized? {
|
|||
///
|
||||
/// let v: Vec<&str> = "".splitn(1, 'X').collect();
|
||||
/// assert_eq!(v, vec![""]);
|
||||
/// # }
|
||||
/// ```
|
||||
fn splitn<'a, Sep: CharEq>(&'a self, count: uint, sep: Sep) -> CharSplitsN<'a, Sep>;
|
||||
|
||||
|
|
@ -1408,6 +1407,9 @@ pub trait StrPrelude for Sized? {
|
|||
/// # Example
|
||||
///
|
||||
/// ```rust
|
||||
/// # #![feature(unboxed_closures)]
|
||||
///
|
||||
/// # fn main() {
|
||||
/// let v: Vec<&str> = "A.B.".split_terminator('.').collect();
|
||||
/// assert_eq!(v, vec!["A", "B"]);
|
||||
///
|
||||
|
|
@ -1417,11 +1419,12 @@ pub trait StrPrelude for Sized? {
|
|||
/// let v: Vec<&str> = "Mary had a little lamb".split(' ').rev().collect();
|
||||
/// assert_eq!(v, vec!["lamb", "little", "a", "had", "Mary"]);
|
||||
///
|
||||
/// let v: Vec<&str> = "abc1def2ghi".split(|c: char| c.is_numeric()).rev().collect();
|
||||
/// let v: Vec<&str> = "abc1def2ghi".split(|&: c: char| c.is_numeric()).rev().collect();
|
||||
/// assert_eq!(v, vec!["ghi", "def", "abc"]);
|
||||
///
|
||||
/// let v: Vec<&str> = "lionXXtigerXleopard".split('X').rev().collect();
|
||||
/// assert_eq!(v, vec!["leopard", "tiger", "", "lion"]);
|
||||
/// # }
|
||||
/// ```
|
||||
fn split_terminator<'a, Sep: CharEq>(&'a self, sep: Sep) -> CharSplits<'a, Sep>;
|
||||
|
||||
|
|
@ -1432,14 +1435,18 @@ pub trait StrPrelude for Sized? {
|
|||
/// # Example
|
||||
///
|
||||
/// ```rust
|
||||
/// # #![feature(unboxed_closures)]
|
||||
///
|
||||
/// # fn main() {
|
||||
/// let v: Vec<&str> = "Mary had a little lamb".rsplitn(2, ' ').collect();
|
||||
/// assert_eq!(v, vec!["lamb", "little", "Mary had a"]);
|
||||
///
|
||||
/// let v: Vec<&str> = "abc1def2ghi".rsplitn(1, |c: char| c.is_numeric()).collect();
|
||||
/// let v: Vec<&str> = "abc1def2ghi".rsplitn(1, |&: c: char| c.is_numeric()).collect();
|
||||
/// assert_eq!(v, vec!["ghi", "abc1def"]);
|
||||
///
|
||||
/// let v: Vec<&str> = "lionXXtigerXleopard".rsplitn(2, 'X').collect();
|
||||
/// assert_eq!(v, vec!["leopard", "tiger", "lionX"]);
|
||||
/// # }
|
||||
/// ```
|
||||
fn rsplitn<'a, Sep: CharEq>(&'a self, count: uint, sep: Sep) -> CharSplitsN<'a, Sep>;
|
||||
|
||||
|
|
@ -1650,10 +1657,14 @@ pub trait StrPrelude for Sized? {
|
|||
/// # Example
|
||||
///
|
||||
/// ```rust
|
||||
/// # #![feature(unboxed_closures)]
|
||||
///
|
||||
/// # fn main() {
|
||||
/// assert_eq!("11foo1bar11".trim_chars('1'), "foo1bar")
|
||||
/// let x: &[_] = &['1', '2'];
|
||||
/// assert_eq!("12foo1bar12".trim_chars(x), "foo1bar")
|
||||
/// assert_eq!("123foo1bar123".trim_chars(|c: char| c.is_numeric()), "foo1bar")
|
||||
/// assert_eq!("123foo1bar123".trim_chars(|&: c: char| c.is_numeric()), "foo1bar")
|
||||
/// # }
|
||||
/// ```
|
||||
fn trim_chars<'a, C: CharEq>(&'a self, to_trim: C) -> &'a str;
|
||||
|
||||
|
|
@ -1666,10 +1677,14 @@ pub trait StrPrelude for Sized? {
|
|||
/// # Example
|
||||
///
|
||||
/// ```rust
|
||||
/// # #![feature(unboxed_closures)]
|
||||
///
|
||||
/// # fn main() {
|
||||
/// assert_eq!("11foo1bar11".trim_left_chars('1'), "foo1bar11")
|
||||
/// let x: &[_] = &['1', '2'];
|
||||
/// assert_eq!("12foo1bar12".trim_left_chars(x), "foo1bar12")
|
||||
/// assert_eq!("123foo1bar123".trim_left_chars(|c: char| c.is_numeric()), "foo1bar123")
|
||||
/// assert_eq!("123foo1bar123".trim_left_chars(|&: c: char| c.is_numeric()), "foo1bar123")
|
||||
/// # }
|
||||
/// ```
|
||||
fn trim_left_chars<'a, C: CharEq>(&'a self, to_trim: C) -> &'a str;
|
||||
|
||||
|
|
@ -1682,10 +1697,14 @@ pub trait StrPrelude for Sized? {
|
|||
/// # Example
|
||||
///
|
||||
/// ```rust
|
||||
/// # #![feature(unboxed_closures)]
|
||||
///
|
||||
/// # fn main() {
|
||||
/// assert_eq!("11foo1bar11".trim_right_chars('1'), "11foo1bar")
|
||||
/// let x: &[_] = &['1', '2'];
|
||||
/// assert_eq!("12foo1bar12".trim_right_chars(x), "12foo1bar")
|
||||
/// assert_eq!("123foo1bar123".trim_right_chars(|c: char| c.is_numeric()), "123foo1bar")
|
||||
/// assert_eq!("123foo1bar123".trim_right_chars(|&: c: char| c.is_numeric()), "123foo1bar")
|
||||
/// # }
|
||||
/// ```
|
||||
fn trim_right_chars<'a, C: CharEq>(&'a self, to_trim: C) -> &'a str;
|
||||
|
||||
|
|
@ -1826,17 +1845,21 @@ pub trait StrPrelude for Sized? {
|
|||
/// # Example
|
||||
///
|
||||
/// ```rust
|
||||
/// # #![feature(unboxed_closures)]
|
||||
///
|
||||
/// # fn main() {
|
||||
/// let s = "Löwe 老虎 Léopard";
|
||||
///
|
||||
/// assert_eq!(s.find('L'), Some(0));
|
||||
/// assert_eq!(s.find('é'), Some(14));
|
||||
///
|
||||
/// // the first space
|
||||
/// assert_eq!(s.find(|c: char| c.is_whitespace()), Some(5));
|
||||
/// assert_eq!(s.find(|&: c: char| c.is_whitespace()), Some(5));
|
||||
///
|
||||
/// // neither are found
|
||||
/// let x: &[_] = &['1', '2'];
|
||||
/// assert_eq!(s.find(x), None);
|
||||
/// # }
|
||||
/// ```
|
||||
fn find<C: CharEq>(&self, search: C) -> Option<uint>;
|
||||
|
||||
|
|
@ -1851,17 +1874,21 @@ pub trait StrPrelude for Sized? {
|
|||
/// # Example
|
||||
///
|
||||
/// ```rust
|
||||
/// # #![feature(unboxed_closures)]
|
||||
///
|
||||
/// # fn main() {
|
||||
/// let s = "Löwe 老虎 Léopard";
|
||||
///
|
||||
/// assert_eq!(s.rfind('L'), Some(13));
|
||||
/// assert_eq!(s.rfind('é'), Some(14));
|
||||
///
|
||||
/// // the second space
|
||||
/// assert_eq!(s.rfind(|c: char| c.is_whitespace()), Some(12));
|
||||
/// assert_eq!(s.rfind(|&: c: char| c.is_whitespace()), Some(12));
|
||||
///
|
||||
/// // searches for an occurrence of either `1` or `2`, but neither are found
|
||||
/// let x: &[_] = &['1', '2'];
|
||||
/// assert_eq!(s.rfind(x), None);
|
||||
/// # }
|
||||
/// ```
|
||||
fn rfind<C: CharEq>(&self, search: C) -> Option<uint>;
|
||||
|
||||
|
|
@ -1980,7 +2007,9 @@ impl StrPrelude for str {
|
|||
|
||||
#[inline]
|
||||
fn bytes(&self) -> Bytes {
|
||||
self.as_bytes().iter().map(|&b| b)
|
||||
fn deref(&x: &u8) -> u8 { x }
|
||||
|
||||
self.as_bytes().iter().map(deref)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
|
|
@ -2053,11 +2082,13 @@ impl StrPrelude for str {
|
|||
}
|
||||
|
||||
fn lines_any(&self) -> AnyLines {
|
||||
self.lines().map(|line| {
|
||||
fn f(line: &str) -> &str {
|
||||
let l = line.len();
|
||||
if l > 0 && line.as_bytes()[l - 1] == b'\r' { line.slice(0, l - 1) }
|
||||
else { line }
|
||||
})
|
||||
}
|
||||
|
||||
self.lines().map(f)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
|
|
@ -2140,11 +2171,11 @@ impl StrPrelude for str {
|
|||
|
||||
#[inline]
|
||||
fn trim_chars<C: CharEq>(&self, mut to_trim: C) -> &str {
|
||||
let cur = match self.find(|c: char| !to_trim.matches(c)) {
|
||||
let cur = match self.find(|&mut: c: char| !to_trim.matches(c)) {
|
||||
None => "",
|
||||
Some(i) => unsafe { self.slice_unchecked(i, self.len()) }
|
||||
};
|
||||
match cur.rfind(|c: char| !to_trim.matches(c)) {
|
||||
match cur.rfind(|&mut: c: char| !to_trim.matches(c)) {
|
||||
None => "",
|
||||
Some(i) => {
|
||||
let right = cur.char_range_at(i).next;
|
||||
|
|
@ -2155,7 +2186,7 @@ impl StrPrelude for str {
|
|||
|
||||
#[inline]
|
||||
fn trim_left_chars<C: CharEq>(&self, mut to_trim: C) -> &str {
|
||||
match self.find(|c: char| !to_trim.matches(c)) {
|
||||
match self.find(|&mut: c: char| !to_trim.matches(c)) {
|
||||
None => "",
|
||||
Some(first) => unsafe { self.slice_unchecked(first, self.len()) }
|
||||
}
|
||||
|
|
@ -2163,7 +2194,7 @@ impl StrPrelude for str {
|
|||
|
||||
#[inline]
|
||||
fn trim_right_chars<C: CharEq>(&self, mut to_trim: C) -> &str {
|
||||
match self.rfind(|c: char| !to_trim.matches(c)) {
|
||||
match self.rfind(|&mut: c: char| !to_trim.matches(c)) {
|
||||
None => "",
|
||||
Some(last) => {
|
||||
let next = self.char_range_at(last).next;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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"]);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -87,6 +87,7 @@
|
|||
html_playground_url = "http://play.rust-lang.org/")]
|
||||
#![feature(globs, phase)]
|
||||
#![feature(import_shadowing)]
|
||||
#![feature(unboxed_closures)]
|
||||
#![deny(missing_docs)]
|
||||
|
||||
#[cfg(test)] #[phase(plugin, link)] extern crate log;
|
||||
|
|
@ -867,8 +868,9 @@ impl Copy for LengthLimit {}
|
|||
///
|
||||
/// Panics during iteration if the string contains a non-whitespace
|
||||
/// sequence longer than the limit.
|
||||
fn each_split_within<'a>(ss: &'a str, lim: uint, it: |&'a str| -> bool)
|
||||
-> bool {
|
||||
fn each_split_within<F>(ss: &str, lim: uint, mut it: F) -> bool where
|
||||
F: FnMut(&str) -> bool
|
||||
{
|
||||
// Just for fun, let's write this as a state machine:
|
||||
|
||||
let mut slice_start = 0;
|
||||
|
|
|
|||
|
|
@ -269,6 +269,7 @@
|
|||
html_favicon_url = "http://www.rust-lang.org/favicon.ico",
|
||||
html_root_url = "http://doc.rust-lang.org/nightly/")]
|
||||
#![feature(globs, slicing_syntax)]
|
||||
#![feature(unboxed_closures)]
|
||||
|
||||
pub use self::LabelText::*;
|
||||
|
||||
|
|
@ -420,7 +421,7 @@ pub trait Labeller<'a,N,E> {
|
|||
}
|
||||
|
||||
impl<'a> LabelText<'a> {
|
||||
fn escape_char(c: char, f: |char|) {
|
||||
fn escape_char<F>(c: char, mut f: F) where F: FnMut(char) {
|
||||
match c {
|
||||
// not escaping \\, since Graphviz escString needs to
|
||||
// interpret backslashes; see EscStr above.
|
||||
|
|
|
|||
|
|
@ -142,7 +142,7 @@ impl<'a,T:Clone> CloneSliceAllocPrelude<T> for MaybeOwnedVector<'a,T> {
|
|||
self.as_slice().to_vec()
|
||||
}
|
||||
|
||||
fn partitioned(&self, f: |&T| -> bool) -> (Vec<T>, Vec<T>) {
|
||||
fn partitioned<F>(&self, f: F) -> (Vec<T>, Vec<T>) where F: FnMut(&T) -> bool {
|
||||
self.as_slice().partitioned(f)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -208,14 +208,14 @@ mod ziggurat_tables;
|
|||
// the perf improvement (25-50%) is definitely worth the extra code
|
||||
// size from force-inlining.
|
||||
#[inline(always)]
|
||||
fn ziggurat<R:Rng>(
|
||||
fn ziggurat<R: Rng, P, Z>(
|
||||
rng: &mut R,
|
||||
symmetric: bool,
|
||||
x_tab: ziggurat_tables::ZigTable,
|
||||
f_tab: ziggurat_tables::ZigTable,
|
||||
pdf: |f64|: 'static -> f64,
|
||||
zero_case: |&mut R, f64|: 'static -> f64)
|
||||
-> f64 {
|
||||
mut pdf: P,
|
||||
mut zero_case: Z)
|
||||
-> f64 where P: FnMut(f64) -> f64, Z: FnMut(&mut R, f64) -> f64 {
|
||||
static SCALE: f64 = (1u64 << 53) as f64;
|
||||
loop {
|
||||
// reimplement the f64 generation as an optimisation suggested
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@
|
|||
html_playground_url = "http://play.rust-lang.org/")]
|
||||
|
||||
#![feature(macro_rules, phase, globs)]
|
||||
#![feature(unboxed_closures)]
|
||||
#![no_std]
|
||||
#![experimental]
|
||||
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@
|
|||
html_playground_url = "http://play.rust-lang.org/")]
|
||||
#![allow(unknown_features)]
|
||||
#![feature(macro_rules, phase, slicing_syntax, globs)]
|
||||
#![feature(unboxed_closures)]
|
||||
#![allow(missing_docs)]
|
||||
|
||||
extern crate serialize;
|
||||
|
|
@ -259,7 +260,9 @@ pub mod reader {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn docs<'a>(d: Doc<'a>, it: |uint, Doc<'a>| -> bool) -> bool {
|
||||
pub fn docs<F>(d: Doc, mut it: F) -> bool where
|
||||
F: FnMut(uint, Doc) -> bool,
|
||||
{
|
||||
let mut pos = d.start;
|
||||
while pos < d.end {
|
||||
let elt_tag = try_or!(vuint_at(d.data, pos), false);
|
||||
|
|
@ -273,7 +276,9 @@ pub mod reader {
|
|||
return true;
|
||||
}
|
||||
|
||||
pub fn tagged_docs<'a>(d: Doc<'a>, tg: uint, it: |Doc<'a>| -> bool) -> bool {
|
||||
pub fn tagged_docs<F>(d: Doc, tg: uint, mut it: F) -> bool where
|
||||
F: FnMut(Doc) -> bool,
|
||||
{
|
||||
let mut pos = d.start;
|
||||
while pos < d.end {
|
||||
let elt_tag = try_or!(vuint_at(d.data, pos), false);
|
||||
|
|
@ -290,7 +295,9 @@ pub mod reader {
|
|||
return true;
|
||||
}
|
||||
|
||||
pub fn with_doc_data<'a, T>(d: Doc<'a>, f: |x: &'a [u8]| -> T) -> T {
|
||||
pub fn with_doc_data<T, F>(d: Doc, f: F) -> T where
|
||||
F: FnOnce(&[u8]) -> T,
|
||||
{
|
||||
f(d.data[d.start..d.end])
|
||||
}
|
||||
|
||||
|
|
@ -378,8 +385,9 @@ pub mod reader {
|
|||
Ok(r_doc)
|
||||
}
|
||||
|
||||
fn push_doc<T>(&mut self, exp_tag: EbmlEncoderTag,
|
||||
f: |&mut Decoder<'doc>| -> DecodeResult<T>) -> DecodeResult<T> {
|
||||
fn push_doc<T, F>(&mut self, exp_tag: EbmlEncoderTag, f: F) -> DecodeResult<T> where
|
||||
F: FnOnce(&mut Decoder<'doc>) -> DecodeResult<T>,
|
||||
{
|
||||
let d = try!(self.next_doc(exp_tag));
|
||||
let old_parent = self.parent;
|
||||
let old_pos = self.pos;
|
||||
|
|
@ -397,8 +405,9 @@ pub mod reader {
|
|||
Ok(r as uint)
|
||||
}
|
||||
|
||||
pub fn read_opaque<R>(&mut self,
|
||||
op: |&mut Decoder<'doc>, Doc| -> DecodeResult<R>) -> DecodeResult<R> {
|
||||
pub fn read_opaque<R, F>(&mut self, op: F) -> DecodeResult<R> where
|
||||
F: FnOnce(&mut Decoder, Doc) -> DecodeResult<R>,
|
||||
{
|
||||
let doc = try!(self.next_doc(EsOpaque));
|
||||
|
||||
let (old_parent, old_pos) = (self.parent, self.pos);
|
||||
|
|
@ -471,9 +480,9 @@ pub mod reader {
|
|||
}
|
||||
|
||||
// Compound types:
|
||||
fn read_enum<T>(&mut self,
|
||||
name: &str,
|
||||
f: |&mut Decoder<'doc>| -> DecodeResult<T>) -> DecodeResult<T> {
|
||||
fn read_enum<T, F>(&mut self, name: &str, f: F) -> DecodeResult<T> where
|
||||
F: FnOnce(&mut Decoder<'doc>) -> DecodeResult<T>,
|
||||
{
|
||||
debug!("read_enum({})", name);
|
||||
try!(self._check_label(name));
|
||||
|
||||
|
|
@ -490,10 +499,9 @@ pub mod reader {
|
|||
Ok(result)
|
||||
}
|
||||
|
||||
fn read_enum_variant<T>(&mut self,
|
||||
_: &[&str],
|
||||
f: |&mut Decoder<'doc>, uint| -> DecodeResult<T>)
|
||||
-> DecodeResult<T> {
|
||||
fn read_enum_variant<T, F>(&mut self, _: &[&str], f: F) -> DecodeResult<T> where
|
||||
F: FnOnce(&mut Decoder<'doc>, uint) -> DecodeResult<T>,
|
||||
{
|
||||
debug!("read_enum_variant()");
|
||||
let idx = try!(self._next_uint(EsEnumVid));
|
||||
debug!(" idx={}", idx);
|
||||
|
|
@ -511,17 +519,16 @@ pub mod reader {
|
|||
Ok(result)
|
||||
}
|
||||
|
||||
fn read_enum_variant_arg<T>(&mut self,
|
||||
idx: uint,
|
||||
f: |&mut Decoder<'doc>| -> DecodeResult<T>) -> DecodeResult<T> {
|
||||
fn read_enum_variant_arg<T, F>(&mut self, idx: uint, f: F) -> DecodeResult<T> where
|
||||
F: FnOnce(&mut Decoder<'doc>) -> DecodeResult<T>,
|
||||
{
|
||||
debug!("read_enum_variant_arg(idx={})", idx);
|
||||
f(self)
|
||||
}
|
||||
|
||||
fn read_enum_struct_variant<T>(&mut self,
|
||||
_: &[&str],
|
||||
f: |&mut Decoder<'doc>, uint| -> DecodeResult<T>)
|
||||
-> DecodeResult<T> {
|
||||
fn read_enum_struct_variant<T, F>(&mut self, _: &[&str], f: F) -> DecodeResult<T> where
|
||||
F: FnOnce(&mut Decoder<'doc>, uint) -> DecodeResult<T>,
|
||||
{
|
||||
debug!("read_enum_struct_variant()");
|
||||
let idx = try!(self._next_uint(EsEnumVid));
|
||||
debug!(" idx={}", idx);
|
||||
|
|
@ -539,39 +546,37 @@ pub mod reader {
|
|||
Ok(result)
|
||||
}
|
||||
|
||||
fn read_enum_struct_variant_field<T>(&mut self,
|
||||
name: &str,
|
||||
idx: uint,
|
||||
f: |&mut Decoder<'doc>| -> DecodeResult<T>)
|
||||
-> DecodeResult<T> {
|
||||
debug!("read_enum_struct_variant_arg(name={}, idx={})", name, idx);
|
||||
fn read_enum_struct_variant_field<T, F>(&mut self,
|
||||
name: &str,
|
||||
idx: uint,
|
||||
f: F)
|
||||
-> DecodeResult<T> where
|
||||
F: FnOnce(&mut Decoder<'doc>) -> DecodeResult<T>,
|
||||
{
|
||||
debug!("read_enum_struct_variant_arg(name={}, idx={})", name, idx);
|
||||
f(self)
|
||||
}
|
||||
|
||||
fn read_struct<T>(&mut self,
|
||||
name: &str,
|
||||
_: uint,
|
||||
f: |&mut Decoder<'doc>| -> DecodeResult<T>)
|
||||
-> DecodeResult<T> {
|
||||
fn read_struct<T, F>(&mut self, name: &str, _: uint, f: F) -> DecodeResult<T> where
|
||||
F: FnOnce(&mut Decoder<'doc>) -> DecodeResult<T>,
|
||||
{
|
||||
debug!("read_struct(name={})", name);
|
||||
f(self)
|
||||
}
|
||||
|
||||
fn read_struct_field<T>(&mut self,
|
||||
name: &str,
|
||||
idx: uint,
|
||||
f: |&mut Decoder<'doc>| -> DecodeResult<T>)
|
||||
-> DecodeResult<T> {
|
||||
fn read_struct_field<T, F>(&mut self, name: &str, idx: uint, f: F) -> DecodeResult<T> where
|
||||
F: FnOnce(&mut Decoder<'doc>) -> DecodeResult<T>,
|
||||
{
|
||||
debug!("read_struct_field(name={}, idx={})", name, idx);
|
||||
try!(self._check_label(name));
|
||||
f(self)
|
||||
}
|
||||
|
||||
fn read_tuple<T>(&mut self,
|
||||
tuple_len: uint,
|
||||
f: |&mut Decoder<'doc>| -> DecodeResult<T>) -> DecodeResult<T> {
|
||||
fn read_tuple<T, F>(&mut self, tuple_len: uint, f: F) -> DecodeResult<T> where
|
||||
F: FnOnce(&mut Decoder<'doc>) -> DecodeResult<T>,
|
||||
{
|
||||
debug!("read_tuple()");
|
||||
self.read_seq(|d, len| {
|
||||
self.read_seq(move |d, len| {
|
||||
if len == tuple_len {
|
||||
f(d)
|
||||
} else {
|
||||
|
|
@ -581,34 +586,36 @@ pub mod reader {
|
|||
})
|
||||
}
|
||||
|
||||
fn read_tuple_arg<T>(&mut self, idx: uint, f: |&mut Decoder<'doc>| -> DecodeResult<T>)
|
||||
-> DecodeResult<T> {
|
||||
fn read_tuple_arg<T, F>(&mut self, idx: uint, f: F) -> DecodeResult<T> where
|
||||
F: FnOnce(&mut Decoder<'doc>) -> DecodeResult<T>,
|
||||
{
|
||||
debug!("read_tuple_arg(idx={})", idx);
|
||||
self.read_seq_elt(idx, f)
|
||||
}
|
||||
|
||||
fn read_tuple_struct<T>(&mut self,
|
||||
name: &str,
|
||||
len: uint,
|
||||
f: |&mut Decoder<'doc>| -> DecodeResult<T>)
|
||||
-> DecodeResult<T> {
|
||||
fn read_tuple_struct<T, F>(&mut self, name: &str, len: uint, f: F) -> DecodeResult<T> where
|
||||
F: FnOnce(&mut Decoder<'doc>) -> DecodeResult<T>,
|
||||
{
|
||||
debug!("read_tuple_struct(name={})", name);
|
||||
self.read_tuple(len, f)
|
||||
}
|
||||
|
||||
fn read_tuple_struct_arg<T>(&mut self,
|
||||
idx: uint,
|
||||
f: |&mut Decoder<'doc>| -> DecodeResult<T>)
|
||||
-> DecodeResult<T> {
|
||||
fn read_tuple_struct_arg<T, F>(&mut self,
|
||||
idx: uint,
|
||||
f: F)
|
||||
-> DecodeResult<T> where
|
||||
F: FnOnce(&mut Decoder<'doc>) -> DecodeResult<T>,
|
||||
{
|
||||
debug!("read_tuple_struct_arg(idx={})", idx);
|
||||
self.read_tuple_arg(idx, f)
|
||||
}
|
||||
|
||||
fn read_option<T>(&mut self,
|
||||
f: |&mut Decoder<'doc>, bool| -> DecodeResult<T>) -> DecodeResult<T> {
|
||||
fn read_option<T, F>(&mut self, f: F) -> DecodeResult<T> where
|
||||
F: FnOnce(&mut Decoder<'doc>, bool) -> DecodeResult<T>,
|
||||
{
|
||||
debug!("read_option()");
|
||||
self.read_enum("Option", |this| {
|
||||
this.read_enum_variant(&["None", "Some"], |this, idx| {
|
||||
self.read_enum("Option", move |this| {
|
||||
this.read_enum_variant(&["None", "Some"], move |this, idx| {
|
||||
match idx {
|
||||
0 => f(this, false),
|
||||
1 => f(this, true),
|
||||
|
|
@ -620,40 +627,45 @@ pub mod reader {
|
|||
})
|
||||
}
|
||||
|
||||
fn read_seq<T>(&mut self,
|
||||
f: |&mut Decoder<'doc>, uint| -> DecodeResult<T>) -> DecodeResult<T> {
|
||||
fn read_seq<T, F>(&mut self, f: F) -> DecodeResult<T> where
|
||||
F: FnOnce(&mut Decoder<'doc>, uint) -> DecodeResult<T>,
|
||||
{
|
||||
debug!("read_seq()");
|
||||
self.push_doc(EsVec, |d| {
|
||||
self.push_doc(EsVec, move |d| {
|
||||
let len = try!(d._next_uint(EsVecLen));
|
||||
debug!(" len={}", len);
|
||||
f(d, len)
|
||||
})
|
||||
}
|
||||
|
||||
fn read_seq_elt<T>(&mut self, idx: uint, f: |&mut Decoder<'doc>| -> DecodeResult<T>)
|
||||
-> DecodeResult<T> {
|
||||
fn read_seq_elt<T, F>(&mut self, idx: uint, f: F) -> DecodeResult<T> where
|
||||
F: FnOnce(&mut Decoder<'doc>) -> DecodeResult<T>,
|
||||
{
|
||||
debug!("read_seq_elt(idx={})", idx);
|
||||
self.push_doc(EsVecElt, f)
|
||||
}
|
||||
|
||||
fn read_map<T>(&mut self,
|
||||
f: |&mut Decoder<'doc>, uint| -> DecodeResult<T>) -> DecodeResult<T> {
|
||||
fn read_map<T, F>(&mut self, f: F) -> DecodeResult<T> where
|
||||
F: FnOnce(&mut Decoder<'doc>, uint) -> DecodeResult<T>,
|
||||
{
|
||||
debug!("read_map()");
|
||||
self.push_doc(EsMap, |d| {
|
||||
self.push_doc(EsMap, move |d| {
|
||||
let len = try!(d._next_uint(EsMapLen));
|
||||
debug!(" len={}", len);
|
||||
f(d, len)
|
||||
})
|
||||
}
|
||||
|
||||
fn read_map_elt_key<T>(&mut self, idx: uint, f: |&mut Decoder<'doc>| -> DecodeResult<T>)
|
||||
-> DecodeResult<T> {
|
||||
fn read_map_elt_key<T, F>(&mut self, idx: uint, f: F) -> DecodeResult<T> where
|
||||
F: FnOnce(&mut Decoder<'doc>) -> DecodeResult<T>,
|
||||
{
|
||||
debug!("read_map_elt_key(idx={})", idx);
|
||||
self.push_doc(EsMapKey, f)
|
||||
}
|
||||
|
||||
fn read_map_elt_val<T>(&mut self, idx: uint, f: |&mut Decoder<'doc>| -> DecodeResult<T>)
|
||||
-> DecodeResult<T> {
|
||||
fn read_map_elt_val<T, F>(&mut self, idx: uint, f: F) -> DecodeResult<T> where
|
||||
F: FnOnce(&mut Decoder<'doc>) -> DecodeResult<T>,
|
||||
{
|
||||
debug!("read_map_elt_val(idx={})", idx);
|
||||
self.push_doc(EsMapVal, f)
|
||||
}
|
||||
|
|
@ -756,7 +768,9 @@ pub mod writer {
|
|||
Ok(r)
|
||||
}
|
||||
|
||||
pub fn wr_tag(&mut self, tag_id: uint, blk: || -> EncodeResult) -> EncodeResult {
|
||||
pub fn wr_tag<F>(&mut self, tag_id: uint, blk: F) -> EncodeResult where
|
||||
F: FnOnce() -> EncodeResult,
|
||||
{
|
||||
try!(self.start_tag(tag_id));
|
||||
try!(blk());
|
||||
self.end_tag()
|
||||
|
|
@ -852,7 +866,9 @@ pub mod writer {
|
|||
else { Ok(()) }
|
||||
}
|
||||
|
||||
pub fn emit_opaque(&mut self, f: |&mut Encoder<W>| -> EncodeResult) -> EncodeResult {
|
||||
pub fn emit_opaque<F>(&mut self, f: F) -> EncodeResult where
|
||||
F: FnOnce(&mut Encoder<W>) -> EncodeResult,
|
||||
{
|
||||
try!(self.start_tag(EsOpaque as uint));
|
||||
try!(f(self));
|
||||
self.end_tag()
|
||||
|
|
@ -916,102 +932,106 @@ pub mod writer {
|
|||
self.wr_tagged_str(EsStr as uint, v)
|
||||
}
|
||||
|
||||
fn emit_enum(&mut self,
|
||||
name: &str,
|
||||
f: |&mut Encoder<'a, W>| -> EncodeResult) -> EncodeResult {
|
||||
fn emit_enum<F>(&mut self, name: &str, f: F) -> EncodeResult where
|
||||
F: FnOnce(&mut Encoder<'a, W>) -> EncodeResult,
|
||||
{
|
||||
try!(self._emit_label(name));
|
||||
try!(self.start_tag(EsEnum as uint));
|
||||
try!(f(self));
|
||||
self.end_tag()
|
||||
}
|
||||
|
||||
fn emit_enum_variant(&mut self,
|
||||
_: &str,
|
||||
v_id: uint,
|
||||
_: uint,
|
||||
f: |&mut Encoder<'a, W>| -> EncodeResult) -> EncodeResult {
|
||||
fn emit_enum_variant<F>(&mut self,
|
||||
_: &str,
|
||||
v_id: uint,
|
||||
_: uint,
|
||||
f: F) -> EncodeResult where
|
||||
F: FnOnce(&mut Encoder<'a, W>) -> EncodeResult,
|
||||
{
|
||||
try!(self._emit_tagged_uint(EsEnumVid, v_id));
|
||||
try!(self.start_tag(EsEnumBody as uint));
|
||||
try!(f(self));
|
||||
self.end_tag()
|
||||
}
|
||||
|
||||
fn emit_enum_variant_arg(&mut self,
|
||||
_: uint,
|
||||
f: |&mut Encoder<'a, W>| -> EncodeResult) -> EncodeResult {
|
||||
fn emit_enum_variant_arg<F>(&mut self, _: uint, f: F) -> EncodeResult where
|
||||
F: FnOnce(&mut Encoder<'a, W>) -> EncodeResult,
|
||||
{
|
||||
f(self)
|
||||
}
|
||||
|
||||
fn emit_enum_struct_variant(&mut self,
|
||||
v_name: &str,
|
||||
v_id: uint,
|
||||
cnt: uint,
|
||||
f: |&mut Encoder<'a, W>| -> EncodeResult) -> EncodeResult {
|
||||
fn emit_enum_struct_variant<F>(&mut self,
|
||||
v_name: &str,
|
||||
v_id: uint,
|
||||
cnt: uint,
|
||||
f: F) -> EncodeResult where
|
||||
F: FnOnce(&mut Encoder<'a, W>) -> EncodeResult,
|
||||
{
|
||||
self.emit_enum_variant(v_name, v_id, cnt, f)
|
||||
}
|
||||
|
||||
fn emit_enum_struct_variant_field(&mut self,
|
||||
_: &str,
|
||||
idx: uint,
|
||||
f: |&mut Encoder<'a, W>| -> EncodeResult)
|
||||
-> EncodeResult {
|
||||
fn emit_enum_struct_variant_field<F>(&mut self,
|
||||
_: &str,
|
||||
idx: uint,
|
||||
f: F) -> EncodeResult where
|
||||
F: FnOnce(&mut Encoder<'a, W>) -> EncodeResult,
|
||||
{
|
||||
self.emit_enum_variant_arg(idx, f)
|
||||
}
|
||||
|
||||
fn emit_struct(&mut self,
|
||||
_: &str,
|
||||
_len: uint,
|
||||
f: |&mut Encoder<'a, W>| -> EncodeResult) -> EncodeResult {
|
||||
fn emit_struct<F>(&mut self, _: &str, _len: uint, f: F) -> EncodeResult where
|
||||
F: FnOnce(&mut Encoder<'a, W>) -> EncodeResult,
|
||||
{
|
||||
f(self)
|
||||
}
|
||||
|
||||
fn emit_struct_field(&mut self,
|
||||
name: &str,
|
||||
_: uint,
|
||||
f: |&mut Encoder<'a, W>| -> EncodeResult) -> EncodeResult {
|
||||
fn emit_struct_field<F>(&mut self, name: &str, _: uint, f: F) -> EncodeResult where
|
||||
F: FnOnce(&mut Encoder<'a, W>) -> EncodeResult,
|
||||
{
|
||||
try!(self._emit_label(name));
|
||||
f(self)
|
||||
}
|
||||
|
||||
fn emit_tuple(&mut self,
|
||||
len: uint,
|
||||
f: |&mut Encoder<'a, W>| -> EncodeResult) -> EncodeResult {
|
||||
fn emit_tuple<F>(&mut self, len: uint, f: F) -> EncodeResult where
|
||||
F: FnOnce(&mut Encoder<'a, W>) -> EncodeResult,
|
||||
{
|
||||
self.emit_seq(len, f)
|
||||
}
|
||||
fn emit_tuple_arg(&mut self,
|
||||
idx: uint,
|
||||
f: |&mut Encoder<'a, W>| -> EncodeResult) -> EncodeResult {
|
||||
fn emit_tuple_arg<F>(&mut self, idx: uint, f: F) -> EncodeResult where
|
||||
F: FnOnce(&mut Encoder<'a, W>) -> EncodeResult,
|
||||
{
|
||||
self.emit_seq_elt(idx, f)
|
||||
}
|
||||
|
||||
fn emit_tuple_struct(&mut self,
|
||||
_: &str,
|
||||
len: uint,
|
||||
f: |&mut Encoder<'a, W>| -> EncodeResult) -> EncodeResult {
|
||||
fn emit_tuple_struct<F>(&mut self, _: &str, len: uint, f: F) -> EncodeResult where
|
||||
F: FnOnce(&mut Encoder<'a, W>) -> EncodeResult,
|
||||
{
|
||||
self.emit_seq(len, f)
|
||||
}
|
||||
fn emit_tuple_struct_arg(&mut self,
|
||||
idx: uint,
|
||||
f: |&mut Encoder<'a, W>| -> EncodeResult) -> EncodeResult {
|
||||
fn emit_tuple_struct_arg<F>(&mut self, idx: uint, f: F) -> EncodeResult where
|
||||
F: FnOnce(&mut Encoder<'a, W>) -> EncodeResult,
|
||||
{
|
||||
self.emit_seq_elt(idx, f)
|
||||
}
|
||||
|
||||
fn emit_option(&mut self,
|
||||
f: |&mut Encoder<'a, W>| -> EncodeResult) -> EncodeResult {
|
||||
fn emit_option<F>(&mut self, f: F) -> EncodeResult where
|
||||
F: FnOnce(&mut Encoder<'a, W>) -> EncodeResult,
|
||||
{
|
||||
self.emit_enum("Option", f)
|
||||
}
|
||||
fn emit_option_none(&mut self) -> EncodeResult {
|
||||
self.emit_enum_variant("None", 0, 0, |_| Ok(()))
|
||||
}
|
||||
fn emit_option_some(&mut self,
|
||||
f: |&mut Encoder<'a, W>| -> EncodeResult) -> EncodeResult {
|
||||
fn emit_option_some<F>(&mut self, f: F) -> EncodeResult where
|
||||
F: FnOnce(&mut Encoder<'a, W>) -> EncodeResult,
|
||||
{
|
||||
|
||||
self.emit_enum_variant("Some", 1, 1, f)
|
||||
}
|
||||
|
||||
fn emit_seq(&mut self,
|
||||
len: uint,
|
||||
f: |&mut Encoder<'a, W>| -> EncodeResult) -> EncodeResult {
|
||||
fn emit_seq<F>(&mut self, len: uint, f: F) -> EncodeResult where
|
||||
F: FnOnce(&mut Encoder<'a, W>) -> EncodeResult,
|
||||
{
|
||||
|
||||
try!(self.start_tag(EsVec as uint));
|
||||
try!(self._emit_tagged_uint(EsVecLen, len));
|
||||
|
|
@ -1019,18 +1039,18 @@ pub mod writer {
|
|||
self.end_tag()
|
||||
}
|
||||
|
||||
fn emit_seq_elt(&mut self,
|
||||
_idx: uint,
|
||||
f: |&mut Encoder<'a, W>| -> EncodeResult) -> EncodeResult {
|
||||
fn emit_seq_elt<F>(&mut self, _idx: uint, f: F) -> EncodeResult where
|
||||
F: FnOnce(&mut Encoder<'a, W>) -> EncodeResult,
|
||||
{
|
||||
|
||||
try!(self.start_tag(EsVecElt as uint));
|
||||
try!(f(self));
|
||||
self.end_tag()
|
||||
}
|
||||
|
||||
fn emit_map(&mut self,
|
||||
len: uint,
|
||||
f: |&mut Encoder<'a, W>| -> EncodeResult) -> EncodeResult {
|
||||
fn emit_map<F>(&mut self, len: uint, f: F) -> EncodeResult where
|
||||
F: FnOnce(&mut Encoder<'a, W>) -> EncodeResult,
|
||||
{
|
||||
|
||||
try!(self.start_tag(EsMap as uint));
|
||||
try!(self._emit_tagged_uint(EsMapLen, len));
|
||||
|
|
@ -1038,18 +1058,18 @@ pub mod writer {
|
|||
self.end_tag()
|
||||
}
|
||||
|
||||
fn emit_map_elt_key(&mut self,
|
||||
_idx: uint,
|
||||
f: |&mut Encoder<'a, W>| -> EncodeResult) -> EncodeResult {
|
||||
fn emit_map_elt_key<F>(&mut self, _idx: uint, mut f: F) -> EncodeResult where
|
||||
F: FnMut(&mut Encoder<'a, W>) -> EncodeResult,
|
||||
{
|
||||
|
||||
try!(self.start_tag(EsMapKey as uint));
|
||||
try!(f(self));
|
||||
self.end_tag()
|
||||
}
|
||||
|
||||
fn emit_map_elt_val(&mut self,
|
||||
_idx: uint,
|
||||
f: |&mut Encoder<'a, W>| -> EncodeResult) -> EncodeResult {
|
||||
fn emit_map_elt_val<F>(&mut self, _idx: uint, f: F) -> EncodeResult where
|
||||
F: FnOnce(&mut Encoder<'a, W>) -> EncodeResult,
|
||||
{
|
||||
try!(self.start_tag(EsMapVal as uint));
|
||||
try!(f(self));
|
||||
self.end_tag()
|
||||
|
|
|
|||
|
|
@ -370,6 +370,7 @@
|
|||
|
||||
#![allow(unknown_features)]
|
||||
#![feature(macro_rules, phase, slicing_syntax, globs)]
|
||||
#![feature(unboxed_closures)]
|
||||
#![deny(missing_docs)]
|
||||
|
||||
#[cfg(test)]
|
||||
|
|
|
|||
|
|
@ -838,8 +838,9 @@ impl<'a> Parser<'a> {
|
|||
// Otherwise, an error will be returned.
|
||||
// Generally, `allow_start` is only true when you're *not* expecting an
|
||||
// opening parenthesis.
|
||||
fn pos_last(&self, allow_start: bool, pred: |&BuildAst| -> bool)
|
||||
-> Result<uint, Error> {
|
||||
fn pos_last<P>(&self, allow_start: bool, pred: P) -> Result<uint, Error> where
|
||||
P: FnMut(&BuildAst) -> bool,
|
||||
{
|
||||
let from = match self.stack.iter().rev().position(pred) {
|
||||
Some(i) => i,
|
||||
None => {
|
||||
|
|
@ -887,8 +888,9 @@ impl<'a> Parser<'a> {
|
|||
// build_from combines all AST elements starting at 'from' in the
|
||||
// parser's stack using 'mk' to combine them. If any such element is not an
|
||||
// AST then it is popped off the stack and ignored.
|
||||
fn build_from(&mut self, from: uint, mk: |Ast, Ast| -> Ast)
|
||||
-> Result<Ast, Error> {
|
||||
fn build_from<F>(&mut self, from: uint, mut mk: F) -> Result<Ast, Error> where
|
||||
F: FnMut(Ast, Ast) -> Ast,
|
||||
{
|
||||
if from >= self.stack.len() {
|
||||
return self.err("Empty group or alternate not allowed.")
|
||||
}
|
||||
|
|
|
|||
|
|
@ -429,10 +429,11 @@ impl Regex {
|
|||
///
|
||||
/// ```rust
|
||||
/// # #![feature(phase)]
|
||||
/// # #![feature(unboxed_closures)]
|
||||
/// # extern crate regex; #[phase(plugin)] extern crate regex_macros;
|
||||
/// # use regex::Captures; fn main() {
|
||||
/// let re = regex!(r"([^,\s]+),\s+(\S+)");
|
||||
/// let result = re.replace("Springsteen, Bruce", |caps: &Captures| {
|
||||
/// let result = re.replace("Springsteen, Bruce", |&: caps: &Captures| {
|
||||
/// format!("{} {}", caps.at(2), caps.at(1))
|
||||
/// });
|
||||
/// assert_eq!(result.as_slice(), "Bruce Springsteen");
|
||||
|
|
@ -585,7 +586,7 @@ impl<'t> Replacer for &'t str {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'t> Replacer for |&Captures|: 't -> String {
|
||||
impl<F> Replacer for F where F: FnMut(&Captures) -> String {
|
||||
fn reg_replace<'a>(&'a mut self, caps: &Captures) -> CowString<'a> {
|
||||
(*self)(caps).into_cow()
|
||||
}
|
||||
|
|
@ -767,7 +768,7 @@ impl<'t> Captures<'t> {
|
|||
// How evil can you get?
|
||||
// FIXME: Don't use regexes for this. It's completely unnecessary.
|
||||
let re = Regex::new(r"(^|[^$]|\b)\$(\w+)").unwrap();
|
||||
let text = re.replace_all(text, |refs: &Captures| -> String {
|
||||
let text = re.replace_all(text, |&mut: refs: &Captures| -> String {
|
||||
let (pre, name) = (refs.at(1), refs.at(2));
|
||||
format!("{}{}", pre,
|
||||
match from_str::<uint>(name.as_slice()) {
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@
|
|||
html_root_url = "http://doc.rust-lang.org/nightly/")]
|
||||
|
||||
#![feature(plugin_registrar, quote)]
|
||||
#![feature(unboxed_closures)]
|
||||
|
||||
extern crate regex;
|
||||
extern crate syntax;
|
||||
|
|
@ -601,9 +602,10 @@ fn exec<'t>(which: ::regex::native::MatchKind, input: &'t str,
|
|||
|
||||
// Converts `xs` to a `[x1, x2, .., xN]` expression by calling `to_expr`
|
||||
// on each element in `xs`.
|
||||
fn vec_expr<T, It: Iterator<T>>(&self, xs: It,
|
||||
to_expr: |&ExtCtxt, T| -> P<ast::Expr>)
|
||||
-> P<ast::Expr> {
|
||||
fn vec_expr<T, It, F>(&self, xs: It, mut to_expr: F) -> P<ast::Expr> where
|
||||
It: Iterator<T>,
|
||||
F: FnMut(&ExtCtxt, T) -> P<ast::Expr>,
|
||||
{
|
||||
let exprs = xs.map(|x| to_expr(self.cx, x)).collect();
|
||||
self.cx.expr_vec(self.sp, exprs)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -464,9 +464,11 @@ impl<'a, 'tcx> Context<'a, 'tcx> {
|
|||
/// Merge the lints specified by any lint attributes into the
|
||||
/// current lint context, call the provided function, then reset the
|
||||
/// lints in effect to their previous state.
|
||||
fn with_lint_attrs(&mut self,
|
||||
attrs: &[ast::Attribute],
|
||||
f: |&mut Context|) {
|
||||
fn with_lint_attrs<F>(&mut self,
|
||||
attrs: &[ast::Attribute],
|
||||
f: F) where
|
||||
F: FnOnce(&mut Context),
|
||||
{
|
||||
// Parse all of the lint attributes, and then add them all to the
|
||||
// current dictionary of lint information. Along the way, keep a history
|
||||
// of what we changed so we can roll everything back after invoking the
|
||||
|
|
@ -528,7 +530,9 @@ impl<'a, 'tcx> Context<'a, 'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
fn visit_ids(&mut self, f: |&mut ast_util::IdVisitor<Context>|) {
|
||||
fn visit_ids<F>(&mut self, f: F) where
|
||||
F: FnOnce(&mut ast_util::IdVisitor<Context>)
|
||||
{
|
||||
let mut v = ast_util::IdVisitor {
|
||||
operation: self,
|
||||
pass_through_items: false,
|
||||
|
|
|
|||
|
|
@ -47,20 +47,22 @@ pub fn get_symbol(cstore: &cstore::CStore, def: ast::DefId) -> String {
|
|||
}
|
||||
|
||||
/// Iterates over all the language items in the given crate.
|
||||
pub fn each_lang_item(cstore: &cstore::CStore,
|
||||
cnum: ast::CrateNum,
|
||||
f: |ast::NodeId, uint| -> bool)
|
||||
-> bool {
|
||||
pub fn each_lang_item<F>(cstore: &cstore::CStore,
|
||||
cnum: ast::CrateNum,
|
||||
f: F)
|
||||
-> bool where
|
||||
F: FnMut(ast::NodeId, uint) -> bool,
|
||||
{
|
||||
let crate_data = cstore.get_crate_data(cnum);
|
||||
decoder::each_lang_item(&*crate_data, f)
|
||||
}
|
||||
|
||||
/// Iterates over each child of the given item.
|
||||
pub fn each_child_of_item(cstore: &cstore::CStore,
|
||||
def_id: ast::DefId,
|
||||
callback: |decoder::DefLike,
|
||||
ast::Name,
|
||||
ast::Visibility|) {
|
||||
pub fn each_child_of_item<F>(cstore: &cstore::CStore,
|
||||
def_id: ast::DefId,
|
||||
callback: F) where
|
||||
F: FnMut(decoder::DefLike, ast::Name, ast::Visibility),
|
||||
{
|
||||
let crate_data = cstore.get_crate_data(def_id.krate);
|
||||
let get_crate_data: decoder::GetCrateDataCb = |cnum| {
|
||||
cstore.get_crate_data(cnum)
|
||||
|
|
@ -73,11 +75,11 @@ pub fn each_child_of_item(cstore: &cstore::CStore,
|
|||
}
|
||||
|
||||
/// Iterates over each top-level crate item.
|
||||
pub fn each_top_level_item_of_crate(cstore: &cstore::CStore,
|
||||
cnum: ast::CrateNum,
|
||||
callback: |decoder::DefLike,
|
||||
ast::Name,
|
||||
ast::Visibility|) {
|
||||
pub fn each_top_level_item_of_crate<F>(cstore: &cstore::CStore,
|
||||
cnum: ast::CrateNum,
|
||||
callback: F) where
|
||||
F: FnMut(decoder::DefLike, ast::Name, ast::Visibility),
|
||||
{
|
||||
let crate_data = cstore.get_crate_data(cnum);
|
||||
let get_crate_data: decoder::GetCrateDataCb = |cnum| {
|
||||
cstore.get_crate_data(cnum)
|
||||
|
|
@ -195,9 +197,11 @@ pub fn get_methods_if_impl(cstore: &cstore::CStore,
|
|||
decoder::get_methods_if_impl(cstore.intr.clone(), &*cdata, def.node)
|
||||
}
|
||||
|
||||
pub fn get_item_attrs(cstore: &cstore::CStore,
|
||||
def_id: ast::DefId,
|
||||
f: |Vec<ast::Attribute>|) {
|
||||
pub fn get_item_attrs<F>(cstore: &cstore::CStore,
|
||||
def_id: ast::DefId,
|
||||
f: F) where
|
||||
F: FnOnce(Vec<ast::Attribute>),
|
||||
{
|
||||
let cdata = cstore.get_crate_data(def_id.krate);
|
||||
decoder::get_item_attrs(&*cdata, def_id.node, f)
|
||||
}
|
||||
|
|
@ -279,23 +283,29 @@ pub fn get_native_libraries(cstore: &cstore::CStore, crate_num: ast::CrateNum)
|
|||
decoder::get_native_libraries(&*cdata)
|
||||
}
|
||||
|
||||
pub fn each_impl(cstore: &cstore::CStore,
|
||||
crate_num: ast::CrateNum,
|
||||
callback: |ast::DefId|) {
|
||||
pub fn each_impl<F>(cstore: &cstore::CStore,
|
||||
crate_num: ast::CrateNum,
|
||||
callback: F) where
|
||||
F: FnMut(ast::DefId),
|
||||
{
|
||||
let cdata = cstore.get_crate_data(crate_num);
|
||||
decoder::each_impl(&*cdata, callback)
|
||||
}
|
||||
|
||||
pub fn each_implementation_for_type(cstore: &cstore::CStore,
|
||||
def_id: ast::DefId,
|
||||
callback: |ast::DefId|) {
|
||||
pub fn each_implementation_for_type<F>(cstore: &cstore::CStore,
|
||||
def_id: ast::DefId,
|
||||
callback: F) where
|
||||
F: FnMut(ast::DefId),
|
||||
{
|
||||
let cdata = cstore.get_crate_data(def_id.krate);
|
||||
decoder::each_implementation_for_type(&*cdata, def_id.node, callback)
|
||||
}
|
||||
|
||||
pub fn each_implementation_for_trait(cstore: &cstore::CStore,
|
||||
def_id: ast::DefId,
|
||||
callback: |ast::DefId|) {
|
||||
pub fn each_implementation_for_trait<F>(cstore: &cstore::CStore,
|
||||
def_id: ast::DefId,
|
||||
callback: F) where
|
||||
F: FnMut(ast::DefId),
|
||||
{
|
||||
let cdata = cstore.get_crate_data(def_id.krate);
|
||||
decoder::each_implementation_for_trait(&*cdata, def_id.node, callback)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -113,16 +113,18 @@ impl CStore {
|
|||
self.metas.borrow_mut().insert(cnum, data);
|
||||
}
|
||||
|
||||
pub fn iter_crate_data(&self, i: |ast::CrateNum, &crate_metadata|) {
|
||||
pub fn iter_crate_data<I>(&self, mut i: I) where
|
||||
I: FnMut(ast::CrateNum, &crate_metadata),
|
||||
{
|
||||
for (&k, v) in self.metas.borrow().iter() {
|
||||
i(k, &**v);
|
||||
}
|
||||
}
|
||||
|
||||
/// Like `iter_crate_data`, but passes source paths (if available) as well.
|
||||
pub fn iter_crate_data_origins(&self, i: |ast::CrateNum,
|
||||
&crate_metadata,
|
||||
Option<CrateSource>|) {
|
||||
pub fn iter_crate_data_origins<I>(&self, mut i: I) where
|
||||
I: FnMut(ast::CrateNum, &crate_metadata, Option<CrateSource>),
|
||||
{
|
||||
for (&k, v) in self.metas.borrow().iter() {
|
||||
let origin = self.get_used_crate_source(k);
|
||||
origin.as_ref().map(|cs| { assert!(k == cs.cnum); });
|
||||
|
|
|
|||
|
|
@ -60,8 +60,9 @@ pub type Cmd<'a> = &'a crate_metadata;
|
|||
// what crate that's in and give us a def_id that makes sense for the current
|
||||
// build.
|
||||
|
||||
fn lookup_hash<'a>(d: rbml::Doc<'a>, eq_fn: |&[u8]| -> bool,
|
||||
hash: u64) -> Option<rbml::Doc<'a>> {
|
||||
fn lookup_hash<'a, F>(d: rbml::Doc<'a>, mut eq_fn: F, hash: u64) -> Option<rbml::Doc<'a>> where
|
||||
F: FnMut(&[u8]) -> bool,
|
||||
{
|
||||
let index = reader::get_doc(d, tag_index);
|
||||
let table = reader::get_doc(index, tag_index_table);
|
||||
let hash_pos = table.start + (hash % 256 * 4) as uint;
|
||||
|
|
@ -212,7 +213,9 @@ fn get_provided_source(d: rbml::Doc, cdata: Cmd) -> Option<ast::DefId> {
|
|||
})
|
||||
}
|
||||
|
||||
fn each_reexport(d: rbml::Doc, f: |rbml::Doc| -> bool) -> bool {
|
||||
fn each_reexport<F>(d: rbml::Doc, f: F) -> bool where
|
||||
F: FnMut(rbml::Doc) -> bool,
|
||||
{
|
||||
reader::tagged_docs(d, tag_items_data_item_reexport, f)
|
||||
}
|
||||
|
||||
|
|
@ -446,7 +449,9 @@ pub enum DefLike {
|
|||
impl Copy for DefLike {}
|
||||
|
||||
/// Iterates over the language items in the given crate.
|
||||
pub fn each_lang_item(cdata: Cmd, f: |ast::NodeId, uint| -> bool) -> bool {
|
||||
pub fn each_lang_item<F>(cdata: Cmd, mut f: F) -> bool where
|
||||
F: FnMut(ast::NodeId, uint) -> bool,
|
||||
{
|
||||
let root = rbml::Doc::new(cdata.data());
|
||||
let lang_items = reader::get_doc(root, tag_lang_items);
|
||||
reader::tagged_docs(lang_items, tag_lang_items_item, |item_doc| {
|
||||
|
|
@ -462,13 +467,13 @@ pub fn each_lang_item(cdata: Cmd, f: |ast::NodeId, uint| -> bool) -> bool {
|
|||
|
||||
pub type GetCrateDataCb<'a> = |ast::CrateNum|: 'a -> Rc<crate_metadata>;
|
||||
|
||||
fn each_child_of_item_or_crate(intr: Rc<IdentInterner>,
|
||||
cdata: Cmd,
|
||||
item_doc: rbml::Doc,
|
||||
get_crate_data: GetCrateDataCb,
|
||||
callback: |DefLike,
|
||||
ast::Name,
|
||||
ast::Visibility|) {
|
||||
fn each_child_of_item_or_crate<F>(intr: Rc<IdentInterner>,
|
||||
cdata: Cmd,
|
||||
item_doc: rbml::Doc,
|
||||
get_crate_data: GetCrateDataCb,
|
||||
mut callback: F) where
|
||||
F: FnMut(DefLike, ast::Name, ast::Visibility),
|
||||
{
|
||||
// Iterate over all children.
|
||||
let _ = reader::tagged_docs(item_doc, tag_mod_child, |child_info_doc| {
|
||||
let child_def_id = reader::with_doc_data(child_info_doc,
|
||||
|
|
@ -581,11 +586,13 @@ fn each_child_of_item_or_crate(intr: Rc<IdentInterner>,
|
|||
}
|
||||
|
||||
/// Iterates over each child of the given item.
|
||||
pub fn each_child_of_item(intr: Rc<IdentInterner>,
|
||||
cdata: Cmd,
|
||||
id: ast::NodeId,
|
||||
get_crate_data: GetCrateDataCb,
|
||||
callback: |DefLike, ast::Name, ast::Visibility|) {
|
||||
pub fn each_child_of_item<F>(intr: Rc<IdentInterner>,
|
||||
cdata: Cmd,
|
||||
id: ast::NodeId,
|
||||
get_crate_data: GetCrateDataCb,
|
||||
callback: F) where
|
||||
F: FnMut(DefLike, ast::Name, ast::Visibility),
|
||||
{
|
||||
// Find the item.
|
||||
let root_doc = rbml::Doc::new(cdata.data());
|
||||
let items = reader::get_doc(root_doc, tag_items);
|
||||
|
|
@ -602,12 +609,12 @@ pub fn each_child_of_item(intr: Rc<IdentInterner>,
|
|||
}
|
||||
|
||||
/// Iterates over all the top-level crate items.
|
||||
pub fn each_top_level_item_of_crate(intr: Rc<IdentInterner>,
|
||||
cdata: Cmd,
|
||||
get_crate_data: GetCrateDataCb,
|
||||
callback: |DefLike,
|
||||
ast::Name,
|
||||
ast::Visibility|) {
|
||||
pub fn each_top_level_item_of_crate<F>(intr: Rc<IdentInterner>,
|
||||
cdata: Cmd,
|
||||
get_crate_data: GetCrateDataCb,
|
||||
callback: F) where
|
||||
F: FnMut(DefLike, ast::Name, ast::Visibility),
|
||||
{
|
||||
let root_doc = rbml::Doc::new(cdata.data());
|
||||
let misc_info_doc = reader::get_doc(root_doc, tag_misc_info);
|
||||
let crate_items_doc = reader::get_doc(misc_info_doc,
|
||||
|
|
@ -980,9 +987,11 @@ pub fn get_tuple_struct_definition_if_ctor(cdata: Cmd,
|
|||
ret
|
||||
}
|
||||
|
||||
pub fn get_item_attrs(cdata: Cmd,
|
||||
orig_node_id: ast::NodeId,
|
||||
f: |Vec<ast::Attribute>|) {
|
||||
pub fn get_item_attrs<F>(cdata: Cmd,
|
||||
orig_node_id: ast::NodeId,
|
||||
f: F) where
|
||||
F: FnOnce(Vec<ast::Attribute>),
|
||||
{
|
||||
// The attributes for a tuple struct are attached to the definition, not the ctor;
|
||||
// we assume that someone passing in a tuple struct ctor is actually wanting to
|
||||
// look at the definition
|
||||
|
|
@ -1222,7 +1231,9 @@ pub fn translate_def_id(cdata: Cmd, did: ast::DefId) -> ast::DefId {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn each_impl(cdata: Cmd, callback: |ast::DefId|) {
|
||||
pub fn each_impl<F>(cdata: Cmd, mut callback: F) where
|
||||
F: FnMut(ast::DefId),
|
||||
{
|
||||
let impls_doc = reader::get_doc(rbml::Doc::new(cdata.data()), tag_impls);
|
||||
let _ = reader::tagged_docs(impls_doc, tag_impls_impl, |impl_doc| {
|
||||
callback(item_def_id(impl_doc, cdata));
|
||||
|
|
@ -1230,9 +1241,11 @@ pub fn each_impl(cdata: Cmd, callback: |ast::DefId|) {
|
|||
});
|
||||
}
|
||||
|
||||
pub fn each_implementation_for_type(cdata: Cmd,
|
||||
pub fn each_implementation_for_type<F>(cdata: Cmd,
|
||||
id: ast::NodeId,
|
||||
callback: |ast::DefId|) {
|
||||
mut callback: F) where
|
||||
F: FnMut(ast::DefId),
|
||||
{
|
||||
let item_doc = lookup_item(id, cdata.data());
|
||||
reader::tagged_docs(item_doc,
|
||||
tag_items_data_item_inherent_impl,
|
||||
|
|
@ -1243,9 +1256,11 @@ pub fn each_implementation_for_type(cdata: Cmd,
|
|||
});
|
||||
}
|
||||
|
||||
pub fn each_implementation_for_trait(cdata: Cmd,
|
||||
id: ast::NodeId,
|
||||
callback: |ast::DefId|) {
|
||||
pub fn each_implementation_for_trait<F>(cdata: Cmd,
|
||||
id: ast::NodeId,
|
||||
mut callback: F) where
|
||||
F: FnMut(ast::DefId),
|
||||
{
|
||||
let item_doc = lookup_item(id, cdata.data());
|
||||
|
||||
let _ = reader::tagged_docs(item_doc,
|
||||
|
|
|
|||
|
|
@ -493,7 +493,9 @@ fn encode_reexported_static_methods(ecx: &EncodeContext,
|
|||
/// top-level items that are sub-items of the given item. Specifically:
|
||||
///
|
||||
/// * For newtype structs, iterates through the node ID of the constructor.
|
||||
fn each_auxiliary_node_id(item: &ast::Item, callback: |NodeId| -> bool) -> bool {
|
||||
fn each_auxiliary_node_id<F>(item: &ast::Item, callback: F) -> bool where
|
||||
F: FnOnce(NodeId) -> bool,
|
||||
{
|
||||
let mut continue_ = true;
|
||||
match item.node {
|
||||
ast::ItemStruct(ref struct_def, _) => {
|
||||
|
|
@ -1579,8 +1581,10 @@ fn encode_info_for_items(ecx: &EncodeContext,
|
|||
|
||||
// Path and definition ID indexing
|
||||
|
||||
fn encode_index<T: Hash>(rbml_w: &mut Encoder, index: Vec<entry<T>>,
|
||||
write_fn: |&mut SeekableMemWriter, &T|) {
|
||||
fn encode_index<T, F>(rbml_w: &mut Encoder, index: Vec<entry<T>>, mut write_fn: F) where
|
||||
F: FnMut(&mut SeekableMemWriter, &T),
|
||||
T: Hash,
|
||||
{
|
||||
let mut buckets: Vec<Vec<entry<T>>> = Vec::from_fn(256, |_| Vec::new());
|
||||
for elt in index.into_iter() {
|
||||
let h = hash::hash(&elt.val) as uint;
|
||||
|
|
|
|||
|
|
@ -42,7 +42,9 @@ pub struct FileSearch<'a> {
|
|||
}
|
||||
|
||||
impl<'a> FileSearch<'a> {
|
||||
pub fn for_each_lib_search_path(&self, f: |&Path| -> FileMatch) {
|
||||
pub fn for_each_lib_search_path<F>(&self, mut f: F) where
|
||||
F: FnMut(&Path) -> FileMatch,
|
||||
{
|
||||
let mut visited_dirs = HashSet::new();
|
||||
let mut found = false;
|
||||
|
||||
|
|
|
|||
|
|
@ -89,7 +89,10 @@ fn next_byte(st: &mut PState) -> u8 {
|
|||
return b;
|
||||
}
|
||||
|
||||
fn scan<R>(st: &mut PState, is_last: |char| -> bool, op: |&[u8]| -> R) -> R {
|
||||
fn scan<R, F, G>(st: &mut PState, mut is_last: F, op: G) -> R where
|
||||
F: FnMut(char) -> bool,
|
||||
G: FnOnce(&[u8]) -> R,
|
||||
{
|
||||
let start_pos = st.pos;
|
||||
debug!("scan: '{}' (start)", st.data[st.pos] as char);
|
||||
while !is_last(st.data[st.pos] as char) {
|
||||
|
|
@ -110,7 +113,9 @@ pub fn parse_name(st: &mut PState, last: char) -> ast::Name {
|
|||
parse_name_(st, |a| is_last(last, a) )
|
||||
}
|
||||
|
||||
fn parse_name_(st: &mut PState, is_last: |char| -> bool) -> ast::Name {
|
||||
fn parse_name_<F>(st: &mut PState, is_last: F) -> ast::Name where
|
||||
F: FnMut(char) -> bool,
|
||||
{
|
||||
scan(st, is_last, |bytes| {
|
||||
token::intern(str::from_utf8(bytes).unwrap())
|
||||
})
|
||||
|
|
@ -234,9 +239,10 @@ fn parse_trait_store(st: &mut PState, conv: conv_did) -> ty::TraitStore {
|
|||
}
|
||||
}
|
||||
|
||||
fn parse_vec_per_param_space<'a, 'tcx, T>(st: &mut PState<'a, 'tcx>,
|
||||
f: |&mut PState<'a, 'tcx>| -> T)
|
||||
-> VecPerParamSpace<T>
|
||||
fn parse_vec_per_param_space<'a, 'tcx, T, F>(st: &mut PState<'a, 'tcx>,
|
||||
mut f: F)
|
||||
-> VecPerParamSpace<T> where
|
||||
F: FnMut(&mut PState<'a, 'tcx>) -> T,
|
||||
{
|
||||
let mut r = VecPerParamSpace::empty();
|
||||
for &space in subst::ParamSpace::all().iter() {
|
||||
|
|
@ -350,8 +356,9 @@ fn parse_scope(st: &mut PState) -> region::CodeExtent {
|
|||
}
|
||||
}
|
||||
|
||||
fn parse_opt<'a, 'tcx, T>(st: &mut PState<'a, 'tcx>, f: |&mut PState<'a, 'tcx>| -> T)
|
||||
-> Option<T> {
|
||||
fn parse_opt<'a, 'tcx, T, F>(st: &mut PState<'a, 'tcx>, f: F) -> Option<T> where
|
||||
F: FnOnce(&mut PState<'a, 'tcx>) -> T,
|
||||
{
|
||||
match next(st) {
|
||||
'n' => None,
|
||||
's' => Some(f(st)),
|
||||
|
|
|
|||
|
|
@ -86,7 +86,9 @@ fn enc_mt<'a, 'tcx>(w: &mut SeekableMemWriter, cx: &ctxt<'a, 'tcx>,
|
|||
enc_ty(w, cx, mt.ty);
|
||||
}
|
||||
|
||||
fn enc_opt<T>(w: &mut SeekableMemWriter, t: Option<T>, enc_f: |&mut SeekableMemWriter, T|) {
|
||||
fn enc_opt<T, F>(w: &mut SeekableMemWriter, t: Option<T>, enc_f: F) where
|
||||
F: FnOnce(&mut SeekableMemWriter, T),
|
||||
{
|
||||
match t {
|
||||
None => mywrite!(w, "n"),
|
||||
Some(v) => {
|
||||
|
|
@ -96,10 +98,12 @@ fn enc_opt<T>(w: &mut SeekableMemWriter, t: Option<T>, enc_f: |&mut SeekableMemW
|
|||
}
|
||||
}
|
||||
|
||||
fn enc_vec_per_param_space<'a, 'tcx, T>(w: &mut SeekableMemWriter,
|
||||
cx: &ctxt<'a, 'tcx>,
|
||||
v: &VecPerParamSpace<T>,
|
||||
op: |&mut SeekableMemWriter, &ctxt<'a, 'tcx>, &T|) {
|
||||
fn enc_vec_per_param_space<'a, 'tcx, T, F>(w: &mut SeekableMemWriter,
|
||||
cx: &ctxt<'a, 'tcx>,
|
||||
v: &VecPerParamSpace<T>,
|
||||
mut op: F) where
|
||||
F: FnMut(&mut SeekableMemWriter, &ctxt<'a, 'tcx>, &T),
|
||||
{
|
||||
for &space in subst::ParamSpace::all().iter() {
|
||||
mywrite!(w, "[");
|
||||
for t in v.get_slice(space).iter() {
|
||||
|
|
|
|||
|
|
@ -680,9 +680,8 @@ pub fn encode_unboxed_closure_kind(ebml_w: &mut Encoder,
|
|||
}
|
||||
|
||||
pub trait vtable_decoder_helpers<'tcx> {
|
||||
fn read_vec_per_param_space<T>(&mut self,
|
||||
f: |&mut Self| -> T)
|
||||
-> VecPerParamSpace<T>;
|
||||
fn read_vec_per_param_space<T, F>(&mut self, f: F) -> VecPerParamSpace<T> where
|
||||
F: FnMut(&mut Self) -> T;
|
||||
fn read_vtable_res_with_key(&mut self,
|
||||
tcx: &ty::ctxt<'tcx>,
|
||||
cdata: &cstore::crate_metadata)
|
||||
|
|
@ -699,9 +698,8 @@ pub trait vtable_decoder_helpers<'tcx> {
|
|||
}
|
||||
|
||||
impl<'tcx, 'a> vtable_decoder_helpers<'tcx> for reader::Decoder<'a> {
|
||||
fn read_vec_per_param_space<T>(&mut self,
|
||||
f: |&mut reader::Decoder<'a>| -> T)
|
||||
-> VecPerParamSpace<T>
|
||||
fn read_vec_per_param_space<T, F>(&mut self, mut f: F) -> VecPerParamSpace<T> where
|
||||
F: FnMut(&mut reader::Decoder<'a>) -> T,
|
||||
{
|
||||
let types = self.read_to_vec(|this| Ok(f(this))).unwrap();
|
||||
let selfs = self.read_to_vec(|this| Ok(f(this))).unwrap();
|
||||
|
|
@ -793,9 +791,11 @@ impl<'tcx, 'a> vtable_decoder_helpers<'tcx> for reader::Decoder<'a> {
|
|||
// ___________________________________________________________________________
|
||||
//
|
||||
|
||||
fn encode_vec_per_param_space<T>(rbml_w: &mut Encoder,
|
||||
v: &subst::VecPerParamSpace<T>,
|
||||
f: |&mut Encoder, &T|) {
|
||||
fn encode_vec_per_param_space<T, F>(rbml_w: &mut Encoder,
|
||||
v: &subst::VecPerParamSpace<T>,
|
||||
mut f: F) where
|
||||
F: FnMut(&mut Encoder, &T),
|
||||
{
|
||||
for &space in subst::ParamSpace::all().iter() {
|
||||
rbml_w.emit_from_vec(v.get_slice(space),
|
||||
|rbml_w, n| Ok(f(rbml_w, n))).unwrap();
|
||||
|
|
@ -1124,14 +1124,16 @@ impl<'a, 'tcx> rbml_writer_helpers<'tcx> for Encoder<'a> {
|
|||
}
|
||||
|
||||
trait write_tag_and_id {
|
||||
fn tag(&mut self, tag_id: c::astencode_tag, f: |&mut Self|);
|
||||
fn tag<F>(&mut self, tag_id: c::astencode_tag, f: F) where F: FnOnce(&mut Self);
|
||||
fn id(&mut self, id: ast::NodeId);
|
||||
}
|
||||
|
||||
impl<'a> write_tag_and_id for Encoder<'a> {
|
||||
fn tag(&mut self,
|
||||
tag_id: c::astencode_tag,
|
||||
f: |&mut Encoder<'a>|) {
|
||||
fn tag<F>(&mut self,
|
||||
tag_id: c::astencode_tag,
|
||||
f: F) where
|
||||
F: FnOnce(&mut Encoder<'a>),
|
||||
{
|
||||
self.start_tag(tag_id as uint);
|
||||
f(self);
|
||||
self.end_tag();
|
||||
|
|
|
|||
|
|
@ -24,16 +24,22 @@ struct CheckCrateVisitor<'a, 'tcx: 'a> {
|
|||
}
|
||||
|
||||
impl<'a, 'tcx> CheckCrateVisitor<'a, 'tcx> {
|
||||
fn with_const(&mut self, in_const: bool, f: |&mut CheckCrateVisitor<'a, 'tcx>|) {
|
||||
fn with_const<F>(&mut self, in_const: bool, f: F) where
|
||||
F: FnOnce(&mut CheckCrateVisitor<'a, 'tcx>),
|
||||
{
|
||||
let was_const = self.in_const;
|
||||
self.in_const = in_const;
|
||||
f(self);
|
||||
self.in_const = was_const;
|
||||
}
|
||||
fn inside_const(&mut self, f: |&mut CheckCrateVisitor<'a, 'tcx>|) {
|
||||
fn inside_const<F>(&mut self, f: F) where
|
||||
F: FnOnce(&mut CheckCrateVisitor<'a, 'tcx>),
|
||||
{
|
||||
self.with_const(true, f);
|
||||
}
|
||||
fn outside_const(&mut self, f: |&mut CheckCrateVisitor<'a, 'tcx>|) {
|
||||
fn outside_const<F>(&mut self, f: F) where
|
||||
F: FnOnce(&mut CheckCrateVisitor<'a, 'tcx>),
|
||||
{
|
||||
self.with_const(false, f);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -64,7 +64,9 @@ impl<'a, 'v> Visitor<'v> for CheckLoopVisitor<'a> {
|
|||
}
|
||||
|
||||
impl<'a> CheckLoopVisitor<'a> {
|
||||
fn with_context(&mut self, cx: Context, f: |&mut CheckLoopVisitor<'a>|) {
|
||||
fn with_context<F>(&mut self, cx: Context, f: F) where
|
||||
F: FnOnce(&mut CheckLoopVisitor<'a>),
|
||||
{
|
||||
let old_cx = self.cx;
|
||||
self.cx = cx;
|
||||
f(self);
|
||||
|
|
|
|||
|
|
@ -980,7 +980,9 @@ fn check_fn(cx: &mut MatchCheckCtxt,
|
|||
}
|
||||
}
|
||||
|
||||
fn is_refutable<A>(cx: &MatchCheckCtxt, pat: &Pat, refutable: |&Pat| -> A) -> Option<A> {
|
||||
fn is_refutable<A, F>(cx: &MatchCheckCtxt, pat: &Pat, refutable: F) -> Option<A> where
|
||||
F: FnOnce(&Pat) -> A,
|
||||
{
|
||||
let pats = Matrix(vec!(vec!(pat)));
|
||||
match is_useful(cx, &pats, &[DUMMY_WILD_PAT], ConstructWitness) {
|
||||
UsefulWithWitness(pats) => {
|
||||
|
|
|
|||
|
|
@ -85,7 +85,9 @@ pub fn check_crate(tcx: &ty::ctxt) {
|
|||
}
|
||||
|
||||
impl<'a, 'tcx> CheckStaticVisitor<'a, 'tcx> {
|
||||
fn with_mode(&mut self, mode: Mode, f: |&mut CheckStaticVisitor<'a, 'tcx>|) {
|
||||
fn with_mode<F>(&mut self, mode: Mode, f: F) where
|
||||
F: FnOnce(&mut CheckStaticVisitor<'a, 'tcx>),
|
||||
{
|
||||
let old = self.mode;
|
||||
self.mode = mode;
|
||||
f(self);
|
||||
|
|
|
|||
|
|
@ -280,10 +280,9 @@ impl<'a, 'tcx, O:DataFlowOperator> DataFlowContext<'a, 'tcx, O> {
|
|||
}
|
||||
|
||||
|
||||
pub fn each_bit_on_entry(&self,
|
||||
id: ast::NodeId,
|
||||
f: |uint| -> bool)
|
||||
-> bool {
|
||||
pub fn each_bit_on_entry<F>(&self, id: ast::NodeId, f: F) -> bool where
|
||||
F: FnMut(uint) -> bool,
|
||||
{
|
||||
//! Iterates through each bit that is set on entry to `id`.
|
||||
//! Only useful after `propagate()` has been called.
|
||||
if !self.has_bitset_for_nodeid(id) {
|
||||
|
|
@ -293,11 +292,9 @@ impl<'a, 'tcx, O:DataFlowOperator> DataFlowContext<'a, 'tcx, O> {
|
|||
self.each_bit_for_node(Entry, cfgidx, f)
|
||||
}
|
||||
|
||||
pub fn each_bit_for_node(&self,
|
||||
e: EntryOrExit,
|
||||
cfgidx: CFGIndex,
|
||||
f: |uint| -> bool)
|
||||
-> bool {
|
||||
pub fn each_bit_for_node<F>(&self, e: EntryOrExit, cfgidx: CFGIndex, f: F) -> bool where
|
||||
F: FnMut(uint) -> bool,
|
||||
{
|
||||
//! Iterates through each bit that is set on entry/exit to `cfgidx`.
|
||||
//! Only useful after `propagate()` has been called.
|
||||
|
||||
|
|
@ -324,8 +321,9 @@ impl<'a, 'tcx, O:DataFlowOperator> DataFlowContext<'a, 'tcx, O> {
|
|||
self.each_bit(slice, f)
|
||||
}
|
||||
|
||||
pub fn each_gen_bit(&self, id: ast::NodeId, f: |uint| -> bool)
|
||||
-> bool {
|
||||
pub fn each_gen_bit<F>(&self, id: ast::NodeId, f: F) -> bool where
|
||||
F: FnMut(uint) -> bool,
|
||||
{
|
||||
//! Iterates through each bit in the gen set for `id`.
|
||||
if !self.has_bitset_for_nodeid(id) {
|
||||
return true;
|
||||
|
|
@ -345,7 +343,9 @@ impl<'a, 'tcx, O:DataFlowOperator> DataFlowContext<'a, 'tcx, O> {
|
|||
self.each_bit(gens, f)
|
||||
}
|
||||
|
||||
fn each_bit(&self, words: &[uint], f: |uint| -> bool) -> bool {
|
||||
fn each_bit<F>(&self, words: &[uint], mut f: F) -> bool where
|
||||
F: FnMut(uint) -> bool,
|
||||
{
|
||||
//! Helper for iterating over the bits in a bit set.
|
||||
//! Returns false on the first call to `f` that returns false;
|
||||
//! if all calls to `f` return true, then returns true.
|
||||
|
|
|
|||
|
|
@ -61,7 +61,9 @@ pub enum MethodProvenance {
|
|||
}
|
||||
|
||||
impl MethodProvenance {
|
||||
pub fn map(self, f: |ast::DefId| -> ast::DefId) -> MethodProvenance {
|
||||
pub fn map<F>(self, f: F) -> MethodProvenance where
|
||||
F: FnOnce(ast::DefId) -> ast::DefId,
|
||||
{
|
||||
match self {
|
||||
FromTrait(did) => FromTrait(f(did)),
|
||||
FromImpl(did) => FromImpl(f(did))
|
||||
|
|
|
|||
|
|
@ -221,39 +221,43 @@ impl<N,E> Graph<N,E> {
|
|||
///////////////////////////////////////////////////////////////////////////
|
||||
// Iterating over nodes, edges
|
||||
|
||||
pub fn each_node<'a>(&'a self, f: |NodeIndex, &'a Node<N>| -> bool) -> bool {
|
||||
pub fn each_node<'a, F>(&'a self, mut f: F) -> bool where
|
||||
F: FnMut(NodeIndex, &'a Node<N>) -> bool,
|
||||
{
|
||||
//! Iterates over all edges defined in the graph.
|
||||
self.nodes.iter().enumerate().all(|(i, node)| f(NodeIndex(i), node))
|
||||
}
|
||||
|
||||
pub fn each_edge<'a>(&'a self, f: |EdgeIndex, &'a Edge<E>| -> bool) -> bool {
|
||||
pub fn each_edge<'a, F>(&'a self, mut f: F) -> bool where
|
||||
F: FnMut(EdgeIndex, &'a Edge<E>) -> bool,
|
||||
{
|
||||
//! Iterates over all edges defined in the graph
|
||||
self.edges.iter().enumerate().all(|(i, edge)| f(EdgeIndex(i), edge))
|
||||
}
|
||||
|
||||
pub fn each_outgoing_edge<'a>(&'a self,
|
||||
source: NodeIndex,
|
||||
f: |EdgeIndex, &'a Edge<E>| -> bool)
|
||||
-> bool {
|
||||
pub fn each_outgoing_edge<'a, F>(&'a self, source: NodeIndex, f: F) -> bool where
|
||||
F: FnMut(EdgeIndex, &'a Edge<E>) -> bool,
|
||||
{
|
||||
//! Iterates over all outgoing edges from the node `from`
|
||||
|
||||
self.each_adjacent_edge(source, Outgoing, f)
|
||||
}
|
||||
|
||||
pub fn each_incoming_edge<'a>(&'a self,
|
||||
target: NodeIndex,
|
||||
f: |EdgeIndex, &'a Edge<E>| -> bool)
|
||||
-> bool {
|
||||
pub fn each_incoming_edge<'a, F>(&'a self, target: NodeIndex, f: F) -> bool where
|
||||
F: FnMut(EdgeIndex, &'a Edge<E>) -> bool,
|
||||
{
|
||||
//! Iterates over all incoming edges to the node `target`
|
||||
|
||||
self.each_adjacent_edge(target, Incoming, f)
|
||||
}
|
||||
|
||||
pub fn each_adjacent_edge<'a>(&'a self,
|
||||
node: NodeIndex,
|
||||
dir: Direction,
|
||||
f: |EdgeIndex, &'a Edge<E>| -> bool)
|
||||
-> bool {
|
||||
pub fn each_adjacent_edge<'a, F>(&'a self,
|
||||
node: NodeIndex,
|
||||
dir: Direction,
|
||||
mut f: F)
|
||||
-> bool where
|
||||
F: FnMut(EdgeIndex, &'a Edge<E>) -> bool,
|
||||
{
|
||||
//! Iterates over all edges adjacent to the node `node`
|
||||
//! in the direction `dir` (either `Outgoing` or `Incoming)
|
||||
|
||||
|
|
@ -277,11 +281,9 @@ impl<N,E> Graph<N,E> {
|
|||
// variables or other bitsets. This method facilitates such a
|
||||
// computation.
|
||||
|
||||
pub fn iterate_until_fixed_point<'a>(&'a self,
|
||||
op: |iter_index: uint,
|
||||
edge_index: EdgeIndex,
|
||||
edge: &'a Edge<E>|
|
||||
-> bool) {
|
||||
pub fn iterate_until_fixed_point<'a, F>(&'a self, mut op: F) where
|
||||
F: FnMut(uint, EdgeIndex, &'a Edge<E>) -> bool,
|
||||
{
|
||||
let mut iteration = 0;
|
||||
let mut changed = true;
|
||||
while changed {
|
||||
|
|
@ -294,7 +296,9 @@ impl<N,E> Graph<N,E> {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn each_edge_index(max_edge_index: EdgeIndex, f: |EdgeIndex| -> bool) {
|
||||
pub fn each_edge_index<F>(max_edge_index: EdgeIndex, mut f: F) where
|
||||
F: FnMut(EdgeIndex) -> bool,
|
||||
{
|
||||
let mut i = 0;
|
||||
let n = max_edge_index.get();
|
||||
while i < n {
|
||||
|
|
|
|||
|
|
@ -194,8 +194,9 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn unpack_actual_value<T>(&self, a: Ty<'tcx>, f: |&ty::sty<'tcx>| -> T)
|
||||
-> T {
|
||||
pub fn unpack_actual_value<T, F>(&self, a: Ty<'tcx>, f: F) -> T where
|
||||
F: FnOnce(&ty::sty<'tcx>) -> T,
|
||||
{
|
||||
match resolve_type(self.get_ref().infcx, None,
|
||||
a, try_resolve_tvar_shallow) {
|
||||
Ok(t) => {
|
||||
|
|
@ -458,13 +459,15 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
|
|||
|| AutoUnsafe(b_mutbl, None))
|
||||
}
|
||||
|
||||
fn coerce_object(&self,
|
||||
a: Ty<'tcx>,
|
||||
sty_a: &ty::sty<'tcx>,
|
||||
b: Ty<'tcx>,
|
||||
b_mutbl: ast::Mutability,
|
||||
mk_ty: |Ty<'tcx>| -> Ty<'tcx>,
|
||||
mk_adjust: || -> ty::AutoRef<'tcx>) -> CoerceResult<'tcx>
|
||||
fn coerce_object<F, G>(&self,
|
||||
a: Ty<'tcx>,
|
||||
sty_a: &ty::sty<'tcx>,
|
||||
b: Ty<'tcx>,
|
||||
b_mutbl: ast::Mutability,
|
||||
mk_ty: F,
|
||||
mk_adjust: G) -> CoerceResult<'tcx> where
|
||||
F: FnOnce(Ty<'tcx>) -> Ty<'tcx>,
|
||||
G: FnOnce() -> ty::AutoRef<'tcx>,
|
||||
{
|
||||
let tcx = self.get_ref().infcx.tcx;
|
||||
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -477,14 +477,17 @@ pub fn resolve_region(cx: &InferCtxt, r: ty::Region, modes: uint)
|
|||
}
|
||||
|
||||
trait then<'tcx> {
|
||||
fn then<T:Clone>(&self, f: || -> Result<T,ty::type_err<'tcx>>)
|
||||
-> Result<T,ty::type_err<'tcx>>;
|
||||
fn then<T, F>(&self, f: F) -> Result<T, ty::type_err<'tcx>> where
|
||||
T: Clone,
|
||||
F: FnOnce() -> Result<T, ty::type_err<'tcx>>;
|
||||
}
|
||||
|
||||
impl<'tcx> then<'tcx> for ures<'tcx> {
|
||||
fn then<T:Clone>(&self, f: || -> Result<T,ty::type_err<'tcx>>)
|
||||
-> Result<T,ty::type_err<'tcx>> {
|
||||
self.and_then(|_i| f())
|
||||
fn then<T, F>(&self, f: F) -> Result<T, ty::type_err<'tcx>> where
|
||||
T: Clone,
|
||||
F: FnOnce() -> Result<T, ty::type_err<'tcx>>,
|
||||
{
|
||||
self.and_then(move |_| f())
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -502,12 +505,15 @@ impl<'tcx, T> ToUres<'tcx> for cres<'tcx, T> {
|
|||
}
|
||||
|
||||
trait CresCompare<'tcx, T> {
|
||||
fn compare(&self, t: T, f: || -> ty::type_err<'tcx>) -> cres<'tcx, T>;
|
||||
fn compare<F>(&self, t: T, f: F) -> cres<'tcx, T> where
|
||||
F: FnOnce() -> ty::type_err<'tcx>;
|
||||
}
|
||||
|
||||
impl<'tcx, T:Clone + PartialEq> CresCompare<'tcx, T> for cres<'tcx, T> {
|
||||
fn compare(&self, t: T, f: || -> ty::type_err<'tcx>) -> cres<'tcx, T> {
|
||||
(*self).clone().and_then(|s| {
|
||||
fn compare<F>(&self, t: T, f: F) -> cres<'tcx, T> where
|
||||
F: FnOnce() -> ty::type_err<'tcx>,
|
||||
{
|
||||
(*self).clone().and_then(move |s| {
|
||||
if s == t {
|
||||
(*self).clone()
|
||||
} else {
|
||||
|
|
@ -616,7 +622,9 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
|||
}
|
||||
|
||||
/// Execute `f` and commit the bindings
|
||||
pub fn commit_unconditionally<R>(&self, f: || -> R) -> R {
|
||||
pub fn commit_unconditionally<R, F>(&self, f: F) -> R where
|
||||
F: FnOnce() -> R,
|
||||
{
|
||||
debug!("commit()");
|
||||
let snapshot = self.start_snapshot();
|
||||
let r = f();
|
||||
|
|
@ -625,12 +633,16 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
|||
}
|
||||
|
||||
/// Execute `f` and commit the bindings if successful
|
||||
pub fn commit_if_ok<T,E>(&self, f: || -> Result<T,E>) -> Result<T,E> {
|
||||
self.commit_unconditionally(|| self.try(|| f()))
|
||||
pub fn commit_if_ok<T, E, F>(&self, f: F) -> Result<T, E> where
|
||||
F: FnOnce() -> Result<T, E>
|
||||
{
|
||||
self.commit_unconditionally(move || self.try(move || f()))
|
||||
}
|
||||
|
||||
/// Execute `f`, unroll bindings on panic
|
||||
pub fn try<T,E>(&self, f: || -> Result<T,E>) -> Result<T,E> {
|
||||
pub fn try<T, E, F>(&self, f: F) -> Result<T, E> where
|
||||
F: FnOnce() -> Result<T, E>
|
||||
{
|
||||
debug!("try()");
|
||||
let snapshot = self.start_snapshot();
|
||||
let r = f();
|
||||
|
|
@ -647,7 +659,9 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
|||
}
|
||||
|
||||
/// Execute `f` then unroll any bindings it creates
|
||||
pub fn probe<R>(&self, f: || -> R) -> R {
|
||||
pub fn probe<R, F>(&self, f: F) -> R where
|
||||
F: FnOnce() -> R,
|
||||
{
|
||||
debug!("probe()");
|
||||
let snapshot = self.start_snapshot();
|
||||
let r = f();
|
||||
|
|
@ -902,22 +916,24 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
|||
// in this case. The typechecker should only ever report type errors involving mismatched
|
||||
// types using one of these four methods, and should not call span_err directly for such
|
||||
// errors.
|
||||
pub fn type_error_message_str(&self,
|
||||
sp: Span,
|
||||
mk_msg: |Option<String>, String| -> String,
|
||||
actual_ty: String,
|
||||
err: Option<&ty::type_err<'tcx>>) {
|
||||
pub fn type_error_message_str<M>(&self,
|
||||
sp: Span,
|
||||
mk_msg: M,
|
||||
actual_ty: String,
|
||||
err: Option<&ty::type_err<'tcx>>) where
|
||||
M: FnOnce(Option<String>, String) -> String,
|
||||
{
|
||||
self.type_error_message_str_with_expected(sp, mk_msg, None, actual_ty, err)
|
||||
}
|
||||
|
||||
pub fn type_error_message_str_with_expected(&self,
|
||||
sp: Span,
|
||||
mk_msg: |Option<String>,
|
||||
String|
|
||||
-> String,
|
||||
expected_ty: Option<Ty<'tcx>>,
|
||||
actual_ty: String,
|
||||
err: Option<&ty::type_err<'tcx>>) {
|
||||
pub fn type_error_message_str_with_expected<M>(&self,
|
||||
sp: Span,
|
||||
mk_msg: M,
|
||||
expected_ty: Option<Ty<'tcx>>,
|
||||
actual_ty: String,
|
||||
err: Option<&ty::type_err<'tcx>>) where
|
||||
M: FnOnce(Option<String>, String) -> String,
|
||||
{
|
||||
debug!("hi! expected_ty = {}, actual_ty = {}", expected_ty, actual_ty);
|
||||
|
||||
let resolved_expected = expected_ty.map(|e_ty| {
|
||||
|
|
@ -942,11 +958,13 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn type_error_message(&self,
|
||||
sp: Span,
|
||||
mk_msg: |String| -> String,
|
||||
actual_ty: Ty<'tcx>,
|
||||
err: Option<&ty::type_err<'tcx>>) {
|
||||
pub fn type_error_message<M>(&self,
|
||||
sp: Span,
|
||||
mk_msg: M,
|
||||
actual_ty: Ty<'tcx>,
|
||||
err: Option<&ty::type_err<'tcx>>) where
|
||||
M: FnOnce(String) -> String,
|
||||
{
|
||||
let actual_ty = self.resolve_type_vars_if_possible(actual_ty);
|
||||
|
||||
// Don't report an error if actual type is ty_err.
|
||||
|
|
@ -954,7 +972,9 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
|||
return;
|
||||
}
|
||||
|
||||
self.type_error_message_str(sp, |_e, a| { mk_msg(a) }, self.ty_to_string(actual_ty), err);
|
||||
self.type_error_message_str(sp,
|
||||
move |_e, a| { mk_msg(a) },
|
||||
self.ty_to_string(actual_ty), err);
|
||||
}
|
||||
|
||||
pub fn report_mismatched_types(&self,
|
||||
|
|
|
|||
|
|
@ -569,15 +569,15 @@ impl<'a, 'tcx> RegionVarBindings<'a, 'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn combine_vars(&self,
|
||||
t: CombineMapType,
|
||||
a: Region,
|
||||
b: Region,
|
||||
origin: SubregionOrigin<'tcx>,
|
||||
relate: |this: &RegionVarBindings<'a, 'tcx>,
|
||||
old_r: Region,
|
||||
new_r: Region|)
|
||||
-> Region {
|
||||
pub fn combine_vars<F>(&self,
|
||||
t: CombineMapType,
|
||||
a: Region,
|
||||
b: Region,
|
||||
origin: SubregionOrigin<'tcx>,
|
||||
mut relate: F)
|
||||
-> Region where
|
||||
F: FnMut(&RegionVarBindings<'a, 'tcx>, Region, Region),
|
||||
{
|
||||
let vars = TwoRegions { a: a, b: b };
|
||||
match self.combine_map(t).borrow().get(&vars) {
|
||||
Some(&c) => {
|
||||
|
|
@ -1539,9 +1539,9 @@ impl<'a, 'tcx> RegionVarBindings<'a, 'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
fn iterate_until_fixed_point(&self,
|
||||
tag: &str,
|
||||
body: |constraint: &Constraint| -> bool) {
|
||||
fn iterate_until_fixed_point<F>(&self, tag: &str, mut body: F) where
|
||||
F: FnMut(&Constraint) -> bool,
|
||||
{
|
||||
let mut iteration = 0u;
|
||||
let mut changed = true;
|
||||
while changed {
|
||||
|
|
|
|||
|
|
@ -54,11 +54,12 @@ impl<'a, 'tcx> TypeSkolemizer<'a, 'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
fn skolemize(&mut self,
|
||||
opt_ty: Option<Ty<'tcx>>,
|
||||
key: ty::InferTy,
|
||||
skolemizer: |uint| -> ty::InferTy)
|
||||
-> Ty<'tcx>
|
||||
fn skolemize<F>(&mut self,
|
||||
opt_ty: Option<Ty<'tcx>>,
|
||||
key: ty::InferTy,
|
||||
skolemizer: F)
|
||||
-> Ty<'tcx> where
|
||||
F: FnOnce(uint) -> ty::InferTy,
|
||||
{
|
||||
match opt_ty {
|
||||
Some(ty) => { return ty.fold_with(self); }
|
||||
|
|
|
|||
|
|
@ -616,9 +616,9 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
|
|||
self.ir.variable(node_id, span)
|
||||
}
|
||||
|
||||
fn pat_bindings(&mut self,
|
||||
pat: &ast::Pat,
|
||||
f: |&mut Liveness<'a, 'tcx>, LiveNode, Variable, Span, NodeId|) {
|
||||
fn pat_bindings<F>(&mut self, pat: &ast::Pat, mut f: F) where
|
||||
F: FnMut(&mut Liveness<'a, 'tcx>, LiveNode, Variable, Span, NodeId),
|
||||
{
|
||||
pat_util::pat_bindings(&self.ir.tcx.def_map, pat, |_bm, p_id, sp, _n| {
|
||||
let ln = self.live_node(p_id, sp);
|
||||
let var = self.variable(p_id, sp);
|
||||
|
|
@ -626,9 +626,9 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
|
|||
})
|
||||
}
|
||||
|
||||
fn arm_pats_bindings(&mut self,
|
||||
pat: Option<&ast::Pat>,
|
||||
f: |&mut Liveness<'a, 'tcx>, LiveNode, Variable, Span, NodeId|) {
|
||||
fn arm_pats_bindings<F>(&mut self, pat: Option<&ast::Pat>, f: F) where
|
||||
F: FnMut(&mut Liveness<'a, 'tcx>, LiveNode, Variable, Span, NodeId),
|
||||
{
|
||||
match pat {
|
||||
Some(pat) => {
|
||||
self.pat_bindings(pat, f);
|
||||
|
|
@ -691,10 +691,9 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
|
|||
self.assigned_on_entry(successor, var)
|
||||
}
|
||||
|
||||
fn indices2(&mut self,
|
||||
ln: LiveNode,
|
||||
succ_ln: LiveNode,
|
||||
op: |&mut Liveness<'a, 'tcx>, uint, uint|) {
|
||||
fn indices2<F>(&mut self, ln: LiveNode, succ_ln: LiveNode, mut op: F) where
|
||||
F: FnMut(&mut Liveness<'a, 'tcx>, uint, uint),
|
||||
{
|
||||
let node_base_idx = self.idx(ln, Variable(0u));
|
||||
let succ_base_idx = self.idx(succ_ln, Variable(0u));
|
||||
for var_idx in range(0u, self.ir.num_vars) {
|
||||
|
|
@ -702,10 +701,13 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
fn write_vars(&self,
|
||||
wr: &mut io::Writer,
|
||||
ln: LiveNode,
|
||||
test: |uint| -> LiveNode) -> io::IoResult<()> {
|
||||
fn write_vars<F>(&self,
|
||||
wr: &mut io::Writer,
|
||||
ln: LiveNode,
|
||||
mut test: F)
|
||||
-> io::IoResult<()> where
|
||||
F: FnMut(uint) -> LiveNode,
|
||||
{
|
||||
let node_base_idx = self.idx(ln, Variable(0));
|
||||
for var_idx in range(0u, self.ir.num_vars) {
|
||||
let idx = node_base_idx + var_idx;
|
||||
|
|
@ -1408,12 +1410,14 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
|
|||
cond_ln
|
||||
}
|
||||
|
||||
fn with_loop_nodes<R>(&mut self,
|
||||
loop_node_id: NodeId,
|
||||
break_ln: LiveNode,
|
||||
cont_ln: LiveNode,
|
||||
f: |&mut Liveness<'a, 'tcx>| -> R)
|
||||
-> R {
|
||||
fn with_loop_nodes<R, F>(&mut self,
|
||||
loop_node_id: NodeId,
|
||||
break_ln: LiveNode,
|
||||
cont_ln: LiveNode,
|
||||
f: F)
|
||||
-> R where
|
||||
F: FnOnce(&mut Liveness<'a, 'tcx>) -> R,
|
||||
{
|
||||
debug!("with_loop_nodes: {} {}", loop_node_id, break_ln.get());
|
||||
self.loop_scope.push(loop_node_id);
|
||||
self.break_ln.insert(loop_node_id, break_ln);
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -91,9 +91,9 @@ pub fn pat_is_binding_or_wild(dm: &resolve::DefMap, pat: &ast::Pat) -> bool {
|
|||
|
||||
/// Call `it` on every "binding" in a pattern, e.g., on `a` in
|
||||
/// `match foo() { Some(a) => (), None => () }`
|
||||
pub fn pat_bindings(dm: &resolve::DefMap,
|
||||
pat: &ast::Pat,
|
||||
it: |ast::BindingMode, ast::NodeId, Span, &ast::SpannedIdent|) {
|
||||
pub fn pat_bindings<I>(dm: &resolve::DefMap, pat: &ast::Pat, mut it: I) where
|
||||
I: FnMut(ast::BindingMode, ast::NodeId, Span, &ast::SpannedIdent),
|
||||
{
|
||||
walk_pat(pat, |p| {
|
||||
match p.node {
|
||||
ast::PatIdent(binding_mode, ref pth, _) if pat_is_binding(dm, p) => {
|
||||
|
|
|
|||
|
|
@ -62,7 +62,9 @@ impl CodeExtent {
|
|||
|
||||
/// Maps this scope to a potentially new one according to the
|
||||
/// NodeId transformer `f_id`.
|
||||
pub fn map_id(&self, f_id: |ast::NodeId| -> ast::NodeId) -> CodeExtent {
|
||||
pub fn map_id<F>(&self, f_id: F) -> CodeExtent where
|
||||
F: FnOnce(ast::NodeId) -> ast::NodeId,
|
||||
{
|
||||
match *self {
|
||||
CodeExtent::Misc(node_id) => CodeExtent::Misc(f_id(node_id)),
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1837,10 +1837,12 @@ impl<'a> Resolver<'a> {
|
|||
}
|
||||
|
||||
/// Constructs the reduced graph for one foreign item.
|
||||
fn build_reduced_graph_for_foreign_item(&mut self,
|
||||
foreign_item: &ForeignItem,
|
||||
parent: ReducedGraphParent,
|
||||
f: |&mut Resolver|) {
|
||||
fn build_reduced_graph_for_foreign_item<F>(&mut self,
|
||||
foreign_item: &ForeignItem,
|
||||
parent: ReducedGraphParent,
|
||||
f: F) where
|
||||
F: FnOnce(&mut Resolver),
|
||||
{
|
||||
let name = foreign_item.ident.name;
|
||||
let is_public = foreign_item.vis == ast::Public;
|
||||
let modifiers = if is_public { PUBLIC } else { DefModifiers::empty() } | IMPORTABLE;
|
||||
|
|
@ -3970,7 +3972,9 @@ impl<'a> Resolver<'a> {
|
|||
// generate a fake "implementation scope" containing all the
|
||||
// implementations thus found, for compatibility with old resolve pass.
|
||||
|
||||
fn with_scope(&mut self, name: Option<Name>, f: |&mut Resolver|) {
|
||||
fn with_scope<F>(&mut self, name: Option<Name>, f: F) where
|
||||
F: FnOnce(&mut Resolver),
|
||||
{
|
||||
let orig_module = self.current_module.clone();
|
||||
|
||||
// Move down in the graph.
|
||||
|
|
@ -4373,9 +4377,9 @@ impl<'a> Resolver<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
fn with_type_parameter_rib(&mut self,
|
||||
type_parameters: TypeParameters,
|
||||
f: |&mut Resolver|) {
|
||||
fn with_type_parameter_rib<F>(&mut self, type_parameters: TypeParameters, f: F) where
|
||||
F: FnOnce(&mut Resolver),
|
||||
{
|
||||
match type_parameters {
|
||||
HasTypeParameters(generics, space, node_id, rib_kind) => {
|
||||
let mut function_type_rib = Rib::new(rib_kind);
|
||||
|
|
@ -4422,13 +4426,17 @@ impl<'a> Resolver<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
fn with_label_rib(&mut self, f: |&mut Resolver|) {
|
||||
fn with_label_rib<F>(&mut self, f: F) where
|
||||
F: FnOnce(&mut Resolver),
|
||||
{
|
||||
self.label_ribs.push(Rib::new(NormalRibKind));
|
||||
f(self);
|
||||
self.label_ribs.pop();
|
||||
}
|
||||
|
||||
fn with_constant_rib(&mut self, f: |&mut Resolver|) {
|
||||
fn with_constant_rib<F>(&mut self, f: F) where
|
||||
F: FnOnce(&mut Resolver),
|
||||
{
|
||||
self.value_ribs.push(Rib::new(ConstantItemRibKind));
|
||||
self.type_ribs.push(Rib::new(ConstantItemRibKind));
|
||||
f(self);
|
||||
|
|
@ -4676,7 +4684,9 @@ impl<'a> Resolver<'a> {
|
|||
method.pe_body());
|
||||
}
|
||||
|
||||
fn with_current_self_type<T>(&mut self, self_type: &Ty, f: |&mut Resolver| -> T) -> T {
|
||||
fn with_current_self_type<T, F>(&mut self, self_type: &Ty, f: F) -> T where
|
||||
F: FnOnce(&mut Resolver) -> T,
|
||||
{
|
||||
// Handle nested impls (inside fn bodies)
|
||||
let previous_value = replace(&mut self.current_self_type, Some(self_type.clone()));
|
||||
let result = f(self);
|
||||
|
|
@ -4684,9 +4694,11 @@ impl<'a> Resolver<'a> {
|
|||
result
|
||||
}
|
||||
|
||||
fn with_optional_trait_ref<T>(&mut self, id: NodeId,
|
||||
opt_trait_ref: &Option<TraitRef>,
|
||||
f: |&mut Resolver| -> T) -> T {
|
||||
fn with_optional_trait_ref<T, F>(&mut self, id: NodeId,
|
||||
opt_trait_ref: &Option<TraitRef>,
|
||||
f: F) -> T where
|
||||
F: FnOnce(&mut Resolver) -> T,
|
||||
{
|
||||
let new_val = match *opt_trait_ref {
|
||||
Some(ref trait_ref) => {
|
||||
self.resolve_trait_reference(id, trait_ref, TraitImplementation);
|
||||
|
|
@ -5620,7 +5632,9 @@ impl<'a> Resolver<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
fn with_no_errors<T>(&mut self, f: |&mut Resolver| -> T) -> T {
|
||||
fn with_no_errors<T, F>(&mut self, f: F) -> T where
|
||||
F: FnOnce(&mut Resolver) -> T,
|
||||
{
|
||||
self.emit_errors = false;
|
||||
let rs = f(self);
|
||||
self.emit_errors = true;
|
||||
|
|
|
|||
|
|
@ -247,7 +247,9 @@ impl<'a, 'v> Visitor<'v> for LifetimeContext<'a> {
|
|||
}
|
||||
|
||||
impl<'a> LifetimeContext<'a> {
|
||||
fn with(&mut self, wrap_scope: ScopeChain, f: |&mut LifetimeContext|) {
|
||||
fn with<F>(&mut self, wrap_scope: ScopeChain, f: F) where
|
||||
F: FnOnce(&mut LifetimeContext),
|
||||
{
|
||||
let LifetimeContext {sess, ref mut named_region_map, ..} = *self;
|
||||
let mut this = LifetimeContext {
|
||||
sess: sess,
|
||||
|
|
@ -278,10 +280,12 @@ impl<'a> LifetimeContext<'a> {
|
|||
/// already in scope (for a fn item, that will be 0, but for a method it might not be). Late
|
||||
/// bound lifetimes are resolved by name and associated with a binder id (`binder_id`), so the
|
||||
/// ordering is not important there.
|
||||
fn visit_early_late(&mut self,
|
||||
early_space: subst::ParamSpace,
|
||||
generics: &ast::Generics,
|
||||
walk: |&mut LifetimeContext|) {
|
||||
fn visit_early_late<F>(&mut self,
|
||||
early_space: subst::ParamSpace,
|
||||
generics: &ast::Generics,
|
||||
walk: F) where
|
||||
F: FnOnce(&mut LifetimeContext),
|
||||
{
|
||||
let referenced_idents = early_bound_lifetime_names(generics);
|
||||
|
||||
debug!("visit_early_late: referenced_idents={}",
|
||||
|
|
@ -290,8 +294,8 @@ impl<'a> LifetimeContext<'a> {
|
|||
let (early, late) = generics.lifetimes.clone().partition(
|
||||
|l| referenced_idents.iter().any(|&i| i == l.lifetime.name));
|
||||
|
||||
self.with(EarlyScope(early_space, &early, self.scope), |this| {
|
||||
this.with(LateScope(&late, this.scope), |this| {
|
||||
self.with(EarlyScope(early_space, &early, self.scope), move |this| {
|
||||
this.with(LateScope(&late, this.scope), move |this| {
|
||||
this.check_lifetime_defs(&generics.lifetimes);
|
||||
walk(this);
|
||||
});
|
||||
|
|
|
|||
|
|
@ -43,7 +43,9 @@ struct Annotator {
|
|||
impl Annotator {
|
||||
// Determine the stability for a node based on its attributes and inherited
|
||||
// stability. The stability is recorded in the index and used as the parent.
|
||||
fn annotate(&mut self, id: NodeId, attrs: &Vec<Attribute>, f: |&mut Annotator|) {
|
||||
fn annotate<F>(&mut self, id: NodeId, attrs: &Vec<Attribute>, f: F) where
|
||||
F: FnOnce(&mut Annotator),
|
||||
{
|
||||
match attr::find_stability(attrs.as_slice()) {
|
||||
Some(stab) => {
|
||||
self.index.local.insert(id, stab.clone());
|
||||
|
|
|
|||
|
|
@ -167,10 +167,9 @@ impl<'tcx> Substs<'tcx> {
|
|||
}
|
||||
|
||||
impl RegionSubsts {
|
||||
fn map<A>(self,
|
||||
a: A,
|
||||
op: |VecPerParamSpace<ty::Region>, A| -> VecPerParamSpace<ty::Region>)
|
||||
-> RegionSubsts {
|
||||
fn map<A, F>(self, a: A, op: F) -> RegionSubsts where
|
||||
F: FnOnce(VecPerParamSpace<ty::Region>, A) -> VecPerParamSpace<ty::Region>,
|
||||
{
|
||||
match self {
|
||||
ErasedRegions => ErasedRegions,
|
||||
NonerasedRegions(r) => NonerasedRegions(op(r, a))
|
||||
|
|
@ -415,16 +414,18 @@ impl<T> VecPerParamSpace<T> {
|
|||
self.content.as_slice()
|
||||
}
|
||||
|
||||
pub fn all_vecs(&self, pred: |&[T]| -> bool) -> bool {
|
||||
pub fn all_vecs<P>(&self, mut pred: P) -> bool where
|
||||
P: FnMut(&[T]) -> bool,
|
||||
{
|
||||
let spaces = [TypeSpace, SelfSpace, FnSpace];
|
||||
spaces.iter().all(|&space| { pred(self.get_slice(space)) })
|
||||
}
|
||||
|
||||
pub fn all(&self, pred: |&T| -> bool) -> bool {
|
||||
pub fn all<P>(&self, pred: P) -> bool where P: FnMut(&T) -> bool {
|
||||
self.iter().all(pred)
|
||||
}
|
||||
|
||||
pub fn any(&self, pred: |&T| -> bool) -> bool {
|
||||
pub fn any<P>(&self, pred: P) -> bool where P: FnMut(&T) -> bool {
|
||||
self.iter().any(pred)
|
||||
}
|
||||
|
||||
|
|
@ -432,7 +433,7 @@ impl<T> VecPerParamSpace<T> {
|
|||
self.all_vecs(|v| v.is_empty())
|
||||
}
|
||||
|
||||
pub fn map<U>(&self, pred: |&T| -> U) -> VecPerParamSpace<U> {
|
||||
pub fn map<U, P>(&self, pred: P) -> VecPerParamSpace<U> where P: FnMut(&T) -> U {
|
||||
let result = self.iter().map(pred).collect();
|
||||
VecPerParamSpace::new_internal(result,
|
||||
self.type_limit,
|
||||
|
|
@ -440,7 +441,9 @@ impl<T> VecPerParamSpace<T> {
|
|||
self.assoc_limit)
|
||||
}
|
||||
|
||||
pub fn map_enumerated<U>(&self, pred: |(ParamSpace, uint, &T)| -> U) -> VecPerParamSpace<U> {
|
||||
pub fn map_enumerated<U, P>(&self, pred: P) -> VecPerParamSpace<U> where
|
||||
P: FnMut((ParamSpace, uint, &T)) -> U,
|
||||
{
|
||||
let result = self.iter_enumerated().map(pred).collect();
|
||||
VecPerParamSpace::new_internal(result,
|
||||
self.type_limit,
|
||||
|
|
@ -448,7 +451,9 @@ impl<T> VecPerParamSpace<T> {
|
|||
self.assoc_limit)
|
||||
}
|
||||
|
||||
pub fn map_move<U>(self, pred: |T| -> U) -> VecPerParamSpace<U> {
|
||||
pub fn map_move<U, F>(self, mut pred: F) -> VecPerParamSpace<U> where
|
||||
F: FnMut(T) -> U,
|
||||
{
|
||||
let SeparateVecsPerParamSpace {
|
||||
types: t,
|
||||
selfs: s,
|
||||
|
|
|
|||
|
|
@ -312,7 +312,7 @@ impl<'tcx, N> Vtable<'tcx, N> {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn map_nested<M>(&self, op: |&N| -> M) -> Vtable<'tcx, M> {
|
||||
pub fn map_nested<M, F>(&self, op: F) -> Vtable<'tcx, M> where F: FnMut(&N) -> M {
|
||||
match *self {
|
||||
VtableImpl(ref i) => VtableImpl(i.map_nested(op)),
|
||||
VtableFnPointer(ref sig) => VtableFnPointer((*sig).clone()),
|
||||
|
|
@ -322,7 +322,9 @@ impl<'tcx, N> Vtable<'tcx, N> {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn map_move_nested<M>(self, op: |N| -> M) -> Vtable<'tcx, M> {
|
||||
pub fn map_move_nested<M, F>(self, op: F) -> Vtable<'tcx, M> where
|
||||
F: FnMut(N) -> M,
|
||||
{
|
||||
match self {
|
||||
VtableImpl(i) => VtableImpl(i.map_move_nested(op)),
|
||||
VtableFnPointer(sig) => VtableFnPointer(sig),
|
||||
|
|
@ -338,9 +340,8 @@ impl<'tcx, N> VtableImplData<'tcx, N> {
|
|||
self.nested.iter()
|
||||
}
|
||||
|
||||
pub fn map_nested<M>(&self,
|
||||
op: |&N| -> M)
|
||||
-> VtableImplData<'tcx, M>
|
||||
pub fn map_nested<M, F>(&self, op: F) -> VtableImplData<'tcx, M> where
|
||||
F: FnMut(&N) -> M,
|
||||
{
|
||||
VtableImplData {
|
||||
impl_def_id: self.impl_def_id,
|
||||
|
|
@ -349,8 +350,9 @@ impl<'tcx, N> VtableImplData<'tcx, N> {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn map_move_nested<M>(self, op: |N| -> M)
|
||||
-> VtableImplData<'tcx, M> {
|
||||
pub fn map_move_nested<M, F>(self, op: F) -> VtableImplData<'tcx, M> where
|
||||
F: FnMut(N) -> M,
|
||||
{
|
||||
let VtableImplData { impl_def_id, substs, nested } = self;
|
||||
VtableImplData {
|
||||
impl_def_id: impl_def_id,
|
||||
|
|
@ -365,16 +367,15 @@ impl<N> VtableBuiltinData<N> {
|
|||
self.nested.iter()
|
||||
}
|
||||
|
||||
pub fn map_nested<M>(&self,
|
||||
op: |&N| -> M)
|
||||
-> VtableBuiltinData<M>
|
||||
{
|
||||
pub fn map_nested<M, F>(&self, op: F) -> VtableBuiltinData<M> where F: FnMut(&N) -> M {
|
||||
VtableBuiltinData {
|
||||
nested: self.nested.map(op)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn map_move_nested<M>(self, op: |N| -> M) -> VtableBuiltinData<M> {
|
||||
pub fn map_move_nested<M, F>(self, op: F) -> VtableBuiltinData<M> where
|
||||
F: FnMut(N) -> M,
|
||||
{
|
||||
VtableBuiltinData {
|
||||
nested: self.nested.map_move(op)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -306,10 +306,11 @@ pub fn predicate_for_builtin_bound<'tcx>(
|
|||
/// of caller obligations), search through the trait and supertraits to find one where `test(d)` is
|
||||
/// true, where `d` is the def-id of the trait/supertrait. If any is found, return `Some(p)` where
|
||||
/// `p` is the path to that trait/supertrait. Else `None`.
|
||||
pub fn search_trait_and_supertraits_from_bound<'tcx>(tcx: &ty::ctxt<'tcx>,
|
||||
caller_bound: Rc<ty::TraitRef<'tcx>>,
|
||||
test: |ast::DefId| -> bool)
|
||||
-> Option<VtableParamData<'tcx>>
|
||||
pub fn search_trait_and_supertraits_from_bound<'tcx, F>(tcx: &ty::ctxt<'tcx>,
|
||||
caller_bound: Rc<ty::TraitRef<'tcx>>,
|
||||
mut test: F)
|
||||
-> Option<VtableParamData<'tcx>> where
|
||||
F: FnMut(ast::DefId) -> bool,
|
||||
{
|
||||
for bound in transitive_bounds(tcx, &[caller_bound]) {
|
||||
if test(bound.def_id) {
|
||||
|
|
|
|||
|
|
@ -2420,10 +2420,13 @@ pub fn mk_param_from_def<'tcx>(cx: &ctxt<'tcx>, def: &TypeParameterDef) -> Ty<'t
|
|||
|
||||
pub fn mk_open<'tcx>(cx: &ctxt<'tcx>, ty: Ty<'tcx>) -> Ty<'tcx> { mk_t(cx, ty_open(ty)) }
|
||||
|
||||
pub fn walk_ty<'tcx>(ty: Ty<'tcx>, f: |Ty<'tcx>|) {
|
||||
pub fn walk_ty<'tcx, F>(ty: Ty<'tcx>, mut f: F) where
|
||||
F: FnMut(Ty<'tcx>),
|
||||
{
|
||||
maybe_walk_ty(ty, |ty| { f(ty); true });
|
||||
}
|
||||
|
||||
// FIXME(#19596) unbox `f`
|
||||
pub fn maybe_walk_ty<'tcx>(ty: Ty<'tcx>, f: |Ty<'tcx>| -> bool) {
|
||||
if !f(ty) {
|
||||
return;
|
||||
|
|
@ -2464,9 +2467,11 @@ pub fn maybe_walk_ty<'tcx>(ty: Ty<'tcx>, f: |Ty<'tcx>| -> bool) {
|
|||
}
|
||||
|
||||
// Folds types from the bottom up.
|
||||
pub fn fold_ty<'tcx>(cx: &ctxt<'tcx>, t0: Ty<'tcx>,
|
||||
fldop: |Ty<'tcx>| -> Ty<'tcx>)
|
||||
-> Ty<'tcx> {
|
||||
pub fn fold_ty<'tcx, F>(cx: &ctxt<'tcx>, t0: Ty<'tcx>,
|
||||
fldop: F)
|
||||
-> Ty<'tcx> where
|
||||
F: FnMut(Ty<'tcx>) -> Ty<'tcx>,
|
||||
{
|
||||
let mut f = ty_fold::BottomUpFolder {tcx: cx, fldop: fldop};
|
||||
f.fold_ty(t0)
|
||||
}
|
||||
|
|
@ -2843,7 +2848,9 @@ impl TypeContents {
|
|||
*self & TC::ReachesAll
|
||||
}
|
||||
|
||||
pub fn union<T>(v: &[T], f: |&T| -> TypeContents) -> TypeContents {
|
||||
pub fn union<T, F>(v: &[T], mut f: F) -> TypeContents where
|
||||
F: FnMut(&T) -> TypeContents,
|
||||
{
|
||||
v.iter().fold(TC::None, |tc, ty| tc | f(ty))
|
||||
}
|
||||
|
||||
|
|
@ -3162,10 +3169,12 @@ pub fn type_contents<'tcx>(cx: &ctxt<'tcx>, ty: Ty<'tcx>) -> TypeContents {
|
|||
|
||||
// Iterates over all builtin bounds on the type parameter def, including
|
||||
// those inherited from traits with builtin-kind-supertraits.
|
||||
fn each_inherited_builtin_bound<'tcx>(cx: &ctxt<'tcx>,
|
||||
bounds: BuiltinBounds,
|
||||
traits: &[Rc<TraitRef<'tcx>>],
|
||||
f: |BuiltinBound|) {
|
||||
fn each_inherited_builtin_bound<'tcx, F>(cx: &ctxt<'tcx>,
|
||||
bounds: BuiltinBounds,
|
||||
traits: &[Rc<TraitRef<'tcx>>],
|
||||
mut f: F) where
|
||||
F: FnMut(BuiltinBound),
|
||||
{
|
||||
for bound in bounds.iter() {
|
||||
f(bound);
|
||||
}
|
||||
|
|
@ -3959,14 +3968,15 @@ pub fn local_var_name_str(cx: &ctxt, id: NodeId) -> InternedString {
|
|||
}
|
||||
|
||||
/// See `expr_ty_adjusted`
|
||||
pub fn adjust_ty<'tcx>(cx: &ctxt<'tcx>,
|
||||
span: Span,
|
||||
expr_id: ast::NodeId,
|
||||
unadjusted_ty: Ty<'tcx>,
|
||||
adjustment: Option<&AutoAdjustment<'tcx>>,
|
||||
method_type: |MethodCall| -> Option<Ty<'tcx>>)
|
||||
-> Ty<'tcx> {
|
||||
|
||||
pub fn adjust_ty<'tcx, F>(cx: &ctxt<'tcx>,
|
||||
span: Span,
|
||||
expr_id: ast::NodeId,
|
||||
unadjusted_ty: Ty<'tcx>,
|
||||
adjustment: Option<&AutoAdjustment<'tcx>>,
|
||||
mut method_type: F)
|
||||
-> Ty<'tcx> where
|
||||
F: FnMut(MethodCall) -> Option<Ty<'tcx>>,
|
||||
{
|
||||
if let ty_err = unadjusted_ty.sty {
|
||||
return unadjusted_ty;
|
||||
}
|
||||
|
|
@ -4604,11 +4614,13 @@ pub fn provided_trait_methods<'tcx>(cx: &ctxt<'tcx>, id: ast::DefId)
|
|||
/// id is local, it should have been loaded into the map by the `typeck::collect` phase. If the
|
||||
/// def-id is external, then we have to go consult the crate loading code (and cache the result for
|
||||
/// the future).
|
||||
fn lookup_locally_or_in_crate_store<V:Clone>(
|
||||
descr: &str,
|
||||
def_id: ast::DefId,
|
||||
map: &mut DefIdMap<V>,
|
||||
load_external: || -> V) -> V {
|
||||
fn lookup_locally_or_in_crate_store<V, F>(descr: &str,
|
||||
def_id: ast::DefId,
|
||||
map: &mut DefIdMap<V>,
|
||||
load_external: F) -> V where
|
||||
V: Clone,
|
||||
F: FnOnce() -> V,
|
||||
{
|
||||
match map.get(&def_id).cloned() {
|
||||
Some(v) => { return v; }
|
||||
None => { }
|
||||
|
|
@ -4916,7 +4928,9 @@ pub fn has_dtor(cx: &ctxt, struct_id: DefId) -> bool {
|
|||
cx.destructor_for_type.borrow().contains_key(&struct_id)
|
||||
}
|
||||
|
||||
pub fn with_path<T>(cx: &ctxt, id: ast::DefId, f: |ast_map::PathElems| -> T) -> T {
|
||||
pub fn with_path<T, F>(cx: &ctxt, id: ast::DefId, f: F) -> T where
|
||||
F: FnOnce(ast_map::PathElems) -> T,
|
||||
{
|
||||
if id.krate == ast::LOCAL_CRATE {
|
||||
cx.map.with_path(id.node, f)
|
||||
} else {
|
||||
|
|
@ -5162,7 +5176,9 @@ pub fn predicates<'tcx>(
|
|||
/// Iterate over attributes of a definition.
|
||||
// (This should really be an iterator, but that would require csearch and
|
||||
// decoder to use iterators instead of higher-order functions.)
|
||||
pub fn each_attr(tcx: &ctxt, did: DefId, f: |&ast::Attribute| -> bool) -> bool {
|
||||
pub fn each_attr<F>(tcx: &ctxt, did: DefId, mut f: F) -> bool where
|
||||
F: FnMut(&ast::Attribute) -> bool,
|
||||
{
|
||||
if is_local(did) {
|
||||
let item = tcx.map.expect_item(did.node);
|
||||
item.attrs.iter().all(|attr| f(attr))
|
||||
|
|
@ -5501,10 +5517,11 @@ pub fn eval_repeat_count(tcx: &ctxt, count_expr: &ast::Expr) -> uint {
|
|||
// Here, the supertraits are the transitive closure of the supertrait
|
||||
// relation on the supertraits from each bounded trait's constraint
|
||||
// list.
|
||||
pub fn each_bound_trait_and_supertraits<'tcx>(tcx: &ctxt<'tcx>,
|
||||
bounds: &[Rc<TraitRef<'tcx>>],
|
||||
f: |Rc<TraitRef<'tcx>>| -> bool)
|
||||
-> bool
|
||||
pub fn each_bound_trait_and_supertraits<'tcx, F>(tcx: &ctxt<'tcx>,
|
||||
bounds: &[Rc<TraitRef<'tcx>>],
|
||||
mut f: F)
|
||||
-> bool where
|
||||
F: FnMut(Rc<TraitRef<'tcx>>) -> bool,
|
||||
{
|
||||
for bound_trait_ref in traits::transitive_bounds(tcx, bounds) {
|
||||
if !f(bound_trait_ref) {
|
||||
|
|
@ -6192,7 +6209,9 @@ pub type FreevarMap = NodeMap<Vec<Freevar>>;
|
|||
|
||||
pub type CaptureModeMap = NodeMap<ast::CaptureClause>;
|
||||
|
||||
pub fn with_freevars<T>(tcx: &ty::ctxt, fid: ast::NodeId, f: |&[Freevar]| -> T) -> T {
|
||||
pub fn with_freevars<T, F>(tcx: &ty::ctxt, fid: ast::NodeId, f: F) -> T where
|
||||
F: FnOnce(&[Freevar]) -> T,
|
||||
{
|
||||
match tcx.freevars.borrow().get(&fid) {
|
||||
None => f(&[]),
|
||||
Some(d) => f(d.as_slice())
|
||||
|
|
@ -6240,12 +6259,13 @@ pub fn erase_late_bound_regions<'tcx, HR>(
|
|||
}
|
||||
|
||||
/// Replaces the late-bound-regions in `value` that are bound by `value`.
|
||||
pub fn replace_late_bound_regions<'tcx, HR>(
|
||||
pub fn replace_late_bound_regions<'tcx, HR, F>(
|
||||
tcx: &ty::ctxt<'tcx>,
|
||||
value: &HR,
|
||||
mapf: |BoundRegion, DebruijnIndex| -> ty::Region)
|
||||
-> (HR, FnvHashMap<ty::BoundRegion,ty::Region>)
|
||||
where HR : HigherRankedFoldable<'tcx>
|
||||
mut mapf: F)
|
||||
-> (HR, FnvHashMap<ty::BoundRegion, ty::Region>) where
|
||||
HR : HigherRankedFoldable<'tcx>,
|
||||
F: FnMut(BoundRegion, DebruijnIndex) -> ty::Region,
|
||||
{
|
||||
debug!("replace_late_bound_regions({})", value.repr(tcx));
|
||||
|
||||
|
|
|
|||
|
|
@ -743,12 +743,14 @@ impl<'tcx, T:HigherRankedFoldable<'tcx>> HigherRankedFoldable<'tcx> for Rc<T> {
|
|||
///////////////////////////////////////////////////////////////////////////
|
||||
// Some sample folders
|
||||
|
||||
pub struct BottomUpFolder<'a, 'tcx: 'a> {
|
||||
pub struct BottomUpFolder<'a, 'tcx: 'a, F> where F: FnMut(Ty<'tcx>) -> Ty<'tcx> {
|
||||
pub tcx: &'a ty::ctxt<'tcx>,
|
||||
pub fldop: |Ty<'tcx>|: 'a -> Ty<'tcx>,
|
||||
pub fldop: F,
|
||||
}
|
||||
|
||||
impl<'a, 'tcx> TypeFolder<'tcx> for BottomUpFolder<'a, 'tcx> {
|
||||
impl<'a, 'tcx, F> TypeFolder<'tcx> for BottomUpFolder<'a, 'tcx, F> where
|
||||
F: FnMut(Ty<'tcx>) -> Ty<'tcx>,
|
||||
{
|
||||
fn tcx<'a>(&'a self) -> &'a ty::ctxt<'tcx> { self.tcx }
|
||||
|
||||
fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {
|
||||
|
|
@ -772,15 +774,14 @@ impl<'a, 'tcx> TypeFolder<'tcx> for BottomUpFolder<'a, 'tcx> {
|
|||
/// (The distinction between "free" and "bound" is represented by
|
||||
/// keeping track of each `FnSig` in the lexical context of the
|
||||
/// current position of the fold.)
|
||||
pub struct RegionFolder<'a, 'tcx: 'a> {
|
||||
pub struct RegionFolder<'a, 'tcx: 'a, F> where F: FnMut(ty::Region, uint) -> ty::Region {
|
||||
tcx: &'a ty::ctxt<'tcx>,
|
||||
current_depth: uint,
|
||||
fld_r: |ty::Region, uint|: 'a -> ty::Region,
|
||||
fld_r: F,
|
||||
}
|
||||
|
||||
impl<'a, 'tcx> RegionFolder<'a, 'tcx> {
|
||||
pub fn new(tcx: &'a ty::ctxt<'tcx>, fld_r: |ty::Region, uint|: 'a -> ty::Region)
|
||||
-> RegionFolder<'a, 'tcx> {
|
||||
impl<'a, 'tcx, F> RegionFolder<'a, 'tcx, F> where F: FnMut(ty::Region, uint) -> ty::Region {
|
||||
pub fn new(tcx: &'a ty::ctxt<'tcx>, fld_r: F) -> RegionFolder<'a, 'tcx, F> {
|
||||
RegionFolder {
|
||||
tcx: tcx,
|
||||
current_depth: 1,
|
||||
|
|
@ -789,7 +790,9 @@ impl<'a, 'tcx> RegionFolder<'a, 'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'a, 'tcx> TypeFolder<'tcx> for RegionFolder<'a, 'tcx> {
|
||||
impl<'a, 'tcx, F> TypeFolder<'tcx> for RegionFolder<'a, 'tcx, F> where
|
||||
F: FnMut(ty::Region, uint) -> ty::Region,
|
||||
{
|
||||
fn tcx<'a>(&'a self) -> &'a ty::ctxt<'tcx> { self.tcx }
|
||||
|
||||
fn enter_region_binder(&mut self) {
|
||||
|
|
|
|||
|
|
@ -288,7 +288,9 @@ pub fn build_session_(sopts: config::Options,
|
|||
}
|
||||
|
||||
// Seems out of place, but it uses session, so I'm putting it here
|
||||
pub fn expect<T>(sess: &Session, opt: Option<T>, msg: || -> String) -> T {
|
||||
pub fn expect<T, M>(sess: &Session, opt: Option<T>, msg: M) -> T where
|
||||
M: FnOnce() -> String,
|
||||
{
|
||||
diagnostic::expect(sess.diagnostic(), opt, msg)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -27,7 +27,9 @@ pub struct ErrorReported;
|
|||
|
||||
impl Copy for ErrorReported {}
|
||||
|
||||
pub fn time<T, U>(do_it: bool, what: &str, u: U, f: |U| -> T) -> T {
|
||||
pub fn time<T, U, F>(do_it: bool, what: &str, u: U, f: F) -> T where
|
||||
F: FnOnce(U) -> T,
|
||||
{
|
||||
thread_local!(static DEPTH: Cell<uint> = Cell::new(0));
|
||||
if !do_it { return f(u); }
|
||||
|
||||
|
|
@ -39,9 +41,13 @@ pub fn time<T, U>(do_it: bool, what: &str, u: U, f: |U| -> T) -> T {
|
|||
|
||||
let mut u = Some(u);
|
||||
let mut rv = None;
|
||||
let dur = Duration::span(|| {
|
||||
rv = Some(f(u.take().unwrap()))
|
||||
});
|
||||
let dur = {
|
||||
let ref mut rvp = rv;
|
||||
|
||||
Duration::span(move || {
|
||||
*rvp = Some(f(u.take().unwrap()))
|
||||
})
|
||||
};
|
||||
let rv = rv.unwrap();
|
||||
|
||||
println!("{}time: {}.{:03} \t{}", " ".repeat(old),
|
||||
|
|
@ -51,7 +57,10 @@ pub fn time<T, U>(do_it: bool, what: &str, u: U, f: |U| -> T) -> T {
|
|||
rv
|
||||
}
|
||||
|
||||
pub fn indent<R: Show>(op: || -> R) -> R {
|
||||
pub fn indent<R, F>(op: F) -> R where
|
||||
R: Show,
|
||||
F: FnOnce() -> R,
|
||||
{
|
||||
// Use in conjunction with the log post-processor like `src/etc/indenter`
|
||||
// to make debug output more readable.
|
||||
debug!(">>");
|
||||
|
|
@ -73,12 +82,12 @@ pub fn indenter() -> Indenter {
|
|||
Indenter { _cannot_construct_outside_of_this_module: () }
|
||||
}
|
||||
|
||||
struct LoopQueryVisitor<'a> {
|
||||
p: |&ast::Expr_|: 'a -> bool,
|
||||
struct LoopQueryVisitor<P> where P: FnMut(&ast::Expr_) -> bool {
|
||||
p: P,
|
||||
flag: bool,
|
||||
}
|
||||
|
||||
impl<'a, 'v> Visitor<'v> for LoopQueryVisitor<'a> {
|
||||
impl<'v, P> Visitor<'v> for LoopQueryVisitor<P> where P: FnMut(&ast::Expr_) -> bool {
|
||||
fn visit_expr(&mut self, e: &ast::Expr) {
|
||||
self.flag |= (self.p)(&e.node);
|
||||
match e.node {
|
||||
|
|
@ -92,7 +101,7 @@ impl<'a, 'v> Visitor<'v> for LoopQueryVisitor<'a> {
|
|||
|
||||
// Takes a predicate p, returns true iff p is true for any subexpressions
|
||||
// of b -- skipping any inner loops (loop, while, loop_body)
|
||||
pub fn loop_query(b: &ast::Block, p: |&ast::Expr_| -> bool) -> bool {
|
||||
pub fn loop_query<P>(b: &ast::Block, p: P) -> bool where P: FnMut(&ast::Expr_) -> bool {
|
||||
let mut v = LoopQueryVisitor {
|
||||
p: p,
|
||||
flag: false,
|
||||
|
|
@ -101,12 +110,12 @@ pub fn loop_query(b: &ast::Block, p: |&ast::Expr_| -> bool) -> bool {
|
|||
return v.flag;
|
||||
}
|
||||
|
||||
struct BlockQueryVisitor<'a> {
|
||||
p: |&ast::Expr|: 'a -> bool,
|
||||
struct BlockQueryVisitor<P> where P: FnMut(&ast::Expr) -> bool {
|
||||
p: P,
|
||||
flag: bool,
|
||||
}
|
||||
|
||||
impl<'a, 'v> Visitor<'v> for BlockQueryVisitor<'a> {
|
||||
impl<'v, P> Visitor<'v> for BlockQueryVisitor<P> where P: FnMut(&ast::Expr) -> bool {
|
||||
fn visit_expr(&mut self, e: &ast::Expr) {
|
||||
self.flag |= (self.p)(e);
|
||||
visit::walk_expr(self, e)
|
||||
|
|
@ -115,7 +124,7 @@ impl<'a, 'v> Visitor<'v> for BlockQueryVisitor<'a> {
|
|||
|
||||
// Takes a predicate p, returns true iff p is true for any subexpressions
|
||||
// of b -- skipping any inner loops (loop, while, loop_body)
|
||||
pub fn block_query(b: &ast::Block, p: |&ast::Expr| -> bool) -> bool {
|
||||
pub fn block_query<P>(b: &ast::Block, p: P) -> bool where P: FnMut(&ast::Expr) -> bool {
|
||||
let mut v = BlockQueryVisitor {
|
||||
p: p,
|
||||
flag: false,
|
||||
|
|
@ -194,11 +203,12 @@ pub fn can_reach<S,H:Hasher<S>,T:Eq+Clone+Hash<S>>(
|
|||
/// }
|
||||
/// ```
|
||||
#[inline(always)]
|
||||
pub fn memoized<T: Clone + Hash<S> + Eq, U: Clone, S, H: Hasher<S>>(
|
||||
cache: &RefCell<HashMap<T, U, H>>,
|
||||
arg: T,
|
||||
f: |T| -> U
|
||||
) -> U {
|
||||
pub fn memoized<T, U, S, H, F>(cache: &RefCell<HashMap<T, U, H>>, arg: T, f: F) -> U where
|
||||
T: Clone + Hash<S> + Eq,
|
||||
U: Clone,
|
||||
H: Hasher<S>,
|
||||
F: FnOnce(T) -> U,
|
||||
{
|
||||
let key = arg.clone();
|
||||
let result = cache.borrow().get(&key).map(|result| result.clone());
|
||||
match result {
|
||||
|
|
|
|||
|
|
@ -241,7 +241,9 @@ pub fn trait_store_to_string(cx: &ctxt, s: ty::TraitStore) -> String {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn vec_map_to_string<T>(ts: &[T], f: |t: &T| -> String) -> String {
|
||||
pub fn vec_map_to_string<T, F>(ts: &[T], f: F) -> String where
|
||||
F: FnMut(&T) -> String,
|
||||
{
|
||||
let tstrs = ts.iter().map(f).collect::<Vec<String>>();
|
||||
format!("[{}]", tstrs.connect(", "))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -279,8 +279,9 @@ impl<'a> ArchiveBuilder<'a> {
|
|||
self.archive
|
||||
}
|
||||
|
||||
fn add_archive(&mut self, archive: &Path, name: &str,
|
||||
skip: |&str| -> bool) -> io::IoResult<()> {
|
||||
fn add_archive<F>(&mut self, archive: &Path, name: &str, mut skip: F) -> io::IoResult<()> where
|
||||
F: FnMut(&str) -> bool,
|
||||
{
|
||||
let loc = TempDir::new("rsar").unwrap();
|
||||
|
||||
// First, extract the contents of the archive to a temporary directory.
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@
|
|||
|
||||
#![allow(unknown_features)]
|
||||
#![feature(globs, phase, macro_rules, slicing_syntax)]
|
||||
#![feature(unboxed_closures)]
|
||||
|
||||
#[phase(plugin, link)]
|
||||
extern crate log;
|
||||
|
|
|
|||
|
|
@ -14,17 +14,22 @@ use std::os;
|
|||
use std::io::IoError;
|
||||
use syntax::ast;
|
||||
|
||||
pub struct RPathConfig<'a> {
|
||||
pub struct RPathConfig<F, G> where
|
||||
F: FnOnce() -> Path,
|
||||
G: FnMut(&Path) -> Result<Path, IoError>,
|
||||
{
|
||||
pub used_crates: Vec<(ast::CrateNum, Option<Path>)>,
|
||||
pub out_filename: Path,
|
||||
pub is_like_osx: bool,
|
||||
pub has_rpath: bool,
|
||||
pub get_install_prefix_lib_path: ||:'a -> Path,
|
||||
pub realpath: |&Path|:'a -> Result<Path, IoError>
|
||||
pub get_install_prefix_lib_path: F,
|
||||
pub realpath: G,
|
||||
}
|
||||
|
||||
pub fn get_rpath_flags(config: RPathConfig) -> Vec<String> {
|
||||
|
||||
pub fn get_rpath_flags<F, G>(config: RPathConfig<F, G>) -> Vec<String> where
|
||||
F: FnOnce() -> Path,
|
||||
G: FnMut(&Path) -> Result<Path, IoError>,
|
||||
{
|
||||
// No rpath on windows
|
||||
if !config.has_rpath {
|
||||
return Vec::new();
|
||||
|
|
@ -52,8 +57,10 @@ fn rpaths_to_flags(rpaths: &[String]) -> Vec<String> {
|
|||
return ret;
|
||||
}
|
||||
|
||||
fn get_rpaths(mut config: RPathConfig,
|
||||
libs: &[Path]) -> Vec<String> {
|
||||
fn get_rpaths<F, G>(mut config: RPathConfig<F, G>, libs: &[Path]) -> Vec<String> where
|
||||
F: FnOnce() -> Path,
|
||||
G: FnMut(&Path) -> Result<Path, IoError>,
|
||||
{
|
||||
debug!("output: {}", config.out_filename.display());
|
||||
debug!("libs:");
|
||||
for libpath in libs.iter() {
|
||||
|
|
@ -86,13 +93,18 @@ fn get_rpaths(mut config: RPathConfig,
|
|||
return rpaths;
|
||||
}
|
||||
|
||||
fn get_rpaths_relative_to_output(config: &mut RPathConfig,
|
||||
libs: &[Path]) -> Vec<String> {
|
||||
fn get_rpaths_relative_to_output<F, G>(config: &mut RPathConfig<F, G>,
|
||||
libs: &[Path]) -> Vec<String> where
|
||||
F: FnOnce() -> Path,
|
||||
G: FnMut(&Path) -> Result<Path, IoError>,
|
||||
{
|
||||
libs.iter().map(|a| get_rpath_relative_to_output(config, a)).collect()
|
||||
}
|
||||
|
||||
fn get_rpath_relative_to_output(config: &mut RPathConfig,
|
||||
lib: &Path) -> String {
|
||||
fn get_rpath_relative_to_output<F, G>(config: &mut RPathConfig<F, G>, lib: &Path) -> String where
|
||||
F: FnOnce() -> Path,
|
||||
G: FnMut(&Path) -> Result<Path, IoError>,
|
||||
{
|
||||
use std::os;
|
||||
|
||||
// Mac doesn't appear to support $ORIGIN
|
||||
|
|
@ -114,7 +126,10 @@ fn get_rpath_relative_to_output(config: &mut RPathConfig,
|
|||
relative.as_str().expect("non-utf8 component in path"))
|
||||
}
|
||||
|
||||
fn get_install_prefix_rpath(config: RPathConfig) -> String {
|
||||
fn get_install_prefix_rpath<F, G>(config: RPathConfig<F, G>) -> String where
|
||||
F: FnOnce() -> Path,
|
||||
G: FnMut(&Path) -> Result<Path, IoError>,
|
||||
{
|
||||
let path = (config.get_install_prefix_lib_path)();
|
||||
let path = os::make_absolute(&path).unwrap();
|
||||
// FIXME (#9639): This needs to handle non-utf8 paths
|
||||
|
|
|
|||
|
|
@ -82,7 +82,8 @@ fn add_bytes_to_bits<T: Int + ToBits>(bits: T, bytes: T) -> T {
|
|||
trait FixedBuffer {
|
||||
/// Input a vector of bytes. If the buffer becomes full, process it with the provided
|
||||
/// function and then clear the buffer.
|
||||
fn input(&mut self, input: &[u8], func: |&[u8]|);
|
||||
fn input<F>(&mut self, input: &[u8], func: F) where
|
||||
F: FnMut(&[u8]);
|
||||
|
||||
/// Reset the buffer.
|
||||
fn reset(&mut self);
|
||||
|
|
@ -125,7 +126,9 @@ impl FixedBuffer64 {
|
|||
}
|
||||
|
||||
impl FixedBuffer for FixedBuffer64 {
|
||||
fn input(&mut self, input: &[u8], func: |&[u8]|) {
|
||||
fn input<F>(&mut self, input: &[u8], mut func: F) where
|
||||
F: FnMut(&[u8]),
|
||||
{
|
||||
let mut i = 0;
|
||||
|
||||
let size = self.size();
|
||||
|
|
@ -201,11 +204,11 @@ trait StandardPadding {
|
|||
/// guaranteed to have exactly rem remaining bytes when it returns. If there are not at least
|
||||
/// rem bytes available, the buffer will be zero padded, processed, cleared, and then filled
|
||||
/// with zeros again until only rem bytes are remaining.
|
||||
fn standard_padding(&mut self, rem: uint, func: |&[u8]|);
|
||||
fn standard_padding<F>(&mut self, rem: uint, func: F) where F: FnMut(&[u8]);
|
||||
}
|
||||
|
||||
impl <T: FixedBuffer> StandardPadding for T {
|
||||
fn standard_padding(&mut self, rem: uint, func: |&[u8]|) {
|
||||
fn standard_padding<F>(&mut self, rem: uint, mut func: F) where F: FnMut(&[u8]) {
|
||||
let size = self.size();
|
||||
|
||||
self.next(1)[0] = 128;
|
||||
|
|
|
|||
|
|
@ -232,8 +232,9 @@ fn compatible_borrow_kinds(borrow_kind1: ty::BorrowKind,
|
|||
impl<'a, 'tcx> CheckLoanCtxt<'a, 'tcx> {
|
||||
pub fn tcx(&self) -> &'a ty::ctxt<'tcx> { self.bccx.tcx }
|
||||
|
||||
pub fn each_issued_loan(&self, scope: region::CodeExtent, op: |&Loan<'tcx>| -> bool)
|
||||
-> bool {
|
||||
pub fn each_issued_loan<F>(&self, scope: region::CodeExtent, mut op: F) -> bool where
|
||||
F: FnMut(&Loan<'tcx>) -> bool,
|
||||
{
|
||||
//! Iterates over each loan that has been issued
|
||||
//! on entrance to `scope`, regardless of whether it is
|
||||
//! actually *in scope* at that point. Sometimes loans
|
||||
|
|
@ -246,10 +247,9 @@ impl<'a, 'tcx> CheckLoanCtxt<'a, 'tcx> {
|
|||
})
|
||||
}
|
||||
|
||||
pub fn each_in_scope_loan(&self,
|
||||
scope: region::CodeExtent,
|
||||
op: |&Loan<'tcx>| -> bool)
|
||||
-> bool {
|
||||
pub fn each_in_scope_loan<F>(&self, scope: region::CodeExtent, mut op: F) -> bool where
|
||||
F: FnMut(&Loan<'tcx>) -> bool,
|
||||
{
|
||||
//! Like `each_issued_loan()`, but only considers loans that are
|
||||
//! currently in scope.
|
||||
|
||||
|
|
@ -263,11 +263,13 @@ impl<'a, 'tcx> CheckLoanCtxt<'a, 'tcx> {
|
|||
})
|
||||
}
|
||||
|
||||
fn each_in_scope_loan_affecting_path(&self,
|
||||
scope: region::CodeExtent,
|
||||
loan_path: &LoanPath<'tcx>,
|
||||
op: |&Loan<'tcx>| -> bool)
|
||||
-> bool {
|
||||
fn each_in_scope_loan_affecting_path<F>(&self,
|
||||
scope: region::CodeExtent,
|
||||
loan_path: &LoanPath<'tcx>,
|
||||
mut op: F)
|
||||
-> bool where
|
||||
F: FnMut(&Loan<'tcx>) -> bool,
|
||||
{
|
||||
//! Iterates through all of the in-scope loans affecting `loan_path`,
|
||||
//! calling `op`, and ceasing iteration if `false` is returned.
|
||||
|
||||
|
|
|
|||
|
|
@ -523,8 +523,9 @@ impl<'tcx> MoveData<'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
fn each_base_path(&self, index: MovePathIndex, f: |MovePathIndex| -> bool)
|
||||
-> bool {
|
||||
fn each_base_path<F>(&self, index: MovePathIndex, mut f: F) -> bool where
|
||||
F: FnMut(MovePathIndex) -> bool,
|
||||
{
|
||||
let mut p = index;
|
||||
while p != InvalidMovePathIndex {
|
||||
if !f(p) {
|
||||
|
|
@ -535,10 +536,8 @@ impl<'tcx> MoveData<'tcx> {
|
|||
return true;
|
||||
}
|
||||
|
||||
fn each_extending_path(&self,
|
||||
index: MovePathIndex,
|
||||
f: |MovePathIndex| -> bool)
|
||||
-> bool {
|
||||
// FIXME(#19596) unbox `f`
|
||||
fn each_extending_path(&self, index: MovePathIndex, f: |MovePathIndex| -> bool) -> bool {
|
||||
if !f(index) {
|
||||
return false;
|
||||
}
|
||||
|
|
@ -554,10 +553,9 @@ impl<'tcx> MoveData<'tcx> {
|
|||
return true;
|
||||
}
|
||||
|
||||
fn each_applicable_move(&self,
|
||||
index0: MovePathIndex,
|
||||
f: |MoveIndex| -> bool)
|
||||
-> bool {
|
||||
fn each_applicable_move<F>(&self, index0: MovePathIndex, mut f: F) -> bool where
|
||||
F: FnMut(MoveIndex) -> bool,
|
||||
{
|
||||
let mut ret = true;
|
||||
self.each_extending_path(index0, |index| {
|
||||
let mut p = self.path_first_move(index);
|
||||
|
|
@ -660,11 +658,13 @@ impl<'a, 'tcx> FlowedMoveData<'a, 'tcx> {
|
|||
/// Iterates through each move of `loan_path` (or some base path of `loan_path`) that *may*
|
||||
/// have occurred on entry to `id` without an intervening assignment. In other words, any moves
|
||||
/// that would invalidate a reference to `loan_path` at location `id`.
|
||||
pub fn each_move_of(&self,
|
||||
id: ast::NodeId,
|
||||
loan_path: &Rc<LoanPath<'tcx>>,
|
||||
f: |&Move, &LoanPath<'tcx>| -> bool)
|
||||
-> bool {
|
||||
pub fn each_move_of<F>(&self,
|
||||
id: ast::NodeId,
|
||||
loan_path: &Rc<LoanPath<'tcx>>,
|
||||
mut f: F)
|
||||
-> bool where
|
||||
F: FnMut(&Move, &LoanPath<'tcx>) -> bool,
|
||||
{
|
||||
// Bad scenarios:
|
||||
//
|
||||
// 1. Move of `a.b.c`, use of `a.b.c`
|
||||
|
|
@ -715,11 +715,13 @@ impl<'a, 'tcx> FlowedMoveData<'a, 'tcx> {
|
|||
|
||||
/// Iterates through every assignment to `loan_path` that may have occurred on entry to `id`.
|
||||
/// `loan_path` must be a single variable.
|
||||
pub fn each_assignment_of(&self,
|
||||
id: ast::NodeId,
|
||||
loan_path: &Rc<LoanPath<'tcx>>,
|
||||
f: |&Assignment| -> bool)
|
||||
-> bool {
|
||||
pub fn each_assignment_of<F>(&self,
|
||||
id: ast::NodeId,
|
||||
loan_path: &Rc<LoanPath<'tcx>>,
|
||||
mut f: F)
|
||||
-> bool where
|
||||
F: FnMut(&Assignment) -> bool,
|
||||
{
|
||||
let loan_path_index = {
|
||||
match self.move_data.existing_move_path(loan_path) {
|
||||
Some(i) => i,
|
||||
|
|
|
|||
|
|
@ -75,11 +75,13 @@ impl<'a, 'tcx> DataflowLabeller<'a, 'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
fn build_set<O:DataFlowOperator>(&self,
|
||||
e: EntryOrExit,
|
||||
cfgidx: CFGIndex,
|
||||
dfcx: &DataFlowContext<'a, 'tcx, O>,
|
||||
to_lp: |uint| -> Rc<LoanPath<'tcx>>) -> String {
|
||||
fn build_set<O:DataFlowOperator, F>(&self,
|
||||
e: EntryOrExit,
|
||||
cfgidx: CFGIndex,
|
||||
dfcx: &DataFlowContext<'a, 'tcx, O>,
|
||||
mut to_lp: F) -> String where
|
||||
F: FnMut(uint) -> Rc<LoanPath<'tcx>>,
|
||||
{
|
||||
let mut saw_some = false;
|
||||
let mut set = "{".to_string();
|
||||
dfcx.each_bit_for_node(e, cfgidx, |index| {
|
||||
|
|
@ -98,7 +100,7 @@ impl<'a, 'tcx> DataflowLabeller<'a, 'tcx> {
|
|||
|
||||
fn dataflow_loans_for(&self, e: EntryOrExit, cfgidx: CFGIndex) -> String {
|
||||
let dfcx = &self.analysis_data.loans;
|
||||
let loan_index_to_path = |loan_index| {
|
||||
let loan_index_to_path = |&mut: loan_index| {
|
||||
let all_loans = &self.analysis_data.all_loans;
|
||||
all_loans[loan_index].loan_path()
|
||||
};
|
||||
|
|
@ -107,7 +109,7 @@ impl<'a, 'tcx> DataflowLabeller<'a, 'tcx> {
|
|||
|
||||
fn dataflow_moves_for(&self, e: EntryOrExit, cfgidx: CFGIndex) -> String {
|
||||
let dfcx = &self.analysis_data.move_data.dfcx_moves;
|
||||
let move_index_to_path = |move_index| {
|
||||
let move_index_to_path = |&mut: move_index| {
|
||||
let move_data = &self.analysis_data.move_data.move_data;
|
||||
let moves = move_data.moves.borrow();
|
||||
let the_move = &(*moves)[move_index];
|
||||
|
|
@ -118,7 +120,7 @@ impl<'a, 'tcx> DataflowLabeller<'a, 'tcx> {
|
|||
|
||||
fn dataflow_assigns_for(&self, e: EntryOrExit, cfgidx: CFGIndex) -> String {
|
||||
let dfcx = &self.analysis_data.move_data.dfcx_assign;
|
||||
let assign_index_to_path = |assign_index| {
|
||||
let assign_index_to_path = |&mut: assign_index| {
|
||||
let move_data = &self.analysis_data.move_data.move_data;
|
||||
let assignments = move_data.var_assignments.borrow();
|
||||
let assignment = &(*assignments)[assign_index];
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -78,7 +78,7 @@ pub fn parse_pretty(sess: &Session, name: &str) -> (PpMode, Option<UserIdentifie
|
|||
or `expanded,identified`; got {}", name).as_slice());
|
||||
}
|
||||
};
|
||||
let opt_second = opt_second.and_then::<UserIdentifiedItem>(from_str);
|
||||
let opt_second = opt_second.and_then::<UserIdentifiedItem, _>(from_str);
|
||||
(first, opt_second)
|
||||
}
|
||||
|
||||
|
|
@ -99,13 +99,15 @@ pub fn parse_pretty(sess: &Session, name: &str) -> (PpMode, Option<UserIdentifie
|
|||
|
||||
impl PpSourceMode {
|
||||
/// Constructs a `PrinterSupport` object and passes it to `f`.
|
||||
fn call_with_pp_support<'tcx, A, B>(&self,
|
||||
sess: Session,
|
||||
ast_map: Option<ast_map::Map<'tcx>>,
|
||||
type_arena: &'tcx TypedArena<ty::TyS<'tcx>>,
|
||||
id: String,
|
||||
payload: B,
|
||||
f: |&PrinterSupport, B| -> A) -> A {
|
||||
fn call_with_pp_support<'tcx, A, B, F>(&self,
|
||||
sess: Session,
|
||||
ast_map: Option<ast_map::Map<'tcx>>,
|
||||
type_arena: &'tcx TypedArena<ty::TyS<'tcx>>,
|
||||
id: String,
|
||||
payload: B,
|
||||
f: F) -> A where
|
||||
F: FnOnce(&PrinterSupport, B) -> A,
|
||||
{
|
||||
match *self {
|
||||
PpmNormal | PpmExpanded => {
|
||||
let annotation = NoAnn { sess: sess, ast_map: ast_map };
|
||||
|
|
@ -313,14 +315,12 @@ pub enum UserIdentifiedItem {
|
|||
|
||||
impl FromStr for UserIdentifiedItem {
|
||||
fn from_str(s: &str) -> Option<UserIdentifiedItem> {
|
||||
let extract_path_parts = || {
|
||||
from_str(s).map(ItemViaNode).or_else(|| {
|
||||
let v : Vec<_> = s.split_str("::")
|
||||
.map(|x|x.to_string())
|
||||
.collect();
|
||||
Some(ItemViaPath(v))
|
||||
};
|
||||
|
||||
from_str(s).map(ItemViaNode).or_else(extract_path_parts)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -93,9 +93,11 @@ fn errors(msgs: &[&str]) -> (Box<Emitter+Send>, uint) {
|
|||
(box ExpectErrorEmitter { messages: v } as Box<Emitter+Send>, msgs.len())
|
||||
}
|
||||
|
||||
fn test_env(source_string: &str,
|
||||
(emitter, expected_err_count): (Box<Emitter+Send>, uint),
|
||||
body: |Env|) {
|
||||
fn test_env<F>(source_string: &str,
|
||||
(emitter, expected_err_count): (Box<Emitter+Send>, uint),
|
||||
body: F) where
|
||||
F: FnOnce(Env),
|
||||
{
|
||||
let mut options =
|
||||
config::basic_options();
|
||||
options.debugging_opts |= config::VERBOSE;
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@
|
|||
|
||||
#![feature(globs)]
|
||||
#![feature(link_args)]
|
||||
#![feature(unboxed_closures)]
|
||||
|
||||
extern crate libc;
|
||||
|
||||
|
|
@ -2206,7 +2207,7 @@ pub unsafe extern "C" fn rust_llvm_string_write_impl(sr: RustStringRef,
|
|||
(*sr).borrow_mut().push_all(slice);
|
||||
}
|
||||
|
||||
pub fn build_string(f: |RustStringRef|) -> Option<String> {
|
||||
pub fn build_string<F>(f: F) -> Option<String> where F: FnOnce(RustStringRef){
|
||||
let mut buf = RefCell::new(Vec::new());
|
||||
f(&mut buf as RustStringRepr as RustStringRef);
|
||||
String::from_utf8(buf.into_inner()).ok()
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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(),
|
||||
|
|
|
|||
|
|
@ -488,8 +488,12 @@ unsafe fn optimize_and_codegen(cgcx: &CodegenContext,
|
|||
// pass manager passed to the closure should be ensured to not
|
||||
// escape the closure itself, and the manager should only be
|
||||
// used once.
|
||||
unsafe fn with_codegen(tm: TargetMachineRef, llmod: ModuleRef,
|
||||
no_builtins: bool, f: |PassManagerRef|) {
|
||||
unsafe fn with_codegen<F>(tm: TargetMachineRef,
|
||||
llmod: ModuleRef,
|
||||
no_builtins: bool,
|
||||
f: F) where
|
||||
F: FnOnce(PassManagerRef),
|
||||
{
|
||||
let cpm = llvm::LLVMCreatePassManager();
|
||||
llvm::LLVMRustAddAnalysisPasses(tm, cpm, llmod);
|
||||
llvm::LLVMRustAddLibraryInfo(cpm, llmod, no_builtins);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -79,7 +79,9 @@ struct DxrVisitor<'l, 'tcx: 'l> {
|
|||
}
|
||||
|
||||
impl <'l, 'tcx> DxrVisitor<'l, 'tcx> {
|
||||
fn nest(&mut self, scope_id: NodeId, f: |&mut DxrVisitor<'l, 'tcx>|) {
|
||||
fn nest<F>(&mut self, scope_id: NodeId, f: F) where
|
||||
F: FnOnce(&mut DxrVisitor<'l, 'tcx>),
|
||||
{
|
||||
let parent_scope = self.cur_scope;
|
||||
self.cur_scope = scope_id;
|
||||
f(self);
|
||||
|
|
|
|||
|
|
@ -771,7 +771,7 @@ fn pick_column_to_specialize(def_map: &DefMap, m: &[Match]) -> Option<uint> {
|
|||
}
|
||||
};
|
||||
|
||||
let column_contains_any_nonwild_patterns: |&uint| -> bool = |&col| {
|
||||
let column_contains_any_nonwild_patterns = |&: &col: &uint| -> bool {
|
||||
m.iter().any(|row| match row.pats[col].node {
|
||||
ast::PatWild(_) => false,
|
||||
_ => true
|
||||
|
|
@ -1578,14 +1578,15 @@ pub fn store_for_loop_binding<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
|
|||
bind_irrefutable_pat(bcx, pat, llvalue, body_scope)
|
||||
}
|
||||
|
||||
fn mk_binding_alloca<'blk, 'tcx, A>(bcx: Block<'blk, 'tcx>,
|
||||
p_id: ast::NodeId,
|
||||
ident: &ast::Ident,
|
||||
cleanup_scope: cleanup::ScopeId,
|
||||
arg: A,
|
||||
populate: |A, Block<'blk, 'tcx>, ValueRef, Ty<'tcx>|
|
||||
-> Block<'blk, 'tcx>)
|
||||
-> Block<'blk, 'tcx> {
|
||||
fn mk_binding_alloca<'blk, 'tcx, A, F>(bcx: Block<'blk, 'tcx>,
|
||||
p_id: ast::NodeId,
|
||||
ident: &ast::Ident,
|
||||
cleanup_scope: cleanup::ScopeId,
|
||||
arg: A,
|
||||
populate: F)
|
||||
-> Block<'blk, 'tcx> where
|
||||
F: FnOnce(A, Block<'blk, 'tcx>, ValueRef, Ty<'tcx>) -> Block<'blk, 'tcx>,
|
||||
{
|
||||
let var_ty = node_id_type(bcx, p_id);
|
||||
|
||||
// Allocate memory on stack for the binding.
|
||||
|
|
|
|||
|
|
@ -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, _) => {
|
||||
|
|
|
|||
|
|
@ -107,9 +107,11 @@ thread_local!(static TASK_LOCAL_INSN_KEY: RefCell<Option<Vec<&'static str>>> = {
|
|||
RefCell::new(None)
|
||||
})
|
||||
|
||||
pub fn with_insn_ctxt(blk: |&[&'static str]|) {
|
||||
TASK_LOCAL_INSN_KEY.with(|slot| {
|
||||
slot.borrow().as_ref().map(|s| blk(s.as_slice()));
|
||||
pub fn with_insn_ctxt<F>(blk: F) where
|
||||
F: FnOnce(&[&'static str]),
|
||||
{
|
||||
TASK_LOCAL_INSN_KEY.with(move |slot| {
|
||||
slot.borrow().as_ref().map(move |s| blk(s.as_slice()));
|
||||
})
|
||||
}
|
||||
|
||||
|
|
@ -841,12 +843,15 @@ pub fn cast_shift_const_rhs(op: ast::BinOp,
|
|||
|a, b| unsafe { llvm::LLVMConstZExt(a, b.to_ref()) })
|
||||
}
|
||||
|
||||
pub fn cast_shift_rhs(op: ast::BinOp,
|
||||
lhs: ValueRef,
|
||||
rhs: ValueRef,
|
||||
trunc: |ValueRef, Type| -> ValueRef,
|
||||
zext: |ValueRef, Type| -> ValueRef)
|
||||
-> ValueRef {
|
||||
pub fn cast_shift_rhs<F, G>(op: ast::BinOp,
|
||||
lhs: ValueRef,
|
||||
rhs: ValueRef,
|
||||
trunc: F,
|
||||
zext: G)
|
||||
-> ValueRef where
|
||||
F: FnOnce(ValueRef, Type) -> ValueRef,
|
||||
G: FnOnce(ValueRef, Type) -> ValueRef,
|
||||
{
|
||||
// Shifts may have any size int on the rhs
|
||||
unsafe {
|
||||
if ast_util::is_shift_binop(op) {
|
||||
|
|
@ -1101,10 +1106,12 @@ pub fn raw_block<'blk, 'tcx>(fcx: &'blk FunctionContext<'blk, 'tcx>,
|
|||
common::BlockS::new(llbb, is_lpad, None, fcx)
|
||||
}
|
||||
|
||||
pub fn with_cond<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
|
||||
val: ValueRef,
|
||||
f: |Block<'blk, 'tcx>| -> Block<'blk, 'tcx>)
|
||||
-> Block<'blk, 'tcx> {
|
||||
pub fn with_cond<'blk, 'tcx, F>(bcx: Block<'blk, 'tcx>,
|
||||
val: ValueRef,
|
||||
f: F)
|
||||
-> Block<'blk, 'tcx> where
|
||||
F: FnOnce(Block<'blk, 'tcx>) -> Block<'blk, 'tcx>,
|
||||
{
|
||||
let _icx = push_ctxt("with_cond");
|
||||
let fcx = bcx.fcx;
|
||||
let next_cx = fcx.new_temp_block("next");
|
||||
|
|
|
|||
|
|
@ -17,7 +17,12 @@ pub struct BasicBlock(pub BasicBlockRef);
|
|||
|
||||
impl Copy for BasicBlock {}
|
||||
|
||||
pub type Preds<'a> = Map<'a, Value, BasicBlock, Filter<'a, Value, Users>>;
|
||||
pub type Preds = Map<
|
||||
Value,
|
||||
BasicBlock,
|
||||
Filter<Value, Users, fn(&Value) -> bool>,
|
||||
fn(Value) -> BasicBlock,
|
||||
>;
|
||||
|
||||
/// Wrapper for LLVM BasicBlockRef
|
||||
impl BasicBlock {
|
||||
|
|
@ -31,10 +36,13 @@ impl BasicBlock {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn pred_iter(self) -> Preds<'static> {
|
||||
pub fn pred_iter(self) -> Preds {
|
||||
fn is_a_terminator_inst(user: &Value) -> bool { user.is_a_terminator_inst() }
|
||||
fn get_parent(user: Value) -> BasicBlock { user.get_parent().unwrap() }
|
||||
|
||||
self.as_value().user_iter()
|
||||
.filter(|user| user.is_a_terminator_inst())
|
||||
.map(|user| user.get_parent().unwrap())
|
||||
.filter(is_a_terminator_inst)
|
||||
.map(get_parent)
|
||||
}
|
||||
|
||||
pub fn get_single_predecessor(self) -> Option<BasicBlock> {
|
||||
|
|
|
|||
|
|
@ -342,11 +342,13 @@ pub fn compute_abi_info(ccx: &CrateContext,
|
|||
atys: &[Type],
|
||||
rty: Type,
|
||||
ret_def: bool) -> FnType {
|
||||
fn x86_64_ty(ccx: &CrateContext,
|
||||
ty: Type,
|
||||
is_mem_cls: |cls: &[RegClass]| -> bool,
|
||||
ind_attr: Attribute)
|
||||
-> ArgType {
|
||||
fn x86_64_ty<F>(ccx: &CrateContext,
|
||||
ty: Type,
|
||||
is_mem_cls: F,
|
||||
ind_attr: Attribute)
|
||||
-> ArgType where
|
||||
F: FnOnce(&[RegClass]) -> bool,
|
||||
{
|
||||
if !ty.is_reg_ty() {
|
||||
let cls = classify_ty(ty);
|
||||
if is_mem_cls(cls.as_slice()) {
|
||||
|
|
|
|||
|
|
@ -781,15 +781,15 @@ pub fn trans_lang_call<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
|
|||
///
|
||||
/// For non-lang items, `dest` is always Some, and hence the result is written into memory
|
||||
/// somewhere. Nonetheless we return the actual return value of the function.
|
||||
pub fn trans_call_inner<'a, 'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
|
||||
call_info: Option<NodeInfo>,
|
||||
callee_ty: Ty<'tcx>,
|
||||
get_callee: |bcx: Block<'blk, 'tcx>,
|
||||
arg_cleanup_scope: cleanup::ScopeId|
|
||||
-> Callee<'blk, 'tcx>,
|
||||
args: CallArgs<'a, 'tcx>,
|
||||
dest: Option<expr::Dest>)
|
||||
-> Result<'blk, 'tcx> {
|
||||
pub fn trans_call_inner<'a, 'blk, 'tcx, F>(bcx: Block<'blk, 'tcx>,
|
||||
call_info: Option<NodeInfo>,
|
||||
callee_ty: Ty<'tcx>,
|
||||
get_callee: F,
|
||||
args: CallArgs<'a, 'tcx>,
|
||||
dest: Option<expr::Dest>)
|
||||
-> Result<'blk, 'tcx> where
|
||||
F: FnOnce(Block<'blk, 'tcx>, cleanup::ScopeId) -> Callee<'blk, 'tcx>,
|
||||
{
|
||||
// Introduce a temporary cleanup scope that will contain cleanups
|
||||
// for the arguments while they are being evaluated. The purpose
|
||||
// this cleanup is to ensure that, should a panic occur while
|
||||
|
|
|
|||
|
|
@ -527,7 +527,7 @@ impl<'blk, 'tcx> CleanupHelperMethods<'blk, 'tcx> for FunctionContext<'blk, 'tcx
|
|||
self.scopes.borrow_mut().pop().unwrap()
|
||||
}
|
||||
|
||||
fn top_scope<R>(&self, f: |&CleanupScope<'blk, 'tcx>| -> R) -> R {
|
||||
fn top_scope<R, F>(&self, f: F) -> R where F: FnOnce(&CleanupScope<'blk, 'tcx>) -> R {
|
||||
f(self.scopes.borrow().last().unwrap())
|
||||
}
|
||||
|
||||
|
|
@ -1145,5 +1145,5 @@ trait CleanupHelperMethods<'blk, 'tcx> {
|
|||
fn scopes_len(&self) -> uint;
|
||||
fn push_scope(&self, scope: CleanupScope<'blk, 'tcx>);
|
||||
fn pop_scope(&self) -> CleanupScope<'blk, 'tcx>;
|
||||
fn top_scope<R>(&self, f: |&CleanupScope<'blk, 'tcx>| -> R) -> R;
|
||||
fn top_scope<R, F>(&self, f: F) -> R where F: FnOnce(&CleanupScope<'blk, 'tcx>) -> R;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -113,15 +113,16 @@ pub fn immediate_rvalue_bcx<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
|
|||
/// it. The memory will be dropped upon exit from `scope`. The callback `populate` should
|
||||
/// initialize the memory. If `zero` is true, the space will be zeroed when it is allocated; this
|
||||
/// is not necessary unless `bcx` does not dominate the end of `scope`.
|
||||
pub fn lvalue_scratch_datum<'blk, 'tcx, A>(bcx: Block<'blk, 'tcx>,
|
||||
ty: Ty<'tcx>,
|
||||
name: &str,
|
||||
zero: bool,
|
||||
scope: cleanup::ScopeId,
|
||||
arg: A,
|
||||
populate: |A, Block<'blk, 'tcx>, ValueRef|
|
||||
-> Block<'blk, 'tcx>)
|
||||
-> DatumBlock<'blk, 'tcx, Lvalue> {
|
||||
pub fn lvalue_scratch_datum<'blk, 'tcx, A, F>(bcx: Block<'blk, 'tcx>,
|
||||
ty: Ty<'tcx>,
|
||||
name: &str,
|
||||
zero: bool,
|
||||
scope: cleanup::ScopeId,
|
||||
arg: A,
|
||||
populate: F)
|
||||
-> DatumBlock<'blk, 'tcx, Lvalue> where
|
||||
F: FnOnce(A, Block<'blk, 'tcx>, ValueRef) -> Block<'blk, 'tcx>,
|
||||
{
|
||||
let scratch = if zero {
|
||||
alloca_zeroed(bcx, ty, name)
|
||||
} else {
|
||||
|
|
@ -339,10 +340,10 @@ impl<'tcx> Datum<'tcx, Rvalue> {
|
|||
/// here since we can `match self.kind` rather than having to implement
|
||||
/// generic methods in `KindOps`.)
|
||||
impl<'tcx> Datum<'tcx, Expr> {
|
||||
fn match_kind<R>(self,
|
||||
if_lvalue: |Datum<'tcx, Lvalue>| -> R,
|
||||
if_rvalue: |Datum<'tcx, Rvalue>| -> R)
|
||||
-> R {
|
||||
fn match_kind<R, F, G>(self, if_lvalue: F, if_rvalue: G) -> R where
|
||||
F: FnOnce(Datum<'tcx, Lvalue>) -> R,
|
||||
G: FnOnce(Datum<'tcx, Rvalue>) -> R,
|
||||
{
|
||||
let Datum { val, ty, kind } = self;
|
||||
match kind {
|
||||
LvalueExpr => if_lvalue(Datum::new(val, ty, Lvalue)),
|
||||
|
|
@ -455,9 +456,11 @@ impl<'tcx> Datum<'tcx, Lvalue> {
|
|||
// datum may also be unsized _without the size information_. It is the
|
||||
// callers responsibility to package the result in some way to make a valid
|
||||
// datum in that case (e.g., by making a fat pointer or opened pair).
|
||||
pub fn get_element<'blk>(&self, bcx: Block<'blk, 'tcx>, ty: Ty<'tcx>,
|
||||
gep: |ValueRef| -> ValueRef)
|
||||
-> Datum<'tcx, Lvalue> {
|
||||
pub fn get_element<'blk, F>(&self, bcx: Block<'blk, 'tcx>, ty: Ty<'tcx>,
|
||||
gep: F)
|
||||
-> Datum<'tcx, Lvalue> where
|
||||
F: FnOnce(ValueRef) -> ValueRef,
|
||||
{
|
||||
let val = match self.ty.sty {
|
||||
_ if ty::type_is_sized(bcx.tcx(), self.ty) => gep(self.val),
|
||||
ty::ty_open(_) => {
|
||||
|
|
|
|||
|
|
@ -3212,13 +3212,13 @@ fn populate_scope_map(cx: &CrateContext,
|
|||
});
|
||||
|
||||
// local helper functions for walking the AST.
|
||||
fn with_new_scope(cx: &CrateContext,
|
||||
scope_span: Span,
|
||||
scope_stack: &mut Vec<ScopeStackEntry> ,
|
||||
scope_map: &mut NodeMap<DIScope>,
|
||||
inner_walk: |&CrateContext,
|
||||
&mut Vec<ScopeStackEntry> ,
|
||||
&mut NodeMap<DIScope>|) {
|
||||
fn with_new_scope<F>(cx: &CrateContext,
|
||||
scope_span: Span,
|
||||
scope_stack: &mut Vec<ScopeStackEntry> ,
|
||||
scope_map: &mut NodeMap<DIScope>,
|
||||
inner_walk: F) where
|
||||
F: FnOnce(&CrateContext, &mut Vec<ScopeStackEntry>, &mut NodeMap<DIScope>),
|
||||
{
|
||||
// Create a new lexical scope and push it onto the stack
|
||||
let loc = cx.sess().codemap().lookup_char_pos(scope_span.lo);
|
||||
let file_metadata = file_metadata(cx, loc.file.name.as_slice());
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue