]> git.lizzy.rs Git - rust.git/commitdiff
Merge pull request #387 from ecstatic-morse/eq-hash
authorRalf Jung <post@ralfj.de>
Fri, 13 Jul 2018 07:24:32 +0000 (09:24 +0200)
committerGitHub <noreply@github.com>
Fri, 13 Jul 2018 07:24:32 +0000 (09:24 +0200)
Implement `Eq`, `Clone` and `Hash` for MemoryData and Evaluator

src/lib.rs
src/locks.rs
src/range_map.rs

index 88bca91aa2de5ab2c0ff251e50976be06c9de031..75397262b225a1d0d30b1d0b75e8c6f8d83fbae9 100644 (file)
 use rustc::hir::def_id::DefId;
 use rustc::mir;
 
+use rustc_data_structures::fx::FxHasher;
+
 use syntax::ast::Mutability;
 use syntax::codemap::Span;
 
 use std::collections::{HashMap, BTreeMap};
+use std::hash::{Hash, Hasher};
 
 pub use rustc::mir::interpret::*;
 pub use rustc_mir::interpret::*;
@@ -296,7 +299,7 @@ pub fn eval_main<'a, 'tcx: 'a>(
     }
 }
 
-#[derive(Default)]
+#[derive(Clone, Default, PartialEq, Eq)]
 pub struct Evaluator<'tcx> {
     /// Environment variables set by `setenv`
     /// Miri does not expose env vars from the host to the emulated program
@@ -306,15 +309,34 @@ pub struct Evaluator<'tcx> {
     pub(crate) suspended: HashMap<DynamicLifetime, Vec<ValidationQuery<'tcx>>>,
 }
 
+impl<'tcx> Hash for Evaluator<'tcx> {
+    fn hash<H: Hasher>(&self, state: &mut H) {
+        let Evaluator {
+            env_vars,
+            suspended: _,
+        } = self;
+
+        env_vars.iter()
+            .map(|(env, ptr)| {
+                let mut h = FxHasher::default();
+                env.hash(&mut h);
+                ptr.hash(&mut h);
+                h.finish()
+            })
+            .fold(0u64, |acc, hash| acc.wrapping_add(hash))
+            .hash(state);
+    }
+}
+
 pub type TlsKey = u128;
 
-#[derive(Copy, Clone, Debug)]
+#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)]
 pub struct TlsEntry<'tcx> {
     data: Scalar, // Will eventually become a map from thread IDs to `Scalar`s, if we ever support more than one thread.
     dtor: Option<ty::Instance<'tcx>>,
 }
 
-#[derive(Default)]
+#[derive(Clone, Default, PartialEq, Eq)]
 pub struct MemoryData<'tcx> {
     /// The Key to use for the next thread-local allocation.
     next_thread_local: TlsKey,
@@ -331,6 +353,19 @@ pub struct MemoryData<'tcx> {
     statics: HashMap<GlobalId<'tcx>, AllocId>,
 }
 
+impl<'tcx> Hash for MemoryData<'tcx> {
+    fn hash<H: Hasher>(&self, state: &mut H) {
+        let MemoryData {
+            next_thread_local: _,
+            thread_local,
+            locks: _,
+            statics: _,
+        } = self;
+
+        thread_local.hash(state);
+    }
+}
+
 impl<'mir, 'tcx: 'mir> Machine<'mir, 'tcx> for Evaluator<'tcx> {
     type MemoryData = MemoryData<'tcx>;
     type MemoryKinds = memory::MemoryKind;
index 3b67c9bb7f3e4ef020095a2f25a45fc253f30fb5..9f4126ad82b60002e105863b78712e8f10ae5278 100644 (file)
@@ -7,7 +7,7 @@
 ////////////////////////////////////////////////////////////////////////////////
 
 /// Information about a lock that is currently held.
-#[derive(Clone, Debug)]
+#[derive(Clone, Debug, PartialEq, Eq)]
 pub struct LockInfo<'tcx> {
     /// Stores for which lifetimes (of the original write lock) we got
     /// which suspensions.
index fcffaf7128f11704a663a0b41b983486868527ef..76d01ad19e3ab609e5bfafc80aed5ea3c7cf24c7 100644 (file)
@@ -7,7 +7,7 @@
 use std::collections::BTreeMap;
 use std::ops;
 
-#[derive(Clone, Debug)]
+#[derive(Clone, Debug, PartialEq, Eq)]
 pub struct RangeMap<T> {
     map: BTreeMap<Range, T>,
 }