about summary refs log tree commit diff
diff options
context:
space:
mode:
authorNiko Matsakis <niko@alum.mit.edu>2013-04-10 13:11:35 -0700
committerNiko Matsakis <niko@alum.mit.edu>2013-04-10 17:32:03 -0700
commit61b9e0ebfa7c96886c45a461c6d8edb22f8153da (patch)
treef392a8f4119df4569328a228c994be2c4392d10a
parent49de82cdca2064a909d3104f4e5eccacb0425fd0 (diff)
downloadrust-61b9e0ebfa7c96886c45a461c6d8edb22f8153da.tar.gz
rust-61b9e0ebfa7c96886c45a461c6d8edb22f8153da.zip
core: changes in response to #5656
-rw-r--r--src/libcore/condition.rs2
-rw-r--r--src/libcore/container.rs36
-rw-r--r--src/libcore/hashmap.rs173
-rw-r--r--src/libcore/option.rs104
-rw-r--r--src/libcore/result.rs7
-rw-r--r--src/libcore/rt/rtio.rs5
-rw-r--r--src/libcore/rt/sched.rs40
-rw-r--r--src/libcore/rt/uvio.rs16
-rw-r--r--src/libcore/task/mod.rs2
-rw-r--r--src/libcore/trie.rs97
-rw-r--r--src/libcore/tuple.rs28
-rw-r--r--src/libcore/vec.rs195
12 files changed, 700 insertions, 5 deletions
diff --git a/src/libcore/condition.rs b/src/libcore/condition.rs
index ed94f2ef2c4..dc6c80228dd 100644
--- a/src/libcore/condition.rs
+++ b/src/libcore/condition.rs
@@ -28,7 +28,7 @@ pub struct Condition<'self, T, U> {
 }
 
 pub impl<'self, T, U> Condition<'self, T, U> {
-    fn trap(&self, h: &'self fn(T) -> U) -> Trap<'self, T, U> {
+    fn trap(&'self self, h: &'self fn(T) -> U) -> Trap<'self, T, U> {
         unsafe {
             let p : *RustClosure = ::cast::transmute(&h);
             let prev = task::local_data::local_data_get(self.key);
diff --git a/src/libcore/container.rs b/src/libcore/container.rs
index a1836d16fd7..88c78aebfc5 100644
--- a/src/libcore/container.rs
+++ b/src/libcore/container.rs
@@ -25,6 +25,7 @@ pub trait Mutable: Container {
     fn clear(&mut self);
 }
 
+#[cfg(stage0)]
 pub trait Map<K, V>: Mutable {
     /// Return true if the map contains a value for the specified key
     fn contains_key(&self, key: &K) -> bool;
@@ -57,6 +58,41 @@ pub trait Map<K, V>: Mutable {
     fn remove(&mut self, key: &K) -> bool;
 }
 
+#[cfg(stage1)]
+#[cfg(stage2)]
+#[cfg(stage3)]
+pub trait Map<K, V>: Mutable {
+    /// Return true if the map contains a value for the specified key
+    fn contains_key(&self, key: &K) -> bool;
+
+    // Visits all keys and values
+    fn each<'a>(&'a self, f: &fn(&K, &'a V) -> bool);
+
+    /// Visit all keys
+    fn each_key(&self, f: &fn(&K) -> bool);
+
+    /// Visit all values
+    fn each_value<'a>(&'a self, f: &fn(&'a V) -> bool);
+
+    /// Iterate over the map and mutate the contained values
+    fn mutate_values(&mut self, f: &fn(&K, &mut V) -> bool);
+
+    /// Return a reference to the value corresponding to the key
+    fn find<'a>(&'a self, key: &K) -> Option<&'a V>;
+
+    /// Return a mutable reference to the value corresponding to the key
+    fn find_mut<'a>(&'a mut self, key: &K) -> Option<&'a mut V>;
+
+    /// Insert a key-value pair into the map. An existing value for a
+    /// key is replaced by the new value. Return true if the key did
+    /// not already exist in the map.
+    fn insert(&mut self, key: K, value: V) -> bool;
+
+    /// Remove a key-value pair from the map. Return true if the key
+    /// was present in the map, otherwise false.
+    fn remove(&mut self, key: &K) -> bool;
+}
+
 pub trait Set<T>: Mutable {
     /// Return true if the set contains a value
     fn contains(&self, value: &T) -> bool;
diff --git a/src/libcore/hashmap.rs b/src/libcore/hashmap.rs
index d4af0ffe7fe..2869c198ca2 100644
--- a/src/libcore/hashmap.rs
+++ b/src/libcore/hashmap.rs
@@ -186,6 +186,7 @@ priv impl<K:Hash + IterBytes + Eq,V> HashMap<K, V> {
         }
     }
 
+    #[cfg(stage0)]
     #[inline(always)]
     fn value_for_bucket(&self, idx: uint) -> &'self V {
         match self.buckets[idx] {
@@ -194,6 +195,18 @@ priv impl<K:Hash + IterBytes + Eq,V> HashMap<K, V> {
         }
     }
 
+    #[cfg(stage1)]
+    #[cfg(stage2)]
+    #[cfg(stage3)]
+    #[inline(always)]
+    fn value_for_bucket<'a>(&'a self, idx: uint) -> &'a V {
+        match self.buckets[idx] {
+            Some(ref bkt) => &bkt.value,
+            None => fail!(~"HashMap::find: internal logic error"),
+        }
+    }
+
+    #[cfg(stage0)]
     #[inline(always)]
     fn mut_value_for_bucket(&mut self, idx: uint) -> &'self mut V {
         match self.buckets[idx] {
@@ -202,6 +215,17 @@ priv impl<K:Hash + IterBytes + Eq,V> HashMap<K, V> {
         }
     }
 
+    #[cfg(stage1)]
+    #[cfg(stage2)]
+    #[cfg(stage3)]
+    #[inline(always)]
+    fn mut_value_for_bucket<'a>(&'a mut self, idx: uint) -> &'a mut V {
+        match self.buckets[idx] {
+            Some(ref mut bkt) => &mut bkt.value,
+            None => unreachable()
+        }
+    }
+
     /// Inserts the key value pair into the buckets.
     /// Assumes that there will be a bucket.
     /// True if there was no previous entry with that key
@@ -307,6 +331,7 @@ impl<K:Hash + IterBytes + Eq,V> Map<K, V> for HashMap<K, V> {
     }
 
     /// Visit all key-value pairs
+    #[cfg(stage0)]
     fn each(&self, blk: &fn(&'self K, &'self V) -> bool) {
         for uint::range(0, self.buckets.len()) |i| {
             for self.buckets[i].each |bucket| {
@@ -317,19 +342,41 @@ impl<K:Hash + IterBytes + Eq,V> Map<K, V> for HashMap<K, V> {
         }
     }
 
+    /// Visit all key-value pairs
+    #[cfg(stage1)]
+    #[cfg(stage2)]
+    #[cfg(stage3)]
+    fn each<'a>(&'a self, blk: &fn(&'a K, &'a V) -> bool) {
+        for uint::range(0, self.buckets.len()) |i| {
+            for self.buckets[i].each |bucket| {
+                if !blk(&bucket.key, &bucket.value) {
+                    return;
+                }
+            }
+        }
+    }
+
     /// Visit all keys
     fn each_key(&self, blk: &fn(k: &K) -> bool) {
         self.each(|k, _| blk(k))
     }
 
     /// Visit all values
+    #[cfg(stage0)]
     fn each_value(&self, blk: &fn(v: &V) -> bool) {
         self.each(|_, v| blk(v))
     }
 
+    /// Visit all values
+    #[cfg(stage1)]
+    #[cfg(stage2)]
+    #[cfg(stage3)]
+    fn each_value<'a>(&'a self, blk: &fn(v: &'a V) -> bool) {
+        self.each(|_, v| blk(v))
+    }
+
     /// Iterate over the map and mutate the contained values
-    fn mutate_values(&mut self, blk: &fn(&'self K,
-                          &'self mut V) -> bool) {
+    fn mutate_values(&mut self, blk: &fn(&K, &mut V) -> bool) {
         for uint::range(0, self.buckets.len()) |i| {
             match self.buckets[i] {
               Some(Bucket{key: ref key, value: ref mut value, _}) => {
@@ -341,6 +388,7 @@ impl<K:Hash + IterBytes + Eq,V> Map<K, V> for HashMap<K, V> {
     }
 
     /// Return a reference to the value corresponding to the key
+    #[cfg(stage0)]
     fn find(&self, k: &K) -> Option<&'self V> {
         match self.bucket_for_key(k) {
             FoundEntry(idx) => Some(self.value_for_bucket(idx)),
@@ -348,7 +396,19 @@ impl<K:Hash + IterBytes + Eq,V> Map<K, V> for HashMap<K, V> {
         }
     }
 
+    /// Return a reference to the value corresponding to the key
+    #[cfg(stage1)]
+    #[cfg(stage2)]
+    #[cfg(stage3)]
+    fn find<'a>(&'a self, k: &K) -> Option<&'a V> {
+        match self.bucket_for_key(k) {
+            FoundEntry(idx) => Some(self.value_for_bucket(idx)),
+            TableFull | FoundHole(_) => None,
+        }
+    }
+
     /// Return a mutable reference to the value corresponding to the key
+    #[cfg(stage0)]
     fn find_mut(&mut self, k: &K) -> Option<&'self mut V> {
         let idx = match self.bucket_for_key(k) {
             FoundEntry(idx) => idx,
@@ -359,6 +419,20 @@ impl<K:Hash + IterBytes + Eq,V> Map<K, V> for HashMap<K, V> {
         }
     }
 
+    /// Return a mutable reference to the value corresponding to the key
+    #[cfg(stage1)]
+    #[cfg(stage2)]
+    #[cfg(stage3)]
+    fn find_mut<'a>(&'a mut self, k: &K) -> Option<&'a mut V> {
+        let idx = match self.bucket_for_key(k) {
+            FoundEntry(idx) => idx,
+            TableFull | FoundHole(_) => return None
+        };
+        unsafe {  // FIXME(#4903)---requires flow-sensitive borrow checker
+            Some(::cast::transmute_mut_region(self.mut_value_for_bucket(idx)))
+        }
+    }
+
     /// Insert a key-value pair into the map. An existing value for a
     /// key is replaced by the new value. Return true if the key did
     /// not already exist in the map.
@@ -431,6 +505,7 @@ pub impl<K: Hash + IterBytes + Eq, V> HashMap<K, V> {
 
     /// Return the value corresponding to the key in the map, or insert
     /// and return the value if it doesn't exist.
+    #[cfg(stage0)]
     fn find_or_insert(&mut self, k: K, v: V) -> &'self V {
         if self.size >= self.resize_at {
             // n.b.: We could also do this after searching, so
@@ -459,8 +534,42 @@ pub impl<K: Hash + IterBytes + Eq, V> HashMap<K, V> {
         }
     }
 
+    /// Return the value corresponding to the key in the map, or insert
+    /// and return the value if it doesn't exist.
+    #[cfg(stage1)]
+    #[cfg(stage2)]
+    #[cfg(stage3)]
+    fn find_or_insert<'a>(&'a mut self, k: K, v: V) -> &'a V {
+        if self.size >= self.resize_at {
+            // n.b.: We could also do this after searching, so
+            // that we do not resize if this call to insert is
+            // simply going to update a key in place.  My sense
+            // though is that it's worse to have to search through
+            // buckets to find the right spot twice than to just
+            // resize in this corner case.
+            self.expand();
+        }
+
+        let hash = k.hash_keyed(self.k0, self.k1) as uint;
+        let idx = match self.bucket_for_key_with_hash(hash, &k) {
+            TableFull => fail!(~"Internal logic error"),
+            FoundEntry(idx) => idx,
+            FoundHole(idx) => {
+                self.buckets[idx] = Some(Bucket{hash: hash, key: k,
+                                     value: v});
+                self.size += 1;
+                idx
+            },
+        };
+
+        unsafe { // FIXME(#4903)---requires flow-sensitive borrow checker
+            ::cast::transmute_region(self.value_for_bucket(idx))
+        }
+    }
+
     /// Return the value corresponding to the key in the map, or create,
     /// insert, and return a new value if it doesn't exist.
+    #[cfg(stage0)]
     fn find_or_insert_with(&mut self, k: K, f: &fn(&K) -> V) -> &'self V {
         if self.size >= self.resize_at {
             // n.b.: We could also do this after searching, so
@@ -490,6 +599,40 @@ pub impl<K: Hash + IterBytes + Eq, V> HashMap<K, V> {
         }
     }
 
+    /// Return the value corresponding to the key in the map, or create,
+    /// insert, and return a new value if it doesn't exist.
+    #[cfg(stage1)]
+    #[cfg(stage2)]
+    #[cfg(stage3)]
+    fn find_or_insert_with<'a>(&'a mut self, k: K, f: &fn(&K) -> V) -> &'a V {
+        if self.size >= self.resize_at {
+            // n.b.: We could also do this after searching, so
+            // that we do not resize if this call to insert is
+            // simply going to update a key in place.  My sense
+            // though is that it's worse to have to search through
+            // buckets to find the right spot twice than to just
+            // resize in this corner case.
+            self.expand();
+        }
+
+        let hash = k.hash_keyed(self.k0, self.k1) as uint;
+        let idx = match self.bucket_for_key_with_hash(hash, &k) {
+            TableFull => fail!(~"Internal logic error"),
+            FoundEntry(idx) => idx,
+            FoundHole(idx) => {
+                let v = f(&k);
+                self.buckets[idx] = Some(Bucket{hash: hash, key: k,
+                                     value: v});
+                self.size += 1;
+                idx
+            },
+        };
+
+        unsafe { // FIXME(#4903)---requires flow-sensitive borrow checker
+            ::cast::transmute_region(self.value_for_bucket(idx))
+        }
+    }
+
     fn consume(&mut self, f: &fn(K, V)) {
         let mut buckets = ~[];
         self.buckets <-> buckets;
@@ -506,6 +649,7 @@ pub impl<K: Hash + IterBytes + Eq, V> HashMap<K, V> {
         }
     }
 
+    #[cfg(stage0)]
     fn get(&self, k: &K) -> &'self V {
         match self.find(k) {
             Some(v) => v,
@@ -513,6 +657,16 @@ pub impl<K: Hash + IterBytes + Eq, V> HashMap<K, V> {
         }
     }
 
+    #[cfg(stage1)]
+    #[cfg(stage2)]
+    #[cfg(stage3)]
+    fn get<'a>(&'a self, k: &K) -> &'a V {
+        match self.find(k) {
+            Some(v) => v,
+            None => fail!(fmt!("No entry found for key: %?", k)),
+        }
+    }
+
     /// Return true if the map contains a value for the specified key,
     /// using equivalence
     fn contains_key_equiv<Q:Hash + IterBytes + Equiv<K>>(&self, key: &Q)
