From 6d7a0c8cbcd81242d12ad41e0d13c2408c73c8ac Mon Sep 17 00:00:00 2001 From: blake2-ppc Date: Wed, 31 Jul 2013 21:07:44 +0200 Subject: [PATCH 01/10] std: Use `do` blocks instead of `for` with .iter_bytes() --- src/libstd/hash.rs | 75 +++++++++++++++++++++++++----------------- src/libstd/to_bytes.rs | 7 ++-- 2 files changed, 49 insertions(+), 33 deletions(-) diff --git a/src/libstd/hash.rs b/src/libstd/hash.rs index 16d138d4e1fbe..5d4b9b4e3f0ba 100644 --- a/src/libstd/hash.rs +++ b/src/libstd/hash.rs @@ -85,9 +85,10 @@ impl Hash for A { #[inline] fn hash_keyed(&self, k0: u64, k1: u64) -> u64 { let mut s = State::new(k0, k1); - for self.iter_bytes(true) |bytes| { + do self.iter_bytes(true) |bytes| { s.input(bytes); - } + true + }; s.result_u64() } } @@ -95,12 +96,14 @@ impl Hash for A { fn hash_keyed_2(a: &A, b: &B, k0: u64, k1: u64) -> u64 { let mut s = State::new(k0, k1); - for a.iter_bytes(true) |bytes| { + do a.iter_bytes(true) |bytes| { s.input(bytes); - } - for b.iter_bytes(true) |bytes| { + true + }; + do b.iter_bytes(true) |bytes| { s.input(bytes); - } + true + }; s.result_u64() } @@ -108,15 +111,18 @@ fn hash_keyed_3(a: &A, b: &B, c: &C, k0: u64, k1: u64) -> u64 { let mut s = State::new(k0, k1); - for a.iter_bytes(true) |bytes| { + do a.iter_bytes(true) |bytes| { s.input(bytes); - } - for b.iter_bytes(true) |bytes| { + true + }; + do b.iter_bytes(true) |bytes| { s.input(bytes); - } - for c.iter_bytes(true) |bytes| { + true + }; + do c.iter_bytes(true) |bytes| { s.input(bytes); - } + true + }; s.result_u64() } @@ -132,18 +138,22 @@ fn hash_keyed_4 u64 { let mut s = State::new(k0, k1); - for a.iter_bytes(true) |bytes| { + do a.iter_bytes(true) |bytes| { s.input(bytes); - } - for b.iter_bytes(true) |bytes| { + true + }; + do b.iter_bytes(true) |bytes| { s.input(bytes); - } - for c.iter_bytes(true) |bytes| { + true + }; + do c.iter_bytes(true) |bytes| { s.input(bytes); - } - for d.iter_bytes(true) |bytes| { + true + }; + do d.iter_bytes(true) |bytes| { s.input(bytes); - } + true + }; s.result_u64() } @@ -161,21 +171,26 @@ fn hash_keyed_5 u64 { let mut s = State::new(k0, k1); - for a.iter_bytes(true) |bytes| { + do a.iter_bytes(true) |bytes| { s.input(bytes); - } - for b.iter_bytes(true) |bytes| { + true + }; + do b.iter_bytes(true) |bytes| { s.input(bytes); - } - for c.iter_bytes(true) |bytes| { + true + }; + do c.iter_bytes(true) |bytes| { s.input(bytes); - } - for d.iter_bytes(true) |bytes| { + true + }; + do d.iter_bytes(true) |bytes| { s.input(bytes); - } - for e.iter_bytes(true) |bytes| { + true + }; + do e.iter_bytes(true) |bytes| { s.input(bytes); - } + true + }; s.result_u64() } diff --git a/src/libstd/to_bytes.rs b/src/libstd/to_bytes.rs index 60df31fd4ca8c..5ad7969c8d21f 100644 --- a/src/libstd/to_bytes.rs +++ b/src/libstd/to_bytes.rs @@ -353,9 +353,10 @@ pub trait ToBytes { impl ToBytes for A { fn to_bytes(&self, lsb0: bool) -> ~[u8] { do io::with_bytes_writer |wr| { - for self.iter_bytes(lsb0) |bytes| { - wr.write(bytes) - } + do self.iter_bytes(lsb0) |bytes| { + wr.write(bytes); + true + }; } } } From 02bdf90cf6509f0f308ce133551a833c264b8960 Mon Sep 17 00:00:00 2001 From: blake2-ppc Date: Wed, 31 Jul 2013 21:07:44 +0200 Subject: [PATCH 02/10] extra: Use `do` instead of `for` in extra::iter --- src/libextra/iter.rs | 41 ++++++++++++++++++++++------------------- 1 file changed, 22 insertions(+), 19 deletions(-) diff --git a/src/libextra/iter.rs b/src/libextra/iter.rs index 3552ff59783a9..720a525164a32 100644 --- a/src/libextra/iter.rs +++ b/src/libextra/iter.rs @@ -72,12 +72,9 @@ pub trait FromIter { #[inline] pub fn any(predicate: &fn(T) -> bool, iter: &fn(f: &fn(T) -> bool) -> bool) -> bool { - for iter |x| { - if predicate(x) { - return true; - } + do iter |x| { + predicate(x) } - return false; } /** @@ -111,12 +108,14 @@ pub fn all(predicate: &fn(T) -> bool, #[inline] pub fn find(predicate: &fn(&T) -> bool, iter: &fn(f: &fn(T) -> bool) -> bool) -> Option { - for iter |x| { + let mut ret = None; + do iter |x| { if predicate(&x) { - return Some(x); - } - } - None + ret = Some(x); + false + } else { true } + }; + ret } /** @@ -132,7 +131,7 @@ pub fn find(predicate: &fn(&T) -> bool, #[inline] pub fn max(iter: &fn(f: &fn(T) -> bool) -> bool) -> Option { let mut result = None; - for iter |x| { + do iter |x| { match result { Some(ref mut y) => { if x > *y { @@ -141,7 +140,8 @@ pub fn max(iter: &fn(f: &fn(T) -> bool) -> bool) -> Option { } None => result = Some(x) } - } + true + }; result } @@ -158,7 +158,7 @@ pub fn max(iter: &fn(f: &fn(T) -> bool) -> bool) -> Option { #[inline] pub fn min(iter: &fn(f: &fn(T) -> bool) -> bool) -> Option { let mut result = None; - for iter |x| { + do iter |x| { match result { Some(ref mut y) => { if x < *y { @@ -167,7 +167,8 @@ pub fn min(iter: &fn(f: &fn(T) -> bool) -> bool) -> Option { } None => result = Some(x) } - } + true + }; result } @@ -183,9 +184,10 @@ pub fn min(iter: &fn(f: &fn(T) -> bool) -> bool) -> Option { #[inline] pub fn fold(start: T, iter: &fn(f: &fn(U) -> bool) -> bool, f: &fn(&mut T, U)) -> T { let mut result = start; - for iter |x| { + do iter |x| { f(&mut result, x); - } + true + }; result } @@ -206,9 +208,10 @@ pub fn fold(start: T, iter: &fn(f: &fn(U) -> bool) -> bool, f: &fn(&mut T, #[inline] pub fn fold_ref(start: T, iter: &fn(f: &fn(&U) -> bool) -> bool, f: &fn(&mut T, &U)) -> T { let mut result = start; - for iter |x| { + do iter |x| { f(&mut result, x); - } + true + }; result } @@ -246,7 +249,7 @@ impl FromIter for ~[T]{ #[inline] pub fn from_iter(iter: &fn(f: &fn(T) -> bool) -> bool) -> ~[T] { let mut v = ~[]; - for iter |x| { v.push(x) } + do iter |x| { v.push(x); true }; v } } From b18bd785ec489c5c0ae9f84e8144a37e414cdee5 Mon Sep 17 00:00:00 2001 From: blake2-ppc Date: Wed, 31 Jul 2013 21:07:44 +0200 Subject: [PATCH 03/10] std: Replace `for` with `do { .. }` expr where internal iterators are used --- src/libextra/serialize.rs | 10 ++++--- src/libstd/cleanup.rs | 15 ++++++---- src/libstd/hashmap.rs | 35 +++++++++++----------- src/libstd/io.rs | 17 +++++------ src/libstd/os.rs | 3 +- src/libstd/task/spawn.rs | 3 +- src/libstd/trie.rs | 51 +++++++++++++++++++-------------- src/libstd/vec.rs | 33 ++++++++++++--------- src/test/run-pass/issue-2904.rs | 7 +++-- 9 files changed, 96 insertions(+), 78 deletions(-) diff --git a/src/libextra/serialize.rs b/src/libextra/serialize.rs index 0c8821e753e3a..95f3af006e8cc 100644 --- a/src/libextra/serialize.rs +++ b/src/libextra/serialize.rs @@ -784,11 +784,12 @@ impl< fn encode(&self, e: &mut E) { do e.emit_map(self.len()) |e| { let mut i = 0; - for self.each |key, val| { + do self.each |key, val| { e.emit_map_elt_key(i, |e| key.encode(e)); e.emit_map_elt_val(i, |e| val.encode(e)); i += 1; - } + true + }; } } } @@ -814,10 +815,11 @@ impl Encodable for TrieSet { fn encode(&self, s: &mut S) { do s.emit_seq(self.len()) |s| { let mut i = 0; - for self.each |e| { + do self.each |e| { s.emit_seq_elt(i, |s| e.encode(s)); i += 1; - } + true + }; } } } diff --git a/src/libstd/cleanup.rs b/src/libstd/cleanup.rs index ed2b0e1681817..24ca6fc23091d 100644 --- a/src/libstd/cleanup.rs +++ b/src/libstd/cleanup.rs @@ -94,27 +94,29 @@ pub unsafe fn annihilate() { // // In this pass, nothing gets freed, so it does not matter whether // we read the next field before or after the callback. - for each_live_alloc(true) |box, uniq| { + do each_live_alloc(true) |box, uniq| { stats.n_total_boxes += 1; if uniq { stats.n_unique_boxes += 1; } else { (*box).ref_count = managed::RC_IMMORTAL; } - } + true + }; // Pass 2: Drop all boxes. // // In this pass, unique-managed boxes may get freed, but not // managed boxes, so we must read the `next` field *after* the // callback, as the original value may have been freed. - for each_live_alloc(false) |box, uniq| { + do each_live_alloc(false) |box, uniq| { if !uniq { let tydesc = (*box).type_desc; let data = &(*box).data as *(); ((*tydesc).drop_glue)(data as *i8); } - } + true + }; // Pass 3: Free all boxes. // @@ -122,14 +124,15 @@ pub unsafe fn annihilate() { // unique-managed boxes, though I think that none of those are // left), so we must read the `next` field before, since it will // not be valid after. - for each_live_alloc(true) |box, uniq| { + do each_live_alloc(true) |box, uniq| { if !uniq { stats.n_bytes_freed += (*((*box).type_desc)).size + sys::size_of::>(); local_free(box as *i8); } - } + true + }; if debug_mem() { // We do logging here w/o allocation. diff --git a/src/libstd/hashmap.rs b/src/libstd/hashmap.rs index b162869201d39..8c06f23b8c191 100644 --- a/src/libstd/hashmap.rs +++ b/src/libstd/hashmap.rs @@ -130,15 +130,17 @@ impl HashMap { hash: uint, k: &K) -> SearchResult { - for self.bucket_sequence(hash) |i| { + let mut ret = TableFull; + do self.bucket_sequence(hash) |i| { match self.buckets[i] { - Some(ref bkt) => if bkt.hash == hash && *k == bkt.key { - return FoundEntry(i); + Some(ref bkt) if bkt.hash == hash && *k == bkt.key => { + ret = FoundEntry(i); false }, - None => return FoundHole(i) + None => { ret = FoundHole(i); false } + _ => true, } - } - TableFull + }; + ret } #[inline] @@ -146,17 +148,17 @@ impl HashMap { hash: uint, k: &Q) -> SearchResult { - for self.bucket_sequence(hash) |i| { + let mut ret = TableFull; + do self.bucket_sequence(hash) |i| { match self.buckets[i] { - Some(ref bkt) => { - if bkt.hash == hash && k.equiv(&bkt.key) { - return FoundEntry(i); - } + Some(ref bkt) if bkt.hash == hash && k.equiv(&bkt.key) => { + ret = FoundEntry(i); false }, - None => return FoundHole(i) + None => { ret = FoundHole(i); false } + _ => true, } - } - TableFull + }; + ret } /// Expand the capacity of the array to the next power of two @@ -272,11 +274,6 @@ impl HashMap { value } - - fn search(&self, hash: uint, - op: &fn(x: &Option>) -> bool) { - let _ = self.bucket_sequence(hash, |i| op(&self.buckets[i])); - } } impl Container for HashMap { diff --git a/src/libstd/io.rs b/src/libstd/io.rs index cef183d04291d..153286a311a9c 100644 --- a/src/libstd/io.rs +++ b/src/libstd/io.rs @@ -770,9 +770,10 @@ impl ReaderUtil for T { fn read_lines(&self) -> ~[~str] { do vec::build |push| { - for self.each_line |line| { + do self.each_line |line| { push(line.to_owned()); - } + true + }; } } @@ -1880,16 +1881,16 @@ mod tests { { let file = io::file_reader(&path).unwrap(); - for file.each_byte() |_| { - fail!("must be empty"); - } + do file.each_byte() |_| { + fail!("must be empty") + }; } { let file = io::file_reader(&path).unwrap(); - for file.each_char() |_| { - fail!("must be empty"); - } + do file.each_char() |_| { + fail!("must be empty") + }; } } diff --git a/src/libstd/os.rs b/src/libstd/os.rs index 3afd946ee264b..1bfae8c40e16f 100644 --- a/src/libstd/os.rs +++ b/src/libstd/os.rs @@ -790,7 +790,7 @@ pub fn list_dir_path(p: &Path) -> ~[Path] { /// all its contents. Use carefully! pub fn remove_dir_recursive(p: &Path) -> bool { let mut error_happened = false; - for walk_dir(p) |inner| { + do walk_dir(p) |inner| { if !error_happened { if path_is_dir(inner) { if !remove_dir_recursive(inner) { @@ -803,6 +803,7 @@ pub fn remove_dir_recursive(p: &Path) -> bool { } } } + true }; // Directory should now be empty !error_happened && remove_dir(p) diff --git a/src/libstd/task/spawn.rs b/src/libstd/task/spawn.rs index 81db5e690a66f..4558f8e32c1e1 100644 --- a/src/libstd/task/spawn.rs +++ b/src/libstd/task/spawn.rs @@ -372,8 +372,9 @@ impl Drop for Taskgroup { // with our own taskgroup, so long as both happen before we die. // We remove ourself from every ancestor we can, so no cleanup; no // break. - for each_ancestor(&mut this.ancestors, |_| {}) |ancestor_group| { + do each_ancestor(&mut this.ancestors, |_| {}) |ancestor_group| { leave_taskgroup(ancestor_group, &me, false); + true }; } } diff --git a/src/libstd/trie.rs b/src/libstd/trie.rs index 704e3a500f12b..f60093ce48c6c 100644 --- a/src/libstd/trie.rs +++ b/src/libstd/trie.rs @@ -459,11 +459,12 @@ mod test_map { assert!(m.insert(1, 2)); let mut n = 0; - for m.each |k, v| { + do m.each |k, v| { assert_eq!(*k, n); assert_eq!(*v, n * 2); n += 1; - } + true + }; } #[test] @@ -475,14 +476,16 @@ mod test_map { } let mut n = uint::max_value - 10000; - for m.each |k, v| { - if n == uint::max_value - 5000 { break } - assert!(n < uint::max_value - 5000); - - assert_eq!(*k, n); - assert_eq!(*v, n / 2); - n += 1; - } + do m.each |k, v| { + if n == uint::max_value - 5000 { false } else { + assert!(n < uint::max_value - 5000); + + assert_eq!(*k, n); + assert_eq!(*v, n / 2); + n += 1; + true + } + }; } #[test] @@ -496,11 +499,12 @@ mod test_map { assert!(m.insert(1, 2)); let mut n = 4; - for m.each_reverse |k, v| { + do m.each_reverse |k, v| { assert_eq!(*k, n); assert_eq!(*v, n * 2); n -= 1; - } + true + }; } #[test] @@ -512,14 +516,16 @@ mod test_map { } let mut n = uint::max_value - 1; - for m.each_reverse |k, v| { - if n == uint::max_value - 5000 { break } - assert!(n > uint::max_value - 5000); - - assert_eq!(*k, n); - assert_eq!(*v, n / 2); - n -= 1; - } + do m.each_reverse |k, v| { + if n == uint::max_value - 5000 { false } else { + assert!(n > uint::max_value - 5000); + + assert_eq!(*k, n); + assert_eq!(*v, n / 2); + n -= 1; + true + } + }; } #[test] @@ -572,10 +578,11 @@ mod test_set { let mut i = 0; - for trie.each |x| { + do trie.each |x| { assert_eq!(expected[i], *x); i += 1; - } + true + }; } #[test] diff --git a/src/libstd/vec.rs b/src/libstd/vec.rs index 534dc27196c30..6cff9ce84cf18 100644 --- a/src/libstd/vec.rs +++ b/src/libstd/vec.rs @@ -2767,19 +2767,19 @@ mod tests { let mut results: ~[~[int]]; results = ~[]; - for each_permutation([]) |v| { results.push(v.to_owned()); } + do each_permutation([]) |v| { results.push(v.to_owned()); true }; assert_eq!(results, ~[~[]]); results = ~[]; - for each_permutation([7]) |v| { results.push(v.to_owned()); } + do each_permutation([7]) |v| { results.push(v.to_owned()); true }; assert_eq!(results, ~[~[7]]); results = ~[]; - for each_permutation([1,1]) |v| { results.push(v.to_owned()); } + do each_permutation([1,1]) |v| { results.push(v.to_owned()); true }; assert_eq!(results, ~[~[1,1],~[1,1]]); results = ~[]; - for each_permutation([5,2,0]) |v| { results.push(v.to_owned()); } + do each_permutation([5,2,0]) |v| { results.push(v.to_owned()); true }; assert!(results == ~[~[5,2,0],~[5,0,2],~[2,5,0],~[2,0,5],~[0,5,2],~[0,2,5]]); } @@ -3107,12 +3107,13 @@ mod tests { fn test_permute_fail() { let v = [(~0, @0), (~0, @0), (~0, @0), (~0, @0)]; let mut i = 0; - for each_permutation(v) |_elt| { + do each_permutation(v) |_elt| { if i == 2 { fail!() } i += 0; - } + true + }; } #[test] @@ -3425,9 +3426,10 @@ mod tests { fn test_permutations0() { let values = []; let mut v : ~[~[int]] = ~[]; - for each_permutation(values) |p| { + do each_permutation(values) |p| { v.push(p.to_owned()); - } + true + }; assert_eq!(v, ~[~[]]); } @@ -3435,9 +3437,10 @@ mod tests { fn test_permutations1() { let values = [1]; let mut v : ~[~[int]] = ~[]; - for each_permutation(values) |p| { + do each_permutation(values) |p| { v.push(p.to_owned()); - } + true + }; assert_eq!(v, ~[~[1]]); } @@ -3445,9 +3448,10 @@ mod tests { fn test_permutations2() { let values = [1,2]; let mut v : ~[~[int]] = ~[]; - for each_permutation(values) |p| { + do each_permutation(values) |p| { v.push(p.to_owned()); - } + true + }; assert_eq!(v, ~[~[1,2],~[2,1]]); } @@ -3455,9 +3459,10 @@ mod tests { fn test_permutations3() { let values = [1,2,3]; let mut v : ~[~[int]] = ~[]; - for each_permutation(values) |p| { + do each_permutation(values) |p| { v.push(p.to_owned()); - } + true + }; assert_eq!(v, ~[~[1,2,3],~[1,3,2],~[2,1,3],~[2,3,1],~[3,1,2],~[3,2,1]]); } diff --git a/src/test/run-pass/issue-2904.rs b/src/test/run-pass/issue-2904.rs index 092d5e5813bc5..b86ad6d56f826 100644 --- a/src/test/run-pass/issue-2904.rs +++ b/src/test/run-pass/issue-2904.rs @@ -65,13 +65,14 @@ fn square_from_char(c: char) -> square { fn read_board_grid(input: rdr) -> ~[~[square]] { let input = @input as @io::Reader; let mut grid = ~[]; - for input.each_line |line| { + do input.each_line |line| { let mut row = ~[]; foreach c in line.iter() { row.push(square_from_char(c)) } - grid.push(row) - } + grid.push(row); + true + }; let width = grid[0].len(); foreach row in grid.iter() { assert!(row.len() == width) } grid From dbcb74e247b892a5174524bbbafbe93c51c53f65 Mon Sep 17 00:00:00 2001 From: blake2-ppc Date: Wed, 31 Jul 2013 21:07:44 +0200 Subject: [PATCH 04/10] extra: Replace `for` with `do { .. }` expr where internal iterators are used --- src/libextra/arena.rs | 5 +++-- src/libextra/bitv.rs | 45 +++++++++++++++++++++++------------------ src/libextra/getopts.rs | 7 ++++--- src/libextra/list.rs | 9 +++++---- src/libextra/treemap.rs | 17 +++++++++------- 5 files changed, 47 insertions(+), 36 deletions(-) diff --git a/src/libextra/arena.rs b/src/libextra/arena.rs index efe1d47563e84..31acb5bd49873 100644 --- a/src/libextra/arena.rs +++ b/src/libextra/arena.rs @@ -72,11 +72,12 @@ impl Drop for Arena { fn drop(&self) { unsafe { destroy_chunk(&self.head); - for self.chunks.each |chunk| { + do self.chunks.each |chunk| { if !chunk.is_pod { destroy_chunk(chunk); } - } + true + }; } } } diff --git a/src/libextra/bitv.rs b/src/libextra/bitv.rs index 4d2d5635effe9..c2ea2dee82cfc 100644 --- a/src/libextra/bitv.rs +++ b/src/libextra/bitv.rs @@ -646,9 +646,10 @@ impl BitvSet { /// Creates a new bit vector set from the given bit vector pub fn from_bitv(bitv: Bitv) -> BitvSet { let mut size = 0; - for bitv.ones |_| { + do bitv.ones |_| { size += 1; - } + true + }; let Bitv{rep, _} = bitv; match rep { Big(b) => BitvSet{ size: size, bitv: b }, @@ -1354,18 +1355,18 @@ mod tests { fn test_small_clear() { let mut b = Bitv::new(14, true); b.clear(); - for b.ones |i| { - fail!("found 1 at %?", i); - } + do b.ones |i| { + fail!("found 1 at %?", i) + }; } #[test] fn test_big_clear() { let mut b = Bitv::new(140, true); b.clear(); - for b.ones |i| { - fail!("found 1 at %?", i); - } + do b.ones |i| { + fail!("found 1 at %?", i) + }; } #[test] @@ -1400,10 +1401,11 @@ mod tests { let mut i = 0; let expected = [3, 5, 11, 77]; - for a.intersection(&b) |x| { + do a.intersection(&b) |x| { assert_eq!(*x, expected[i]); - i += 1 - } + i += 1; + true + }; assert_eq!(i, expected.len()); } @@ -1423,10 +1425,11 @@ mod tests { let mut i = 0; let expected = [1, 5, 500]; - for a.difference(&b) |x| { + do a.difference(&b) |x| { assert_eq!(*x, expected[i]); - i += 1 - } + i += 1; + true + }; assert_eq!(i, expected.len()); } @@ -1448,10 +1451,11 @@ mod tests { let mut i = 0; let expected = [1, 5, 11, 14, 220]; - for a.symmetric_difference(&b) |x| { + do a.symmetric_difference(&b) |x| { assert_eq!(*x, expected[i]); - i += 1 - } + i += 1; + true + }; assert_eq!(i, expected.len()); } @@ -1476,10 +1480,11 @@ mod tests { let mut i = 0; let expected = [1, 3, 5, 9, 11, 13, 19, 24, 160]; - for a.union(&b) |x| { + do a.union(&b) |x| { assert_eq!(*x, expected[i]); - i += 1 - } + i += 1; + true + }; assert_eq!(i, expected.len()); } diff --git a/src/libextra/getopts.rs b/src/libextra/getopts.rs index b0e6f82322b61..e50693236fd98 100644 --- a/src/libextra/getopts.rs +++ b/src/libextra/getopts.rs @@ -678,9 +678,10 @@ pub mod groups { // FIXME: #5516 let mut desc_rows = ~[]; - for each_split_within(desc_normalized_whitespace, 54) |substr| { + do each_split_within(desc_normalized_whitespace, 54) |substr| { desc_rows.push(substr.to_owned()); - } + true + }; // FIXME: #5516 // wrapped description @@ -780,7 +781,7 @@ pub mod groups { priv fn test_split_within() { fn t(s: &str, i: uint, u: &[~str]) { let mut v = ~[]; - for each_split_within(s, i) |s| { v.push(s.to_owned()) } + do each_split_within(s, i) |s| { v.push(s.to_owned()); true }; assert!(v.iter().zip(u.iter()).all(|(a,b)| a == b)); } t("", 0, []); diff --git a/src/libextra/list.rs b/src/libextra/list.rs index 8f7ade7228b02..0e8c50ac87302 100644 --- a/src/libextra/list.rs +++ b/src/libextra/list.rs @@ -70,10 +70,11 @@ pub fn find(ls: @List, f: &fn(&T) -> bool) -> Option { /// Returns true if a list contains an element with the given value pub fn has(ls: @List, elt: T) -> bool { - for each(ls) |e| { - if *e == elt { return true; } - } - return false; + let mut found = false; + do each(ls) |e| { + if *e == elt { found = true; false } else { true } + }; + return found; } /// Returns true if the list is empty diff --git a/src/libextra/treemap.rs b/src/libextra/treemap.rs index 50ad5c77fbac9..4e66870a9473f 100644 --- a/src/libextra/treemap.rs +++ b/src/libextra/treemap.rs @@ -1001,11 +1001,12 @@ mod test_treemap { assert!(m.insert(1, 2)); let mut n = 4; - for m.each_reverse |k, v| { + do m.each_reverse |k, v| { assert_eq!(*k, n); assert_eq!(*v, n * 2); n -= 1; - } + true + }; } #[test] @@ -1277,10 +1278,11 @@ mod test_set { assert!(m.insert(1)); let mut n = 4; - for m.each_reverse |x| { + do m.each_reverse |x| { assert_eq!(*x, n); - n -= 1 - } + n -= 1; + true + }; } fn check(a: &[int], b: &[int], expected: &[int], @@ -1292,10 +1294,11 @@ mod test_set { foreach y in b.iter() { assert!(set_b.insert(*y)) } let mut i = 0; - for f(&set_a, &set_b) |x| { + do f(&set_a, &set_b) |x| { assert_eq!(*x, expected[i]); i += 1; - } + true + }; assert_eq!(i, expected.len()); } From 310e0b6e92e2a5c48a96a0b5c0951d77e402dd75 Mon Sep 17 00:00:00 2001 From: blake2-ppc Date: Wed, 31 Jul 2013 21:07:44 +0200 Subject: [PATCH 05/10] extra: Use external iterators in bitv implementation Convert some internally used functions to use a external iterators. Change all uses of remaining internal iterators to use `do` expr --- src/libextra/bitv.rs | 88 +++++++++++++++++++++++++++----------------- 1 file changed, 55 insertions(+), 33 deletions(-) diff --git a/src/libextra/bitv.rs b/src/libextra/bitv.rs index c2ea2dee82cfc..44e5ca56c436a 100644 --- a/src/libextra/bitv.rs +++ b/src/libextra/bitv.rs @@ -12,7 +12,8 @@ use std::cmp; -use std::iterator::{DoubleEndedIterator, RandomAccessIterator, Invert}; +use std::iterator::RandomAccessIterator; +use std::iterator::{Invert, Enumerate}; use std::num; use std::ops; use std::uint; @@ -164,7 +165,7 @@ impl BigBitv { } #[inline] - pub fn negate(&mut self) { for self.each_storage |w| { *w = !*w } } + pub fn negate(&mut self) { do self.each_storage |w| { *w = !*w; true }; } #[inline] pub fn union(&mut self, b: &BigBitv, nbits: uint) -> bool { @@ -723,12 +724,12 @@ impl cmp::Eq for BitvSet { if self.size != other.size { return false; } - for self.each_common(other) |_, w1, w2| { + for self.common_iter(other).advance |(_, w1, w2)| { if w1 != w2 { return false; } } - for self.each_outlier(other) |_, _, w| { + for self.outlier_iter(other).advance |(_, _, w)| { if w != 0 { return false; } @@ -746,7 +747,7 @@ impl Container for BitvSet { impl Mutable for BitvSet { fn clear(&mut self) { - for self.bitv.each_storage |w| { *w = 0; } + do self.bitv.each_storage |w| { *w = 0; true }; self.size = 0; } } @@ -757,14 +758,13 @@ impl Set for BitvSet { } fn is_disjoint(&self, other: &BitvSet) -> bool { - for self.intersection(other) |_| { - return false; + do self.intersection(other) |_| { + false } - return true; } fn is_subset(&self, other: &BitvSet) -> bool { - for self.each_common(other) |_, w1, w2| { + for self.common_iter(other).advance |(_, w1, w2)| { if w1 & w2 != w1 { return false; } @@ -772,7 +772,7 @@ impl Set for BitvSet { /* If anything is not ours, then everything is not ours so we're definitely a subset in that case. Otherwise if there's any stray ones that 'other' doesn't have, we're not a subset. */ - for self.each_outlier(other) |mine, _, w| { + for self.outlier_iter(other).advance |(mine, _, w)| { if !mine { return true; } else if w != 0 { @@ -787,38 +787,38 @@ impl Set for BitvSet { } fn difference(&self, other: &BitvSet, f: &fn(&uint) -> bool) -> bool { - for self.each_common(other) |i, w1, w2| { + for self.common_iter(other).advance |(i, w1, w2)| { if !iterate_bits(i, w1 & !w2, |b| f(&b)) { return false; } } /* everything we have that they don't also shows up */ - self.each_outlier(other, |mine, i, w| + self.outlier_iter(other).advance(|(mine, i, w)| !mine || iterate_bits(i, w, |b| f(&b)) ) } fn symmetric_difference(&self, other: &BitvSet, f: &fn(&uint) -> bool) -> bool { - for self.each_common(other) |i, w1, w2| { + for self.common_iter(other).advance |(i, w1, w2)| { if !iterate_bits(i, w1 ^ w2, |b| f(&b)) { return false; } } - self.each_outlier(other, |_, i, w| iterate_bits(i, w, |b| f(&b))) + self.outlier_iter(other).advance(|(_, i, w)| iterate_bits(i, w, |b| f(&b))) } fn intersection(&self, other: &BitvSet, f: &fn(&uint) -> bool) -> bool { - self.each_common(other, |i, w1, w2| iterate_bits(i, w1 & w2, |b| f(&b))) + self.common_iter(other).advance(|(i, w1, w2)| iterate_bits(i, w1 & w2, |b| f(&b))) } fn union(&self, other: &BitvSet, f: &fn(&uint) -> bool) -> bool { - for self.each_common(other) |i, w1, w2| { + for self.common_iter(other).advance |(i, w1, w2)| { if !iterate_bits(i, w1 | w2, |b| f(&b)) { return false; } } - self.each_outlier(other, |_, i, w| iterate_bits(i, w, |b| f(&b))) + self.outlier_iter(other).advance(|(_, i, w)| iterate_bits(i, w, |b| f(&b))) } } @@ -861,13 +861,14 @@ impl BitvSet { /// both have in common. The three yielded arguments are (bit location, /// w1, w2) where the bit location is the number of bits offset so far, /// and w1/w2 are the words coming from the two vectors self, other. - fn each_common(&self, other: &BitvSet, - f: &fn(uint, uint, uint) -> bool) -> bool { + fn common_iter<'a>(&'a self, other: &'a BitvSet) + -> MapE<(uint,&uint),(uint,uint,uint), &'a ~[uint],Enumerate>> { let min = num::min(self.bitv.storage.len(), other.bitv.storage.len()); - self.bitv.storage.slice(0, min).iter().enumerate().advance(|(i, &w)| { - f(i * uint::bits, w, other.bitv.storage[i]) - }) + MapE{iter: self.bitv.storage.slice(0, min).iter().enumerate(), + env: &other.bitv.storage, + f: |(i, &w): (uint, &uint), o_store| (i * uint::bits, w, o_store[i]) + } } /// Visits each word in self or other that extends beyond the other. This @@ -877,24 +878,45 @@ impl BitvSet { /// The yielded arguments are a bool, the bit offset, and a word. The bool /// is true if the word comes from 'self', and false if it comes from /// 'other'. - fn each_outlier(&self, other: &BitvSet, - f: &fn(bool, uint, uint) -> bool) -> bool { + fn outlier_iter<'a>(&'a self, other: &'a BitvSet) + -> MapE<(uint, &uint),(bool, uint, uint), uint, Enumerate>> { let len1 = self.bitv.storage.len(); let len2 = other.bitv.storage.len(); let min = num::min(len1, len2); - /* only one of these loops will execute and that's the point */ - foreach (i, &w) in self.bitv.storage.slice(min, len1).iter().enumerate() { - if !f(true, (i + min) * uint::bits, w) { - return false; + if min < len1 { + MapE{iter: self.bitv.storage.slice(min, len1).iter().enumerate(), + env: min, + f: |(i, &w): (uint, &uint), min| (true, (i + min) * uint::bits, w) } - } - foreach (i, &w) in other.bitv.storage.slice(min, len2).iter().enumerate() { - if !f(false, (i + min) * uint::bits, w) { - return false; + } else { + MapE{iter: other.bitv.storage.slice(min, len2).iter().enumerate(), + env: min, + f: |(i, &w): (uint, &uint), min| (false, (i + min) * uint::bits, w) } } - return true; + } +} + +/// Like iterator::Map with explicit env capture +struct MapE { + priv env: Env, + priv f: &'static fn(A, Env) -> B, + priv iter: I, +} + +impl<'self, A, B, Env: Clone, I: Iterator> Iterator for MapE { + #[inline] + fn next(&mut self) -> Option { + match self.iter.next() { + Some(elt) => Some((self.f)(elt, self.env.clone())), + None => None + } + } + + #[inline] + fn size_hint(&self) -> (uint, Option) { + self.iter.size_hint() } } From e5a64f2adddd1ed2ec8e92ec94658b24ece4dbfc Mon Sep 17 00:00:00 2001 From: blake2-ppc Date: Wed, 31 Jul 2013 21:07:45 +0200 Subject: [PATCH 06/10] std: Remove the internal iterator methods from trait Set .intersection(), .union() etc methods in trait std::container::Set use internal iters. Remove these methods from the trait. I reported issue #8154 for the reinstatement of iterator-based set algebra methods to the Set trait. For bitv and treemap, that lack Iterator implementations of set operations, preserve them as methods directly on the types themselves. For HashSet, these methods are replaced by the present .union_iter() etc. --- src/libextra/bitv.rs | 70 ++++++++++++++++++++--------------------- src/libextra/treemap.rs | 70 ++++++++++++++++++++--------------------- src/libstd/container.rs | 12 +------ src/libstd/hashmap.rs | 22 ------------- 4 files changed, 71 insertions(+), 103 deletions(-) diff --git a/src/libextra/bitv.rs b/src/libextra/bitv.rs index 44e5ca56c436a..85002029fc607 100644 --- a/src/libextra/bitv.rs +++ b/src/libextra/bitv.rs @@ -717,6 +717,41 @@ impl BitvSet { pub fn iter<'a>(&'a self) -> BitvSetIterator<'a> { BitvSetIterator {set: self, next_idx: 0} } + + pub fn difference(&self, other: &BitvSet, f: &fn(&uint) -> bool) -> bool { + for self.common_iter(other).advance |(i, w1, w2)| { + if !iterate_bits(i, w1 & !w2, |b| f(&b)) { + return false; + } + } + /* everything we have that they don't also shows up */ + self.outlier_iter(other).advance(|(mine, i, w)| + !mine || iterate_bits(i, w, |b| f(&b)) + ) + } + + pub fn symmetric_difference(&self, other: &BitvSet, + f: &fn(&uint) -> bool) -> bool { + for self.common_iter(other).advance |(i, w1, w2)| { + if !iterate_bits(i, w1 ^ w2, |b| f(&b)) { + return false; + } + } + self.outlier_iter(other).advance(|(_, i, w)| iterate_bits(i, w, |b| f(&b))) + } + + pub fn intersection(&self, other: &BitvSet, f: &fn(&uint) -> bool) -> bool { + self.common_iter(other).advance(|(i, w1, w2)| iterate_bits(i, w1 & w2, |b| f(&b))) + } + + pub fn union(&self, other: &BitvSet, f: &fn(&uint) -> bool) -> bool { + for self.common_iter(other).advance |(i, w1, w2)| { + if !iterate_bits(i, w1 | w2, |b| f(&b)) { + return false; + } + } + self.outlier_iter(other).advance(|(_, i, w)| iterate_bits(i, w, |b| f(&b))) + } } impl cmp::Eq for BitvSet { @@ -785,41 +820,6 @@ impl Set for BitvSet { fn is_superset(&self, other: &BitvSet) -> bool { other.is_subset(self) } - - fn difference(&self, other: &BitvSet, f: &fn(&uint) -> bool) -> bool { - for self.common_iter(other).advance |(i, w1, w2)| { - if !iterate_bits(i, w1 & !w2, |b| f(&b)) { - return false; - } - } - /* everything we have that they don't also shows up */ - self.outlier_iter(other).advance(|(mine, i, w)| - !mine || iterate_bits(i, w, |b| f(&b)) - ) - } - - fn symmetric_difference(&self, other: &BitvSet, - f: &fn(&uint) -> bool) -> bool { - for self.common_iter(other).advance |(i, w1, w2)| { - if !iterate_bits(i, w1 ^ w2, |b| f(&b)) { - return false; - } - } - self.outlier_iter(other).advance(|(_, i, w)| iterate_bits(i, w, |b| f(&b))) - } - - fn intersection(&self, other: &BitvSet, f: &fn(&uint) -> bool) -> bool { - self.common_iter(other).advance(|(i, w1, w2)| iterate_bits(i, w1 & w2, |b| f(&b))) - } - - fn union(&self, other: &BitvSet, f: &fn(&uint) -> bool) -> bool { - for self.common_iter(other).advance |(i, w1, w2)| { - if !iterate_bits(i, w1 | w2, |b| f(&b)) { - return false; - } - } - self.outlier_iter(other).advance(|(_, i, w)| iterate_bits(i, w, |b| f(&b))) - } } impl MutableSet for BitvSet { diff --git a/src/libextra/treemap.rs b/src/libextra/treemap.rs index 4e66870a9473f..8a2d6cfcf49d7 100644 --- a/src/libextra/treemap.rs +++ b/src/libextra/treemap.rs @@ -396,9 +396,40 @@ impl Set for TreeSet { } true } +} + +impl MutableSet for TreeSet { + /// Add a value to the set. Return true if the value was not already + /// present in the set. + #[inline] + fn insert(&mut self, value: T) -> bool { self.map.insert(value, ()) } + + /// Remove a value from the set. Return true if the value was + /// present in the set. + #[inline] + fn remove(&mut self, value: &T) -> bool { self.map.remove(value) } +} + +impl TreeSet { + /// Create an empty TreeSet + #[inline] + pub fn new() -> TreeSet { TreeSet{map: TreeMap::new()} } + + /// Get a lazy iterator over the values in the set. + /// Requires that it be frozen (immutable). + #[inline] + pub fn iter<'a>(&'a self) -> TreeSetIterator<'a, T> { + TreeSetIterator{iter: self.map.iter()} + } + + /// Visit all values in reverse order + #[inline] + pub fn each_reverse(&self, f: &fn(&T) -> bool) -> bool { + self.map.each_key_reverse(f) + } /// Visit the values (in-order) representing the difference - fn difference(&self, other: &TreeSet, f: &fn(&T) -> bool) -> bool { + pub fn difference(&self, other: &TreeSet, f: &fn(&T) -> bool) -> bool { let mut x = self.iter(); let mut y = other.iter(); @@ -427,7 +458,7 @@ impl Set for TreeSet { } /// Visit the values (in-order) representing the symmetric difference - fn symmetric_difference(&self, other: &TreeSet, + pub fn symmetric_difference(&self, other: &TreeSet, f: &fn(&T) -> bool) -> bool { let mut x = self.iter(); let mut y = other.iter(); @@ -461,7 +492,7 @@ impl Set for TreeSet { } /// Visit the values (in-order) representing the intersection - fn intersection(&self, other: &TreeSet, f: &fn(&T) -> bool) -> bool { + pub fn intersection(&self, other: &TreeSet, f: &fn(&T) -> bool) -> bool { let mut x = self.iter(); let mut y = other.iter(); @@ -487,7 +518,7 @@ impl Set for TreeSet { } /// Visit the values (in-order) representing the union - fn union(&self, other: &TreeSet, f: &fn(&T) -> bool) -> bool { + pub fn union(&self, other: &TreeSet, f: &fn(&T) -> bool) -> bool { let mut x = self.iter(); let mut y = other.iter(); @@ -519,37 +550,6 @@ impl Set for TreeSet { } } -impl MutableSet for TreeSet { - /// Add a value to the set. Return true if the value was not already - /// present in the set. - #[inline] - fn insert(&mut self, value: T) -> bool { self.map.insert(value, ()) } - - /// Remove a value from the set. Return true if the value was - /// present in the set. - #[inline] - fn remove(&mut self, value: &T) -> bool { self.map.remove(value) } -} - -impl TreeSet { - /// Create an empty TreeSet - #[inline] - pub fn new() -> TreeSet { TreeSet{map: TreeMap::new()} } - - /// Get a lazy iterator over the values in the set. - /// Requires that it be frozen (immutable). - #[inline] - pub fn iter<'a>(&'a self) -> TreeSetIterator<'a, T> { - TreeSetIterator{iter: self.map.iter()} - } - - /// Visit all values in reverse order - #[inline] - pub fn each_reverse(&self, f: &fn(&T) -> bool) -> bool { - self.map.each_key_reverse(f) - } -} - /// Lazy forward iterator over a set pub struct TreeSetIterator<'self, T> { priv iter: TreeMapIterator<'self, T, ()> diff --git a/src/libstd/container.rs b/src/libstd/container.rs index d855beea50b2e..10f3fc6586f58 100644 --- a/src/libstd/container.rs +++ b/src/libstd/container.rs @@ -87,17 +87,7 @@ pub trait Set: Container { /// Return true if the set is a superset of another fn is_superset(&self, other: &Self) -> bool; - /// Visit the values representing the difference - fn difference(&self, other: &Self, f: &fn(&T) -> bool) -> bool; - - /// Visit the values representing the symmetric difference - fn symmetric_difference(&self, other: &Self, f: &fn(&T) -> bool) -> bool; - - /// Visit the values representing the intersection - fn intersection(&self, other: &Self, f: &fn(&T) -> bool) -> bool; - - /// Visit the values representing the union - fn union(&self, other: &Self, f: &fn(&T) -> bool) -> bool; + // FIXME #8154: Add difference, sym. difference, intersection and union iterators } /// This trait represents actions which can be performed on sets to mutate diff --git a/src/libstd/hashmap.rs b/src/libstd/hashmap.rs index 8c06f23b8c191..ca61f3e5ad805 100644 --- a/src/libstd/hashmap.rs +++ b/src/libstd/hashmap.rs @@ -672,28 +672,6 @@ impl Set for HashSet { fn is_superset(&self, other: &HashSet) -> bool { other.is_subset(self) } - - /// Visit the values representing the difference - fn difference(&self, other: &HashSet, f: &fn(&T) -> bool) -> bool { - self.difference_iter(other).advance(f) - } - - /// Visit the values representing the symmetric difference - fn symmetric_difference(&self, - other: &HashSet, - f: &fn(&T) -> bool) -> bool { - self.symmetric_difference_iter(other).advance(f) - } - - /// Visit the values representing the intersection - fn intersection(&self, other: &HashSet, f: &fn(&T) -> bool) -> bool { - self.intersection_iter(other).advance(f) - } - - /// Visit the values representing the union - fn union(&self, other: &HashSet, f: &fn(&T) -> bool) -> bool { - self.union_iter(other).advance(f) - } } impl MutableSet for HashSet { From 7e210a8129c844e0b3aca4a28153effd0817ef41 Mon Sep 17 00:00:00 2001 From: blake2-ppc Date: Wed, 31 Jul 2013 21:07:45 +0200 Subject: [PATCH 07/10] std: Replace `for` with `do { .. }` expr in std::gc Change all users of old-style for with internal iterators to using `do`-loops. The code in stackwalk.rs does not actually implement the looping protocol (no break on return false). The code in gc.rs does not use loop breaks, nor does any code using it. We remove the capacity to break from the loops in std::gc and implement the walks using `do { .. }` expressions. No behavior change. --- src/libstd/gc.rs | 107 ++++++++++++++++++---------------------- src/libstd/stackwalk.rs | 7 ++- 2 files changed, 52 insertions(+), 62 deletions(-) diff --git a/src/libstd/gc.rs b/src/libstd/gc.rs index ee270b553e68b..9a8db6990b65d 100644 --- a/src/libstd/gc.rs +++ b/src/libstd/gc.rs @@ -121,11 +121,11 @@ unsafe fn is_safe_point(pc: *Word) -> Option { return None; } -type Visitor<'self> = &'self fn(root: **Word, tydesc: *TyDesc) -> bool; +type Visitor<'self> = &'self fn(root: **Word, tydesc: *TyDesc); // Walks the list of roots for the given safe point, and calls visitor // on each root. -unsafe fn _walk_safe_point(fp: *Word, sp: SafePoint, visitor: Visitor) -> bool { +unsafe fn _walk_safe_point(fp: *Word, sp: SafePoint, visitor: Visitor) { let fp_bytes = fp as *u8; let sp_meta = sp.sp_meta as *u32; @@ -151,7 +151,7 @@ unsafe fn _walk_safe_point(fp: *Word, sp: SafePoint, visitor: Visitor) -> bool { } else { ptr::null() }; - if !visitor(root, tydesc) { return false; } + visitor(root, tydesc); } sri += 1; } @@ -164,10 +164,9 @@ unsafe fn _walk_safe_point(fp: *Word, sp: SafePoint, visitor: Visitor) -> bool { } rri += 1; } - return true; } -unsafe fn walk_safe_point(fp: *Word, sp: SafePoint, visitor: Visitor) -> bool { +unsafe fn walk_safe_point(fp: *Word, sp: SafePoint, visitor: Visitor) { _walk_safe_point(fp, sp, visitor) } @@ -223,7 +222,7 @@ static need_cleanup: Memory = exchange_heap | stack; // Walks stack, searching for roots of the requested type, and passes // each root to the visitor. -unsafe fn _walk_gc_roots(mem: Memory, sentinel: **Word, visitor: Visitor) -> bool { +unsafe fn _walk_gc_roots(mem: Memory, sentinel: **Word, visitor: Visitor) { let mut segment = rustrt::rust_get_stack_segment(); let mut last_ret: *Word = ptr::null(); // To avoid collecting memory used by the GC itself, skip stack @@ -231,7 +230,7 @@ unsafe fn _walk_gc_roots(mem: Memory, sentinel: **Word, visitor: Visitor) -> boo // frame is marked by a sentinel, which is a box pointer stored on // the stack. let mut reached_sentinel = ptr::is_null(sentinel); - for walk_stack |frame| { + do walk_stack |frame| { let pc = last_ret; let Segment {segment: next_segment, boundary: boundary} = find_segment_for_frame(frame.fp, segment); @@ -248,53 +247,46 @@ unsafe fn _walk_gc_roots(mem: Memory, sentinel: **Word, visitor: Visitor) -> boo let ret_offset = if boundary { 4 } else { 1 }; last_ret = *ptr::offset(frame.fp, ret_offset as int) as *Word; - if ptr::is_null(pc) { - loop; - } - - let mut delay_reached_sentinel = reached_sentinel; - let sp = is_safe_point(pc); - match sp { - Some(sp_info) => { - for walk_safe_point(frame.fp, sp_info) |root, tydesc| { - // Skip roots until we see the sentinel. - if !reached_sentinel { - if root == sentinel { - delay_reached_sentinel = true; - } - loop; - } - - // Skip null pointers, which can occur when a - // unique pointer has already been freed. - if ptr::is_null(*root) { - loop; - } - - if ptr::is_null(tydesc) { - // Root is a generic box. - let refcount = **root; - if mem | task_local_heap != 0 && refcount != -1 { - if !visitor(root, tydesc) { return false; } - } else if mem | exchange_heap != 0 && refcount == -1 { - if !visitor(root, tydesc) { return false; } - } - } else { - // Root is a non-immediate. - if mem | stack != 0 { - if !visitor(root, tydesc) { return false; } + if !ptr::is_null(pc) { + + let mut delay_reached_sentinel = reached_sentinel; + let sp = is_safe_point(pc); + match sp { + Some(sp_info) => { + do walk_safe_point(frame.fp, sp_info) |root, tydesc| { + // Skip roots until we see the sentinel. + if !reached_sentinel && root == sentinel { + delay_reached_sentinel = true; + } + + // Skip null pointers, which can occur when a + // unique pointer has already been freed. + if reached_sentinel && !ptr::is_null(*root) { + if ptr::is_null(tydesc) { + // Root is a generic box. + let refcount = **root; + if mem | task_local_heap != 0 && refcount != -1 { + visitor(root, tydesc); + } else if mem | exchange_heap != 0 && refcount == -1 { + visitor(root, tydesc); + } + } else { + // Root is a non-immediate. + if mem | stack != 0 { + visitor(root, tydesc); + } + } + } } } + None => () } - } - None => () + reached_sentinel = delay_reached_sentinel; } - reached_sentinel = delay_reached_sentinel; } - return true; } -unsafe fn walk_gc_roots(mem: Memory, sentinel: **Word, visitor: Visitor) -> bool { +unsafe fn walk_gc_roots(mem: Memory, sentinel: **Word, visitor: Visitor) { _walk_gc_roots(mem, sentinel, visitor) } pub fn gc() { @@ -304,7 +296,7 @@ pub fn gc() { return; } - for walk_gc_roots(task_local_heap, ptr::null()) |_root, _tydesc| { + do walk_gc_roots(task_local_heap, ptr::null()) |_root, _tydesc| { // FIXME(#2997): Walk roots and mark them. io::stdout().write([46]); // . } @@ -349,18 +341,17 @@ pub fn cleanup_stack_for_failure() { }; let mut roots = HashSet::new(); - for walk_gc_roots(need_cleanup, sentinel) |root, tydesc| { + do walk_gc_roots(need_cleanup, sentinel) |root, tydesc| { // Track roots to avoid double frees. - if roots.contains(&*root) { - loop; - } - roots.insert(*root); + if !roots.contains(&*root) { + roots.insert(*root); - if ptr::is_null(tydesc) { - // FIXME #4420: Destroy this box - // FIXME #4330: Destroy this box - } else { - ((*tydesc).drop_glue)(*root as *i8); + if ptr::is_null(tydesc) { + // FIXME #4420: Destroy this box + // FIXME #4330: Destroy this box + } else { + ((*tydesc).drop_glue)(*root as *i8); + } } } } diff --git a/src/libstd/stackwalk.rs b/src/libstd/stackwalk.rs index c3e3ca57a8e74..cc516fb559ea8 100644 --- a/src/libstd/stackwalk.rs +++ b/src/libstd/stackwalk.rs @@ -25,7 +25,7 @@ pub fn Frame(fp: *Word) -> Frame { } } -pub fn walk_stack(visit: &fn(Frame) -> bool) -> bool { +pub fn walk_stack(visit: &fn(Frame)) { debug!("beginning stack walk"); @@ -51,12 +51,11 @@ pub fn walk_stack(visit: &fn(Frame) -> bool) -> bool { } } } - return true; } #[test] fn test_simple() { - for walk_stack |_frame| { + do walk_stack |_frame| { } } @@ -65,7 +64,7 @@ fn test_simple_deep() { fn run(i: int) { if i == 0 { return } - for walk_stack |_frame| { + do walk_stack |_frame| { // Would be nice to test something here... } run(i - 1); From 78cde5b9fb9db91f954f7fe4afdd230de6754e54 Mon Sep 17 00:00:00 2001 From: blake2-ppc Date: Thu, 1 Aug 2013 04:18:19 +0200 Subject: [PATCH 08/10] std: Change `Times` trait to use `do` instead of `for` Change the former repetition:: for 5.times { } to:: do 5.times { } .times() cannot be broken with `break` or `return` anymore; for those cases, use a numerical range loop instead. --- doc/tutorial-tasks.md | 4 +- doc/tutorial.md | 2 +- src/libextra/arc.rs | 12 +++--- src/libextra/base64.rs | 6 +-- src/libextra/bitv.rs | 2 +- src/libextra/dlist.rs | 2 +- src/libextra/flate.rs | 6 +-- src/libextra/getopts.rs | 2 +- src/libextra/json.rs | 2 +- src/libextra/ringbuf.rs | 2 +- src/libextra/sort.rs | 8 ++-- src/libextra/sync.rs | 24 ++++++------ src/libextra/task_pool.rs | 2 +- src/libextra/tempfile.rs | 3 +- src/libextra/treemap.rs | 11 +++--- src/librustc/middle/dataflow.rs | 2 +- src/librustc/middle/lint.rs | 2 +- src/librustc/middle/privacy.rs | 4 +- src/librustc/middle/trans/consts.rs | 2 +- src/librustdoc/markdown_pass.rs | 4 +- src/libstd/iter.rs | 4 +- src/libstd/iterator.rs | 6 +-- src/libstd/num/uint.rs | 13 +++---- src/libstd/rand.rs | 6 +-- src/libstd/rt/comm.rs | 38 +++++++++---------- src/libstd/rt/io/net/tcp.rs | 8 ++-- src/libstd/rt/mod.rs | 2 +- src/libstd/rt/sched.rs | 2 +- src/libstd/rt/select.rs | 4 +- src/libstd/str.rs | 2 +- src/libstd/task/mod.rs | 18 ++++----- src/libstd/unstable/extfmt.rs | 2 +- src/libstd/unstable/sync.rs | 2 +- src/libsyntax/diagnostic.rs | 4 +- src/libsyntax/ext/tt/macro_parser.rs | 2 +- src/test/bench/core-set.rs | 4 +- src/test/bench/noise.rs | 2 +- src/test/bench/shootout-chameneos-redux.rs | 2 +- src/test/bench/shootout-fasta-redux.rs | 2 +- src/test/bench/shootout-k-nucleotide.rs | 4 +- src/test/bench/shootout-mandelbrot.rs | 2 +- src/test/bench/shootout-nbody.rs | 2 +- src/test/bench/shootout-spectralnorm.rs | 2 +- src/test/bench/task-perf-alloc-unwind.rs | 2 +- src/test/bench/task-perf-linked-failure.rs | 4 +- .../block-must-not-have-result-for.rs | 15 -------- .../compile-fail/borrowck-lend-flow-loop.rs | 2 +- src/test/compile-fail/issue-3651-2.rs | 3 +- src/test/run-fail/extern-fail.rs | 2 +- src/test/run-pass/bitv-perf-test.rs | 3 +- .../run-pass/deriving-encodable-decodable.rs | 2 +- src/test/run-pass/deriving-rand.rs | 2 +- src/test/run-pass/extern-stress.rs | 2 +- src/test/run-pass/extern-yield.rs | 2 +- src/test/run-pass/issue-3211.rs | 2 +- src/test/run-pass/issue-3563-3.rs | 2 +- src/test/run-pass/issue-4241.rs | 2 +- src/test/run-pass/issue-4401.rs | 2 +- .../issue-5321-immediates-with-bare-self.rs | 2 +- .../run-pass/numeric-method-autoexport.rs | 2 +- src/test/run-pass/syntax-extension-fmt.rs | 2 +- 61 files changed, 137 insertions(+), 151 deletions(-) delete mode 100644 src/test/compile-fail/block-must-not-have-result-for.rs diff --git a/doc/tutorial-tasks.md b/doc/tutorial-tasks.md index 3092dfff56e9f..08989be871be0 100644 --- a/doc/tutorial-tasks.md +++ b/doc/tutorial-tasks.md @@ -548,7 +548,7 @@ an intermediate generation has already exited: ~~~ # use std::task; # fn sleep_forever() { loop { task::yield() } } -# fn wait_for_a_while() { for 1000.times { task::yield() } } +# fn wait_for_a_while() { do 1000.times { task::yield() } } # do task::try:: { do task::spawn_supervised { do task::spawn_supervised { @@ -567,7 +567,7 @@ other at all, using `task::spawn_unlinked` for _isolated failure_. ~~~ # use std::task; # fn random() -> uint { 100 } -# fn sleep_for(i: uint) { for i.times { task::yield() } } +# fn sleep_for(i: uint) { do i.times { task::yield() } } # do task::try::<()> { let (time1, time2) = (random(), random()); do task::spawn_unlinked { diff --git a/doc/tutorial.md b/doc/tutorial.md index a8ace8558b5a6..c9f1dfcd5a390 100644 --- a/doc/tutorial.md +++ b/doc/tutorial.md @@ -1899,7 +1899,7 @@ struct TimeBomb { impl Drop for TimeBomb { fn drop(&self) { - for self.explosivity.times { + do self.explosivity.times { println("blam!"); } } diff --git a/src/libextra/arc.rs b/src/libextra/arc.rs index 9e622b78fff4a..79eb8439fba4b 100644 --- a/src/libextra/arc.rs +++ b/src/libextra/arc.rs @@ -23,7 +23,7 @@ * let numbers=vec::from_fn(100, |ind| (ind as float)*rand::random()); * let shared_numbers=arc::Arc::new(numbers); * - * for 10.times { + * do 10.times { * let (port, chan) = stream(); * chan.send(shared_numbers.clone()); * @@ -765,7 +765,7 @@ mod tests { do task::spawn || { do arc2.write |num| { - for 10.times { + do 10.times { let tmp = *num; *num = -1; task::yield(); @@ -777,7 +777,7 @@ mod tests { // Readers try to catch the writer in the act let mut children = ~[]; - for 5.times { + do 5.times { let arc3 = (*arc).clone(); let mut builder = task::task(); builder.future_result(|r| children.push(r)); @@ -811,7 +811,7 @@ mod tests { // Reader tasks let mut reader_convos = ~[]; - for 10.times { + do 10.times { let ((rp1,rc1),(rp2,rc2)) = (comm::stream(),comm::stream()); reader_convos.push((rc1, rp2)); let arcn = (*arc).clone(); @@ -925,7 +925,7 @@ mod tests { do read_mode.read |state| { // if writer mistakenly got in, make sure it mutates state // before we assert on it - for 5.times { task::yield(); } + do 5.times { task::yield(); } // make sure writer didn't get in. assert!(*state); } @@ -937,6 +937,6 @@ mod tests { // helped to expose the race nearly 100% of the time... but adding // yields in the intuitively-right locations made it even less likely, // and I wasn't sure why :( . This is a mediocre "next best" option. - for 8.times { test_rw_write_cond_downgrade_read_race_helper() } + do 8.times { test_rw_write_cond_downgrade_read_race_helper() } } } diff --git a/src/libextra/base64.rs b/src/libextra/base64.rs index 5061dbf401b37..5d5311d232922 100644 --- a/src/libextra/base64.rs +++ b/src/libextra/base64.rs @@ -358,9 +358,9 @@ mod test { use std::rand::{task_rng, random, RngUtil}; use std::vec; - for 1000.times { + do 1000.times { let v: ~[u8] = do vec::build |push| { - for task_rng().gen_uint_range(1, 100).times { + do task_rng().gen_uint_range(1, 100).times { push(random()); } }; @@ -389,4 +389,4 @@ mod test { bh.bytes = b.len() as u64; } -} \ No newline at end of file +} diff --git a/src/libextra/bitv.rs b/src/libextra/bitv.rs index 85002029fc607..570186b65a620 100644 --- a/src/libextra/bitv.rs +++ b/src/libextra/bitv.rs @@ -674,7 +674,7 @@ impl BitvSet { fn other_op(&mut self, other: &BitvSet, f: &fn(uint, uint) -> uint) { fn nbits(mut w: uint) -> uint { let mut bits = 0; - for uint::bits.times { + for uint::range(0, uint::bits) |_| { if w == 0 { break; } diff --git a/src/libextra/dlist.rs b/src/libextra/dlist.rs index c684ff14615c7..b2b39d34ce2cd 100644 --- a/src/libextra/dlist.rs +++ b/src/libextra/dlist.rs @@ -933,7 +933,7 @@ mod tests { #[test] fn test_fuzz() { - for 25.times { + do 25.times { fuzz_test(3); fuzz_test(16); fuzz_test(189); diff --git a/src/libextra/flate.rs b/src/libextra/flate.rs index 57edaa53eaf3b..d330b0ea16395 100644 --- a/src/libextra/flate.rs +++ b/src/libextra/flate.rs @@ -90,13 +90,13 @@ mod tests { fn test_flate_round_trip() { let mut r = rand::rng(); let mut words = ~[]; - for 20.times { + do 20.times { let range = r.gen_uint_range(1, 10); words.push(r.gen_bytes(range)); } - for 20.times { + do 20.times { let mut input = ~[]; - for 2000.times { + do 2000.times { input.push_all(r.choose(words)); } debug!("de/inflate of %u bytes of random word-sequences", diff --git a/src/libextra/getopts.rs b/src/libextra/getopts.rs index e50693236fd98..31a73833e27ca 100644 --- a/src/libextra/getopts.rs +++ b/src/libextra/getopts.rs @@ -662,7 +662,7 @@ pub mod groups { // here we just need to indent the start of the description let rowlen = row.len(); if rowlen < 24 { - for (24 - rowlen).times { + do (24 - rowlen).times { row.push_char(' ') } } else { diff --git a/src/libextra/json.rs b/src/libextra/json.rs index f0d5b336e3083..a9f4276e79e70 100644 --- a/src/libextra/json.rs +++ b/src/libextra/json.rs @@ -77,7 +77,7 @@ fn escape_str(s: &str) -> ~str { fn spaces(n: uint) -> ~str { let mut ss = ~""; - for n.times { + do n.times { ss.push_str(" "); } return ss; diff --git a/src/libextra/ringbuf.rs b/src/libextra/ringbuf.rs index e2950293719b3..9cb45a2ec7af9 100644 --- a/src/libextra/ringbuf.rs +++ b/src/libextra/ringbuf.rs @@ -509,7 +509,7 @@ mod tests { fn bench_grow(b: &mut test::BenchHarness) { let mut deq = RingBuf::new(); do b.iter { - for 65.times { + do 65.times { deq.push_front(1); } } diff --git a/src/libextra/sort.rs b/src/libextra/sort.rs index 9cce19da524d7..9832ff7396bcb 100644 --- a/src/libextra/sort.rs +++ b/src/libextra/sort.rs @@ -1081,7 +1081,7 @@ mod big_tests { tim_sort(arr); // /sort isSorted(arr); - for 3.times { + do 3.times { let i1 = rng.gen_uint_range(0, n); let i2 = rng.gen_uint_range(0, n); arr.swap(i1, i2); @@ -1100,7 +1100,7 @@ mod big_tests { tim_sort(arr); // +sort isSorted(arr); - for (n/100).times { + do (n/100).times { let idx = rng.gen_uint_range(0, n); arr[idx] = rng.gen(); } @@ -1153,7 +1153,7 @@ mod big_tests { tim_sort(arr); // /sort isSorted(arr); - for 3.times { + do 3.times { let i1 = rng.gen_uint_range(0, n); let i2 = rng.gen_uint_range(0, n); arr.swap(i1, i2); @@ -1172,7 +1172,7 @@ mod big_tests { tim_sort(arr); // +sort isSorted(arr); - for (n/100).times { + do (n/100).times { let idx = rng.gen_uint_range(0, n); arr[idx] = @rng.gen(); } diff --git a/src/libextra/sync.rs b/src/libextra/sync.rs index dc26d1e36ce13..e539b067edd1c 100644 --- a/src/libextra/sync.rs +++ b/src/libextra/sync.rs @@ -106,7 +106,7 @@ impl Sem { } } // Uncomment if you wish to test for sem races. Not valgrind-friendly. - /* for 1000.times { task::yield(); } */ + /* do 1000.times { task::yield(); } */ // Need to wait outside the exclusive. if waiter_nobe.is_some() { let _ = comm::recv_one(waiter_nobe.unwrap()); @@ -143,7 +143,7 @@ impl Sem<~[WaitQueue]> { fn new_and_signal(count: int, num_condvars: uint) -> Sem<~[WaitQueue]> { let mut queues = ~[]; - for num_condvars.times { + do num_condvars.times { queues.push(WaitQueue::new()); } Sem::new(count, queues) @@ -826,11 +826,11 @@ mod tests { let s2 = ~s.clone(); do task::spawn || { do s2.access { - for 5.times { task::yield(); } + do 5.times { task::yield(); } } } do s.access { - for 5.times { task::yield(); } + do 5.times { task::yield(); } } } #[test] @@ -843,7 +843,7 @@ mod tests { s2.acquire(); c.send(()); } - for 5.times { task::yield(); } + do 5.times { task::yield(); } s.release(); let _ = p.recv(); @@ -852,7 +852,7 @@ mod tests { let s = ~Semaphore::new(0); let s2 = ~s.clone(); do task::spawn || { - for 5.times { task::yield(); } + do 5.times { task::yield(); } s2.release(); let _ = p.recv(); } @@ -895,7 +895,7 @@ mod tests { c.send(()); } let _ = p.recv(); // wait for child to come alive - for 5.times { task::yield(); } // let the child contend + do 5.times { task::yield(); } // let the child contend } let _ = p.recv(); // wait for child to be done } @@ -929,7 +929,7 @@ mod tests { } fn access_shared(sharedstate: &mut int, m: &Mutex, n: uint) { - for n.times { + do n.times { do m.lock { let oldval = *sharedstate; task::yield(); @@ -975,7 +975,7 @@ mod tests { let m = ~Mutex::new(); let mut ports = ~[]; - for num_waiters.times { + do num_waiters.times { let mi = ~m.clone(); let (port, chan) = comm::stream(); ports.push(port); @@ -1065,7 +1065,7 @@ mod tests { let result: result::Result<(),()> = do task::try || { let mut sibling_convos = ~[]; - for 2.times { + do 2.times { let (p,c) = comm::stream(); let c = Cell::new(c); sibling_convos.push(p); @@ -1212,7 +1212,7 @@ mod tests { fn access_shared(sharedstate: &mut int, x: &RWLock, mode: RWLockMode, n: uint) { - for n.times { + do n.times { do lock_rwlock_in_mode(x, mode) { let oldval = *sharedstate; task::yield(); @@ -1343,7 +1343,7 @@ mod tests { let x = ~RWLock::new(); let mut ports = ~[]; - for num_waiters.times { + do num_waiters.times { let xi = (*x).clone(); let (port, chan) = comm::stream(); ports.push(port); diff --git a/src/libextra/task_pool.rs b/src/libextra/task_pool.rs index 523e11e810c87..ddb3c31ec0576 100644 --- a/src/libextra/task_pool.rs +++ b/src/libextra/task_pool.rs @@ -102,7 +102,7 @@ fn test_task_pool() { g }; let mut pool = TaskPool::new(4, Some(SingleThreaded), f); - for 8.times { + do 8.times { pool.execute(|i| printfln!("Hello from thread %u!", *i)); } } diff --git a/src/libextra/tempfile.rs b/src/libextra/tempfile.rs index c5fb4b9292e34..0a2f32375f812 100644 --- a/src/libextra/tempfile.rs +++ b/src/libextra/tempfile.rs @@ -14,12 +14,13 @@ use std::os; use std::rand::RngUtil; use std::rand; +use std::uint; /// Attempts to make a temporary directory inside of `tmpdir` whose name will /// have the suffix `suffix`. If no directory can be created, None is returned. pub fn mkdtemp(tmpdir: &Path, suffix: &str) -> Option { let mut r = rand::rng(); - for 1000.times { + for uint::range(0, 1000) |_| { let p = tmpdir.push(r.gen_str(16) + suffix); if os::make_dir(&p, 0x1c0) { // 700 return Some(p); diff --git a/src/libextra/treemap.rs b/src/libextra/treemap.rs index 8a2d6cfcf49d7..9493a6fb0e0d0 100644 --- a/src/libextra/treemap.rs +++ b/src/libextra/treemap.rs @@ -16,6 +16,7 @@ use std::num; use std::util::{swap, replace}; use std::iterator::{FromIterator, Extendable}; +use std::uint; // This is implemented as an AA tree, which is a simplified variation of // a red-black tree where red (horizontal) nodes can only be added @@ -47,7 +48,7 @@ impl Eq for TreeMap { } else { let mut x = self.iter(); let mut y = other.iter(); - for self.len().times { + for uint::range(0, self.len()) |_| { if x.next().unwrap() != y.next().unwrap() { return false } @@ -65,7 +66,7 @@ fn lt(a: &TreeMap, let mut y = b.iter(); let (a_len, b_len) = (a.len(), b.len()); - for num::min(a_len, b_len).times { + for uint::range(0, num::min(a_len, b_len)) |_| { let (key_a, value_a) = x.next().unwrap(); let (key_b, value_b) = y.next().unwrap(); if *key_a < *key_b { return true; } @@ -931,8 +932,8 @@ mod test_treemap { let mut rng = rand::IsaacRng::new_seeded(&[42]); - for 3.times { - for 90.times { + do 3.times { + do 90.times { let k = rng.gen(); let v = rng.gen(); if !ctrl.iter().any(|x| x == &(k, v)) { @@ -943,7 +944,7 @@ mod test_treemap { } } - for 30.times { + do 30.times { let r = rng.gen_uint_range(0, ctrl.len()); let (key, _) = ctrl.remove(r); assert!(map.remove(&key)); diff --git a/src/librustc/middle/dataflow.rs b/src/librustc/middle/dataflow.rs index 44ebca8c1bf36..e98a759d8a8d4 100644 --- a/src/librustc/middle/dataflow.rs +++ b/src/librustc/middle/dataflow.rs @@ -189,7 +189,7 @@ impl DataFlowContext { }; if expanded { let entry = if self.oper.initial_value() { uint::max_value } else {0}; - for self.words_per_id.times { + do self.words_per_id.times { self.gens.push(0); self.kills.push(0); self.on_entry.push(entry); diff --git a/src/librustc/middle/lint.rs b/src/librustc/middle/lint.rs index cb1ceef18ed31..c8d4901752c29 100644 --- a/src/librustc/middle/lint.rs +++ b/src/librustc/middle/lint.rs @@ -451,7 +451,7 @@ impl Context { if doc_hidden && self.doc_hidden { self.doc_hidden = false; } - for pushed.times { + do pushed.times { let (lint, lvl, src) = self.lint_stack.pop(); self.set_level(lint, lvl, src); } diff --git a/src/librustc/middle/privacy.rs b/src/librustc/middle/privacy.rs index d5855dac177b9..8b2171b59acd5 100644 --- a/src/librustc/middle/privacy.rs +++ b/src/librustc/middle/privacy.rs @@ -340,7 +340,7 @@ pub fn check_crate<'mm>(tcx: ty::ctxt, visit::visit_mod(the_module, span, node_id, (method_map, visitor)); - for n_added.times { + do n_added.times { ignore(privileged_items.pop()); } }, @@ -370,7 +370,7 @@ pub fn check_crate<'mm>(tcx: ty::ctxt, visit::visit_block(block, (method_map, visitor)); - for n_added.times { + do n_added.times { ignore(privileged_items.pop()); } }, diff --git a/src/librustc/middle/trans/consts.rs b/src/librustc/middle/trans/consts.rs index a1ae29337a6b9..40d0d77c16ecb 100644 --- a/src/librustc/middle/trans/consts.rs +++ b/src/librustc/middle/trans/consts.rs @@ -188,7 +188,7 @@ pub fn const_expr(cx: @mut CrateContext, e: @ast::expr) -> ValueRef { Some(@ty::AutoDerefRef(ref adj)) => { let mut ty = ety; let mut maybe_ptr = None; - for adj.autoderefs.times { + do adj.autoderefs.times { let (dv, dt) = const_deref(cx, llconst, ty, false); maybe_ptr = Some(llconst); llconst = dv; diff --git a/src/librustdoc/markdown_pass.rs b/src/librustdoc/markdown_pass.rs index 0706cd98e5816..67fc60c4912c7 100644 --- a/src/librustdoc/markdown_pass.rs +++ b/src/librustdoc/markdown_pass.rs @@ -637,7 +637,7 @@ mod test { let doc = (page_pass::mk_pass(config::DocPerMod).f)(srv, doc); write_markdown(doc, writer_factory); // We expect two pages to have been written - for 2.times { + do 2.times { po.recv(); } } @@ -649,7 +649,7 @@ mod test { ~"#[link(name = \"core\")]; mod a { }"); let doc = (page_pass::mk_pass(config::DocPerMod).f)(srv, doc); write_markdown(doc, writer_factory); - for 2.times { + do 2.times { let (page, markdown) = po.recv(); match page { doc::CratePage(_) => { diff --git a/src/libstd/iter.rs b/src/libstd/iter.rs index 2092ae588d01d..ce528bc952255 100644 --- a/src/libstd/iter.rs +++ b/src/libstd/iter.rs @@ -14,13 +14,13 @@ use iter::Times; let ten = 10 as uint; let mut accum = 0; -for ten.times { accum += 1; } +do ten.times { accum += 1; } ~~~ */ #[allow(missing_doc)] pub trait Times { - fn times(&self, it: &fn() -> bool) -> bool; + fn times(&self, it: &fn()); } diff --git a/src/libstd/iterator.rs b/src/libstd/iterator.rs index 84923876cbf64..013901d57f80e 100644 --- a/src/libstd/iterator.rs +++ b/src/libstd/iterator.rs @@ -18,7 +18,6 @@ implementing the `Iterator` trait. */ use cmp; -use iter::Times; use num::{Zero, One}; use option::{Option, Some, None}; use ops::{Add, Mul}; @@ -1229,8 +1228,9 @@ impl> Iterator for Skip { if self.n == 0 { next } else { - let n = self.n; - for n.times { + let mut n = self.n; + while n > 0 { + n -= 1; match next { Some(_) => { next = self.iter.next(); diff --git a/src/libstd/num/uint.rs b/src/libstd/num/uint.rs index 126150c0f1bfc..275a72d6ecc05 100644 --- a/src/libstd/num/uint.rs +++ b/src/libstd/num/uint.rs @@ -97,22 +97,21 @@ pub fn iterate(lo: uint, hi: uint, it: &fn(uint) -> bool) -> bool { impl iter::Times for uint { #[inline] /// - /// A convenience form for basic iteration. Given a uint `x`, - /// `for x.times { ... }` executes the given block x times. + /// A convenience form for basic repetition. Given a uint `x`, + /// `do x.times { ... }` executes the given block x times. /// /// Equivalent to `for uint::range(0, x) |_| { ... }`. /// /// Not defined on all integer types to permit unambiguous /// use with integer literals of inferred integer-type as - /// the self-value (eg. `for 100.times { ... }`). + /// the self-value (eg. `do 100.times { ... }`). /// - fn times(&self, it: &fn() -> bool) -> bool { + fn times(&self, it: &fn()) { let mut i = *self; while i > 0 { - if !it() { return false; } + it(); i -= 1; } - return true; } } @@ -190,6 +189,6 @@ pub fn test_times() { use iter::Times; let ten = 10 as uint; let mut accum = 0; - for ten.times { accum += 1; } + do ten.times { accum += 1; } assert!((accum == 10)); } diff --git a/src/libstd/rand.rs b/src/libstd/rand.rs index aed68f47fdf39..9134d2da25785 100644 --- a/src/libstd/rand.rs +++ b/src/libstd/rand.rs @@ -695,7 +695,7 @@ impl IsaacRng { }} ); - for 4.times { mix!(); } + do 4.times { mix!(); } if use_rsl { macro_rules! memloop ( @@ -1092,7 +1092,7 @@ mod test { } // run against several seeds - for 10.times { + do 10.times { unsafe { let seed = super::seed(); let rt_rng = do seed.as_imm_buf |p, sz| { @@ -1100,7 +1100,7 @@ mod test { }; let mut rng = IsaacRng::new_seeded(seed); - for 10000.times { + do 10000.times { assert_eq!(rng.next(), rustrt::rand_next(rt_rng)); } rustrt::rand_free(rt_rng); diff --git a/src/libstd/rt/comm.rs b/src/libstd/rt/comm.rs index a27ff559b2ba1..79ee8405531ac 100644 --- a/src/libstd/rt/comm.rs +++ b/src/libstd/rt/comm.rs @@ -769,7 +769,7 @@ mod test { #[test] fn oneshot_multi_thread_close_stress() { - for stress_factor().times { + do stress_factor().times { do run_in_newsched_task { let (port, chan) = oneshot::(); let port_cell = Cell::new(port); @@ -784,7 +784,7 @@ mod test { #[test] fn oneshot_multi_thread_send_close_stress() { - for stress_factor().times { + do stress_factor().times { do run_in_newsched_task { let (port, chan) = oneshot::(); let chan_cell = Cell::new(chan); @@ -804,7 +804,7 @@ mod test { #[test] fn oneshot_multi_thread_recv_close_stress() { - for stress_factor().times { + do stress_factor().times { do run_in_newsched_task { let (port, chan) = oneshot::(); let chan_cell = Cell::new(chan); @@ -830,7 +830,7 @@ mod test { #[test] fn oneshot_multi_thread_send_recv_stress() { - for stress_factor().times { + do stress_factor().times { do run_in_newsched_task { let (port, chan) = oneshot::<~int>(); let chan_cell = Cell::new(chan); @@ -849,7 +849,7 @@ mod test { #[test] fn stream_send_recv_stress() { - for stress_factor().times { + do stress_factor().times { do run_in_mt_newsched_task { let (port, chan) = stream::<~int>(); @@ -886,8 +886,8 @@ mod test { // Regression test that we don't run out of stack in scheduler context do run_in_newsched_task { let (port, chan) = stream(); - for 10000.times { chan.send(()) } - for 10000.times { port.recv() } + do 10000.times { chan.send(()) } + do 10000.times { port.recv() } } } @@ -897,14 +897,14 @@ mod test { let (port, chan) = stream(); let chan = SharedChan::new(chan); let total = stress_factor() + 100; - for total.times { + do total.times { let chan_clone = chan.clone(); do spawntask_random { chan_clone.send(()); } } - for total.times { + do total.times { port.recv(); } } @@ -919,7 +919,7 @@ mod test { let end_chan = SharedChan::new(end_chan); let port = SharedPort::new(port); let total = stress_factor() + 100; - for total.times { + do total.times { let end_chan_clone = end_chan.clone(); let port_clone = port.clone(); do spawntask_random { @@ -928,11 +928,11 @@ mod test { } } - for total.times { + do total.times { chan.send(()); } - for total.times { + do total.times { end_port.recv(); } } @@ -959,7 +959,7 @@ mod test { let send_total = 10; let recv_total = 20; do spawntask_random { - for send_total.times { + do send_total.times { let chan_clone = chan.clone(); do spawntask_random { chan_clone.send(()); @@ -968,7 +968,7 @@ mod test { } let end_chan_clone = end_chan.clone(); do spawntask_random { - for recv_total.times { + do recv_total.times { let port_clone = port.clone(); let end_chan_clone = end_chan_clone.clone(); do spawntask_random { @@ -979,7 +979,7 @@ mod test { } let mut recvd = 0; - for recv_total.times { + do recv_total.times { recvd += if end_port.recv() { 1 } else { 0 }; } @@ -998,15 +998,15 @@ mod test { let pipe = megapipe(); let total = stress_factor() + 10; let mut rng = rand::rng(); - for total.times { + do total.times { let msgs = rng.gen_uint_range(0, 10); let pipe_clone = pipe.clone(); let end_chan_clone = end_chan.clone(); do spawntask_random { - for msgs.times { + do msgs.times { pipe_clone.send(()); } - for msgs.times { + do msgs.times { pipe_clone.recv(); } } @@ -1014,7 +1014,7 @@ mod test { end_chan_clone.send(()); } - for total.times { + do total.times { end_port.recv(); } } diff --git a/src/libstd/rt/io/net/tcp.rs b/src/libstd/rt/io/net/tcp.rs index 82278875fa50a..1d7dafc430248 100644 --- a/src/libstd/rt/io/net/tcp.rs +++ b/src/libstd/rt/io/net/tcp.rs @@ -371,7 +371,7 @@ mod test { do spawntask_immediately { let mut listener = TcpListener::bind(addr); - for max.times { + do max.times { let mut stream = listener.accept(); let mut buf = [0]; stream.read(buf); @@ -380,7 +380,7 @@ mod test { } do spawntask_immediately { - for max.times { + do max.times { let mut stream = TcpStream::connect(addr); stream.write([99]); } @@ -396,7 +396,7 @@ mod test { do spawntask_immediately { let mut listener = TcpListener::bind(addr); - for max.times { + do max.times { let mut stream = listener.accept(); let mut buf = [0]; stream.read(buf); @@ -405,7 +405,7 @@ mod test { } do spawntask_immediately { - for max.times { + do max.times { let mut stream = TcpStream::connect(addr); stream.write([99]); } diff --git a/src/libstd/rt/mod.rs b/src/libstd/rt/mod.rs index 8648832c591af..3bcf678782459 100644 --- a/src/libstd/rt/mod.rs +++ b/src/libstd/rt/mod.rs @@ -255,7 +255,7 @@ fn run_(main: ~fn(), use_main_sched: bool) -> int { // sent the Shutdown message to terminate the schedulers. let mut handles = ~[]; - for nscheds.times { + do nscheds.times { // Every scheduler is driven by an I/O event loop. let loop_ = ~UvEventLoop::new(); let mut sched = ~Scheduler::new(loop_, work_queue.clone(), sleepers.clone()); diff --git a/src/libstd/rt/sched.rs b/src/libstd/rt/sched.rs index 98df38f9b1dc5..ae4ca2b978357 100644 --- a/src/libstd/rt/sched.rs +++ b/src/libstd/rt/sched.rs @@ -1097,7 +1097,7 @@ mod test { do run_in_mt_newsched_task { let mut ports = ~[]; - for 10.times { + do 10.times { let (port, chan) = oneshot(); let chan_cell = Cell::new(chan); do spawntask_later { diff --git a/src/libstd/rt/select.rs b/src/libstd/rt/select.rs index 6296186aa4913..aba42ee92c3f8 100644 --- a/src/libstd/rt/select.rs +++ b/src/libstd/rt/select.rs @@ -187,7 +187,7 @@ mod test { do run_in_newsched_task { let (ports, _) = unzip(from_fn(10, |_| stream())); let (port, chan) = stream(); - for 10.times { chan.send(31337); } + do 10.times { chan.send(31337); } let mut ports = ports; let mut port = Some(port); let order = [5u,0,4,3,2,6,9,8,7,1]; @@ -268,7 +268,7 @@ mod test { do run_in_newsched_task { // A bit of stress, since ordinarily this is just smoke and mirrors. - for 4.times { + do 4.times { let send_on_chans = send_on_chans.clone(); do task::spawn { let mut ports = ~[]; diff --git a/src/libstd/str.rs b/src/libstd/str.rs index 894351bcc5398..f0c0595744c95 100644 --- a/src/libstd/str.rs +++ b/src/libstd/str.rs @@ -1828,7 +1828,7 @@ impl<'self> StrSlice<'self> for &'self str { do ret.as_mut_buf |rbuf, _len| { let mut rbuf = rbuf; - for nn.times { + do nn.times { ptr::copy_memory(rbuf, buf, len); rbuf = rbuf.offset(len as int); } diff --git a/src/libstd/task/mod.rs b/src/libstd/task/mod.rs index aff4bc12039fc..d0124407bd4a2 100644 --- a/src/libstd/task/mod.rs +++ b/src/libstd/task/mod.rs @@ -683,7 +683,7 @@ fn test_spawn_unlinked_unsup_no_fail_down() { // grandchild sends on a port let ch = ch.clone(); do spawn_unlinked { // Give middle task a chance to fail-but-not-kill-us. - for 16.times { task::yield(); } + do 16.times { task::yield(); } ch.send(()); // If killed first, grandparent hangs. } fail!(); // Shouldn't kill either (grand)parent or (grand)child. @@ -698,7 +698,7 @@ fn test_spawn_unlinked_unsup_no_fail_up() { // child unlinked fails fn test_spawn_unlinked_sup_no_fail_up() { // child unlinked fails do spawn_supervised { fail!(); } // Give child a chance to fail-but-not-kill-us. - for 16.times { task::yield(); } + do 16.times { task::yield(); } } #[test] #[should_fail] #[ignore(cfg(windows))] fn test_spawn_unlinked_sup_fail_down() { @@ -760,7 +760,7 @@ fn test_spawn_failure_propagate_grandchild() { do spawn_supervised { do spawn_supervised { block_forever(); } } - for 16.times { task::yield(); } + do 16.times { task::yield(); } fail!(); } @@ -770,7 +770,7 @@ fn test_spawn_failure_propagate_secondborn() { do spawn_supervised { do spawn { block_forever(); } // linked } - for 16.times { task::yield(); } + do 16.times { task::yield(); } fail!(); } @@ -780,7 +780,7 @@ fn test_spawn_failure_propagate_nephew_or_niece() { do spawn { // linked do spawn_supervised { block_forever(); } } - for 16.times { task::yield(); } + do 16.times { task::yield(); } fail!(); } @@ -790,7 +790,7 @@ fn test_spawn_linked_sup_propagate_sibling() { do spawn { // linked do spawn { block_forever(); } // linked } - for 16.times { task::yield(); } + do 16.times { task::yield(); } fail!(); } @@ -970,7 +970,7 @@ fn test_spawn_sched_blocking() { // Testing that a task in one scheduler can block in foreign code // without affecting other schedulers - for 20u.times { + do 20u.times { let (start_po, start_ch) = stream(); let (fin_po, fin_ch) = stream(); @@ -1076,7 +1076,7 @@ fn test_unkillable() { // We want to do this after failing do spawn_unlinked { - for 10.times { yield() } + do 10.times { yield() } ch.send(()); } @@ -1111,7 +1111,7 @@ fn test_unkillable_nested() { // We want to do this after failing do spawn_unlinked || { - for 10.times { yield() } + do 10.times { yield() } ch.send(()); } diff --git a/src/libstd/unstable/extfmt.rs b/src/libstd/unstable/extfmt.rs index a8cdd1fb2dcc7..5417af5008131 100644 --- a/src/libstd/unstable/extfmt.rs +++ b/src/libstd/unstable/extfmt.rs @@ -636,7 +636,7 @@ pub mod rt { buf.push_char(c); } buf.push_str(s); - for diff.times { + do diff.times { buf.push_char(padchar); } return; diff --git a/src/libstd/unstable/sync.rs b/src/libstd/unstable/sync.rs index e865d3a467dd4..f5c82bad2b1d4 100644 --- a/src/libstd/unstable/sync.rs +++ b/src/libstd/unstable/sync.rs @@ -626,7 +626,7 @@ mod tests { let x = Exclusive::new(~~"hello"); let x2 = x.clone(); do task::spawn { - for 10.times { task::yield(); } // try to let the unwrapper go + do 10.times { task::yield(); } // try to let the unwrapper go fail!(); // punt it awake from its deadlock } let _z = x.unwrap(); diff --git a/src/libsyntax/diagnostic.rs b/src/libsyntax/diagnostic.rs index 4c7c9c0c32557..0fb28596e11ba 100644 --- a/src/libsyntax/diagnostic.rs +++ b/src/libsyntax/diagnostic.rs @@ -302,7 +302,7 @@ fn highlight_lines(cm: @codemap::CodeMap, // Skip is the number of characters we need to skip because they are // part of the 'filename:line ' part of the previous line. let skip = fm.name.len() + digits + 3u; - for skip.times() { + do skip.times() { s.push_char(' '); } let orig = fm.get_line(lines.lines[0] as int); @@ -323,7 +323,7 @@ fn highlight_lines(cm: @codemap::CodeMap, if hi.col != lo.col { // the ^ already takes up one space let num_squigglies = hi.col.to_uint()-lo.col.to_uint()-1u; - for num_squigglies.times() { + do num_squigglies.times() { s.push_char('~') } } diff --git a/src/libsyntax/ext/tt/macro_parser.rs b/src/libsyntax/ext/tt/macro_parser.rs index 66965f0021503..ad26d7b3f7eab 100644 --- a/src/libsyntax/ext/tt/macro_parser.rs +++ b/src/libsyntax/ext/tt/macro_parser.rs @@ -403,7 +403,7 @@ pub fn parse( } cur_eis.push(ei); - for rust_parser.tokens_consumed.times() || { + do rust_parser.tokens_consumed.times() || { rdr.next_token(); } } diff --git a/src/test/bench/core-set.rs b/src/test/bench/core-set.rs index 461f4caa30b01..7a11a93abc549 100644 --- a/src/test/bench/core-set.rs +++ b/src/test/bench/core-set.rs @@ -59,7 +59,7 @@ impl Results { { let mut set = f(); do timed(&mut self.random_ints) { - for num_keys.times { + do num_keys.times { set.insert((rng.next() as uint) % rand_cap); } } @@ -103,7 +103,7 @@ impl Results { { let mut set = f(); do timed(&mut self.random_strings) { - for num_keys.times { + do num_keys.times { let s = uint::to_str(rng.next() as uint); set.insert(s); } diff --git a/src/test/bench/noise.rs b/src/test/bench/noise.rs index a8742b3073f61..e25f1bdfa7805 100644 --- a/src/test/bench/noise.rs +++ b/src/test/bench/noise.rs @@ -105,7 +105,7 @@ fn main() { let symbols = [" ", "░", "▒", "▓", "█", "█"]; let mut pixels = [0f32, ..256*256]; let n2d = ~Noise2DContext::new(); - for 100.times { + do 100.times { for int::range(0, 256) |y| { for int::range(0, 256) |x| { let v = n2d.get( diff --git a/src/test/bench/shootout-chameneos-redux.rs b/src/test/bench/shootout-chameneos-redux.rs index 52548f40f8291..4ad96a21b88d2 100644 --- a/src/test/bench/shootout-chameneos-redux.rs +++ b/src/test/bench/shootout-chameneos-redux.rs @@ -169,7 +169,7 @@ fn rendezvous(nn: uint, set: ~[color]) { let mut creatures_met = 0; // set up meetings... - for nn.times { + do nn.times { let fst_creature: CreatureInfo = from_creatures.recv(); let snd_creature: CreatureInfo = from_creatures.recv(); diff --git a/src/test/bench/shootout-fasta-redux.rs b/src/test/bench/shootout-fasta-redux.rs index f2cc364ab1095..f7b66e9e1458f 100644 --- a/src/test/bench/shootout-fasta-redux.rs +++ b/src/test/bench/shootout-fasta-redux.rs @@ -164,7 +164,7 @@ impl RandomFasta { let chars_left = n % LINE_LEN; let mut buf = [0, ..LINE_LEN + 1]; - for lines.times { + do lines.times { for range(0, LINE_LEN) |i| { buf[i] = self.nextc(); } diff --git a/src/test/bench/shootout-k-nucleotide.rs b/src/test/bench/shootout-k-nucleotide.rs index a7b784e1a96e8..69d173c807026 100644 --- a/src/test/bench/shootout-k-nucleotide.rs +++ b/src/test/bench/shootout-k-nucleotide.rs @@ -54,7 +54,7 @@ impl Code { fn unpack(&self, frame: i32) -> ~str { let mut key = **self; let mut result = ~[]; - for (frame as uint).times { + do (frame as uint).times { result.push(unpack_symbol((key as u8) & 3)); key >>= 2; } @@ -251,7 +251,7 @@ fn generate_frequencies(frequencies: &mut Table, let mut code = Code(0); // Pull first frame. - for (frame as uint).times { + do (frame as uint).times { code = code.push_char(input[0]); input = next_char(input); } diff --git a/src/test/bench/shootout-mandelbrot.rs b/src/test/bench/shootout-mandelbrot.rs index 594593e2ea343..930439fe7f08b 100644 --- a/src/test/bench/shootout-mandelbrot.rs +++ b/src/test/bench/shootout-mandelbrot.rs @@ -30,7 +30,7 @@ fn main() { let Cr = 2.0 * (x as f64) / (w as f64) - 1.5; let Ci = 2.0 * (y as f64) / (h as f64) - 1.0; - for ITER.times { + for range(0, ITER as i32) |_| { if Tr + Ti > LIMIT * LIMIT { break; } diff --git a/src/test/bench/shootout-nbody.rs b/src/test/bench/shootout-nbody.rs index 3fbebbdb55659..b294ca8f282c6 100644 --- a/src/test/bench/shootout-nbody.rs +++ b/src/test/bench/shootout-nbody.rs @@ -80,7 +80,7 @@ struct Planet { fn advance(bodies: &mut [Planet, ..N_BODIES], dt: f64, steps: i32) { let mut d = [ 0.0, ..3 ]; - for (steps as uint).times { + do (steps as uint).times { for range(0, N_BODIES) |i| { for range(i + 1, N_BODIES) |j| { d[0] = bodies[i].x[0] - bodies[j].x[0]; diff --git a/src/test/bench/shootout-spectralnorm.rs b/src/test/bench/shootout-spectralnorm.rs index 893431e6bb375..5187d0352985a 100644 --- a/src/test/bench/shootout-spectralnorm.rs +++ b/src/test/bench/shootout-spectralnorm.rs @@ -56,7 +56,7 @@ fn main() { let mut u = vec::from_elem(n, 1f64); let mut v = u.clone(); let mut tmp = u.clone(); - for 8.times { + do 8.times { mult_AtAv(u, v, tmp); mult_AtAv(v, u, tmp); } diff --git a/src/test/bench/task-perf-alloc-unwind.rs b/src/test/bench/task-perf-alloc-unwind.rs index 3470cc9274578..ca539d712fdef 100644 --- a/src/test/bench/task-perf-alloc-unwind.rs +++ b/src/test/bench/task-perf-alloc-unwind.rs @@ -32,7 +32,7 @@ fn main() { } fn run(repeat: int, depth: int) { - for (repeat as uint).times { + do (repeat as uint).times { info!("starting %.4f", precise_time_s()); do task::try { recurse_or_fail(depth, None) diff --git a/src/test/bench/task-perf-linked-failure.rs b/src/test/bench/task-perf-linked-failure.rs index 7eb138e99a086..6ab83e5b3830b 100644 --- a/src/test/bench/task-perf-linked-failure.rs +++ b/src/test/bench/task-perf-linked-failure.rs @@ -32,7 +32,7 @@ fn grandchild_group(num_tasks: uint) { let (po, ch) = stream(); let ch = SharedChan::new(ch); - for num_tasks.times { + do num_tasks.times { let ch = ch.clone(); do task::spawn { // linked ch.send(()); @@ -41,7 +41,7 @@ fn grandchild_group(num_tasks: uint) { } } error!("Grandchild group getting started"); - for num_tasks.times { + do num_tasks.times { // Make sure all above children are fully spawned; i.e., enlisted in // their ancestor groups. po.recv(); diff --git a/src/test/compile-fail/block-must-not-have-result-for.rs b/src/test/compile-fail/block-must-not-have-result-for.rs deleted file mode 100644 index 1aa05a9477de9..0000000000000 --- a/src/test/compile-fail/block-must-not-have-result-for.rs +++ /dev/null @@ -1,15 +0,0 @@ -// Copyright 2012 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -fn main() { - for 2.times { //~ ERROR A for-loop body must return (), but - true - } -} diff --git a/src/test/compile-fail/borrowck-lend-flow-loop.rs b/src/test/compile-fail/borrowck-lend-flow-loop.rs index e66acddd05e2b..642e4653cd023 100644 --- a/src/test/compile-fail/borrowck-lend-flow-loop.rs +++ b/src/test/compile-fail/borrowck-lend-flow-loop.rs @@ -40,7 +40,7 @@ fn block_overarching_alias_mut() { let mut v = ~3; let mut x = &mut v; - for 3.times { + do 3.times { borrow(v); //~ ERROR cannot borrow } *x = ~5; diff --git a/src/test/compile-fail/issue-3651-2.rs b/src/test/compile-fail/issue-3651-2.rs index 98a02b6b74691..bcd8e86d1d3bb 100644 --- a/src/test/compile-fail/issue-3651-2.rs +++ b/src/test/compile-fail/issue-3651-2.rs @@ -9,5 +9,6 @@ // except according to those terms. fn main() { - do 5.times {}; //~ ERROR Do-block body must return bool, but returns () here. Perhaps + fn take_block(f: &fn() -> bool) -> bool { f() } + do take_block {}; //~ ERROR Do-block body must return bool, but returns () here. Perhaps } diff --git a/src/test/run-fail/extern-fail.rs b/src/test/run-fail/extern-fail.rs index 717cecff6d681..a281e9863649e 100644 --- a/src/test/run-fail/extern-fail.rs +++ b/src/test/run-fail/extern-fail.rs @@ -40,7 +40,7 @@ fn count(n: uint) -> uint { } fn main() { - for 10u.times { + do 10u.times { do task::spawn { let result = count(5u); info!("result = %?", result); diff --git a/src/test/run-pass/bitv-perf-test.rs b/src/test/run-pass/bitv-perf-test.rs index c6edbfbe463d0..b57e179f4a9af 100644 --- a/src/test/run-pass/bitv-perf-test.rs +++ b/src/test/run-pass/bitv-perf-test.rs @@ -13,11 +13,10 @@ extern mod extra; use extra::bitv::*; -fn bitv_test() -> bool { +fn bitv_test() { let mut v1 = ~Bitv::new(31, false); let v2 = ~Bitv::new(31, true); v1.union(v2); - true } pub fn main() { diff --git a/src/test/run-pass/deriving-encodable-decodable.rs b/src/test/run-pass/deriving-encodable-decodable.rs index fa672581238fe..c282860957a1f 100644 --- a/src/test/run-pass/deriving-encodable-decodable.rs +++ b/src/test/run-pass/deriving-encodable-decodable.rs @@ -69,7 +69,7 @@ pub fn main() { roundtrip::(); roundtrip::(); - for 20.times { + do 20.times { roundtrip::(); roundtrip::(); roundtrip::>(); diff --git a/src/test/run-pass/deriving-rand.rs b/src/test/run-pass/deriving-rand.rs index 193bb1628ef56..65bfc14406fc4 100644 --- a/src/test/run-pass/deriving-rand.rs +++ b/src/test/run-pass/deriving-rand.rs @@ -32,7 +32,7 @@ enum D { fn main() { // check there's no segfaults - for 20.times { + do 20.times { rand::random::(); rand::random::(); rand::random::(); diff --git a/src/test/run-pass/extern-stress.rs b/src/test/run-pass/extern-stress.rs index 33003aa8ba680..4574fbc1ff0cd 100644 --- a/src/test/run-pass/extern-stress.rs +++ b/src/test/run-pass/extern-stress.rs @@ -39,7 +39,7 @@ fn count(n: uint) -> uint { } pub fn main() { - for 100u.times { + do 100u.times { do task::spawn { assert_eq!(count(5u), 16u); }; diff --git a/src/test/run-pass/extern-yield.rs b/src/test/run-pass/extern-yield.rs index 103ed71fc2ba1..4722eeea3d7cc 100644 --- a/src/test/run-pass/extern-yield.rs +++ b/src/test/run-pass/extern-yield.rs @@ -36,7 +36,7 @@ fn count(n: uint) -> uint { } pub fn main() { - for 10u.times { + do 10u.times { do task::spawn { let result = count(5u); info!("result = %?", result); diff --git a/src/test/run-pass/issue-3211.rs b/src/test/run-pass/issue-3211.rs index 3e3e6d6f99215..49ed6de0c9999 100644 --- a/src/test/run-pass/issue-3211.rs +++ b/src/test/run-pass/issue-3211.rs @@ -1,6 +1,6 @@ pub fn main() { let mut x = 0; - for 4096.times { + do 4096.times { x += 1; } assert_eq!(x, 4096); diff --git a/src/test/run-pass/issue-3563-3.rs b/src/test/run-pass/issue-3563-3.rs index b85ddf95a5471..5d8405ce43336 100644 --- a/src/test/run-pass/issue-3563-3.rs +++ b/src/test/run-pass/issue-3563-3.rs @@ -68,7 +68,7 @@ fn AsciiArt(width: uint, height: uint, fill: char) -> AsciiArt { // Use an anonymous function to build a vector of vectors containing // blank characters for each position in our canvas. let mut lines = do vec::build_sized(height) |push| { - for height.times { + do height.times { push(vec::from_elem(width, '.')); } }; diff --git a/src/test/run-pass/issue-4241.rs b/src/test/run-pass/issue-4241.rs index 3bfb2ef38537d..f9b374e7cd21b 100644 --- a/src/test/run-pass/issue-4241.rs +++ b/src/test/run-pass/issue-4241.rs @@ -45,7 +45,7 @@ priv fn parse_data(len: uint, io: @io::Reader) -> Result { priv fn parse_list(len: uint, io: @io::Reader) -> Result { let mut list: ~[Result] = ~[]; - for len.times { + do len.times { let v = match io.read_char() { '$' => parse_bulk(io), diff --git a/src/test/run-pass/issue-4401.rs b/src/test/run-pass/issue-4401.rs index e993d827abb7d..99250c4c8a24a 100644 --- a/src/test/run-pass/issue-4401.rs +++ b/src/test/run-pass/issue-4401.rs @@ -1,6 +1,6 @@ pub fn main() { let mut count = 0; - for 999_999.times() { + do 999_999.times() { count += 1; } assert_eq!(count, 999_999); diff --git a/src/test/run-pass/issue-5321-immediates-with-bare-self.rs b/src/test/run-pass/issue-5321-immediates-with-bare-self.rs index 7b809c39cb83d..3f4b732af3276 100644 --- a/src/test/run-pass/issue-5321-immediates-with-bare-self.rs +++ b/src/test/run-pass/issue-5321-immediates-with-bare-self.rs @@ -14,7 +14,7 @@ trait Fooable { impl Fooable for uint { fn yes(self) { - for self.times { + do self.times { println("yes"); } } diff --git a/src/test/run-pass/numeric-method-autoexport.rs b/src/test/run-pass/numeric-method-autoexport.rs index 7092f8190154a..569ccf5335ea0 100644 --- a/src/test/run-pass/numeric-method-autoexport.rs +++ b/src/test/run-pass/numeric-method-autoexport.rs @@ -32,7 +32,7 @@ pub fn main() { assert_eq!(15u64.add(&6u64), 21u64); // times - 15u.times(|| false); + 15u.times(|| {}); // floats // num diff --git a/src/test/run-pass/syntax-extension-fmt.rs b/src/test/run-pass/syntax-extension-fmt.rs index 513bc078e7f91..7c90b38bae1c9 100644 --- a/src/test/run-pass/syntax-extension-fmt.rs +++ b/src/test/run-pass/syntax-extension-fmt.rs @@ -266,7 +266,7 @@ fn more_floats() { } fn pointer() { - for 10.times { + do 10.times { let x: uint = ::std::rand::random(); assert_eq!(fmt!("%p", x as *uint), fmt!("0x%x", x)); } From 7c21ccc4835326e87d6baaaaa8d1c616a398d924 Mon Sep 17 00:00:00 2001 From: Huon Wilson Date: Thu, 1 Aug 2013 19:36:56 +1000 Subject: [PATCH 09/10] rustc: add a lint for `for`, suggesting `foreach` or `do`. This is just to aid the transistion to the new `for` loop, by pointing at each location where the old one occurs. --- src/librustc/middle/lint.rs | 27 +++++++++++++++++++ .../compile-fail/lint-deprecated-for-loop.rs | 20 ++++++++++++++ 2 files changed, 47 insertions(+) create mode 100644 src/test/compile-fail/lint-deprecated-for-loop.rs diff --git a/src/librustc/middle/lint.rs b/src/librustc/middle/lint.rs index c8d4901752c29..f972406ae11d8 100644 --- a/src/librustc/middle/lint.rs +++ b/src/librustc/middle/lint.rs @@ -74,6 +74,7 @@ pub enum lint { unused_imports, unnecessary_qualification, while_true, + deprecated_for_loop, path_statement, unrecognized_lint, non_camel_case_types, @@ -165,6 +166,13 @@ static lint_table: &'static [(&'static str, LintSpec)] = &[ default: warn }), + ("deprecated_for_loop", + LintSpec { + lint: deprecated_for_loop, + desc: "recommend using `foreach` or `do` instead of `for`", + default: allow + }), + ("path_statement", LintSpec { lint: path_statement, @@ -561,6 +569,24 @@ fn lint_while_true() -> visit::vt<@mut Context> { }) } +fn lint_deprecated_for_loop() -> visit::vt<@mut Context> { + visit::mk_vt(@visit::Visitor { + visit_expr: |e, (cx, vt): (@mut Context, visit::vt<@mut Context>)| { + match e.node { + ast::expr_call(_, _, ast::ForSugar) | + ast::expr_method_call(_, _, _, _, _, ast::ForSugar) => { + cx.span_lint(deprecated_for_loop, e.span, + "`for` is deprecated; use `foreach in \ + ` or `do`") + } + _ => {} + } + visit::visit_expr(e, (cx, vt)); + }, + .. *visit::default_visitor() + }) +} + fn lint_type_limits() -> visit::vt<@mut Context> { fn is_valid(binop: ast::binop, v: T, min: T, max: T) -> bool { @@ -1096,6 +1122,7 @@ pub fn check_crate(tcx: ty::ctxt, crate: @ast::Crate) { // Register each of the lint passes with the context cx.add_lint(lint_while_true()); + cx.add_lint(lint_deprecated_for_loop()); cx.add_lint(lint_path_statement()); cx.add_lint(lint_heap()); cx.add_lint(lint_type_limits()); diff --git a/src/test/compile-fail/lint-deprecated-for-loop.rs b/src/test/compile-fail/lint-deprecated-for-loop.rs new file mode 100644 index 0000000000000..5570562cf8b00 --- /dev/null +++ b/src/test/compile-fail/lint-deprecated-for-loop.rs @@ -0,0 +1,20 @@ +// Copyright 2013 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + + +#[forbid(deprecated_for_loop)]; + +fn f(_: &fn() -> bool) -> bool { + true +} + +fn main() { + for f {} //~ ERROR `for` is deprecated +} From 94f1a5d6f8ecd30c6f59dfeaacdd5962f58bc44c Mon Sep 17 00:00:00 2001 From: Daniel Micay Date: Thu, 1 Aug 2013 15:26:47 -0400 Subject: [PATCH 10/10] migrate to foreach --- src/libstd/rt/select.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libstd/rt/select.rs b/src/libstd/rt/select.rs index aba42ee92c3f8..b19357fa2219f 100644 --- a/src/libstd/rt/select.rs +++ b/src/libstd/rt/select.rs @@ -53,8 +53,8 @@ pub fn select(ports: &mut [A]) -> uint { do sched.deschedule_running_task_and_then |sched, task| { let task_handles = task.make_selectable(ports.len()); - for ports.mut_iter().zip(task_handles.consume_iter()).enumerate().advance - |(index, (port, task_handle))| { + foreach (index, (port, task_handle)) in + ports.mut_iter().zip(task_handles.consume_iter()).enumerate() { // If one of the ports has data by now, it will wake the handle. if port.block_on(sched, task_handle) { ready_index = index;