Navigation Menu

Skip to content

Commit

Permalink
change PartialEq impl for ConstVal so that two constants are ==
Browse files Browse the repository at this point in the history
if they represent the same constant; otherwise the match algorithm
goes into infinite recursion when a pattern contains `NaN`
  • Loading branch information
nikomatsakis committed Oct 5, 2015
1 parent 0197f98 commit 7e1e830
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 1 deletion.
24 changes: 23 additions & 1 deletion src/librustc/middle/const_eval.rs
Expand Up @@ -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;

Expand Down Expand Up @@ -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),
Expand All @@ -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 {
Expand Down
5 changes: 5 additions & 0 deletions src/librustc_mir/repr.rs
Expand Up @@ -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> {
Expand All @@ -655,3 +659,4 @@ pub enum Literal<H:Hair> {
Item { def_id: H::DefId, substs: H::Substs },
Value { value: H::ConstVal },
}

0 comments on commit 7e1e830

Please sign in to comment.