From 5d823d46ad5350e095a531d847464f42c5f29261 Mon Sep 17 00:00:00 2001 From: Graydon Hoare Date: Fri, 7 Sep 2012 17:24:02 -0700 Subject: [PATCH] Migrate std::map to use core::hash::Hash trait. Disable many hokey hashes. --- src/libcore/hash.rs | 30 +- src/libcore/to_bytes.rs | 390 ++++++++++-------- src/libstd/map.rs | 120 ++---- src/libsyntax/ast.rs | 94 +++++ src/libsyntax/ast_util.rs | 26 +- src/libsyntax/parse/token.rs | 5 +- src/libsyntax/util/interner.rs | 25 +- src/rustc/lib/llvm.rs | 2 +- src/rustc/middle/borrowck.rs | 18 +- src/rustc/middle/resolve.rs | 2 +- src/rustc/middle/trans/base.rs | 4 +- src/rustc/middle/trans/common.rs | 32 +- src/rustc/middle/trans/shape.rs | 55 +-- src/rustc/middle/ty.rs | 282 ++++++++++++- .../typeck/infer/region_var_bindings.rs | 40 +- .../borrowck-borrowed-uniq-rvalue.rs | 3 +- .../compile-fail/regions-glb-free-free.rs | 1 - src/test/run-fail/unwind-misc-1.rs | 14 +- 18 files changed, 741 insertions(+), 402 deletions(-) diff --git a/src/libcore/hash.rs b/src/libcore/hash.rs index 48fc9f205b9..ef792ef690e 100644 --- a/src/libcore/hash.rs +++ b/src/libcore/hash.rs @@ -64,7 +64,7 @@ impl A: Hash { pure fn hash_keyed(k0: u64, k1: u64) -> u64 { unchecked { let s = &State(k0, k1); - for self.iter_le_bytes |bytes| { + for self.iter_bytes(true) |bytes| { s.input(bytes); } s.result_u64() @@ -79,8 +79,8 @@ pure fn hash_keyed_2 u64 { unchecked { let s = &State(k0, k1); - for a.iter_le_bytes |bytes| { s.input(bytes); } - for b.iter_le_bytes |bytes| { s.input(bytes); } + for a.iter_bytes(true) |bytes| { s.input(bytes); } + for b.iter_bytes(true) |bytes| { s.input(bytes); } s.result_u64() } } @@ -91,9 +91,9 @@ pure fn hash_keyed_3 u64 { unchecked { let s = &State(k0, k1); - for a.iter_le_bytes |bytes| { s.input(bytes); } - for b.iter_le_bytes |bytes| { s.input(bytes); } - for c.iter_le_bytes |bytes| { s.input(bytes); } + for a.iter_bytes(true) |bytes| { s.input(bytes); } + for b.iter_bytes(true) |bytes| { s.input(bytes); } + for c.iter_bytes(true) |bytes| { s.input(bytes); } s.result_u64() } } @@ -105,10 +105,10 @@ pure fn hash_keyed_4 u64 { unchecked { let s = &State(k0, k1); - for a.iter_le_bytes |bytes| { s.input(bytes); } - for b.iter_le_bytes |bytes| { s.input(bytes); } - for c.iter_le_bytes |bytes| { s.input(bytes); } - for d.iter_le_bytes |bytes| { s.input(bytes); } + for a.iter_bytes(true) |bytes| { s.input(bytes); } + for b.iter_bytes(true) |bytes| { s.input(bytes); } + for c.iter_bytes(true) |bytes| { s.input(bytes); } + for d.iter_bytes(true) |bytes| { s.input(bytes); } s.result_u64() } } @@ -121,11 +121,11 @@ pure fn hash_keyed_5 u64 { unchecked { let s = &State(k0, k1); - for a.iter_le_bytes |bytes| { s.input(bytes); } - for b.iter_le_bytes |bytes| { s.input(bytes); } - for c.iter_le_bytes |bytes| { s.input(bytes); } - for d.iter_le_bytes |bytes| { s.input(bytes); } - for e.iter_le_bytes |bytes| { s.input(bytes); } + for a.iter_bytes(true) |bytes| { s.input(bytes); } + for b.iter_bytes(true) |bytes| { s.input(bytes); } + for c.iter_bytes(true) |bytes| { s.input(bytes); } + for d.iter_bytes(true) |bytes| { s.input(bytes); } + for e.iter_bytes(true) |bytes| { s.input(bytes); } s.result_u64() } } diff --git a/src/libcore/to_bytes.rs b/src/libcore/to_bytes.rs index 077f56cab45..f619085bd4b 100644 --- a/src/libcore/to_bytes.rs +++ b/src/libcore/to_bytes.rs @@ -7,221 +7,273 @@ use io::Writer; type Cb = fn(buf: &[const u8]) -> bool; trait IterBytes { - fn iter_le_bytes(f: Cb); - fn iter_be_bytes(f: Cb); + fn iter_bytes(lsb0: bool, f: Cb); } impl u8: IterBytes { #[inline(always)] - fn iter_le_bytes(f: Cb) { + fn iter_bytes(_lsb0: bool, f: Cb) { f([ - self, - ]); - } - #[inline(always)] - fn iter_be_bytes(f: Cb) { - f([ - self as u8 + self ]); } } impl u16: IterBytes { #[inline(always)] - fn iter_le_bytes(f: Cb) { - f([ - self as u8, - (self >> 8) as u8 - ]); - } - #[inline(always)] - fn iter_be_bytes(f: Cb) { - f([ - (self >> 8) as u8, - self as u8 - ]); + fn iter_bytes(lsb0: bool, f: Cb) { + if lsb0 { + f([ + self as u8, + (self >> 8) as u8 + ]); + } else { + f([ + (self >> 8) as u8, + self as u8 + ]); + } } } impl u32: IterBytes { #[inline(always)] - fn iter_le_bytes(f: Cb) { - f([ - self as u8, - (self >> 8) as u8, - (self >> 16) as u8, - (self >> 24) as u8, - ]); - } - #[inline(always)] - fn iter_be_bytes(f: Cb) { - f([ - (self >> 24) as u8, - (self >> 16) as u8, - (self >> 8) as u8, - self as u8 - ]); + fn iter_bytes(lsb0: bool, f: Cb) { + if lsb0 { + f([ + self as u8, + (self >> 8) as u8, + (self >> 16) as u8, + (self >> 24) as u8, + ]); + } else { + f([ + (self >> 24) as u8, + (self >> 16) as u8, + (self >> 8) as u8, + self as u8 + ]); + } } } impl u64: IterBytes { #[inline(always)] - fn iter_le_bytes(f: Cb) { - f([ - self as u8, - (self >> 8) as u8, - (self >> 16) as u8, - (self >> 24) as u8, - (self >> 32) as u8, - (self >> 40) as u8, - (self >> 48) as u8, - (self >> 56) as u8 - ]); - } - #[inline(always)] - fn iter_be_bytes(f: Cb) { - f([ - (self >> 56) as u8, - (self >> 48) as u8, - (self >> 40) as u8, - (self >> 32) as u8, - (self >> 24) as u8, - (self >> 16) as u8, - (self >> 8) as u8, - self as u8 - ]); + fn iter_bytes(lsb0: bool, f: Cb) { + if lsb0 { + f([ + self as u8, + (self >> 8) as u8, + (self >> 16) as u8, + (self >> 24) as u8, + (self >> 32) as u8, + (self >> 40) as u8, + (self >> 48) as u8, + (self >> 56) as u8 + ]); + } else { + f([ + (self >> 56) as u8, + (self >> 48) as u8, + (self >> 40) as u8, + (self >> 32) as u8, + (self >> 24) as u8, + (self >> 16) as u8, + (self >> 8) as u8, + self as u8 + ]); + } } } impl i8: IterBytes { #[inline(always)] - fn iter_le_bytes(f: Cb) { (self as u8).iter_le_bytes(f) } - #[inline(always)] - fn iter_be_bytes(f: Cb) { (self as u8).iter_be_bytes(f) } + fn iter_bytes(lsb0: bool, f: Cb) { + (self as u8).iter_bytes(lsb0, f) + } } impl i16: IterBytes { #[inline(always)] - fn iter_le_bytes(f: Cb) { (self as u16).iter_le_bytes(f) } - #[inline(always)] - fn iter_be_bytes(f: Cb) { (self as u16).iter_be_bytes(f) } + fn iter_bytes(lsb0: bool, f: Cb) { + (self as u16).iter_bytes(lsb0, f) + } } impl i32: IterBytes { #[inline(always)] - fn iter_le_bytes(f: Cb) { (self as u32).iter_le_bytes(f) } - #[inline(always)] - fn iter_be_bytes(f: Cb) { (self as u32).iter_be_bytes(f) } + fn iter_bytes(lsb0: bool, f: Cb) { + (self as u32).iter_bytes(lsb0, f) + } } impl i64: IterBytes { #[inline(always)] - fn iter_le_bytes(f: Cb) { (self as u64).iter_le_bytes(f) } - #[inline(always)] - fn iter_be_bytes(f: Cb) { (self as u64).iter_be_bytes(f) } + fn iter_bytes(lsb0: bool, f: Cb) { + (self as u64).iter_bytes(lsb0, f) + } } #[cfg(target_word_size = "32")] impl uint: IterBytes { #[inline(always)] - fn iter_le_bytes(f: Cb) { (self as u32).iter_le_bytes(f) } - #[inline(always)] - fn iter_be_bytes(f: Cb) { (self as u32).iter_be_bytes(f) } + fn iter_bytes(lsb0: bool, f: Cb) { + (self as u32).iter_bytes(lsb0, f) + } } #[cfg(target_word_size = "64")] impl uint: IterBytes { #[inline(always)] - fn iter_le_bytes(f: Cb) { (self as u64).iter_le_bytes(f) } - #[inline(always)] - fn iter_be_bytes(f: Cb) { (self as u64).iter_be_bytes(f) } + fn iter_bytes(lsb0: bool, f: Cb) { + (self as u64).iter_bytes(lsb0, f) + } } impl int: IterBytes { #[inline(always)] - fn iter_le_bytes(f: Cb) { (self as uint).iter_le_bytes(f) } - #[inline(always)] - fn iter_be_bytes(f: Cb) { (self as uint).iter_be_bytes(f) } -} - -impl ~[const u8]: IterBytes { - #[inline(always)] - fn iter_le_bytes(f: Cb) { f(self); } - #[inline(always)] - fn iter_be_bytes(f: Cb) { f(self); } -} - -impl @[const u8]: IterBytes { - #[inline(always)] - fn iter_le_bytes(f: Cb) { f(self); } - #[inline(always)] - fn iter_be_bytes(f: Cb) { f(self); } + fn iter_bytes(lsb0: bool, f: Cb) { + (self as uint).iter_bytes(lsb0, f) + } } impl &[const A]: IterBytes { #[inline(always)] - fn iter_le_bytes(f: Cb) { + fn iter_bytes(lsb0: bool, f: Cb) { for self.each |elt| { - do elt.iter_le_bytes |bytes| { + do elt.iter_bytes(lsb0) |bytes| { f(bytes) } } } +} + +// Move this to vec, probably. +fn borrow(a: &x/[const A]) -> &x/[const A] { + a +} + +impl ~[const A]: IterBytes { #[inline(always)] - fn iter_be_bytes(f: Cb) { - for self.each |elt| { - do elt.iter_be_bytes |bytes| { - f(bytes) - } - } + fn iter_bytes(lsb0: bool, f: Cb) { + borrow(self).iter_bytes(lsb0, f) } } -fn iter_le_bytes_2(a: &A, b: &B, f: Cb) { - let mut flag = true; - a.iter_le_bytes(|bytes| {flag = f(bytes); flag}); - if !flag { return; } - b.iter_le_bytes(|bytes| {flag = f(bytes); flag}); + +impl @[const A]: IterBytes { + #[inline(always)] + fn iter_bytes(lsb0: bool, f: Cb) { + borrow(self).iter_bytes(lsb0, f) + } } -fn iter_be_bytes_2(a: &A, b: &B, f: Cb) { +fn iter_bytes_2(a: &A, b: &B, + lsb0: bool, z: Cb) { let mut flag = true; - a.iter_be_bytes(|bytes| {flag = f(bytes); flag}); + a.iter_bytes(lsb0, |bytes| {flag = z(bytes); flag}); if !flag { return; } - b.iter_be_bytes(|bytes| {flag = f(bytes); flag}); + b.iter_bytes(lsb0, |bytes| {flag = z(bytes); flag}); } -fn iter_le_bytes_3(a: &A, b: &B, c: &C, f: Cb) { +fn iter_bytes_3(a: &A, b: &B, c: &C, + lsb0: bool, z: Cb) { let mut flag = true; - a.iter_le_bytes(|bytes| {flag = f(bytes); flag}); + a.iter_bytes(lsb0, |bytes| {flag = z(bytes); flag}); if !flag { return; } - b.iter_le_bytes(|bytes| { flag = f(bytes); flag}); + b.iter_bytes(lsb0, |bytes| {flag = z(bytes); flag}); if !flag { return; } - c.iter_le_bytes(|bytes| {flag = f(bytes); flag}); + c.iter_bytes(lsb0, |bytes| {flag = z(bytes); flag}); } -fn iter_be_bytes_3(a: &A, b: &B, c: &C, f: Cb) { +fn iter_bytes_4(a: &A, b: &B, c: &C, + d: &D, + lsb0: bool, z: Cb) { let mut flag = true; - a.iter_be_bytes(|bytes| {flag = f(bytes); flag}); + a.iter_bytes(lsb0, |bytes| {flag = z(bytes); flag}); if !flag { return; } - b.iter_be_bytes(|bytes| {flag = f(bytes); flag}); + b.iter_bytes(lsb0, |bytes| {flag = z(bytes); flag}); if !flag { return; } - c.iter_be_bytes(|bytes| {flag = f(bytes); flag}); + c.iter_bytes(lsb0, |bytes| {flag = z(bytes); flag}); + if !flag { return; } + d.iter_bytes(lsb0, |bytes| {flag = z(bytes); flag}); +} + +fn iter_bytes_5(a: &A, b: &B, c: &C, + d: &D, e: &E, + lsb0: bool, z: Cb) { + let mut flag = true; + a.iter_bytes(lsb0, |bytes| {flag = z(bytes); flag}); + if !flag { return; } + b.iter_bytes(lsb0, |bytes| {flag = z(bytes); flag}); + if !flag { return; } + c.iter_bytes(lsb0, |bytes| {flag = z(bytes); flag}); + if !flag { return; } + d.iter_bytes(lsb0, |bytes| {flag = z(bytes); flag}); + if !flag { return; } + e.iter_bytes(lsb0, |bytes| {flag = z(bytes); flag}); +} + +fn iter_bytes_6(a: &A, b: &B, c: &C, + d: &D, e: &E, f: &F, + lsb0: bool, z: Cb) { + let mut flag = true; + a.iter_bytes(lsb0, |bytes| {flag = z(bytes); flag}); + if !flag { return; } + b.iter_bytes(lsb0, |bytes| {flag = z(bytes); flag}); + if !flag { return; } + c.iter_bytes(lsb0, |bytes| {flag = z(bytes); flag}); + if !flag { return; } + d.iter_bytes(lsb0, |bytes| {flag = z(bytes); flag}); + if !flag { return; } + e.iter_bytes(lsb0, |bytes| {flag = z(bytes); flag}); + if !flag { return; } + f.iter_bytes(lsb0, |bytes| {flag = z(bytes); flag}); +} + +fn iter_bytes_7(a: &A, b: &B, c: &C, + d: &D, e: &E, f: &F, + g: &G, + lsb0: bool, z: Cb) { + let mut flag = true; + a.iter_bytes(lsb0, |bytes| {flag = z(bytes); flag}); + if !flag { return; } + b.iter_bytes(lsb0, |bytes| {flag = z(bytes); flag}); + if !flag { return; } + c.iter_bytes(lsb0, |bytes| {flag = z(bytes); flag}); + if !flag { return; } + d.iter_bytes(lsb0, |bytes| {flag = z(bytes); flag}); + if !flag { return; } + e.iter_bytes(lsb0, |bytes| {flag = z(bytes); flag}); + if !flag { return; } + f.iter_bytes(lsb0, |bytes| {flag = z(bytes); flag}); + if !flag { return; } + g.iter_bytes(lsb0, |bytes| {flag = z(bytes); flag}); } impl &str: IterBytes { #[inline(always)] - fn iter_le_bytes(f: Cb) { - do str::byte_slice(self) |bytes| { - f(bytes); - } - } - #[inline(always)] - fn iter_be_bytes(f: Cb) { + fn iter_bytes(_lsb0: bool, f: Cb) { do str::byte_slice(self) |bytes| { f(bytes); } @@ -230,13 +282,7 @@ impl &str: IterBytes { impl ~str: IterBytes { #[inline(always)] - fn iter_le_bytes(f: Cb) { - do str::byte_slice(self) |bytes| { - f(bytes); - } - } - #[inline(always)] - fn iter_be_bytes(f: Cb) { + fn iter_bytes(_lsb0: bool, f: Cb) { do str::byte_slice(self) |bytes| { f(bytes); } @@ -245,48 +291,41 @@ impl ~str: IterBytes { impl @str: IterBytes { #[inline(always)] - fn iter_le_bytes(f: Cb) { - do str::byte_slice(self) |bytes| { - f(bytes); - } - } - #[inline(always)] - fn iter_be_bytes(f: Cb) { + fn iter_bytes(_lsb0: bool, f: Cb) { do str::byte_slice(self) |bytes| { f(bytes); } } } + +impl Option: IterBytes { + #[inline(always)] + fn iter_bytes(lsb0: bool, f: Cb) { + match self { + Some(a) => iter_bytes_2(&0u8, &a, lsb0, f), + None => 1u8.iter_bytes(lsb0, f) + } + } +} + impl &A: IterBytes { #[inline(always)] - fn iter_le_bytes(f: Cb) { - (*self).iter_le_bytes(f); - } - #[inline(always)] - fn iter_be_bytes(f: Cb) { - (*self).iter_be_bytes(f); + fn iter_bytes(lsb0: bool, f: Cb) { + (*self).iter_bytes(lsb0, f); } } impl @A: IterBytes { #[inline(always)] - fn iter_le_bytes(f: Cb) { - (*self).iter_le_bytes(f); - } - #[inline(always)] - fn iter_be_bytes(f: Cb) { - (*self).iter_be_bytes(f); + fn iter_bytes(lsb0: bool, f: Cb) { + (*self).iter_bytes(lsb0, f); } } impl ~A: IterBytes { #[inline(always)] - fn iter_le_bytes(f: Cb) { - (*self).iter_le_bytes(f); - } - #[inline(always)] - fn iter_be_bytes(f: Cb) { - (*self).iter_be_bytes(f); + fn iter_bytes(lsb0: bool, f: Cb) { + (*self).iter_bytes(lsb0, f); } } @@ -294,35 +333,22 @@ impl ~A: IterBytes { // to the target; it just gives you the pointer-bytes. impl *A: IterBytes { #[inline(always)] - fn iter_le_bytes(f: Cb) { - (self as uint).iter_le_bytes(f); - } - #[inline(always)] - fn iter_be_bytes(f: Cb) { - (self as uint).iter_be_bytes(f); + fn iter_bytes(lsb0: bool, f: Cb) { + (self as uint).iter_bytes(lsb0, f); } } trait ToBytes { - fn to_le_bytes() -> ~[u8]; - fn to_be_bytes() -> ~[u8]; + fn to_bytes(lsb0: bool) -> ~[u8]; } impl A: ToBytes { - fn to_le_bytes() -> ~[u8] { + fn to_bytes(lsb0: bool) -> ~[u8] { let buf = io::mem_buffer(); - for self.iter_le_bytes |bytes| { + for self.iter_bytes(lsb0) |bytes| { buf.write(bytes) } io::mem_buffer_buf(buf) } - fn to_be_bytes() -> ~[u8] { - let buf = io::mem_buffer(); - for self.iter_be_bytes |bytes| { - buf.write(bytes) - } - io::mem_buffer_buf(buf) - } - } diff --git a/src/libstd/map.rs b/src/libstd/map.rs index 3db1c3407df..603cff98721 100644 --- a/src/libstd/map.rs +++ b/src/libstd/map.rs @@ -19,21 +19,12 @@ export hash_from_vec, hash_from_strs, hash_from_bytes; export hash_from_ints, hash_from_uints; export vec_from_set; -/** - * A function that returns a hash of a value - * - * The hash should concentrate entropy in the lower bits. - */ -type hashfn = fn~(key: &K) -> uint; - -type eqfn = fn~(key1: &K, key2: &K) -> bool; - /// A convenience type to treat a hashmap as a set -type set = hashmap; +type set = hashmap; -type hashmap = chained::t; +type hashmap = chained::t; -trait map { +trait map { /// Return the number of elements in the map pure fn size() -> uint; @@ -119,14 +110,12 @@ mod chained { mut next: Option<@entry> } - struct hashmap_ { + struct hashmap_ { mut count: uint, - mut chains: ~[mut Option<@entry>], - hasher: hashfn, - eqer: eqfn + mut chains: ~[mut Option<@entry>] } - type t = @hashmap_; + type t = @hashmap_; enum search_result { not_found, @@ -134,7 +123,7 @@ mod chained { found_after(@entry, @entry) } - priv impl t { + priv impl t { pure fn search_rem(k: &K, h: uint, idx: uint, e_root: @entry) -> search_result { let mut e0 = e_root; @@ -149,7 +138,7 @@ mod chained { Some(e1) => { comp += 1u; unchecked { - if e1.hash == h && self.eqer(&e1.key, k) { + if e1.hash == h && e1.key == *k { debug!("search_tbl: present, comp %u, \ hash %u, idx %u", comp, h, idx); @@ -173,7 +162,7 @@ mod chained { } Some(e) => { unchecked { - if e.hash == h && self.eqer(&e.key, k) { + if e.hash == h && e.key == *k { debug!("search_tbl: present, comp %u, hash %u, \ idx %u", 1u, h, idx); return found_first(idx, e); @@ -218,7 +207,7 @@ mod chained { } } - impl t: map { + impl t: map { pure fn size() -> uint { self.count } fn contains_key(+k: K) -> bool { @@ -226,7 +215,7 @@ mod chained { } fn contains_key_ref(k: &K) -> bool { - let hash = self.hasher(k); + let hash = k.hash_keyed(0,0) as uint; match self.search_tbl(k, hash) { not_found => false, found_first(*) | found_after(*) => true @@ -234,7 +223,7 @@ mod chained { } fn insert(+k: K, +v: V) -> bool { - let hash = self.hasher(&k); + let hash = k.hash_keyed(0,0) as uint; match self.search_tbl(&k, hash) { not_found => { self.count += 1u; @@ -277,7 +266,7 @@ mod chained { pure fn find(+k: K) -> Option { unchecked { - match self.search_tbl(&k, self.hasher(&k)) { + match self.search_tbl(&k, k.hash_keyed(0,0) as uint) { not_found => None, found_first(_, entry) => Some(entry.value), found_after(_, entry) => Some(entry.value) @@ -294,7 +283,7 @@ mod chained { } fn remove(+k: K) -> bool { - match self.search_tbl(&k, self.hasher(&k)) { + match self.search_tbl(&k, k.hash_keyed(0,0) as uint) { not_found => false, found_first(idx, entry) => { self.count -= 1u; @@ -341,7 +330,7 @@ mod chained { } } - impl t: ToStr { + impl t: ToStr { fn to_writer(wr: io::Writer) { if self.count == 0u { wr.write_str(~"{}"); @@ -367,7 +356,7 @@ mod chained { } } - impl t: ops::Index { + impl t: ops::Index { pure fn index(&&k: K) -> V { unchecked { self.get(k) @@ -379,11 +368,9 @@ mod chained { vec::to_mut(vec::from_elem(nchains, None)) } - fn mk(+hasher: hashfn, +eqer: eqfn) -> t { + fn mk() -> t { let slf: t = @hashmap_ {count: 0u, - chains: chains(initial_capacity), - hasher: hasher, - eqer: eqer}; + chains: chains(initial_capacity)}; slf } } @@ -392,56 +379,49 @@ mod chained { Function: hashmap Construct a hashmap. - -Parameters: - -hasher - The hash function for key type K -eqer - The equality function for key type K */ -fn hashmap(+hasher: hashfn, +eqer: eqfn) +fn hashmap() -> hashmap { - chained::mk(hasher, eqer) + chained::mk() } /// Construct a hashmap for string-slice keys fn str_slice_hash() -> hashmap<&str, V> { - return hashmap(|s| hash::hash_str(*s) as uint, - |a,b| str::eq_slice(*a, *b)); + return hashmap(); } /// Construct a hashmap for string keys fn str_hash() -> hashmap<~str, V> { - return hashmap(str::hash, str::eq); + return hashmap(); } /// Construct a hashmap for boxed string keys fn box_str_hash() -> hashmap<@~str, V> { - hashmap(|x: &@~str| str::hash(&**x), - |x: &@~str, y: &@~str| str::eq(&**x, &**y)) + hashmap() } /// Construct a hashmap for byte string keys fn bytes_hash() -> hashmap<~[u8], V> { - return hashmap(vec::u8::hash, vec::u8::eq); + return hashmap(); } /// Construct a hashmap for int keys fn int_hash() -> hashmap { - return hashmap(|x| { int::hash(*x) }, |x, y| { int::eq(*x, *y)}); + return hashmap(); } /// Construct a hashmap for uint keys fn uint_hash() -> hashmap { - return hashmap(|x| { uint::hash(*x) }, |x, y| { uint::eq(*x, *y) } ); + return hashmap(); } /// Convenience function for adding keys to a hashmap with nil type keys -fn set_add(set: set, +key: K) -> bool { +fn set_add(set: set, +key: K) -> bool { set.insert(key, ()) } /// Convert a set into a vector. -fn vec_from_set(s: set) -> ~[T] { +fn vec_from_set(s: set) -> ~[T] { let mut v = ~[]; vec::reserve(v, s.size()); do s.each_key() |k| { @@ -452,9 +432,9 @@ fn vec_from_set(s: set) -> ~[T] { } /// Construct a hashmap from a vector -fn hash_from_vec(+hasher: hashfn, +eqer: eqfn, - items: &[(K, V)]) -> hashmap { - let map = hashmap(hasher, eqer); +fn hash_from_vec( + items: &[(K, V)]) -> hashmap { + let map = hashmap(); do vec::iter(items) |item| { let (key, value) = item; map.insert(key, value); @@ -464,22 +444,22 @@ fn hash_from_vec(+hasher: hashfn, +eqer: eqfn, /// Construct a hashmap from a vector with string keys fn hash_from_strs(items: &[(~str, V)]) -> hashmap<~str, V> { - hash_from_vec(str::hash, str::eq, items) + hash_from_vec(items) } /// Construct a hashmap from a vector with byte keys fn hash_from_bytes(items: &[(~[u8], V)]) -> hashmap<~[u8], V> { - hash_from_vec(vec::u8::hash, vec::u8::eq, items) + hash_from_vec(items) } /// Construct a hashmap from a vector with int keys fn hash_from_ints(items: &[(int, V)]) -> hashmap { - hash_from_vec(|x| { int::hash(*x) }, |x, y| { int::eq(*x, *y) }, items) + hash_from_vec(items) } /// Construct a hashmap from a vector with uint keys fn hash_from_uints(items: &[(uint, V)]) -> hashmap { - hash_from_vec(|x| { uint::hash(*x) }, |x, y| { uint::eq(*x, *y) } , items) + hash_from_vec(items) } // XXX Transitional @@ -594,13 +574,9 @@ mod tests { debug!("*** starting test_simple"); 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_id; - let eqer_uint: map::eqfn = 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 = - map::hashmap::(copy hasher_uint, copy eqer_uint); + map::hashmap::(); assert (hm_uu.insert(10u, 12u)); assert (hm_uu.insert(11u, 13u)); assert (hm_uu.insert(12u, 14u)); @@ -616,7 +592,7 @@ mod tests { let twelve: ~str = ~"twelve"; debug!("str -> uint"); let hm_su: map::hashmap<~str, uint> = - map::hashmap::<~str, uint>(copy hasher_str, copy eqer_str); + map::hashmap::<~str, uint>(); assert (hm_su.insert(~"ten", 12u)); assert (hm_su.insert(eleven, 13u)); assert (hm_su.insert(~"twelve", 14u)); @@ -630,7 +606,7 @@ mod tests { assert (hm_su.get(~"twelve") == 12u); debug!("uint -> str"); let hm_us: map::hashmap = - map::hashmap::(copy hasher_uint, copy eqer_uint); + map::hashmap::(); assert (hm_us.insert(10u, ~"twelve")); assert (hm_us.insert(11u, ~"thirteen")); assert (hm_us.insert(12u, ~"fourteen")); @@ -643,7 +619,7 @@ mod tests { assert hm_us.get(12u) == ~"twelve"; debug!("str -> str"); let hm_ss: map::hashmap<~str, ~str> = - map::hashmap::<~str, ~str>(copy hasher_str, copy eqer_str); + map::hashmap::<~str, ~str>(); assert (hm_ss.insert(ten, ~"twelve")); assert (hm_ss.insert(eleven, ~"thirteen")); assert (hm_ss.insert(twelve, ~"fourteen")); @@ -668,10 +644,8 @@ mod tests { 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_id; - let eqer_uint: map::eqfn = eq_uint; let hm_uu: map::hashmap = - map::hashmap::(hasher_uint, eqer_uint); + map::hashmap::(); let mut i: uint = 0u; while i < num_to_insert { assert (hm_uu.insert(i, i * i)); @@ -695,10 +669,8 @@ mod tests { i += 1u; } debug!("str -> str"); - let hasher_str: map::hashfn<~str> = str::hash; - let eqer_str: map::eqfn<~str> = str::eq; let hm_ss: map::hashmap<~str, ~str> = - map::hashmap::<~str, ~str>(hasher_str, eqer_str); + map::hashmap::<~str, ~str>(); i = 0u; while i < num_to_insert { assert hm_ss.insert(uint::to_str(i, 2u), uint::to_str(i * i, 2u)); @@ -745,10 +717,8 @@ mod tests { assert (hash(&0u) == hash(&1u)); assert (hash(&2u) == hash(&3u)); assert (hash(&0u) != hash(&2u)); - let hasher: map::hashfn = hash; - let eqer: map::eqfn = eq; let hm: map::hashmap = - map::hashmap::(hasher, eqer); + map::hashmap::(); let mut i: uint = 0u; while i < num_to_insert { assert (hm.insert(i, i * i)); @@ -808,7 +778,7 @@ mod tests { #[test] fn test_contains_key() { let key = ~"k"; - let map = map::hashmap::<~str, ~str>(str::hash, str::eq); + let map = map::hashmap::<~str, ~str>(); assert (!map.contains_key(key)); map.insert(key, ~"val"); assert (map.contains_key(key)); @@ -817,7 +787,7 @@ mod tests { #[test] fn test_find() { let key = ~"k"; - let map = map::hashmap::<~str, ~str>(str::hash, str::eq); + let map = map::hashmap::<~str, ~str>(); assert (option::is_none(map.find(key))); map.insert(key, ~"val"); assert (option::get(map.find(key)) == ~"val"); @@ -826,7 +796,7 @@ mod tests { #[test] fn test_clear() { let key = ~"k"; - let map = map::hashmap::<~str, ~str>(str::hash, str::eq); + let map = map::hashmap::<~str, ~str>(); map.insert(key, ~"val"); assert (map.size() == 1); assert (map.contains_key(key)); diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index 140df4c29c0..e2cfdd119b6 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -310,6 +310,22 @@ enum binding_mode { bind_by_implicit_ref } +impl binding_mode : to_bytes::IterBytes { + fn iter_bytes(lsb0: bool, f: to_bytes::Cb) { + match self { + bind_by_value => 0u8.iter_bytes(lsb0, f), + + bind_by_move => 1u8.iter_bytes(lsb0, f), + + bind_by_ref(ref m) => + to_bytes::iter_bytes_2(&2u8, m, lsb0, f), + + bind_by_implicit_ref => + 3u8.iter_bytes(lsb0, f), + } + } +} + impl binding_mode : cmp::Eq { pure fn eq(&&other: binding_mode) -> bool { match self { @@ -368,6 +384,12 @@ enum pat_ { #[auto_serialize] enum mutability { m_mutbl, m_imm, m_const, } +impl mutability : to_bytes::IterBytes { + fn iter_bytes(lsb0: bool, f: to_bytes::Cb) { + (self as u8).iter_bytes(lsb0, f) + } +} + impl mutability: cmp::Eq { pure fn eq(&&other: mutability) -> bool { (self as uint) == (other as uint) @@ -443,6 +465,18 @@ enum inferable { infer(node_id) } +impl inferable : to_bytes::IterBytes { + fn iter_bytes(lsb0: bool, f: to_bytes::Cb) { + match self { + expl(ref t) => + to_bytes::iter_bytes_2(&0u8, t, lsb0, f), + + infer(ref n) => + to_bytes::iter_bytes_2(&1u8, n, lsb0, f), + } + } +} + impl inferable : cmp::Eq { pure fn eq(&&other: inferable) -> bool { match self { @@ -467,6 +501,13 @@ impl inferable : cmp::Eq { #[auto_serialize] enum rmode { by_ref, by_val, by_mutbl_ref, by_move, by_copy } +impl rmode : to_bytes::IterBytes { + fn iter_bytes(lsb0: bool, f: to_bytes::Cb) { + (self as u8).iter_bytes(lsb0, f) + } +} + + impl rmode : cmp::Eq { pure fn eq(&&other: rmode) -> bool { (self as uint) == (other as uint) @@ -822,6 +863,12 @@ enum trait_method { #[auto_serialize] enum int_ty { ty_i, ty_char, ty_i8, ty_i16, ty_i32, ty_i64, } +impl int_ty : to_bytes::IterBytes { + fn iter_bytes(lsb0: bool, f: to_bytes::Cb) { + (self as u8).iter_bytes(lsb0, f) + } +} + impl int_ty: cmp::Eq { pure fn eq(&&other: int_ty) -> bool { match (self, other) { @@ -845,6 +892,12 @@ impl int_ty: cmp::Eq { #[auto_serialize] enum uint_ty { ty_u, ty_u8, ty_u16, ty_u32, ty_u64, } +impl uint_ty : to_bytes::IterBytes { + fn iter_bytes(lsb0: bool, f: to_bytes::Cb) { + (self as u8).iter_bytes(lsb0, f) + } +} + impl uint_ty: cmp::Eq { pure fn eq(&&other: uint_ty) -> bool { match (self, other) { @@ -866,6 +919,11 @@ impl uint_ty: cmp::Eq { #[auto_serialize] enum float_ty { ty_f, ty_f32, ty_f64, } +impl float_ty : to_bytes::IterBytes { + fn iter_bytes(lsb0: bool, f: to_bytes::Cb) { + (self as u8).iter_bytes(lsb0, f) + } +} impl float_ty: cmp::Eq { pure fn eq(&&other: float_ty) -> bool { match (self, other) { @@ -954,6 +1012,24 @@ enum ty_ { ty_infer, } +// Equality and byte-iter (hashing) can be quite approximate for AST types. +// since we only care about this for normalizing them to "real" types. +impl ty : cmp::Eq { + pure fn eq(&&other: ty) -> bool { + ptr::addr_of(self) == ptr::addr_of(other) + } + pure fn ne(&&other: ty) -> bool { + ptr::addr_of(self) != ptr::addr_of(other) + } +} + +impl ty : to_bytes::IterBytes { + fn iter_bytes(lsb0: bool, f: to_bytes::Cb) { + to_bytes::iter_bytes_2(&self.span.lo, &self.span.hi, lsb0, f); + } +} + + #[auto_serialize] type arg = {mode: mode, ty: @ty, ident: ident, id: node_id}; @@ -971,6 +1047,12 @@ enum purity { extern_fn, // declared with "extern fn" } +impl purity : to_bytes::IterBytes { + fn iter_bytes(lsb0: bool, f: to_bytes::Cb) { + (self as u8).iter_bytes(lsb0, f) + } +} + impl purity : cmp::Eq { pure fn eq(&&other: purity) -> bool { (self as uint) == (other as uint) @@ -985,6 +1067,12 @@ enum ret_style { return_val, // everything else } +impl ret_style : to_bytes::IterBytes { + fn iter_bytes(lsb0: bool, f: to_bytes::Cb) { + (self as u8).iter_bytes(lsb0, f) + } +} + impl ret_style : cmp::Eq { pure fn eq(&&other: ret_style) -> bool { match (self, other) { @@ -1276,6 +1364,12 @@ enum item_ { #[auto_serialize] enum class_mutability { class_mutable, class_immutable } +impl class_mutability : to_bytes::IterBytes { + fn iter_bytes(lsb0: bool, f: to_bytes::Cb) { + (self as u8).iter_bytes(lsb0, f) + } +} + impl class_mutability : cmp::Eq { pure fn eq(&&other: class_mutability) -> bool { match (self, other) { diff --git a/src/libsyntax/ast_util.rs b/src/libsyntax/ast_util.rs index 429028b966e..97dcb922c43 100644 --- a/src/libsyntax/ast_util.rs +++ b/src/libsyntax/ast_util.rs @@ -251,28 +251,16 @@ pure fn is_call_expr(e: @expr) -> bool { match e.node { expr_call(_, _, _) => true, _ => false } } -pure fn eq_ty(a: &@ty, b: &@ty) -> bool { box::ptr_eq(*a, *b) } - -pure fn hash_ty(t: &@ty) -> uint { - let res = (t.span.lo << 16u) + t.span.hi; - return res; -} - -pure fn def_eq(a: &ast::def_id, b: &ast::def_id) -> bool { - a.crate == b.crate && a.node == b.node -} - -pure fn hash_def(d: &ast::def_id) -> uint { - let mut h = 5381u; - h = (h << 5u) + h ^ (d.crate as uint); - h = (h << 5u) + h ^ (d.node as uint); - return h; +// This makes def_id hashable +impl def_id : core::to_bytes::IterBytes { + #[inline(always)] + fn iter_bytes(lsb0: bool, f: core::to_bytes::Cb) { + core::to_bytes::iter_bytes_2(&self.crate, &self.node, lsb0, f); + } } fn new_def_hash() -> std::map::hashmap { - let hasher: std::map::hashfn = hash_def; - let eqer: std::map::eqfn = def_eq; - return std::map::hashmap::(hasher, eqer); + return std::map::hashmap::(); } fn block_from_expr(e: @expr) -> blk { diff --git a/src/libsyntax/parse/token.rs b/src/libsyntax/parse/token.rs index e258f9a2bdd..cc1b049ab93 100644 --- a/src/libsyntax/parse/token.rs +++ b/src/libsyntax/parse/token.rs @@ -345,8 +345,7 @@ fn mk_ident_interner() -> ident_interner { @~"dtor", @~"main", @~"", @~"blk", @~"static", @~"intrinsic", @~"__foreign_mod__"]; - let rv = interner::mk_prefill::<@~str>(|x| str::hash(*x), - |x,y| str::eq(*x, *y), init_vec); + let rv = interner::mk_prefill::<@~str>(init_vec); /* having multiple interners will just confuse the serializer */ unsafe{ assert task::local_data_get(interner_key!()).is_none() }; @@ -357,7 +356,7 @@ fn mk_ident_interner() -> ident_interner { /* for when we don't care about the contents; doesn't interact with TLD or serialization */ fn mk_fake_ident_interner() -> ident_interner { - interner::mk::<@~str>(|x| str::hash(*x), |x,y| str::eq(*x, *y)) + interner::mk::<@~str>() } /** diff --git a/src/libsyntax/util/interner.rs b/src/libsyntax/util/interner.rs index 9a52d608887..59cdb6b98a7 100644 --- a/src/libsyntax/util/interner.rs +++ b/src/libsyntax/util/interner.rs @@ -2,40 +2,39 @@ // allows bidirectional lookup; i.e. given a value, one can easily find the // type, and vice versa. use std::map; -use std::map::{hashmap, hashfn, eqfn}; +use std::map::hashmap; use dvec::DVec; +use cmp::Eq; +use hash::Hash; +use to_bytes::IterBytes; type hash_interner = {map: hashmap, - vect: DVec, - hasher: hashfn, - eqer: eqfn}; + vect: DVec}; -fn mk(+hasher: hashfn, +eqer: eqfn) -> interner { - let m = map::hashmap::(copy hasher, copy eqer); +fn mk() -> interner { + let m = map::hashmap::(); let hi: hash_interner = - {map: m, vect: DVec(), hasher: hasher, eqer: eqer}; + {map: m, vect: DVec()}; return hi as interner::; } -fn mk_prefill(hasher: hashfn, eqer: eqfn, - init: ~[T]) -> interner { - - let rv = mk(copy hasher, copy eqer); +fn mk_prefill(init: ~[T]) -> interner { + let rv = mk(); for init.each() |v| { rv.intern(v); } return rv; } /* when traits can extend traits, we should extend index to get [] */ -trait interner { +trait interner { fn intern(T) -> uint; fn gensym(T) -> uint; pure fn get(uint) -> T; fn len() -> uint; } -impl hash_interner: interner { +impl hash_interner: interner { fn intern(val: T) -> uint { match self.map.find(val) { Some(idx) => return idx, diff --git a/src/rustc/lib/llvm.rs b/src/rustc/lib/llvm.rs index cad0429e9b6..4e529239401 100644 --- a/src/rustc/lib/llvm.rs +++ b/src/rustc/lib/llvm.rs @@ -1057,7 +1057,7 @@ fn name_has_type(tn: type_names, s: ~str) -> Option { fn mk_type_names() -> type_names { pure fn hash(t: &TypeRef) -> uint { *t as uint } pure fn eq(a: &TypeRef, b: &TypeRef) -> bool { *a == *b } - @{type_names: std::map::hashmap(hash, eq), + @{type_names: std::map::hashmap(), named_types: std::map::str_hash()} } diff --git a/src/rustc/middle/borrowck.rs b/src/rustc/middle/borrowck.rs index 785665b42bf..70f12581245 100644 --- a/src/rustc/middle/borrowck.rs +++ b/src/rustc/middle/borrowck.rs @@ -404,8 +404,24 @@ fn save_and_restore(&save_and_restore_t: T, f: fn() -> U) -> U { } /// Creates and returns a new root_map + +impl root_map_key : cmp::Eq { + pure fn eq(&&other: root_map_key) -> bool { + self.id == other.id && self.derefs == other.derefs + } + pure fn ne(&&other: root_map_key) -> bool { + ! (self == other) + } +} + +impl root_map_key : to_bytes::IterBytes { + fn iter_bytes(lsb0: bool, f: to_bytes::Cb) { + to_bytes::iter_bytes_2(&self.id, &self.derefs, lsb0, f); + } +} + fn root_map() -> root_map { - return hashmap(root_map_key_hash, root_map_key_eq); + return hashmap(); pure fn root_map_key_eq(k1: &root_map_key, k2: &root_map_key) -> bool { k1.id == k2.id && k1.derefs == k2.derefs diff --git a/src/rustc/middle/resolve.rs b/src/rustc/middle/resolve.rs index 32f3348218a..c34881abdfa 100644 --- a/src/rustc/middle/resolve.rs +++ b/src/rustc/middle/resolve.rs @@ -309,7 +309,7 @@ fn Atom(n: uint) -> Atom { /// Creates a hash table of atoms. fn atom_hashmap() -> hashmap { - hashmap::(|x| { uint::hash(*x) }, |x, y| { uint::eq(*x, *y) }) + hashmap::() } /// One local scope. diff --git a/src/rustc/middle/trans/base.rs b/src/rustc/middle/trans/base.rs index f9eb3f737b4..420893f29d4 100644 --- a/src/rustc/middle/trans/base.rs +++ b/src/rustc/middle/trans/base.rs @@ -2658,10 +2658,10 @@ fn trans_crate(sess: session::session, tydescs: ty::new_ty_hash(), mut finished_tydescs: false, external: ast_util::new_def_hash(), - monomorphized: map::hashmap(hash_mono_id, sys::shape_eq), + monomorphized: map::hashmap(), monomorphizing: ast_util::new_def_hash(), type_use_cache: ast_util::new_def_hash(), - vtables: map::hashmap(hash_mono_id, sys::shape_eq), + vtables: map::hashmap(), const_cstr_cache: map::str_hash(), const_globals: int_hash::(), module_data: str_hash::(), diff --git a/src/rustc/middle/trans/common.rs b/src/rustc/middle/trans/common.rs index f4a3af08734..75007312e11 100644 --- a/src/rustc/middle/trans/common.rs +++ b/src/rustc/middle/trans/common.rs @@ -1125,24 +1125,24 @@ impl mono_id_: cmp::Eq { pure fn ne(&&other: mono_id_) -> bool { !self.eq(other) } } -pure fn hash_mono_id(mi: &mono_id) -> uint { - let mut h = syntax::ast_util::hash_def(&mi.def); - for vec::each(mi.params) |param| { - h = h * match param { - mono_precise(ty, vts) => { - let mut h = ty::type_id(ty); - do option::iter(vts) |vts| { - for vec::each(vts) |vt| { - h += hash_mono_id(&vt); - } - } - h - } - mono_any => 1u, - mono_repr(sz, align) => sz * (align + 2u) +impl mono_param_id : to_bytes::IterBytes { + fn iter_bytes(lsb0: bool, f: to_bytes::Cb) { + match self { + mono_precise(t, mids) => + to_bytes::iter_bytes_3(&0u8, &ty::type_id(t), &mids, lsb0, f), + + mono_any => 1u8.iter_bytes(lsb0, f), + + mono_repr(a,b) => + to_bytes::iter_bytes_3(&2u8, &a, &b, lsb0, f) } } - h +} + +impl mono_id_ : core::to_bytes::IterBytes { + fn iter_bytes(lsb0: bool, f: to_bytes::Cb) { + to_bytes::iter_bytes_2(&self.def, &self.params, lsb0, f); + } } fn umax(cx: block, a: ValueRef, b: ValueRef) -> ValueRef { diff --git a/src/rustc/middle/trans/shape.rs b/src/rustc/middle/trans/shape.rs index f93d9c0b593..6fee6f22fe0 100644 --- a/src/rustc/middle/trans/shape.rs +++ b/src/rustc/middle/trans/shape.rs @@ -22,8 +22,34 @@ use option::is_some; use ty_ctxt = middle::ty::ctxt; -type nominal_id = @{did: ast::def_id, parent_id: Option, +type nominal_id_ = {did: ast::def_id, parent_id: Option, tps: ~[ty::t]}; +type nominal_id = @nominal_id_; + +impl nominal_id_ : core::cmp::Eq { + pure fn eq(&&other: nominal_id_) -> bool { + if self.did != other.did || + self.parent_id != other.parent_id { + false + } else { + do vec::all2(self.tps, other.tps) |m_tp, n_tp| { + ty::type_id(m_tp) == ty::type_id(n_tp) + } + } + } + pure fn ne(&&other: nominal_id_) -> bool { + ! (self == other) + } +} + +impl nominal_id_ : to_bytes::IterBytes { + fn iter_bytes(lsb0: bool, f: to_bytes::Cb) { + to_bytes::iter_bytes_2(&self.did, &self.parent_id, lsb0, f); + for self.tps.each |t| { + ty::type_id(t).iter_bytes(lsb0, f); + } + } +} fn mk_nominal_id(tcx: ty::ctxt, did: ast::def_id, parent_id: Option, @@ -32,31 +58,8 @@ fn mk_nominal_id(tcx: ty::ctxt, did: ast::def_id, @{did: did, parent_id: parent_id, tps: tps_norm} } -pure fn hash_nominal_id(ri: &nominal_id) -> uint { - let mut h = 5381u; - h *= 33u; - h += ri.did.crate as uint; - h *= 33u; - h += ri.did.node as uint; - for vec::each(ri.tps) |t| { - h *= 33u; - h += ty::type_id(t); - } - return h; -} - -pure fn eq_nominal_id(mi: &nominal_id, ni: &nominal_id) -> bool { - if mi.did != ni.did { - false - } else { - do vec::all2(mi.tps, ni.tps) |m_tp, n_tp| { - ty::type_id(m_tp) == ty::type_id(n_tp) - } - } -} - fn new_nominal_id_hash() -> hashmap { - return hashmap(hash_nominal_id, eq_nominal_id); + return hashmap(); } type enum_data = {did: ast::def_id, substs: ty::substs}; @@ -193,7 +196,7 @@ fn mk_ctxt(llmod: ModuleRef) -> ctxt { pad: 0u16, tag_id_to_index: new_nominal_id_hash(), tag_order: DVec(), - resources: interner::mk(hash_nominal_id, eq_nominal_id), + resources: interner::mk(), llshapetablesty: llshapetablesty, llshapetables: llshapetables}; } diff --git a/src/rustc/middle/ty.rs b/src/rustc/middle/ty.rs index 1d6cd1f45c3..b8679a3818a 100644 --- a/src/rustc/middle/ty.rs +++ b/src/rustc/middle/ty.rs @@ -226,7 +226,25 @@ type field_ty = { // Contains information needed to resolve types and (in the future) look up // the types of AST nodes. -type creader_cache = hashmap<{cnum: int, pos: uint, len: uint}, t>; +type creader_cache_key = {cnum: int, pos: uint, len: uint}; +type creader_cache = hashmap; + +impl creader_cache_key : cmp::Eq { + pure fn eq(&&other: creader_cache_key) -> bool { + self.cnum == other.cnum && + self.pos == other.pos && + self.len == other.len + } + pure fn ne(&&other: creader_cache_key) -> bool { + !(self == other) + } +} + +impl creader_cache_key : to_bytes::IterBytes { + fn iter_bytes(lsb0: bool, f: to_bytes::Cb) { + to_bytes::iter_bytes_3(&self.cnum, &self.pos, &self.len, lsb0, f); + } +} type intern_key = {struct: sty, o_def_id: Option}; @@ -237,6 +255,12 @@ impl intern_key: cmp::Eq { pure fn ne(&&other: intern_key) -> bool { !self.eq(other) } } +impl intern_key : to_bytes::IterBytes { + fn iter_bytes(lsb0: bool, f: to_bytes::Cb) { + to_bytes::iter_bytes_2(&self.struct, &self.o_def_id, lsb0, f); + } +} + enum ast_ty_to_ty_cache_entry { atttce_unresolved, /* not resolved yet */ atttce_resolved(t) /* resolved to a type, irrespective of region */ @@ -366,6 +390,12 @@ enum closure_kind { ck_uniq, } +impl closure_kind : to_bytes::IterBytes { + fn iter_bytes(lsb0: bool, f: to_bytes::Cb) { + (self as u8).iter_bytes(lsb0, f) + } +} + impl closure_kind : cmp::Eq { pure fn eq(&&other: closure_kind) -> bool { (self as uint) == (other as uint) @@ -378,6 +408,18 @@ enum fn_proto { proto_vstore(vstore) } +impl fn_proto : to_bytes::IterBytes { + fn iter_bytes(lsb0: bool, f: to_bytes::Cb) { + match self { + proto_bare => + 0u8.iter_bytes(lsb0, f), + + proto_vstore(ref v) => + to_bytes::iter_bytes_2(&1u8, v, lsb0, f) + } + } +} + impl fn_proto : cmp::Eq { pure fn eq(&&other: fn_proto) -> bool { match self { @@ -444,6 +486,13 @@ impl param_ty: cmp::Eq { pure fn ne(&&other: param_ty) -> bool { !self.eq(other) } } +impl param_ty : to_bytes::IterBytes { + fn iter_bytes(lsb0: bool, f: to_bytes::Cb) { + to_bytes::iter_bytes_2(&self.idx, &self.def_id, lsb0, f) + } +} + + /// Representation of regions: enum region { /// Bound regions are found (primarily) in function types. They indicate @@ -606,6 +655,28 @@ enum InferTy { IntVar(IntVid) } +impl InferTy : to_bytes::IterBytes { + fn iter_bytes(lsb0: bool, f: to_bytes::Cb) { + match self { + TyVar(ref tv) => to_bytes::iter_bytes_2(&0u8, tv, lsb0, f), + IntVar(ref iv) => to_bytes::iter_bytes_2(&1u8, iv, lsb0, f) + } + } +} + +impl param_bound : to_bytes::IterBytes { + fn iter_bytes(lsb0: bool, f: to_bytes::Cb) { + match self { + bound_copy => 0u8.iter_bytes(lsb0, f), + bound_owned => 1u8.iter_bytes(lsb0, f), + bound_send => 2u8.iter_bytes(lsb0, f), + bound_const => 3u8.iter_bytes(lsb0, f), + bound_trait(ref t) => + to_bytes::iter_bytes_2(&4u8, t, lsb0, f) + } + } +} + trait vid { pure fn to_uint() -> uint; pure fn to_str() -> ~str; @@ -657,6 +728,30 @@ impl purity: purity_to_str { } } +impl RegionVid : to_bytes::IterBytes { + fn iter_bytes(lsb0: bool, f: to_bytes::Cb) { + (*self).iter_bytes(lsb0, f) + } +} + +impl TyVid : to_bytes::IterBytes { + fn iter_bytes(lsb0: bool, f: to_bytes::Cb) { + (*self).iter_bytes(lsb0, f) + } +} + +impl IntVid : to_bytes::IterBytes { + fn iter_bytes(lsb0: bool, f: to_bytes::Cb) { + (*self).iter_bytes(lsb0, f) + } +} + +impl FnVid : to_bytes::IterBytes { + fn iter_bytes(lsb0: bool, f: to_bytes::Cb) { + (*self).iter_bytes(lsb0, f) + } +} + fn param_bounds_to_kind(bounds: param_bounds) -> kind { let mut kind = kind_noncopyable(); for vec::each(*bounds) |bound| { @@ -701,18 +796,11 @@ type node_type_table = @smallintmap::SmallIntMap; fn mk_rcache() -> creader_cache { type val = {cnum: int, pos: uint, len: uint}; - pure fn hash_cache_entry(k: &val) -> uint { - (k.cnum as uint) + k.pos + k.len - } - pure fn eq_cache_entries(a: &val, b: &val) -> bool { - a.cnum == b.cnum && a.pos == b.pos && a.len == b.len - } - return map::hashmap(hash_cache_entry, eq_cache_entries); + return map::hashmap(); } fn new_ty_hash() -> map::hashmap { - map::hashmap(|t: &t| type_id(*t), - |a: &t, b: &t| type_id(*a) == type_id(*b)) + map::hashmap() } fn mk_ctxt(s: session::session, @@ -721,11 +809,7 @@ fn mk_ctxt(s: session::session, freevars: freevars::freevar_map, region_map: middle::region::region_map, region_paramd_items: middle::region::region_paramd_items) -> ctxt { - pure fn hash_intern_key(k: &intern_key) -> uint { - hash_type_structure(&k.struct) + - option::map_default(k.o_def_id, 0u, |d| ast_util::hash_def(&d)) - } - let interner = map::hashmap(hash_intern_key, sys::shape_eq); + let interner = map::hashmap(); let vecs_implicitly_copyable = get_lint_level(s.lint_settings.default_settings, lint::vecs_implicitly_copyable) == allow; @@ -750,8 +834,7 @@ fn mk_ctxt(s: session::session, needs_drop_cache: new_ty_hash(), needs_unwind_cleanup_cache: new_ty_hash(), kind_cache: new_ty_hash(), - ast_ty_to_ty_cache: map::hashmap( - ast_util::hash_ty, ast_util::eq_ty), + ast_ty_to_ty_cache: map::hashmap(), enum_var_cache: new_def_hash(), trait_method_cache: new_def_hash(), ty_param_bounds: map::int_hash(), @@ -2314,6 +2397,167 @@ fn index_sty(cx: ctxt, sty: &sty) -> Option { } } +impl bound_region : to_bytes::IterBytes { + fn iter_bytes(lsb0: bool, f: to_bytes::Cb) { + match self { + ty::br_self => 0u8.iter_bytes(lsb0, f), + + ty::br_anon(ref idx) => + to_bytes::iter_bytes_2(&1u8, idx, lsb0, f), + + ty::br_named(ref ident) => + to_bytes::iter_bytes_2(&2u8, ident, lsb0, f), + + ty::br_cap_avoid(ref id, ref br) => + to_bytes::iter_bytes_3(&3u8, id, br, lsb0, f) + } + } +} + +impl region : to_bytes::IterBytes { + fn iter_bytes(lsb0: bool, f: to_bytes::Cb) { + match self { + re_bound(ref br) => + to_bytes::iter_bytes_2(&0u8, br, lsb0, f), + + re_free(ref id, ref br) => + to_bytes::iter_bytes_3(&1u8, id, br, lsb0, f), + + re_scope(ref id) => + to_bytes::iter_bytes_2(&2u8, id, lsb0, f), + + re_var(ref id) => + to_bytes::iter_bytes_2(&3u8, id, lsb0, f), + + re_static => 4u8.iter_bytes(lsb0, f) + } + } +} + +impl vstore : to_bytes::IterBytes { + fn iter_bytes(lsb0: bool, f: to_bytes::Cb) { + match self { + vstore_fixed(ref u) => + to_bytes::iter_bytes_2(&0u8, u, lsb0, f), + + vstore_uniq => 1u8.iter_bytes(lsb0, f), + vstore_box => 2u8.iter_bytes(lsb0, f), + + vstore_slice(ref r) => + to_bytes::iter_bytes_2(&3u8, r, lsb0, f), + } + } +} + +impl substs : to_bytes::IterBytes { + fn iter_bytes(lsb0: bool, f: to_bytes::Cb) { + to_bytes::iter_bytes_3(&self.self_r, + &self.self_ty, + &self.tps, lsb0, f) + } +} + +impl mt : to_bytes::IterBytes { + fn iter_bytes(lsb0: bool, f: to_bytes::Cb) { + to_bytes::iter_bytes_2(&self.ty, + &self.mutbl, lsb0, f) + } +} + +impl field : to_bytes::IterBytes { + fn iter_bytes(lsb0: bool, f: to_bytes::Cb) { + to_bytes::iter_bytes_2(&self.ident, + &self.mt, lsb0, f) + } +} + +impl arg : to_bytes::IterBytes { + fn iter_bytes(lsb0: bool, f: to_bytes::Cb) { + to_bytes::iter_bytes_2(&self.mode, + &self.ty, lsb0, f) + } +} + +impl sty : to_bytes::IterBytes { + fn iter_bytes(lsb0: bool, f: to_bytes::Cb) { + match self { + ty_nil => 0u8.iter_bytes(lsb0, f), + ty_bool => 1u8.iter_bytes(lsb0, f), + + ty_int(ref t) => + to_bytes::iter_bytes_2(&2u8, t, lsb0, f), + + ty_uint(ref t) => + to_bytes::iter_bytes_2(&3u8, t, lsb0, f), + + ty_float(ref t) => + to_bytes::iter_bytes_2(&4u8, t, lsb0, f), + + ty_estr(ref v) => + to_bytes::iter_bytes_2(&5u8, v, lsb0, f), + + ty_enum(ref did, ref substs) => + to_bytes::iter_bytes_3(&6u8, did, substs, lsb0, f), + + ty_box(ref mt) => + to_bytes::iter_bytes_2(&7u8, mt, lsb0, f), + + ty_evec(ref mt, ref v) => + to_bytes::iter_bytes_3(&8u8, mt, v, lsb0, f), + + ty_unboxed_vec(ref mt) => + to_bytes::iter_bytes_2(&9u8, mt, lsb0, f), + + ty_tup(ref ts) => + to_bytes::iter_bytes_2(&10u8, ts, lsb0, f), + + ty_rec(ref fs) => + to_bytes::iter_bytes_2(&11u8, fs, lsb0, f), + + ty_fn(ref ft) => + to_bytes::iter_bytes_7(&12u8, + &ft.meta.purity, + &ft.meta.proto, + &ft.meta.bounds, + &ft.sig.inputs, + &ft.sig.output, + &ft.meta.ret_style, + lsb0, f), + + ty_self => 13u8.iter_bytes(lsb0, f), + + ty_infer(ref v) => + to_bytes::iter_bytes_2(&14u8, v, lsb0, f), + + ty_param(ref p) => + to_bytes::iter_bytes_2(&15u8, p, lsb0, f), + + ty_type => 16u8.iter_bytes(lsb0, f), + ty_bot => 17u8.iter_bytes(lsb0, f), + + ty_ptr(ref mt) => + to_bytes::iter_bytes_2(&18u8, mt, lsb0, f), + + ty_uniq(ref mt) => + to_bytes::iter_bytes_2(&19u8, mt, lsb0, f), + + ty_trait(ref did, ref substs, ref v) => + to_bytes::iter_bytes_4(&20u8, did, substs, v, lsb0, f), + + ty_opaque_closure_ptr(ref ck) => + to_bytes::iter_bytes_2(&21u8, ck, lsb0, f), + + ty_opaque_box => 22u8.iter_bytes(lsb0, f), + + ty_class(ref did, ref substs) => + to_bytes::iter_bytes_3(&23u8, did, substs, lsb0, f), + + ty_rptr(ref r, ref mt) => + to_bytes::iter_bytes_3(&24u8, r, mt, lsb0, f), + } + } +} + pure fn hash_bound_region(br: &bound_region) -> uint { match *br { // no idea if this is any good ty::br_self => 0u, @@ -2325,7 +2569,7 @@ pure fn hash_bound_region(br: &bound_region) -> uint { } fn br_hashmap() -> hashmap { - map::hashmap(hash_bound_region, sys::shape_eq) + map::hashmap() } pure fn hash_region(r: ®ion) -> uint { @@ -3328,7 +3572,7 @@ fn enum_variant_with_id(cx: ctxt, enum_id: ast::def_id, let mut i = 0u; while i < vec::len::(*variants) { let variant = variants[i]; - if ast_util::def_eq(&variant.id, &variant_id) { return variant; } + if variant.id == variant_id { return variant; } i += 1u; } cx.sess.bug(~"enum_variant_with_id(): no variant exists with that ID"); diff --git a/src/rustc/middle/typeck/infer/region_var_bindings.rs b/src/rustc/middle/typeck/infer/region_var_bindings.rs index be87558ee5b..3c51c22bf05 100644 --- a/src/rustc/middle/typeck/infer/region_var_bindings.rs +++ b/src/rustc/middle/typeck/infer/region_var_bindings.rs @@ -349,6 +349,21 @@ impl Constraint: cmp::Eq { pure fn ne(&&other: Constraint) -> bool { !self.eq(other) } } +impl Constraint : to_bytes::IterBytes { + fn iter_bytes(lsb0: bool, f: to_bytes::Cb) { + match self { + ConstrainVarSubVar(ref v0, ref v1) => + to_bytes::iter_bytes_3(&0u8, v0, v1, lsb0, f), + + ConstrainRegSubVar(ref ra, ref va) => + to_bytes::iter_bytes_3(&1u8, ra, va, lsb0, f), + + ConstrainVarSubReg(ref va, ref ra) => + to_bytes::iter_bytes_3(&2u8, va, ra, lsb0, f) + } + } +} + struct TwoRegions { a: region, b: region, @@ -361,6 +376,12 @@ impl TwoRegions: cmp::Eq { pure fn ne(&&other: TwoRegions) -> bool { !self.eq(other) } } +impl TwoRegions : to_bytes::IterBytes { + fn iter_bytes(lsb0: bool, f: to_bytes::Cb) { + to_bytes::iter_bytes_2(&self.a, &self.b, lsb0, f) + } +} + enum UndoLogEntry { Snapshot, AddVar(RegionVid), @@ -394,7 +415,7 @@ fn RegionVarBindings(tcx: ty::ctxt) -> RegionVarBindings { tcx: tcx, var_spans: DVec(), values: empty_cell(), - constraints: hashmap(hash_constraint, sys::shape_eq), + constraints: hashmap(), lubs: CombineMap(), glbs: CombineMap(), undo_log: DVec() @@ -405,16 +426,7 @@ fn RegionVarBindings(tcx: ty::ctxt) -> RegionVarBindings { // `b`! Not obvious that this is the most efficient way to go about // it. fn CombineMap() -> CombineMap { - return hashmap(hash_two_regions, eq_two_regions); - - pure fn hash_two_regions(rc: &TwoRegions) -> uint { - hash_region(&rc.a) ^ hash_region(&rc.b) - } - - pure fn eq_two_regions(rc1: &TwoRegions, rc2: &TwoRegions) -> bool { - (rc1.a == rc2.a && rc1.b == rc2.b) || - (rc1.a == rc2.b && rc1.b == rc2.a) - } + return hashmap(); } pure fn hash_constraint(rc: &Constraint) -> uint { @@ -795,11 +807,7 @@ struct SpannedRegion { type TwoRegionsMap = hashmap; fn TwoRegionsMap() -> TwoRegionsMap { - return hashmap(hash_two_regions, sys::shape_eq); - - pure fn hash_two_regions(rc: &TwoRegions) -> uint { - hash_region(&rc.a) ^ (hash_region(&rc.b) << 2) - } + return hashmap(); } impl RegionVarBindings { diff --git a/src/test/compile-fail/borrowck-borrowed-uniq-rvalue.rs b/src/test/compile-fail/borrowck-borrowed-uniq-rvalue.rs index 785929fe002..49ea43439d1 100644 --- a/src/test/compile-fail/borrowck-borrowed-uniq-rvalue.rs +++ b/src/test/compile-fail/borrowck-borrowed-uniq-rvalue.rs @@ -5,8 +5,7 @@ use std::map; fn main() { let buggy_map :hashmap = - hashmap::(|x| { uint::hash(*x) }, - |x, y| { uint::eq(*x, *y) }); + hashmap::(); buggy_map.insert(42, ~1); //~ ERROR illegal borrow // but it is ok if we use a temporary diff --git a/src/test/compile-fail/regions-glb-free-free.rs b/src/test/compile-fail/regions-glb-free-free.rs index 4e35380623d..28c6e7222e2 100644 --- a/src/test/compile-fail/regions-glb-free-free.rs +++ b/src/test/compile-fail/regions-glb-free-free.rs @@ -1,7 +1,6 @@ mod argparse { use std; - import std::map; import either::{Either, Left, Right}; struct Flag { diff --git a/src/test/run-fail/unwind-misc-1.rs b/src/test/run-fail/unwind-misc-1.rs index a29aad2b7b0..5af2191c151 100644 --- a/src/test/run-fail/unwind-misc-1.rs +++ b/src/test/run-fail/unwind-misc-1.rs @@ -6,19 +6,13 @@ use std::map::hashmap; fn main() { let count = @mut 0u; - pure fn hash(s: &~[@~str]) -> uint { - if vec::len(*s) > 0u && *s[0] == ~"boom" { fail; } - return 10u; - } - pure fn eq(s: &~[@~str], t: &~[@~str]) -> bool { - return *s == *t; - } - - let map = map::hashmap(hash, eq); + let map = map::hashmap(); let mut arr = ~[]; for uint::range(0u, 10u) |i| { arr += ~[@~"key stuff"]; map.insert(arr, arr + ~[@~"value stuff"]); + if arr.len() == 5 { + fail; + } } - map.insert(~[@~"boom"], ~[]); }