]> git.lizzy.rs Git - rust.git/commitdiff
Merge remote-tracking branch 'bstrie/rimov' into incoming
authorBrian Anderson <banderson@mozilla.com>
Mon, 4 Feb 2013 19:07:36 +0000 (11:07 -0800)
committerBrian Anderson <banderson@mozilla.com>
Mon, 4 Feb 2013 19:58:30 +0000 (11:58 -0800)
Conflicts:
src/libsyntax/parse/parser.rs
src/test/bench/graph500-bfs.rs
src/test/bench/sudoku.rs
src/test/run-pass/borrowck-mut-vec-as-imm-slice.rs
src/test/run-pass/empty-mutable-vec.rs
src/test/run-pass/foreach-nested.rs
src/test/run-pass/swap-2.rs

33 files changed:
1  2 
doc/rust.md
doc/tutorial.md
src/libfuzzer/rand_util.rs
src/librustdoc/markdown_writer.rs
src/libstd/bitv.rs
src/libstd/net_tcp.rs
src/libstd/oldmap.rs
src/libstd/rope.rs
src/libstd/sort.rs
src/libstd/sync.rs
src/libsyntax/attr.rs
src/libsyntax/parse/parser.rs
src/libsyntax/print/pp.rs
src/test/bench/graph500-bfs.rs
src/test/bench/sudoku.rs
src/test/run-pass/borrowck-mut-vec-as-imm-slice.rs
src/test/run-pass/coerce-reborrow-imm-vec-arg.rs
src/test/run-pass/coerce-reborrow-imm-vec-rcvr.rs
src/test/run-pass/coerce-reborrow-mut-vec-arg.rs
src/test/run-pass/coerce-reborrow-mut-vec-rcvr.rs
src/test/run-pass/empty-mutable-vec.rs
src/test/run-pass/explicit-self-objects-ext-1.rs
src/test/run-pass/explicit-self-objects-ext-2.rs
src/test/run-pass/explicit-self-objects-ext-3.rs
src/test/run-pass/explicit-self-objects-ext-4.rs
src/test/run-pass/foreach-nested.rs
src/test/run-pass/impl-variance.rs
src/test/run-pass/issue-3563-3.rs
src/test/run-pass/log-linearized.rs
src/test/run-pass/maybe-mutable.rs
src/test/run-pass/mutable-vec-drop.rs
src/test/run-pass/rcvr-borrowed-to-slice.rs
src/test/run-pass/swap-2.rs