@@ -525,6 +679,7 @@ pub impl<K: Hash + IterBytes + Eq, V> HashMap<K, V> {
 
     /// Return the value corresponding to the key in the map, using
     /// equivalence
+    #[cfg(stage0)]
     fn find_equiv<Q:Hash + IterBytes + Equiv<K>>(&self, k: &Q)
                                               -> Option<&'self V> {
         match self.bucket_for_key_equiv(k) {
@@ -532,6 +687,20 @@ pub impl<K: Hash + IterBytes + Eq, V> HashMap<K, V> {
             TableFull | FoundHole(_) => None,
         }
     }
+
+    /// Return the value corresponding to the key in the map, using
+    /// equivalence
+    #[cfg(stage1)]
+    #[cfg(stage2)]
+    #[cfg(stage3)]
+    fn find_equiv<'a, Q:Hash + IterBytes + Equiv<K>>(
+        &'a self, k: &Q) -> Option<&'a V>
+    {
+        match self.bucket_for_key_equiv(k) {
+            FoundEntry(idx) => Some(self.value_for_bucket(idx)),
+            TableFull | FoundHole(_) => None,
+        }
+    }
 }
 
 impl<K:Hash + IterBytes + Eq,V:Eq> Eq for HashMap<K, V> {
diff --git a/src/libcore/option.rs b/src/libcore/option.rs
index de1482e2c39..9b7276879c1 100644
--- a/src/libcore/option.rs
+++ b/src/libcore/option.rs
@@ -101,11 +101,21 @@ impl<T: Copy + Add<T,T>> Add<Option<T>, Option<T>> for Option<T> {
 
 impl<T> BaseIter<T> for Option<T> {
     /// Performs an operation on the contained value by reference
+    #[cfg(stage0)]
     #[inline(always)]
     fn each(&self, f: &fn(x: &'self T) -> bool) {
         match *self { None => (), Some(ref t) => { f(t); } }
     }
 
+    /// Performs an operation on the contained value by reference
+    #[cfg(stage1)]
+    #[cfg(stage2)]
+    #[cfg(stage3)]
+    #[inline(always)]
+    fn each<'a>(&'a self, f: &fn(x: &'a T) -> bool) {
+        match *self { None => (), Some(ref t) => { f(t); } }
+    }
+
     #[inline(always)]
     fn size_hint(&self) -> Option<uint> {
         if self.is_some() { Some(1) } else { Some(0) }
@@ -113,10 +123,19 @@ impl<T> BaseIter<T> for Option<T> {
 }
 
 impl<T> MutableIter<T> for Option<T> {
+    #[cfg(stage0)]
     #[inline(always)]
     fn each_mut(&mut self, f: &fn(&'self mut T) -> bool) {
         match *self { None => (), Some(ref mut t) => { f(t); } }
     }
+
+    #[cfg(stage1)]
+    #[cfg(stage2)]
+    #[cfg(stage3)]
+    #[inline(always)]
+    fn each_mut<'a>(&'a mut self, f: &fn(&'a mut T) -> bool) {
+        match *self { None => (), Some(ref mut t) => { f(t); } }
+    }
 }
 
 impl<A> ExtendedIter<A> for Option<A> {
@@ -182,17 +201,40 @@ pub impl<T> Option<T> {
      * Update an optional value by optionally running its content by reference
      * through a function that returns an option.
      */
+    #[cfg(stage0)]
     #[inline(always)]
     fn chain_ref<U>(&self, f: &fn(x: &'self T) -> Option<U>) -> Option<U> {
         match *self { Some(ref x) => f(x), None => None }
     }
 
+    /**
+     * Update an optional value by optionally running its content by reference
+     * through a function that returns an option.
+     */
+    #[cfg(stage1)]
+    #[cfg(stage2)]
+    #[cfg(stage3)]
+    #[inline(always)]
+    fn chain_ref<'a, U>(&'a self, f: &fn(x: &'a T) -> Option<U>) -> Option<U> {
+        match *self { Some(ref x) => f(x), None => None }
+    }
+
     /// Maps a `some` value from one type to another by reference
+    #[cfg(stage0)]
     #[inline(always)]
     fn map<U>(&self, f: &fn(&'self T) -> U) -> Option<U> {
         match *self { Some(ref x) => Some(f(x)), None => None }
     }
 
+    /// Maps a `some` value from one type to another by reference
+    #[cfg(stage1)]
+    #[cfg(stage2)]
+    #[cfg(stage3)]
+    #[inline(always)]
+    fn map<'a, U>(&self, f: &fn(&'a T) -> U) -> Option<U> {
+        match *self { Some(ref x) => Some(f(x)), None => None }
+    }
+
     /// As `map`, but consumes the option and gives `f` ownership to avoid
     /// copying.
     #[inline(always)]
@@ -201,11 +243,21 @@ pub impl<T> Option<T> {
     }
 
     /// Applies a function to the contained value or returns a default
+    #[cfg(stage0)]
     #[inline(always)]
     fn map_default<U>(&self, def: U, f: &fn(&'self T) -> U) -> U {
         match *self { None => def, Some(ref t) => f(t) }
     }
 
+    /// Applies a function to the contained value or returns a default
+    #[cfg(stage1)]
+    #[cfg(stage2)]
+    #[cfg(stage3)]
+    #[inline(always)]
+    fn map_default<'a, U>(&'a self, def: U, f: &fn(&'a T) -> U) -> U {
+        match *self { None => def, Some(ref t) => f(t) }
+    }
+
     /// As `map_default`, but consumes the option and gives `f`
     /// ownership to avoid copying.
     #[inline(always)]
@@ -244,6 +296,7 @@ pub impl<T> Option<T> {
     case explicitly.
      */
     #[inline(always)]
+    #[cfg(stage0)]
     fn get_ref(&self) -> &'self T {
         match *self {
           Some(ref x) => x,
@@ -252,6 +305,31 @@ pub impl<T> Option<T> {
     }
 
     /**
+    Gets an immutable reference to the value inside an option.
+
+    # Failure
+
+    Fails if the value equals `None`
+
+    # Safety note
+
+    In general, because this function may fail, its use is discouraged
+    (calling `get` on `None` is akin to dereferencing a null pointer).
+    Instead, prefer to use pattern matching and handle the `None`
+    case explicitly.
+     */
+    #[inline(always)]
+    #[cfg(stage1)]
+    #[cfg(stage2)]
+    #[cfg(stage3)]
+    fn get_ref<'a>(&'a self) -> &'a T {
+        match *self {
+          Some(ref x) => x,
+          None => fail!(~"option::get_ref none")
+        }
+    }
+
+    /**
     Gets a mutable reference to the value inside an option.
 
     # Failure
@@ -266,6 +344,7 @@ pub impl<T> Option<T> {
     case explicitly.
      */
     #[inline(always)]
+    #[cfg(stage0)]
     fn get_mut_ref(&mut self) -> &'self mut T {
         match *self {
           Some(ref mut x) => x,
@@ -273,6 +352,31 @@ pub impl<T> Option<T> {
         }
     }
 
+    /**
+    Gets a mutable reference to the value inside an option.
+
+    # Failure
+
+    Fails if the value equals `None`
+
+    # Safety note
+
+    In general, because this function may fail, its use is discouraged
+    (calling `get` on `None` is akin to dereferencing a null pointer).
+    Instead, prefer to use pattern matching and handle the `None`
+    case explicitly.
+     */
+    #[inline(always)]
+    #[cfg(stage1)]
+    #[cfg(stage2)]
+    #[cfg(stage3)]
+    fn get_mut_ref<'a>(&'a mut self) -> &'a mut T {
+        match *self {
+          Some(ref mut x) => x,
+          None => fail!(~"option::get_mut_ref none")
+        }
+    }
+
     #[inline(always)]
     fn unwrap(self) -> T {
         /*!
diff --git a/src/libcore/result.rs b/src/libcore/result.rs
index 8fd81a20603..58e281c29c6 100644
--- a/src/libcore/result.rs
+++ b/src/libcore/result.rs
@@ -226,9 +226,16 @@ pub fn map_err<T:Copy,E,F:Copy>(res: &Result<T, E>, op: &fn(&E) -> F)
 }
 
 pub impl<T, E> Result<T, E> {
+    #[cfg(stage0)]
     #[inline(always)]
     fn get_ref(&self) -> &'self T { get_ref(self) }
 
+    #[cfg(stage1)]
+    #[cfg(stage2)]
+    #[cfg(stage3)]
+    #[inline(always)]
+    fn get_ref<'a>(&'a self) -> &'a T { get_ref(self) }
+
     #[inline(always)]
     fn is_ok(&self) -> bool { is_ok(self) }
 
diff --git a/src/libcore/rt/rtio.rs b/src/libcore/rt/rtio.rs
index 55e062de85b..6a7c3970c00 100644
--- a/src/libcore/rt/rtio.rs
+++ b/src/libcore/rt/rtio.rs
@@ -22,7 +22,12 @@ pub trait EventLoop {
     fn run(&mut self);
     fn callback(&mut self, ~fn());
     /// The asynchronous I/O services. Not all event loops may provide one
+    #[cfg(stage0)]
     fn io(&mut self) -> Option<&'self mut IoFactoryObject>;
+    #[cfg(stage1)]
+    #[cfg(stage2)]
+    #[cfg(stage3)]
+    fn io<'a>(&'a mut self) -> Option<&'a mut IoFactoryObject>;
 }
 
 pub trait IoFactory {
diff --git a/src/libcore/rt/sched.rs b/src/libcore/rt/sched.rs
index 46ea5713e2a..25f446fb86d 100644
--- a/src/libcore/rt/sched.rs
+++ b/src/libcore/rt/sched.rs
@@ -272,6 +272,7 @@ pub impl Scheduler {
 
     // XXX: Hack. This should return &'self mut but I don't know how to
     // make the borrowcheck happy
+    #[cfg(stage0)]
     fn task_from_last_cleanup_job(&mut self) -> &mut Task {
         assert!(!self.cleanup_jobs.is_empty());
         let last_job: &'self mut CleanupJob = &mut self.cleanup_jobs[0];
@@ -285,6 +286,25 @@ pub impl Scheduler {
         // borrows
         return unsafe { transmute::<&Task, &mut Task>(last_task) };
     }
+
+    // XXX: Hack. This should return &'self mut but I don't know how to
+    // make the borrowcheck happy
+    #[cfg(stage1)]
+    #[cfg(stage2)]
+    #[cfg(stage3)]
+    fn task_from_last_cleanup_job<'a>(&'a mut self) -> &mut Task {
+        assert!(!self.cleanup_jobs.is_empty());
+        let last_job: &'a mut CleanupJob = &mut self.cleanup_jobs[0];
+        let last_task: &'a Task = match last_job {
+            &RescheduleTask(~ref task) => task,
+            &RecycleTask(~ref task) => task,
+            &GiveTask(~ref task, _) => task,
+        };
+        // XXX: Pattern matching mutable pointers above doesn't work
+        // because borrowck thinks the three patterns are conflicting
+        // borrows
+        return unsafe { transmute::<&Task, &mut Task>(last_task) };
+    }
 }
 
 static TASK_MIN_STACK_SIZE: uint = 10000000; // XXX: Too much stack
@@ -354,6 +374,7 @@ impl ThreadLocalScheduler {
         }
     }
 
+    #[cfg(stage0)]
     fn get_scheduler(&mut self) -> &'self mut Scheduler {
         unsafe {
             let key = match self { &ThreadLocalScheduler(key) => key };
@@ -370,6 +391,25 @@ impl ThreadLocalScheduler {
         }
     }
 
+    #[cfg(stage1)]
+    #[cfg(stage2)]
+    #[cfg(stage3)]
+    fn get_scheduler<'a>(&'a mut self) -> &'a mut Scheduler {
+        unsafe {
+            let key = match self { &ThreadLocalScheduler(key) => key };
+            let mut value: *mut c_void = tls::get(key);
+            assert!(value.is_not_null());
+            {
+                let value_ptr = &mut value;
+                let sched: &mut ~Scheduler = {
+                    transmute::<&mut *mut c_void, &mut ~Scheduler>(value_ptr)
+                };
+                let sched: &mut Scheduler = &mut **sched;
+                return sched;
+            }
+        }
+    }
+
     fn take_scheduler(&mut self) -> ~Scheduler {
         unsafe {
             let key = match self { &ThreadLocalScheduler(key) => key };
diff --git a/src/libcore/rt/uvio.rs b/src/libcore/rt/uvio.rs
index 37f29d1a5c0..7162ed27a9d 100644
--- a/src/libcore/rt/uvio.rs
+++ b/src/libcore/rt/uvio.rs
@@ -67,9 +67,17 @@ impl EventLoop for UvEventLoop {
         }
     }
 
+    #[cfg(stage0)]
     fn io(&mut self) -> Option<&'self mut IoFactoryObject> {
         Some(&mut self.uvio)
     }
+
+    #[cfg(stage1)]
+    #[cfg(stage2)]
+    #[cfg(stage3)]
+    fn io<'a>(&'a mut self) -> Option<&'a mut IoFactoryObject> {
+        Some(&mut self.uvio)
+    }
 }
 
 #[test]
@@ -89,9 +97,17 @@ fn test_callback_run_once() {
 pub struct UvIoFactory(Loop);
 
 pub impl UvIoFactory {
+    #[cfg(stage0)]
     fn uv_loop(&mut self) -> &'self mut Loop {
         match self { &UvIoFactory(ref mut ptr) => ptr }
     }
+
+    #[cfg(stage1)]
+    #[cfg(stage2)]
+    #[cfg(stage3)]
+    fn uv_loop<'a>(&'a mut self) -> &'a mut Loop {
+        match self { &UvIoFactory(ref mut ptr) => ptr }
+    }
 }
 
 impl IoFactory for UvIoFactory {
diff --git a/src/libcore/task/mod.rs b/src/libcore/task/mod.rs
index 502efcf9dc6..e4ee430cdda 100644
--- a/src/libcore/task/mod.rs
+++ b/src/libcore/task/mod.rs
@@ -39,7 +39,7 @@ use result::Result;
 use comm::{stream, Chan, GenericChan, GenericPort, Port};
 use prelude::*;
 use result;
-use task::rt::{task_id, sched_id, rust_task};
+use task::rt::{task_id, sched_id};
 use util;
 use util::replace;
 use unstable::finally::Finally;
diff --git a/src/libcore/trie.rs b/src/libcore/trie.rs
index f6a92a21385..f4e9ddbdd90 100644
--- a/src/libcore/trie.rs
+++ b/src/libcore/trie.rs
@@ -56,10 +56,20 @@ impl<T> Map<uint, T> for TrieMap<T> {
 
     /// Visit all key-value pairs in order
     #[inline(always)]
+    #[cfg(stage0)]
     fn each(&self, f: &fn(&uint, &'self T) -> bool) {
         self.root.each(f);
     }
 
+    /// Visit all key-value pairs in order
+    #[inline(always)]
+    #[cfg(stage1)]
+    #[cfg(stage2)]
+    #[cfg(stage3)]
+    fn each<'a>(&'a self, f: &fn(&uint, &'a T) -> bool) {
+        self.root.each(f);
+    }
+
     /// Visit all keys in order
     #[inline(always)]
     fn each_key(&self, f: &fn(&uint) -> bool) {
@@ -68,10 +78,20 @@ impl<T> Map<uint, T> for TrieMap<T> {
 
     /// Visit all values in order
     #[inline(always)]
+    #[cfg(stage0)]
     fn each_value(&self, f: &fn(&T) -> bool) {
         self.each(|_, v| f(v))
     }
 
+    /// Visit all values in order
+    #[inline(always)]
+    #[cfg(stage1)]
+    #[cfg(stage2)]
+    #[cfg(stage3)]
+    fn each_value<'a>(&'a self, f: &fn(&'a T) -> bool) {
+        self.each(|_, v| f(v))
+    }
+
     /// Iterate over the map and mutate the contained values
     #[inline(always)]
     fn mutate_values(&mut self, f: &fn(&uint, &mut T) -> bool) {
@@ -79,6 +99,7 @@ impl<T> Map<uint, T> for TrieMap<T> {
     }
 
     /// Return a reference to the value corresponding to the key
+    #[cfg(stage0)]
     #[inline(hint)]
     fn find(&self, key: &uint) -> Option<&'self T> {
         let mut node: &'self TrieNode<T> = &self.root;
@@ -99,12 +120,46 @@ impl<T> Map<uint, T> for TrieMap<T> {
         }
     }
 
+    /// Return a reference to the value corresponding to the key
+    #[cfg(stage1)]
+    #[cfg(stage2)]
+    #[cfg(stage3)]
+    #[inline(hint)]
+    fn find<'a>(&'a self, key: &uint) -> Option<&'a T> {
+        let mut node: &'a TrieNode<T> = &self.root;
+        let mut idx = 0;
+        loop {
+            match node.children[chunk(*key, idx)] {
+              Internal(ref x) => node = &**x,
+              External(stored, ref value) => {
+                if stored == *key {
+                    return Some(value)
+                } else {
+                    return None
+                }
+              }
+              Nothing => return None
+            }
+            idx += 1;
+        }
+    }
+
     /// Return a mutable reference to the value corresponding to the key
+    #[cfg(stage0)]
     #[inline(always)]
     fn find_mut(&mut self, key: &uint) -> Option<&'self mut T> {
         find_mut(&mut self.root.children[chunk(*key, 0)], *key, 1)
     }
 
+    /// Return a mutable reference to the value corresponding to the key
+    #[cfg(stage1)]
+    #[cfg(stage2)]
+    #[cfg(stage3)]
+    #[inline(always)]
+    fn find_mut<'a>(&'a mut self, key: &uint) -> Option<&'a mut T> {
+        find_mut(&mut self.root.children[chunk(*key, 0)], *key, 1)
+    }
+
     /// Insert a key-value pair into the map. An existing value for a
     /// key is replaced by the new value. Return true if the key did
     /// not already exist in the map.
@@ -138,10 +193,20 @@ pub impl<T> TrieMap<T> {
 
     /// Visit all key-value pairs in reverse order
     #[inline(always)]
+    #[cfg(stage0)]
     fn each_reverse(&self, f: &fn(&uint, &'self T) -> bool) {
         self.root.each_reverse(f);
     }
 
+    /// Visit all key-value pairs in reverse order
+    #[inline(always)]
+    #[cfg(stage1)]
+    #[cfg(stage2)]
+    #[cfg(stage3)]
+    fn each_reverse<'a>(&'a self, f: &fn(&uint, &'a T) -> bool) {
+        self.root.each_reverse(f);
+    }
+
     /// Visit all keys in reverse order
     #[inline(always)]
     fn each_key_reverse(&self, f: &fn(&uint) -> bool) {
@@ -233,6 +298,7 @@ impl<T> TrieNode<T> {
 }
 
 impl<T> TrieNode<T> {
+    #[cfg(stage0)]
     fn each(&self, f: &fn(&uint, &'self T) -> bool) -> bool {
         for uint::range(0, self.children.len()) |idx| {
             match self.children[idx] {
@@ -244,6 +310,21 @@ impl<T> TrieNode<T> {
         true
     }
 
+    #[cfg(stage1)]
+    #[cfg(stage2)]
+    #[cfg(stage3)]
+    fn each<'a>(&'a self, f: &fn(&uint, &'a T) -> bool) -> bool {
+        for uint::range(0, self.children.len()) |idx| {
+            match self.children[idx] {
+                Internal(ref x) => if !x.each(f) { return false },
+                External(k, ref v) => if !f(&k, v) { return false },
+                Nothing => ()
+            }
+        }
+        true
+    }
+
+    #[cfg(stage0)]
     fn each_reverse(&self, f: &fn(&uint, &'self T) -> bool) -> bool {
         for uint::range_rev(self.children.len(), 0) |idx| {
             match self.children[idx - 1] {
@@ -255,7 +336,21 @@ impl<T> TrieNode<T> {
         true
     }
 
-    fn mutate_values(&mut self, f: &fn(&uint, &mut T) -> bool) -> bool {
+    #[cfg(stage1)]
+    #[cfg(stage2)]
+    #[cfg(stage3)]
+    fn each_reverse<'a>(&'a self, f: &fn(&uint, &'a T) -> bool) -> bool {
+        for uint::range_rev(self.children.len(), 0) |idx| {
+            match self.children[idx - 1] {
+                Internal(ref x) => if !x.each_reverse(f) { return false },
+                External(k, ref v) => if !f(&k, v) { return false },
+                Nothing => ()
+            }
+        }
+        true
+    }
+
+    fn mutate_values<'a>(&'a mut self, f: &fn(&uint, &mut T) -> bool) -> bool {
         for vec::each_mut(self.children) |child| {
             match *child {
                 Internal(ref mut x) => if !x.mutate_values(f) {
diff --git a/src/libcore/tuple.rs b/src/libcore/tuple.rs
index 8234129e254..8e908435f35 100644
--- a/src/libcore/tuple.rs
+++ b/src/libcore/tuple.rs
@@ -56,11 +56,13 @@ impl<T:Clone,U:Clone> Clone for (T, U) {
     }
 }
 
+#[cfg(stage0)]
 pub trait ImmutableTuple<T, U> {
     fn first_ref(&self) -> &'self T;
     fn second_ref(&self) -> &'self U;
 }
 
+#[cfg(stage0)]
 impl<T, U> ImmutableTuple<T, U> for (T, U) {
     #[inline(always)]
     fn first_ref(&self) -> &'self T {
@@ -76,6 +78,32 @@ impl<T, U> ImmutableTuple<T, U> for (T, U) {
     }
 }
 
+#[cfg(stage1)]
+#[cfg(stage2)]
+#[cfg(stage3)]
+pub trait ImmutableTuple<T, U> {
+    fn first_ref<'a>(&'a self) -> &'a T;
+    fn second_ref<'a>(&'a self) -> &'a U;
+}
+
+#[cfg(stage1)]
+#[cfg(stage2)]
+#[cfg(stage3)]
+impl<T, U> ImmutableTuple<T, U> for (T, U) {
+    #[inline(always)]
+    fn first_ref<'a>(&'a self) -> &'a T {
+        match *self {
+            (ref t, _) => t,
+        }
+    }
+    #[inline(always)]
+    fn second_ref<'a>(&'a self) -> &'a U {
+        match *self {
+            (_, ref u) => u,
+        }
+    }
+}
+
 pub trait ExtendedTupleOps<A,B> {
     fn zip(&self) -> ~[(A, B)];
     fn map<C>(&self, f: &fn(a: &A, b: &B) -> C) -> ~[C];
diff --git a/src/libcore/vec.rs b/src/libcore/vec.rs
index 5b06591f9ec..7940502d27e 100644
--- a/src/libcore/vec.rs
+++ b/src/libcore/vec.rs
@@ -1763,6 +1763,7 @@ impl<'self,T:Copy> CopyableVector<T> for &'self const [T] {
     }
 }
 
+#[cfg(stage0)]
 pub trait ImmutableVector<T> {
     fn slice(&self, start: uint, end: uint) -> &'self [T];
     fn head(&self) -> &'self T;
@@ -1785,6 +1786,7 @@ pub trait ImmutableVector<T> {
 }
 
 /// Extension methods for vectors
+#[cfg(stage0)]
 impl<'self,T> ImmutableVector<T> for &'self [T] {
     /// Return a slice that points into another slice.
     #[inline]
@@ -1893,6 +1895,142 @@ impl<'self,T> ImmutableVector<T> for &'self [T] {
     }
 }
 
+#[cfg(stage1)]
+#[cfg(stage2)]
+#[cfg(stage3)]
+pub trait ImmutableVector<'self, T> {
+    fn slice(&self, start: uint, end: uint) -> &'self [T];
+    fn head(&self) -> &'self T;
+    fn head_opt(&self) -> Option<&'self T>;
+    fn tail(&self) -> &'self [T];
+    fn tailn(&self, n: uint) -> &'self [T];
+    fn init(&self) -> &'self [T];
+    fn initn(&self, n: uint) -> &'self [T];
+    fn last(&self) -> &'self T;
+    fn last_opt(&self) -> Option<&'self T>;
+    fn each_reverse(&self, blk: &fn(&T) -> bool);
+    fn eachi_reverse(&self, blk: &fn(uint, &T) -> bool);
+    fn foldr<U: Copy>(&self, z: U, p: &fn(t: &T, u: U) -> U) -> U;
+    fn map<U>(&self, f: &fn(t: &T) -> U) -> ~[U];
+    fn mapi<U>(&self, f: &fn(uint, t: &T) -> U) -> ~[U];
+    fn map_r<U>(&self, f: &fn(x: &T) -> U) -> ~[U];
+    fn alli(&self, f: &fn(uint, t: &T) -> bool) -> bool;
+    fn flat_map<U>(&self, f: &fn(t: &T) -> ~[U]) -> ~[U];
+    fn filter_mapped<U:Copy>(&self, f: &fn(t: &T) -> Option<U>) -> ~[U];
+}
+
+/// Extension methods for vectors
+#[cfg(stage1)]
+#[cfg(stage2)]
+#[cfg(stage3)]
+impl<'self,T> ImmutableVector<'self, T> for &'self [T] {
+    /// Return a slice that points into another slice.
+    #[inline]
+    fn slice(&self, start: uint, end: uint) -> &'self [T] {
+        slice(*self, start, end)
+    }
+
+    /// Returns the first element of a vector, failing if the vector is empty.
+    #[inline]
+    fn head(&self) -> &'self T { head(*self) }
+
+    /// Returns the first element of a vector
+    #[inline]
+    fn head_opt(&self) -> Option<&'self T> { head_opt(*self) }
+
+    /// Returns all but the first element of a vector
+    #[inline]
+    fn tail(&self) -> &'self [T] { tail(*self) }
+
+    /// Returns all but the first `n' elements of a vector
+    #[inline]
+    fn tailn(&self, n: uint) -> &'self [T] { tailn(*self, n) }
+
+    /// Returns all but the last elemnt of a vector
+    #[inline]
+    fn init(&self) -> &'self [T] { init(*self) }
+
+    /// Returns all but the last `n' elemnts of a vector
+    #[inline]
+    fn initn(&self, n: uint) -> &'self [T] { initn(*self, n) }
+
+    /// Returns the last element of a `v`, failing if the vector is empty.
+    #[inline]
+    fn last(&self) -> &'self T { last(*self) }
+
+    /// Returns the last element of a `v`, failing if the vector is empty.
+    #[inline]
+    fn last_opt(&self) -> Option<&'self T> { last_opt(*self) }
+
+    /// Iterates over a vector's elements in reverse.
+    #[inline]
+    fn each_reverse(&self, blk: &fn(&T) -> bool) {
+        each_reverse(*self, blk)
+    }
+
+    /// Iterates over a vector's elements and indices in reverse.
+    #[inline]
+    fn eachi_reverse(&self, blk: &fn(uint, &T) -> bool) {
+        eachi_reverse(*self, blk)
+    }
+
+    /// Reduce a vector from right to left
+    #[inline]
+    fn foldr<U:Copy>(&self, z: U, p: &fn(t: &T, u: U) -> U) -> U {
+        foldr(*self, z, p)
+    }
+
+    /// Apply a function to each element of a vector and return the results
+    #[inline]
+    fn map<U>(&self, f: &fn(t: &T) -> U) -> ~[U] { map(*self, f) }
+
+    /**
+     * Apply a function to the index and value of each element in the vector
+     * and return the results
+     */
+    fn mapi<U>(&self, f: &fn(uint, t: &T) -> U) -> ~[U] {
+        mapi(*self, f)
+    }
+
+    #[inline]
+    fn map_r<U>(&self, f: &fn(x: &T) -> U) -> ~[U] {
+        let mut r = ~[];
+        let mut i = 0;
+        while i < self.len() {
+            r.push(f(&self[i]));
+            i += 1;
+        }
+        r
+    }
+
+    /**
+     * Returns true if the function returns true for all elements.
+     *
+     *     If the vector is empty, true is returned.
+     */
+    fn alli(&self, f: &fn(uint, t: &T) -> bool) -> bool {
+        alli(*self, f)
+    }
+    /**
+     * Apply a function to each element of a vector and return a concatenation
+     * of each result vector
+     */
+    #[inline]
+    fn flat_map<U>(&self, f: &fn(t: &T) -> ~[U]) -> ~[U] {
+        flat_map(*self, f)
+    }
+    /**
+     * Apply a function to each element of a vector and return the results
+     *
+     * If function `f` returns `none` then that element is excluded from
+     * the resulting vector.
+     */
+    #[inline]
+    fn filter_mapped<U:Copy>(&self, f: &fn(t: &T) -> Option<U>) -> ~[U] {
+        filter_mapped(*self, f)
+    }
+}
+
 pub trait ImmutableEqVector<T:Eq> {
     fn position(&self, f: &fn(t: &T) -> bool) -> Option<uint>;
     fn position_elem(&self, t: &T) -> Option<uint>;
@@ -2353,6 +2491,7 @@ pub mod bytes {
 // ___________________________________________________________________________
 // ITERATION TRAIT METHODS
 
+#[cfg(stage0)]
 impl<'self,A> iter::BaseIter<A> for &'self [A] {
     #[inline(always)]
     fn each(&self, blk: &fn(v: &'self A) -> bool) { each(*self, blk) }
@@ -2360,7 +2499,18 @@ impl<'self,A> iter::BaseIter<A> for &'self [A] {
     fn size_hint(&self) -> Option<uint> { Some(self.len()) }
 }
 
+#[cfg(stage1)]
+#[cfg(stage2)]
+#[cfg(stage3)]
+impl<'self,A> iter::BaseIter<A> for &'self [A] {
+    #[inline(always)]
+    fn each<'a>(&'a self, blk: &fn(v: &'a A) -> bool) { each(*self, blk) }
+    #[inline(always)]
+    fn size_hint(&self) -> Option<uint> { Some(self.len()) }
+}
+
 // FIXME(#4148): This should be redundant
+#[cfg(stage0)]
 impl<A> iter::BaseIter<A> for ~[A] {
     #[inline(always)]
     fn each(&self, blk: &fn(v: &'self A) -> bool) { each(*self, blk) }
@@ -2369,6 +2519,18 @@ impl<A> iter::BaseIter<A> for ~[A] {
 }
 
 // FIXME(#4148): This should be redundant
+#[cfg(stage1)]
+#[cfg(stage2)]
+#[cfg(stage3)]
+impl<A> iter::BaseIter<A> for ~[A] {
+    #[inline(always)]
+    fn each<'a>(&'a self, blk: &fn(v: &'a A) -> bool) { each(*self, blk) }
+    #[inline(always)]
+    fn size_hint(&self) -> Option<uint> { Some(self.len()) }
+}
+
+// FIXME(#4148): This should be redundant
+#[cfg(stage0)]
 impl<A> iter::BaseIter<A> for @[A] {
     #[inline(always)]
     fn each(&self, blk: &fn(v: &'self A) -> bool) { each(*self, blk) }
@@ -2376,6 +2538,18 @@ impl<A> iter::BaseIter<A> for @[A] {
     fn size_hint(&self) -> Option<uint> { Some(self.len()) }
 }
 
+// FIXME(#4148): This should be redundant
+#[cfg(stage1)]
+#[cfg(stage2)]
+#[cfg(stage3)]
+impl<A> iter::BaseIter<A> for @[A] {
+    #[inline(always)]
+    fn each<'a>(&'a self, blk: &fn(v: &'a A) -> bool) { each(*self, blk) }
+    #[inline(always)]
+    fn size_hint(&self) -> Option<uint> { Some(self.len()) }
+}
+
+#[cfg(stage0)]
 impl<'self,A> iter::MutableIter<A> for &'self mut [A] {
     #[inline(always)]
     fn each_mut(&mut self, blk: &fn(v: &'self mut A) -> bool) {
@@ -2383,7 +2557,18 @@ impl<'self,A> iter::MutableIter<A> for &'self mut [A] {
     }
 }
 
+#[cfg(stage1)]
+#[cfg(stage2)]
+#[cfg(stage3)]
+impl<'self,A> iter::MutableIter<A> for &'self mut [A] {
+    #[inline(always)]
+    fn each_mut<'a>(&'a mut self, blk: &fn(v: &'a mut A) -> bool) {
+        each_mut(*self, blk)
+    }
+}
+
 // FIXME(#4148): This should be redundant
+#[cfg(stage0)]
 impl<A> iter::MutableIter<A> for ~[A] {
     #[inline(always)]
     fn each_mut(&mut self, blk: &fn(v: &'self mut A) -> bool) {
@@ -2391,6 +2576,16 @@ impl<A> iter::MutableIter<A> for ~[A] {
     }
 }
 
+#[cfg(stage1)]
+#[cfg(stage2)]
+#[cfg(stage3)]
+impl<A> iter::MutableIter<A> for ~[A] {
+    #[inline(always)]
+    fn each_mut<'a>(&'a mut self, blk: &fn(v: &'a mut A) -> bool) {
+        each_mut(*self, blk)
+    }
+}
+
 // FIXME(#4148): This should be redundant
 impl<A> iter::MutableIter<A> for @mut [A] {
     #[inline(always)]