]> git.lizzy.rs Git - rust.git/commitdiff
use TotalEq for HashMap
authorDaniel Micay <danielmicay@gmail.com>
Sat, 22 Mar 2014 20:30:45 +0000 (16:30 -0400)
committerDaniel Micay <danielmicay@gmail.com>
Sun, 23 Mar 2014 05:59:11 +0000 (01:59 -0400)
Closes #5283

28 files changed:
src/libcollections/enum_set.rs
src/libcollections/hashmap.rs
src/libcollections/lru_cache.rs
src/librustc/middle/borrowck/mod.rs
src/librustc/middle/mem_categorization.rs
src/librustc/middle/resolve.rs
src/librustc/middle/trans/common.rs
src/librustc/middle/trans/datum.rs
src/librustc/middle/ty.rs
src/librustc/middle/typeck/infer/region_inference/mod.rs
src/librustc/middle/typeck/mod.rs
src/librustc/util/nodemap.rs
src/libserialize/collection_impls.rs
src/libstd/fmt/parse.rs
src/libstd/path/posix.rs
src/libstd/path/windows.rs
src/libstd/ptr.rs
src/libstd/rc.rs
src/libsyntax/abi.rs
src/libsyntax/ast.rs
src/libsyntax/codemap.rs
src/libsyntax/owned_slice.rs
src/libsyntax/parse/obsolete.rs
src/libsyntax/parse/token.rs
src/libsyntax/util/interner.rs
src/libtest/stats.rs
src/test/run-pass/issue-12860.rs
src/test/run-pass/regions-mock-tcx.rs

index 7fda99d8d2cbac39134fa2b564f97c70f0bcc3bf..07f3181d218e591f0b21c37d4b8f32eeb66f6b4f 100644 (file)
@@ -15,7 +15,7 @@
 
 use std::num::Bitwise;
 
