diff --git a/src/libcore/cleanup.rs b/src/libcore/cleanup.rs index 912f965db7c9a..a5df97e3d574f 100644 --- a/src/libcore/cleanup.rs +++ b/src/libcore/cleanup.rs @@ -127,6 +127,7 @@ struct AnnihilateStats { n_bytes_freed: uint } +#[cfg(stage0)] unsafe fn each_live_alloc(read_next_before: bool, f: &fn(box: *mut BoxRepr, uniq: bool) -> bool) { //! Walks the internal list of allocations @@ -141,8 +142,8 @@ unsafe fn each_live_alloc(read_next_before: bool, let uniq = (*box).header.ref_count == managed::raw::RC_MANAGED_UNIQUE; - if ! f(box, uniq) { - break + if !f(box, uniq) { + return; } if read_next_before { @@ -152,6 +153,33 @@ unsafe fn each_live_alloc(read_next_before: bool, } } } +#[cfg(not(stage0))] +unsafe fn each_live_alloc(read_next_before: bool, + f: &fn(box: *mut BoxRepr, uniq: bool) -> bool) -> bool { + //! Walks the internal list of allocations + + use managed; + + let task: *Task = transmute(rustrt::rust_get_task()); + let box = (*task).boxed_region.live_allocs; + let mut box: *mut BoxRepr = transmute(copy box); + while box != mut_null() { + let next_before = transmute(copy (*box).header.next); + let uniq = + (*box).header.ref_count == managed::raw::RC_MANAGED_UNIQUE; + + if !f(box, uniq) { + return false; + } + + if read_next_before { + box = next_before; + } else { + box = transmute(copy (*box).header.next); + } + } + return true; +} #[cfg(unix)] fn debug_mem() -> bool { diff --git a/src/libcore/container.rs b/src/libcore/container.rs index 37b904bbe6327..1d5d77649549e 100644 --- a/src/libcore/container.rs +++ b/src/libcore/container.rs @@ -30,16 +30,32 @@ pub trait Map: Mutable { fn contains_key(&self, key: &K) -> bool; // Visits all keys and values + #[cfg(stage0)] fn each<'a>(&'a self, f: &fn(&K, &'a V) -> bool); + // Visits all keys and values + #[cfg(not(stage0))] + fn each<'a>(&'a self, f: &fn(&K, &'a V) -> bool) -> bool; /// Visit all keys + #[cfg(stage0)] fn each_key(&self, f: &fn(&K) -> bool); + /// Visit all keys + #[cfg(not(stage0))] + fn each_key(&self, f: &fn(&K) -> bool) -> bool; /// Visit all values + #[cfg(stage0)] fn each_value<'a>(&'a self, f: &fn(&'a V) -> bool); + /// Visit all values + #[cfg(not(stage0))] + fn each_value<'a>(&'a self, f: &fn(&'a V) -> bool) -> bool; /// Iterate over the map and mutate the contained values + #[cfg(stage0)] fn mutate_values(&mut self, f: &fn(&K, &mut V) -> bool); + /// Iterate over the map and mutate the contained values + #[cfg(not(stage0))] + fn mutate_values(&mut self, f: &fn(&K, &mut V) -> bool) -> bool; /// Return a reference to the value corresponding to the key fn find<'a>(&'a self, key: &K) -> Option<&'a V>; @@ -65,6 +81,7 @@ pub trait Map: Mutable { fn pop(&mut self, k: &K) -> Option; } +#[cfg(stage0)] pub trait Set: Mutable { /// Return true if the set contains a value fn contains(&self, value: &T) -> bool; @@ -99,3 +116,39 @@ pub trait Set: Mutable { /// Visit the values representing the union fn union(&self, other: &Self, f: &fn(&T) -> bool); } + +#[cfg(not(stage0))] +pub trait Set: Mutable { + /// Return true if the set contains a value + fn contains(&self, value: &T) -> bool; + + /// Add a value to the set. Return true if the value was not already + /// present in the set. + fn insert(&mut self, value: T) -> bool; + + /// Remove a value from the set. Return true if the value was + /// present in the set. + fn remove(&mut self, value: &T) -> bool; + + /// Return true if the set has no elements in common with `other`. + /// This is equivalent to checking for an empty intersection. + fn is_disjoint(&self, other: &Self) -> bool; + + /// Return true if the set is a subset of another + fn is_subset(&self, other: &Self) -> bool; + + /// 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; +} diff --git a/src/libcore/core b/src/libcore/core new file mode 100755 index 0000000000000..790c07db685e3 Binary files /dev/null and b/src/libcore/core differ diff --git a/src/libcore/gc.rs b/src/libcore/gc.rs index 9a7d0056b8245..6a427297cc22d 100644 --- a/src/libcore/gc.rs +++ b/src/libcore/gc.rs @@ -129,7 +129,7 @@ type Visitor<'self> = &'self fn(root: **Word, tydesc: *Word) -> bool; // 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) { +unsafe fn _walk_safe_point(fp: *Word, sp: SafePoint, visitor: Visitor) -> bool { let fp_bytes: *u8 = cast::transmute(fp); let sp_meta: *u32 = cast::transmute(sp.sp_meta); @@ -155,7 +155,7 @@ unsafe fn walk_safe_point(fp: *Word, sp: SafePoint, visitor: Visitor) { } else { ptr::null() }; - if !visitor(root, tydesc) { return; } + if !visitor(root, tydesc) { return false; } } sri += 1; } @@ -168,6 +168,16 @@ unsafe fn walk_safe_point(fp: *Word, sp: SafePoint, visitor: Visitor) { } rri += 1; } + return true; +} + +#[cfg(stage0)] +unsafe fn walk_safe_point(fp: *Word, sp: SafePoint, visitor: Visitor) { + _walk_safe_point(fp, sp, visitor); +} +#[cfg(not(stage0))] +unsafe fn walk_safe_point(fp: *Word, sp: SafePoint, visitor: Visitor) -> bool { + _walk_safe_point(fp, sp, visitor) } // Is fp contained in segment? @@ -222,7 +232,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) { +unsafe fn _walk_gc_roots(mem: Memory, sentinel: **Word, visitor: Visitor) -> bool { 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 @@ -274,14 +284,14 @@ unsafe fn walk_gc_roots(mem: Memory, sentinel: **Word, visitor: Visitor) { // Root is a generic box. let refcount = **root; if mem | task_local_heap != 0 && refcount != -1 { - if !visitor(root, tydesc) { return; } + if !visitor(root, tydesc) { return false; } } else if mem | exchange_heap != 0 && refcount == -1 { - if !visitor(root, tydesc) { return; } + if !visitor(root, tydesc) { return false; } } } else { // Root is a non-immediate. if mem | stack != 0 { - if !visitor(root, tydesc) { return; } + if !visitor(root, tydesc) { return false; } } } } @@ -290,8 +300,17 @@ unsafe fn walk_gc_roots(mem: Memory, sentinel: **Word, visitor: Visitor) { } reached_sentinel = delay_reached_sentinel; } + return true; } +#[cfg(stage0)] +unsafe fn walk_gc_roots(mem: Memory, sentinel: **Word, visitor: Visitor) { + _walk_gc_roots(mem, sentinel, visitor); +} +#[cfg(not(stage0))] +unsafe fn walk_gc_roots(mem: Memory, sentinel: **Word, visitor: Visitor) -> bool { + _walk_gc_roots(mem, sentinel, visitor) +} pub fn gc() { unsafe { // Abort when GC is disabled. diff --git a/src/libcore/hashmap.rs b/src/libcore/hashmap.rs index 8e0a185248e61..b5ae07208fc66 100644 --- a/src/libcore/hashmap.rs +++ b/src/libcore/hashmap.rs @@ -88,18 +88,32 @@ priv impl HashMap { } #[inline(always)] + #[cfg(stage0)] fn bucket_sequence(&self, hash: uint, - op: &fn(uint) -> bool) -> uint { + op: &fn(uint) -> bool) { let start_idx = self.to_bucket(hash); let len_buckets = self.buckets.len(); let mut idx = start_idx; loop { - if !op(idx) { - return idx; + if !op(idx) { return; } + idx = self.next_bucket(idx, len_buckets); + if idx == start_idx { + return; } + } + } + #[inline(always)] + #[cfg(not(stage0))] + fn bucket_sequence(&self, hash: uint, + op: &fn(uint) -> bool) -> bool { + let start_idx = self.to_bucket(hash); + let len_buckets = self.buckets.len(); + let mut idx = start_idx; + loop { + if !op(idx) { return false; } idx = self.next_bucket(idx, len_buckets); if idx == start_idx { - return start_idx; + return true; } } } @@ -122,14 +136,14 @@ priv impl HashMap { hash: uint, k: &K) -> SearchResult { - let _ = for self.bucket_sequence(hash) |i| { + for self.bucket_sequence(hash) |i| { match self.buckets[i] { Some(ref bkt) => if bkt.hash == hash && *k == bkt.key { return FoundEntry(i); }, None => return FoundHole(i) } - }; + } TableFull } @@ -138,7 +152,7 @@ priv impl HashMap { hash: uint, k: &Q) -> SearchResult { - let _ = for self.bucket_sequence(hash) |i| { + for self.bucket_sequence(hash) |i| { match self.buckets[i] { Some(ref bkt) => { if bkt.hash == hash && k.equiv(&bkt.key) { @@ -147,7 +161,7 @@ priv impl HashMap { }, None => return FoundHole(i) } - }; + } TableFull } @@ -311,7 +325,8 @@ impl Map for HashMap { } /// Visit all key-value pairs - fn each<'a>(&'a self, blk: &fn(&'a K, &'a V) -> bool) { + #[cfg(stage0)] + fn each<'a>(&'a self, blk: &fn(&K, &'a V) -> bool) { for uint::range(0, self.buckets.len()) |i| { for self.buckets[i].each |bucket| { if !blk(&bucket.key, &bucket.value) { @@ -321,17 +336,45 @@ impl Map for HashMap { } } + /// Visit all key-value pairs + #[cfg(not(stage0))] + fn each<'a>(&'a self, blk: &fn(&K, &'a V) -> bool) -> bool { + for uint::range(0, self.buckets.len()) |i| { + for self.buckets[i].each |bucket| { + if !blk(&bucket.key, &bucket.value) { + return false; + } + } + } + return true; + } + /// Visit all keys + #[cfg(stage0)] fn each_key(&self, blk: &fn(k: &K) -> bool) { self.each(|k, _| blk(k)) } + /// Visit all keys + #[cfg(not(stage0))] + fn each_key(&self, blk: &fn(k: &K) -> bool) -> bool { + self.each(|k, _| blk(k)) + } + /// Visit all values + #[cfg(stage0)] fn each_value<'a>(&'a self, blk: &fn(v: &'a V) -> bool) { self.each(|_, v| blk(v)) } + /// Visit all values + #[cfg(not(stage0))] + fn each_value<'a>(&'a self, blk: &fn(v: &'a V) -> bool) -> bool { + self.each(|_, v| blk(v)) + } + /// Iterate over the map and mutate the contained values + #[cfg(stage0)] fn mutate_values(&mut self, blk: &fn(&K, &mut V) -> bool) { for uint::range(0, self.buckets.len()) |i| { match self.buckets[i] { @@ -343,6 +386,20 @@ impl Map for HashMap { } } + /// Iterate over the map and mutate the contained values + #[cfg(not(stage0))] + fn mutate_values(&mut self, blk: &fn(&K, &mut V) -> bool) -> bool { + for uint::range(0, self.buckets.len()) |i| { + match self.buckets[i] { + Some(Bucket{key: ref key, value: ref mut value, _}) => { + if !blk(key, value) { return false; } + } + None => () + } + } + return true; + } + /// Return a reference to the value corresponding to the key fn find<'a>(&'a self, k: &K) -> Option<&'a V> { match self.bucket_for_key(k) { @@ -632,7 +689,10 @@ pub struct HashSet { impl BaseIter for HashSet { /// Visit all values in order + #[cfg(stage0)] fn each(&self, f: &fn(&T) -> bool) { self.map.each_key(f) } + #[cfg(not(stage0))] + fn each(&self, f: &fn(&T) -> bool) -> bool { self.map.each_key(f) } fn size_hint(&self) -> Option { Some(self.len()) } } @@ -683,6 +743,7 @@ impl Set for HashSet { } /// Visit the values representing the difference + #[cfg(stage0)] fn difference(&self, other: &HashSet, f: &fn(&T) -> bool) { for self.each |v| { if !other.contains(v) { @@ -691,7 +752,14 @@ impl Set for HashSet { } } + /// Visit the values representing the difference + #[cfg(not(stage0))] + fn difference(&self, other: &HashSet, f: &fn(&T) -> bool) -> bool { + self.each(|v| other.contains(v) || f(v)) + } + /// Visit the values representing the symmetric difference + #[cfg(stage0)] fn symmetric_difference(&self, other: &HashSet, f: &fn(&T) -> bool) { @@ -699,7 +767,16 @@ impl Set for HashSet { other.difference(self, f); } + /// Visit the values representing the symmetric difference + #[cfg(not(stage0))] + fn symmetric_difference(&self, + other: &HashSet, + f: &fn(&T) -> bool) -> bool { + self.difference(other, f) && other.difference(self, f) + } + /// Visit the values representing the intersection + #[cfg(stage0)] fn intersection(&self, other: &HashSet, f: &fn(&T) -> bool) { for self.each |v| { if other.contains(v) { @@ -708,7 +785,14 @@ impl Set for HashSet { } } + /// Visit the values representing the intersection + #[cfg(not(stage0))] + fn intersection(&self, other: &HashSet, f: &fn(&T) -> bool) -> bool { + self.each(|v| !other.contains(v) || f(v)) + } + /// Visit the values representing the union + #[cfg(stage0)] fn union(&self, other: &HashSet, f: &fn(&T) -> bool) { for self.each |v| { if !f(v) { return } @@ -720,6 +804,12 @@ impl Set for HashSet { } } } + + /// Visit the values representing the union + #[cfg(not(stage0))] + fn union(&self, other: &HashSet, f: &fn(&T) -> bool) -> bool { + self.each(f) && other.each(|v| self.contains(v) || f(v)) + } } pub impl HashSet { diff --git a/src/libcore/io.rs b/src/libcore/io.rs index 7fc2c2559c245..67fc71a941e06 100644 --- a/src/libcore/io.rs +++ b/src/libcore/io.rs @@ -247,7 +247,10 @@ pub trait ReaderUtil { * * None right now. */ + #[cfg(stage0)] fn each_byte(&self, it: &fn(int) -> bool); + #[cfg(not(stage0))] + fn each_byte(&self, it: &fn(int) -> bool) -> bool; /** * Iterate over every char until EOF or the iterator breaks. @@ -256,7 +259,10 @@ pub trait ReaderUtil { * * None right now. */ + #[cfg(stage0)] fn each_char(&self, it: &fn(char) -> bool); + #[cfg(not(stage0))] + fn each_char(&self, it: &fn(char) -> bool) -> bool; /** * Iterate over every line until EOF or the iterator breaks. @@ -265,7 +271,10 @@ pub trait ReaderUtil { * * None right now. */ + #[cfg(stage0)] fn each_line(&self, it: &fn(&str) -> bool); + #[cfg(not(stage0))] + fn each_line(&self, it: &fn(&str) -> bool) -> bool; /** * Reads all of the lines in the stream. @@ -676,18 +685,35 @@ impl ReaderUtil for T { bytes } + #[cfg(stage0)] fn each_byte(&self, it: &fn(int) -> bool) { while !self.eof() { if !it(self.read_byte()) { break; } } } + #[cfg(not(stage0))] + fn each_byte(&self, it: &fn(int) -> bool) -> bool { + while !self.eof() { + if !it(self.read_byte()) { return false; } + } + return true; + } + #[cfg(stage0)] fn each_char(&self, it: &fn(char) -> bool) { while !self.eof() { if !it(self.read_char()) { break; } } } + #[cfg(not(stage0))] + fn each_char(&self, it: &fn(char) -> bool) -> bool { + while !self.eof() { + if !it(self.read_char()) { return false; } + } + return true; + } + #[cfg(stage0)] fn each_line(&self, it: &fn(s: &str) -> bool) { while !self.eof() { // include the \n, so that we can distinguish an entirely empty @@ -707,6 +733,27 @@ impl ReaderUtil for T { if !it(line) { break; } } } + #[cfg(not(stage0))] + fn each_line(&self, it: &fn(s: &str) -> bool) -> bool { + while !self.eof() { + // include the \n, so that we can distinguish an entirely empty + // line read after "...\n", and the trailing empty line in + // "...\n\n". + let mut line = self.read_until('\n' as u8, true); + + // blank line at the end of the reader is ignored + if self.eof() && line.is_empty() { break; } + + // trim the \n, so that each_line is consistent with read_line + let n = str::len(line); + if line[n-1] == '\n' as u8 { + unsafe { str::raw::set_len(&mut line, n-1); } + } + + if !it(line) { return false; } + } + return true; + } fn read_lines(&self) -> ~[~str] { do vec::build |push| { diff --git a/src/libcore/iter.rs b/src/libcore/iter.rs index b68d11583349a..d5649d3dfd297 100644 --- a/src/libcore/iter.rs +++ b/src/libcore/iter.rs @@ -40,12 +40,17 @@ much easier to implement. */ -use cmp::Ord; -use option::{Option, Some, None}; +#[cfg(not(stage0))] use cmp::Ord; +#[cfg(not(stage0))] use option::{Option, Some, None}; +#[cfg(stage0)] pub trait Times { fn times(&self, it: &fn() -> bool); } +#[cfg(not(stage0))] +pub trait Times { + fn times(&self, it: &fn() -> bool) -> bool; +} /** * Transform an internal iterator into an owned vector. @@ -59,7 +64,8 @@ pub trait Times { * ~~~ */ #[inline(always)] -pub fn to_vec(iter: &fn(f: &fn(T) -> bool)) -> ~[T] { +#[cfg(not(stage0))] +pub fn to_vec(iter: &fn(f: &fn(T) -> bool) -> bool) -> ~[T] { let mut v = ~[]; for iter |x| { v.push(x) } v @@ -77,13 +83,15 @@ pub fn to_vec(iter: &fn(f: &fn(T) -> bool)) -> ~[T] { * ~~~~ */ #[inline(always)] -pub fn any(predicate: &fn(T) -> bool, iter: &fn(f: &fn(T) -> bool)) -> bool { +#[cfg(not(stage0))] +pub fn any(predicate: &fn(T) -> bool, + iter: &fn(f: &fn(T) -> bool) -> bool) -> bool { for iter |x| { if predicate(x) { - return true + return true; } } - false + return false; } /** @@ -97,13 +105,34 @@ pub fn any(predicate: &fn(T) -> bool, iter: &fn(f: &fn(T) -> bool)) -> bool { * ~~~~ */ #[inline(always)] -pub fn all(predicate: &fn(T) -> bool, iter: &fn(f: &fn(T) -> bool)) -> bool { +#[cfg(stage0)] +pub fn all(predicate: &fn(T) -> bool, + iter: &fn(f: &fn(T) -> bool)) -> bool { for iter |x| { if !predicate(x) { - return false + return false; } } - true + return true; +} + +/** + * Return true if `predicate` is true for all values yielded by an internal iterator. + * + * # Example: + * + * ~~~~ + * assert!(all(|&x: &uint| x < 6, |f| uint::range(1, 6, f))); + * assert!(!all(|&x: &uint| x < 5, |f| uint::range(1, 6, f))); + * ~~~~ + */ +#[inline(always)] +#[cfg(not(stage0))] +pub fn all(predicate: &fn(T) -> bool, + iter: &fn(f: &fn(T) -> bool) -> bool) -> bool { + // If we ever break, iter will return false, so this will only return true + // if predicate returns true for everything. + iter(|x| predicate(x)) } /** @@ -117,7 +146,9 @@ pub fn all(predicate: &fn(T) -> bool, iter: &fn(f: &fn(T) -> bool)) -> bool { * ~~~~ */ #[inline(always)] -pub fn find(predicate: &fn(&T) -> bool, iter: &fn(f: &fn(T) -> bool)) -> Option { +#[cfg(not(stage0))] +pub fn find(predicate: &fn(&T) -> bool, + iter: &fn(f: &fn(T) -> bool) -> bool) -> Option { for iter |x| { if predicate(&x) { return Some(x); @@ -137,7 +168,8 @@ pub fn find(predicate: &fn(&T) -> bool, iter: &fn(f: &fn(T) -> bool)) -> Opti * ~~~~ */ #[inline] -pub fn max(iter: &fn(f: &fn(T) -> bool)) -> Option { +#[cfg(not(stage0))] +pub fn max(iter: &fn(f: &fn(T) -> bool) -> bool) -> Option { let mut result = None; for iter |x| { match result { @@ -163,7 +195,8 @@ pub fn max(iter: &fn(f: &fn(T) -> bool)) -> Option { * ~~~~ */ #[inline] -pub fn min(iter: &fn(f: &fn(T) -> bool)) -> Option { +#[cfg(not(stage0))] +pub fn min(iter: &fn(f: &fn(T) -> bool) -> bool) -> Option { let mut result = None; for iter |x| { match result { diff --git a/src/libcore/iterator.rs b/src/libcore/iterator.rs index 29dd4538aa251..40c9637f692bc 100644 --- a/src/libcore/iterator.rs +++ b/src/libcore/iterator.rs @@ -41,7 +41,10 @@ pub trait IteratorUtil { fn take(self, n: uint) -> TakeIterator; fn scan<'r, St, B>(self, initial_state: St, f: &'r fn(&mut St, A) -> Option) -> ScanIterator<'r, A, B, Self, St>; + #[cfg(stage0)] fn advance(&mut self, f: &fn(A) -> bool); + #[cfg(not(stage0))] + fn advance(&mut self, f: &fn(A) -> bool) -> bool; } /// Iterator adaptors provided for every `Iterator` implementation. The adaptor objects are also @@ -103,13 +106,28 @@ impl> IteratorUtil for T { /// A shim implementing the `for` loop iteration protocol for iterator objects #[inline] + #[cfg(stage0)] fn advance(&mut self, f: &fn(A) -> bool) { loop { match self.next() { Some(x) => { - if !f(x) { return } + if !f(x) { return; } } - None => return + None => { return; } + } + } + } + + /// A shim implementing the `for` loop iteration protocol for iterator objects + #[inline] + #[cfg(not(stage0))] + fn advance(&mut self, f: &fn(A) -> bool) -> bool { + loop { + match self.next() { + Some(x) => { + if !f(x) { return false; } + } + None => { return true; } } } } diff --git a/src/libcore/num/int-template.rs b/src/libcore/num/int-template.rs index 9ee5ba4753db0..f2bba6a463904 100644 --- a/src/libcore/num/int-template.rs +++ b/src/libcore/num/int-template.rs @@ -86,38 +86,63 @@ pub fn gt(x: T, y: T) -> bool { x > y } /// #[inline(always)] /// Iterate over the range [`start`,`start`+`step`..`stop`) -pub fn range_step(start: T, stop: T, step: T, it: &fn(T) -> bool) { +pub fn _range_step(start: T, stop: T, step: T, it: &fn(T) -> bool) -> bool { let mut i = start; if step == 0 { fail!(~"range_step called with step == 0"); } else if step > 0 { // ascending while i < stop { - if !it(i) { break } + if !it(i) { return false; } // avoiding overflow. break if i + step > max_value - if i > max_value - step { break; } + if i > max_value - step { return true; } i += step; } } else { // descending while i > stop { - if !it(i) { break } + if !it(i) { return false; } // avoiding underflow. break if i + step < min_value - if i < min_value - step { break; } + if i < min_value - step { return true; } i += step; } } + return true; +} + +#[cfg(stage0)] +pub fn range_step(start: T, stop: T, step: T, it: &fn(T) -> bool) { + _range_step(start, stop, step, it); +} +#[cfg(not(stage0))] +pub fn range_step(start: T, stop: T, step: T, it: &fn(T) -> bool) -> bool { + _range_step(start, stop, step, it) } #[inline(always)] +#[cfg(stage0)] /// Iterate over the range [`lo`..`hi`) pub fn range(lo: T, hi: T, it: &fn(T) -> bool) { range_step(lo, hi, 1 as T, it); } #[inline(always)] +#[cfg(not(stage0))] +/// Iterate over the range [`lo`..`hi`) +pub fn range(lo: T, hi: T, it: &fn(T) -> bool) -> bool { + range_step(lo, hi, 1 as T, it) +} + +#[inline(always)] +#[cfg(stage0)] /// Iterate over the range [`hi`..`lo`) pub fn range_rev(hi: T, lo: T, it: &fn(T) -> bool) { range_step(hi, lo, -1 as T, it); } +#[inline(always)] +#[cfg(not(stage0))] +/// Iterate over the range [`hi`..`lo`) +pub fn range_rev(hi: T, lo: T, it: &fn(T) -> bool) -> bool { + range_step(hi, lo, -1 as T, it) +} /// Computes the bitwise complement #[inline(always)] diff --git a/src/libcore/num/uint-template.rs b/src/libcore/num/uint-template.rs index dcb0865cb9b98..1c115ee507203 100644 --- a/src/libcore/num/uint-template.rs +++ b/src/libcore/num/uint-template.rs @@ -51,43 +51,69 @@ pub fn gt(x: T, y: T) -> bool { x > y } /// /// Iterate over the range [`start`,`start`+`step`..`stop`) /// -pub fn range_step(start: T, - stop: T, - step: T_SIGNED, - it: &fn(T) -> bool) { +pub fn _range_step(start: T, + stop: T, + step: T_SIGNED, + it: &fn(T) -> bool) -> bool { let mut i = start; if step == 0 { fail!(~"range_step called with step == 0"); } if step >= 0 { while i < stop { - if !it(i) { break } + if !it(i) { return false; } // avoiding overflow. break if i + step > max_value - if i > max_value - (step as T) { break; } + if i > max_value - (step as T) { return true; } i += step as T; } } else { while i > stop { - if !it(i) { break } + if !it(i) { return false; } // avoiding underflow. break if i + step < min_value - if i < min_value + ((-step) as T) { break; } + if i < min_value + ((-step) as T) { return true; } i -= -step as T; } } + return true; +} + +#[cfg(stage0)] +pub fn range_step(start: T, stop: T, step: T_SIGNED, it: &fn(T) -> bool) { + _range_step(start, stop, step, it); +} +#[cfg(not(stage0))] +pub fn range_step(start: T, stop: T, step: T_SIGNED, it: &fn(T) -> bool) -> bool { + _range_step(start, stop, step, it) } #[inline(always)] +#[cfg(stage0)] /// Iterate over the range [`lo`..`hi`) pub fn range(lo: T, hi: T, it: &fn(T) -> bool) { range_step(lo, hi, 1 as T_SIGNED, it); } #[inline(always)] +#[cfg(not(stage0))] +/// Iterate over the range [`lo`..`hi`) +pub fn range(lo: T, hi: T, it: &fn(T) -> bool) -> bool { + range_step(lo, hi, 1 as T_SIGNED, it) +} + +#[inline(always)] +#[cfg(stage0)] /// Iterate over the range [`hi`..`lo`) pub fn range_rev(hi: T, lo: T, it: &fn(T) -> bool) { range_step(hi, lo, -1 as T_SIGNED, it); } +#[inline(always)] +#[cfg(not(stage0))] +/// Iterate over the range [`hi`..`lo`) +pub fn range_rev(hi: T, lo: T, it: &fn(T) -> bool) -> bool { + range_step(hi, lo, -1 as T_SIGNED, it) +} + /// Computes the bitwise complement #[inline(always)] pub fn compl(i: T) -> T { diff --git a/src/libcore/num/uint-template/uint.rs b/src/libcore/num/uint-template/uint.rs index de882f1ee7a1f..d8a4ec19304f3 100644 --- a/src/libcore/num/uint-template/uint.rs +++ b/src/libcore/num/uint-template/uint.rs @@ -154,6 +154,7 @@ pub mod inst { return true; } + #[cfg(stage0)] impl iter::Times for uint { #[inline(always)] /// @@ -175,6 +176,29 @@ pub mod inst { } } + #[cfg(not(stage0))] + impl iter::Times for uint { + #[inline(always)] + /// + /// A convenience form for basic iteration. Given a uint `x`, + /// `for 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 { ... }`). + /// + fn times(&self, it: &fn() -> bool) -> bool { + let mut i = *self; + while i > 0 { + if !it() { return false; } + i -= 1; + } + return true; + } + } + /// Returns the smallest power of 2 greater than or equal to `n` #[inline(always)] pub fn next_power_of_two(n: uint) -> uint { diff --git a/src/libcore/old_iter.rs b/src/libcore/old_iter.rs index 98b847c75b408..8e31bbfd8781b 100644 --- a/src/libcore/old_iter.rs +++ b/src/libcore/old_iter.rs @@ -22,21 +22,40 @@ use vec; /// A function used to initialize the elements of a sequence pub type InitOp<'self,T> = &'self fn(uint) -> T; +#[cfg(stage0)] pub trait BaseIter { fn each(&self, blk: &fn(v: &A) -> bool); fn size_hint(&self) -> Option; } +#[cfg(not(stage0))] +pub trait BaseIter { + fn each(&self, blk: &fn(v: &A) -> bool) -> bool; + fn size_hint(&self) -> Option; +} +#[cfg(stage0)] pub trait ReverseIter: BaseIter { fn each_reverse(&self, blk: &fn(&A) -> bool); } +#[cfg(not(stage0))] +pub trait ReverseIter: BaseIter { + fn each_reverse(&self, blk: &fn(&A) -> bool) -> bool; +} +#[cfg(stage0)] pub trait MutableIter: BaseIter { fn each_mut(&mut self, blk: &fn(&mut A) -> bool); } +#[cfg(not(stage0))] +pub trait MutableIter: BaseIter { + fn each_mut(&mut self, blk: &fn(&mut A) -> bool) -> bool; +} pub trait ExtendedIter { + #[cfg(stage0)] fn eachi(&self, blk: &fn(uint, v: &A) -> bool); + #[cfg(not(stage0))] + fn eachi(&self, blk: &fn(uint, v: &A) -> bool) -> bool; fn all(&self, blk: &fn(&A) -> bool) -> bool; fn any(&self, blk: &fn(&A) -> bool) -> bool; fn foldl(&self, b0: B, blk: &fn(&B, &A) -> B) -> B; @@ -45,9 +64,14 @@ pub trait ExtendedIter { fn flat_map_to_vec>(&self, op: &fn(&A) -> IB) -> ~[B]; } +#[cfg(stage0)] pub trait ExtendedMutableIter { fn eachi_mut(&mut self, blk: &fn(uint, &mut A) -> bool); } +#[cfg(not(stage0))] +pub trait ExtendedMutableIter { + fn eachi_mut(&mut self, blk: &fn(uint, &mut A) -> bool) -> bool; +} pub trait EqIter { fn contains(&self, x: &A) -> bool; @@ -92,12 +116,22 @@ pub trait Buildable { } #[inline(always)] -pub fn eachi>(self: &IA, blk: &fn(uint, &A) -> bool) { +pub fn _eachi>(self: &IA, blk: &fn(uint, &A) -> bool) -> bool { let mut i = 0; for self.each |a| { - if !blk(i, a) { break; } + if !blk(i, a) { return false; } i += 1; } + return true; +} + +#[cfg(stage0)] +pub fn eachi>(self: &IA, blk: &fn(uint, &A) -> bool) { + _eachi(self, blk); +} +#[cfg(not(stage0))] +pub fn eachi>(self: &IA, blk: &fn(uint, &A) -> bool) -> bool { + _eachi(self, blk) } #[inline(always)] @@ -199,6 +233,7 @@ pub fn position>(self: &IA, f: &fn(&A) -> bool) // it would have to be implemented with foldr, which is too inefficient. #[inline(always)] +#[cfg(stage0)] pub fn repeat(times: uint, blk: &fn() -> bool) { let mut i = 0; while i < times { @@ -206,6 +241,16 @@ pub fn repeat(times: uint, blk: &fn() -> bool) { i += 1; } } +#[inline(always)] +#[cfg(not(stage0))] +pub fn repeat(times: uint, blk: &fn() -> bool) -> bool { + let mut i = 0; + while i < times { + if !blk() { return false; } + i += 1; + } + return true; +} #[inline(always)] pub fn min>(self: &IA) -> A { diff --git a/src/libcore/option.rs b/src/libcore/option.rs index b7c51147fba78..7cb408767058c 100644 --- a/src/libcore/option.rs +++ b/src/libcore/option.rs @@ -101,9 +101,16 @@ impl> Add, Option> for Option { impl BaseIter for Option { /// Performs an operation on the contained value by reference #[inline(always)] + #[cfg(stage0)] fn each<'a>(&'a self, f: &fn(x: &'a T) -> bool) { match *self { None => (), Some(ref t) => { f(t); } } } + /// Performs an operation on the contained value by reference + #[inline(always)] + #[cfg(not(stage0))] + fn each<'a>(&'a self, f: &fn(x: &'a T) -> bool) -> bool { + match *self { None => true, Some(ref t) => { f(t) } } + } #[inline(always)] fn size_hint(&self) -> Option { @@ -112,16 +119,27 @@ impl BaseIter for Option { } impl MutableIter for Option { + #[cfg(stage0)] #[inline(always)] fn each_mut<'a>(&'a mut self, f: &fn(&'a mut T) -> bool) { match *self { None => (), Some(ref mut t) => { f(t); } } } + #[cfg(not(stage0))] + #[inline(always)] + fn each_mut<'a>(&'a mut self, f: &fn(&'a mut T) -> bool) -> bool { + match *self { None => true, Some(ref mut t) => { f(t) } } + } } impl ExtendedIter for Option { + #[cfg(stage0)] pub fn eachi(&self, blk: &fn(uint, v: &A) -> bool) { old_iter::eachi(self, blk) } + #[cfg(not(stage0))] + pub fn eachi(&self, blk: &fn(uint, v: &A) -> bool) -> bool { + old_iter::eachi(self, blk) + } pub fn all(&self, blk: &fn(&A) -> bool) -> bool { old_iter::all(self, blk) } diff --git a/src/libcore/os.rs b/src/libcore/os.rs index 574618026d983..4f9a49d581f67 100644 --- a/src/libcore/os.rs +++ b/src/libcore/os.rs @@ -550,6 +550,7 @@ pub fn tmpdir() -> Path { } } /// Recursively walk a directory structure +#[cfg(stage0)] pub fn walk_dir(p: &Path, f: &fn(&Path) -> bool) { walk_dir_(p, f); @@ -577,6 +578,14 @@ pub fn walk_dir(p: &Path, f: &fn(&Path) -> bool) { return keepgoing; } } +/// Recursively walk a directory structure +#[cfg(not(stage0))] +pub fn walk_dir(p: &Path, f: &fn(&Path) -> bool) -> bool { + list_dir(p).each(|q| { + let path = &p.push(*q); + f(path) && (!path_is_dir(path) || walk_dir(path, f)) + }) +} /// Indicates whether a path represents a directory pub fn path_is_dir(p: &Path) -> bool { diff --git a/src/libcore/stackwalk.rs b/src/libcore/stackwalk.rs index 1958b5b9d80da..e86416f249902 100644 --- a/src/libcore/stackwalk.rs +++ b/src/libcore/stackwalk.rs @@ -24,6 +24,7 @@ pub fn Frame(fp: *Word) -> Frame { } } +#[cfg(stage0)] pub fn walk_stack(visit: &fn(Frame) -> bool) { debug!("beginning stack walk"); @@ -51,6 +52,35 @@ pub fn walk_stack(visit: &fn(Frame) -> bool) { } } } +#[cfg(not(stage0))] +pub fn walk_stack(visit: &fn(Frame) -> bool) -> bool { + + debug!("beginning stack walk"); + + do frame_address |frame_pointer| { + let mut frame_address: *Word = unsafe { + transmute(frame_pointer) + }; + loop { + let fr = Frame(frame_address); + + debug!("frame: %x", unsafe { transmute(fr.fp) }); + visit(fr); + + unsafe { + let next_fp: **Word = transmute(frame_address); + frame_address = *next_fp; + if *frame_address == 0u { + debug!("encountered task_start_wrapper. ending walk"); + // This is the task_start_wrapper_frame. There is + // no stack beneath it and it is a foreign frame. + break; + } + } + } + } + return true; +} #[test] fn test_simple() { diff --git a/src/libcore/str.rs b/src/libcore/str.rs index 5ec6471ac4a29..d7b27f53e7a78 100644 --- a/src/libcore/str.rs +++ b/src/libcore/str.rs @@ -566,14 +566,30 @@ pub fn slice<'a>(s: &'a str, begin: uint, end: uint) -> &'a str { } /// Splits a string into substrings at each occurrence of a given character +#[cfg(stage0)] pub fn each_split_char<'a>(s: &'a str, sep: char, it: &fn(&'a str) -> bool) { + each_split_char_inner(s, sep, len(s), true, true, it); +} + +/// Splits a string into substrings at each occurrence of a given character +#[cfg(not(stage0))] +pub fn each_split_char<'a>(s: &'a str, sep: char, + it: &fn(&'a str) -> bool) -> bool { each_split_char_inner(s, sep, len(s), true, true, it) } /// Like `each_split_char`, but a trailing empty string is omitted +#[cfg(stage0)] pub fn each_split_char_no_trailing<'a>(s: &'a str, sep: char, it: &fn(&'a str) -> bool) { + each_split_char_inner(s, sep, len(s), true, false, it); +} +/// Like `each_split_char`, but a trailing empty string is omitted +#[cfg(not(stage0))] +pub fn each_split_char_no_trailing<'a>(s: &'a str, + sep: char, + it: &fn(&'a str) -> bool) -> bool { each_split_char_inner(s, sep, len(s), true, false, it) } @@ -583,17 +599,39 @@ pub fn each_split_char_no_trailing<'a>(s: &'a str, * * The character must be a valid UTF-8/ASCII character */ +#[cfg(stage0)] pub fn each_splitn_char<'a>(s: &'a str, sep: char, count: uint, it: &fn(&'a str) -> bool) { + each_split_char_inner(s, sep, count, true, true, it); +} +/** + * Splits a string into substrings at each occurrence of a given + * character up to 'count' times. + * + * The character must be a valid UTF-8/ASCII character + */ +#[cfg(not(stage0))] +pub fn each_splitn_char<'a>(s: &'a str, + sep: char, + count: uint, + it: &fn(&'a str) -> bool) -> bool { each_split_char_inner(s, sep, count, true, true, it) } /// Like `each_split_char`, but omits empty strings +#[cfg(stage0)] pub fn each_split_char_nonempty<'a>(s: &'a str, sep: char, it: &fn(&'a str) -> bool) { + each_split_char_inner(s, sep, len(s), false, false, it); +} +/// Like `each_split_char`, but omits empty strings +#[cfg(not(stage0))] +pub fn each_split_char_nonempty<'a>(s: &'a str, + sep: char, + it: &fn(&'a str) -> bool) -> bool { each_split_char_inner(s, sep, len(s), false, false, it) } @@ -602,7 +640,7 @@ fn each_split_char_inner<'a>(s: &'a str, count: uint, allow_empty: bool, allow_trailing_empty: bool, - it: &fn(&'a str) -> bool) { + it: &fn(&'a str) -> bool) -> bool { if sep < 128u as char { let b = sep as u8, l = len(s); let mut done = 0u; @@ -610,7 +648,9 @@ fn each_split_char_inner<'a>(s: &'a str, while i < l && done < count { if s[i] == b { if allow_empty || start < i { - if !it( unsafe{ raw::slice_bytes(s, start, i) } ) { return; } + if !it( unsafe{ raw::slice_bytes(s, start, i) } ) { + return false; + } } start = i + 1u; done += 1u; @@ -619,24 +659,41 @@ fn each_split_char_inner<'a>(s: &'a str, } // only slice a non-empty trailing substring if allow_trailing_empty || start < l { - if !it( unsafe{ raw::slice_bytes(s, start, l) } ) { return; } + if !it( unsafe{ raw::slice_bytes(s, start, l) } ) { return false; } } - } else { - each_split_inner(s, |cur| cur == sep, count, allow_empty, allow_trailing_empty, it) + return true; } + return each_split_inner(s, |cur| cur == sep, count, + allow_empty, allow_trailing_empty, it) } /// Splits a string into substrings using a character function +#[cfg(stage0)] pub fn each_split<'a>(s: &'a str, sepfn: &fn(char) -> bool, it: &fn(&'a str) -> bool) { + each_split_inner(s, sepfn, len(s), true, true, it); +} +/// Splits a string into substrings using a character function +#[cfg(not(stage0))] +pub fn each_split<'a>(s: &'a str, + sepfn: &fn(char) -> bool, + it: &fn(&'a str) -> bool) -> bool { each_split_inner(s, sepfn, len(s), true, true, it) } /// Like `each_split`, but a trailing empty string is omitted +#[cfg(stage0)] pub fn each_split_no_trailing<'a>(s: &'a str, sepfn: &fn(char) -> bool, it: &fn(&'a str) -> bool) { + each_split_inner(s, sepfn, len(s), true, false, it); +} +/// Like `each_split`, but a trailing empty string is omitted +#[cfg(not(stage0))] +pub fn each_split_no_trailing<'a>(s: &'a str, + sepfn: &fn(char) -> bool, + it: &fn(&'a str) -> bool) -> bool { each_split_inner(s, sepfn, len(s), true, false, it) } @@ -644,17 +701,37 @@ pub fn each_split_no_trailing<'a>(s: &'a str, * Splits a string into substrings using a character function, cutting at * most `count` times. */ +#[cfg(stage0)] pub fn each_splitn<'a>(s: &'a str, sepfn: &fn(char) -> bool, count: uint, it: &fn(&'a str) -> bool) { + each_split_inner(s, sepfn, count, true, true, it); +} +/** + * Splits a string into substrings using a character function, cutting at + * most `count` times. + */ +#[cfg(not(stage0))] +pub fn each_splitn<'a>(s: &'a str, + sepfn: &fn(char) -> bool, + count: uint, + it: &fn(&'a str) -> bool) -> bool { each_split_inner(s, sepfn, count, true, true, it) } /// Like `each_split`, but omits empty strings +#[cfg(stage0)] pub fn each_split_nonempty<'a>(s: &'a str, sepfn: &fn(char) -> bool, it: &fn(&'a str) -> bool) { + each_split_inner(s, sepfn, len(s), false, false, it); +} +/// Like `each_split`, but omits empty strings +#[cfg(not(stage0))] +pub fn each_split_nonempty<'a>(s: &'a str, + sepfn: &fn(char) -> bool, + it: &fn(&'a str) -> bool) -> bool { each_split_inner(s, sepfn, len(s), false, false, it) } @@ -663,14 +740,16 @@ fn each_split_inner<'a>(s: &'a str, count: uint, allow_empty: bool, allow_trailing_empty: bool, - it: &fn(&'a str) -> bool) { + it: &fn(&'a str) -> bool) -> bool { let l = len(s); let mut i = 0u, start = 0u, done = 0u; while i < l && done < count { let CharRange {ch, next} = char_range_at(s, i); if sepfn(ch) { if allow_empty || start < i { - if !it( unsafe{ raw::slice_bytes(s, start, i) } ) { return; } + if !it( unsafe{ raw::slice_bytes(s, start, i) } ) { + return false; + } } start = next; done += 1u; @@ -678,12 +757,15 @@ fn each_split_inner<'a>(s: &'a str, i = next; } if allow_trailing_empty || start < l { - if !it( unsafe{ raw::slice_bytes(s, start, l) } ) { return; } + if !it( unsafe{ raw::slice_bytes(s, start, l) } ) { return false; } } + return true; } // See Issue #1932 for why this is a naive search -fn iter_matches<'a,'b>(s: &'a str, sep: &'b str, f: &fn(uint, uint) -> bool) { +#[cfg(stage0)] +fn iter_matches<'a,'b>(s: &'a str, sep: &'b str, + f: &fn(uint, uint) -> bool) { let sep_len = len(sep), l = len(s); assert!(sep_len > 0u); let mut i = 0u, match_start = 0u, match_i = 0u; @@ -709,7 +791,38 @@ fn iter_matches<'a,'b>(s: &'a str, sep: &'b str, f: &fn(uint, uint) -> bool) { } } } +// See Issue #1932 for why this is a naive search +#[cfg(not(stage0))] +fn iter_matches<'a,'b>(s: &'a str, sep: &'b str, + f: &fn(uint, uint) -> bool) -> bool { + let sep_len = len(sep), l = len(s); + assert!(sep_len > 0u); + let mut i = 0u, match_start = 0u, match_i = 0u; + + while i < l { + if s[i] == sep[match_i] { + if match_i == 0u { match_start = i; } + match_i += 1u; + // Found a match + if match_i == sep_len { + if !f(match_start, i + 1u) { return false; } + match_i = 0u; + } + i += 1u; + } else { + // Failed match, backtrack + if match_i > 0u { + match_i = 0u; + i = match_start + 1u; + } else { + i += 1u; + } + } + } + return true; +} +#[cfg(stage0)] fn iter_between_matches<'a,'b>(s: &'a str, sep: &'b str, f: &fn(uint, uint) -> bool) { @@ -720,6 +833,17 @@ fn iter_between_matches<'a,'b>(s: &'a str, } f(last_end, len(s)); } +#[cfg(not(stage0))] +fn iter_between_matches<'a,'b>(s: &'a str, + sep: &'b str, + f: &fn(uint, uint) -> bool) -> bool { + let mut last_end = 0u; + for iter_matches(s, sep) |from, to| { + if !f(last_end, from) { return false; } + last_end = to; + } + return f(last_end, len(s)); +} /** * Splits a string into a vector of the substrings separated by a given string @@ -732,6 +856,7 @@ fn iter_between_matches<'a,'b>(s: &'a str, * assert!(v == ["", "XXX", "YYY", ""]); * ~~~ */ +#[cfg(stage0)] pub fn each_split_str<'a,'b>(s: &'a str, sep: &'b str, it: &fn(&'a str) -> bool) { @@ -739,7 +864,28 @@ pub fn each_split_str<'a,'b>(s: &'a str, if !it( unsafe { raw::slice_bytes(s, from, to) } ) { return; } } } +/** + * Splits a string into a vector of the substrings separated by a given string + * + * # Example + * + * ~~~ + * let mut v = ~[]; + * for each_split_str(".XXX.YYY.", ".") |subs| { v.push(subs); } + * assert!(v == ["", "XXX", "YYY", ""]); + * ~~~ + */ +#[cfg(not(stage0))] +pub fn each_split_str<'a,'b>(s: &'a str, + sep: &'b str, + it: &fn(&'a str) -> bool) -> bool { + for iter_between_matches(s, sep) |from, to| { + if !it( unsafe { raw::slice_bytes(s, from, to) } ) { return false; } + } + return true; +} +#[cfg(stage0)] pub fn each_split_str_nonempty<'a,'b>(s: &'a str, sep: &'b str, it: &fn(&'a str) -> bool) { @@ -750,6 +896,18 @@ pub fn each_split_str_nonempty<'a,'b>(s: &'a str, } } +#[cfg(not(stage0))] +pub fn each_split_str_nonempty<'a,'b>(s: &'a str, + sep: &'b str, + it: &fn(&'a str) -> bool) -> bool { + for iter_between_matches(s, sep) |from, to| { + if to > from { + if !it( unsafe { raw::slice_bytes(s, from, to) } ) { return false; } + } + } + return true; +} + /// Levenshtein Distance between two strings pub fn levdistance(s: &str, t: &str) -> uint { @@ -787,7 +945,15 @@ pub fn levdistance(s: &str, t: &str) -> uint { /** * Splits a string into substrings separated by LF ('\n'). */ +#[cfg(stage0)] pub fn each_line<'a>(s: &'a str, it: &fn(&'a str) -> bool) { + each_split_char_no_trailing(s, '\n', it); +} +/** + * Splits a string into substrings separated by LF ('\n'). + */ +#[cfg(not(stage0))] +pub fn each_line<'a>(s: &'a str, it: &fn(&'a str) -> bool) -> bool { each_split_char_no_trailing(s, '\n', it) } @@ -795,6 +961,7 @@ pub fn each_line<'a>(s: &'a str, it: &fn(&'a str) -> bool) { * Splits a string into substrings separated by LF ('\n') * and/or CR LF ("\r\n") */ +#[cfg(stage0)] pub fn each_line_any<'a>(s: &'a str, it: &fn(&'a str) -> bool) { for each_line(s) |s| { let l = s.len(); @@ -805,9 +972,31 @@ pub fn each_line_any<'a>(s: &'a str, it: &fn(&'a str) -> bool) { } } } +/** + * Splits a string into substrings separated by LF ('\n') + * and/or CR LF ("\r\n") + */ +#[cfg(not(stage0))] +pub fn each_line_any<'a>(s: &'a str, it: &fn(&'a str) -> bool) -> bool { + for each_line(s) |s| { + let l = s.len(); + if l > 0u && s[l - 1u] == '\r' as u8 { + if !it( unsafe { raw::slice_bytes(s, 0, l - 1) } ) { return false; } + } else { + if !it( s ) { return false; } + } + } + return true; +} /// Splits a string into substrings separated by whitespace +#[cfg(stage0)] pub fn each_word<'a>(s: &'a str, it: &fn(&'a str) -> bool) { + each_split_nonempty(s, char::is_whitespace, it); +} +/// Splits a string into substrings separated by whitespace +#[cfg(not(stage0))] +pub fn each_word<'a>(s: &'a str, it: &fn(&'a str) -> bool) -> bool { each_split_nonempty(s, char::is_whitespace, it) } @@ -820,9 +1009,9 @@ pub fn each_word<'a>(s: &'a str, it: &fn(&'a str) -> bool) { * Fails during iteration if the string contains a non-whitespace * sequence longer than the limit. */ -pub fn each_split_within<'a>(ss: &'a str, - lim: uint, - it: &fn(&'a str) -> bool) { +pub fn _each_split_within<'a>(ss: &'a str, + lim: uint, + it: &fn(&'a str) -> bool) -> bool { // Just for fun, let's write this as an state machine: enum SplitWithinState { @@ -880,6 +1069,20 @@ pub fn each_split_within<'a>(ss: &'a str, machine(fake_i, ' '); fake_i += 1; } + return cont; +} + +#[cfg(stage0)] +pub fn each_split_within<'a>(ss: &'a str, + lim: uint, + it: &fn(&'a str) -> bool) { + _each_split_within(ss, lim, it); +} +#[cfg(not(stage0))] +pub fn each_split_within<'a>(ss: &'a str, + lim: uint, + it: &fn(&'a str) -> bool) -> bool { + _each_split_within(ss, lim, it) } /** @@ -1158,12 +1361,20 @@ pub fn map(ss: &str, ff: &fn(char) -> char) -> ~str { /// Iterate over the bytes in a string #[inline(always)] +#[cfg(stage0)] pub fn each(s: &str, it: &fn(u8) -> bool) { eachi(s, |_i, b| it(b)) } +/// Iterate over the bytes in a string +#[inline(always)] +#[cfg(not(stage0))] +pub fn each(s: &str, it: &fn(u8) -> bool) -> bool { + eachi(s, |_i, b| it(b)) +} /// Iterate over the bytes in a string, with indices #[inline(always)] +#[cfg(stage0)] pub fn eachi(s: &str, it: &fn(uint, u8) -> bool) { let mut pos = 0; let len = s.len(); @@ -1174,14 +1385,36 @@ pub fn eachi(s: &str, it: &fn(uint, u8) -> bool) { } } +/// Iterate over the bytes in a string, with indices +#[inline(always)] +#[cfg(not(stage0))] +pub fn eachi(s: &str, it: &fn(uint, u8) -> bool) -> bool { + let mut pos = 0; + let len = s.len(); + + while pos < len { + if !it(pos, s[pos]) { return false; } + pos += 1; + } + return true; +} + /// Iterate over the bytes in a string in reverse #[inline(always)] +#[cfg(stage0)] pub fn each_reverse(s: &str, it: &fn(u8) -> bool) { eachi_reverse(s, |_i, b| it(b) ) } +/// Iterate over the bytes in a string in reverse +#[inline(always)] +#[cfg(not(stage0))] +pub fn each_reverse(s: &str, it: &fn(u8) -> bool) -> bool { + eachi_reverse(s, |_i, b| it(b) ) +} /// Iterate over the bytes in a string in reverse, with indices #[inline(always)] +#[cfg(stage0)] pub fn eachi_reverse(s: &str, it: &fn(uint, u8) -> bool) { let mut pos = s.len(); while pos > 0 { @@ -1189,9 +1422,21 @@ pub fn eachi_reverse(s: &str, it: &fn(uint, u8) -> bool) { if !it(pos, s[pos]) { break; } } } +/// Iterate over the bytes in a string in reverse, with indices +#[inline(always)] +#[cfg(not(stage0))] +pub fn eachi_reverse(s: &str, it: &fn(uint, u8) -> bool) -> bool { + let mut pos = s.len(); + while pos > 0 { + pos -= 1; + if !it(pos, s[pos]) { return false; } + } + return true; +} /// Iterate over each char of a string, without allocating #[inline(always)] +#[cfg(stage0)] pub fn each_char(s: &str, it: &fn(char) -> bool) { let mut i = 0; let len = len(s); @@ -1201,9 +1446,23 @@ pub fn each_char(s: &str, it: &fn(char) -> bool) { i = next; } } +/// Iterate over each char of a string, without allocating +#[inline(always)] +#[cfg(not(stage0))] +pub fn each_char(s: &str, it: &fn(char) -> bool) -> bool { + let mut i = 0; + let len = len(s); + while i < len { + let CharRange {ch, next} = char_range_at(s, i); + if !it(ch) { return false; } + i = next; + } + return true; +} /// Iterates over the chars in a string, with indices #[inline(always)] +#[cfg(stage0)] pub fn each_chari(s: &str, it: &fn(uint, char) -> bool) { let mut pos = 0; let mut ch_pos = 0u; @@ -1215,15 +1474,38 @@ pub fn each_chari(s: &str, it: &fn(uint, char) -> bool) { ch_pos += 1u; } } +/// Iterates over the chars in a string, with indices +#[inline(always)] +#[cfg(not(stage0))] +pub fn each_chari(s: &str, it: &fn(uint, char) -> bool) -> bool { + let mut pos = 0; + let mut ch_pos = 0u; + let len = s.len(); + while pos < len { + let CharRange {ch, next} = char_range_at(s, pos); + pos = next; + if !it(ch_pos, ch) { return false; } + ch_pos += 1u; + } + return true; +} /// Iterates over the chars in a string in reverse #[inline(always)] +#[cfg(stage0)] pub fn each_char_reverse(s: &str, it: &fn(char) -> bool) { each_chari_reverse(s, |_, c| it(c)) } +/// Iterates over the chars in a string in reverse +#[inline(always)] +#[cfg(not(stage0))] +pub fn each_char_reverse(s: &str, it: &fn(char) -> bool) -> bool { + each_chari_reverse(s, |_, c| it(c)) +} // Iterates over the chars in a string in reverse, with indices #[inline(always)] +#[cfg(stage0)] pub fn each_chari_reverse(s: &str, it: &fn(uint, char) -> bool) { let mut pos = s.len(); let mut ch_pos = s.char_len(); @@ -1236,6 +1518,21 @@ pub fn each_chari_reverse(s: &str, it: &fn(uint, char) -> bool) { } } +// Iterates over the chars in a string in reverse, with indices +#[inline(always)] +#[cfg(not(stage0))] +pub fn each_chari_reverse(s: &str, it: &fn(uint, char) -> bool) -> bool { + let mut pos = s.len(); + let mut ch_pos = s.char_len(); + while pos > 0 { + let CharRange {ch, next} = char_range_at_reverse(s, pos); + pos = next; + ch_pos -= 1; + + if !it(ch_pos, ch) { return false; } + } + return true; +} /* Section: Searching @@ -2473,14 +2770,22 @@ pub trait StrSlice<'self> { fn contains<'a>(&self, needle: &'a str) -> bool; fn contains_char(&self, needle: char) -> bool; fn char_iter(&self) -> StrCharIterator<'self>; - fn each(&self, it: &fn(u8) -> bool); - fn eachi(&self, it: &fn(uint, u8) -> bool); - fn each_reverse(&self, it: &fn(u8) -> bool); - fn eachi_reverse(&self, it: &fn(uint, u8) -> bool); - fn each_char(&self, it: &fn(char) -> bool); - fn each_chari(&self, it: &fn(uint, char) -> bool); - fn each_char_reverse(&self, it: &fn(char) -> bool); - fn each_chari_reverse(&self, it: &fn(uint, char) -> bool); + #[cfg(stage0)] fn each(&self, it: &fn(u8) -> bool); + #[cfg(not(stage0))] fn each(&self, it: &fn(u8) -> bool) -> bool; + #[cfg(stage0)] fn eachi(&self, it: &fn(uint, u8) -> bool); + #[cfg(not(stage0))] fn eachi(&self, it: &fn(uint, u8) -> bool) -> bool; + #[cfg(stage0)] fn each_reverse(&self, it: &fn(u8) -> bool); + #[cfg(not(stage0))] fn each_reverse(&self, it: &fn(u8) -> bool) -> bool; + #[cfg(stage0)] fn eachi_reverse(&self, it: &fn(uint, u8) -> bool); + #[cfg(not(stage0))] fn eachi_reverse(&self, it: &fn(uint, u8) -> bool) -> bool; + #[cfg(stage0)] fn each_char(&self, it: &fn(char) -> bool); + #[cfg(not(stage0))] fn each_char(&self, it: &fn(char) -> bool) -> bool; + #[cfg(stage0)] fn each_chari(&self, it: &fn(uint, char) -> bool); + #[cfg(not(stage0))] fn each_chari(&self, it: &fn(uint, char) -> bool) -> bool; + #[cfg(stage0)] fn each_char_reverse(&self, it: &fn(char) -> bool); + #[cfg(not(stage0))] fn each_char_reverse(&self, it: &fn(char) -> bool) -> bool; + #[cfg(stage0)] fn each_chari_reverse(&self, it: &fn(uint, char) -> bool); + #[cfg(not(stage0))] fn each_chari_reverse(&self, it: &fn(uint, char) -> bool) -> bool; fn ends_with(&self, needle: &str) -> bool; fn is_empty(&self) -> bool; fn is_whitespace(&self) -> bool; @@ -2488,9 +2793,18 @@ pub trait StrSlice<'self> { fn len(&self) -> uint; fn char_len(&self) -> uint; fn slice(&self, begin: uint, end: uint) -> &'self str; + #[cfg(stage0)] fn each_split(&self, sepfn: &fn(char) -> bool, it: &fn(&'self str) -> bool); + #[cfg(not(stage0))] + fn each_split(&self, sepfn: &fn(char) -> bool, it: &fn(&'self str) -> bool) -> bool; + #[cfg(stage0)] fn each_split_char(&self, sep: char, it: &fn(&'self str) -> bool); + #[cfg(not(stage0))] + fn each_split_char(&self, sep: char, it: &fn(&'self str) -> bool) -> bool; + #[cfg(stage0)] fn each_split_str<'a>(&self, sep: &'a str, it: &fn(&'self str) -> bool); + #[cfg(not(stage0))] + fn each_split_str<'a>(&self, sep: &'a str, it: &fn(&'self str) -> bool) -> bool; fn starts_with<'a>(&self, needle: &'a str) -> bool; fn substr(&self, begin: uint, n: uint) -> &'self str; fn escape_default(&self) -> ~str; @@ -2543,39 +2857,86 @@ impl<'self> StrSlice<'self> for &'self str { /// Iterate over the bytes in a string #[inline] + #[cfg(stage0)] fn each(&self, it: &fn(u8) -> bool) { each(*self, it) } + /// Iterate over the bytes in a string + #[inline] + #[cfg(not(stage0))] + fn each(&self, it: &fn(u8) -> bool) -> bool { each(*self, it) } /// Iterate over the bytes in a string, with indices #[inline] + #[cfg(stage0)] fn eachi(&self, it: &fn(uint, u8) -> bool) { eachi(*self, it) } + /// Iterate over the bytes in a string, with indices + #[inline] + #[cfg(not(stage0))] + fn eachi(&self, it: &fn(uint, u8) -> bool) -> bool { eachi(*self, it) } /// Iterate over the bytes in a string #[inline] - fn each_reverse(&self, it: &fn(u8) -> bool) { - each_reverse(*self, it) - } + #[cfg(stage0)] + fn each_reverse(&self, it: &fn(u8) -> bool) { each_reverse(*self, it) } + /// Iterate over the bytes in a string + #[inline] + #[cfg(not(stage0))] + fn each_reverse(&self, it: &fn(u8) -> bool) -> bool { each_reverse(*self, it) } /// Iterate over the bytes in a string, with indices #[inline] + #[cfg(stage0)] fn eachi_reverse(&self, it: &fn(uint, u8) -> bool) { eachi_reverse(*self, it) } + /// Iterate over the bytes in a string, with indices + #[inline] + #[cfg(not(stage0))] + fn eachi_reverse(&self, it: &fn(uint, u8) -> bool) -> bool { + eachi_reverse(*self, it) + } /// Iterate over the chars in a string #[inline] + #[cfg(stage0)] fn each_char(&self, it: &fn(char) -> bool) { each_char(*self, it) } + /// Iterate over the chars in a string + #[inline] + #[cfg(not(stage0))] + fn each_char(&self, it: &fn(char) -> bool) -> bool { each_char(*self, it) } /// Iterate over the chars in a string, with indices #[inline] + #[cfg(stage0)] fn each_chari(&self, it: &fn(uint, char) -> bool) { each_chari(*self, it) } + /// Iterate over the chars in a string, with indices + #[inline] + #[cfg(not(stage0))] + fn each_chari(&self, it: &fn(uint, char) -> bool) -> bool { + each_chari(*self, it) + } /// Iterate over the chars in a string in reverse #[inline] + #[cfg(stage0)] fn each_char_reverse(&self, it: &fn(char) -> bool) { each_char_reverse(*self, it) } + /// Iterate over the chars in a string in reverse + #[inline] + #[cfg(not(stage0))] + fn each_char_reverse(&self, it: &fn(char) -> bool) -> bool { + each_char_reverse(*self, it) + } /// Iterate over the chars in a string in reverse, with indices from the /// end #[inline] + #[cfg(stage0)] fn each_chari_reverse(&self, it: &fn(uint, char) -> bool) { each_chari_reverse(*self, it) } + /// Iterate over the chars in a string in reverse, with indices from the + /// end + #[inline] + #[cfg(not(stage0))] + fn each_chari_reverse(&self, it: &fn(uint, char) -> bool) -> bool { + each_chari_reverse(*self, it) + } /// Returns true if one string ends with another #[inline] fn ends_with(&self, needle: &str) -> bool { @@ -2617,24 +2978,50 @@ impl<'self> StrSlice<'self> for &'self str { } /// Splits a string into substrings using a character function #[inline] + #[cfg(stage0)] fn each_split(&self, sepfn: &fn(char) -> bool, it: &fn(&'self str) -> bool) { each_split(*self, sepfn, it) } + /// Splits a string into substrings using a character function + #[inline] + #[cfg(not(stage0))] + fn each_split(&self, sepfn: &fn(char) -> bool, it: &fn(&'self str) -> bool) -> bool { + each_split(*self, sepfn, it) + } /** * Splits a string into substrings at each occurrence of a given character */ #[inline] + #[cfg(stage0)] fn each_split_char(&self, sep: char, it: &fn(&'self str) -> bool) { each_split_char(*self, sep, it) } + /** + * Splits a string into substrings at each occurrence of a given character + */ + #[inline] + #[cfg(not(stage0))] + fn each_split_char(&self, sep: char, it: &fn(&'self str) -> bool) -> bool { + each_split_char(*self, sep, it) + } /** * Splits a string into a vector of the substrings separated by a given * string */ #[inline] + #[cfg(stage0)] fn each_split_str<'a>(&self, sep: &'a str, it: &fn(&'self str) -> bool) { each_split_str(*self, sep, it) } + /** + * Splits a string into a vector of the substrings separated by a given + * string + */ + #[inline] + #[cfg(not(stage0))] + fn each_split_str<'a>(&self, sep: &'a str, it: &fn(&'self str) -> bool) -> bool { + each_split_str(*self, sep, it) + } /// Returns true if one string starts with another #[inline] fn starts_with<'a>(&self, needle: &'a str) -> bool { @@ -3017,7 +3404,7 @@ mod tests { let lf = ~"\nMary had a little lamb\nLittle lamb\n"; let crlf = ~"\r\nMary had a little lamb\r\nLittle lamb\r\n"; - fn t(s: &str, f: &fn(&str, &fn(&str) -> bool), u: &[~str]) { + fn t(s: &str, f: &fn(&str, &fn(&str) -> bool) -> bool, u: &[~str]) { let mut v = ~[]; for f(s) |s| { v.push(s.to_owned()) } assert!(vec::all2(v, u, |a,b| a == b)); @@ -3037,7 +3424,7 @@ mod tests { #[test] fn test_words () { - fn t(s: &str, f: &fn(&str, &fn(&str) -> bool), u: &[~str]) { + fn t(s: &str, f: &fn(&str, &fn(&str) -> bool) -> bool, u: &[~str]) { let mut v = ~[]; for f(s) |s| { v.push(s.to_owned()) } assert!(vec::all2(v, u, |a,b| a == b)); diff --git a/src/libcore/task/spawn.rs b/src/libcore/task/spawn.rs index 19c417dfdfc95..846d4a349508b 100644 --- a/src/libcore/task/spawn.rs +++ b/src/libcore/task/spawn.rs @@ -110,9 +110,14 @@ fn taskset_remove(tasks: &mut TaskSet, task: *rust_task) { let was_present = tasks.remove(&task); assert!(was_present); } +#[cfg(stage0)] pub fn taskset_each(tasks: &TaskSet, blk: &fn(v: *rust_task) -> bool) { tasks.each(|k| blk(*k)) } +#[cfg(not(stage0))] +pub fn taskset_each(tasks: &TaskSet, blk: &fn(v: *rust_task) -> bool) -> bool { + tasks.each(|k| blk(*k)) +} // One of these per group of linked-failure tasks. struct TaskGroupData { @@ -685,13 +690,11 @@ fn spawn_raw_oldsched(mut opts: TaskOpts, f: ~fn()) { }; // Attempt to join every ancestor group. result = - for each_ancestor(ancestors, Some(bail)) |ancestor_tg| { + each_ancestor(ancestors, Some(bail), |ancestor_tg| { // Enlist as a descendant, not as an actual member. // Descendants don't kill ancestor groups on failure. - if !enlist_in_taskgroup(ancestor_tg, child, false) { - break; - } - }; + enlist_in_taskgroup(ancestor_tg, child, false) + }); // If any ancestor group fails, need to exit this group too. if !result { do access_group(child_arc) |child_tg| { diff --git a/src/libcore/to_bytes.rs b/src/libcore/to_bytes.rs index 9e4da7ab48868..182a03da4b1c6 100644 --- a/src/libcore/to_bytes.rs +++ b/src/libcore/to_bytes.rs @@ -21,6 +21,11 @@ use str; pub type Cb<'self> = &'self fn(buf: &[u8]) -> bool; +#[cfg(stage0)] +pub trait IterBytes { + fn iter_bytes(&self, lsb0: bool, f: Cb); +} + /** * A trait to implement in order to make a type hashable; * This works in combination with the trait `Hash::Hash`, and @@ -28,6 +33,7 @@ pub type Cb<'self> = &'self fn(buf: &[u8]) -> bool; * modified when default methods and trait inheritence are * completed. */ +#[cfg(not(stage0))] pub trait IterBytes { /** * Call the provided callback `f` one or more times with @@ -43,9 +49,10 @@ pub trait IterBytes { * left-to-right in declaration order, regardless of * underlying memory endianness. */ - fn iter_bytes(&self, lsb0: bool, f: Cb); + fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool; } +#[cfg(stage0)] impl IterBytes for bool { #[inline(always)] fn iter_bytes(&self, _lsb0: bool, f: Cb) { @@ -54,7 +61,17 @@ impl IterBytes for bool { ]); } } +#[cfg(not(stage0))] +impl IterBytes for bool { + #[inline(always)] + fn iter_bytes(&self, _lsb0: bool, f: Cb) -> bool { + f([ + *self as u8 + ]) + } +} +#[cfg(stage0)] impl IterBytes for u8 { #[inline(always)] fn iter_bytes(&self, _lsb0: bool, f: Cb) { @@ -63,7 +80,17 @@ impl IterBytes for u8 { ]); } } +#[cfg(not(stage0))] +impl IterBytes for u8 { + #[inline(always)] + fn iter_bytes(&self, _lsb0: bool, f: Cb) -> bool { + f([ + *self + ]) + } +} +#[cfg(stage0)] impl IterBytes for u16 { #[inline(always)] fn iter_bytes(&self, lsb0: bool, f: Cb) { @@ -80,7 +107,25 @@ impl IterBytes for u16 { } } } +#[cfg(not(stage0))] +impl IterBytes for u16 { + #[inline(always)] + fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool { + if lsb0 { + f([ + *self as u8, + (*self >> 8) as u8 + ]) + } else { + f([ + (*self >> 8) as u8, + *self as u8 + ]) + } + } +} +#[cfg(stage0)] impl IterBytes for u32 { #[inline(always)] fn iter_bytes(&self, lsb0: bool, f: Cb) { @@ -101,7 +146,29 @@ impl IterBytes for u32 { } } } +#[cfg(not(stage0))] +impl IterBytes for u32 { + #[inline(always)] + fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool { + if lsb0 { + f([ + *self as u8, + (*self >> 8) as u8, + (*self >> 16) as u8, + (*self >> 24) as u8, + ]) + } else { + f([ + (*self >> 24) as u8, + (*self >> 16) as u8, + (*self >> 8) as u8, + *self as u8 + ]) + } + } +} +#[cfg(stage0)] impl IterBytes for u64 { #[inline(always)] fn iter_bytes(&self, lsb0: bool, f: Cb) { @@ -130,73 +197,157 @@ impl IterBytes for u64 { } } } +#[cfg(not(stage0))] +impl IterBytes for u64 { + #[inline(always)] + fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool { + if lsb0 { + f([ + *self as u8, + (*self >> 8) as u8, + (*self >> 16) as u8, + (*self >> 24) as u8, + (*self >> 32) as u8, + (*self >> 40) as u8, + (*self >> 48) as u8, + (*self >> 56) as u8 + ]) + } else { + f([ + (*self >> 56) as u8, + (*self >> 48) as u8, + (*self >> 40) as u8, + (*self >> 32) as u8, + (*self >> 24) as u8, + (*self >> 16) as u8, + (*self >> 8) as u8, + *self as u8 + ]) + } + } +} +#[cfg(stage0)] impl IterBytes for i8 { #[inline(always)] fn iter_bytes(&self, lsb0: bool, f: Cb) { (*self as u8).iter_bytes(lsb0, f) } } +#[cfg(not(stage0))] +impl IterBytes for i8 { + #[inline(always)] + fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool { + (*self as u8).iter_bytes(lsb0, f) + } +} +#[cfg(stage0)] impl IterBytes for i16 { #[inline(always)] fn iter_bytes(&self, lsb0: bool, f: Cb) { (*self as u16).iter_bytes(lsb0, f) } } +#[cfg(not(stage0))] +impl IterBytes for i16 { + #[inline(always)] + fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool { + (*self as u16).iter_bytes(lsb0, f) + } +} +#[cfg(stage0)] impl IterBytes for i32 { #[inline(always)] fn iter_bytes(&self, lsb0: bool, f: Cb) { (*self as u32).iter_bytes(lsb0, f) } } +#[cfg(not(stage0))] +impl IterBytes for i32 { + #[inline(always)] + fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool { + (*self as u32).iter_bytes(lsb0, f) + } +} +#[cfg(stage0)] impl IterBytes for i64 { #[inline(always)] fn iter_bytes(&self, lsb0: bool, f: Cb) { (*self as u64).iter_bytes(lsb0, f) } } +#[cfg(not(stage0))] +impl IterBytes for i64 { + #[inline(always)] + fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool { + (*self as u64).iter_bytes(lsb0, f) + } +} +#[cfg(stage0)] impl IterBytes for char { #[inline(always)] fn iter_bytes(&self, lsb0: bool, f: Cb) { (*self as u32).iter_bytes(lsb0, f) } } - -#[cfg(target_word_size = "32")] -pub mod x32 { - use to_bytes::{Cb, IterBytes}; - - impl IterBytes for uint { - #[inline(always)] - fn iter_bytes(&self, lsb0: bool, f: Cb) { - (*self as u32).iter_bytes(lsb0, f) - } +#[cfg(not(stage0))] +impl IterBytes for char { + #[inline(always)] + fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool { + (*self as u32).iter_bytes(lsb0, f) } } -#[cfg(target_word_size = "64")] -pub mod x64 { - use to_bytes::{Cb, IterBytes}; +#[cfg(target_word_size = "32", stage0)] +impl IterBytes for uint { + #[inline(always)] + fn iter_bytes(&self, lsb0: bool, f: Cb) { + (*self as u32).iter_bytes(lsb0, f) + } +} +#[cfg(target_word_size = "32", not(stage0))] +impl IterBytes for uint { + #[inline(always)] + fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool { + (*self as u32).iter_bytes(lsb0, f) + } +} - impl IterBytes for uint { - #[inline(always)] - fn iter_bytes(&self, lsb0: bool, f: Cb) { - (*self as u64).iter_bytes(lsb0, f) - } +#[cfg(target_word_size = "64", stage0)] +impl IterBytes for uint { + #[inline(always)] + fn iter_bytes(&self, lsb0: bool, f: Cb) { + (*self as u64).iter_bytes(lsb0, f) + } +} +#[cfg(target_word_size = "64", not(stage0))] +impl IterBytes for uint { + #[inline(always)] + fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool { + (*self as u64).iter_bytes(lsb0, f) } } +#[cfg(stage0)] impl IterBytes for int { #[inline(always)] fn iter_bytes(&self, lsb0: bool, f: Cb) { (*self as uint).iter_bytes(lsb0, f) } } +#[cfg(not(stage0))] +impl IterBytes for int { + #[inline(always)] + fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool { + (*self as uint).iter_bytes(lsb0, f) + } +} +#[cfg(stage0)] impl<'self,A:IterBytes> IterBytes for &'self [A] { #[inline(always)] fn iter_bytes(&self, lsb0: bool, f: Cb) { @@ -207,7 +358,15 @@ impl<'self,A:IterBytes> IterBytes for &'self [A] { } } } +#[cfg(not(stage0))] +impl<'self,A:IterBytes> IterBytes for &'self [A] { + #[inline(always)] + fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool { + self.each(|elt| elt.iter_bytes(lsb0, |b| f(b))) + } +} +#[cfg(stage0)] impl IterBytes for (A,B) { #[inline(always)] fn iter_bytes(&self, lsb0: bool, f: Cb) { @@ -218,7 +377,17 @@ impl IterBytes for (A,B) { } } } +#[cfg(not(stage0))] +impl IterBytes for (A,B) { + #[inline(always)] + fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool { + match *self { + (ref a, ref b) => { a.iter_bytes(lsb0, f) && b.iter_bytes(lsb0, f) } + } + } +} +#[cfg(stage0)] impl IterBytes for (A,B,C) { #[inline(always)] fn iter_bytes(&self, lsb0: bool, f: Cb) { @@ -229,26 +398,57 @@ impl IterBytes for (A,B,C) { } } } +#[cfg(not(stage0))] +impl IterBytes for (A,B,C) { + #[inline(always)] + fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool { + match *self { + (ref a, ref b, ref c) => { + a.iter_bytes(lsb0, f) && b.iter_bytes(lsb0, f) && c.iter_bytes(lsb0, f) + } + } + } +} // Move this to vec, probably. fn borrow<'x,A>(a: &'x [A]) -> &'x [A] { a } +#[cfg(stage0)] impl IterBytes for ~[A] { #[inline(always)] fn iter_bytes(&self, lsb0: bool, f: Cb) { borrow(*self).iter_bytes(lsb0, f) } } +#[cfg(not(stage0))] +impl IterBytes for ~[A] { + #[inline(always)] + fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool { + borrow(*self).iter_bytes(lsb0, f) + } +} +#[cfg(stage0)] impl IterBytes for @[A] { #[inline(always)] fn iter_bytes(&self, lsb0: bool, f: Cb) { borrow(*self).iter_bytes(lsb0, f) } } +#[cfg(not(stage0))] +impl IterBytes for @[A] { + #[inline(always)] + fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool { + borrow(*self).iter_bytes(lsb0, f) + } +} + +// NOTE: remove all of these after a snapshot, the new for-loop iteration +// protocol makes these unnecessary. +#[cfg(stage0)] pub fn iter_bytes_2(a: &A, b: &B, lsb0: bool, z: Cb) { let mut flag = true; @@ -256,11 +456,17 @@ pub fn iter_bytes_2(a: &A, b: &B, if !flag { return; } b.iter_bytes(lsb0, |bytes| {flag = z(bytes); flag}); } +#[cfg(not(stage0))] +pub fn iter_bytes_2(a: &A, b: &B, + lsb0: bool, z: Cb) -> bool { + a.iter_bytes(lsb0, z) && b.iter_bytes(lsb0, z) +} +#[cfg(stage0)] pub fn iter_bytes_3(a: &A, b: &B, c: &C, - lsb0: bool, z: Cb) { + B: IterBytes, + C: IterBytes>(a: &A, b: &B, c: &C, + lsb0: bool, z: Cb) { let mut flag = true; a.iter_bytes(lsb0, |bytes| {flag = z(bytes); flag}); if !flag { return; } @@ -268,7 +474,14 @@ pub fn iter_bytes_3(a: &A, b: &B, c: &C, lsb0: bool, z: Cb) -> bool { + a.iter_bytes(lsb0, z) && b.iter_bytes(lsb0, z) && c.iter_bytes(lsb0, z) +} +#[cfg(stage0)] pub fn iter_bytes_4(a: &A, b: &B, c: &C, - d: &D, e: &E, - lsb0: bool, z: Cb) { - let mut flag = true; - a.iter_bytes(lsb0, |bytes| {flag = z(bytes); flag}); - if !flag { return; } - b.iter_bytes(lsb0, |bytes| {flag = z(bytes); flag}); - if !flag { return; } - c.iter_bytes(lsb0, |bytes| {flag = z(bytes); flag}); - if !flag { return; } - d.iter_bytes(lsb0, |bytes| {flag = z(bytes); flag}); - if !flag { return; } - e.iter_bytes(lsb0, |bytes| {flag = z(bytes); flag}); + D: IterBytes>(a: &A, b: &B, c: &C, + d: &D, + lsb0: bool, z: Cb) -> bool { + a.iter_bytes(lsb0, z) && b.iter_bytes(lsb0, z) && c.iter_bytes(lsb0, z) && + d.iter_bytes(lsb0, z) } -pub fn iter_bytes_6(a: &A, b: &B, c: &C, - d: &D, e: &E, f: &F, + E: IterBytes>(a: &A, b: &B, c: &C, + d: &D, e: &E, lsb0: bool, z: Cb) { let mut flag = true; a.iter_bytes(lsb0, |bytes| {flag = z(bytes); flag}); @@ -322,36 +526,20 @@ pub fn iter_bytes_6(a: &A, b: &B, c: &C, - d: &D, e: &E, f: &F, - g: &G, - lsb0: bool, z: Cb) { - let mut flag = true; - a.iter_bytes(lsb0, |bytes| {flag = z(bytes); flag}); - if !flag { return; } - b.iter_bytes(lsb0, |bytes| {flag = z(bytes); flag}); - if !flag { return; } - c.iter_bytes(lsb0, |bytes| {flag = z(bytes); flag}); - if !flag { return; } - d.iter_bytes(lsb0, |bytes| {flag = z(bytes); flag}); - if !flag { return; } - e.iter_bytes(lsb0, |bytes| {flag = z(bytes); flag}); - if !flag { return; } - f.iter_bytes(lsb0, |bytes| {flag = z(bytes); flag}); - if !flag { return; } - g.iter_bytes(lsb0, |bytes| {flag = z(bytes); flag}); + E: IterBytes>(a: &A, b: &B, c: &C, + d: &D, e: &E, + lsb0: bool, z: Cb) -> bool { + a.iter_bytes(lsb0, z) && b.iter_bytes(lsb0, z) && c.iter_bytes(lsb0, z) && + d.iter_bytes(lsb0, z) && e.iter_bytes(lsb0, z) } +#[cfg(stage0)] impl<'self> IterBytes for &'self str { #[inline(always)] fn iter_bytes(&self, _lsb0: bool, f: Cb) { @@ -360,7 +548,17 @@ impl<'self> IterBytes for &'self str { } } } +#[cfg(not(stage0))] +impl<'self> IterBytes for &'self str { + #[inline(always)] + fn iter_bytes(&self, _lsb0: bool, f: Cb) -> bool { + do str::byte_slice(*self) |bytes| { + f(bytes) + } + } +} +#[cfg(stage0)] impl IterBytes for ~str { #[inline(always)] fn iter_bytes(&self, _lsb0: bool, f: Cb) { @@ -369,7 +567,17 @@ impl IterBytes for ~str { } } } +#[cfg(not(stage0))] +impl IterBytes for ~str { + #[inline(always)] + fn iter_bytes(&self, _lsb0: bool, f: Cb) -> bool { + do str::byte_slice(*self) |bytes| { + f(bytes) + } + } +} +#[cfg(stage0)] impl IterBytes for @str { #[inline(always)] fn iter_bytes(&self, _lsb0: bool, f: Cb) { @@ -378,7 +586,17 @@ impl IterBytes for @str { } } } +#[cfg(not(stage0))] +impl IterBytes for @str { + #[inline(always)] + fn iter_bytes(&self, _lsb0: bool, f: Cb) -> bool { + do str::byte_slice(*self) |bytes| { + f(bytes) + } + } +} +#[cfg(stage0)] impl IterBytes for Option { #[inline(always)] fn iter_bytes(&self, lsb0: bool, f: Cb) { @@ -388,36 +606,80 @@ impl IterBytes for Option { } } } +#[cfg(not(stage0))] +impl IterBytes for Option { + #[inline(always)] + fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool { + match *self { + Some(ref a) => 0u8.iter_bytes(lsb0, f) && a.iter_bytes(lsb0, f), + None => 1u8.iter_bytes(lsb0, f) + } + } +} +#[cfg(stage0)] impl<'self,A:IterBytes> IterBytes for &'self A { #[inline(always)] fn iter_bytes(&self, lsb0: bool, f: Cb) { (**self).iter_bytes(lsb0, f); } } +#[cfg(not(stage0))] +impl<'self,A:IterBytes> IterBytes for &'self A { + #[inline(always)] + fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool { + (**self).iter_bytes(lsb0, f) + } +} +#[cfg(stage0)] impl IterBytes for @A { #[inline(always)] fn iter_bytes(&self, lsb0: bool, f: Cb) { (**self).iter_bytes(lsb0, f); } } +#[cfg(not(stage0))] +impl IterBytes for @A { + #[inline(always)] + fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool { + (**self).iter_bytes(lsb0, f) + } +} +#[cfg(stage0)] impl IterBytes for ~A { #[inline(always)] fn iter_bytes(&self, lsb0: bool, f: Cb) { (**self).iter_bytes(lsb0, f); } } +#[cfg(not(stage0))] +impl IterBytes for ~A { + #[inline(always)] + fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool { + (**self).iter_bytes(lsb0, f) + } +} // NB: raw-pointer IterBytes does _not_ dereference // to the target; it just gives you the pointer-bytes. +#[cfg(stage0)] impl IterBytes for *const A { #[inline(always)] fn iter_bytes(&self, lsb0: bool, f: Cb) { (*self as uint).iter_bytes(lsb0, f); } } +// NB: raw-pointer IterBytes does _not_ dereference +// to the target; it just gives you the pointer-bytes. +#[cfg(not(stage0))] +impl IterBytes for *const A { + #[inline(always)] + fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool { + (*self as uint).iter_bytes(lsb0, f) + } +} pub trait ToBytes { fn to_bytes(&self, lsb0: bool) -> ~[u8]; diff --git a/src/libcore/trie.rs b/src/libcore/trie.rs index af1c1aa83c3d1..05ef1cf433faf 100644 --- a/src/libcore/trie.rs +++ b/src/libcore/trie.rs @@ -57,28 +57,60 @@ impl Map for TrieMap { /// Visit all key-value pairs in order #[inline(always)] + #[cfg(stage0)] fn each<'a>(&'a self, f: &fn(&uint, &'a T) -> bool) { self.root.each(f); } + /// Visit all key-value pairs in order + #[inline(always)] + #[cfg(not(stage0))] + fn each<'a>(&'a self, f: &fn(&uint, &'a T) -> bool) -> bool { + self.root.each(f) + } + /// Visit all keys in order #[inline(always)] + #[cfg(stage0)] fn each_key(&self, f: &fn(&uint) -> bool) { self.each(|k, _| f(k)) } + /// Visit all keys in order + #[inline(always)] + #[cfg(not(stage0))] + fn each_key(&self, f: &fn(&uint) -> bool) -> bool { + self.each(|k, _| f(k)) + } + /// Visit all values in order #[inline(always)] + #[cfg(stage0)] fn each_value<'a>(&'a self, f: &fn(&'a T) -> bool) { self.each(|_, v| f(v)) } + /// Visit all values in order + #[inline(always)] + #[cfg(not(stage0))] + fn each_value<'a>(&'a self, f: &fn(&'a T) -> bool) -> bool { + self.each(|_, v| f(v)) + } + /// Iterate over the map and mutate the contained values #[inline(always)] + #[cfg(stage0)] fn mutate_values(&mut self, f: &fn(&uint, &mut T) -> bool) { self.root.mutate_values(f); } + /// Iterate over the map and mutate the contained values + #[inline(always)] + #[cfg(not(stage0))] + fn mutate_values(&mut self, f: &fn(&uint, &mut T) -> bool) -> bool { + self.root.mutate_values(f) + } + /// Return a reference to the value corresponding to the key #[inline(hint)] fn find<'a>(&'a self, key: &uint) -> Option<&'a T> { @@ -151,21 +183,43 @@ pub impl TrieMap { /// Visit all key-value pairs in reverse order #[inline(always)] + #[cfg(stage0)] fn each_reverse<'a>(&'a self, f: &fn(&uint, &'a T) -> bool) { self.root.each_reverse(f); } + /// Visit all key-value pairs in reverse order + #[inline(always)] + #[cfg(not(stage0))] + fn each_reverse<'a>(&'a self, f: &fn(&uint, &'a T) -> bool) -> bool { + self.root.each_reverse(f) + } + /// Visit all keys in reverse order #[inline(always)] + #[cfg(stage0)] fn each_key_reverse(&self, f: &fn(&uint) -> bool) { self.each_reverse(|k, _| f(k)) } + /// Visit all keys in reverse order + #[inline(always)] + #[cfg(not(stage0))] + fn each_key_reverse(&self, f: &fn(&uint) -> bool) -> bool { + self.each_reverse(|k, _| f(k)) + } /// Visit all values in reverse order #[inline(always)] + #[cfg(stage0)] fn each_value_reverse(&self, f: &fn(&T) -> bool) { self.each_reverse(|_, v| f(v)) } + /// Visit all values in reverse order + #[inline(always)] + #[cfg(not(stage0))] + fn each_value_reverse(&self, f: &fn(&T) -> bool) -> bool { + self.each_reverse(|_, v| f(v)) + } } pub struct TrieSet { @@ -175,7 +229,10 @@ pub struct TrieSet { impl BaseIter for TrieSet { /// Visit all values in order #[inline(always)] + #[cfg(stage0)] fn each(&self, f: &fn(&uint) -> bool) { self.map.each_key(f) } + #[cfg(not(stage0))] + fn each(&self, f: &fn(&uint) -> bool) -> bool { self.map.each_key(f) } #[inline(always)] fn size_hint(&self) -> Option { Some(self.len()) } } @@ -183,9 +240,14 @@ impl BaseIter for TrieSet { impl ReverseIter for TrieSet { /// Visit all values in reverse order #[inline(always)] + #[cfg(stage0)] fn each_reverse(&self, f: &fn(&uint) -> bool) { self.map.each_key_reverse(f) } + #[cfg(not(stage0))] + fn each_reverse(&self, f: &fn(&uint) -> bool) -> bool { + self.map.each_key_reverse(f) + } } impl Container for TrieSet { diff --git a/src/libcore/vec.rs b/src/libcore/vec.rs index 3f3691670effb..7eba2cbf0ccc4 100644 --- a/src/libcore/vec.rs +++ b/src/libcore/vec.rs @@ -1489,13 +1489,14 @@ pub fn reversed(v: &const [T]) -> ~[T] { * ~~~ */ #[inline(always)] -pub fn each<'r,T>(v: &'r [T], f: &fn(&'r T) -> bool) { +pub fn _each<'r,T>(v: &'r [T], f: &fn(&'r T) -> bool) -> bool { // ^^^^ // NB---this CANNOT be &const [T]! The reason // is that you are passing it to `f()` using // an immutable. - do vec::as_imm_buf(v) |p, n| { + let mut broke = false; + do as_imm_buf(v) |p, n| { let mut n = n; let mut p = p; while n > 0u { @@ -1506,42 +1507,69 @@ pub fn each<'r,T>(v: &'r [T], f: &fn(&'r T) -> bool) { } n -= 1u; } + broke = n > 0; } + return true; } +#[cfg(stage0)] +pub fn each<'r,T>(v: &'r [T], f: &fn(&'r T) -> bool) { _each(v, f); } +#[cfg(not(stage0))] +pub fn each<'r,T>(v: &'r [T], f: &fn(&'r T) -> bool) -> bool { _each(v, f) } + /// Like `each()`, but for the case where you have /// a vector with mutable contents and you would like /// to mutate the contents as you iterate. #[inline(always)] -pub fn each_mut<'r,T>(v: &'r mut [T], f: &fn(elem: &'r mut T) -> bool) { - do vec::as_mut_buf(v) |p, n| { +pub fn _each_mut<'r,T>(v: &'r mut [T], f: &fn(elem: &'r mut T) -> bool) -> bool { + let mut broke = false; + do as_mut_buf(v) |p, n| { let mut n = n; let mut p = p; while n > 0 { unsafe { let q: &'r mut T = cast::transmute_mut_region(&mut *p); - if !f(q) { - break; - } + if !f(q) { break; } p = p.offset(1); } n -= 1; } + broke = n > 0; } + return broke; +} + +#[cfg(stage0)] +pub fn each_mut<'r,T>(v: &'r mut [T], f: &fn(elem: &'r mut T) -> bool) { + _each_mut(v, f); +} +#[cfg(not(stage0))] +pub fn each_mut<'r,T>(v: &'r mut [T], f: &fn(elem: &'r mut T) -> bool) -> bool { + _each_mut(v, f) } /// Like `each()`, but for the case where you have a vector that *may or may /// not* have mutable contents. #[inline(always)] -pub fn each_const(v: &const [T], f: &fn(elem: &const T) -> bool) { +pub fn _each_const(v: &const [T], f: &fn(elem: &const T) -> bool) -> bool { let mut i = 0; let n = v.len(); while i < n { if !f(&const v[i]) { - return; + return false; } i += 1; } + return true; +} + +#[cfg(stage0)] +pub fn each_const(v: &const [t], f: &fn(elem: &const t) -> bool) { + _each_const(v, f); +} +#[cfg(not(stage0))] +pub fn each_const(v: &const [t], f: &fn(elem: &const t) -> bool) -> bool { + _each_const(v, f) } /** @@ -1550,12 +1578,20 @@ pub fn each_const(v: &const [T], f: &fn(elem: &const T) -> bool) { * Return true to continue, false to break. */ #[inline(always)] -pub fn eachi<'r,T>(v: &'r [T], f: &fn(uint, v: &'r T) -> bool) { +pub fn _eachi<'r,T>(v: &'r [T], f: &fn(uint, v: &'r T) -> bool) -> bool { let mut i = 0; for each(v) |p| { - if !f(i, p) { return; } + if !f(i, p) { return false; } i += 1; } + return true; +} + +#[cfg(stage0)] +pub fn eachi<'r,T>(v: &'r [T], f: &fn(uint, v: &'r T) -> bool) { _eachi(v, f); } +#[cfg(not(stage0))] +pub fn eachi<'r,T>(v: &'r [T], f: &fn(uint, v: &'r T) -> bool) -> bool { + _eachi(v, f) } /** @@ -1564,14 +1600,26 @@ pub fn eachi<'r,T>(v: &'r [T], f: &fn(uint, v: &'r T) -> bool) { * Return true to continue, false to break. */ #[inline(always)] -pub fn eachi_mut<'r,T>(v: &'r mut [T], f: &fn(uint, v: &'r mut T) -> bool) { +pub fn _eachi_mut<'r,T>(v: &'r mut [T], + f: &fn(uint, v: &'r mut T) -> bool) -> bool { let mut i = 0; for each_mut(v) |p| { if !f(i, p) { - return; + return false; } i += 1; } + return true; +} + +#[cfg(stage0)] +pub fn eachi_mut<'r,T>(v: &'r mut [T], f: &fn(uint, v: &'r mut T) -> bool) { + _eachi_mut(v, f); +} +#[cfg(not(stage0))] +pub fn eachi_mut<'r,T>(v: &'r mut [T], + f: &fn(uint, v: &'r mut T) -> bool) -> bool { + _eachi_mut(v, f) } /** @@ -1580,8 +1628,17 @@ pub fn eachi_mut<'r,T>(v: &'r mut [T], f: &fn(uint, v: &'r mut T) -> bool) { * Return true to continue, false to break. */ #[inline(always)] +pub fn _each_reverse<'r,T>(v: &'r [T], blk: &fn(v: &'r T) -> bool) -> bool { + _eachi_reverse(v, |_i, v| blk(v)) +} + +#[cfg(stage0)] pub fn each_reverse<'r,T>(v: &'r [T], blk: &fn(v: &'r T) -> bool) { - eachi_reverse(v, |_i, v| blk(v)) + _each_reverse(v, blk); +} +#[cfg(not(stage0))] +pub fn each_reverse<'r,T>(v: &'r [T], blk: &fn(v: &'r T) -> bool) -> bool { + _each_reverse(v, blk) } /** @@ -1590,14 +1647,26 @@ pub fn each_reverse<'r,T>(v: &'r [T], blk: &fn(v: &'r T) -> bool) { * Return true to continue, false to break. */ #[inline(always)] -pub fn eachi_reverse<'r,T>(v: &'r [T], blk: &fn(i: uint, v: &'r T) -> bool) { +pub fn _eachi_reverse<'r,T>(v: &'r [T], + blk: &fn(i: uint, v: &'r T) -> bool) -> bool { let mut i = v.len(); while i > 0 { i -= 1; if !blk(i, &v[i]) { - return; + return false; } } + return true; +} + +#[cfg(stage0)] +pub fn eachi_reverse<'r,T>(v: &'r [T], blk: &fn(i: uint, v: &'r T) -> bool) { + _eachi_reverse(v, blk); +} +#[cfg(not(stage0))] +pub fn eachi_reverse<'r,T>(v: &'r [T], + blk: &fn(i: uint, v: &'r T) -> bool) -> bool { + _eachi_reverse(v, blk) } /** @@ -1608,13 +1677,23 @@ pub fn eachi_reverse<'r,T>(v: &'r [T], blk: &fn(i: uint, v: &'r T) -> bool) { * Both vectors must have the same length */ #[inline] -pub fn each2(v1: &[U], v2: &[T], f: &fn(u: &U, t: &T) -> bool) { +pub fn _each2(v1: &[U], v2: &[T], f: &fn(u: &U, t: &T) -> bool) -> bool { assert!(len(v1) == len(v2)); for uint::range(0u, len(v1)) |i| { if !f(&v1[i], &v2[i]) { - return; + return false; } } + return true; +} + +#[cfg(stage0)] +pub fn each2(v1: &[U], v2: &[T], f: &fn(u: &U, t: &T) -> bool) { + _each2(v1, v2, f); +} +#[cfg(not(stage0))] +pub fn each2(v1: &[U], v2: &[T], f: &fn(u: &U, t: &T) -> bool) -> bool { + _each2(v1, v2, f) } /** @@ -1627,7 +1706,8 @@ pub fn each2(v1: &[U], v2: &[T], f: &fn(u: &U, t: &T) -> bool) { * The total number of permutations produced is `len(v)!`. If `v` contains * repeated elements, then some permutations are repeated. */ -pub fn each_permutation(v: &[T], put: &fn(ts: &[T]) -> bool) { +#[cfg(not(stage0))] +pub fn each_permutation(v: &[T], put: &fn(ts: &[T]) -> bool) -> bool { let ln = len(v); if ln <= 1 { put(v); @@ -1641,12 +1721,13 @@ pub fn each_permutation(v: &[T], put: &fn(ts: &[T]) -> bool) { rest.push_all(const_slice(v, i+1u, ln)); for each_permutation(rest) |permutation| { if !put(append(~[elt], permutation)) { - return; + return false; } } i += 1u; } } + return true; } /** @@ -1663,6 +1744,7 @@ pub fn each_permutation(v: &[T], put: &fn(ts: &[T]) -> bool) { * ~~~ * */ +#[cfg(stage0)] pub fn windowed<'r, T>(n: uint, v: &'r [T], it: &fn(&'r [T]) -> bool) { assert!(1u <= n); if n > v.len() { return; } @@ -1670,6 +1752,29 @@ pub fn windowed<'r, T>(n: uint, v: &'r [T], it: &fn(&'r [T]) -> bool) { if !it(v.slice(i, i + n)) { return } } } +/** + * Iterate over all contiguous windows of length `n` of the vector `v`. + * + * # Example + * + * Print the adjacent pairs of a vector (i.e. `[1,2]`, `[2,3]`, `[3,4]`) + * + * ~~~ + * for windowed(2, &[1,2,3,4]) |v| { + * io::println(fmt!("%?", v)); + * } + * ~~~ + * + */ +#[cfg(not(stage0))] +pub fn windowed<'r, T>(n: uint, v: &'r [T], it: &fn(&'r [T]) -> bool) -> bool { + assert!(1u <= n); + if n > v.len() { return true; } + for uint::range(0, v.len() - n + 1) |i| { + if !it(v.slice(i, i + n)) { return false; } + } + return true; +} /** * Work with the buffer of a vector. @@ -1932,8 +2037,14 @@ pub trait ImmutableVector<'self, T> { fn initn(&self, n: uint) -> &'self [T]; fn last(&self) -> &'self T; fn last_opt(&self) -> Option<&'self T>; + #[cfg(stage0)] fn each_reverse(&self, blk: &fn(&T) -> bool); + #[cfg(not(stage0))] + fn each_reverse(&self, blk: &fn(&T) -> bool) -> bool; + #[cfg(stage0)] fn eachi_reverse(&self, blk: &fn(uint, &T) -> bool); + #[cfg(not(stage0))] + fn eachi_reverse(&self, blk: &fn(uint, &T) -> bool) -> bool; fn foldr<'a, U>(&'a self, z: U, p: &fn(t: &'a T, u: U) -> U) -> U; fn map(&self, f: &fn(t: &T) -> U) -> ~[U]; fn mapi(&self, f: &fn(uint, t: &T) -> U) -> ~[U]; @@ -1995,15 +2106,29 @@ impl<'self,T> ImmutableVector<'self, T> for &'self [T] { /// Iterates over a vector's elements in reverse. #[inline] + #[cfg(stage0)] fn each_reverse(&self, blk: &fn(&T) -> bool) { each_reverse(*self, blk) } + /// Iterates over a vector's elements in reverse. + #[inline] + #[cfg(not(stage0))] + fn each_reverse(&self, blk: &fn(&T) -> bool) -> bool { + each_reverse(*self, blk) + } /// Iterates over a vector's elements and indices in reverse. + #[cfg(stage0)] #[inline] fn eachi_reverse(&self, blk: &fn(uint, &T) -> bool) { eachi_reverse(*self, blk) } + /// Iterates over a vector's elements and indices in reverse. + #[cfg(not(stage0))] + #[inline] + fn eachi_reverse(&self, blk: &fn(uint, &T) -> bool) -> bool { + eachi_reverse(*self, blk) + } /// Reduce a vector from right to left #[inline] @@ -2555,44 +2680,81 @@ pub mod bytes { // ITERATION TRAIT METHODS impl<'self,A> old_iter::BaseIter for &'self [A] { + #[cfg(stage0)] + #[inline(always)] + fn each<'a>(&'a self, blk: &fn(v: &'a A) -> bool) { + each(*self, blk) + } + #[cfg(not(stage0))] #[inline(always)] - fn each<'a>(&'a self, blk: &fn(v: &'a A) -> bool) { each(*self, blk) } + fn each<'a>(&'a self, blk: &fn(v: &'a A) -> bool) -> bool { + each(*self, blk) + } #[inline(always)] fn size_hint(&self) -> Option { Some(self.len()) } } // FIXME(#4148): This should be redundant impl old_iter::BaseIter for ~[A] { + #[cfg(stage0)] #[inline(always)] - fn each<'a>(&'a self, blk: &fn(v: &'a A) -> bool) { each(*self, blk) } + fn each<'a>(&'a self, blk: &fn(v: &'a A) -> bool) { + each(*self, blk) + } + #[cfg(not(stage0))] + #[inline(always)] + fn each<'a>(&'a self, blk: &fn(v: &'a A) -> bool) -> bool { + each(*self, blk) + } #[inline(always)] fn size_hint(&self) -> Option { Some(self.len()) } } // FIXME(#4148): This should be redundant impl old_iter::BaseIter for @[A] { + #[cfg(stage0)] + #[inline(always)] + fn each<'a>(&'a self, blk: &fn(v: &'a A) -> bool) { + each(*self, blk) + } + #[cfg(not(stage0))] #[inline(always)] - fn each<'a>(&'a self, blk: &fn(v: &'a A) -> bool) { each(*self, blk) } + fn each<'a>(&'a self, blk: &fn(v: &'a A) -> bool) -> bool { + each(*self, blk) + } #[inline(always)] fn size_hint(&self) -> Option { Some(self.len()) } } impl<'self,A> old_iter::MutableIter for &'self mut [A] { + #[cfg(stage0)] #[inline(always)] fn each_mut<'a>(&'a mut self, blk: &fn(v: &'a mut A) -> bool) { each_mut(*self, blk) } + #[cfg(not(stage0))] + #[inline(always)] + fn each_mut<'a>(&'a mut self, blk: &fn(v: &'a mut A) -> bool) -> bool { + each_mut(*self, blk) + } } // FIXME(#4148): This should be redundant impl old_iter::MutableIter for ~[A] { + #[cfg(stage0)] #[inline(always)] fn each_mut<'a>(&'a mut self, blk: &fn(v: &'a mut A) -> bool) { each_mut(*self, blk) } + #[cfg(not(stage0))] + #[inline(always)] + fn each_mut<'a>(&'a mut self, blk: &fn(v: &'a mut A) -> bool) -> bool { + each_mut(*self, blk) + } } // FIXME(#4148): This should be redundant +#[cfg(stage0)] impl old_iter::MutableIter for @mut [A] { #[inline(always)] fn each_mut(&mut self, blk: &fn(v: &mut A) -> bool) { @@ -2600,10 +2762,23 @@ impl old_iter::MutableIter for @mut [A] { } } +#[cfg(not(stage0))] +impl old_iter::MutableIter for @mut [A] { + #[inline(always)] + fn each_mut(&mut self, blk: &fn(v: &mut A) -> bool) -> bool { + each_mut(*self, blk) + } +} + impl<'self,A> old_iter::ExtendedIter for &'self [A] { + #[cfg(stage0)] pub fn eachi(&self, blk: &fn(uint, v: &A) -> bool) { old_iter::eachi(self, blk) } + #[cfg(not(stage0))] + pub fn eachi(&self, blk: &fn(uint, v: &A) -> bool) -> bool { + old_iter::eachi(self, blk) + } pub fn all(&self, blk: &fn(&A) -> bool) -> bool { old_iter::all(self, blk) } @@ -2627,16 +2802,27 @@ impl<'self,A> old_iter::ExtendedIter for &'self [A] { impl<'self,A> old_iter::ExtendedMutableIter for &'self mut [A] { #[inline(always)] + #[cfg(stage0)] pub fn eachi_mut(&mut self, blk: &fn(uint, v: &mut A) -> bool) { eachi_mut(*self, blk) } + #[inline(always)] + #[cfg(not(stage0))] + pub fn eachi_mut(&mut self, blk: &fn(uint, v: &mut A) -> bool) -> bool { + eachi_mut(*self, blk) + } } // FIXME(#4148): This should be redundant impl old_iter::ExtendedIter for ~[A] { + #[cfg(stage0)] pub fn eachi(&self, blk: &fn(uint, v: &A) -> bool) { old_iter::eachi(self, blk) } + #[cfg(not(stage0))] + pub fn eachi(&self, blk: &fn(uint, v: &A) -> bool) -> bool { + old_iter::eachi(self, blk) + } pub fn all(&self, blk: &fn(&A) -> bool) -> bool { old_iter::all(self, blk) } @@ -2660,9 +2846,14 @@ impl old_iter::ExtendedIter for ~[A] { // FIXME(#4148): This should be redundant impl old_iter::ExtendedIter for @[A] { + #[cfg(stage0)] pub fn eachi(&self, blk: &fn(uint, v: &A) -> bool) { old_iter::eachi(self, blk) } + #[cfg(not(stage0))] + pub fn eachi(&self, blk: &fn(uint, v: &A) -> bool) -> bool { + old_iter::eachi(self, blk) + } pub fn all(&self, blk: &fn(&A) -> bool) -> bool { old_iter::all(self, blk) } @@ -4399,7 +4590,7 @@ mod tests { } i += 0; false - } + }; } #[test] @@ -4414,7 +4605,7 @@ mod tests { } i += 0; false - } + }; } #[test] diff --git a/src/librustc/metadata/csearch.rs b/src/librustc/metadata/csearch.rs index 375989b0ebe61..2f4a0d0b2a0e3 100644 --- a/src/librustc/metadata/csearch.rs +++ b/src/librustc/metadata/csearch.rs @@ -44,14 +44,24 @@ pub fn get_type_param_count(cstore: @mut cstore::CStore, def: ast::def_id) } /// Iterates over all the language items in the given crate. +#[cfg(stage0)] pub fn each_lang_item(cstore: @mut cstore::CStore, cnum: ast::crate_num, f: &fn(ast::node_id, uint) -> bool) { let crate_data = cstore::get_crate_data(cstore, cnum); decoder::each_lang_item(crate_data, f) } +/// Iterates over all the language items in the given crate. +#[cfg(not(stage0))] +pub fn each_lang_item(cstore: @mut cstore::CStore, + cnum: ast::crate_num, + f: &fn(ast::node_id, uint) -> bool) -> bool { + let crate_data = cstore::get_crate_data(cstore, cnum); + decoder::each_lang_item(crate_data, f) +} /// Iterates over all the paths in the given crate. +#[cfg(stage0)] pub fn each_path(cstore: @mut cstore::CStore, cnum: ast::crate_num, f: &fn(&str, decoder::def_like) -> bool) { @@ -61,6 +71,17 @@ pub fn each_path(cstore: @mut cstore::CStore, }; decoder::each_path(cstore.intr, crate_data, get_crate_data, f); } +/// Iterates over all the paths in the given crate. +#[cfg(not(stage0))] +pub fn each_path(cstore: @mut cstore::CStore, + cnum: ast::crate_num, + f: &fn(&str, decoder::def_like) -> bool) -> bool { + let crate_data = cstore::get_crate_data(cstore, cnum); + let get_crate_data: decoder::GetCrateDataCb = |cnum| { + cstore::get_crate_data(cstore, cnum) + }; + decoder::each_path(cstore.intr, crate_data, get_crate_data, f) +} pub fn get_item_path(tcx: ty::ctxt, def: ast::def_id) -> ast_map::path { let cstore = tcx.cstore; diff --git a/src/librustc/metadata/decoder.rs b/src/librustc/metadata/decoder.rs index fd35a4425d870..c121ddafc4daa 100644 --- a/src/librustc/metadata/decoder.rs +++ b/src/librustc/metadata/decoder.rs @@ -196,6 +196,7 @@ fn item_def_id(d: ebml::Doc, cdata: cmd) -> ast::def_id { |d| parse_def_id(d))); } +#[cfg(stage0)] fn each_reexport(d: ebml::Doc, f: &fn(ebml::Doc) -> bool) { for reader::tagged_docs(d, tag_items_data_item_reexport) |reexport_doc| { if !f(reexport_doc) { @@ -203,6 +204,15 @@ fn each_reexport(d: ebml::Doc, f: &fn(ebml::Doc) -> bool) { } } } +#[cfg(not(stage0))] +fn each_reexport(d: ebml::Doc, f: &fn(ebml::Doc) -> bool) -> bool { + for reader::tagged_docs(d, tag_items_data_item_reexport) |reexport_doc| { + if !f(reexport_doc) { + return false; + } + } + return true; +} fn variant_disr_val(d: ebml::Doc) -> Option { do reader::maybe_get_doc(d, tag_disr_val).chain |val_doc| { @@ -454,6 +464,7 @@ fn def_like_to_def(def_like: def_like) -> ast::def { } /// Iterates over the language items in the given crate. +#[cfg(stage0)] pub fn each_lang_item(cdata: cmd, f: &fn(ast::node_id, uint) -> bool) { let root = reader::Doc(cdata.data); let lang_items = reader::get_doc(root, tag_lang_items); @@ -469,11 +480,29 @@ pub fn each_lang_item(cdata: cmd, f: &fn(ast::node_id, uint) -> bool) { } } } +/// Iterates over the language items in the given crate. +#[cfg(not(stage0))] +pub fn each_lang_item(cdata: cmd, f: &fn(ast::node_id, uint) -> bool) -> bool { + let root = reader::Doc(cdata.data); + let lang_items = reader::get_doc(root, tag_lang_items); + for reader::tagged_docs(lang_items, tag_lang_items_item) |item_doc| { + let id_doc = reader::get_doc(item_doc, tag_lang_items_item_id); + let id = reader::doc_as_u32(id_doc) as uint; + let node_id_doc = reader::get_doc(item_doc, + tag_lang_items_item_node_id); + let node_id = reader::doc_as_u32(node_id_doc) as ast::node_id; + + if !f(node_id, id) { + return false; + } + } + return true; +} /// Iterates over all the paths in the given crate. -pub fn each_path(intr: @ident_interner, cdata: cmd, - get_crate_data: GetCrateDataCb, - f: &fn(&str, def_like) -> bool) { +pub fn _each_path(intr: @ident_interner, cdata: cmd, + get_crate_data: GetCrateDataCb, + f: &fn(&str, def_like) -> bool) -> bool { let root = reader::Doc(cdata.data); let items = reader::get_doc(root, tag_items); let items_data = reader::get_doc(items, tag_items_data); @@ -555,10 +584,20 @@ pub fn each_path(intr: @ident_interner, cdata: cmd, } } - // If broken, stop here. - if broken { - return; - } + return broken; +} + +#[cfg(stage0)] +pub fn each_path(intr: @ident_interner, cdata: cmd, + get_crate_data: GetCrateDataCb, + f: &fn(&str, def_like) -> bool) { + _each_path(intr, cdata, get_crate_data, f); +} +#[cfg(not(stage0))] +pub fn each_path(intr: @ident_interner, cdata: cmd, + get_crate_data: GetCrateDataCb, + f: &fn(&str, def_like) -> bool) -> bool { + _each_path(intr, cdata, get_crate_data, f) } pub fn get_item_path(intr: @ident_interner, cdata: cmd, id: ast::node_id) diff --git a/src/librustc/metadata/encoder.rs b/src/librustc/metadata/encoder.rs index 6c02ece9289ae..7d25d5f3ec92e 100644 --- a/src/librustc/metadata/encoder.rs +++ b/src/librustc/metadata/encoder.rs @@ -1391,11 +1391,10 @@ pub fn encode_metadata(parms: EncodeParams, crate: &crate) -> ~[u8] { ecx.stats.total_bytes = *wr.pos; if (tcx.sess.meta_stats()) { - do wr.bytes.each |e| { + for wr.bytes.each |e| { if *e == 0 { ecx.stats.zero_bytes += 1; } - true } io::println("metadata stats:"); diff --git a/src/librustc/metadata/filesearch.rs b/src/librustc/metadata/filesearch.rs index 7547f7f763af0..0708b7d38d321 100644 --- a/src/librustc/metadata/filesearch.rs +++ b/src/librustc/metadata/filesearch.rs @@ -21,7 +21,10 @@ pub fn pick_file(file: Path, path: &Path) -> Option { pub trait FileSearch { fn sysroot(&self) -> @Path; + #[cfg(stage0)] fn for_each_lib_search_path(&self, f: &fn(&Path) -> bool); + #[cfg(not(stage0))] + fn for_each_lib_search_path(&self, f: &fn(&Path) -> bool) -> bool; fn get_target_lib_path(&self) -> Path; fn get_target_lib_file_path(&self, file: &Path) -> Path; } @@ -37,6 +40,7 @@ pub fn mk_filesearch(maybe_sysroot: &Option<@Path>, } impl FileSearch for FileSearchImpl { fn sysroot(&self) -> @Path { self.sysroot } + #[cfg(stage0)] fn for_each_lib_search_path(&self, f: &fn(&Path) -> bool) { debug!("filesearch: searching additional lib search paths"); // a little weird @@ -60,6 +64,30 @@ pub fn mk_filesearch(maybe_sysroot: &Option<@Path>, result::Err(_) => true }; } + #[cfg(not(stage0))] + fn for_each_lib_search_path(&self, f: &fn(&Path) -> bool) -> bool { + debug!("filesearch: searching additional lib search paths"); + // a little weird + self.addl_lib_search_paths.each(f); + + debug!("filesearch: searching target lib path"); + if !f(&make_target_lib_path(self.sysroot, + self.target_triple)) { + return false; + } + debug!("filesearch: searching rustpkg lib path nearest"); + if match get_rustpkg_lib_path_nearest() { + result::Ok(ref p) => f(p), + result::Err(_) => true + } { + return true; + } + debug!("filesearch: searching rustpkg lib path"); + match get_rustpkg_lib_path() { + result::Ok(ref p) => f(p), + result::Err(_) => true + } + } fn get_target_lib_path(&self) -> Path { make_target_lib_path(self.sysroot, self.target_triple) } diff --git a/src/librustc/middle/borrowck/check_loans.rs b/src/librustc/middle/borrowck/check_loans.rs index ba719fe34d719..27f6ae33ba3d1 100644 --- a/src/librustc/middle/borrowck/check_loans.rs +++ b/src/librustc/middle/borrowck/check_loans.rs @@ -67,6 +67,7 @@ enum MoveError { pub impl<'self> CheckLoanCtxt<'self> { fn tcx(&self) -> ty::ctxt { self.bccx.tcx } + #[cfg(stage0)] fn each_issued_loan(&self, scope_id: ast::node_id, op: &fn(&Loan) -> bool) @@ -84,7 +85,27 @@ pub impl<'self> CheckLoanCtxt<'self> { } } } + #[cfg(not(stage0))] + fn each_issued_loan(&self, + scope_id: ast::node_id, + op: &fn(&Loan) -> bool) -> bool + { + //! Iterates over each loan that that has been issued + //! on entrance to `scope_id`, regardless of whether it is + //! actually *in scope* at that point. Sometimes loans + //! are issued for future scopes and thus they may have been + //! *issued* but not yet be in effect. + + for self.dfcx.each_bit_on_entry(scope_id) |loan_index| { + let loan = &self.all_loans[loan_index]; + if !op(loan) { + return false; + } + } + return true; + } + #[cfg(stage0)] fn each_in_scope_loan(&self, scope_id: ast::node_id, op: &fn(&Loan) -> bool) @@ -101,7 +122,26 @@ pub impl<'self> CheckLoanCtxt<'self> { } } } + #[cfg(not(stage0))] + fn each_in_scope_loan(&self, + scope_id: ast::node_id, + op: &fn(&Loan) -> bool) -> bool + { + //! Like `each_issued_loan()`, but only considers loans that are + //! currently in scope. + let region_maps = self.tcx().region_maps; + for self.each_issued_loan(scope_id) |loan| { + if region_maps.is_subscope_of(scope_id, loan.kill_scope) { + if !op(loan) { + return false; + } + } + } + return true; + } + + #[cfg(stage0)] fn each_in_scope_restriction(&self, scope_id: ast::node_id, loan_path: @LoanPath, @@ -120,6 +160,26 @@ pub impl<'self> CheckLoanCtxt<'self> { } } } + #[cfg(not(stage0))] + fn each_in_scope_restriction(&self, + scope_id: ast::node_id, + loan_path: @LoanPath, + op: &fn(&Loan, &Restriction) -> bool) -> bool + { + //! Iterates through all the in-scope restrictions for the + //! given `loan_path` + + for self.each_in_scope_loan(scope_id) |loan| { + for loan.restrictions.each |restr| { + if restr.loan_path == loan_path { + if !op(loan, restr) { + return false; + } + } + } + } + return true; + } fn loans_generated_by(&self, scope_id: ast::node_id) -> ~[uint] { //! Returns a vector of the loans that are generated as diff --git a/src/librustc/middle/dataflow.rs b/src/librustc/middle/dataflow.rs index ccb34851046bd..f1fa5144f4c75 100644 --- a/src/librustc/middle/dataflow.rs +++ b/src/librustc/middle/dataflow.rs @@ -182,6 +182,7 @@ impl DataFlowContext { } + #[cfg(stage0)] pub fn each_bit_on_entry(&self, id: ast::node_id, f: &fn(uint) -> bool) { @@ -194,7 +195,21 @@ impl DataFlowContext { id, bits_to_str(on_entry)); self.each_bit(on_entry, f); } + #[cfg(not(stage0))] + pub fn each_bit_on_entry(&self, + id: ast::node_id, + f: &fn(uint) -> bool) -> bool { + //! Iterates through each bit that is set on entry to `id`. + //! Only useful after `propagate()` has been called. + + let (start, end) = self.compute_id_range(id); + let on_entry = vec::slice(self.on_entry, start, end); + debug!("each_bit_on_entry(id=%?, on_entry=%s)", + id, bits_to_str(on_entry)); + self.each_bit(on_entry, f) + } + #[cfg(stage0)] pub fn each_gen_bit(&self, id: ast::node_id, f: &fn(uint) -> bool) { @@ -206,7 +221,20 @@ impl DataFlowContext { id, bits_to_str(gens)); self.each_bit(gens, f) } + #[cfg(not(stage0))] + pub fn each_gen_bit(&self, + id: ast::node_id, + f: &fn(uint) -> bool) -> bool { + //! Iterates through each bit in the gen set for `id`. + let (start, end) = self.compute_id_range(id); + let gens = vec::slice(self.gens, start, end); + debug!("each_gen_bit(id=%?, gens=%s)", + id, bits_to_str(gens)); + self.each_bit(gens, f) + } + + #[cfg(stage0)] fn each_bit(&self, words: &[uint], f: &fn(uint) -> bool) { @@ -236,6 +264,39 @@ impl DataFlowContext { } } } + #[cfg(not(stage0))] + fn each_bit(&self, + words: &[uint], + f: &fn(uint) -> bool) -> bool { + //! Helper for iterating over the bits in a bit set. + + for words.eachi |word_index, &word| { + if word != 0 { + let base_index = word_index * uint::bits; + for uint::range(0, uint::bits) |offset| { + let bit = 1 << offset; + if (word & bit) != 0 { + // NB: we round up the total number of bits + // that we store in any given bit set so that + // it is an even multiple of uint::bits. This + // means that there may be some stray bits at + // the end that do not correspond to any + // actual value. So before we callback, check + // whether the bit_index is greater than the + // actual value the user specified and stop + // iterating if so. + let bit_index = base_index + offset; + if bit_index >= self.bits_per_id { + return true; + } else if !f(bit_index) { + return false; + } + } + } + } + } + return true; + } } impl DataFlowContext { diff --git a/src/librustc/middle/lang_items.rs b/src/librustc/middle/lang_items.rs index c94dc3046dfd4..e2b4684696a90 100644 --- a/src/librustc/middle/lang_items.rs +++ b/src/librustc/middle/lang_items.rs @@ -86,6 +86,7 @@ pub impl LanguageItems { } } + #[cfg(stage0)] fn each_item(&self, f: &fn(def_id: def_id, i: uint) -> bool) { for self.items.eachi |i, &item| { if !f(item.get(), i) { @@ -93,6 +94,10 @@ pub impl LanguageItems { } } } + #[cfg(not(stage0))] + fn each_item(&self, f: &fn(def_id: def_id, i: uint) -> bool) -> bool { + self.items.eachi(|i, &item| f(item.get(), i)) + } pub fn item_name(index: uint) -> &'static str { match index { diff --git a/src/librustc/middle/resolve.rs b/src/librustc/middle/resolve.rs index 5c3bb6ca401a6..e1e74f7a84766 100644 --- a/src/librustc/middle/resolve.rs +++ b/src/librustc/middle/resolve.rs @@ -2408,14 +2408,14 @@ pub impl Resolver { let merge_import_resolution = |ident, name_bindings: @mut NameBindings| { let dest_import_resolution; - match module_.import_resolutions.find(ident) { + match module_.import_resolutions.find(&ident) { None => { // Create a new import resolution from this child. dest_import_resolution = @mut ImportResolution(privacy, span, state); module_.import_resolutions.insert - (*ident, dest_import_resolution); + (ident, dest_import_resolution); } Some(&existing_import_resolution) => { dest_import_resolution = existing_import_resolution; @@ -2424,7 +2424,7 @@ pub impl Resolver { debug!("(resolving glob import) writing resolution `%s` in `%s` \ to `%s`, privacy=%?", - *self.session.str_of(*ident), + *self.session.str_of(ident), self.module_to_str(containing_module), self.module_to_str(module_), copy dest_import_resolution.privacy); @@ -2443,13 +2443,13 @@ pub impl Resolver { }; // Add all children from the containing module. - for containing_module.children.each |ident, name_bindings| { + for containing_module.children.each |&ident, name_bindings| { merge_import_resolution(ident, *name_bindings); } // Add external module children from the containing module. for containing_module.external_module_children.each - |ident, module| { + |&ident, module| { let name_bindings = @mut Resolver::create_name_bindings_from_module(*module); merge_import_resolution(ident, name_bindings); diff --git a/src/librustc/middle/resolve_stage0.rs b/src/librustc/middle/resolve_stage0.rs index 3a6424efe1d22..a0fe66ead0425 100644 --- a/src/librustc/middle/resolve_stage0.rs +++ b/src/librustc/middle/resolve_stage0.rs @@ -2424,14 +2424,14 @@ pub impl Resolver { let merge_import_resolution = |ident, name_bindings: @mut NameBindings| { let dest_import_resolution; - match module_.import_resolutions.find(ident) { + match module_.import_resolutions.find(&ident) { None => { // Create a new import resolution from this child. dest_import_resolution = @mut ImportResolution(privacy, span, state); module_.import_resolutions.insert - (*ident, dest_import_resolution); + (ident, dest_import_resolution); } Some(existing_import_resolution) => { dest_import_resolution = *existing_import_resolution; @@ -2440,7 +2440,7 @@ pub impl Resolver { debug!("(resolving glob import) writing resolution `%s` in `%s` \ to `%s`, privacy=%?", - *self.session.str_of(*ident), + *self.session.str_of(ident), self.module_to_str(containing_module), self.module_to_str(module_), copy dest_import_resolution.privacy); @@ -2459,13 +2459,13 @@ pub impl Resolver { }; // Add all children from the containing module. - for containing_module.children.each |ident, name_bindings| { + for containing_module.children.each |&ident, name_bindings| { merge_import_resolution(ident, *name_bindings); } // Add external module children from the containing module. for containing_module.external_module_children.each - |ident, module| { + |&ident, module| { let name_bindings = @mut Resolver::create_name_bindings_from_module(*module); merge_import_resolution(ident, name_bindings); diff --git a/src/librustc/middle/trans/callee.rs b/src/librustc/middle/trans/callee.rs index e5e60b2d4ac33..c530cd973978b 100644 --- a/src/librustc/middle/trans/callee.rs +++ b/src/librustc/middle/trans/callee.rs @@ -550,7 +550,14 @@ pub fn trans_call_inner(in_cx: block, // drop the value if it is not being saved. unsafe { if llvm::LLVMIsUndef(llretslot) != lib::llvm::True { - if ty::type_is_immediate(ret_ty) { + if ty::type_is_nil(ret_ty) { + // When implementing the for-loop sugar syntax, the + // type of the for-loop is nil, but the function + // it's invoking returns a bool. This is a special + // case to ignore instead of invoking the Store + // below into a scratch pointer of a mismatched + // type. + } else if ty::type_is_immediate(ret_ty) { let llscratchptr = alloc_ty(bcx, ret_ty); Store(bcx, llresult, llscratchptr); bcx = glue::drop_ty(bcx, llscratchptr, ret_ty); diff --git a/src/librustc/middle/trans/common.rs b/src/librustc/middle/trans/common.rs index c1309b422880a..d8db5bac24dc5 100644 --- a/src/librustc/middle/trans/common.rs +++ b/src/librustc/middle/trans/common.rs @@ -1369,6 +1369,7 @@ pub struct mono_id_ { pub type mono_id = @mono_id_; +#[cfg(stage0)] impl to_bytes::IterBytes for mono_param_id { fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) { match *self { @@ -1382,18 +1383,46 @@ impl to_bytes::IterBytes for mono_param_id { } } } +#[cfg(not(stage0))] +impl to_bytes::IterBytes for mono_param_id { + fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) -> bool { + match *self { + mono_precise(t, ref mids) => + to_bytes::iter_bytes_3(&0u8, &ty::type_id(t), mids, lsb0, f), + + mono_any => 1u8.iter_bytes(lsb0, f), + mono_repr(ref a, ref b, ref c, ref d) => + to_bytes::iter_bytes_5(&2u8, a, b, c, d, lsb0, f) + } + } +} + +#[cfg(stage0)] impl to_bytes::IterBytes for MonoDataClass { fn iter_bytes(&self, lsb0: bool, f:to_bytes::Cb) { (*self as u8).iter_bytes(lsb0, f) } } +#[cfg(not(stage0))] +impl to_bytes::IterBytes for MonoDataClass { + fn iter_bytes(&self, lsb0: bool, f:to_bytes::Cb) -> bool { + (*self as u8).iter_bytes(lsb0, f) + } +} +#[cfg(stage0)] impl to_bytes::IterBytes for mono_id_ { fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) { to_bytes::iter_bytes_2(&self.def, &self.params, lsb0, f); } } +#[cfg(not(stage0))] +impl to_bytes::IterBytes for mono_id_ { + fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) -> bool { + to_bytes::iter_bytes_2(&self.def, &self.params, lsb0, f) + } +} pub fn umax(cx: block, a: ValueRef, b: ValueRef) -> ValueRef { let cond = build::ICmp(cx, lib::llvm::IntULT, a, b); diff --git a/src/librustc/middle/trans/datum.rs b/src/librustc/middle/trans/datum.rs index 64b29fd8573d2..374bb23f2cb57 100644 --- a/src/librustc/middle/trans/datum.rs +++ b/src/librustc/middle/trans/datum.rs @@ -155,11 +155,18 @@ pub impl DatumMode { } } +#[cfg(stage0)] impl to_bytes::IterBytes for DatumMode { fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) { (*self as uint).iter_bytes(lsb0, f) } } +#[cfg(not(stage0))] +impl to_bytes::IterBytes for DatumMode { + fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) -> bool { + (*self as uint).iter_bytes(lsb0, f) + } +} /// See `Datum cleanup styles` section at the head of this module. #[deriving(Eq)] diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs index c31843870e88c..737548ee86869 100644 --- a/src/librustc/middle/ty.rs +++ b/src/librustc/middle/ty.rs @@ -121,11 +121,18 @@ pub struct creader_cache_key { type creader_cache = @mut HashMap; +#[cfg(stage0)] impl to_bytes::IterBytes for creader_cache_key { fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) { to_bytes::iter_bytes_3(&self.cnum, &self.pos, &self.len, lsb0, f); } } +#[cfg(not(stage0))] +impl to_bytes::IterBytes for creader_cache_key { + fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) -> bool { + to_bytes::iter_bytes_3(&self.cnum, &self.pos, &self.len, lsb0, f) + } +} struct intern_key { sty: *sty, @@ -145,6 +152,7 @@ impl cmp::Eq for intern_key { } } +#[cfg(stage0)] impl to_bytes::IterBytes for intern_key { fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) { unsafe { @@ -152,6 +160,14 @@ impl to_bytes::IterBytes for intern_key { } } } +#[cfg(not(stage0))] +impl to_bytes::IterBytes for intern_key { + fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) -> bool { + unsafe { + (*self.sty).iter_bytes(lsb0, f) + } + } +} pub enum ast_ty_to_ty_cache_entry { atttce_unresolved, /* not resolved yet */ @@ -382,18 +398,33 @@ pub struct FnSig { output: t } +#[cfg(stage0)] impl to_bytes::IterBytes for BareFnTy { fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) { to_bytes::iter_bytes_3(&self.purity, &self.abis, &self.sig, lsb0, f) } } +#[cfg(not(stage0))] +impl to_bytes::IterBytes for BareFnTy { + fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) -> bool { + to_bytes::iter_bytes_3(&self.purity, &self.abis, &self.sig, lsb0, f) + } +} +#[cfg(stage0)] impl to_bytes::IterBytes for ClosureTy { fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) { to_bytes::iter_bytes_5(&self.purity, &self.sigil, &self.onceness, &self.region, &self.sig, lsb0, f) } } +#[cfg(not(stage0))] +impl to_bytes::IterBytes for ClosureTy { + fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) -> bool { + to_bytes::iter_bytes_5(&self.purity, &self.sigil, &self.onceness, + &self.region, &self.sig, lsb0, f) + } +} #[deriving(Eq, IterBytes)] pub struct param_ty { @@ -705,6 +736,7 @@ pub enum InferTy { FloatVar(FloatVid) } +#[cfg(stage0)] impl to_bytes::IterBytes for InferTy { fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) { match *self { @@ -714,6 +746,16 @@ impl to_bytes::IterBytes for InferTy { } } } +#[cfg(not(stage0))] +impl to_bytes::IterBytes for InferTy { + fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) -> bool { + match *self { + TyVar(ref tv) => to_bytes::iter_bytes_2(&0u8, tv, lsb0, f), + IntVar(ref iv) => to_bytes::iter_bytes_2(&1u8, iv, lsb0, f), + FloatVar(ref fv) => to_bytes::iter_bytes_2(&2u8, fv, lsb0, f), + } + } +} #[auto_encode] #[auto_decode] @@ -722,6 +764,7 @@ pub enum InferRegion { ReSkolemized(uint, bound_region) } +#[cfg(stage0)] impl to_bytes::IterBytes for InferRegion { fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) { match *self { @@ -730,6 +773,15 @@ impl to_bytes::IterBytes for InferRegion { } } } +#[cfg(not(stage0))] +impl to_bytes::IterBytes for InferRegion { + fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) -> bool { + match *self { + ReVar(ref rv) => to_bytes::iter_bytes_2(&0u8, rv, lsb0, f), + ReSkolemized(ref v, _) => to_bytes::iter_bytes_2(&1u8, v, lsb0, f) + } + } +} impl cmp::Eq for InferRegion { fn eq(&self, other: &InferRegion) -> bool { @@ -810,29 +862,57 @@ impl ToStr for IntVarValue { } } +#[cfg(stage0)] impl to_bytes::IterBytes for TyVid { fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) { self.to_uint().iter_bytes(lsb0, f) } } +#[cfg(not(stage0))] +impl to_bytes::IterBytes for TyVid { + fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) -> bool { + self.to_uint().iter_bytes(lsb0, f) + } +} +#[cfg(stage0)] impl to_bytes::IterBytes for IntVid { fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) { self.to_uint().iter_bytes(lsb0, f) } } +#[cfg(not(stage0))] +impl to_bytes::IterBytes for IntVid { + fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) -> bool { + self.to_uint().iter_bytes(lsb0, f) + } +} +#[cfg(stage0)] impl to_bytes::IterBytes for FloatVid { fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) { self.to_uint().iter_bytes(lsb0, f) } } +#[cfg(not(stage0))] +impl to_bytes::IterBytes for FloatVid { + fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) -> bool { + self.to_uint().iter_bytes(lsb0, f) + } +} +#[cfg(stage0)] impl to_bytes::IterBytes for RegionVid { fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) { self.to_uint().iter_bytes(lsb0, f) } } +#[cfg(not(stage0))] +impl to_bytes::IterBytes for RegionVid { + fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) -> bool { + self.to_uint().iter_bytes(lsb0, f) + } +} pub struct TypeParameterDef { def_id: ast::def_id, @@ -2637,6 +2717,7 @@ impl cmp::TotalEq for bound_region { } } +#[cfg(stage0)] impl to_bytes::IterBytes for vstore { fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) { match *self { @@ -2651,7 +2732,23 @@ impl to_bytes::IterBytes for vstore { } } } +#[cfg(not(stage0))] +impl to_bytes::IterBytes for vstore { + fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) -> bool { + match *self { + vstore_fixed(ref u) => + to_bytes::iter_bytes_2(&0u8, u, lsb0, f), + vstore_uniq => 1u8.iter_bytes(lsb0, f), + vstore_box => 2u8.iter_bytes(lsb0, f), + + vstore_slice(ref r) => + to_bytes::iter_bytes_2(&3u8, r, lsb0, f), + } + } +} + +#[cfg(stage0)] impl to_bytes::IterBytes for substs { fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) { to_bytes::iter_bytes_3(&self.self_r, @@ -2659,21 +2756,46 @@ impl to_bytes::IterBytes for substs { &self.tps, lsb0, f) } } +#[cfg(not(stage0))] +impl to_bytes::IterBytes for substs { + fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) -> bool { + to_bytes::iter_bytes_3(&self.self_r, + &self.self_ty, + &self.tps, lsb0, f) + } +} +#[cfg(stage0)] impl to_bytes::IterBytes for mt { fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) { to_bytes::iter_bytes_2(&self.ty, &self.mutbl, lsb0, f) } } +#[cfg(not(stage0))] +impl to_bytes::IterBytes for mt { + fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) -> bool { + to_bytes::iter_bytes_2(&self.ty, + &self.mutbl, lsb0, f) + } +} +#[cfg(stage0)] impl to_bytes::IterBytes for field { fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) { to_bytes::iter_bytes_2(&self.ident, &self.mt, lsb0, f) } } +#[cfg(not(stage0))] +impl to_bytes::IterBytes for field { + fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) -> bool { + to_bytes::iter_bytes_2(&self.ident, + &self.mt, lsb0, f) + } +} +#[cfg(stage0)] impl to_bytes::IterBytes for FnSig { fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) { to_bytes::iter_bytes_2(&self.inputs, @@ -2681,7 +2803,16 @@ impl to_bytes::IterBytes for FnSig { lsb0, f); } } +#[cfg(not(stage0))] +impl to_bytes::IterBytes for FnSig { + fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) -> bool { + to_bytes::iter_bytes_2(&self.inputs, + &self.output, + lsb0, f) + } +} +#[cfg(stage0)] impl to_bytes::IterBytes for sty { fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) { match *self { @@ -2756,6 +2887,81 @@ impl to_bytes::IterBytes for sty { } } } +#[cfg(not(stage0))] +impl to_bytes::IterBytes for sty { + fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) -> bool { + match *self { + ty_nil => 0u8.iter_bytes(lsb0, f), + ty_bool => 1u8.iter_bytes(lsb0, f), + + ty_int(ref t) => + to_bytes::iter_bytes_2(&2u8, t, lsb0, f), + + ty_uint(ref t) => + to_bytes::iter_bytes_2(&3u8, t, lsb0, f), + + ty_float(ref t) => + to_bytes::iter_bytes_2(&4u8, t, lsb0, f), + + ty_estr(ref v) => + to_bytes::iter_bytes_2(&5u8, v, lsb0, f), + + ty_enum(ref did, ref substs) => + to_bytes::iter_bytes_3(&6u8, did, substs, lsb0, f), + + ty_box(ref mt) => + to_bytes::iter_bytes_2(&7u8, mt, lsb0, f), + + ty_evec(ref mt, ref v) => + to_bytes::iter_bytes_3(&8u8, mt, v, lsb0, f), + + ty_unboxed_vec(ref mt) => + to_bytes::iter_bytes_2(&9u8, mt, lsb0, f), + + ty_tup(ref ts) => + to_bytes::iter_bytes_2(&10u8, ts, lsb0, f), + + ty_bare_fn(ref ft) => + to_bytes::iter_bytes_2(&12u8, ft, lsb0, f), + + ty_self(ref did) => to_bytes::iter_bytes_2(&13u8, did, lsb0, f), + + ty_infer(ref v) => + to_bytes::iter_bytes_2(&14u8, v, lsb0, f), + + ty_param(ref p) => + to_bytes::iter_bytes_2(&15u8, p, lsb0, f), + + ty_type => 16u8.iter_bytes(lsb0, f), + ty_bot => 17u8.iter_bytes(lsb0, f), + + ty_ptr(ref mt) => + to_bytes::iter_bytes_2(&18u8, mt, lsb0, f), + + ty_uniq(ref mt) => + to_bytes::iter_bytes_2(&19u8, mt, lsb0, f), + + ty_trait(ref did, ref substs, ref v, ref mutbl) => + to_bytes::iter_bytes_5(&20u8, did, substs, v, mutbl, lsb0, f), + + ty_opaque_closure_ptr(ref ck) => + to_bytes::iter_bytes_2(&21u8, ck, lsb0, f), + + ty_opaque_box => 22u8.iter_bytes(lsb0, f), + + ty_struct(ref did, ref substs) => + to_bytes::iter_bytes_3(&23u8, did, substs, lsb0, f), + + ty_rptr(ref r, ref mt) => + to_bytes::iter_bytes_3(&24u8, r, mt, lsb0, f), + + ty_err => 25u8.iter_bytes(lsb0, f), + + ty_closure(ref ct) => + to_bytes::iter_bytes_2(&26u8, ct, lsb0, f), + } + } +} pub fn node_id_to_trait_ref(cx: ctxt, id: ast::node_id) -> @ty::TraitRef { match cx.trait_refs.find(&id) { @@ -4284,6 +4490,7 @@ pub fn determine_inherited_purity(parent: (ast::purity, ast::node_id), // Here, the supertraits are the transitive closure of the supertrait // relation on the supertraits from each bounded trait's constraint // list. +#[cfg(stage0)] pub fn each_bound_trait_and_supertraits(tcx: ctxt, bounds: &ParamBounds, f: &fn(@TraitRef) -> bool) { @@ -4323,6 +4530,52 @@ pub fn each_bound_trait_and_supertraits(tcx: ctxt, } } } +// Iterate over a type parameter's bounded traits and any supertraits +// of those traits, ignoring kinds. +// Here, the supertraits are the transitive closure of the supertrait +// relation on the supertraits from each bounded trait's constraint +// list. +#[cfg(not(stage0))] +pub fn each_bound_trait_and_supertraits(tcx: ctxt, + bounds: &ParamBounds, + f: &fn(@TraitRef) -> bool) -> bool { + for bounds.trait_bounds.each |&bound_trait_ref| { + let mut supertrait_set = HashMap::new(); + let mut trait_refs = ~[]; + let mut i = 0; + + // Seed the worklist with the trait from the bound + supertrait_set.insert(bound_trait_ref.def_id, ()); + trait_refs.push(bound_trait_ref); + + // Add the given trait ty to the hash map + while i < trait_refs.len() { + debug!("each_bound_trait_and_supertraits(i=%?, trait_ref=%s)", + i, trait_refs[i].repr(tcx)); + + if !f(trait_refs[i]) { + return false; + } + + // Add supertraits to supertrait_set + let supertrait_refs = trait_ref_supertraits(tcx, trait_refs[i]); + for supertrait_refs.each |&supertrait_ref| { + debug!("each_bound_trait_and_supertraits(supertrait_ref=%s)", + supertrait_ref.repr(tcx)); + + let d_id = supertrait_ref.def_id; + if !supertrait_set.contains_key(&d_id) { + // FIXME(#5527) Could have same trait multiple times + supertrait_set.insert(d_id, ()); + trait_refs.push(supertrait_ref); + } + } + + i += 1; + } + } + return true; +} pub fn count_traits_and_supertraits(tcx: ctxt, type_param_defs: &[TypeParameterDef]) -> uint { diff --git a/src/librustc/middle/typeck/check/mod.rs b/src/librustc/middle/typeck/check/mod.rs index a6f2f0da234d4..1c3890e2e179c 100644 --- a/src/librustc/middle/typeck/check/mod.rs +++ b/src/librustc/middle/typeck/check/mod.rs @@ -828,6 +828,7 @@ pub impl FnCtxt { } } + #[cfg(stage0)] fn opt_node_ty_substs(&self, id: ast::node_id, f: &fn(&ty::substs) -> bool) { match self.inh.node_type_substs.find(&id) { @@ -835,6 +836,14 @@ pub impl FnCtxt { None => () } } + #[cfg(not(stage0))] + fn opt_node_ty_substs(&self, id: ast::node_id, + f: &fn(&ty::substs) -> bool) -> bool { + match self.inh.node_type_substs.find(&id) { + Some(s) => f(s), + None => true + } + } fn mk_subty(&self, a_is_expected: bool, @@ -1294,6 +1303,26 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt, // The callee checks for bot / err, we don't need to } + fn write_call(fcx: @mut FnCtxt, + call_expr: @ast::expr, + output: ty::t, + sugar: ast::CallSugar) { + let ret_ty = match sugar { + ast::ForSugar => { + match ty::get(output).sty { + ty::ty_bool => {} + _ => fcx.type_error_message(call_expr.span, |actual| { + fmt!("expected `for` closure to return `bool`, \ + but found `%s`", actual) }, + output, None) + } + ty::mk_nil() + } + _ => output + }; + fcx.write_ty(call_expr.id, ret_ty); + } + // A generic function for doing all of the checking for call expressions fn check_call(fcx: @mut FnCtxt, call_expr: @ast::expr, @@ -1344,8 +1373,7 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt, check_argument_types(fcx, call_expr.span, fn_sig.inputs, f, args, sugar, DontDerefArgs); - // Pull the return type out of the type of the function. - fcx.write_ty(call_expr.id, fn_sig.output); + write_call(fcx, call_expr, fn_sig.output, sugar); } // Checks a method call. @@ -1401,8 +1429,7 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt, fn_ty, expr, args, sugar, DontDerefArgs); - // Pull the return type out of the type of the function. - fcx.write_ty(expr.id, ret_ty); + write_call(fcx, expr, ret_ty, sugar); } // A generic function for checking the then and else in an if diff --git a/src/librustc/middle/typeck/coherence.rs b/src/librustc/middle/typeck/coherence.rs index 6a83db6baee3c..260d3f440f9cf 100644 --- a/src/librustc/middle/typeck/coherence.rs +++ b/src/librustc/middle/typeck/coherence.rs @@ -524,6 +524,7 @@ pub impl CoherenceChecker { } } + #[cfg(stage0)] fn each_provided_trait_method(&self, trait_did: ast::def_id, f: &fn(x: @ty::method) -> bool) { @@ -543,6 +544,27 @@ pub impl CoherenceChecker { } } } + #[cfg(not(stage0))] + fn each_provided_trait_method(&self, + trait_did: ast::def_id, + f: &fn(x: @ty::method) -> bool) -> bool { + // Make a list of all the names of the provided methods. + // XXX: This is horrible. + let mut provided_method_idents = HashSet::new(); + let tcx = self.crate_context.tcx; + for ty::provided_trait_methods(tcx, trait_did).each |ident| { + provided_method_idents.insert(*ident); + } + + for ty::trait_methods(tcx, trait_did).each |&method| { + if provided_method_idents.contains(&method.ident) { + if !f(method) { + return false; + } + } + } + return true; + } fn polytypes_unify(&self, polytype_a: ty_param_bounds_and_ty, polytype_b: ty_param_bounds_and_ty) diff --git a/src/librustc/middle/typeck/infer/region_inference.rs b/src/librustc/middle/typeck/infer/region_inference.rs index 8349e16d2c440..73c120ad35dd3 100644 --- a/src/librustc/middle/typeck/infer/region_inference.rs +++ b/src/librustc/middle/typeck/infer/region_inference.rs @@ -560,6 +560,7 @@ enum Constraint { ConstrainVarSubReg(RegionVid, Region) } +#[cfg(stage0)] impl to_bytes::IterBytes for Constraint { fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) { match *self { @@ -574,6 +575,21 @@ impl to_bytes::IterBytes for Constraint { } } } +#[cfg(not(stage0))] +impl to_bytes::IterBytes for Constraint { + fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) -> bool { + match *self { + ConstrainVarSubVar(ref v0, ref v1) => + to_bytes::iter_bytes_3(&0u8, v0, v1, lsb0, f), + + ConstrainRegSubVar(ref ra, ref va) => + to_bytes::iter_bytes_3(&1u8, ra, va, lsb0, f), + + ConstrainVarSubReg(ref va, ref ra) => + to_bytes::iter_bytes_3(&2u8, va, ra, lsb0, f) + } + } +} #[deriving(Eq, IterBytes)] struct TwoRegions { @@ -1756,6 +1772,7 @@ pub impl RegionVarBindings { } } + #[cfg(stage0)] fn each_edge(&mut self, graph: &Graph, node_idx: RegionVid, @@ -1771,6 +1788,23 @@ pub impl RegionVarBindings { edge_idx = edge_ptr.next_edge[dir as uint]; } } + #[cfg(not(stage0))] + fn each_edge(&mut self, + graph: &Graph, + node_idx: RegionVid, + dir: Direction, + op: &fn(edge: &GraphEdge) -> bool) -> bool { + let mut edge_idx = + graph.nodes[node_idx.to_uint()].head_edge[dir as uint]; + while edge_idx != uint::max_value { + let edge_ptr = &graph.edges[edge_idx]; + if !op(edge_ptr) { + return false; + } + edge_idx = edge_ptr.next_edge[dir as uint]; + } + return true; + } } fn iterate_until_fixed_point( diff --git a/src/librustc/util/enum_set.rs b/src/librustc/util/enum_set.rs index 859e743b43bfa..c589ab5287421 100644 --- a/src/librustc/util/enum_set.rs +++ b/src/librustc/util/enum_set.rs @@ -49,6 +49,7 @@ pub impl EnumSet { (self.bits & bit(e)) != 0 } + #[cfg(stage0)] fn each(&self, f: &fn(E) -> bool) { let mut bits = self.bits; let mut index = 0; @@ -63,6 +64,22 @@ pub impl EnumSet { bits >>= 1; } } + #[cfg(not(stage0))] + fn each(&self, f: &fn(E) -> bool) -> bool { + let mut bits = self.bits; + let mut index = 0; + while bits != 0 { + if (bits & 1) != 0 { + let e = CLike::from_uint(index); + if !f(e) { + return false; + } + } + index += 1; + bits >>= 1; + } + return true; + } } impl core::Sub, EnumSet> for EnumSet { diff --git a/src/librustpkg/workspace.rs b/src/librustpkg/workspace.rs index 15e2166b24abe..94b94d373e6b6 100644 --- a/src/librustpkg/workspace.rs +++ b/src/librustpkg/workspace.rs @@ -14,7 +14,7 @@ use path_util::{rust_path, workspace_contains_package_id}; use util::PkgId; use core::path::Path; -pub fn pkg_parent_workspaces(pkgid: PkgId, action: &fn(&Path) -> bool) { +pub fn pkg_parent_workspaces(pkgid: PkgId, action: &fn(&Path) -> bool) -> bool { // Using the RUST_PATH, find workspaces that contain // this package ID let workspaces = rust_path().filtered(|ws| @@ -31,4 +31,5 @@ pub fn pkg_parent_workspaces(pkgid: PkgId, action: &fn(&Path) -> bool) { break; } } -} \ No newline at end of file + return true; +} diff --git a/src/libstd/bitv.rs b/src/libstd/bitv.rs index 461fb61ed5665..09f86f30d320f 100644 --- a/src/libstd/bitv.rs +++ b/src/libstd/bitv.rs @@ -143,6 +143,7 @@ pub impl BigBitv { } #[inline(always)] + #[cfg(stage0)] fn each_storage(&mut self, op: &fn(v: &mut uint) -> bool) { for uint::range(0, self.storage.len()) |i| { let mut w = self.storage[i]; @@ -150,7 +151,12 @@ pub impl BigBitv { self.storage[i] = w; if !b { break; } } - } + } + #[inline(always)] + #[cfg(not(stage0))] + fn each_storage(&mut self, op: &fn(v: &mut uint) -> bool) -> bool { + uint::range(0, self.storage.len(), |i| op(&mut self.storage[i])) + } #[inline(always)] fn invert(&mut self) { for self.each_storage |w| { *w = !*w } } @@ -193,6 +199,7 @@ pub impl BigBitv { } #[inline(always)] + #[cfg(stage0)] fn equals(&self, b: &BigBitv, nbits: uint) -> bool { let len = b.storage.len(); for uint::iterate(0, len) |i| { @@ -203,6 +210,19 @@ pub impl BigBitv { } } + #[inline(always)] + #[cfg(not(stage0))] + fn equals(&self, b: &BigBitv, nbits: uint) -> bool { + let len = b.storage.len(); + for uint::iterate(0, len) |i| { + let mask = big_mask(nbits, i); + if mask & self.storage[i] != mask & b.storage[i] { + return false; + } + } + return true; + } + } enum BitvVariant { Big(~BigBitv), Small(~SmallBitv) } @@ -387,6 +407,7 @@ pub impl Bitv { } #[inline(always)] + #[cfg(stage0)] fn each(&self, f: &fn(bool) -> bool) { let mut i = 0; while i < self.nbits { @@ -394,6 +415,16 @@ pub impl Bitv { i += 1; } } + #[inline(always)] + #[cfg(not(stage0))] + fn each(&self, f: &fn(bool) -> bool) -> bool { + let mut i = 0; + while i < self.nbits { + if !f(self.get(i)) { return false; } + i += 1; + } + return true; + } /// Returns true if all bits are 0 fn is_false(&self) -> bool { @@ -488,6 +519,7 @@ pub impl Bitv { true } + #[cfg(stage0)] fn ones(&self, f: &fn(uint) -> bool) { for uint::range(0, self.nbits) |i| { if self.get(i) { @@ -495,6 +527,10 @@ pub impl Bitv { } } } + #[cfg(not(stage0))] + fn ones(&self, f: &fn(uint) -> bool) -> bool { + uint::range(0, self.nbits, |i| !self.get(i) || f(i)) + } } @@ -661,18 +697,21 @@ pub impl BitvSet { } } +#[cfg(not(stage0))] impl BaseIter for BitvSet { fn size_hint(&self) -> Option { Some(self.len()) } - fn each(&self, blk: &fn(v: &uint) -> bool) { + fn each(&self, blk: &fn(v: &uint) -> bool) -> bool { for self.bitv.storage.eachi |i, &w| { if !iterate_bits(i * uint::bits, w, |b| blk(&b)) { - return; + return false; } } + return true; } } +#[cfg(not(stage0))] impl cmp::Eq for BitvSet { fn eq(&self, other: &BitvSet) -> bool { if self.size != other.size { @@ -706,6 +745,7 @@ impl Mutable for BitvSet { } } +#[cfg(not(stage0))] impl Set for BitvSet { fn contains(&self, value: &uint) -> bool { *value < self.bitv.storage.len() * uint::bits && self.bitv.get(*value) @@ -773,64 +813,55 @@ impl Set for BitvSet { other.is_subset(self) } - fn difference(&self, other: &BitvSet, f: &fn(&uint) -> bool) { + fn difference(&self, other: &BitvSet, f: &fn(&uint) -> bool) -> bool { for self.each_common(other) |i, w1, w2| { if !iterate_bits(i, w1 & !w2, |b| f(&b)) { - return; + return false; } } /* everything we have that they don't also shows up */ self.each_outlier(other, |mine, i, w| !mine || iterate_bits(i, w, |b| f(&b)) - ); + ) } fn symmetric_difference(&self, other: &BitvSet, - f: &fn(&uint) -> bool) { + f: &fn(&uint) -> bool) -> bool { for self.each_common(other) |i, w1, w2| { if !iterate_bits(i, w1 ^ w2, |b| f(&b)) { - return; + return false; } } - self.each_outlier(other, |_, i, w| - iterate_bits(i, w, |b| f(&b)) - ); + self.each_outlier(other, |_, i, w| iterate_bits(i, w, |b| f(&b))) } - fn intersection(&self, other: &BitvSet, f: &fn(&uint) -> bool) { - for self.each_common(other) |i, w1, w2| { - if !iterate_bits(i, w1 & w2, |b| f(&b)) { - return; - } - } + 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))) } - fn union(&self, other: &BitvSet, f: &fn(&uint) -> bool) { + fn union(&self, other: &BitvSet, f: &fn(&uint) -> bool) -> bool { for self.each_common(other) |i, w1, w2| { if !iterate_bits(i, w1 | w2, |b| f(&b)) { - return; + return false; } } - self.each_outlier(other, |_, i, w| - iterate_bits(i, w, |b| f(&b)) - ); + self.each_outlier(other, |_, i, w| iterate_bits(i, w, |b| f(&b))) } } +#[cfg(not(stage0))] priv impl BitvSet { /// Visits each of the words that the two bit vectors (self and other) /// 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) { + f: &fn(uint, uint, uint) -> bool) -> bool { let min = uint::min(self.bitv.storage.len(), other.bitv.storage.len()); - for self.bitv.storage.slice(0, min).eachi |i, &w| { - if !f(i * uint::bits, w, other.bitv.storage[i]) { - return; - } - } + self.bitv.storage.slice(0, min).eachi(|i, &w| { + f(i * uint::bits, w, other.bitv.storage[i]) + }) } /// Visits each word in self or other that extends beyond the other. This @@ -841,7 +872,7 @@ priv impl BitvSet { /// 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) { + f: &fn(bool, uint, uint) -> bool) -> bool { let len1 = self.bitv.storage.len(); let len2 = other.bitv.storage.len(); let min = uint::min(len1, len2); @@ -849,14 +880,15 @@ priv impl BitvSet { /* only one of these loops will execute and that's the point */ for self.bitv.storage.slice(min, len1).eachi |i, &w| { if !f(true, (i + min) * uint::bits, w) { - return; + return false; } } for other.bitv.storage.slice(min, len2).eachi |i, &w| { if !f(false, (i + min) * uint::bits, w) { - return; + return false; } } + return true; } } diff --git a/src/libstd/deque.rs b/src/libstd/deque.rs index 4c7f2edc6b048..4eb359e48a84d 100644 --- a/src/libstd/deque.rs +++ b/src/libstd/deque.rs @@ -63,15 +63,25 @@ pub impl Deque { } /// Iterate over the elements in the deque + #[cfg(stage0)] fn each(&self, f: &fn(&T) -> bool) { self.eachi(|_i, e| f(e)) } + /// Iterate over the elements in the deque + #[cfg(not(stage0))] + fn each(&self, f: &fn(&T) -> bool) -> bool { + self.eachi(|_i, e| f(e)) + } /// Iterate over the elements in the deque by index + #[cfg(stage0)] fn eachi(&self, f: &fn(uint, &T) -> bool) { - for uint::range(0, self.nelts) |i| { - if !f(i, self.get(i as int)) { return; } - } + uint::range(0, self.nelts, |i| f(i, self.get(i as int))) + } + /// Iterate over the elements in the deque by index + #[cfg(not(stage0))] + fn eachi(&self, f: &fn(uint, &T) -> bool) -> bool { + uint::range(0, self.nelts, |i| f(i, self.get(i as int))) } /// Remove and return the first element in the deque diff --git a/src/libstd/dlist.rs b/src/libstd/dlist.rs index 1257d55453205..741bd62968018 100644 --- a/src/libstd/dlist.rs +++ b/src/libstd/dlist.rs @@ -393,6 +393,7 @@ pub impl DList { } /// Iterate over nodes. + #[cfg(stage0)] fn each_node(@mut self, f: &fn(@mut DListNode) -> bool) { let mut link = self.peek_n(); while link.is_some() { @@ -401,6 +402,17 @@ pub impl DList { link = nobe.next_link(); } } + /// Iterate over nodes. + #[cfg(not(stage0))] + fn each_node(@mut self, f: &fn(@mut DListNode) -> bool) -> bool { + let mut link = self.peek_n(); + while link.is_some() { + let nobe = link.get(); + if !f(nobe) { return false; } + link = nobe.next_link(); + } + return true; + } /// Check data structure integrity. O(n). fn assert_consistent(@mut self) { @@ -492,12 +504,13 @@ pub impl DList { impl BaseIter for @mut DList { /** - * Iterates through the current contents. - * - * Attempts to access this dlist during iteration are allowed (to - * allow for e.g. breadth-first search with in-place enqueues), but - * removing the current node is forbidden. - */ + * Iterates through the current contents. + * + * Attempts to access this dlist during iteration are allowed (to + * allow for e.g. breadth-first search with in-place enqueues), but + * removing the current node is forbidden. + */ + #[cfg(stage0)] fn each(&self, f: &fn(v: &T) -> bool) { let mut link = self.peek_n(); while link.is_some() { @@ -525,6 +538,42 @@ impl BaseIter for @mut DList { link = nobe.next_link(); } } + /** + * Iterates through the current contents. + * + * Attempts to access this dlist during iteration are allowed (to + * allow for e.g. breadth-first search with in-place enqueues), but + * removing the current node is forbidden. + */ + #[cfg(not(stage0))] + fn each(&self, f: &fn(v: &T) -> bool) -> bool { + let mut link = self.peek_n(); + while link.is_some() { + let nobe = link.get(); + assert!(nobe.linked); + + { + let frozen_nobe = &*nobe; + if !f(&frozen_nobe.data) { return false; } + } + + // Check (weakly) that the user didn't do a remove. + if self.size == 0 { + fail!("The dlist became empty during iteration??") + } + if !nobe.linked || + (!((nobe.prev.is_some() + || managed::mut_ptr_eq(self.hd.expect(~"headless dlist?"), + nobe)) + && (nobe.next.is_some() + || managed::mut_ptr_eq(self.tl.expect(~"tailless dlist?"), + nobe)))) { + fail!("Removing a dlist node during iteration is forbidden!") + } + link = nobe.next_link(); + } + return true; + } #[inline(always)] fn size_hint(&self) -> Option { Some(self.len()) } diff --git a/src/libstd/ebml.rs b/src/libstd/ebml.rs index 5e4f708f52fd4..8bf81a090cf29 100644 --- a/src/libstd/ebml.rs +++ b/src/libstd/ebml.rs @@ -199,6 +199,7 @@ pub mod reader { } } + #[cfg(stage0)] pub fn docs(d: Doc, it: &fn(uint, Doc) -> bool) { let mut pos = d.start; while pos < d.end { @@ -211,7 +212,22 @@ pub mod reader { } } } + #[cfg(not(stage0))] + pub fn docs(d: Doc, it: &fn(uint, Doc) -> bool) -> bool { + let mut pos = d.start; + while pos < d.end { + let elt_tag = vuint_at(*d.data, pos); + let elt_size = vuint_at(*d.data, elt_tag.next); + pos = elt_size.next + elt_size.val; + let doc = Doc { data: d.data, start: elt_size.next, end: pos }; + if !it(elt_tag.val, doc) { + return false; + } + } + return true; + } + #[cfg(stage0)] pub fn tagged_docs(d: Doc, tg: uint, it: &fn(Doc) -> bool) { let mut pos = d.start; while pos < d.end { @@ -227,6 +243,23 @@ pub mod reader { } } } + #[cfg(not(stage0))] + pub fn tagged_docs(d: Doc, tg: uint, it: &fn(Doc) -> bool) -> bool { + let mut pos = d.start; + while pos < d.end { + let elt_tag = vuint_at(*d.data, pos); + let elt_size = vuint_at(*d.data, elt_tag.next); + pos = elt_size.next + elt_size.val; + if elt_tag.val == tg { + let doc = Doc { data: d.data, start: elt_size.next, + end: pos }; + if !it(doc) { + return false; + } + } + } + return true; + } pub fn doc_data(d: Doc) -> ~[u8] { vec::slice::(*d.data, d.start, d.end).to_vec() diff --git a/src/libstd/fileinput.rs b/src/libstd/fileinput.rs index 90774d19595ab..2c5cbc1cbf927 100644 --- a/src/libstd/fileinput.rs +++ b/src/libstd/fileinput.rs @@ -256,10 +256,21 @@ impl FileInput { (line numbers and file names, see documentation for `FileInputState`). Otherwise identical to `lines_each`. */ + #[cfg(stage0)] pub fn each_line_state(&self, f: &fn(&str, FileInputState) -> bool) { self.each_line(|line| f(line, copy self.fi.state)); } + /** + Apply `f` to each line successively, along with some state + (line numbers and file names, see documentation for + `FileInputState`). Otherwise identical to `lines_each`. + */ + #[cfg(not(stage0))] + pub fn each_line_state(&self, + f: &fn(&str, FileInputState) -> bool) -> bool { + self.each_line(|line| f(line, copy self.fi.state)) + } /** @@ -367,10 +378,22 @@ reading from `stdin`). Fails when attempting to read from a file that can't be opened. */ +#[cfg(stage0)] pub fn input(f: &fn(&str) -> bool) { let mut i = FileInput::from_args(); i.each_line(f); } +/** +Iterate directly over the command line arguments (no arguments implies +reading from `stdin`). + +Fails when attempting to read from a file that can't be opened. +*/ +#[cfg(not(stage0))] +pub fn input(f: &fn(&str) -> bool) -> bool { + let mut i = FileInput::from_args(); + i.each_line(f) +} /** Iterate directly over the command line arguments (no arguments @@ -379,20 +402,44 @@ provided at each call. Fails when attempting to read from a file that can't be opened. */ +#[cfg(stage0)] pub fn input_state(f: &fn(&str, FileInputState) -> bool) { let mut i = FileInput::from_args(); i.each_line_state(f); } +/** +Iterate directly over the command line arguments (no arguments +implies reading from `stdin`) with the current state of the iteration +provided at each call. + +Fails when attempting to read from a file that can't be opened. +*/ +#[cfg(not(stage0))] +pub fn input_state(f: &fn(&str, FileInputState) -> bool) -> bool { + let mut i = FileInput::from_args(); + i.each_line_state(f) +} /** Iterate over a vector of files (an empty vector implies just `stdin`). Fails when attempting to read from a file that can't be opened. */ +#[cfg(stage0)] pub fn input_vec(files: ~[Option], f: &fn(&str) -> bool) { let mut i = FileInput::from_vec(files); i.each_line(f); } +/** +Iterate over a vector of files (an empty vector implies just `stdin`). + +Fails when attempting to read from a file that can't be opened. +*/ +#[cfg(not(stage0))] +pub fn input_vec(files: ~[Option], f: &fn(&str) -> bool) -> bool { + let mut i = FileInput::from_vec(files); + i.each_line(f) +} /** Iterate over a vector of files (an empty vector implies just `stdin`) @@ -400,11 +447,24 @@ with the current state of the iteration provided at each call. Fails when attempting to read from a file that can't be opened. */ +#[cfg(stage0)] pub fn input_vec_state(files: ~[Option], f: &fn(&str, FileInputState) -> bool) { let mut i = FileInput::from_vec(files); i.each_line_state(f); } +/** +Iterate over a vector of files (an empty vector implies just `stdin`) +with the current state of the iteration provided at each call. + +Fails when attempting to read from a file that can't be opened. +*/ +#[cfg(not(stage0))] +pub fn input_vec_state(files: ~[Option], + f: &fn(&str, FileInputState) -> bool) -> bool { + let mut i = FileInput::from_vec(files); + i.each_line_state(f) +} #[cfg(test)] mod test { diff --git a/src/libstd/list.rs b/src/libstd/list.rs index 8d15508b26e05..13ef377fabeb2 100644 --- a/src/libstd/list.rs +++ b/src/libstd/list.rs @@ -140,6 +140,7 @@ pub fn iter(l: @List, f: &fn(&T)) { } /// Iterate over a list +#[cfg(stage0)] pub fn each(l: @List, f: &fn(&T) -> bool) { let mut cur = l; loop { @@ -152,9 +153,24 @@ pub fn each(l: @List, f: &fn(&T) -> bool) { } } } +/// Iterate over a list +#[cfg(not(stage0))] +pub fn each(l: @List, f: &fn(&T) -> bool) -> bool { + let mut cur = l; + loop { + cur = match *cur { + Cons(ref hd, tl) => { + if !f(hd) { return false; } + tl + } + Nil => { return true; } + } + } +} impl MutList { /// Iterate over a mutable list + #[cfg(stage0)] pub fn each(@mut self, f: &fn(&mut T) -> bool) { let mut cur = self; loop { @@ -170,6 +186,24 @@ impl MutList { } } } + /// Iterate over a mutable list + #[cfg(not(stage0))] + pub fn each(@mut self, f: &fn(&mut T) -> bool) -> bool { + let mut cur = self; + loop { + let borrowed = &mut *cur; + cur = match *borrowed { + MutCons(ref mut hd, tl) => { + if !f(hd) { + return false; + } + tl + } + MutNil => break + } + } + return true; + } } #[cfg(test)] diff --git a/src/libstd/net_url.rs b/src/libstd/net_url.rs index ba3fd69e344c2..e7cf710cf6797 100644 --- a/src/libstd/net_url.rs +++ b/src/libstd/net_url.rs @@ -703,11 +703,18 @@ impl ToStr for Url { } } +#[cfg(stage0)] impl IterBytes for Url { fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) { self.to_str().iter_bytes(lsb0, f) } } +#[cfg(not(stage0))] +impl IterBytes for Url { + fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) -> bool { + self.to_str().iter_bytes(lsb0, f) + } +} // Put a few tests outside of the 'test' module so they can test the internal // functions and those functions don't need 'pub' diff --git a/src/libstd/priority_queue.rs b/src/libstd/priority_queue.rs index b2f8c9c3c4e9a..bdb93142472fb 100644 --- a/src/libstd/priority_queue.rs +++ b/src/libstd/priority_queue.rs @@ -28,7 +28,14 @@ impl BaseIter for PriorityQueue { /// Visit all values in the underlying vector. /// /// The values are **not** visited in order. + #[cfg(stage0)] fn each(&self, f: &fn(&T) -> bool) { self.data.each(f) } + /// Visit all values in the underlying vector. + /// + /// The values are **not** visited in order. + #[cfg(not(stage0))] + fn each(&self, f: &fn(&T) -> bool) -> bool { self.data.each(f) } + fn size_hint(&self) -> Option { self.data.size_hint() } } diff --git a/src/libstd/smallintmap.rs b/src/libstd/smallintmap.rs index fc83a39cacf9a..afc1d0fe65fcb 100644 --- a/src/libstd/smallintmap.rs +++ b/src/libstd/smallintmap.rs @@ -51,6 +51,7 @@ impl Map for SmallIntMap { } /// Visit all key-value pairs in order + #[cfg(stage0)] fn each<'a>(&'a self, it: &fn(&uint, &'a V) -> bool) { for uint::range(0, self.v.len()) |i| { match self.v[i] { @@ -60,25 +61,62 @@ impl Map for SmallIntMap { } } + /// Visit all key-value pairs in order + #[cfg(not(stage0))] + fn each<'a>(&'a self, it: &fn(&uint, &'a V) -> bool) -> bool { + for uint::range(0, self.v.len()) |i| { + match self.v[i] { + Some(ref elt) => if !it(&i, elt) { return false; }, + None => () + } + } + return true; + } + /// Visit all keys in order + #[cfg(stage0)] fn each_key(&self, blk: &fn(key: &uint) -> bool) { self.each(|k, _| blk(k)) } + #[cfg(not(stage0))] + /// Visit all keys in order + fn each_key(&self, blk: &fn(key: &uint) -> bool) -> bool { + self.each(|k, _| blk(k)) + } /// Visit all values in order + #[cfg(stage0)] fn each_value<'a>(&'a self, blk: &fn(value: &'a V) -> bool) { self.each(|_, v| blk(v)) } + /// Visit all values in order + #[cfg(not(stage0))] + fn each_value<'a>(&'a self, blk: &fn(value: &'a V) -> bool) -> bool { + self.each(|_, v| blk(v)) + } + /// Iterate over the map and mutate the contained values + #[cfg(stage0)] fn mutate_values(&mut self, it: &fn(&uint, &mut V) -> bool) { for uint::range(0, self.v.len()) |i| { match self.v[i] { - Some(ref mut elt) => if !it(&i, elt) { break }, + Some(ref mut elt) => if !it(&i, elt) { return; }, None => () } } } + /// Iterate over the map and mutate the contained values + #[cfg(not(stage0))] + fn mutate_values(&mut self, it: &fn(&uint, &mut V) -> bool) -> bool { + for uint::range(0, self.v.len()) |i| { + match self.v[i] { + Some(ref mut elt) => if !it(&i, elt) { return false; }, + None => () + } + } + return true; + } /// Return a reference to the value corresponding to the key fn find<'a>(&'a self, key: &uint) -> Option<&'a V> { @@ -149,6 +187,7 @@ pub impl SmallIntMap { fn new() -> SmallIntMap { SmallIntMap{v: ~[]} } /// Visit all key-value pairs in reverse order + #[cfg(stage0)] fn each_reverse<'a>(&'a self, it: &fn(uint, &'a V) -> bool) { for uint::range_rev(self.v.len(), 0) |i| { match self.v[i - 1] { @@ -158,6 +197,18 @@ pub impl SmallIntMap { } } + /// Visit all key-value pairs in reverse order + #[cfg(not(stage0))] + fn each_reverse<'a>(&'a self, it: &fn(uint, &'a V) -> bool) -> bool { + for uint::range_rev(self.v.len(), 0) |i| { + match self.v[i - 1] { + Some(ref elt) => if !it(i - 1, elt) { return false; }, + None => () + } + } + return true; + } + fn get<'a>(&'a self, key: &uint) -> &'a V { self.find(key).expect("key not present") } diff --git a/src/libstd/treemap.rs b/src/libstd/treemap.rs index 06ac1a71bacd0..252bb1a6af8e9 100644 --- a/src/libstd/treemap.rs +++ b/src/libstd/treemap.rs @@ -105,24 +105,48 @@ impl Map for TreeMap { } /// Visit all key-value pairs in order + #[cfg(stage0)] fn each<'a>(&'a self, f: &fn(&'a K, &'a V) -> bool) { + each(&self.root, f); + } + /// Visit all key-value pairs in order + #[cfg(not(stage0))] + fn each<'a>(&'a self, f: &fn(&'a K, &'a V) -> bool) -> bool { each(&self.root, f) } /// Visit all keys in order + #[cfg(stage0)] fn each_key(&self, f: &fn(&K) -> bool) { self.each(|k, _| f(k)) } + /// Visit all keys in order + #[cfg(not(stage0))] + fn each_key(&self, f: &fn(&K) -> bool) -> bool { + self.each(|k, _| f(k)) + } /// Visit all values in order + #[cfg(stage0)] fn each_value<'a>(&'a self, f: &fn(&'a V) -> bool) { self.each(|_, v| f(v)) } + /// Visit all values in order + #[cfg(not(stage0))] + fn each_value<'a>(&'a self, f: &fn(&'a V) -> bool) -> bool { + self.each(|_, v| f(v)) + } /// Iterate over the map and mutate the contained values + #[cfg(stage0)] fn mutate_values(&mut self, f: &fn(&K, &mut V) -> bool) { mutate_values(&mut self.root, f); } + /// Iterate over the map and mutate the contained values + #[cfg(not(stage0))] + fn mutate_values(&mut self, f: &fn(&K, &mut V) -> bool) -> bool { + mutate_values(&mut self.root, f) + } /// Return a reference to the value corresponding to the key fn find<'a>(&'a self, key: &K) -> Option<&'a V> { @@ -177,6 +201,7 @@ impl Map for TreeMap { } } +#[cfg(stage0)] pub impl TreeMap { /// Create an empty TreeMap fn new() -> TreeMap { TreeMap{root: None, length: 0} } @@ -202,6 +227,32 @@ pub impl TreeMap { TreeMapIterator{stack: ~[], node: &self.root} } } +#[cfg(not(stage0))] +pub impl TreeMap { + /// Create an empty TreeMap + fn new() -> TreeMap { TreeMap{root: None, length: 0} } + + /// Visit all key-value pairs in reverse order + fn each_reverse<'a>(&'a self, f: &fn(&'a K, &'a V) -> bool) -> bool { + each_reverse(&self.root, f) + } + + /// Visit all keys in reverse order + fn each_key_reverse(&self, f: &fn(&K) -> bool) -> bool { + self.each_reverse(|k, _| f(k)) + } + + /// Visit all values in reverse order + fn each_value_reverse(&self, f: &fn(&V) -> bool) -> bool { + self.each_reverse(|_, v| f(v)) + } + + /// Get a lazy iterator over the key-value pairs in the map. + /// Requires that it be frozen (immutable). + fn iter<'a>(&'a self) -> TreeMapIterator<'a, K, V> { + TreeMapIterator{stack: ~[], node: &self.root} + } +} /// Lazy forward iterator over a map pub struct TreeMapIterator<'self, K, V> { @@ -246,17 +297,29 @@ pub struct TreeSet { impl BaseIter for TreeSet { /// Visit all values in order #[inline(always)] + #[cfg(stage0)] fn each(&self, f: &fn(&T) -> bool) { self.map.each_key(f) } + /// Visit all values in order + #[inline(always)] + #[cfg(not(stage0))] + fn each(&self, f: &fn(&T) -> bool) -> bool { self.map.each_key(f) } #[inline(always)] fn size_hint(&self) -> Option { Some(self.len()) } } impl ReverseIter for TreeSet { /// Visit all values in reverse order + #[cfg(stage0)] #[inline(always)] fn each_reverse(&self, f: &fn(&T) -> bool) { self.map.each_key_reverse(f) } + /// Visit all values in reverse order + #[cfg(not(stage0))] + #[inline(always)] + fn each_reverse(&self, f: &fn(&T) -> bool) -> bool { + self.map.each_key_reverse(f) + } } impl Eq for TreeSet { @@ -361,6 +424,7 @@ impl Set for TreeSet { } /// Visit the values (in-order) representing the difference + #[cfg(stage0)] fn difference(&self, other: &TreeSet, f: &fn(&T) -> bool) { let mut x = self.iter(); let mut y = other.iter(); @@ -389,8 +453,38 @@ impl Set for TreeSet { } } } + /// Visit the values (in-order) representing the difference + #[cfg(not(stage0))] + fn difference(&self, other: &TreeSet, f: &fn(&T) -> bool) -> bool { + let mut x = self.iter(); + let mut y = other.iter(); + + let mut a = x.next(); + let mut b = y.next(); + + while a.is_some() { + if b.is_none() { + return f(a.unwrap()) && x.advance(f); + } + + let a1 = a.unwrap(); + let b1 = b.unwrap(); + + let cmp = a1.cmp(b1); + + if cmp == Less { + if !f(a1) { return false; } + a = x.next(); + } else { + if cmp == Equal { a = x.next() } + b = y.next(); + } + } + return true; + } /// Visit the values (in-order) representing the symmetric difference + #[cfg(stage0)] fn symmetric_difference(&self, other: &TreeSet, f: &fn(&T) -> bool) { let mut x = self.iter(); @@ -427,8 +521,43 @@ impl Set for TreeSet { if f(b1) { y.next() } else { None } } } + /// Visit the values (in-order) representing the symmetric difference + #[cfg(not(stage0))] + fn symmetric_difference(&self, other: &TreeSet, + f: &fn(&T) -> bool) -> bool { + let mut x = self.iter(); + let mut y = other.iter(); + + let mut a = x.next(); + let mut b = y.next(); + + while a.is_some() { + if b.is_none() { + return f(a.unwrap()) && x.advance(f); + } + + let a1 = a.unwrap(); + let b1 = b.unwrap(); + + let cmp = a1.cmp(b1); + + if cmp == Less { + if !f(a1) { return false; } + a = x.next(); + } else { + if cmp == Greater { + if !f(b1) { return false; } + } else { + a = x.next(); + } + b = y.next(); + } + } + return b.each(|&x| f(x)) && y.advance(f); + } /// Visit the values (in-order) representing the intersection + #[cfg(stage0)] fn intersection(&self, other: &TreeSet, f: &fn(&T) -> bool) { let mut x = self.iter(); let mut y = other.iter(); @@ -452,8 +581,35 @@ impl Set for TreeSet { } } } + /// Visit the values (in-order) representing the intersection + #[cfg(not(stage0))] + fn intersection(&self, other: &TreeSet, f: &fn(&T) -> bool) -> bool { + let mut x = self.iter(); + let mut y = other.iter(); + + let mut a = x.next(); + let mut b = y.next(); + + while a.is_some() && b.is_some() { + let a1 = a.unwrap(); + let b1 = b.unwrap(); + + let cmp = a1.cmp(b1); + + if cmp == Less { + a = x.next(); + } else { + if cmp == Equal { + if !f(a1) { return false } + } + b = y.next(); + } + } + return true; + } /// Visit the values (in-order) representing the union + #[cfg(stage0)] fn union(&self, other: &TreeSet, f: &fn(&T) -> bool) { let mut x = self.iter(); let mut y = other.iter(); @@ -488,6 +644,38 @@ impl Set for TreeSet { if f(b1) { y.next() } else { None } } } + /// Visit the values (in-order) representing the union + #[cfg(not(stage0))] + fn union(&self, other: &TreeSet, f: &fn(&T) -> bool) -> bool { + let mut x = self.iter(); + let mut y = other.iter(); + + let mut a = x.next(); + let mut b = y.next(); + + while a.is_some() { + if b.is_none() { + return f(a.unwrap()) && x.advance(f); + } + + let a1 = a.unwrap(); + let b1 = b.unwrap(); + + let cmp = a1.cmp(b1); + + if cmp == Greater { + if !f(b1) { return false; } + b = y.next(); + } else { + if !f(a1) { return false; } + if cmp == Equal { + b = y.next(); + } + a = x.next(); + } + } + return b.each(|&x| f(x)) && y.advance(f); + } } pub impl TreeSet { @@ -525,20 +713,28 @@ pub impl TreeNode { } } +#[cfg(stage0)] +fn each<'r, K: TotalOrd, V>(_: &'r Option<~TreeNode>, + _: &fn(&'r K, &'r V) -> bool) -> bool { + fail!(~"don't use me in stage0!") +} +#[cfg(not(stage0))] fn each<'r, K: TotalOrd, V>(node: &'r Option<~TreeNode>, - f: &fn(&'r K, &'r V) -> bool) { - for node.each |x| { - each(&x.left, f); - if f(&x.key, &x.value) { each(&x.right, f) } - } + f: &fn(&'r K, &'r V) -> bool) -> bool { + node.each(|x| each(&x.left, f) && f(&x.key, &x.value) && + each(&x.right, f)) } +#[cfg(stage0)] +fn each_reverse<'r, K: TotalOrd, V>(_: &'r Option<~TreeNode>, + _: &fn(&'r K, &'r V) -> bool) -> bool { + fail!(~"don't use me in stage0!") +} +#[cfg(not(stage0))] fn each_reverse<'r, K: TotalOrd, V>(node: &'r Option<~TreeNode>, - f: &fn(&'r K, &'r V) -> bool) { - for node.each |x| { - each_reverse(&x.right, f); - if f(&x.key, &x.value) { each_reverse(&x.left, f) } - } + f: &fn(&'r K, &'r V) -> bool) -> bool { + node.each(|x| each_reverse(&x.right, f) && f(&x.key, &x.value) && + each_reverse(&x.left, f)) } fn mutate_values<'r, K: TotalOrd, V>(node: &'r mut Option<~TreeNode>, @@ -1130,7 +1326,7 @@ mod test_set { } fn check(a: &[int], b: &[int], expected: &[int], - f: &fn(&TreeSet, &TreeSet, f: &fn(&int) -> bool)) { + f: &fn(&TreeSet, &TreeSet, f: &fn(&int) -> bool) -> bool) { let mut set_a = TreeSet::new(); let mut set_b = TreeSet::new(); diff --git a/src/libstd/workcache.rs b/src/libstd/workcache.rs index dc9204f62f4fb..9b0a6cb6226c1 100644 --- a/src/libstd/workcache.rs +++ b/src/libstd/workcache.rs @@ -99,6 +99,7 @@ struct WorkKey { name: ~str } +#[cfg(stage0)] impl to_bytes::IterBytes for WorkKey { #[inline(always)] fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) { @@ -108,6 +109,13 @@ impl to_bytes::IterBytes for WorkKey { self.name.iter_bytes(lsb0, f); } } +#[cfg(not(stage0))] +impl to_bytes::IterBytes for WorkKey { + #[inline(always)] + fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) -> bool { + self.kind.iter_bytes(lsb0, f) && self.name.iter_bytes(lsb0, f) + } +} impl cmp::Ord for WorkKey { fn lt(&self, other: &WorkKey) -> bool { diff --git a/src/libsyntax/abi.rs b/src/libsyntax/abi.rs index 75782e9ca673f..f266b8871a225 100644 --- a/src/libsyntax/abi.rs +++ b/src/libsyntax/abi.rs @@ -81,6 +81,7 @@ static AbiDatas: &'static [AbiData] = &[ AbiData {abi: RustIntrinsic, name: "rust-intrinsic", abi_arch: RustArch}, ]; +#[cfg(stage0)] fn each_abi(op: &fn(abi: Abi) -> bool) { /*! * @@ -93,6 +94,15 @@ fn each_abi(op: &fn(abi: Abi) -> bool) { } } } +#[cfg(not(stage0))] +fn each_abi(op: &fn(abi: Abi) -> bool) -> bool { + /*! + * + * Iterates through each of the defined ABIs. + */ + + AbiDatas.each(|abi_data| op(abi_data.abi)) +} pub fn lookup(name: &str) -> Option { /*! @@ -189,6 +199,7 @@ pub impl AbiSet { self.bits |= (1 << abi.index()); } + #[cfg(stage0)] fn each(&self, op: &fn(abi: Abi) -> bool) { for each_abi |abi| { if self.contains(abi) { @@ -198,6 +209,10 @@ pub impl AbiSet { } } } + #[cfg(not(stage0))] + fn each(&self, op: &fn(abi: Abi) -> bool) -> bool { + each_abi(|abi| !self.contains(abi) || op(abi)) + } fn is_empty(&self) -> bool { self.bits == 0 @@ -252,17 +267,31 @@ pub impl AbiSet { } } +#[cfg(stage0)] impl to_bytes::IterBytes for Abi { fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) { self.index().iter_bytes(lsb0, f) } } +#[cfg(not(stage0))] +impl to_bytes::IterBytes for Abi { + fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) -> bool { + self.index().iter_bytes(lsb0, f) + } +} +#[cfg(stage0)] impl to_bytes::IterBytes for AbiSet { fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) { self.bits.iter_bytes(lsb0, f) } } +#[cfg(not(stage0))] +impl to_bytes::IterBytes for AbiSet { + fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) -> bool { + self.bits.iter_bytes(lsb0, f) + } +} impl ToStr for Abi { fn to_str(&self) -> ~str { diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index c8fc04eaea1a3..c516ebc402f0c 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -97,11 +97,18 @@ impl Decodable for ident { } } +#[cfg(stage0)] impl to_bytes::IterBytes for ident { fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) { self.repr.iter_bytes(lsb0, f) } } +#[cfg(not(stage0))] +impl to_bytes::IterBytes for ident { + fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) -> bool { + self.repr.iter_bytes(lsb0, f) + } +} // Functions may or may not have names. pub type fn_ident = Option; @@ -284,6 +291,7 @@ pub enum binding_mode { bind_infer } +#[cfg(stage0)] impl to_bytes::IterBytes for binding_mode { fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) { match *self { @@ -297,6 +305,18 @@ impl to_bytes::IterBytes for binding_mode { } } } +#[cfg(not(stage0))] +impl to_bytes::IterBytes for binding_mode { + fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) -> bool { + match *self { + bind_by_copy => 0u8.iter_bytes(lsb0, f), + + bind_by_ref(ref m) => to_bytes::iter_bytes_2(&1u8, m, lsb0, f), + + bind_infer => 2u8.iter_bytes(lsb0, f), + } + } +} #[auto_encode] #[auto_decode] @@ -330,11 +350,18 @@ pub enum pat_ { #[deriving(Eq)] pub enum mutability { m_mutbl, m_imm, m_const, } +#[cfg(stage0)] impl to_bytes::IterBytes for mutability { fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) { (*self as u8).iter_bytes(lsb0, f) } } +#[cfg(not(stage0))] +impl to_bytes::IterBytes for mutability { + fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) -> bool { + (*self as u8).iter_bytes(lsb0, f) + } +} #[auto_encode] #[auto_decode] @@ -345,11 +372,18 @@ pub enum Sigil { ManagedSigil } +#[cfg(stage0)] impl to_bytes::IterBytes for Sigil { fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) { (*self as uint).iter_bytes(lsb0, f) } } +#[cfg(not(stage0))] +impl to_bytes::IterBytes for Sigil { + fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) -> bool { + (*self as uint).iter_bytes(lsb0, f) + } +} impl ToStr for Sigil { fn to_str(&self) -> ~str { @@ -744,11 +778,18 @@ impl ToStr for int_ty { } } +#[cfg(stage0)] impl to_bytes::IterBytes for int_ty { fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) { (*self as u8).iter_bytes(lsb0, f) } } +#[cfg(not(stage0))] +impl to_bytes::IterBytes for int_ty { + fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) -> bool { + (*self as u8).iter_bytes(lsb0, f) + } +} #[auto_encode] #[auto_decode] @@ -761,11 +802,18 @@ impl ToStr for uint_ty { } } +#[cfg(stage0)] impl to_bytes::IterBytes for uint_ty { fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) { (*self as u8).iter_bytes(lsb0, f) } } +#[cfg(not(stage0))] +impl to_bytes::IterBytes for uint_ty { + fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) -> bool { + (*self as u8).iter_bytes(lsb0, f) + } +} #[auto_encode] #[auto_decode] @@ -778,11 +826,18 @@ impl ToStr for float_ty { } } +#[cfg(stage0)] impl to_bytes::IterBytes for float_ty { fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) { (*self as u8).iter_bytes(lsb0, f) } } +#[cfg(not(stage0))] +impl to_bytes::IterBytes for float_ty { + fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) -> bool { + (*self as u8).iter_bytes(lsb0, f) + } +} // NB Eq method appears below. #[auto_encode] @@ -823,11 +878,18 @@ impl ToStr for Onceness { } } +#[cfg(stage0)] impl to_bytes::IterBytes for Onceness { fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) { (*self as uint).iter_bytes(lsb0, f); } } +#[cfg(not(stage0))] +impl to_bytes::IterBytes for Onceness { + fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) -> bool { + (*self as uint).iter_bytes(lsb0, f) + } +} #[auto_encode] #[auto_decode] @@ -874,11 +936,18 @@ pub enum ty_ { ty_infer, } +#[cfg(stage0)] impl to_bytes::IterBytes for Ty { fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) { to_bytes::iter_bytes_2(&self.span.lo, &self.span.hi, lsb0, f); } } +#[cfg(not(stage0))] +impl to_bytes::IterBytes for Ty { + fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) -> bool { + to_bytes::iter_bytes_2(&self.span.lo, &self.span.hi, lsb0, f) + } +} #[auto_encode] #[auto_decode] @@ -941,11 +1010,18 @@ impl ToStr for purity { } } +#[cfg(stage0)] impl to_bytes::IterBytes for purity { fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) { (*self as u8).iter_bytes(lsb0, f) } } +#[cfg(not(stage0))] +impl to_bytes::IterBytes for purity { + fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) -> bool { + (*self as u8).iter_bytes(lsb0, f) + } +} #[auto_encode] #[auto_decode] @@ -956,11 +1032,18 @@ pub enum ret_style { return_val, // everything else } +#[cfg(stage0)] impl to_bytes::IterBytes for ret_style { fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) { (*self as u8).iter_bytes(lsb0, f) } } +#[cfg(not(stage0))] +impl to_bytes::IterBytes for ret_style { + fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) -> bool { + (*self as u8).iter_bytes(lsb0, f) + } +} #[auto_encode] #[auto_decode] diff --git a/src/libsyntax/ast_util.rs b/src/libsyntax/ast_util.rs index 77277dea81453..ceff868d11f21 100644 --- a/src/libsyntax/ast_util.rs +++ b/src/libsyntax/ast_util.rs @@ -191,12 +191,21 @@ pub fn is_call_expr(e: @expr) -> bool { } // This makes def_id hashable +#[cfg(stage0)] impl to_bytes::IterBytes for def_id { #[inline(always)] fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) { to_bytes::iter_bytes_2(&self.crate, &self.node, lsb0, f); } } +// This makes def_id hashable +#[cfg(not(stage0))] +impl to_bytes::IterBytes for def_id { + #[inline(always)] + fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) -> bool { + to_bytes::iter_bytes_2(&self.crate, &self.node, lsb0, f) + } +} pub fn block_from_expr(e: @expr) -> blk { let blk_ = default_block(~[], option::Some::<@expr>(e), e.id); diff --git a/src/libsyntax/codemap.rs b/src/libsyntax/codemap.rs index 846097550d14f..053ed76d66b2a 100644 --- a/src/libsyntax/codemap.rs +++ b/src/libsyntax/codemap.rs @@ -65,11 +65,18 @@ impl Sub for BytePos { } } +#[cfg(stage0)] impl to_bytes::IterBytes for BytePos { fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) { (**self).iter_bytes(lsb0, f) } } +#[cfg(not(stage0))] +impl to_bytes::IterBytes for BytePos { + fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) -> bool { + (**self).iter_bytes(lsb0, f) + } +} impl Pos for CharPos { fn from_uint(n: uint) -> CharPos { CharPos(n) } @@ -83,11 +90,18 @@ impl cmp::Ord for CharPos { fn gt(&self, other: &CharPos) -> bool { **self > **other } } +#[cfg(stage0)] impl to_bytes::IterBytes for CharPos { fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) { (**self).iter_bytes(lsb0, f) } } +#[cfg(not(stage0))] +impl to_bytes::IterBytes for CharPos { + fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) -> bool { + (**self).iter_bytes(lsb0, f) + } +} impl Add for CharPos { fn add(&self, rhs: &CharPos) -> CharPos { diff --git a/src/libsyntax/ext/deriving/iter_bytes.rs b/src/libsyntax/ext/deriving/iter_bytes.rs index 3d66506d6ca8f..9eb246ffe2228 100644 --- a/src/libsyntax/ext/deriving/iter_bytes.rs +++ b/src/libsyntax/ext/deriving/iter_bytes.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use ast::{meta_item, item, expr}; +use ast::{meta_item, item, expr, and}; use codemap::span; use ext::base::ext_ctxt; use ext::build; @@ -31,7 +31,7 @@ pub fn expand_deriving_iter_bytes(cx: @ext_ctxt, Literal(Path::new(~[~"bool"])), Literal(Path::new(~[~"core", ~"to_bytes", ~"Cb"])) ], - ret_ty: nil_ty(), + ret_ty: Literal(Path::new(~[~"bool"])), const_nonmatching: false, combine_substructure: iter_bytes_substructure } @@ -58,13 +58,11 @@ fn iter_bytes_substructure(cx: @ext_ctxt, span: span, substr: &Substructure) -> }; let iter_bytes_ident = substr.method_ident; let call_iterbytes = |thing_expr| { - build::mk_stmt( - cx, span, - build::mk_method_call(cx, span, - thing_expr, iter_bytes_ident, - copy lsb0_f)) + build::mk_method_call(cx, span, + thing_expr, iter_bytes_ident, + copy lsb0_f) }; - let mut stmts = ~[]; + let mut exprs = ~[]; let fields; match *substr.fields { Struct(ref fs) => { @@ -78,7 +76,7 @@ fn iter_bytes_substructure(cx: @ext_ctxt, span: span, substr: &Substructure) -> None => build::mk_uint(cx, span, index) }; - stmts.push(call_iterbytes(discriminant)); + exprs.push(call_iterbytes(discriminant)); fields = fs; } @@ -86,8 +84,14 @@ fn iter_bytes_substructure(cx: @ext_ctxt, span: span, substr: &Substructure) -> } for fields.each |&(_, field, _)| { - stmts.push(call_iterbytes(field)); + exprs.push(call_iterbytes(field)); } - build::mk_block(cx, span, ~[], stmts, None) + if exprs.len() == 0 { + cx.span_bug(span, "#[deriving(IterBytes)] needs at least one field"); + } + + do vec::foldl(exprs[0], exprs.slice(1, exprs.len())) |prev, me| { + build::mk_binary(cx, span, and, prev, *me) + } } diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index 68c74c2d12b55..5129fa6ebd2aa 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -195,18 +195,8 @@ pub fn expand_item(extsbox: @mut SyntaxEnv, } // does this attribute list contain "macro_escape" ? -pub fn contains_macro_escape (attrs: &[ast::attribute]) -> bool{ - let mut accum = false; - do attrs.each |attr| { - let mname = attr::get_attr_name(attr); - if (mname == @~"macro_escape") { - accum = true; - false - } else { - true - } - } - accum +pub fn contains_macro_escape (attrs: &[ast::attribute]) -> bool { + attrs.any(|attr| "macro_escape" == *attr::get_attr_name(attr)) } // this macro disables (one layer of) macro diff --git a/src/libsyntax/ext/pipes/proto.rs b/src/libsyntax/ext/pipes/proto.rs index 647c7741bd897..7c78ec066d031 100644 --- a/src/libsyntax/ext/pipes/proto.rs +++ b/src/libsyntax/ext/pipes/proto.rs @@ -100,6 +100,7 @@ pub impl state_ { /// Iterate over the states that can be reached in one message /// from this state. + #[cfg(stage0)] fn reachable(&self, f: &fn(state) -> bool) { for self.messages.each |m| { match *m { @@ -111,6 +112,21 @@ pub impl state_ { } } } + /// Iterate over the states that can be reached in one message + /// from this state. + #[cfg(not(stage0))] + fn reachable(&self, f: &fn(state) -> bool) -> bool { + for self.messages.each |m| { + match *m { + message(_, _, _, _, Some(next_state { state: ref id, _ })) => { + let state = self.proto.get_state((*id)); + if !f(state) { return false; } + } + _ => () + } + } + return true; + } } pub type protocol = @mut protocol_; diff --git a/src/libsyntax/opt_vec.rs b/src/libsyntax/opt_vec.rs index 600ab964e5238..6110579863dbf 100644 --- a/src/libsyntax/opt_vec.rs +++ b/src/libsyntax/opt_vec.rs @@ -132,12 +132,20 @@ impl Eq for OptVec { } impl BaseIter for OptVec { + #[cfg(stage0)] fn each(&self, blk: &fn(v: &A) -> bool) { match *self { Empty => {} Vec(ref v) => v.each(blk) } } + #[cfg(not(stage0))] + fn each(&self, blk: &fn(v: &A) -> bool) -> bool { + match *self { + Empty => true, + Vec(ref v) => v.each(blk) + } + } fn size_hint(&self) -> Option { Some(self.len()) @@ -146,10 +154,16 @@ impl BaseIter for OptVec { impl old_iter::ExtendedIter for OptVec { #[inline(always)] + #[cfg(stage0)] fn eachi(&self, blk: &fn(v: uint, v: &A) -> bool) { old_iter::eachi(self, blk) } #[inline(always)] + #[cfg(not(stage0))] + fn eachi(&self, blk: &fn(v: uint, v: &A) -> bool) -> bool { + old_iter::eachi(self, blk) + } + #[inline(always)] fn all(&self, blk: &fn(&A) -> bool) -> bool { old_iter::all(self, blk) } diff --git a/src/libsyntax/parse/obsolete.rs b/src/libsyntax/parse/obsolete.rs index e486a6254e76a..a4ac038cf466f 100644 --- a/src/libsyntax/parse/obsolete.rs +++ b/src/libsyntax/parse/obsolete.rs @@ -62,12 +62,20 @@ pub enum ObsoleteSyntax { ObsoleteFixedLengthVectorType, } +#[cfg(stage0)] impl to_bytes::IterBytes for ObsoleteSyntax { #[inline(always)] fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) { (*self as uint).iter_bytes(lsb0, f); } } +#[cfg(not(stage0))] +impl to_bytes::IterBytes for ObsoleteSyntax { + #[inline(always)] + fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) -> bool { + (*self as uint).iter_bytes(lsb0, f) + } +} pub impl Parser { /// Reports an obsolete syntax non-fatal error. diff --git a/src/libsyntax/parse/token.rs b/src/libsyntax/parse/token.rs index fe7bd5b3bc17d..15441b6fcfc57 100644 --- a/src/libsyntax/parse/token.rs +++ b/src/libsyntax/parse/token.rs @@ -355,11 +355,18 @@ impl<'self> Equiv<@~str> for StringRef<'self> { fn equiv(&self, other: &@~str) -> bool { str::eq_slice(**self, **other) } } +#[cfg(stage0)] impl<'self> to_bytes::IterBytes for StringRef<'self> { fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) { (**self).iter_bytes(lsb0, f); } } +#[cfg(not(stage0))] +impl<'self> to_bytes::IterBytes for StringRef<'self> { + fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) -> bool { + (**self).iter_bytes(lsb0, f) + } +} /** * Maps a token to a record specifying the corresponding binary diff --git a/src/test/bench/graph500-bfs.rs b/src/test/bench/graph500-bfs.rs index 1842a8ff42e52..fb27672354371 100644 --- a/src/test/bench/graph500-bfs.rs +++ b/src/test/bench/graph500-bfs.rs @@ -10,8 +10,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#[allow(deprecated_mode)]; - /*! An implementation of the Graph500 Breadth First Search problem in Rust. @@ -23,7 +21,7 @@ use std::arc; use std::time; use std::deque::Deque; use std::par; -use core::hashmap::{HashMap, HashSet}; +use core::hashmap::HashSet; use core::int::abs; use core::rand::RngUtil; @@ -83,14 +81,13 @@ fn make_graph(N: uint, edges: ~[(node_id, node_id)]) -> graph { HashSet::new() }; - do vec::each(edges) |e| { + for vec::each(edges) |e| { match *e { (i, j) => { graph[i].insert(j); graph[j].insert(i); } } - true } do vec::map_consume(graph) |mut v| { diff --git a/src/test/compile-fail/bad-for-loop.rs b/src/test/compile-fail/bad-for-loop.rs index 8835c577fa8fd..7ff51eff8eeb6 100644 --- a/src/test/compile-fail/bad-for-loop.rs +++ b/src/test/compile-fail/bad-for-loop.rs @@ -11,4 +11,5 @@ fn main() { fn baz(_x: &fn(y: int) -> int) {} for baz |_e| { } //~ ERROR A `for` loop iterator should expect a closure that returns `bool` + //~^ ERROR expected `for` closure to return `bool` } diff --git a/src/test/compile-fail/borrowck-lend-flow-loop.rs b/src/test/compile-fail/borrowck-lend-flow-loop.rs index b6384ad9590ab..f7a72d6e6108c 100644 --- a/src/test/compile-fail/borrowck-lend-flow-loop.rs +++ b/src/test/compile-fail/borrowck-lend-flow-loop.rs @@ -17,7 +17,7 @@ fn borrow(_v: &int) {} fn borrow_mut(_v: &mut int) {} fn cond() -> bool { fail!() } -fn for_func(_f: &fn() -> bool) { fail!() } +fn for_func(_f: &fn() -> bool) -> bool { fail!() } fn produce() -> T { fail!(); } fn inc(v: &mut ~int) { diff --git a/src/test/compile-fail/issue-2817-2.rs b/src/test/compile-fail/issue-2817-2.rs index 6084552f0ed6d..17b0d88a6a827 100644 --- a/src/test/compile-fail/issue-2817-2.rs +++ b/src/test/compile-fail/issue-2817-2.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -fn not_bool(f: &fn(int) -> ~str) {} +fn not_bool(f: &fn(int) -> ~str) -> bool {} fn main() { for uint::range(0, 100000) |_i| { //~ ERROR A for-loop body must return (), but diff --git a/src/test/compile-fail/issue-2817.rs b/src/test/compile-fail/issue-2817.rs index 8c28fcdc7fcd7..77585d15b6b3e 100644 --- a/src/test/compile-fail/issue-2817.rs +++ b/src/test/compile-fail/issue-2817.rs @@ -16,10 +16,10 @@ fn uuid_random() -> uint { fail!(); } fn main() { do uint::range(0, 100000) |_i| { //~ ERROR Do-block body must return bool, but - } + }; // should get a more general message if the callback // doesn't return nil do uint::range(0, 100000) |_i| { //~ ERROR mismatched types ~"str" - } + }; } diff --git a/src/test/compile-fail/issue-3651-2.rs b/src/test/compile-fail/issue-3651-2.rs index 2431313df631c..98a02b6b74691 100644 --- a/src/test/compile-fail/issue-3651-2.rs +++ b/src/test/compile-fail/issue-3651-2.rs @@ -9,5 +9,5 @@ // except according to those terms. fn main() { - do 5.times {} //~ ERROR Do-block body must return bool, but returns () here. Perhaps + do 5.times {}; //~ ERROR Do-block body must return bool, but returns () here. Perhaps } diff --git a/src/test/compile-fail/issue-3651.rs b/src/test/compile-fail/issue-3651.rs index 38e9348155ac3..8d704859fe574 100644 --- a/src/test/compile-fail/issue-3651.rs +++ b/src/test/compile-fail/issue-3651.rs @@ -10,4 +10,5 @@ fn main() { for task::spawn { return true; } //~ ERROR A `for` loop iterator should expect a closure that + //~^ ERROR expected `for` closure to return `bool` } diff --git a/src/test/compile-fail/private-method.rs b/src/test/compile-fail/private-method.rs index c918758ad7c68..0d84bc2fc605c 100644 --- a/src/test/compile-fail/private-method.rs +++ b/src/test/compile-fail/private-method.rs @@ -18,7 +18,7 @@ mod kitties { } pub impl cat { - priv fn nap(&self) { uint::range(1u, 10000u, |_i| false)} + priv fn nap(&self) { uint::range(1u, 10000u, |_i| false); } } pub fn cat(in_x : uint, in_y : int) -> cat { diff --git a/src/test/run-pass/assignability-trait.rs b/src/test/run-pass/assignability-trait.rs index c557aa7e22383..6946ed3fbcfc0 100644 --- a/src/test/run-pass/assignability-trait.rs +++ b/src/test/run-pass/assignability-trait.rs @@ -13,22 +13,18 @@ // it. trait iterable { - fn iterate(&self, blk: &fn(x: &A) -> bool); + fn iterate(&self, blk: &fn(x: &A) -> bool) -> bool; } impl<'self,A> iterable for &'self [A] { - fn iterate(&self, f: &fn(x: &A) -> bool) { - for vec::each(*self) |e| { - if !f(e) { break; } - } + fn iterate(&self, f: &fn(x: &A) -> bool) -> bool { + vec::each(*self, f) } } impl iterable for ~[A] { - fn iterate(&self, f: &fn(x: &A) -> bool) { - for vec::each(*self) |e| { - if !f(e) { break; } - } + fn iterate(&self, f: &fn(x: &A) -> bool) -> bool { + vec::each(*self, f) } } diff --git a/src/test/run-pass/borrowck-mut-uniq.rs b/src/test/run-pass/borrowck-mut-uniq.rs index 5f5b9c59d7680..778637701c5fd 100644 --- a/src/test/run-pass/borrowck-mut-uniq.rs +++ b/src/test/run-pass/borrowck-mut-uniq.rs @@ -18,7 +18,7 @@ fn add_int(x: &mut Ints, v: int) { x.values <-> values; } -fn iter_ints(x: &Ints, f: &fn(x: &int) -> bool) { +fn iter_ints(x: &Ints, f: &fn(x: &int) -> bool) -> bool { let l = x.values.len(); uint::range(0, l, |i| f(&x.values[i])) } diff --git a/src/test/run-pass/class-impl-very-parameterized-trait.rs b/src/test/run-pass/class-impl-very-parameterized-trait.rs index b89bf06409274..39d4b25f262be 100644 --- a/src/test/run-pass/class-impl-very-parameterized-trait.rs +++ b/src/test/run-pass/class-impl-very-parameterized-trait.rs @@ -59,25 +59,26 @@ impl Mutable for cat { } impl Map for cat { - fn each<'a>(&'a self, f: &fn(&int, &'a T) -> bool) { + fn each<'a>(&'a self, f: &fn(&int, &'a T) -> bool) -> bool { let mut n = int::abs(self.meows); while n > 0 { - if !f(&n, &self.name) { break; } + if !f(&n, &self.name) { return false; } n -= 1; } + return true; } fn contains_key(&self, k: &int) -> bool { *k <= self.meows } - fn each_key(&self, f: &fn(v: &int) -> bool) { - for self.each |k, _| { if !f(k) { break; } loop;}; + fn each_key(&self, f: &fn(v: &int) -> bool) -> bool { + self.each(|k, _| f(k)) } - fn each_value<'a>(&'a self, f: &fn(v: &'a T) -> bool) { - for self.each |_, v| { if !f(v) { break; } loop;}; + fn each_value<'a>(&'a self, f: &fn(v: &'a T) -> bool) -> bool { + self.each(|_, v| f(v)) } - fn mutate_values(&mut self, _f: &fn(&int, &mut T) -> bool) { + fn mutate_values(&mut self, _f: &fn(&int, &mut T) -> bool) -> bool { fail!(~"nope") } diff --git a/src/test/run-pass/do-for-empty-args.rs b/src/test/run-pass/do-for-empty-args.rs index c86c1768111f7..fb1bc37fd5efa 100644 --- a/src/test/run-pass/do-for-empty-args.rs +++ b/src/test/run-pass/do-for-empty-args.rs @@ -11,14 +11,15 @@ // no-reformat // Testing various forms of `do` and `for` with empty arg lists -fn f(f: &fn() -> bool) { +fn f(f: &fn() -> bool) -> bool { + true } pub fn main() { - do f() || { true } - do f() { true } - do f || { true } - do f { true } + do f() || { true }; + do f() { true }; + do f || { true }; + do f { true }; for f() || { } for f() { } for f || { } diff --git a/src/test/run-pass/do-for-no-args.rs b/src/test/run-pass/do-for-no-args.rs index c89d693c81635..e9d7c946a9a11 100644 --- a/src/test/run-pass/do-for-no-args.rs +++ b/src/test/run-pass/do-for-no-args.rs @@ -10,7 +10,7 @@ // Testing that we can drop the || in for/do exprs -fn f(f: @fn() -> bool) { } +fn f(f: @fn() -> bool) -> bool { true } fn d(f: @fn()) { } diff --git a/src/test/run-pass/ret-break-cont-in-block.rs b/src/test/run-pass/ret-break-cont-in-block.rs index ab61cee422300..1792a89d64f1e 100644 --- a/src/test/run-pass/ret-break-cont-in-block.rs +++ b/src/test/run-pass/ret-break-cont-in-block.rs @@ -12,12 +12,13 @@ use core::cmp::Eq; -fn iter(v: ~[T], it: &fn(&T) -> bool) { +fn iter(v: ~[T], it: &fn(&T) -> bool) -> bool { let mut i = 0u, l = v.len(); while i < l { - if !it(&v[i]) { break; } + if !it(&v[i]) { return false; } i += 1u; } + return true; } fn find_pos(n: T, h: ~[T]) -> Option {