diff options
| author | Niko Matsakis <niko@alum.mit.edu> | 2015-09-29 17:08:05 -0400 |
|---|---|---|
| committer | Niko Matsakis <niko@alum.mit.edu> | 2015-10-04 21:19:45 -0400 |
| commit | 7e1e830a6f6f32b053b71ac628c0fbf8698ad888 (patch) | |
| tree | b058531f3e2ac045d38bf53d8d1fa021815d3ea9 | |
| parent | 0197f982b2c2d4dbf7d95fc28e0e47bce39ea944 (diff) | |
| download | rust-7e1e830a6f6f32b053b71ac628c0fbf8698ad888.tar.gz rust-7e1e830a6f6f32b053b71ac628c0fbf8698ad888.zip | |
change PartialEq impl for ConstVal so that two constants are `==`
if they represent the same constant; otherwise the match algorithm goes into infinite recursion when a pattern contains `NaN`
| -rw-r--r-- | src/librustc/middle/const_eval.rs | 24 | ||||
| -rw-r--r-- | src/librustc_mir/repr.rs | 5 |
2 files changed, 28 insertions, 1 deletions
diff --git a/src/librustc/middle/const_eval.rs b/src/librustc/middle/const_eval.rs index 78acff0ada3..acda0fe2f0e 100644 --- a/src/librustc/middle/const_eval.rs +++ b/src/librustc/middle/const_eval.rs @@ -38,6 +38,7 @@ use std::borrow::{Cow, IntoCow}; use std::num::wrapping::OverflowingOps; use std::cmp::Ordering; use std::collections::hash_map::Entry::Vacant; +use std::mem::transmute; use std::{i8, i16, i32, i64, u8, u16, u32, u64}; use std::rc::Rc; @@ -242,7 +243,7 @@ pub fn lookup_const_fn_by_id<'tcx>(tcx: &ty::ctxt<'tcx>, def_id: DefId) } } -#[derive(Clone, Debug, PartialEq)] +#[derive(Clone, Debug)] pub enum ConstVal { Float(f64), Int(i64), @@ -254,6 +255,27 @@ pub enum ConstVal { Tuple(ast::NodeId), } +/// Note that equality for `ConstVal` means that the it is the same +/// constant, not that the rust values are equal. In particular, `NaN +/// == NaN` (at least if it's the same NaN; distinct encodings for NaN +/// are considering unequal). +impl PartialEq for ConstVal { + #[stable(feature = "rust1", since = "1.0.0")] + fn eq(&self, other: &ConstVal) -> bool { + match (self, other) { + (&Float(a), &Float(b)) => unsafe{transmute::<_,u64>(a) == transmute::<_,u64>(b)}, + (&Int(a), &Int(b)) => a == b, + (&Uint(a), &Uint(b)) => a == b, + (&Str(ref a), &Str(ref b)) => a == b, + (&ByteStr(ref a), &ByteStr(ref b)) => a == b, + (&Bool(a), &Bool(b)) => a == b, + (&Struct(a), &Struct(b)) => a == b, + (&Tuple(a), &Tuple(b)) => a == b, + _ => false, + } + } +} + impl ConstVal { pub fn description(&self) -> &'static str { match *self { diff --git a/src/librustc_mir/repr.rs b/src/librustc_mir/repr.rs index e5a03cbb586..d522518a3d4 100644 --- a/src/librustc_mir/repr.rs +++ b/src/librustc_mir/repr.rs @@ -642,6 +642,10 @@ impl<H:Hair> Debug for Rvalue<H> { /////////////////////////////////////////////////////////////////////////// // Constants +// +// Two constants are equal if they are the same constant. Note that +// this does not necessarily mean that they are "==" in Rust -- in +// particular one must be wary of `NaN`! #[derive(Clone, Debug, PartialEq)] pub struct Constant<H:Hair> { @@ -655,3 +659,4 @@ pub enum Literal<H:Hair> { Item { def_id: H::DefId, substs: H::Substs }, Value { value: H::ConstVal }, } + |
