Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unbox almost all the closures #19467

Merged
merged 92 commits into from
Dec 14, 2014
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
92 commits
Select commit Hold shift + click to select a range
56ecb51
libcore: use unboxed closures in `Option` methods
Nov 19, 2014
60b0dd5
librustc_trans: fix fallout
Dec 2, 2014
135c4ab
Fix compile fail tests
Dec 2, 2014
19524f1
libcore: use unboxed closures in `Result` methods
Dec 2, 2014
1646d10
libcore: use unboxed closures in the fields of `Map`
Dec 2, 2014
f91d87e
libcollections: fix fallout
Dec 2, 2014
0fcd730
librustrt: fix fallout
Dec 2, 2014
d22acb7
libstd: fix fallout
Dec 2, 2014
5e7469c
libsyntax: fix fallout
Dec 2, 2014
fd06ef2
librustc: fix fallout
Dec 2, 2014
44b419b
librustc_trans: fix fallout
Dec 2, 2014
801ae13
libcore: use unboxed closures in the fields of `Filter`
Dec 2, 2014
e66ba15
libunicode: fix fallout
Dec 2, 2014
80a04b1
librustc_trans: fix fallout
Dec 2, 2014
eede5d2
libcore: use unboxed closures in the fields of `FilterMap`
Dec 3, 2014
4f6f6af
libcollections: fix fallout
Dec 3, 2014
c3fe710
libstd: fix fallout
Dec 3, 2014
ca001e1
librustdoc: fix fallout
Dec 3, 2014
0cfdc99
libcore: use unboxed closures in the fields of `SkipWhile`
Dec 3, 2014
e2724cb
libcore: use unboxed closures in the fields of `TakeWhile`
Dec 3, 2014
ba480cb
libcore: use unboxed closures in the fields of `Scan`
Dec 3, 2014
a051ba1
libcore: use unboxed closures in the fields of `FlatMap`
Dec 3, 2014
7e3493e
libcore: use unboxed closures in the fields of `Inspect`
Dec 3, 2014
a50c587
libcoretest: fix fallout
Dec 3, 2014
216bcfd
libcore: use unboxed closures in the fields of `Unfold`
Dec 3, 2014
5e9ca5b
libcore: use unboxed closures in `IteratorExt` methods
Dec 4, 2014
fee500d
libregex: fix fallout
Dec 4, 2014
5a9047b
librustc: fix fallout
Dec 4, 2014
10a14d5
Fix run-pass tests
Dec 4, 2014
b3cd056
libcollections: fix unit tests
Dec 4, 2014
aa921b6
libcore: use unboxed closures in `ExactSizeIterator` methods
Dec 4, 2014
d3f5c13
libcore: impl CharEq for FnMut(char) -> bool implementors
Dec 4, 2014
50ef207
libunicode: fix fallout
Dec 4, 2014
cc242bc
libstd: fix fallout
Dec 4, 2014
4d4915a
librustdoc: fix fallout
Dec 4, 2014
6460835
libcollections: fix fallout in unit tests
Dec 5, 2014
47acce4
libcoretest: fix fallout in unit tests
Dec 5, 2014
30ea64e
libcore: fix fallout in doctests
Dec 5, 2014
9c70465
libcore: use unboxed closures in the fields of `Splits`
Dec 5, 2014
43cf7b4
libstd: fix fallout
Dec 5, 2014
6ae9b9e
libcore: use unboxed closures in the fields of `MutSplits`
Dec 5, 2014
e2a362f
libcore: use unboxed closures in `SlicePrelude` methods
Dec 5, 2014
f18b255
libcore: use unboxed closures in the `finally` module
Dec 5, 2014
40b3617
libstd: fix fallout
Dec 5, 2014
45860b5
Fix run pass test
Dec 5, 2014
8df27d2
libcoretest: fix fallout
Dec 5, 2014
950fbf4
librustrt: fix fallout
Dec 5, 2014
0b0c3e1
libcore: fix fallout in doc tests
Dec 5, 2014
1a87fc7
libcore: use unboxed closures in `Formatter` methods
Dec 5, 2014
02e7389
libcore: use unboxed closures in the `char` module
Dec 5, 2014
0d39fc0
libcollections: use unboxed closures in `TreeMap` methods
Dec 5, 2014
0055678
libcollections: use unboxed closures in `Bitv` methods
Dec 5, 2014
d5c3326
libcollections: use unboxed closures in `Vec` methods
Dec 5, 2014
6f19f8d
libcollections: use unboxed closures in `DList` methods
Dec 5, 2014
a7a065b
libcollections: use unboxed closures in `[Clone]SliceAllocPrelude` me…
Dec 5, 2014
683342c
libgraphviz: fix fallout
Dec 5, 2014
5579692
libcollections: use unboxed closures in `VecMap` methods
Dec 5, 2014
c7b6eb3
libcore: use unboxed closures in `float_to_str_bytes_common`
Dec 6, 2014
f56f972
libcore: use unboxed closures in `slice::raw` free functions
Dec 6, 2014
04652b5
libgetopts: use unboxed closures in `each_split_within`
Dec 6, 2014
5d7543b
libgraphviz: use unboxed closures in `LabelText` methods
Dec 6, 2014
533a47b
librand: use unboxed closures in `distributions` module
Dec 6, 2014
a8aff7e
libserialize: use unboxed closures
Dec 6, 2014
807c5e8
librbml: fix fallout
Dec 6, 2014
594ff51
librbml: use unboxed closures in free functions
Dec 6, 2014
01d2e46
librustc: fix fallout
Dec 6, 2014
61ba334
libregex: impl Replacer for FnMut(&Captures) -> String implementors
Dec 7, 2014
341e7bc
libregex: fix fallout in doc tests
Dec 8, 2014
1c5aac2
libarena: use unboxed closures
Dec 7, 2014
95d0763
libregex: use unboxed closures
Dec 7, 2014
9b075bc
libserialize: use unboxed closures
Dec 7, 2014
879ebce
libcollections: use unboxed closures
Dec 7, 2014
b44b5da
libregex_macros: use unboxed closures
Dec 7, 2014
be53d61
librustrt: use unboxed closures
Dec 7, 2014
cdbb3ca
libstd: use unboxed closures
Dec 7, 2014
2160427
Fix benches
Dec 8, 2014
0dac05d
libsyntax: use unboxed closures
Dec 8, 2014
d3d707c
librustc: fix fallout
Dec 8, 2014
451eef5
librustc_back: use unboxed closures
Dec 8, 2014
3739a24
librustc_trans: fix fallout
Dec 9, 2014
933e7b4
librustc_llvm: use unboxed closures
Dec 9, 2014
1195708
librustc: use unboxed closures
Dec 9, 2014
46272c1
librustc_typeck: fix fallout
Dec 9, 2014
0d4d8b9
librustc_trans: fix fallout
Dec 9, 2014
0676c3b
librustc_trans: use unboxed closures
Dec 9, 2014
888f249
librustdoc: use unboxed closures
Dec 9, 2014
521a6e6
librustc_typeck: use unboxed closures
Dec 9, 2014
015c0fc
librustc_driver: use unboxed closures
Dec 9, 2014
745225d
libtest: use unboxed closures
Dec 9, 2014
6f28816
Remove some unnecessary `move` keywords
Dec 13, 2014
db8300c
libstd: add missing imports
Dec 13, 2014
b8e0b81
librustc_borrowck: add `#![feature(unboxed_closures)]`
Dec 13, 2014
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 5 additions & 4 deletions src/libarena/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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>());
Expand Down Expand Up @@ -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) =
Expand All @@ -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)
Expand Down Expand Up @@ -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!();
});
}
Expand Down
44 changes: 32 additions & 12 deletions src/libcollections/bench.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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();

Expand All @@ -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);
Expand All @@ -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);
Expand All @@ -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);
Expand Down
24 changes: 16 additions & 8 deletions src/libcollections/bit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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));
Expand Down Expand Up @@ -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());

Expand Down Expand Up @@ -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
}
Expand All @@ -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)
Expand Down Expand Up @@ -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
}
Expand All @@ -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
}
Expand Down Expand Up @@ -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
}
Expand Down
14 changes: 10 additions & 4 deletions src/libcollections/btree/map.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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> {
Expand Down Expand Up @@ -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.
Expand All @@ -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.
Expand Down
34 changes: 23 additions & 11 deletions src/libcollections/btree/set.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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> {
Expand Down Expand Up @@ -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)
}
}

Expand Down Expand Up @@ -600,22 +603,31 @@ 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();

for x in a.iter() { assert!(set_a.insert(*x)) }
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());
}

Expand Down
20 changes: 9 additions & 11 deletions src/libcollections/dlist.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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`.
Expand All @@ -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 {
Expand Down
Loading