Skip to content

Commit 7e1e830

Browse files
committed
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`
1 parent 0197f98 commit 7e1e830

File tree

2 files changed

+28
-1
lines changed

2 files changed

+28
-1
lines changed

src/librustc/middle/const_eval.rs

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ use std::borrow::{Cow, IntoCow};
3838
use std::num::wrapping::OverflowingOps;
3939
use std::cmp::Ordering;
4040
use std::collections::hash_map::Entry::Vacant;
41+
use std::mem::transmute;
4142
use std::{i8, i16, i32, i64, u8, u16, u32, u64};
4243
use std::rc::Rc;
4344

@@ -242,7 +243,7 @@ pub fn lookup_const_fn_by_id<'tcx>(tcx: &ty::ctxt<'tcx>, def_id: DefId)
242243
}
243244
}
244245

245-
#[derive(Clone, Debug, PartialEq)]
246+
#[derive(Clone, Debug)]
246247
pub enum ConstVal {
247248
Float(f64),
248249
Int(i64),
@@ -254,6 +255,27 @@ pub enum ConstVal {
254255
Tuple(ast::NodeId),
255256
}
256257

258+
/// Note that equality for `ConstVal` means that the it is the same
259+
/// constant, not that the rust values are equal. In particular, `NaN
260+
/// == NaN` (at least if it's the same NaN; distinct encodings for NaN
261+
/// are considering unequal).
262+
impl PartialEq for ConstVal {
263+
#[stable(feature = "rust1", since = "1.0.0")]
264+
fn eq(&self, other: &ConstVal) -> bool {
265+
match (self, other) {
266+
(&Float(a), &Float(b)) => unsafe{transmute::<_,u64>(a) == transmute::<_,u64>(b)},
267+
(&Int(a), &Int(b)) => a == b,
268+
(&Uint(a), &Uint(b)) => a == b,
269+
(&Str(ref a), &Str(ref b)) => a == b,
270+
(&ByteStr(ref a), &ByteStr(ref b)) => a == b,
271+
(&Bool(a), &Bool(b)) => a == b,
272+
(&Struct(a), &Struct(b)) => a == b,
273+
(&Tuple(a), &Tuple(b)) => a == b,
274+
_ => false,
275+
}
276+
}
277+
}
278+
257279
impl ConstVal {
258280
pub fn description(&self) -> &'static str {
259281
match *self {

src/librustc_mir/repr.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -642,6 +642,10 @@ impl<H:Hair> Debug for Rvalue<H> {
642642

643643
///////////////////////////////////////////////////////////////////////////
644644
// Constants
645+
//
646+
// Two constants are equal if they are the same constant. Note that
647+
// this does not necessarily mean that they are "==" in Rust -- in
648+
// particular one must be wary of `NaN`!
645649

646650
#[derive(Clone, Debug, PartialEq)]
647651
pub struct Constant<H:Hair> {
@@ -655,3 +659,4 @@ pub enum Literal<H:Hair> {
655659
Item { def_id: H::DefId, substs: H::Substs },
656660
Value { value: H::ConstVal },
657661
}
662+

0 commit comments

Comments
 (0)