about summary refs log tree commit diff
path: root/src/libstd
diff options
context:
space:
mode:
authorNiko Matsakis <niko@alum.mit.edu>2012-08-02 15:42:56 -0700
committerNiko Matsakis <niko@alum.mit.edu>2012-08-02 15:53:28 -0700
commit97452c0ca16238a2de5503aca07db26ff9e8ba63 (patch)
tree47ef430d1671ab297bc192009aa74a23723a42fc /src/libstd
parent476ce459bd3b687658e566c75d0fb73281450d67 (diff)
Remove modes from map API and replace with regions.
API is (for now) mostly by value, there are options to use it by
reference if you like.  Hash and equality functions must be pure
and by reference (forward looking to the day when something
like send_map becomes the standard map).
Diffstat (limited to 'src/libstd')
-rw-r--r--src/libstd/bitv.rs3
-rw-r--r--src/libstd/getopts.rs2
-rw-r--r--src/libstd/json.rs18
-rw-r--r--src/libstd/map.rs289
-rw-r--r--src/libstd/smallintmap.rs40
-rw-r--r--src/libstd/sort.rs33
-rw-r--r--src/libstd/term.rs2
-rw-r--r--src/libstd/test.rs15
8 files changed, 224 insertions, 178 deletions
diff --git a/src/libstd/bitv.rs b/src/libstd/bitv.rs
index f27e6c3e266..edc35ff7a87 100644
--- a/src/libstd/bitv.rs
+++ b/src/libstd/bitv.rs
@@ -391,8 +391,7 @@ class bitv {
  * Each uint in the resulting vector has either value 0u or 1u.
  */
     fn to_vec() -> ~[uint] {
-      let sub = |x| self.init_to_vec(x);
-      return vec::from_fn::<uint>(self.nbits, sub);
+        vec::from_fn(self.nbits, |x| self.init_to_vec(x))
     }
 
 /**
diff --git a/src/libstd/getopts.rs b/src/libstd/getopts.rs
index ed7d4206436..ed0ee4ff5ed 100644
--- a/src/libstd/getopts.rs
+++ b/src/libstd/getopts.rs
@@ -201,7 +201,7 @@ fn getopts(args: ~[~str], opts: ~[opt]) -> result unsafe {
         let curlen = str::len(cur);
         if !is_arg(cur) {
             vec::push(free, cur);
-        } else if str::eq(cur, ~"--") {
+        } else if cur == ~"--" {
             let mut j = i + 1u;
             while j < l { vec::push(free, args[j]); j += 1u; }
             break;
diff --git a/src/libstd/json.rs b/src/libstd/json.rs
index f2c2a616ede..9faea572338 100644
--- a/src/libstd/json.rs
+++ b/src/libstd/json.rs
@@ -588,18 +588,24 @@ impl of to_json for @~str {
     fn to_json() -> json { string(self) }
 }
 
-impl <A: to_json copy, B: to_json copy> of to_json for (A, B) {
+impl <A: to_json, B: to_json> of to_json for (A, B) {
     fn to_json() -> json {
-        let (a, b) = self;
-        list(@~[a.to_json(), b.to_json()])
+        alt self {
+          (a, b) => {
+            list(@~[a.to_json(), b.to_json()])
+          }
+        }
     }
 }
 
-impl <A: to_json copy, B: to_json copy, C: to_json copy>
+impl <A: to_json, B: to_json, C: to_json>
   of to_json for (A, B, C) {
     fn to_json() -> json {
-        let (a, b, c) = self;
-        list(@~[a.to_json(), b.to_json(), c.to_json()])
+        alt self {
+          (a, b, c) => {
+            list(@~[a.to_json(), b.to_json(), c.to_json()])
+          }
+        }
     }
 }
 
diff --git a/src/libstd/map.rs b/src/libstd/map.rs
index 902fe5aaf6e..dd99c9945e1 100644
--- a/src/libstd/map.rs
+++ b/src/libstd/map.rs
@@ -1,5 +1,7 @@
 //! A map type
 
+#[warn(deprecated_mode)];
+
 import chained::hashmap;
 import io::writer_util;
 import to_str::to_str;
@@ -15,16 +17,16 @@ export vec_from_set;
  *
  * The hash should concentrate entropy in the lower bits.
  */
-type hashfn<K> = fn@(K) -> uint;
+type hashfn<K> = fn~(key: &K) -> uint;
 
-type eqfn<K> = fn@(K, K) -> bool;
+type eqfn<K> = fn~(key1: &K, key2: &K) -> bool;
 
 /// A convenience type to treat a hashmap as a set
 type set<K> = hashmap<K, ()>;
 
 type hashmap<K, V> = chained::t<K, V>;
 
-trait map<K, V: copy> {
+trait map<K: copy, V: copy> {
     /// Return the number of elements in the map
     fn size() -> uint;
 
@@ -39,40 +41,50 @@ trait map<K, V: copy> {
     fn insert(+K, +V) -> bool;
 
     /// Returns true if the map contains a value for the specified key
-    fn contains_key(K) -> bool;
+    fn contains_key(+key: K) -> bool;
+
+    /// Returns true if the map contains a value for the specified
+    /// key, taking the key by reference.
+    fn contains_key_ref(key: &K) -> bool;
 
     /**
      * Get the value for the specified key. Fails if the key does not exist in
      * the map.
      */
-    fn get(K) -> V;
-
-    /// Like get, but as an operator.
-    fn [](K) -> V;
+    fn get(+key: K) -> V;
 
     /**
      * Get the value for the specified key. If the key does not exist in
      * the map then returns none.
      */
-    fn find(K) -> option<V>;
+    fn find(+key: K) -> option<V>;
 
     /**
      * Remove and return a value from the map. If the key does not exist
      * in the map then returns none.
      */
-    fn remove(K) -> option<V>;
+    fn remove(+key: K) -> option<V>;
 
     /// Clear the map, removing all key/value pairs.
     fn clear();
 
-    /// Iterate over all the key/value pairs in the map
-    fn each(fn(K, V) -> bool);
+    /// Iterate over all the key/value pairs in the map by value
+    fn each(fn(+key: K, +value: V) -> bool);
+
+    /// Iterate over all the keys in the map by value
+    fn each_key(fn(+key: K) -> bool);
+
+    /// Iterate over all the values in the map by value
+    fn each_value(fn(+value: V) -> bool);
 
-    /// Iterate over all the keys in the map
-    fn each_key(fn(K) -> bool);
+    /// Iterate over all the key/value pairs in the map by reference
+    fn each_ref(fn(key: &K, value: &V) -> bool);
 
-    /// Iterate over all the values in the map
-    fn each_value(fn(V) -> bool);
+    /// Iterate over all the keys in the map by reference
+    fn each_key_ref(fn(key: &K) -> bool);
+
+    /// Iterate over all the values in the map by reference
+    fn each_value_ref(fn(value: &V) -> bool);
 }
 
 mod util {
@@ -93,31 +105,21 @@ mod chained {
 
     const initial_capacity: uint = 32u; // 2^5
 
-    type entry<K, V> = {
-        hash: uint,
-        key: K,
-        mut value: V,
-        mut next: chain<K, V>
-    };
-
-    enum chain<K, V> {
-        present(@entry<K, V>),
-        absent
+    struct entry<K, V> {
+        hash: uint;
+        key: K;
+        value: V;
+        mut next: option<@entry<K, V>>;
     }
 
-    type hashmap__<K, V> = {
-        mut count: uint,
-        mut chains: ~[mut chain<K,V>],
-        hasher: hashfn<K>,
-        eqer: eqfn<K>
-    };
-    type t<K, V> = @hashmap_<K, V>;
-
-    enum hashmap_<K, V> {
-        hashmap_(@hashmap__<K, V>)
+    struct hashmap_<K, V> {
+        mut count: uint;
+        mut chains: ~[mut option<@entry<K,V>>];
+        hasher: hashfn<K>;
+        eqer: eqfn<K>;
     }
 
-    type t<K, V> = hashmap_<K, V>;
+    type t<K, V> = @hashmap_<K, V>;
 
     enum search_result<K, V> {
         not_found,
@@ -125,21 +127,21 @@ mod chained {
         found_after(@entry<K,V>, @entry<K,V>)
     }
 
-    impl private_methods<K, V: copy> for hashmap_<K, V> {
-        fn search_rem(k: K, h: uint, idx: uint,
+    impl private_methods<K, V: copy> for t<K, V> {
+        fn search_rem(k: &K, h: uint, idx: uint,
                       e_root: @entry<K,V>) -> search_result<K,V> {
             let mut e0 = e_root;
             let mut comp = 1u;   // for logging
             loop {
                 alt copy e0.next {
-                  absent {
+                  none {
                     debug!{"search_tbl: absent, comp %u, hash %u, idx %u",
                            comp, h, idx};
                     return not_found;
                   }
-                  present(e1) {
+                  some(e1) {
                     comp += 1u;
-                    if e1.hash == h && self.eqer(e1.key, k) {
+                    if e1.hash == h && self.eqer(&e1.key, k) {
                         debug!{"search_tbl: present, comp %u, \
                                 hash %u, idx %u",
                                comp, h, idx};
@@ -152,16 +154,16 @@ mod chained {
             };
         }
 
-        fn search_tbl(k: K, h: uint) -> search_result<K,V> {
+        fn search_tbl(k: &K, h: uint) -> search_result<K,V> {
             let idx = h % vec::len(self.chains);
             alt copy self.chains[idx] {
-              absent {
-                debug!{"search_tbl: absent, comp %u, hash %u, idx %u",
+              none {
+                debug!{"search_tbl: none, comp %u, hash %u, idx %u",
                        0u, h, idx};
                 return not_found;
               }
-              present(e) {
-                if e.hash == h && self.eqer(e.key, k) {
+              some(e) {
+                if e.hash == h && self.eqer(&e.key, k) {
                     debug!{"search_tbl: present, comp %u, hash %u, idx %u",
                            1u, h, idx};
                     return found_first(idx, e);
@@ -173,25 +175,27 @@ mod chained {
         }
 
         fn rehash() {
-            let n_old_chains = vec::len(self.chains);
+            let n_old_chains = self.chains.len();
             let n_new_chains: uint = uint::next_power_of_two(n_old_chains+1u);
             let new_chains = chains(n_new_chains);
             for self.each_entry |entry| {
                 let idx = entry.hash % n_new_chains;
                 entry.next = new_chains[idx];
-                new_chains[idx] = present(entry);
+                new_chains[idx] = some(entry);
             }
             self.chains = new_chains;
         }
 
         fn each_entry(blk: fn(@entry<K,V>) -> bool) {
-            let mut i = 0u, n = vec::len(self.chains);
+            // n.b. we can't use vec::iter() here because self.chains
+            // is stored in a mutable location.
+            let mut i = 0u, n = self.chains.len();
             while i < n {
                 let mut chain = self.chains[i];
                 loop {
                     chain = alt chain {
-                      absent { break; }
-                      present(entry) {
+                      none { break; }
+                      some(entry) {
                         let next = entry.next;
                         if !blk(entry) { return; }
                         next
@@ -203,10 +207,14 @@ mod chained {
         }
     }
 
-    impl hashmap<K, V: copy> of map<K, V> for t<K, V> {
+    impl hashmap<K: copy, V: copy> of map<K, V> for t<K, V> {
         fn size() -> uint { self.count }
 
-        fn contains_key(k: K) -> bool {
+        fn contains_key(+k: K) -> bool {
+            self.contains_key_ref(&k)
+        }
+
+        fn contains_key_ref(k: &K) -> bool {
             let hash = self.hasher(k);
             alt self.search_tbl(k, hash) {
               not_found {false}
@@ -215,17 +223,17 @@ mod chained {
         }
 
         fn insert(+k: K, +v: V) -> bool {
-            let hash = self.hasher(k);
-            alt self.search_tbl(k, hash) {
+            let hash = self.hasher(&k);
+            alt self.search_tbl(&k, hash) {
               not_found {
                 self.count += 1u;
                 let idx = hash % vec::len(self.chains);
                 let old_chain = self.chains[idx];
-                self.chains[idx] = present(@{
+                self.chains[idx] = some(@entry {
                     hash: hash,
                     key: k,
-                    mut value: v,
-                    mut next: old_chain});
+                    value: v,
+                    next: old_chain});
 
                 // consider rehashing if more 3/4 full
                 let nchains = vec::len(self.chains);
@@ -237,38 +245,43 @@ mod chained {
 
                 return true;
               }
-              found_first(_, entry) {
-                entry.value = v;
+              found_first(idx, entry) {
+                self.chains[idx] = some(@entry {
+                    hash: hash,
+                    key: k,
+                    value: v,
+                    next: entry.next});
                 return false;
               }
-              found_after(_, entry) {
-                entry.value = v;
-                return false
+              found_after(prev, entry) {
+                prev.next = some(@entry {
+                    hash: hash,
+                    key: k,
+                    value: v,
+                    next: entry.next});
+                return false;
               }
             }
         }
 
-        fn find(k: K) -> option<V> {
-            alt self.search_tbl(k, self.hasher(k)) {
+        fn find(+k: K) -> option<V> {
+            alt self.search_tbl(&k, self.hasher(&k)) {
               not_found {none}
               found_first(_, entry) {some(entry.value)}
               found_after(_, entry) {some(entry.value)}
             }
         }
 
-        fn get(k: K) -> V {
-            alt self.find(k) {
-              some(v) => {v}
-              none => {fail fmt!{"Key not found in table: %?", k}}
+        fn get(+k: K) -> V {
+            let opt_v = self.find(k);
+            if opt_v.is_none() {
+                fail fmt!{"Key not found in table: %?", k};
             }
+            option::unwrap(opt_v)
         }
 
-        fn [](k: K) -> V {
-            self.get(k)
-        }
-
-        fn remove(k: K) -> option<V> {
-            alt self.search_tbl(k, self.hasher(k)) {
+        fn remove(+k: K) -> option<V> {
+            alt self.search_tbl(&k, self.hasher(&k)) {
               not_found {none}
               found_first(idx, entry) {
                 self.count -= 1u;
@@ -288,18 +301,34 @@ mod chained {
             self.chains = chains(initial_capacity);
         }
 
-        fn each(blk: fn(K,V) -> bool) {
+        fn each(blk: fn(+key: K, +value: V) -> bool) {
+            self.each_ref(|k, v| blk(*k, *v))
+        }
+
+        fn each_key(blk: fn(+key: K) -> bool) {
+            self.each_key_ref(|p| blk(*p))
+        }
+
+        fn each_value(blk: fn(+value: V) -> bool) {
+            self.each_value_ref(|p| blk(*p))
+        }
+
+        fn each_ref(blk: fn(key: &K, value: &V) -> bool) {
             for self.each_entry |entry| {
-                if !blk(entry.key, copy entry.value) { break; }
+                if !blk(&entry.key, &entry.value) { break; }
             }
         }
 
-        fn each_key(blk: fn(K) -> bool) { self.each(|k, _v| blk(k)) }
+        fn each_key_ref(blk: fn(key: &K) -> bool) {
+            self.each_ref(|k, _v| blk(k))
+        }
 
-        fn each_value(blk: fn(V) -> bool) { self.each(|_k, v| blk(v)) }
+        fn each_value_ref(blk: fn(value: &V) -> bool) {
+            self.each_ref(|_k, v| blk(v))
+        }
     }
 
-    impl hashmap<K: to_str, V: to_str copy> of to_str for hashmap_<K, V> {
+    impl hashmap<K: copy to_str, V: to_str copy> of to_str for t<K, V> {
         fn to_writer(wr: io::writer) {
             if self.count == 0u {
                 wr.write_str("{}");
@@ -325,24 +354,23 @@ mod chained {
         }
     }
 
-    impl hashmap<K, V: copy> of ops::index<K, V> for t<K, V> {
-        pure fn index(k: K) -> V {
+    impl hashmap<K: copy, V: copy> of ops::index<K, V> for t<K, V> {
+        pure fn index(&&k: K) -> V {
             unchecked {
                 self.get(k)
             }
         }
     }
 
-
-    fn chains<K,V>(nchains: uint) -> ~[mut chain<K,V>] {
-        return vec::to_mut(vec::from_elem(nchains, absent));
+    fn chains<K,V>(nchains: uint) -> ~[mut option<@entry<K,V>>] {
+        vec::to_mut(vec::from_elem(nchains, none))
     }
 
-    fn mk<K, V: copy>(hasher: hashfn<K>, eqer: eqfn<K>) -> t<K,V> {
-        let slf: t<K, V> = hashmap_(@{mut count: 0u,
-                                      mut chains: chains(initial_capacity),
+    fn mk<K, V: copy>(+hasher: hashfn<K>, +eqer: eqfn<K>) -> t<K,V> {
+        let slf: t<K, V> = @hashmap_ {count: 0u,
+                                      chains: chains(initial_capacity),
                                       hasher: hasher,
-                                      eqer: eqer});
+                                      eqer: eqer};
         slf
     }
 }
@@ -357,7 +385,7 @@ Parameters:
 hasher - The hash function for key type K
 eqer - The equality function for key type K
 */
-fn hashmap<K: const, V: copy>(hasher: hashfn<K>, eqer: eqfn<K>)
+fn hashmap<K: const, V: copy>(+hasher: hashfn<K>, +eqer: eqfn<K>)
         -> hashmap<K, V> {
     chained::mk(hasher, eqer)
 }
@@ -369,7 +397,8 @@ fn str_hash<V: copy>() -> hashmap<~str, V> {
 
 /// Construct a hashmap for boxed string keys
 fn box_str_hash<V: copy>() -> hashmap<@~str, V> {
-    return hashmap(|x: @~str| str::hash(*x), |x,y| str::eq(*x,*y));
+    hashmap(|x: &@~str| str::hash(&**x),
+            |x: &@~str, y: &@~str| str::eq(&**x, &**y))
 }
 
 /// Construct a hashmap for byte string keys
@@ -388,13 +417,14 @@ fn uint_hash<V: copy>() -> hashmap<uint, V> {
 }
 
 /// Convenience function for adding keys to a hashmap with nil type keys
-fn set_add<K: const copy>(set: set<K>, key: K) -> bool {
-    return set.insert(key, ());
+fn set_add<K: const copy>(set: set<K>, +key: K) -> bool {
+    set.insert(key, ())
 }
 
 /// Convert a set into a vector.
 fn vec_from_set<T: copy>(s: set<T>) -> ~[T] {
     let mut v = ~[];
+    vec::reserve(v, s.size());
     do s.each_key() |k| {
         vec::push(v, k);
         true
@@ -403,8 +433,8 @@ fn vec_from_set<T: copy>(s: set<T>) -> ~[T] {
 }
 
 /// Construct a hashmap from a vector
-fn hash_from_vec<K: const copy, V: copy>(hasher: hashfn<K>, eqer: eqfn<K>,
-                                         items: ~[(K, V)]) -> hashmap<K, V> {
+fn hash_from_vec<K: const copy, V: copy>(+hasher: hashfn<K>, +eqer: eqfn<K>,
+                                         items: &[(K, V)]) -> hashmap<K, V> {
     let map = hashmap(hasher, eqer);
     do vec::iter(items) |item| {
         let (key, value) = item;
@@ -414,22 +444,22 @@ fn hash_from_vec<K: const copy, V: copy>(hasher: hashfn<K>, eqer: eqfn<K>,
 }
 
 /// Construct a hashmap from a vector with string keys
-fn hash_from_strs<V: copy>(items: ~[(~str, V)]) -> hashmap<~str, V> {
+fn hash_from_strs<V: copy>(items: &[(~str, V)]) -> hashmap<~str, V> {
     hash_from_vec(str::hash, str::eq, items)
 }
 
 /// Construct a hashmap from a vector with byte keys
-fn hash_from_bytes<V: copy>(items: ~[(~[u8], V)]) -> hashmap<~[u8], V> {
+fn hash_from_bytes<V: copy>(items: &[(~[u8], V)]) -> hashmap<~[u8], V> {
     hash_from_vec(vec::u8::hash, vec::u8::eq, items)
 }
 
 /// Construct a hashmap from a vector with int keys
-fn hash_from_ints<V: copy>(items: ~[(int, V)]) -> hashmap<int, V> {
+fn hash_from_ints<V: copy>(items: &[(int, V)]) -> hashmap<int, V> {
     hash_from_vec(int::hash, int::eq, items)
 }
 
 /// Construct a hashmap from a vector with uint keys
-fn hash_from_uints<V: copy>(items: ~[(uint, V)]) -> hashmap<uint, V> {
+fn hash_from_uints<V: copy>(items: &[(uint, V)]) -> hashmap<uint, V> {
     hash_from_vec(uint::hash, uint::eq, items)
 }
 
@@ -439,15 +469,15 @@ mod tests {
     #[test]
     fn test_simple() {
         debug!{"*** starting test_simple"};
-        fn eq_uint(&&x: uint, &&y: uint) -> bool { return x == y; }
-        fn uint_id(&&x: uint) -> uint { x }
+        pure fn eq_uint(x: &uint, y: &uint) -> bool { *x == *y }
+        pure fn uint_id(x: &uint) -> uint { *x }
         let hasher_uint: map::hashfn<uint> = uint_id;
         let eqer_uint: map::eqfn<uint> = eq_uint;
         let hasher_str: map::hashfn<~str> = str::hash;
         let eqer_str: map::eqfn<~str> = str::eq;
         debug!{"uint -> uint"};
         let hm_uu: map::hashmap<uint, uint> =
-            map::hashmap::<uint, uint>(hasher_uint, eqer_uint);
+            map::hashmap::<uint, uint>(copy hasher_uint, copy eqer_uint);
         assert (hm_uu.insert(10u, 12u));
         assert (hm_uu.insert(11u, 13u));
         assert (hm_uu.insert(12u, 14u));
@@ -463,7 +493,7 @@ mod tests {
         let twelve: ~str = ~"twelve";
         debug!{"str -> uint"};
         let hm_su: map::hashmap<~str, uint> =
-            map::hashmap::<~str, uint>(hasher_str, eqer_str);
+            map::hashmap::<~str, uint>(copy hasher_str, copy eqer_str);
         assert (hm_su.insert(~"ten", 12u));
         assert (hm_su.insert(eleven, 13u));
         assert (hm_su.insert(~"twelve", 14u));
@@ -477,30 +507,30 @@ mod tests {
         assert (hm_su.get(~"twelve") == 12u);
         debug!{"uint -> str"};
         let hm_us: map::hashmap<uint, ~str> =
-            map::hashmap::<uint, ~str>(hasher_uint, eqer_uint);
+            map::hashmap::<uint, ~str>(copy hasher_uint, copy eqer_uint);
         assert (hm_us.insert(10u, ~"twelve"));
         assert (hm_us.insert(11u, ~"thirteen"));
         assert (hm_us.insert(12u, ~"fourteen"));
-        assert (str::eq(hm_us.get(11u), ~"thirteen"));
-        assert (str::eq(hm_us.get(12u), ~"fourteen"));
-        assert (str::eq(hm_us.get(10u), ~"twelve"));
+        assert hm_us.get(11u) == ~"thirteen";
+        assert hm_us.get(12u) == ~"fourteen";
+        assert hm_us.get(10u) == ~"twelve";
         assert (!hm_us.insert(12u, ~"fourteen"));
-        assert (str::eq(hm_us.get(12u), ~"fourteen"));
+        assert hm_us.get(12u) == ~"fourteen";
         assert (!hm_us.insert(12u, ~"twelve"));
-        assert (str::eq(hm_us.get(12u), ~"twelve"));
+        assert hm_us.get(12u) == ~"twelve";
         debug!{"str -> str"};
         let hm_ss: map::hashmap<~str, ~str> =
-            map::hashmap::<~str, ~str>(hasher_str, eqer_str);
+            map::hashmap::<~str, ~str>(copy hasher_str, copy eqer_str);
         assert (hm_ss.insert(ten, ~"twelve"));
         assert (hm_ss.insert(eleven, ~"thirteen"));
         assert (hm_ss.insert(twelve, ~"fourteen"));
-        assert (str::eq(hm_ss.get(~"eleven"), ~"thirteen"));
-        assert (str::eq(hm_ss.get(~"twelve"), ~"fourteen"));
-        assert (str::eq(hm_ss.get(~"ten"), ~"twelve"));
+        assert hm_ss.get(~"eleven") == ~"thirteen";
+        assert hm_ss.get(~"twelve") == ~"fourteen";
+        assert hm_ss.get(~"ten") == ~"twelve";
         assert (!hm_ss.insert(~"twelve", ~"fourteen"));
-        assert (str::eq(hm_ss.get(~"twelve"), ~"fourteen"));
+        assert hm_ss.get(~"twelve") == ~"fourteen";
         assert (!hm_ss.insert(~"twelve", ~"twelve"));
-        assert (str::eq(hm_ss.get(~"twelve"), ~"twelve"));
+        assert hm_ss.get(~"twelve") == ~"twelve";
         debug!{"*** finished test_simple"};
     }
 
@@ -512,8 +542,8 @@ mod tests {
     fn test_growth() {
         debug!{"*** starting test_growth"};
         let num_to_insert: uint = 64u;
-        fn eq_uint(&&x: uint, &&y: uint) -> bool { return x == y; }
-        fn uint_id(&&x: uint) -> uint { x }
+        pure fn eq_uint(x: &uint, y: &uint) -> bool { *x == *y }
+        pure fn uint_id(x: &uint) -> uint { *x }
         debug!{"uint -> uint"};
         let hasher_uint: map::hashfn<uint> = uint_id;
         let eqer_uint: map::eqfn<uint> = eq_uint;
@@ -560,22 +590,20 @@ mod tests {
             debug!{"get(\"%s\") = \"%s\"",
                    uint::to_str(i, 2u),
                    hm_ss.get(uint::to_str(i, 2u))};
-            assert (str::eq(hm_ss.get(uint::to_str(i, 2u)),
-                            uint::to_str(i * i, 2u)));
+            assert hm_ss.get(uint::to_str(i, 2u)) == uint::to_str(i * i, 2u);
             i += 1u;
         }
         assert (hm_ss.insert(uint::to_str(num_to_insert, 2u),
                              uint::to_str(17u, 2u)));
-        assert (str::eq(hm_ss.get(uint::to_str(num_to_insert, 2u)),
-                        uint::to_str(17u, 2u)));
+        assert hm_ss.get(uint::to_str(num_to_insert, 2u)) ==
+            uint::to_str(17u, 2u);
         debug!{"-----"};
         i = 0u;
         while i < num_to_insert {
             debug!{"get(\"%s\") = \"%s\"",
                    uint::to_str(i, 2u),
                    hm_ss.get(uint::to_str(i, 2u))};
-            assert (str::eq(hm_ss.get(uint::to_str(i, 2u)),
-                            uint::to_str(i * i, 2u)));
+            assert hm_ss.get(uint::to_str(i, 2u)) == uint::to_str(i * i, 2u);
             i += 1u;
         }
         debug!{"*** finished test_growth"};
@@ -585,16 +613,15 @@ mod tests {
     fn test_removal() {
         debug!{"*** starting test_removal"};
         let num_to_insert: uint = 64u;
-        fn eq(&&x: uint, &&y: uint) -> bool { return x == y; }
-        fn hash(&&u: uint) -> uint {
+        fn eq(x: &uint, y: &uint) -> bool { *x == *y }
+        fn hash(u: &uint) -> uint {
             // This hash function intentionally causes collisions between
             // consecutive integer pairs.
-
-            return u / 2u * 2u;
+            *u / 2u * 2u
         }
-        assert (hash(0u) == hash(1u));
-        assert (hash(2u) == hash(3u));
-        assert (hash(0u) != hash(2u));
+        assert (hash(&0u) == hash(&1u));
+        assert (hash(&2u) == hash(&3u));
+        assert (hash(&0u) != hash(&2u));
         let hasher: map::hashfn<uint> = hash;
         let eqer: map::eqfn<uint> = eq;
         let hm: map::hashmap<uint, uint> =
diff --git a/src/libstd/smallintmap.rs b/src/libstd/smallintmap.rs
index 825630cf4a4..b8bdf581218 100644
--- a/src/libstd/smallintmap.rs
+++ b/src/libstd/smallintmap.rs
@@ -74,8 +74,10 @@ impl <V: copy> of map::map<uint, V> for smallintmap<V> {
         insert(self, key, value);
         return !exists;
     }
-    fn remove(&&key: uint) -> option<V> {
-        if key >= self.v.len() { return none; }
+    fn remove(+key: uint) -> option<V> {
+        if key >= self.v.len() {
+            return none;
+        }
         let old = self.v.get_elt(key);
         self.v.set_elt(key, none);
         old
@@ -83,14 +85,16 @@ impl <V: copy> of map::map<uint, V> for smallintmap<V> {
     fn clear() {
         self.v.set(~[mut]);
     }
-    fn contains_key(&&key: uint) -> bool {
+    fn contains_key(+key: uint) -> bool {
         contains_key(self, key)
     }
-    fn get(&&key: uint) -> V { get(self, key) }
-    fn [](&&key: uint) -> V { get(self, key) }
-    fn find(&&key: uint) -> option<V> { find(self, key) }
+    fn contains_key_ref(key: &uint) -> bool {
+        contains_key(self, *key)
+    }
+    fn get(+key: uint) -> V { get(self, key) }
+    fn find(+key: uint) -> option<V> { find(self, key) }
     fn rehash() { fail }
-    fn each(it: fn(&&uint, V) -> bool) {
+    fn each(it: fn(+key: uint, +value: V) -> bool) {
         let mut idx = 0u, l = self.v.len();
         while idx < l {
             alt self.v.get_elt(idx) {
@@ -102,15 +106,29 @@ impl <V: copy> of map::map<uint, V> for smallintmap<V> {
             idx += 1u;
         }
     }
-    fn each_key(it: fn(&&uint) -> bool) {
+    fn each_key(it: fn(+key: uint) -> bool) {
+        self.each(|k, _v| it(k))
+    }
+    fn each_value(it: fn(+value: V) -> bool) {
+        self.each(|_k, v| it(v))
+    }
+    fn each_ref(it: fn(key: &uint, value: &V) -> bool) {
         let mut idx = 0u, l = self.v.len();
         while idx < l {
-            if self.v.get_elt(idx) != none && !it(idx) { return; }
+            alt self.v.get_elt(idx) {
+              some(elt) {
+                if !it(&idx, &elt) { break; }
+              }
+              none { }
+            }
             idx += 1u;
         }
     }
-    fn each_value(it: fn(V) -> bool) {
-        self.each(|_i, v| it(v));
+    fn each_key_ref(blk: fn(key: &uint) -> bool) {
+        self.each_ref(|k, _v| blk(k))
+    }
+    fn each_value_ref(blk: fn(value: &V) -> bool) {
+        self.each_ref(|_k, v| blk(v))
     }
 }
 
diff --git a/src/libstd/sort.rs b/src/libstd/sort.rs
index 84aa3c26482..5cd2a8aa532 100644
--- a/src/libstd/sort.rs
+++ b/src/libstd/sort.rs
@@ -1,13 +1,13 @@
 //! Sorting methods
 import vec::{len, push};
-import int::{eq, ord};
+import core::cmp::{eq, ord};
 
 export le;
 export merge_sort;
 export quick_sort;
 export quick_sort3;
 
-type le<T> = fn(T, T) -> bool;
+type le<T> = pure fn(v1: &T, v2: &T) -> bool;
 
 /**
  * Merge sort. Returns a new vector containing the sorted list.
@@ -43,7 +43,7 @@ fn merge_sort<T: copy>(le: le<T>, v: ~[const T]) -> ~[T] {
         let b_len = len(b);
         let mut b_ix = 0u;
         while a_ix < a_len && b_ix < b_len {
-            if le(a[a_ix], b[b_ix]) {
+            if le(&a[a_ix], &b[b_ix]) {
                 vec::push(rs, a[a_ix]);
                 a_ix += 1u;
             } else { vec::push(rs, b[b_ix]); b_ix += 1u; }
@@ -61,7 +61,7 @@ fn part<T: copy>(compare_func: le<T>, arr: ~[mut T], left: uint,
     let mut storage_index: uint = left;
     let mut i: uint = left;
     while i < right {
-        if compare_func(copy arr[i], pivot_value) {
+        if compare_func(&arr[i], &pivot_value) {
             arr[i] <-> arr[storage_index];
             storage_index += 1u;
         }
@@ -105,19 +105,19 @@ fn qsort3<T: copy>(compare_func_lt: le<T>, compare_func_eq: le<T>,
     let mut q: int = j;
     loop {
         i += 1;
-        while compare_func_lt(copy arr[i], v) { i += 1; }
+        while compare_func_lt(&arr[i], &v) { i += 1; }
         j -= 1;
-        while compare_func_lt(v, copy arr[j]) {
+        while compare_func_lt(&v, &arr[j]) {
             if j == left { break; }
             j -= 1;
         }
         if i >= j { break; }
         arr[i] <-> arr[j];
-        if compare_func_eq(copy arr[i], v) {
+        if compare_func_eq(&arr[i], &v) {
             p += 1;
             arr[p] <-> arr[i];
         }
-        if compare_func_eq(v, copy arr[j]) {
+        if compare_func_eq(&v, &arr[j]) {
             q -= 1;
             arr[j] <-> arr[q];
         }
@@ -154,9 +154,8 @@ fn qsort3<T: copy>(compare_func_lt: le<T>, compare_func_eq: le<T>,
  * This is an unstable sort.
  */
 fn quick_sort3<T: copy ord eq>(arr: ~[mut T]) {
-    if len::<T>(arr) == 0u { return; }
-    qsort3::<T>(|x, y| x.lt(y), |x, y| x.eq(y), arr, 0,
-                (len::<T>(arr) as int) - 1);
+    if arr.len() <= 1 { return; }
+    qsort3(core::cmp::lt, core::cmp::eq, arr, 0, (arr.len() - 1) as int);
 }
 
 #[cfg(test)]
@@ -202,9 +201,8 @@ mod test_qsort3 {
 mod test_qsort {
     fn check_sort(v1: ~[mut int], v2: ~[mut int]) {
         let len = vec::len::<int>(v1);
-        fn leual(&&a: int, &&b: int) -> bool { return a <= b; }
-        let f = leual;
-        quick_sort::<int>(f, v1);
+        pure fn leual(a: &int, b: &int) -> bool { *a <= *b }
+        quick_sort::<int>(leual, v1);
         let mut i = 0u;
         while i < len {
             log(debug, v2[i]);
@@ -245,8 +243,7 @@ mod test_qsort {
 
         let expected = ~[1, 2, 3];
 
-        fn le(&&a: int, &&b: int) -> bool { int::le(a, b) }
-        sort::quick_sort(le, names);
+        sort::quick_sort(int::le, names);
 
         let immut_names = vec::from_mut(names);
 
@@ -264,7 +261,7 @@ mod tests {
 
     fn check_sort(v1: ~[int], v2: ~[int]) {
         let len = vec::len::<int>(v1);
-        fn le(&&a: int, &&b: int) -> bool { return a <= b; }
+        pure fn le(a: &int, b: &int) -> bool { *a <= *b }
         let f = le;
         let v3 = merge_sort::<int>(f, v1);
         let mut i = 0u;
@@ -294,7 +291,7 @@ mod tests {
 
     #[test]
     fn test_merge_sort_mutable() {
-        fn le(&&a: int, &&b: int) -> bool { return a <= b; }
+        pure fn le(a: &int, b: &int) -> bool { *a <= *b }
         let v1 = ~[mut 3, 2, 1];
         let v2 = merge_sort(le, v1);
         assert v2 == ~[1, 2, 3];
diff --git a/src/libstd/term.rs b/src/libstd/term.rs
index 0667acb8dd2..20fb9622e3d 100644
--- a/src/libstd/term.rs
+++ b/src/libstd/term.rs
@@ -38,7 +38,7 @@ fn color_supported() -> bool {
     return alt os::getenv(~"TERM") {
           option::some(env) {
             for vec::each(supported_terms) |term| {
-                if str::eq(term, env) { return true; }
+                if term == env { return true; }
             }
             false
           }
diff --git a/src/libstd/test.rs b/src/libstd/test.rs
index 5d503e4c15f..8d2673df5c6 100644
--- a/src/libstd/test.rs
+++ b/src/libstd/test.rs
@@ -372,13 +372,12 @@ fn filter_tests(opts: test_opts,
     };
 
     // Sort the tests alphabetically
-    filtered =
-        {
-            fn lteq(t1: test_desc, t2: test_desc) -> bool {
-                str::le(t1.name, t2.name)
-            }
-        sort::merge_sort(|x,y| lteq(x, y), filtered)
-        };
+    filtered = {
+        pure fn lteq(t1: &test_desc, t2: &test_desc) -> bool {
+            str::le(&t1.name, &t2.name)
+        }
+        sort::merge_sort(lteq, filtered)
+    };
 
     return filtered;
 }
@@ -486,7 +485,7 @@ mod tests {
         let args = ~[~"progname", ~"filter"];
         let opts = alt parse_opts(args) { either::left(o) { o }
           _ { fail ~"Malformed arg in first_free_arg_should_be_a_filter"; } };
-        assert (str::eq(~"filter", option::get(opts.filter)));
+        assert ~"filter" == option::get(opts.filter);
     }
 
     #[test]