diff --cc doc/rust.md
Simple merge
diff --cc doc/tutorial.md
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
index e32043a72254347b09acb96a18834f28e7d718fc,0000000000000000000000000000000000000000..a4d4a4e806b0dd566b0dd64e486fa5ab0d625e5c
mode 100644,000000..100644
--- /dev/null
@@@ -1,702 -1,0 +1,702 @@@
-         mut chains: ~[mut Option<@Entry<K,V>>]
 +// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
 +// file at the top-level directory of this distribution and at
 +// http://rust-lang.org/COPYRIGHT.
 +//
 +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
 +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
 +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
 +// option. This file may not be copied, modified, or distributed
 +// except according to those terms.
 +
 +//! A map type - **deprecated**, use `core::hashmap` instead
 +#[forbid(deprecated_mode)];
 +
 +use core::container::{Container, Mutable, Map};
 +use core::cmp::Eq;
 +use core::hash::Hash;
 +use core::io::WriterUtil;
 +use core::io;
 +use core::ops;
 +use core::to_str::ToStr;
 +use core::prelude::*;
 +use core::to_bytes::IterBytes;
 +use core::uint;
 +use core::vec;
 +
 +/// A convenience type to treat a hashmap as a set
 +pub type Set<K> = HashMap<K, ()>;
 +
 +pub type HashMap<K, V> = chained::T<K, V>;
 +
 +pub mod util {
 +    pub struct Rational {
 +        // : int::positive(*.den);
 +        num: int,
 +        den: int,
 +    }
 +
 +    pub pure fn rational_leq(x: Rational, y: Rational) -> bool {
 +        // NB: Uses the fact that rationals have positive denominators WLOG:
 +
 +        x.num * y.den <= y.num * x.den
 +    }
 +}
 +
 +
 +// FIXME (#2344): package this up and export it as a datatype usable for
 +// external code that doesn't want to pay the cost of a box.
 +pub mod chained {
 +    use super::util;
 +
 +    use core::io;
 +    use core::ops;
 +    use core::option;
 +    use core::prelude::*;
 +    use core::uint;
 +    use core::vec;
 +
 +    const initial_capacity: uint = 32u; // 2^5
 +
 +    struct Entry<K, V> {
 +        hash: uint,
 +        key: K,
 +        value: V,
 +        mut next: Option<@Entry<K, V>>
 +    }
 +
 +    struct HashMap_<K, V> {
 +        mut count: uint,
-             let new_chains = chains(n_new_chains);
++        mut chains: ~[Option<@Entry<K,V>>]
 +    }
 +
 +    pub type T<K, V> = @HashMap_<K, V>;
 +
 +    enum SearchResult<K, V> {
 +        NotFound,
 +        FoundFirst(uint, @Entry<K,V>),
 +        FoundAfter(@Entry<K,V>, @Entry<K,V>)
 +    }
 +
 +    priv impl<K:Eq IterBytes Hash, V: Copy> T<K, V> {
 +        pure fn search_rem(k: &K, h: uint, idx: uint,
 +                           e_root: @Entry<K,V>) -> SearchResult<K,V> {
 +            let mut e0 = e_root;
 +            let mut comp = 1u;   // for logging
 +            loop {
 +                match copy e0.next {
 +                  None => {
 +                    debug!("search_tbl: absent, comp %u, hash %u, idx %u",
 +                           comp, h, idx);
 +                    return NotFound;
 +                  }
 +                  Some(e1) => {
 +                    comp += 1u;
 +                    unsafe {
 +                        if e1.hash == h && e1.key == *k {
 +                            debug!("search_tbl: present, comp %u, \
 +                                    hash %u, idx %u",
 +                                   comp, h, idx);
 +                            return FoundAfter(e0, e1);
 +                        } else {
 +                            e0 = e1;
 +                        }
 +                    }
 +                  }
 +                }
 +            };
 +        }
 +
 +        pure fn search_tbl(k: &K, h: uint) -> SearchResult<K,V> {
 +            let idx = h % vec::len(self.chains);
 +            match copy self.chains[idx] {
 +              None => {
 +                debug!("search_tbl: none, comp %u, hash %u, idx %u",
 +                       0u, h, idx);
 +                return NotFound;
 +              }
 +              Some(e) => {
 +                unsafe {
 +                    if e.hash == h && e.key == *k {
 +                        debug!("search_tbl: present, comp %u, hash %u, \
 +                                idx %u", 1u, h, idx);
 +                        return FoundFirst(idx, e);
 +                    } else {
 +                        return self.search_rem(k, h, idx, e);
 +                    }
 +                }
 +              }
 +            }
 +        }
 +
 +        fn rehash() {
 +            let n_old_chains = self.chains.len();
 +            let n_new_chains: uint = uint::next_power_of_two(n_old_chains+1u);
-     fn chains<K,V>(nchains: uint) -> ~[mut Option<@Entry<K,V>>] {
-         vec::cast_to_mut(vec::from_elem(nchains, None))
++            let mut 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] = Some(entry);
 +            }
 +            self.chains = move new_chains;
 +        }
 +
 +        pure fn each_entry(blk: fn(@Entry<K,V>) -> bool) {
 +            // 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 = match chain {
 +                      None => break,
 +                      Some(entry) => {
 +                        let next = entry.next;
 +                        if !blk(entry) { return; }
 +                        next
 +                      }
 +                    }
 +                }
 +                i += 1u;
 +            }
 +        }
 +    }
 +
 +    impl<K: Eq IterBytes Hash, V> T<K, V>: Container {
 +        pure fn len(&self) -> uint { self.count }
 +        pure fn is_empty(&self) -> bool { self.count == 0 }
 +    }
 +
 +    impl<K: Eq IterBytes Hash, V> T<K, V>: Mutable {
 +        fn clear(&mut self) {
 +            self.count = 0u;
 +            self.chains = chains(initial_capacity);
 +        }
 +    }
 +
 +    impl<K:Eq IterBytes Hash Copy, V: Copy> T<K, V> {
 +        pure fn contains_key_ref(&self, k: &K) -> bool {
 +            let hash = k.hash_keyed(0,0) as uint;
 +            match self.search_tbl(k, hash) {
 +              NotFound => false,
 +              FoundFirst(*) | FoundAfter(*) => true
 +            }
 +        }
 +
 +        fn insert(k: K, v: V) -> bool {
 +            let hash = k.hash_keyed(0,0) as uint;
 +            match self.search_tbl(&k, hash) {
 +              NotFound => {
 +                self.count += 1u;
 +                let idx = hash % vec::len(self.chains);
 +                let old_chain = self.chains[idx];
 +                self.chains[idx] = Some(@Entry {
 +                    hash: hash,
 +                    key: k,
 +                    value: v,
 +                    next: old_chain});
 +
 +                // consider rehashing if more 3/4 full
 +                let nchains = vec::len(self.chains);
 +                let load = util::Rational {
 +                    num: (self.count + 1u) as int,
 +                    den: nchains as int,
 +                };
 +                if !util::rational_leq(load, util::Rational {num:3, den:4}) {
 +                    self.rehash();
 +                }
 +
 +                return true;
 +              }
 +              FoundFirst(idx, entry) => {
 +                self.chains[idx] = Some(@Entry {
 +                    hash: hash,
 +                    key: k,
 +                    value: v,
 +                    next: entry.next});
 +                return false;
 +              }
 +              FoundAfter(prev, entry) => {
 +                prev.next = Some(@Entry {
 +                    hash: hash,
 +                    key: k,
 +                    value: v,
 +                    next: entry.next});
 +                return false;
 +              }
 +            }
 +        }
 +
 +        pure fn find(&self, k: K) -> Option<V> {
 +            unsafe {
 +                match self.search_tbl(&k, k.hash_keyed(0,0) as uint) {
 +                  NotFound => None,
 +                  FoundFirst(_, entry) => Some(entry.value),
 +                  FoundAfter(_, entry) => Some(entry.value)
 +                }
 +            }
 +        }
 +
 +        fn update_with_key(key: K, newval: V, ff: fn(K, V, V) -> V) -> bool {
 +/*
 +            match self.find(key) {
 +                None            => return self.insert(key, val),
 +                Some(copy orig) => return self.insert(key, ff(key, orig, val))
 +            }
 +*/
 +
 +            let hash = key.hash_keyed(0,0) as uint;
 +            match self.search_tbl(&key, hash) {
 +              NotFound => {
 +                self.count += 1u;
 +                let idx = hash % vec::len(self.chains);
 +                let old_chain = self.chains[idx];
 +                self.chains[idx] = Some(@Entry {
 +                    hash: hash,
 +                    key: key,
 +                    value: newval,
 +                    next: old_chain});
 +
 +                // consider rehashing if more 3/4 full
 +                let nchains = vec::len(self.chains);
 +                let load = util::Rational {
 +                    num: (self.count + 1u) as int,
 +                    den: nchains as int,
 +                };
 +                if !util::rational_leq(load, util::Rational {num:3, den:4}) {
 +                    self.rehash();
 +                }
 +
 +                return true;
 +              }
 +              FoundFirst(idx, entry) => {
 +                self.chains[idx] = Some(@Entry {
 +                    hash: hash,
 +                    key: key,
 +                    value: ff(key, entry.value, newval),
 +                    next: entry.next});
 +                return false;
 +              }
 +              FoundAfter(prev, entry) => {
 +                prev.next = Some(@Entry {
 +                    hash: hash,
 +                    key: key,
 +                    value: ff(key, entry.value, newval),
 +                    next: entry.next});
 +                return false;
 +              }
 +            }
 +        }
 +
 +        fn update(key: K, newval: V, ff: fn(V, V) -> V) -> bool {
 +            return self.update_with_key(key, newval, |_k, v, v1| ff(v,v1));
 +        }
 +
 +        pure fn get(&self, k: K) -> V {
 +            let opt_v = self.find(k);
 +            if opt_v.is_none() {
 +                die!(fmt!("Key not found in table: %?", k));
 +            }
 +            option::unwrap(move opt_v)
 +        }
 +
 +        fn remove(k: &K) -> bool {
 +            match self.search_tbl(k, k.hash_keyed(0,0) as uint) {
 +              NotFound => false,
 +              FoundFirst(idx, entry) => {
 +                self.count -= 1u;
 +                self.chains[idx] = entry.next;
 +                true
 +              }
 +              FoundAfter(eprev, entry) => {
 +                self.count -= 1u;
 +                eprev.next = entry.next;
 +                true
 +              }
 +            }
 +        }
 +
 +        pure fn each_ref(&self, blk: fn(key: &K, value: &V) -> bool) {
 +            for self.each_entry |entry| {
 +                if !blk(&entry.key, &entry.value) { break; }
 +            }
 +        }
 +
 +        pure fn each_key_ref(&self, blk: fn(key: &K) -> bool) {
 +            self.each_ref(|k, _v| blk(k))
 +        }
 +
 +        pure fn each_value_ref(&self, blk: fn(value: &V) -> bool) {
 +            self.each_ref(|_k, v| blk(v))
 +        }
 +    }
 +
 +    impl<K:Eq IterBytes Hash Copy ToStr, V: ToStr Copy> T<K, V> {
 +        fn to_writer(wr: io::Writer) {
 +            if self.count == 0u {
 +                wr.write_str(~"{}");
 +                return;
 +            }
 +
 +            wr.write_str(~"{ ");
 +            let mut first = true;
 +            for self.each_entry |entry| {
 +                if !first {
 +                    wr.write_str(~", ");
 +                }
 +                first = false;
 +                wr.write_str(entry.key.to_str());
 +                wr.write_str(~": ");
 +                wr.write_str((copy entry.value).to_str());
 +            };
 +            wr.write_str(~" }");
 +        }
 +    }
 +
 +    impl<K:Eq IterBytes Hash Copy ToStr, V: ToStr Copy> T<K, V>: ToStr {
 +        pure fn to_str(&self) -> ~str {
 +            unsafe {
 +                // Meh -- this should be safe
 +                do io::with_str_writer |wr| { self.to_writer(wr) }
 +            }
 +        }
 +    }
 +
 +    impl<K:Eq IterBytes Hash Copy, V: Copy> T<K, V>: ops::Index<K, V> {
 +        pure fn index(&self, k: K) -> V {
 +            unsafe {
 +                self.get(k)
 +            }
 +        }
 +    }
 +