-#[deriving(Clone, Eq, Hash, Show)]
+#[deriving(Clone, Eq, TotalEq, Hash, Show)]
 /// A specialized Set implementation to use enum types.
 pub struct EnumSet<E> {
     // We must maintain the invariant that no bits are set
index a1f815df72e801efae7544a0471002f54f144dde..5ec5db45f275fcac2687354f44fbc82366bf65b4 100644 (file)
@@ -12,7 +12,7 @@
 
 use std::container::{Container, Mutable, Map, MutableMap, Set, MutableSet};
 use std::clone::Clone;
-use std::cmp::{Eq, Equiv, max};
+use std::cmp::{Eq, TotalEq, Equiv, max};
 use std::default::Default;
 use std::fmt;
 use std::fmt::Show;
@@ -140,6 +140,7 @@ pub enum BucketState {
     }
 
     /// A hash that is not zero, since we use that to represent empty buckets.
+    #[deriving(Eq)]
     pub struct SafeHash {
         priv hash: u64,
     }
@@ -149,10 +150,6 @@ impl SafeHash {
         pub fn inspect(&self) -> u64 { self.hash }
     }
 
-    impl Eq for SafeHash {
-        fn eq(&self, other: &SafeHash) -> bool { self.hash == other.hash }
-    }
-
     /// We need to remove hashes of 0. That's reserved for empty buckets.
     /// This function wraps up `hash_keyed` to be the only way outside this
     /// module to generate a SafeHash.
@@ -698,7 +695,7 @@ fn grow_at(capacity: uint, load_factor: Fraction) -> uint {
     fraction_mul(capacity, load_factor)
 }
 
-impl<K: Eq + Hash<S>, V, S, H: Hasher<S>> HashMap<K, V, H> {
+impl<K: TotalEq + Hash<S>, V, S, H: Hasher<S>> HashMap<K, V, H> {
     /// Get the number of elements which will force the capacity to shrink.
     /// When size == self.shrink_at(), we halve the capacity.
     fn shrink_at(&self) -> uint {
@@ -799,12 +796,12 @@ fn search(&self, k: &K) -> Option<table::FullIndex> {
     }
 }
 
-impl<K: Eq + Hash<S>, V, S, H: Hasher<S>> Container for HashMap<K, V, H> {
+impl<K: TotalEq + Hash<S>, V, S, H: Hasher<S>> Container for HashMap<K, V, H> {
     /// Return the number of elements in the map
     fn len(&self) -> uint { self.table.size() }
 }
 
-impl<K: Eq + Hash<S>, V, S, H: Hasher<S>> Mutable for HashMap<K, V, H> {
+impl<K: TotalEq + Hash<S>, V, S, H: Hasher<S>> Mutable for HashMap<K, V, H> {
     /// Clear the map, removing all key-value pairs.
     fn clear(&mut self) {
         self.minimum_capacity = self.table.size();
@@ -819,7 +816,7 @@ fn clear(&mut self) {
 }
 
 
-impl<K: Eq + Hash<S>, V, S, H: Hasher<S>> Map<K, V> for HashMap<K, V, H> {
+impl<K: TotalEq + Hash<S>, V, S, H: Hasher<S>> Map<K, V> for HashMap<K, V, H> {
     fn find<'a>(&'a self, k: &K) -> Option<&'a V> {
         self.search(k).map(|idx| {
             let (_, v) = self.table.read(&idx);
@@ -832,7 +829,7 @@ fn contains_key(&self, k: &K) -> bool {
     }
 }
 
-impl<K: Eq + Hash<S>, V, S, H: Hasher<S>> MutableMap<K, V> for HashMap<K, V, H> {
+impl<K: TotalEq + Hash<S>, V, S, H: Hasher<S>> MutableMap<K, V> for HashMap<K, V, H> {
     fn find_mut<'a>(&'a mut self, k: &K) -> Option<&'a mut V> {
         match self.search(k) {
             None => None,
@@ -969,7 +966,7 @@ fn pop(&mut self, k: &K) -> Option<V> {
     }
 }
 
-impl<K: Hash + Eq, V> HashMap<K, V, sip::SipHasher> {
+impl<K: Hash + TotalEq, V> HashMap<K, V, sip::SipHasher> {
     /// Create an empty HashMap.
     pub fn new() -> HashMap<K, V, sip::SipHasher> {
         HashMap::with_capacity(INITIAL_CAPACITY)
@@ -984,7 +981,7 @@ pub fn with_capacity(capacity: uint) -> HashMap<K, V, sip::SipHasher> {
     }
 }
 
-impl<K: Eq + Hash<S>, V, S, H: Hasher<S>> HashMap<K, V, H> {
+impl<K: TotalEq + Hash<S>, V, S, H: Hasher<S>> HashMap<K, V, H> {
     pub fn with_hasher(hasher: H) -> HashMap<K, V, H> {
         HashMap::with_capacity_and_hasher(INITIAL_CAPACITY, hasher)
     }
@@ -1296,7 +1293,7 @@ pub fn move_iter(self) -> MoveEntries<K, V> {
     }
 }
 
-impl<K: Eq + Hash<S>, V: Clone, S, H: Hasher<S>> HashMap<K, V, H> {
+impl<K: TotalEq + Hash<S>, V: Clone, S, H: Hasher<S>> HashMap<K, V, H> {
     /// Like `find`, but returns a copy of the value.
     pub fn find_copy(&self, k: &K) -> Option<V> {
         self.find(k).map(|v| (*v).clone())
@@ -1308,7 +1305,7 @@ pub fn get_copy(&self, k: &K) -> V {
     }
 }
 
-impl<K: Eq + Hash<S>, V: Eq, S, H: Hasher<S>> Eq for HashMap<K, V, H> {
+impl<K: TotalEq + Hash<S>, V: Eq, S, H: Hasher<S>> Eq for HashMap<K, V, H> {
     fn eq(&self, other: &HashMap<K, V, H>) -> bool {
         if self.len() != other.len() { return false; }
 
@@ -1321,7 +1318,7 @@ fn eq(&self, other: &HashMap<K, V, H>) -> bool {
     }
 }
 
-impl<K: Eq + Hash<S> + Show, V: Show, S, H: Hasher<S>> Show for HashMap<K, V, H> {
+impl<K: TotalEq + Hash<S> + Show, V: Show, S, H: Hasher<S>> Show for HashMap<K, V, H> {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         try!(write!(f.buf, r"\{"));
 
@@ -1334,7 +1331,7 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
     }
 }
 
-impl<K: Eq + Hash<S>, V, S, H: Hasher<S> + Default> Default for HashMap<K, V, H> {
+impl<K: TotalEq + Hash<S>, V, S, H: Hasher<S> + Default> Default for HashMap<K, V, H> {
     fn default() -> HashMap<K, V, H> {
         HashMap::with_capacity_and_hasher(INITIAL_CAPACITY, Default::default())
     }
@@ -1358,7 +1355,7 @@ fn default() -> HashMap<K, V, H> {
 pub type Values<'a, K, V> =
     iter::Map<'static, (&'a K, &'a V), &'a V, Entries<'a, K, V>>;
 
-impl<K: Eq + Hash<S>, V, S, H: Hasher<S> + Default> FromIterator<(K, V)> for HashMap<K, V, H> {
+impl<K: TotalEq + Hash<S>, V, S, H: Hasher<S> + Default> FromIterator<(K, V)> for HashMap<K, V, H> {
     fn from_iterator<T: Iterator<(K, V)>>(iter: &mut T) -> HashMap<K, V, H> {
         let (lower, _) = iter.size_hint();
         let mut map = HashMap::with_capacity_and_hasher(lower, Default::default());
@@ -1367,7 +1364,7 @@ fn from_iterator<T: Iterator<(K, V)>>(iter: &mut T) -> HashMap<K, V, H> {
     }
 }
 
-impl<K: Eq + Hash<S>, V, S, H: Hasher<S> + Default> Extendable<(K, V)> for HashMap<K, V, H> {
+impl<K: TotalEq + Hash<S>, V, S, H: Hasher<S> + Default> Extendable<(K, V)> for HashMap<K, V, H> {
     fn extend<T: Iterator<(K, V)>>(&mut self, iter: &mut T) {
         for (k, v) in *iter {
             self.insert(k, v);
@@ -1391,7 +1388,7 @@ pub struct HashSet<T, H = sip::SipHasher> {
     priv map: HashMap<T, (), H>
 }
 
-impl<T: Eq + Hash<S>, S, H: Hasher<S>> Eq for HashSet<T, H> {
+impl<T: TotalEq + Hash<S>, S, H: Hasher<S>> Eq for HashSet<T, H> {
     // FIXME #11998: Since the value is a (), and `find` returns a Some(&()),
     // we trigger #11998 when matching on it. I've fallen back to manual
     // iteration until this is fixed.
@@ -1402,17 +1399,17 @@ fn eq(&self, other: &HashSet<T, H>) -> bool {
     }
 }
 
-impl<T: Eq + Hash<S>, S, H: Hasher<S>> Container for HashSet<T, H> {
+impl<T: TotalEq + Hash<S>, S, H: Hasher<S>> Container for HashSet<T, H> {
     /// Return the number of elements in the set
     fn len(&self) -> uint { self.map.len() }
 }
 
-impl<T: Eq + Hash<S>, S, H: Hasher<S>> Mutable for HashSet<T, H> {
+impl<T: TotalEq + Hash<S>, S, H: Hasher<S>> Mutable for HashSet<T, H> {
     /// Clear the set, removing all values.
     fn clear(&mut self) { self.map.clear() }
 }
 
-impl<T: Eq + Hash<S>, S, H: Hasher<S>> Set<T> for HashSet<T, H> {
+impl<T: TotalEq + Hash<S>, S, H: Hasher<S>> Set<T> for HashSet<T, H> {
     /// Return true if the set contains a value
     fn contains(&self, value: &T) -> bool { self.map.search(value).is_some() }
 
@@ -1433,7 +1430,7 @@ fn is_superset(&self, other: &HashSet<T, H>) -> bool {
     }
 }
 
-impl<T: Eq + Hash<S>, S, H: Hasher<S>> MutableSet<T> for HashSet<T, H> {
+impl<T: TotalEq + Hash<S>, S, H: Hasher<S>> MutableSet<T> for HashSet<T, H> {
     /// Add a value to the set. Return true if the value was not already
     /// present in the set.
     fn insert(&mut self, value: T) -> bool { self.map.insert(value, ()) }
@@ -1443,7 +1440,7 @@ fn insert(&mut self, value: T) -> bool { self.map.insert(value, ()) }
     fn remove(&mut self, value: &T) -> bool { self.map.remove(value) }
 }
 
-impl<T: Hash + Eq> HashSet<T, sip::SipHasher> {
+impl<T: Hash + TotalEq> HashSet<T, sip::SipHasher> {
     /// Create an empty HashSet
     pub fn new() -> HashSet<T, sip::SipHasher> {
         HashSet::with_capacity(INITIAL_CAPACITY)
@@ -1456,7 +1453,7 @@ pub fn with_capacity(capacity: uint) -> HashSet<T, sip::SipHasher> {
     }
 }
 
-impl<T: Eq + Hash<S>, S, H: Hasher<S>> HashSet<T, H> {
+impl<T: TotalEq + Hash<S>, S, H: Hasher<S>> HashSet<T, H> {
     pub fn with_hasher(hasher: H) -> HashSet<T, H> {
         HashSet::with_capacity_and_hasher(INITIAL_CAPACITY, hasher)
     }
@@ -1529,7 +1526,7 @@ pub fn union<'a>(&'a self, other: &'a HashSet<T, H>)
 
 }
 
-impl<T: Eq + Hash<S> + fmt::Show, S, H: Hasher<S>> fmt::Show for HashSet<T, H> {
+impl<T: TotalEq + Hash<S> + fmt::Show, S, H: Hasher<S>> fmt::Show for HashSet<T, H> {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         try!(write!(f.buf, r"\{"));
 
@@ -1542,7 +1539,7 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
     }
 }
 
-impl<T: Eq + Hash<S>, S, H: Hasher<S> + Default> FromIterator<T> for HashSet<T, H> {
+impl<T: TotalEq + Hash<S>, S, H: Hasher<S> + Default> FromIterator<T> for HashSet<T, H> {
     fn from_iterator<I: Iterator<T>>(iter: &mut I) -> HashSet<T, H> {
         let (lower, _) = iter.size_hint();
         let mut set = HashSet::with_capacity_and_hasher(lower, Default::default());
@@ -1551,7 +1548,7 @@ fn from_iterator<I: Iterator<T>>(iter: &mut I) -> HashSet<T, H> {
     }
 }
 
-impl<T: Eq + Hash<S>, S, H: Hasher<S> + Default> Extendable<T> for HashSet<T, H> {
+impl<T: TotalEq + Hash<S>, S, H: Hasher<S> + Default> Extendable<T> for HashSet<T, H> {
     fn extend<I: Iterator<T>>(&mut self, iter: &mut I) {
         for k in *iter {
             self.insert(k);
@@ -1559,7 +1556,7 @@ fn extend<I: Iterator<T>>(&mut self, iter: &mut I) {
     }
 }
 
-impl<T: Eq + Hash> Default for HashSet<T, sip::SipHasher> {
+impl<T: TotalEq + Hash> Default for HashSet<T, sip::SipHasher> {
     fn default() -> HashSet<T> { HashSet::new() }
 }
 
@@ -1601,7 +1598,7 @@ fn test_insert() {
 
     local_data_key!(drop_vector: vec::Vec<int>)
 
-    #[deriving(Hash, Eq)]
+    #[deriving(Hash, Eq, TotalEq)]
     struct Dropable {
         k: int
     }
index 28ea36fa2317a2a2597d47e05ff626bfae3beb6a..e328b41cc0fff83cc06b093fa2caf7fe0e711141 100644 (file)
@@ -74,6 +74,8 @@ fn eq(&self, other: &KeyRef<K>) -> bool {
     }
 }
 
+impl<K: TotalEq> TotalEq for KeyRef<K> {}
+
 impl<K, V> LruEntry<K, V> {
     fn new() -> LruEntry<K, V> {
         LruEntry {
@@ -94,7 +96,7 @@ fn with_key_value(k: K, v: V) -> LruEntry<K, V> {
     }
 }
 
-impl<K: Hash + Eq, V> LruCache<K, V> {
+impl<K: Hash + TotalEq, V> LruCache<K, V> {
     /// Create an LRU Cache that holds at most `capacity` items.
     pub fn new(capacity: uint) -> LruCache<K, V> {
         let cache = LruCache {
@@ -218,7 +220,7 @@ fn attach(&mut self, node: *mut LruEntry<K, V>) {
     }
 }
 
-impl<A: fmt::Show + Hash + Eq, B: fmt::Show> fmt::Show for LruCache<A, B> {
+impl<A: fmt::Show + Hash + TotalEq, B: fmt::Show> fmt::Show for LruCache<A, B> {
     /// Return a string that lists the key-value pairs from most-recently
     /// used to least-recently used.
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
@@ -247,14 +249,14 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
     }
 }
 
-impl<K: Hash + Eq, V> Container for LruCache<K, V> {
+impl<K: Hash + TotalEq, V> Container for LruCache<K, V> {
     /// Return the number of key-value pairs in the cache.
     fn len(&self) -> uint {
         self.map.len()
     }
 }
 
-impl<K: Hash + Eq, V> Mutable for LruCache<K, V> {
+impl<K: Hash + TotalEq, V> Mutable for LruCache<K, V> {
     /// Clear the cache of all key-value pairs.
     fn clear(&mut self) {
         self.map.clear();
index 62e79fe8dbd4534345bec9e71f70a1a6d2efec6c..d7d936a704893860cef1a74e4da88cc18affb3d5 100644 (file)
@@ -205,7 +205,7 @@ pub struct BorrowStats {
 //
 // Note that there is no entry with derefs:3---the type of that expression
 // is T, which is not a box.
-#[deriving(Eq, Hash)]
+#[deriving(Eq, TotalEq, Hash)]
 pub struct root_map_key {
     id: ast::NodeId,
     derefs: uint
@@ -243,13 +243,13 @@ pub enum LoanCause {
     RefBinding,
 }
 
-#[deriving(Eq, Hash)]
+#[deriving(Eq, TotalEq, Hash)]
 pub enum LoanPath {
     LpVar(ast::NodeId),               // `x` in doc.rs
     LpExtend(@LoanPath, mc::MutabilityCategory, LoanPathElem)
 }
 
-#[deriving(Eq, Hash)]
+#[deriving(Eq, TotalEq, Hash)]
 pub enum LoanPathElem {
     LpDeref(mc::PointerKind),    // `*LV` in doc.rs
     LpInterior(mc::InteriorKind) // `LV.f` in doc.rs
index 36f981f12dd59b5a192723fa9aa6c760b546aa07..1eb6ab4a8b889064a78b9521e69eb3fe492a7f6c 100644 (file)
@@ -95,7 +95,7 @@ pub struct CopiedUpvar {
 }
 
 // different kinds of pointers:
-#[deriving(Eq, Hash)]
+#[deriving(Eq, TotalEq, Hash)]
 pub enum PointerKind {
     OwnedPtr,
     GcPtr,
@@ -105,26 +105,26 @@ pub enum PointerKind {
 
 // We use the term "interior" to mean "something reachable from the
 // base without a pointer dereference", e.g. a field
-#[deriving(Eq, Hash)]
+#[deriving(Eq, TotalEq, Hash)]
 pub enum InteriorKind {
     InteriorField(FieldName),
     InteriorElement(ElementKind),
 }
 
-#[deriving(Eq, Hash)]
+#[deriving(Eq, TotalEq, Hash)]
 pub enum FieldName {
     NamedField(ast::Name),
     PositionalField(uint)
 }
 
-#[deriving(Eq, Hash)]
+#[deriving(Eq, TotalEq, Hash)]
 pub enum ElementKind {
     VecElement,
     StrElement,
     OtherElement,
 }
 
-#[deriving(Eq, Hash, Show)]
+#[deriving(Eq, TotalEq, Hash, Show)]
 pub enum MutabilityCategory {
     McImmutable, // Immutable.
     McDeclared,  // Directly declared as mutable.
index 292111d7fc3e52de495988e96dad1889826a61a2..d86e05395b4c8b5a218ed6dd9ac948fb05c0542b 100644 (file)
@@ -107,7 +107,7 @@ enum PatternBindingMode {
     ArgumentIrrefutableMode,
 }
 
-#[deriving(Eq, Hash)]
+#[deriving(Eq, TotalEq, Hash)]
 enum Namespace {
     TypeNS,
     ValueNS
index 9787e9228bf9105d4896e9d40634eff3b003f716..78700bab3f24d55a81bd3f1c6b75898fe22a5464 100644 (file)
@@ -710,7 +710,7 @@ pub fn is_null(val: ValueRef) -> bool {
 }
 
 // Used to identify cached monomorphized functions and vtables
-#[deriving(Eq, Hash)]
+#[deriving(Eq, TotalEq, Hash)]
 pub enum mono_param_id {
     mono_precise(ty::t, Option<@Vec<mono_id> >),
     mono_any,
@@ -720,7 +720,7 @@ pub enum mono_param_id {
               datum::RvalueMode),
 }
 
-#[deriving(Eq, Hash)]
+#[deriving(Eq, TotalEq, Hash)]
 pub enum MonoDataClass {
     MonoBits,    // Anything not treated differently from arbitrary integer data
     MonoNonNull, // Non-null pointers (used for optional-pointer optimization)
@@ -742,7 +742,7 @@ pub fn mono_data_classify(t: ty::t) -> MonoDataClass {
     }
 }
 
-#[deriving(Eq, Hash)]
+#[deriving(Eq, TotalEq, Hash)]
 pub struct mono_id_ {
     def: ast::DefId,
     params: Vec<mono_param_id> }
index c334971db5934ab44d99ea00d20cee1d0da9d4d0..4ca2b5a47b05e282aac8073b6ce104564e9a419d 100644 (file)
@@ -82,7 +82,7 @@ impl Drop for Rvalue {
     fn drop(&mut self) { }
 }
 
-#[deriving(Eq, Hash)]
+#[deriving(Eq, TotalEq, Hash)]
 pub enum RvalueMode {
     /// `val` is a pointer to the actual value (and thus has type *T)
     ByRef,
index e9378218ce3a05f2b3d3c30fc828443c809197df..425ac4f85e16ed353daf43aa193b3e482bca9eae 100644 (file)
@@ -62,7 +62,7 @@
 
 // Data types
 
-#[deriving(Eq, Hash)]
+#[deriving(Eq, TotalEq, Hash)]
 pub struct field {
     ident: ast::Ident,
     mt: mt
@@ -123,20 +123,20 @@ pub struct Impl {
     ident: Ident,
     methods: Vec<@Method> }
 
-#[deriving(Clone, Eq, Hash)]
+#[deriving(Clone, Eq, TotalEq, Hash)]
 pub struct mt {
     ty: t,
     mutbl: ast::Mutability,
 }
 
-#[deriving(Clone, Eq, Encodable, Decodable, Hash, Show)]
+#[deriving(Clone, Eq, TotalEq, Encodable, Decodable, Hash, Show)]
 pub enum vstore {
     vstore_fixed(uint),
     vstore_uniq,
     vstore_slice(Region)
 }
 
-#[deriving(Clone, Eq, Hash, Encodable, Decodable, Show)]
+#[deriving(Clone, Eq, TotalEq, Hash, Encodable, Decodable, Show)]
 pub enum TraitStore {
     UniqTraitStore,             // ~Trait
     RegionTraitStore(Region),   // &Trait
@@ -150,7 +150,7 @@ pub struct field_ty {
 
 // Contains information needed to resolve types and (in the future) look up
 // the types of AST nodes.
-#[deriving(Eq, Hash)]
+#[deriving(Eq, TotalEq, Hash)]
 pub struct creader_cache_key {
     cnum: CrateNum,
     pos: uint,
@@ -177,6 +177,8 @@ fn ne(&self, other: &intern_key) -> bool {
     }
 }
 
+impl TotalEq for intern_key {}
+
 impl<W:Writer> Hash<W> for intern_key {
     fn hash(&self, s: &mut W) {
         unsafe { (*self.sty).hash(s) }
@@ -382,7 +384,7 @@ pub struct t_box_ {
 // alive, and using ty::get is unsafe when the ctxt is no longer alive.
 enum t_opaque {}
 
-#[deriving(Clone, Eq, Hash)]
+#[deriving(Clone, Eq, TotalEq, Hash)]
 pub struct t { priv inner: *t_opaque }
 
 impl fmt::Show for t {
@@ -413,14 +415,14 @@ pub fn type_has_regions(t: t) -> bool {
 }
 pub fn type_id(t: t) -> uint { get(t).id }
 
-#[deriving(Clone, Eq, Hash)]
+#[deriving(Clone, Eq, TotalEq, Hash)]
 pub struct BareFnTy {
     purity: ast::Purity,
     abis: AbiSet,
     sig: FnSig
 }
 
-#[deriving(Clone, Eq, Hash)]
+#[deriving(Clone, Eq, TotalEq, Hash)]
 pub struct ClosureTy {
     purity: ast::Purity,
     sigil: ast::Sigil,
@@ -442,7 +444,7 @@ pub struct ClosureTy {
  * - `output` is the return type.
  * - `variadic` indicates whether this is a varidic function. (only true for foreign fns)
  */
-#[deriving(Clone, Eq, Hash)]
+#[deriving(Clone, Eq, TotalEq, Hash)]
 pub struct FnSig {
     binder_id: ast::NodeId,
     inputs: Vec<t>,
@@ -450,14 +452,14 @@ pub struct FnSig {
     variadic: bool
 }
 
-#[deriving(Clone, Eq, Hash)]
+#[deriving(Clone, Eq, TotalEq, Hash)]
 pub struct param_ty {
     idx: uint,
     def_id: DefId
 }
 
 /// Representation of regions:
-#[deriving(Clone, Eq, Hash, Encodable, Decodable, Show)]
+#[deriving(Clone, Eq, TotalEq, Hash, Encodable, Decodable, Show)]
 pub enum Region {
     // Region bound in a type or fn declaration which will be
     // substituted 'early' -- that is, at the same time when type
@@ -498,13 +500,13 @@ pub enum Region {
  * the original var id (that is, the root variable that is referenced
  * by the upvar) and the id of the closure expression.
  */
-#[deriving(Clone, Eq, Hash)]
+#[deriving(Clone, Eq, TotalEq, Hash)]
 pub struct UpvarId {
     var_id: ast::NodeId,
     closure_expr_id: ast::NodeId,
 }
 
-#[deriving(Clone, Eq, Hash)]
+#[deriving(Clone, Eq, TotalEq, Hash)]
 pub enum BorrowKind {
     /// Data must be immutable and is aliasable.
     ImmBorrow,
@@ -642,7 +644,7 @@ pub enum BoundRegion {
  * Represents the values to use when substituting lifetime parameters.
  * If the value is `ErasedRegions`, then this subst is occurring during
  * trans, and all region parameters will be replaced with `ty::ReStatic`. */
-#[deriving(Clone, Eq, Hash)]
+#[deriving(Clone, Eq, TotalEq, Hash)]
 pub enum RegionSubsts {
     ErasedRegions,
     NonerasedRegions(OwnedSlice<ty::Region>)
@@ -665,7 +667,7 @@ pub enum RegionSubsts {
  * - `self_ty` is the type to which `self` should be remapped, if any.  The
  *   `self` type is rather funny in that it can only appear on traits and is
  *   always substituted away to the implementing type for a trait. */
-#[deriving(Clone, Eq, Hash)]
+#[deriving(Clone, Eq, TotalEq, Hash)]
 pub struct substs {
     self_ty: Option<ty::t>,
     tps: Vec<t>,
@@ -720,7 +722,7 @@ macro_rules! def_prim_ty(
 
 // NB: If you change this, you'll probably want to change the corresponding
 // AST structure in libsyntax/ast.rs as well.
-#[deriving(Clone, Eq, Hash)]
+#[deriving(Clone, Eq, TotalEq, Hash)]
 pub enum sty {
     ty_nil,
     ty_bot,
@@ -755,7 +757,7 @@ pub enum sty {
     ty_unboxed_vec(mt),
 }
 
-#[deriving(Clone, Eq, Hash)]
+#[deriving(Clone, Eq, TotalEq, Hash)]
 pub struct TyTrait {
     def_id: DefId,
     substs: substs,
@@ -764,7 +766,7 @@ pub struct TyTrait {
     bounds: BuiltinBounds
 }
 
-#[deriving(Eq, Hash)]
+#[deriving(Eq, TotalEq, Hash)]
 pub struct TraitRef {
     def_id: DefId,
     substs: substs
@@ -826,14 +828,14 @@ pub enum type_err {
     terr_variadic_mismatch(expected_found<bool>)
 }
 
-#[deriving(Eq, Hash)]
+#[deriving(Eq, TotalEq, Hash)]
 pub struct ParamBounds {
     builtin_bounds: BuiltinBounds,
     trait_bounds: Vec<@TraitRef> }
 
 pub type BuiltinBounds = EnumSet<BuiltinBound>;
 
-#[deriving(Clone, Encodable, Eq, Decodable, Hash, Show)]
+#[deriving(Clone, Encodable, Eq, TotalEq, Decodable, Hash, Show)]
 #[repr(uint)]
 pub enum BuiltinBound {
     BoundStatic,
@@ -865,28 +867,28 @@ fn from_uint(v: uint) -> BuiltinBound {
     }
 }
 
-#[deriving(Clone, Eq, Hash)]
+#[deriving(Clone, Eq, TotalEq, Hash)]
 pub struct TyVid(uint);
 
-#[deriving(Clone, Eq, Hash)]
+#[deriving(Clone, Eq, TotalEq, Hash)]
 pub struct IntVid(uint);
 
-#[deriving(Clone, Eq, Hash)]
+#[deriving(Clone, Eq, TotalEq, Hash)]
 pub struct FloatVid(uint);
 
-#[deriving(Clone, Eq, Encodable, Decodable, Hash)]
+#[deriving(Clone, Eq, TotalEq, Encodable, Decodable, Hash)]
 pub struct RegionVid {
     id: uint
 }
 
-#[deriving(Clone, Eq, Hash)]
+#[deriving(Clone, Eq, TotalEq, Hash)]
 pub enum InferTy {
     TyVar(TyVid),
     IntVar(IntVid),
     FloatVar(FloatVid)
 }
 
-#[deriving(Clone, Encodable, Decodable, Hash, Show)]
+#[deriving(Clone, Encodable, Decodable, TotalEq, Hash, Show)]
 pub enum InferRegion {
     ReVar(RegionVid),
     ReSkolemized(uint, BoundRegion)
index 9d2713539887341300ff06690e4e16c4e6cd916f..567916a59f8f5e56e5d2bd156dc69f84c194ec08 100644 (file)
@@ -32,7 +32,7 @@
 
 mod doc;
 
-#[deriving(Eq, Hash)]
+#[deriving(Eq, TotalEq, Hash)]
 pub enum Constraint {
     ConstrainVarSubVar(RegionVid, RegionVid),
     ConstrainRegSubVar(Region, RegionVid),
@@ -40,7 +40,7 @@ pub enum Constraint {
     ConstrainRegSubReg(Region, Region),
 }
 
-#[deriving(Eq, Hash)]
+#[deriving(Eq, TotalEq, Hash)]
 pub struct TwoRegions {
     a: Region,
     b: Region,
index b33819ff7f464f4a43f8c77afb7bc094e7f7d2c7..67db5b7f39620f12c220e1b3478d384bb4a70cca 100644 (file)
@@ -148,7 +148,7 @@ pub struct MethodCallee {
     substs: ty::substs
 }
 
-#[deriving(Clone, Eq, Hash, Show)]
+#[deriving(Clone, Eq, TotalEq, Hash, Show)]
 pub struct MethodCall {
     expr_id: ast::NodeId,
     autoderef: u32
index bbe3192999af6211cf7abb39bdd3196339b9becf..ac4db178a008be244aff317b8097325ba4185471 100644 (file)
@@ -27,7 +27,7 @@
 pub mod FnvHashMap {
     use std::hash::Hash;
     use collections::HashMap;
-    pub fn new<K: Hash<super::FnvState> + Eq, V>() -> super::FnvHashMap<K, V> {
+    pub fn new<K: Hash<super::FnvState> + TotalEq, V>() -> super::FnvHashMap<K, V> {
         HashMap::with_hasher(super::FnvHasher)
     }
 }
index 2d86734e569e07264eab77cb3e6c1f2b17765fd8..bb823c2d8cae79c05b9b146bb7d6c16ca63776f0 100644 (file)
@@ -165,7 +165,7 @@ fn decode(d: &mut D) -> EnumSet<T> {
 
 impl<
     E: Encoder,
-    K: Encodable<E> + Hash<S> + Eq,
+    K: Encodable<E> + Hash<S> + TotalEq,
     V: Encodable<E>,
     S,
     H: Hasher<S>
@@ -184,7 +184,7 @@ fn encode(&self, e: &mut E) {
 
 impl<
     D: Decoder,
-    K: Decodable<D> + Hash<S> + Eq,
+    K: Decodable<D> + Hash<S> + TotalEq,
     V: Decodable<D>,
     S,
     H: Hasher<S> + Default
@@ -205,7 +205,7 @@ fn decode(d: &mut D) -> HashMap<K, V, H> {
 
 impl<
     E: Encoder,
-    T: Encodable<E> + Hash<S> + Eq,
+    T: Encodable<E> + Hash<S> + TotalEq,
     S,
     H: Hasher<S>
 > Encodable<E> for HashSet<T, H> {
@@ -222,7 +222,7 @@ fn encode(&self, s: &mut E) {
 
 impl<
     D: Decoder,
-    T: Decodable<D> + Hash<S> + Eq,
+    T: Decodable<D> + Hash<S> + TotalEq,
     S,
     H: Hasher<S> + Default
 > Decodable<D> for HashSet<T, H> {
index 948f85ca1c2629a1d98dd4f6ecff79e051bde8eb..67088e6f4f8c8aed0970b13be5b6f4f5c7785575 100644 (file)
@@ -121,7 +121,7 @@ pub enum Method<'a> {
 }
 
 /// A selector for what pluralization a plural method should take
-#[deriving(Eq, Hash)]
+#[deriving(Eq, TotalEq, Hash)]
 pub enum PluralSelector {
     /// One of the plural keywords should be used
     Keyword(PluralKeyword),
@@ -143,7 +143,7 @@ pub struct PluralArm<'a> {
 /// specially placed in the `Plural` variant of `Method`
 ///
 /// http://www.icu-project.org/apiref/icu4c/classicu_1_1PluralRules.html
-#[deriving(Eq, Hash)]
+#[deriving(Eq, TotalEq, Hash)]
 #[allow(missing_doc)]
 pub enum PluralKeyword {
     Zero, One, Two, Few, Many
index f654f59266aaf1f02f1db3d81bfe6fb61ea724f6..512b20ebf4ccf68c59a4199df1b47b240b8aa4db 100644 (file)
@@ -13,7 +13,7 @@
 use container::Container;
 use c_str::{CString, ToCStr};
 use clone::Clone;
-use cmp::Eq;
+use cmp::{Eq, TotalEq};
 use from_str::FromStr;
 use io::Writer;
 use iter::{AdditiveIterator, Extendable, Iterator, Map};
@@ -69,6 +69,8 @@ fn eq(&self, other: &Path) -> bool {
     }
 }
 
+impl TotalEq for Path {}
+
 impl FromStr for Path {
     fn from_str(s: &str) -> Option<Path> {
         Path::new_opt(s)
index dba8af4128ba29675dd08c321858d5e576857dfb..81da2f50f8de55952725f1de54b40e9385187633 100644 (file)
@@ -15,7 +15,7 @@
 use cast;
 use clone::Clone;
 use container::Container;
-use cmp::Eq;
+use cmp::{Eq, TotalEq};
 use from_str::FromStr;
 use io::Writer;
 use iter::{AdditiveIterator, DoubleEndedIterator, Extendable, Rev, Iterator, Map};
@@ -93,6 +93,8 @@ fn eq(&self, other: &Path) -> bool {
     }
 }
 
+impl TotalEq for Path {}
+
 impl FromStr for Path {
     fn from_str(s: &str) -> Option<Path> {
         Path::new_opt(s)
index 179100255c4fa6c32b3f762276d41783db0a5042..504c613bf4c1763e4e7f15eb53895b37df395c67 100644 (file)
@@ -19,7 +19,7 @@
 use option::{Option, Some, None};
 use intrinsics;
 
-#[cfg(not(test))] use cmp::{Eq, Ord};
+#[cfg(not(test))] use cmp::{Eq, TotalEq, Ord};
 
 /// Return the offset of the first null pointer in `buf`.
 #[inline]
@@ -272,6 +272,9 @@ fn eq(&self, other: &*T) -> bool {
     fn ne(&self, other: &*T) -> bool { !self.eq(other) }
 }
 
+#[cfg(not(test))]
+impl<T> TotalEq for *T {}
+
 #[cfg(not(test))]
 impl<T> Eq for *mut T {
     #[inline]
@@ -282,6 +285,9 @@ fn eq(&self, other: &*mut T) -> bool {
     fn ne(&self, other: &*mut T) -> bool { !self.eq(other) }
 }
 
+#[cfg(not(test))]
+impl<T> TotalEq for *mut T {}
+
 // Equivalence for pointers
 #[cfg(not(test))]
 impl<T> Equiv<*mut T> for *T {
index 8dd06cb923226308732c93fe02b8f5fa28c1b1e6..d26038f508f35b081463473a08ae46e981e3485b 100644 (file)
@@ -26,7 +26,7 @@
 use cast::transmute;
 use cell::Cell;
 use clone::Clone;
-use cmp::{Eq, Ord};
+use cmp::{Eq, Ord, TotalEq, TotalOrd, Ordering};
 use kinds::marker;
 use ops::{Deref, Drop};
 use option::{Option, Some, None};
@@ -127,6 +127,8 @@ fn eq(&self, other: &Rc<T>) -> bool { **self == **other }
     fn ne(&self, other: &Rc<T>) -> bool { **self != **other }
 }
 
+impl<T: TotalEq> TotalEq for Rc<T> {}
+
 impl<T: Ord> Ord for Rc<T> {
     #[inline(always)]
     fn lt(&self, other: &Rc<T>) -> bool { **self < **other }
@@ -141,6 +143,11 @@ fn gt(&self, other: &Rc<T>) -> bool { **self > **other }
     fn ge(&self, other: &Rc<T>) -> bool { **self >= **other }
 }
 
+impl<T: TotalOrd> TotalOrd for Rc<T> {
+    #[inline]
+    fn cmp(&self, other: &Rc<T>) -> Ordering { (**self).cmp(&**other) }
+}
+
 /// Weak reference to a reference-counted box
 #[unsafe_no_drop_flag]
 pub struct Weak<T> {
index b159920d929cf3bb3e670a34ea0d8bba55958ae3..b833eea6b560cf151dedba0e7eae4b90fdf1c7a7 100644 (file)
@@ -14,7 +14,7 @@
 #[deriving(Eq)]
 pub enum Os { OsWin32, OsMacos, OsLinux, OsAndroid, OsFreebsd, }
 
-#[deriving(Eq, Hash)]
+#[deriving(Eq, TotalEq, Hash)]
 pub enum Abi {
     // NB: This ordering MUST match the AbiDatas array below.
     // (This is ensured by the test indices_are_correct().)
@@ -65,7 +65,7 @@ pub enum AbiArchitecture {
     Archs(u32)  // Multiple architectures (bitset)
 }
 
-#[deriving(Clone, Eq, Encodable, Decodable, Hash)]
+#[deriving(Clone, Eq, TotalEq, Encodable, Decodable, Hash)]
 pub struct AbiSet {
     priv bits: u32   // each bit represents one of the abis below
 }
index f2a256165e2973d9fc53ed07acbf2876a90b5134..24b8a3457763881d69bf2594eeafb9c1af888d2c 100644 (file)
@@ -113,7 +113,7 @@ fn decode(d: &mut D) -> Ident {
 /// Function name (not all functions have names)
 pub type FnIdent = Option<Ident>;
 
-#[deriving(Clone, Eq, Encodable, Decodable, Hash)]
+#[deriving(Clone, Eq, TotalEq, Encodable, Decodable, Hash)]
 pub struct Lifetime {
     id: NodeId,
     span: Span,
@@ -124,7 +124,7 @@ pub struct Lifetime {
 // for instance: std::cmp::Eq  .  It's represented
 // as a sequence of identifiers, along with a bunch
 // of supporting information.
-#[deriving(Clone, Eq, Encodable, Decodable, Hash)]
+#[deriving(Clone, Eq, TotalEq, Encodable, Decodable, Hash)]
 pub struct Path {
     span: Span,
     /// A `::foo` path, is relative to the crate root rather than current
@@ -136,7 +136,7 @@ pub struct Path {
 
 /// A segment of a path: an identifier, an optional lifetime, and a set of
 /// types.
-#[deriving(Clone, Eq, Encodable, Decodable, Hash)]
+#[deriving(Clone, Eq, TotalEq, Encodable, Decodable, Hash)]
 pub struct PathSegment {
     /// The identifier portion of this path segment.
     identifier: Ident,
@@ -170,13 +170,13 @@ pub struct DefId {
 // typeck::collect::compute_bounds matches these against
 // the "special" built-in traits (see middle::lang_items) and
 // detects Copy, Send and Share.
-#[deriving(Clone, Eq, Encodable, Decodable, Hash)]
+#[deriving(Clone, Eq, TotalEq, Encodable, Decodable, Hash)]
 pub enum TyParamBound {
     TraitTyParamBound(TraitRef),
     RegionTyParamBound
 }
 
-#[deriving(Clone, Eq, Encodable, Decodable, Hash)]
+#[deriving(Clone, Eq, TotalEq, Encodable, Decodable, Hash)]
 pub struct TyParam {
     ident: Ident,
     id: NodeId,
@@ -184,7 +184,7 @@ pub struct TyParam {
     default: Option<P<Ty>>
 }
 
-#[deriving(Clone, Eq, Encodable, Decodable, Hash)]
+#[deriving(Clone, Eq, TotalEq, Encodable, Decodable, Hash)]
 pub struct Generics {
     lifetimes: Vec<Lifetime>,
     ty_params: OwnedSlice<TyParam>,
@@ -202,13 +202,13 @@ pub fn is_type_parameterized(&self) -> bool {
     }
 }
 
-#[deriving(Clone, Eq, Encodable, Decodable, Hash)]
+#[deriving(Clone, Eq, TotalEq, Encodable, Decodable, Hash)]
 pub enum MethodProvenance {
     FromTrait(DefId),
     FromImpl(DefId),
 }
 
-#[deriving(Clone, Eq, Encodable, Decodable, Hash)]
+#[deriving(Clone, Eq, TotalEq, Encodable, Decodable, Hash)]
 pub enum Def {
     DefFn(DefId, Purity),
     DefStaticMethod(/* method */ DefId, MethodProvenance, Purity),
@@ -245,7 +245,7 @@ pub enum Def {
     DefMethod(DefId /* method */, Option<DefId> /* trait */),
 }
 
-#[deriving(Clone, Eq, Hash, Encodable, Decodable, Show)]
+#[deriving(Clone, Eq, TotalEq, Hash, Encodable, Decodable, Show)]
 pub enum DefRegion {
     DefStaticRegion,
     DefEarlyBoundRegion(/* index */ uint, /* lifetime decl */ NodeId),
@@ -257,7 +257,7 @@ pub enum DefRegion {
 // used to drive conditional compilation
 pub type CrateConfig = Vec<@MetaItem> ;
 
-#[deriving(Clone, Eq, Encodable, Decodable, Hash)]
+#[deriving(Clone, Eq, TotalEq, Encodable, Decodable, Hash)]
 pub struct Crate {
     module: Mod,
     attrs: Vec<Attribute> ,
@@ -267,7 +267,7 @@ pub struct Crate {
 
 pub type MetaItem = Spanned<MetaItem_>;
 
-#[deriving(Clone, Encodable, Decodable, Hash)]
+#[deriving(Clone, Encodable, Decodable, TotalEq, Hash)]
 pub enum MetaItem_ {
     MetaWord(InternedString),
     MetaList(InternedString, Vec<@MetaItem> ),
@@ -299,7 +299,7 @@ fn eq(&self, other: &MetaItem_) -> bool {
     }
 }
 
-#[deriving(Clone, Eq, Encodable, Decodable, Hash)]
+#[deriving(Clone, Eq, TotalEq, Encodable, Decodable, Hash)]
 pub struct Block {
     view_items: Vec<ViewItem> ,
     stmts: Vec<@Stmt> ,
@@ -309,26 +309,26 @@ pub struct Block {
     span: Span,
 }
 
-#[deriving(Clone, Eq, Encodable, Decodable, Hash)]
+#[deriving(Clone, Eq, TotalEq, Encodable, Decodable, Hash)]
 pub struct Pat {
     id: NodeId,
     node: Pat_,
     span: Span,
 }
 
-#[deriving(Clone, Eq, Encodable, Decodable, Hash)]
+#[deriving(Clone, Eq, TotalEq, Encodable, Decodable, Hash)]
 pub struct FieldPat {
     ident: Ident,
     pat: @Pat,
 }
 
-#[deriving(Clone, Eq, Encodable, Decodable, Hash)]
+#[deriving(Clone, Eq, TotalEq, Encodable, Decodable, Hash)]
 pub enum BindingMode {
     BindByRef(Mutability),
     BindByValue(Mutability),
 }
 
-#[deriving(Clone, Eq, Encodable, Decodable, Hash)]
+#[deriving(Clone, Eq, TotalEq, Encodable, Decodable, Hash)]
 pub enum Pat_ {
     PatWild,
     PatWildMulti,
@@ -353,13 +353,13 @@ pub enum Pat_ {
     PatVec(Vec<@Pat> , Option<@Pat>, Vec<@Pat> )
 }
 
-#[deriving(Clone, Eq, Encodable, Decodable, Hash, Show)]
+#[deriving(Clone, Eq, TotalEq, Encodable, Decodable, Hash, Show)]
 pub enum Mutability {
     MutMutable,
     MutImmutable,
 }
 
-#[deriving(Clone, Eq, Encodable, Decodable, Hash)]
+#[deriving(Clone, Eq, TotalEq, Encodable, Decodable, Hash)]
 pub enum Sigil {
     BorrowedSigil,
     OwnedSigil,
@@ -376,14 +376,14 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
     }
 }
 
-#[deriving(Clone, Eq, Encodable, Decodable, Hash)]
+#[deriving(Clone, Eq, TotalEq, Encodable, Decodable, Hash)]
 pub enum ExprVstore {
     ExprVstoreUniq,                 // ~[1,2,3,4]
     ExprVstoreSlice,                // &[1,2,3,4]
     ExprVstoreMutSlice,             // &mut [1,2,3,4]
 }
 
-#[deriving(Clone, Eq, Encodable, Decodable, Hash)]
+#[deriving(Clone, Eq, TotalEq, Encodable, Decodable, Hash)]
 pub enum BinOp {
     BiAdd,
     BiSub,
@@ -405,7 +405,7 @@ pub enum BinOp {
     BiGt,
 }
 
-#[deriving(Clone, Eq, Encodable, Decodable, Hash)]
+#[deriving(Clone, Eq, TotalEq, Encodable, Decodable, Hash)]
 pub enum UnOp {
     UnBox,
     UnUniq,
@@ -416,7 +416,7 @@ pub enum UnOp {
 
 pub type Stmt = Spanned<Stmt_>;
 
-#[deriving(Clone, Eq, Encodable, Decodable, Hash)]
+#[deriving(Clone, Eq, TotalEq, Encodable, Decodable, Hash)]
 pub enum Stmt_ {
     // could be an item or a local (let) binding:
     StmtDecl(@Decl, NodeId),
@@ -434,7 +434,7 @@ pub enum Stmt_ {
 // FIXME (pending discussion of #1697, #2178...): local should really be
 // a refinement on pat.
 /// Local represents a `let` statement, e.g., `let <pat>:<ty> = <expr>;`
-#[deriving(Eq, Encodable, Decodable, Hash)]
+#[deriving(Eq, TotalEq, Encodable, Decodable, Hash)]
 pub struct Local {
     ty: P<Ty>,
     pat: @Pat,
@@ -445,7 +445,7 @@ pub struct Local {
 
 pub type Decl = Spanned<Decl_>;
 
-#[deriving(Eq, Encodable, Decodable, Hash)]
+#[deriving(Eq, TotalEq, Encodable, Decodable, Hash)]
 pub enum Decl_ {
     // a local (let) binding:
     DeclLocal(@Local),
@@ -453,14 +453,14 @@ pub enum Decl_ {
     DeclItem(@Item),
 }
 
-#[deriving(Clone, Eq, Encodable, Decodable, Hash)]
+#[deriving(Clone, Eq, TotalEq, Encodable, Decodable, Hash)]
 pub struct Arm {
     pats: Vec<@Pat> ,
     guard: Option<@Expr>,
     body: @Expr,
 }
 
-#[deriving(Clone, Eq, Encodable, Decodable, Hash)]
+#[deriving(Clone, Eq, TotalEq, Encodable, Decodable, Hash)]
 pub struct Field {
     ident: SpannedIdent,
     expr: @Expr,
@@ -469,26 +469,26 @@ pub struct Field {
 
 pub type SpannedIdent = Spanned<Ident>;
 
-#[deriving(Clone, Eq, Encodable, Decodable, Hash)]
+#[deriving(Clone, Eq, TotalEq, Encodable, Decodable, Hash)]
 pub enum BlockCheckMode {
     DefaultBlock,
     UnsafeBlock(UnsafeSource),
 }
 
-#[deriving(Clone, Eq, Encodable, Decodable, Hash)]
+#[deriving(Clone, Eq, TotalEq, Encodable, Decodable, Hash)]
 pub enum UnsafeSource {
     CompilerGenerated,
     UserProvided,
 }
 
-#[deriving(Clone, Eq, Encodable, Decodable, Hash)]
+#[deriving(Clone, Eq, TotalEq, Encodable, Decodable, Hash)]
 pub struct Expr {
     id: NodeId,
     node: Expr_,
     span: Span,
 }
 
-#[deriving(Clone, Eq, Encodable, Decodable, Hash)]
+#[deriving(Clone, Eq, TotalEq, Encodable, Decodable, Hash)]
 pub enum Expr_ {
     ExprVstore(@Expr, ExprVstore),
     // First expr is the place; second expr is the value.
@@ -557,7 +557,7 @@ pub enum Expr_ {
 // else knows what to do with them, so you'll probably get a syntax
 // error.
 //
-#[deriving(Clone, Eq, Encodable, Decodable, Hash)]
+#[deriving(Clone, Eq, TotalEq, Encodable, Decodable, Hash)]
 #[doc="For macro invocations; parsing is delegated to the macro"]
 pub enum TokenTree {
     // a single token
@@ -631,7 +631,7 @@ pub enum TokenTree {
 //
 pub type Matcher = Spanned<Matcher_>;
 
-#[deriving(Clone, Eq, Encodable, Decodable, Hash)]
+#[deriving(Clone, Eq, TotalEq, Encodable, Decodable, Hash)]
 pub enum Matcher_ {
     // match one token
     MatchTok(::parse::token::Token),
@@ -648,12 +648,12 @@ pub enum Matcher_ {
 // is being invoked, and the vector of token-trees contains the source
 // of the macro invocation.
 // There's only one flavor, now, so this could presumably be simplified.
-#[deriving(Clone, Eq, Encodable, Decodable, Hash)]
+#[deriving(Clone, Eq, TotalEq, Encodable, Decodable, Hash)]
 pub enum Mac_ {
     MacInvocTT(Path, Vec<TokenTree> , SyntaxContext),   // new macro-invocation
 }
 
-#[deriving(Clone, Eq, Encodable, Decodable, Hash)]
+#[deriving(Clone, Eq, TotalEq, Encodable, Decodable, Hash)]
 pub enum StrStyle {
     CookedStr,
     RawStr(uint)
@@ -661,7 +661,7 @@ pub enum StrStyle {
 
 pub type Lit = Spanned<Lit_>;
 
-#[deriving(Clone, Eq, Encodable, Decodable, Hash)]
+#[deriving(Clone, Eq, TotalEq, Encodable, Decodable, Hash)]
 pub enum Lit_ {
     LitStr(InternedString, StrStyle),
     LitBinary(Rc<Vec<u8> >),
@@ -677,20 +677,20 @@ pub enum Lit_ {
 
 // NB: If you change this, you'll probably want to change the corresponding
 // type structure in middle/ty.rs as well.
-#[deriving(Clone, Eq, Encodable, Decodable, Hash)]
+#[deriving(Clone, Eq, TotalEq, Encodable, Decodable, Hash)]
 pub struct MutTy {
     ty: P<Ty>,
     mutbl: Mutability,
 }
 
-#[deriving(Eq, Encodable, Decodable, Hash)]
+#[deriving(Eq, TotalEq, Encodable, Decodable, Hash)]
 pub struct TypeField {
     ident: Ident,
     mt: MutTy,
     span: Span,
 }
 
-#[deriving(Clone, Eq, Encodable, Decodable, Hash)]
+#[deriving(Clone, Eq, TotalEq, Encodable, Decodable, Hash)]
 pub struct TypeMethod {
     ident: Ident,
     attrs: Vec<Attribute> ,
@@ -705,13 +705,13 @@ pub struct TypeMethod {
 // A trait method is either required (meaning it doesn't have an
 // implementation, just a signature) or provided (meaning it has a default
 // implementation).
-#[deriving(Clone, Eq, Encodable, Decodable, Hash)]
+#[deriving(Clone, Eq, TotalEq, Encodable, Decodable, Hash)]
 pub enum TraitMethod {
     Required(TypeMethod),
     Provided(@Method),
 }
 
-#[deriving(Clone, Eq, Encodable, Decodable, Hash)]
+#[deriving(Clone, Eq, TotalEq, Encodable, Decodable, Hash)]
 pub enum IntTy {
     TyI,
     TyI8,
@@ -726,7 +726,7 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
     }
 }
 
-#[deriving(Clone, Eq, Encodable, Decodable, Hash)]
+#[deriving(Clone, Eq, TotalEq, Encodable, Decodable, Hash)]
 pub enum UintTy {
     TyU,
     TyU8,
@@ -741,7 +741,7 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
     }
 }
 
-#[deriving(Clone, Eq, Encodable, Decodable, Hash)]
+#[deriving(Clone, Eq, TotalEq, Encodable, Decodable, Hash)]
 pub enum FloatTy {
     TyF32,
     TyF64,
@@ -754,7 +754,7 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
 }
 
 // NB Eq method appears below.
-#[deriving(Clone, Eq, Encodable, Decodable, Hash)]
+#[deriving(Clone, Eq, TotalEq, Encodable, Decodable, Hash)]
 pub struct Ty {
     id: NodeId,
     node: Ty_,
@@ -762,7 +762,7 @@ pub struct Ty {
 }
 
 // Not represented directly in the AST, referred to by name through a ty_path.
-#[deriving(Clone, Eq, Encodable, Decodable, Hash)]
+#[deriving(Clone, Eq, TotalEq, Encodable, Decodable, Hash)]
 pub enum PrimTy {
     TyInt(IntTy),
     TyUint(UintTy),
@@ -772,7 +772,7 @@ pub enum PrimTy {
     TyChar
 }
 
-#[deriving(Clone, Eq, Encodable, Decodable, Hash)]
+#[deriving(Clone, Eq, TotalEq, Encodable, Decodable, Hash)]
 pub enum Onceness {
     Once,
     Many
@@ -787,7 +787,7 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
     }
 }
 
-#[deriving(Eq, Encodable, Decodable, Hash)]
+#[deriving(Eq, TotalEq, Encodable, Decodable, Hash)]
 pub struct ClosureTy {
     sigil: Sigil,
     region: Option<Lifetime>,
@@ -802,7 +802,7 @@ pub struct ClosureTy {
     bounds: Option<OwnedSlice<TyParamBound>>,
 }
 
-#[deriving(Eq, Encodable, Decodable, Hash)]
+#[deriving(Eq, TotalEq, Encodable, Decodable, Hash)]
 pub struct BareFnTy {
     purity: Purity,
     abis: AbiSet,
@@ -810,7 +810,7 @@ pub struct BareFnTy {
     decl: P<FnDecl>
 }
 
-#[deriving(Clone, Eq, Encodable, Decodable, Hash)]
+#[deriving(Clone, Eq, TotalEq, Encodable, Decodable, Hash)]
 pub enum Ty_ {
     TyNil,
     TyBot, /* bottom type */
@@ -830,13 +830,13 @@ pub enum Ty_ {
     TyInfer,
 }
 
-#[deriving(Clone, Eq, Encodable, Decodable, Hash)]
+#[deriving(Clone, Eq, TotalEq, Encodable, Decodable, Hash)]
 pub enum AsmDialect {
     AsmAtt,
     AsmIntel
 }
 
-#[deriving(Clone, Eq, Encodable, Decodable, Hash)]
+#[deriving(Clone, Eq, TotalEq, Encodable, Decodable, Hash)]
 pub struct InlineAsm {
     asm: InternedString,
     asm_str_style: StrStyle,
@@ -848,7 +848,7 @@ pub struct InlineAsm {
     dialect: AsmDialect
 }
 
-#[deriving(Clone, Eq, Encodable, Decodable, Hash)]
+#[deriving(Clone, Eq, TotalEq, Encodable, Decodable, Hash)]
 pub struct Arg {
     ty: P<Ty>,
     pat: @Pat,
@@ -875,7 +875,7 @@ pub fn new_self(span: Span, mutability: Mutability) -> Arg {
     }
 }
 
-#[deriving(Clone, Eq, Encodable, Decodable, Hash)]
+#[deriving(Clone, Eq, TotalEq, Encodable, Decodable, Hash)]
 pub struct FnDecl {
     inputs: Vec<Arg> ,
     output: P<Ty>,
@@ -883,7 +883,7 @@ pub struct FnDecl {
     variadic: bool
 }
 
-#[deriving(Clone, Eq, Encodable, Decodable, Hash)]
+#[deriving(Clone, Eq, TotalEq, Encodable, Decodable, Hash)]
 pub enum Purity {
     UnsafeFn, // declared with "unsafe fn"
     ImpureFn, // declared with "fn"
@@ -900,14 +900,14 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
     }
 }
 
-#[deriving(Clone, Eq, Encodable, Decodable, Hash)]
+#[deriving(Clone, Eq, TotalEq, Encodable, Decodable, Hash)]
 pub enum RetStyle {
     NoReturn, // functions with return type _|_ that always
               // raise an error or exit (i.e. never return to the caller)
     Return, // everything else
 }
 
-#[deriving(Clone, Eq, Encodable, Decodable, Hash)]
+#[deriving(Clone, Eq, TotalEq, Encodable, Decodable, Hash)]
 pub enum ExplicitSelf_ {
     SelfStatic,                                // no self
     SelfValue,                                 // `self`
@@ -917,7 +917,7 @@ pub enum ExplicitSelf_ {
 
 pub type ExplicitSelf = Spanned<ExplicitSelf_>;
 
-#[deriving(Eq, Encodable, Decodable, Hash)]
+#[deriving(Eq, TotalEq, Encodable, Decodable, Hash)]
 pub struct Method {
     ident: Ident,
     attrs: Vec<Attribute> ,
@@ -931,37 +931,37 @@ pub struct Method {
     vis: Visibility,
 }
 
-#[deriving(Clone, Eq, Encodable, Decodable, Hash)]
+#[deriving(Clone, Eq, TotalEq, Encodable, Decodable, Hash)]
 pub struct Mod {
     view_items: Vec<ViewItem> ,
     items: Vec<@Item> ,
 }
 
-#[deriving(Clone, Eq, Encodable, Decodable, Hash)]
+#[deriving(Clone, Eq, TotalEq, Encodable, Decodable, Hash)]
 pub struct ForeignMod {
     abis: AbiSet,
     view_items: Vec<ViewItem> ,
     items: Vec<@ForeignItem> ,
 }
 
-#[deriving(Clone, Eq, Encodable, Decodable, Hash)]
+#[deriving(Clone, Eq, TotalEq, Encodable, Decodable, Hash)]
 pub struct VariantArg {
     ty: P<Ty>,
     id: NodeId,
 }
 
-#[deriving(Clone, Eq, Encodable, Decodable, Hash)]
+#[deriving(Clone, Eq, TotalEq, Encodable, Decodable, Hash)]
 pub enum VariantKind {
     TupleVariantKind(Vec<VariantArg> ),
     StructVariantKind(@StructDef),
 }
 
-#[deriving(Clone, Eq, Encodable, Decodable, Hash)]
+#[deriving(Clone, Eq, TotalEq, Encodable, Decodable, Hash)]
 pub struct EnumDef {
     variants: Vec<P<Variant>> ,
 }
 
-#[deriving(Clone, Eq, Encodable, Decodable, Hash)]
+#[deriving(Clone, Eq, TotalEq, Encodable, Decodable, Hash)]
 pub struct Variant_ {
     name: Ident,
     attrs: Vec<Attribute> ,
@@ -973,7 +973,7 @@ pub struct Variant_ {
 
 pub type Variant = Spanned<Variant_>;
 
-#[deriving(Clone, Eq, Encodable, Decodable, Hash)]
+#[deriving(Clone, Eq, TotalEq, Encodable, Decodable, Hash)]
 pub struct PathListIdent_ {
     name: Ident,
     id: NodeId,
@@ -983,7 +983,7 @@ pub struct PathListIdent_ {
 
 pub type ViewPath = Spanned<ViewPath_>;
 
-#[deriving(Eq, Encodable, Decodable, Hash)]
+#[deriving(Eq, TotalEq, Encodable, Decodable, Hash)]
 pub enum ViewPath_ {
 
     // quux = foo::bar::baz
@@ -1000,7 +1000,7 @@ pub enum ViewPath_ {
     ViewPathList(Path, Vec<PathListIdent> , NodeId)
 }
 
-#[deriving(Clone, Eq, Encodable, Decodable, Hash)]
+#[deriving(Clone, Eq, TotalEq, Encodable, Decodable, Hash)]
 pub struct ViewItem {
     node: ViewItem_,
     attrs: Vec<Attribute> ,
@@ -1008,7 +1008,7 @@ pub struct ViewItem {
     span: Span,
 }
 
-#[deriving(Clone, Eq, Encodable, Decodable, Hash)]
+#[deriving(Clone, Eq, TotalEq, Encodable, Decodable, Hash)]
 pub enum ViewItem_ {
     // ident: name used to refer to this crate in the code
     // optional (InternedString,StrStyle): if present, this is a location
@@ -1024,14 +1024,14 @@ pub enum ViewItem_ {
 // Distinguishes between Attributes that decorate items and Attributes that
 // are contained as statements within items. These two cases need to be
 // distinguished for pretty-printing.
-#[deriving(Clone, Eq, Encodable, Decodable, Hash)]
+#[deriving(Clone, Eq, TotalEq, Encodable, Decodable, Hash)]
 pub enum AttrStyle {
     AttrOuter,
     AttrInner,
 }
 
 // doc-comments are promoted to attributes that have is_sugared_doc = true
-#[deriving(Clone, Eq, Encodable, Decodable, Hash)]
+#[deriving(Clone, Eq, TotalEq, Encodable, Decodable, Hash)]
 pub struct Attribute_ {
     style: AttrStyle,
     value: @MetaItem,
@@ -1045,13 +1045,13 @@ pub struct Attribute_ {
   If this impl is an ItemImpl, the impl_id is redundant (it could be the
   same as the impl's node id).
  */
-#[deriving(Clone, Eq, Encodable, Decodable, Hash)]
+#[deriving(Clone, Eq, TotalEq, Encodable, Decodable, Hash)]
 pub struct TraitRef {
     path: Path,
     ref_id: NodeId,
 }
 
-#[deriving(Clone, Eq, Encodable, Decodable, Hash)]
+#[deriving(Clone, Eq, TotalEq, Encodable, Decodable, Hash)]
 pub enum Visibility {
     Public,
     Private,
@@ -1067,7 +1067,7 @@ pub fn inherit_from(&self, parent_visibility: Visibility) -> Visibility {
     }
 }
 
-#[deriving(Clone, Eq, Encodable, Decodable, Hash)]
+#[deriving(Clone, Eq, TotalEq, Encodable, Decodable, Hash)]
 pub struct StructField_ {
     kind: StructFieldKind,
     id: NodeId,
@@ -1077,13 +1077,13 @@ pub struct StructField_ {
 
 pub type StructField = Spanned<StructField_>;
 
-#[deriving(Clone, Eq, Encodable, Decodable, Hash)]
+#[deriving(Clone, Eq, TotalEq, Encodable, Decodable, Hash)]
 pub enum StructFieldKind {
     NamedField(Ident, Visibility),
     UnnamedField // element of a tuple-like struct
 }
 
-#[deriving(Eq, Encodable, Decodable, Hash)]
+#[deriving(Eq, TotalEq, Encodable, Decodable, Hash)]
 pub struct StructDef {
     fields: Vec<StructField> , /* fields, not including ctor */
     /* ID of the constructor. This is only used for tuple- or enum-like
@@ -1095,7 +1095,7 @@ pub struct StructDef {
   FIXME (#3300): Should allow items to be anonymous. Right now
   we just use dummy names for anon items.
  */
-#[deriving(Clone, Eq, Encodable, Decodable, Hash)]
+#[deriving(Clone, Eq, TotalEq, Encodable, Decodable, Hash)]
 pub struct Item {
     ident: Ident,
     attrs: Vec<Attribute> ,
@@ -1105,7 +1105,7 @@ pub struct Item {
     span: Span,
 }
 
-#[deriving(Clone, Eq, Encodable, Decodable, Hash)]
+#[deriving(Clone, Eq, TotalEq, Encodable, Decodable, Hash)]
 pub enum Item_ {
     ItemStatic(P<Ty>, Mutability, @Expr),
     ItemFn(P<FnDecl>, Purity, AbiSet, Generics, P<Block>),
@@ -1123,7 +1123,7 @@ pub enum Item_ {
     ItemMac(Mac),
 }
 
-#[deriving(Eq, Encodable, Decodable, Hash)]
+#[deriving(Eq, TotalEq, Encodable, Decodable, Hash)]
 pub struct ForeignItem {
     ident: Ident,
     attrs: Vec<Attribute> ,
@@ -1133,7 +1133,7 @@ pub struct ForeignItem {
     vis: Visibility,
 }
 
-#[deriving(Eq, Encodable, Decodable, Hash)]
+#[deriving(Eq, TotalEq, Encodable, Decodable, Hash)]
 pub enum ForeignItem_ {
     ForeignItemFn(P<FnDecl>, Generics),
     ForeignItemStatic(P<Ty>, /* is_mutbl */ bool),
@@ -1142,7 +1142,7 @@ pub enum ForeignItem_ {
 // The data we save and restore about an inlined item or method.  This is not
 // part of the AST that we parse from a file, but it becomes part of the tree
 // that we trans.
-#[deriving(Eq, Encodable, Decodable, Hash)]
+#[deriving(Eq, TotalEq, Encodable, Decodable, Hash)]
 pub enum InlinedItem {
     IIItem(@Item),
     IIMethod(DefId /* impl id */, bool /* is provided */, @Method),
index 4ba7921c431947d2810f08743bcfc0692e3d31f0..325df5fda60e7fce7cabbadb50639ad3aefe189a 100644 (file)
@@ -22,7 +22,6 @@
 */
 
 use std::cell::RefCell;
-use std::cmp;
 use std::rc::Rc;
 use serialize::{Encodable, Decodable, Encoder, Decoder};
 
@@ -33,7 +32,7 @@ pub trait Pos {
 
 /// A byte offset. Keep this small (currently 32-bits), as AST contains
 /// a lot of them.
-#[deriving(Clone, Eq, Hash, Ord, Show)]
+#[deriving(Clone, Eq, TotalEq, Hash, Ord, Show)]
 pub struct BytePos(u32);
 
 /// A character offset. Because of multibyte utf8 characters, a byte offset
@@ -94,19 +93,21 @@ pub struct Span {
 
 pub static DUMMY_SP: Span = Span { lo: BytePos(0), hi: BytePos(0), expn_info: None };
 
-#[deriving(Clone, Eq, Encodable, Decodable, Hash)]
+#[deriving(Clone, Eq, TotalEq, Encodable, Decodable, Hash)]
 pub struct Spanned<T> {
     node: T,
     span: Span,
 }
 
-impl cmp::Eq for Span {
+impl Eq for Span {
     fn eq(&self, other: &Span) -> bool {
         return (*self).lo == (*other).lo && (*self).hi == (*other).hi;
     }
     fn ne(&self, other: &Span) -> bool { !(*self).eq(other) }
 }
 
+impl TotalEq for Span {}
+
 impl<S:Encoder> Encodable<S> for Span {
     /* Note #1972 -- spans are encoded but not decoded */
     fn encode(&self, s: &mut S) {
index df38945f198538b808ef5462498e2122cdd93066..d5b90821897f46803803009f8c05bee1ce4e990a 100644 (file)
@@ -119,6 +119,8 @@ fn eq(&self, other: &OwnedSlice<T>) -> bool {
     }
 }
 
+impl<T: TotalEq> TotalEq for OwnedSlice<T> {}
+
 impl<T> Container for OwnedSlice<T> {
     fn len(&self) -> uint { self.len }
 }
index 1d7bf2ef6da9db85da48e80e5398b9553267dd4c..63b3fb09ee3cd55da52b8badc91fc3c81540b1ba 100644 (file)
@@ -23,7 +23,7 @@
 use parse::token;
 
 /// The specific types of unsupported syntax
-#[deriving(Eq, Hash)]
+#[deriving(Eq, TotalEq, Hash)]
 pub enum ObsoleteSyntax {
     ObsoleteSwap,
     ObsoleteUnsafeBlock,
index eebb98294d5e46532845cff406a6ed60cc12e9f4..15525912955fcce4f15a82b2231607744e91b492 100644 (file)
@@ -24,7 +24,7 @@
 use std::path::BytesContainer;
 
 #[allow(non_camel_case_types)]
-#[deriving(Clone, Encodable, Decodable, Eq, Hash, Show)]
+#[deriving(Clone, Encodable, Decodable, Eq, TotalEq, Hash, Show)]
 pub enum BinOp {
     PLUS,
     MINUS,
@@ -39,7 +39,7 @@ pub enum BinOp {
 }
 
 #[allow(non_camel_case_types)]
-#[deriving(Clone, Encodable, Decodable, Eq, Hash, Show)]
+#[deriving(Clone, Encodable, Decodable, Eq, TotalEq, Hash, Show)]
 pub enum Token {
     /* Expression-operator symbols. */
     EQ,
@@ -103,7 +103,7 @@ pub enum Token {
     EOF,
 }
 
-#[deriving(Clone, Encodable, Decodable, Eq, Hash)]
+#[deriving(Clone, Encodable, Decodable, Eq, TotalEq, Hash)]
 /// For interpolation during macro expansion.
 pub enum Nonterminal {
     NtItem(@ast::Item),
index d6f8f1067aecc0f60acdc16e9e2a050afb6983af..9b73cf533a7411971be517814f71c3f7f699a750 100644 (file)
@@ -28,7 +28,7 @@ pub struct Interner<T> {
 }
 
 // when traits can extend traits, we should extend index<Name,T> to get []
-impl<T: Eq + Hash + Clone + 'static> Interner<T> {
+impl<T: TotalEq + Hash + Clone + 'static> Interner<T> {
     pub fn new() -> Interner<T> {
         Interner {
             map: RefCell::new(HashMap::new()),
index 8a3881e801a7805149cd76100b6467af4edb865a..222aff3746519c9dad344e9788440a0b892e1008 100644 (file)
@@ -424,7 +424,7 @@ pub fn write_boxplot(w: &mut io::Writer, s: &Summary,
 
 /// Returns a HashMap with the number of occurrences of every element in the
 /// sequence that the iterator exposes.
-pub fn freq_count<T: Iterator<U>, U: Eq+Hash>(mut iter: T) -> hashmap::HashMap<U, uint> {
+pub fn freq_count<T: Iterator<U>, U: TotalEq+Hash>(mut iter: T) -> hashmap::HashMap<U, uint> {
     let mut map: hashmap::HashMap<U,uint> = hashmap::HashMap::new();
     for elem in iter {
         map.insert_or_update_with(elem, 1, |_, count| *count += 1);
index 52eafaadfd427906dd6ce367ef49ade98c24429d..3876aa45753c7f351082543f764ff623e60f946b 100644 (file)
@@ -14,7 +14,7 @@
 
 use collections::HashSet;
 
-#[deriving(Eq, Hash)]
+#[deriving(Eq, TotalEq, Hash)]
 struct XYZ {
     x: int,
     y: int,
index 7c87c858d42a734f0ec7f04c9dfa2b8236ad2c47..c38df0f7a225ab22378bc374171d0cb82501c5d5 100644 (file)
@@ -42,6 +42,8 @@ fn eq(&self, other: &TypeStructure<'tcx>) -> bool {
     }
 }
 
+impl<'tcx> TotalEq for TypeStructure<'tcx> {}
+
 struct TypeContext<'tcx, 'ast> {
     ty_arena: &'tcx Arena,
     types: Vec<Type<'tcx>> ,
@@ -86,7 +88,7 @@ fn ast(&mut self, a: AstKind<'ast>) -> Ast<'ast> {
     }
 }
 
-#[deriving(Eq, Hash)]
+#[deriving(Eq, TotalEq, Hash)]
 struct NodeId {
     id: uint
 }