Skip to content

Commit 481ca82

Browse files
committed
The Hash and Eq impls of ConstValue were inherently broken
1 parent 99d7b10 commit 481ca82

File tree

2 files changed

+58
-10
lines changed

2 files changed

+58
-10
lines changed

src/librustc/mir/interpret/mod.rs

Lines changed: 56 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,8 @@ use middle::region;
3434
use std::iter;
3535
use std::io;
3636
use std::ops::{Deref, DerefMut};
37-
use std::hash::Hash;
37+
use std::cmp;
38+
use std::hash::{Hash, Hasher};
3839
use syntax::ast::Mutability;
3940
use rustc_serialize::{Encoder, Decodable, Encodable};
4041
use rustc_data_structures::sorted_map::SortedMap;
@@ -217,9 +218,56 @@ impl<'tcx, Tag> Pointer<Tag> {
217218
}
218219

219220

220-
#[derive(Copy, Clone, Eq, Hash, Ord, PartialEq, PartialOrd, Debug)]
221+
#[derive(Copy, Clone, Debug)]
221222
pub struct AllocId(pub u64);
222223

224+
impl Eq for AllocId {}
225+
226+
impl Hash for AllocId {
227+
fn hash<H: Hasher>(&self, state: &mut H) {
228+
ty::tls::with(|tcx| {
229+
let alloc_type = tcx.alloc_map.lock().get(*self);
230+
match alloc_type {
231+
Some(alloc_type) => alloc_type.hash(state),
232+
None => self.0.hash(state),
233+
}
234+
})
235+
}
236+
}
237+
238+
impl PartialEq for AllocId {
239+
fn eq(&self, other: &Self) -> bool {
240+
ty::tls::with(|tcx| {
241+
let (s, o) = {
242+
let map = tcx.alloc_map.lock();
243+
(map.get(*self), map.get(*other))
244+
};
245+
s == o
246+
})
247+
}
248+
}
249+
250+
impl Ord for AllocId {
251+
fn cmp(&self, other: &Self) -> cmp::Ordering {
252+
match self.partial_cmp(other) {
253+
Some(ord) => ord,
254+
None => self.0.cmp(&other.0)
255+
}
256+
}
257+
}
258+
259+
impl PartialOrd for AllocId {
260+
fn partial_cmp(&self, other: &Self) -> Option<cmp::Ordering> {
261+
ty::tls::with(|tcx| {
262+
let (s, o) = {
263+
let map = tcx.alloc_map.lock();
264+
(map.get(*self)?, map.get(*other)?)
265+
};
266+
s.partial_cmp(&o)
267+
})
268+
}
269+
}
270+
223271
impl ::rustc_serialize::UseSpecializedEncodable for AllocId {}
224272
impl ::rustc_serialize::UseSpecializedDecodable for AllocId {}
225273

@@ -427,7 +475,7 @@ impl fmt::Display for AllocId {
427475
}
428476
}
429477

430-
#[derive(Debug, Clone, Eq, PartialEq, Hash, RustcDecodable, RustcEncodable)]
478+
#[derive(Debug, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, RustcDecodable, RustcEncodable)]
431479
pub enum AllocType<'tcx, M> {
432480
/// The alloc id is used as a function pointer
433481
Function(Instance<'tcx>),
@@ -440,7 +488,7 @@ pub enum AllocType<'tcx, M> {
440488

441489
pub struct AllocMap<'tcx, M> {
442490
/// Lets you know what an AllocId refers to
443-
id_to_type: FxHashMap<AllocId, AllocType<'tcx, M>>,
491+
id_to_type: FxHashMap<u64, AllocType<'tcx, M>>,
444492

445493
/// Used to ensure that functions and statics only get one associated AllocId
446494
type_interner: FxHashMap<AllocType<'tcx, M>, AllocId>,
@@ -479,7 +527,7 @@ impl<'tcx, M: fmt::Debug + Eq + Hash + Clone> AllocMap<'tcx, M> {
479527
}
480528
let id = self.reserve();
481529
debug!("creating alloc_type {:?} with id {}", alloc_type, id);
482-
self.id_to_type.insert(id, alloc_type.clone());
530+
self.id_to_type.insert(id.0, alloc_type.clone());
483531
self.type_interner.insert(alloc_type, id);
484532
id
485533
}
@@ -492,7 +540,7 @@ impl<'tcx, M: fmt::Debug + Eq + Hash + Clone> AllocMap<'tcx, M> {
492540
}
493541

494542
pub fn get(&self, id: AllocId) -> Option<AllocType<'tcx, M>> {
495-
self.id_to_type.get(&id).cloned()
543+
self.id_to_type.get(&id.0).cloned()
496544
}
497545

498546
pub fn unwrap_memory(&self, id: AllocId) -> M {
@@ -513,13 +561,13 @@ impl<'tcx, M: fmt::Debug + Eq + Hash + Clone> AllocMap<'tcx, M> {
513561
}
514562

515563
pub fn set_id_memory(&mut self, id: AllocId, mem: M) {
516-
if let Some(old) = self.id_to_type.insert(id, AllocType::Memory(mem)) {
564+
if let Some(old) = self.id_to_type.insert(id.0, AllocType::Memory(mem)) {
517565
bug!("tried to set allocation id {}, but it was already existing as {:#?}", id, old);
518566
}
519567
}
520568

521569
pub fn set_id_same_memory(&mut self, id: AllocId, mem: M) {
522-
self.id_to_type.insert_same(id, AllocType::Memory(mem));
570+
self.id_to_type.insert_same(id.0, AllocType::Memory(mem));
523571
}
524572
}
525573

src/librustc/ty/instance.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,13 @@ use util::ppaux;
1616

1717
use std::fmt;
1818

19-
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, RustcEncodable, RustcDecodable)]
19+
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, RustcEncodable, RustcDecodable)]
2020
pub struct Instance<'tcx> {
2121
pub def: InstanceDef<'tcx>,
2222
pub substs: &'tcx Substs<'tcx>,
2323
}
2424

25-
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, RustcEncodable, RustcDecodable)]
25+
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, RustcEncodable, RustcDecodable)]
2626
pub enum InstanceDef<'tcx> {
2727
Item(DefId),
2828
Intrinsic(DefId),

0 commit comments

Comments
 (0)