++    fn chains<K,V>(nchains: uint) -> ~[Option<@Entry<K,V>>] {
++        vec::from_elem(nchains, None)
 +    }
 +
 +    pub fn mk<K:Eq IterBytes Hash, V: Copy>() -> T<K,V> {
 +        let slf: T<K, V> = @HashMap_ {count: 0u,
 +                                      chains: chains(initial_capacity)};
 +        slf
 +    }
 +}
 +
 +/*
 +Function: hashmap
 +
 +Construct a hashmap.
 +*/
 +pub fn HashMap<K:Eq IterBytes Hash Const, V: Copy>()
 +        -> HashMap<K, V> {
 +    chained::mk()
 +}
 +
 +/// Convenience function for adding keys to a hashmap with nil type keys
 +pub fn set_add<K:Eq IterBytes Hash Const Copy>(set: Set<K>, key: K) -> bool {
 +    set.insert(key, ())
 +}
 +
 +/// Convert a set into a vector.
 +pub pure fn vec_from_set<T:Eq IterBytes Hash Copy>(s: Set<T>) -> ~[T] {
 +    do vec::build_sized(s.len()) |push| {
 +        for s.each_key_ref() |&k| {
 +            push(k);
 +        }
 +    }
 +}
 +
 +/// Construct a hashmap from a vector
 +pub fn hash_from_vec<K: Eq IterBytes Hash Const Copy, V: Copy>(
 +    items: &[(K, V)]) -> HashMap<K, V> {
 +    let map = HashMap();
 +    for vec::each(items) |item| {
 +        match *item {
 +            (copy key, copy value) => {
 +                map.insert(key, value);
 +            }
 +        }
 +    }
 +    map
 +}
 +
 +#[cfg(test)]
 +mod tests {
 +    use core::option::None;
 +    use core::option;
 +    use core::uint;
 +
 +    use super::*;
 +
 +    #[test]
 +    fn test_simple() {
 +        debug!("*** starting test_simple");
 +        pure fn eq_uint(x: &uint, y: &uint) -> bool { *x == *y }
 +        pure fn uint_id(x: &uint) -> uint { *x }
 +        debug!("uint -> uint");
 +        let hm_uu: HashMap<uint, uint> =
 +            HashMap::<uint, uint>();
 +        assert (hm_uu.insert(10u, 12u));
 +        assert (hm_uu.insert(11u, 13u));
 +        assert (hm_uu.insert(12u, 14u));
 +        assert (hm_uu.get(11u) == 13u);
 +        assert (hm_uu.get(12u) == 14u);
 +        assert (hm_uu.get(10u) == 12u);
 +        assert (!hm_uu.insert(12u, 14u));
 +        assert (hm_uu.get(12u) == 14u);
 +        assert (!hm_uu.insert(12u, 12u));
 +        assert (hm_uu.get(12u) == 12u);
 +        let ten: ~str = ~"ten";
 +        let eleven: ~str = ~"eleven";
 +        let twelve: ~str = ~"twelve";
 +        debug!("str -> uint");
 +        let hm_su: HashMap<~str, uint> =
 +            HashMap::<~str, uint>();
 +        assert (hm_su.insert(~"ten", 12u));
 +        assert (hm_su.insert(eleven, 13u));
 +        assert (hm_su.insert(~"twelve", 14u));
 +        assert (hm_su.get(eleven) == 13u);
 +        assert (hm_su.get(~"eleven") == 13u);
 +        assert (hm_su.get(~"twelve") == 14u);
 +        assert (hm_su.get(~"ten") == 12u);
 +        assert (!hm_su.insert(~"twelve", 14u));
 +        assert (hm_su.get(~"twelve") == 14u);
 +        assert (!hm_su.insert(~"twelve", 12u));
 +        assert (hm_su.get(~"twelve") == 12u);
 +        debug!("uint -> str");
 +        let hm_us: HashMap<uint, ~str> =
 +            HashMap::<uint, ~str>();
 +        assert (hm_us.insert(10u, ~"twelve"));
 +        assert (hm_us.insert(11u, ~"thirteen"));
 +        assert (hm_us.insert(12u, ~"fourteen"));
 +        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 hm_us.get(12u) == ~"fourteen";
 +        assert (!hm_us.insert(12u, ~"twelve"));
 +        assert hm_us.get(12u) == ~"twelve";
 +        debug!("str -> str");
 +        let hm_ss: HashMap<~str, ~str> =
 +            HashMap::<~str, ~str>();
 +        assert (hm_ss.insert(ten, ~"twelve"));
 +        assert (hm_ss.insert(eleven, ~"thirteen"));
 +        assert (hm_ss.insert(twelve, ~"fourteen"));
 +        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 hm_ss.get(~"twelve") == ~"fourteen";
 +        assert (!hm_ss.insert(~"twelve", ~"twelve"));
 +        assert hm_ss.get(~"twelve") == ~"twelve";
 +        debug!("*** finished test_simple");
 +    }
 +
 +
 +    /**
 +    * Force map growth
 +    */
 +    #[test]
 +    fn test_growth() {
 +        debug!("*** starting test_growth");
 +        let num_to_insert: uint = 64u;
 +        pure fn eq_uint(x: &uint, y: &uint) -> bool { *x == *y }
 +        pure fn uint_id(x: &uint) -> uint { *x }
 +        debug!("uint -> uint");
 +        let hm_uu: HashMap<uint, uint> =
 +            HashMap::<uint, uint>();
 +        let mut i: uint = 0u;
 +        while i < num_to_insert {
 +            assert (hm_uu.insert(i, i * i));
 +            debug!("inserting %u -> %u", i, i*i);
 +            i += 1u;
 +        }
 +        debug!("-----");
 +        i = 0u;
 +        while i < num_to_insert {
 +            debug!("get(%u) = %u", i, hm_uu.get(i));
 +            assert (hm_uu.get(i) == i * i);
 +            i += 1u;
 +        }
 +        assert (hm_uu.insert(num_to_insert, 17u));
 +        assert (hm_uu.get(num_to_insert) == 17u);
 +        debug!("-----");
 +        i = 0u;
 +        while i < num_to_insert {
 +            debug!("get(%u) = %u", i, hm_uu.get(i));
 +            assert (hm_uu.get(i) == i * i);
 +            i += 1u;
 +        }
 +        debug!("str -> str");
 +        let hm_ss: HashMap<~str, ~str> =
 +            HashMap::<~str, ~str>();
 +        i = 0u;
 +        while i < num_to_insert {
 +            assert hm_ss.insert(uint::to_str_radix(i, 2u),
 +                                uint::to_str_radix(i * i, 2u));
 +            debug!("inserting \"%s\" -> \"%s\"",
 +                   uint::to_str_radix(i, 2u),
 +                   uint::to_str_radix(i*i, 2u));
 +            i += 1u;
 +        }
 +        debug!("-----");
 +        i = 0u;
 +        while i < num_to_insert {
 +            debug!("get(\"%s\") = \"%s\"",
 +                   uint::to_str_radix(i, 2u),
 +                   hm_ss.get(uint::to_str_radix(i, 2u)));
 +            assert hm_ss.get(uint::to_str_radix(i, 2u)) ==
 +                             uint::to_str_radix(i * i, 2u);
 +            i += 1u;
 +        }
 +        assert (hm_ss.insert(uint::to_str_radix(num_to_insert, 2u),
 +                             uint::to_str_radix(17u, 2u)));
 +        assert hm_ss.get(uint::to_str_radix(num_to_insert, 2u)) ==
 +            uint::to_str_radix(17u, 2u);
 +        debug!("-----");
 +        i = 0u;
 +        while i < num_to_insert {
 +            debug!("get(\"%s\") = \"%s\"",
 +                   uint::to_str_radix(i, 2u),
 +                   hm_ss.get(uint::to_str_radix(i, 2u)));
 +            assert hm_ss.get(uint::to_str_radix(i, 2u)) ==
 +                             uint::to_str_radix(i * i, 2u);
 +            i += 1u;
 +        }
 +        debug!("*** finished test_growth");
 +    }
 +
 +    #[test]
 +    fn test_removal() {
 +        debug!("*** starting test_removal");
 +        let num_to_insert: uint = 64u;
 +        let hm: HashMap<uint, uint> =
 +            HashMap::<uint, uint>();
 +        let mut i: uint = 0u;
 +        while i < num_to_insert {
 +            assert (hm.insert(i, i * i));
 +            debug!("inserting %u -> %u", i, i*i);
 +            i += 1u;
 +        }
 +        assert (hm.len() == num_to_insert);
 +        debug!("-----");
 +        debug!("removing evens");
 +        i = 0u;
 +        while i < num_to_insert {
 +            let v = hm.remove(&i);
 +            assert v;
 +            i += 2u;
 +        }
 +        assert (hm.len() == num_to_insert / 2u);
 +        debug!("-----");
 +        i = 1u;
 +        while i < num_to_insert {
 +            debug!("get(%u) = %u", i, hm.get(i));
 +            assert (hm.get(i) == i * i);
 +            i += 2u;
 +        }
 +        debug!("-----");
 +        i = 1u;
 +        while i < num_to_insert {
 +            debug!("get(%u) = %u", i, hm.get(i));
 +            assert (hm.get(i) == i * i);
 +            i += 2u;
 +        }
 +        debug!("-----");
 +        i = 0u;
 +        while i < num_to_insert {
 +            assert (hm.insert(i, i * i));
 +            debug!("inserting %u -> %u", i, i*i);
 +            i += 2u;
 +        }
 +        assert (hm.len() == num_to_insert);
 +        debug!("-----");
 +        i = 0u;
 +        while i < num_to_insert {
 +            debug!("get(%u) = %u", i, hm.get(i));
 +            assert (hm.get(i) == i * i);
 +            i += 1u;
 +        }
 +        debug!("-----");
 +        assert (hm.len() == num_to_insert);
 +        i = 0u;
 +        while i < num_to_insert {
 +            debug!("get(%u) = %u", i, hm.get(i));
 +            assert (hm.get(i) == i * i);
 +            i += 1u;
 +        }
 +        debug!("*** finished test_removal");
 +    }
 +
 +    #[test]
 +    fn test_contains_key() {
 +        let key = ~"k";
 +        let map = HashMap::<~str, ~str>();
 +        assert (!map.contains_key_ref(&key));
 +        map.insert(key, ~"val");
 +        assert (map.contains_key_ref(&key));
 +    }
 +
 +    #[test]
 +    fn test_find() {
 +        let key = ~"k";
 +        let map = HashMap::<~str, ~str>();
 +        assert (option::is_none(&map.find(key)));
 +        map.insert(key, ~"val");
 +        assert (option::get(map.find(key)) == ~"val");
 +    }
 +
 +    #[test]
 +    fn test_clear() {
 +        let key = ~"k";
 +        let mut map = HashMap::<~str, ~str>();
 +        map.insert(key, ~"val");
 +        assert (map.len() == 1);
 +        assert (map.contains_key_ref(&key));
 +        map.clear();
 +        assert (map.len() == 0);
 +        assert (!map.contains_key_ref(&key));
 +    }
 +
 +    #[test]
 +    fn test_hash_from_vec() {
 +        let map = hash_from_vec(~[
 +            (~"a", 1),
 +            (~"b", 2),
 +            (~"c", 3)
 +        ]);
 +        assert map.len() == 3u;
 +        assert map.get(~"a") == 1;
 +        assert map.get(~"b") == 2;
 +        assert map.get(~"c") == 3;
 +    }
 +
 +    #[test]
 +    fn test_update_with_key() {
 +        let map = HashMap::<~str, uint>();
 +
 +        // given a new key, initialize it with this new count, given
 +        // given an existing key, add more to its count
 +        fn addMoreToCount(_k: ~str, v0: uint, v1: uint) -> uint {
 +            v0 + v1
 +        }
 +
 +        fn addMoreToCount_simple(v0: uint, v1: uint) -> uint {
 +            v0 + v1
 +        }
 +
 +        // count the number of several types of animal,
 +        // adding in groups as we go
 +        map.update(~"cat",      1, addMoreToCount_simple);
 +        map.update_with_key(~"mongoose", 1, addMoreToCount);
 +        map.update(~"cat",      7, addMoreToCount_simple);
 +        map.update_with_key(~"ferret",   3, addMoreToCount);
 +        map.update_with_key(~"cat",      2, addMoreToCount);
 +
 +        // check the total counts
 +        assert 10 == option::get(map.find(~"cat"));
 +        assert  3 == option::get(map.find(~"ferret"));
 +        assert  1 == option::get(map.find(~"mongoose"));
 +
 +        // sadly, no mythical animals were counted!
 +        assert None == map.find(~"unicorn");
 +    }
 +}
Simple merge
Simple merge
Simple merge
Simple merge
index 3c7250112ab1f74a0128314bc0419671c1923681,5e5537aedeaccb004199401dee72f2da8498cbd5..5cd78dd90490b5f3243e6b584654cb99b57fb0f2
@@@ -194,7 -193,7 +194,7 @@@ pub fn Parser(sess: parse_sess
          token: tok0.tok,
          span: span0,
          last_span: span0,
-         buffer: [mut TokenAndSpan {tok: tok0.tok, sp: span0}, ..4],
 -        mut buffer: [{tok: tok0.tok, sp: span0}, ..4],
++        mut buffer: [TokenAndSpan {tok: tok0.tok, sp: span0}, ..4],
          buffer_start: 0,
          buffer_end: 0,
          tokens_consumed: 0u,
@@@ -214,7 -213,7 +214,7 @@@ pub struct Parser 
      mut token: token::Token,
      mut span: span,
      mut last_span: span,
-     mut buffer: [mut TokenAndSpan * 4],
 -    mut buffer: [{tok: token::Token, sp: span} * 4],
++    mut buffer: [TokenAndSpan * 4],
      mut buffer_start: int,
      mut buffer_end: int,
      mut tokens_consumed: uint,
Simple merge
index 6c5a8a4377e3f8da7d08911958d2346959cce02e,c9430cf7e385fc73b96db5dec93825b93bdd5f21..5ade0c9ed25db9dc342139fc0ace76f4123e45bb
@@@ -120,8 -120,8 +120,8 @@@ fn gen_search_keys(graph: graph, n: uin
   * Nodes that are unreachable have a parent of -1.
   */
  fn bfs(graph: graph, key: node_id) -> bfs_result {
-     let marks : ~[mut node_id]
-         = vec::cast_to_mut(vec::from_elem(vec::len(graph), -1i64));
 -    let mut marks : ~[node_id] 
++    let mut marks : ~[node_id]
+         = vec::from_elem(vec::len(graph), -1i64);
  
      let Q = deque::create();
  
Simple merge
index 22f46b8ff1e11f10560c41f7ad3ce6e092e849ba,a53dab33b978c5417b17b20733fe2f2798f22245..9126a327d861d60349e04b80f75a70eb480a7344
@@@ -18,6 -18,6 +18,6 @@@ fn has_mut_vec(+v: ~[int]) -> int 
      want_slice(v)
  }
  
 -fn main() {
 +pub fn main() {
-     assert has_mut_vec(~[mut 1, 2, 3]) == 6;
+     assert has_mut_vec(~[1, 2, 3]) == 6;
  }
index cc93aba46f447fdf2dd5f206f511f42ca2766f44,2b60bf31beac762b08f7b52db03147f7a4eb8a59..ba7d78ba04f11691098772531302e75dc0cd5cd5
@@@ -16,4 -16,4 +16,4 @@@ fn sum_const(y: &[const int]) -> int 
      sum(y)
  }
  
- pub fn main() {}
 -fn main() {}
++pub fn main() {}
index 58db60dd723d78d821416ac13db18bd1200da6d2,7ab10a0b3e9d5217d78f864f89b2ea18a45d7eaf..d7e649a8fb684e57d2ca22af113fead0c5c81678
@@@ -10,4 -10,4 +10,4 @@@
  
  
  
- pub fn main() { let v: ~[mut int] = ~[mut]; }
 -fn main() { let mut v: ~[int] = ~[]; }
++pub fn main() { let mut v: ~[int] = ~[]; }
index 96c9740d9e149dff6d44fd1dbc2b7a38c7b2de6a,958910376947692093c5fdf904b82b32cbbb27fa..4d7486b72634197f525ea2216564a287588be003
@@@ -14,8 -14,8 +14,8 @@@
  // -*- rust -*-
  fn two(it: fn(int)) { it(0); it(1); }
  
 -fn main() {
 +pub fn main() {
-     let a: ~[mut int] = ~[mut -1, -1, -1, -1];
+     let mut a: ~[int] = ~[-1, -1, -1, -1];
      let mut p: int = 0;
      do two |i| {
          do two |j| { a[p] = 10 * i + j; p += 1; }
Simple merge
Simple merge
Simple merge
index 700923eb8292f781721b5e5391250f4611a193e5,e6b76c3ca591d7ea4d39f31f1a8dff2def8d20c5..c2532369942aa38561956fee2aedd4b75ebeed23
@@@ -18,9 -18,9 +18,9 @@@ fn len(v: ~[const int]) -> uint 
      return i;
  }
  
 -fn main() {
 +pub fn main() {
      let v0 = ~[1, 2, 3, 4, 5];
      log(debug, len(v0));
-     let v1 = ~[mut 1, 2, 3, 4, 5];
+     let mut v1 = ~[1, 2, 3, 4, 5];
      log(debug, len(v1));
  }
index 63550aacb8d3998ef7b332dc3e7b2cea21d2426f,34e7795918c72cdedc684d523086434d7ada6e2f..d807791027f5601fe33b55281d7ef5769d0ff558
@@@ -11,8 -11,8 +11,8 @@@
  
  struct Pair { a: int, b: int}
  
 -fn main() {
 +pub fn main() {
      // This just tests whether the vec leaks its members.
-     let pvec: ~[mut @Pair] =
-         ~[mut @Pair{a: 1, b: 2}, @Pair{a: 3, b: 4}, @Pair{a: 5, b: 6}];
+     let mut pvec: ~[@Pair] =
+         ~[@Pair{a: 1, b: 2}, @Pair{a: 3, b: 4}, @Pair{a: 5, b: 6}];
  }
index d80c7e9558fda351e5422eae957d6fd685b5308f,c2c3d077799fb56b1856038e8789256f4e47f061..0f1ad1624c69c7c04df4f6eba8a5b2087bd9f857
@@@ -8,10 -8,10 +8,10 @@@
  // option. This file may not be copied, modified, or distributed
  // except according to those terms.
  
- fn swap<T>(v: &[mut T], i: int, j: int) { v[i] <-> v[j]; }
+ fn swap<T>(v: &mut [T], i: int, j: int) { v[i] <-> v[j]; }
  
 -fn main() {
 +pub fn main() {
-     let a: ~[mut int] = ~[mut 0, 1, 2, 3, 4, 5, 6];
+     let mut a: ~[int] = ~[0, 1, 2, 3, 4, 5, 6];
      swap(a, 2, 4);
      assert (a[2] == 4);
      assert (a[4] == 2);