]> git.lizzy.rs Git - rust.git/commitdiff
rename `rustc_const_eval` to `rustc_const_math`
authorOliver Schneider <git-spam-no-reply9815368754983@oli-obk.de>
Tue, 15 Mar 2016 11:33:13 +0000 (12:33 +0100)
committerOliver Schneider <git-spam-no-reply9815368754983@oli-obk.de>
Wed, 30 Mar 2016 09:10:21 +0000 (11:10 +0200)
38 files changed:
mk/crates.mk
src/librustc/Cargo.toml
src/librustc/lib.rs
src/librustc/middle/const_eval.rs
src/librustc/mir/repr.rs
src/librustc/mir/visit.rs
src/librustc/ty/mod.rs
src/librustc/ty/util.rs
src/librustc_const_eval/Cargo.toml [deleted file]
src/librustc_const_eval/err.rs [deleted file]
src/librustc_const_eval/int.rs [deleted file]
src/librustc_const_eval/is.rs [deleted file]
src/librustc_const_eval/lib.rs [deleted file]
src/librustc_const_eval/us.rs [deleted file]
src/librustc_const_math/Cargo.toml [new file with mode: 0644]
src/librustc_const_math/err.rs [new file with mode: 0644]
src/librustc_const_math/int.rs [new file with mode: 0644]
src/librustc_const_math/is.rs [new file with mode: 0644]
src/librustc_const_math/lib.rs [new file with mode: 0644]
src/librustc_const_math/us.rs [new file with mode: 0644]
src/librustc_metadata/Cargo.toml
src/librustc_metadata/decoder.rs
src/librustc_metadata/lib.rs
src/librustc_mir/Cargo.toml
src/librustc_mir/build/scope.rs
src/librustc_mir/hair/cx/expr.rs
src/librustc_mir/hair/cx/mod.rs
src/librustc_mir/lib.rs
src/librustc_trans/Cargo.toml
src/librustc_trans/consts.rs
src/librustc_trans/lib.rs
src/librustc_trans/mir/constant.rs
src/librustc_trans/mir/rvalue.rs
src/librustc_typeck/Cargo.toml
src/librustc_typeck/astconv.rs
src/librustc_typeck/collect.rs
src/librustc_typeck/lib.rs
src/test/auxiliary/dummy_mir_pass.rs

index ba959d2778e78ed9ca0d79c60156067235663203..1b614595e2a8ef19410e7088585f895fc4ee4c97 100644 (file)
@@ -92,7 +92,7 @@ DEPS_test := std getopts term native:rust_test_helpers
 DEPS_syntax := std term serialize log arena libc rustc_bitflags rustc_unicode
 DEPS_syntax_ext := syntax fmt_macros
 
-DEPS_rustc_const_eval := std syntax
+DEPS_rustc_const_math := std syntax log serialize
 
 DEPS_rustc := syntax fmt_macros flate arena serialize getopts rbml rustc_front\
               log graphviz rustc_back rustc_data_structures\
index d2dc5f1ed93e08c4a1edf87efca5d091e74fc49a..cdbe8696a90d471de9c8288d1ad7f028542ec726 100644 (file)
@@ -18,7 +18,7 @@ log = { path = "../liblog" }
 rbml = { path = "../librbml" }
 rustc_back = { path = "../librustc_back" }
 rustc_bitflags = { path = "../librustc_bitflags" }
-rustc_const_eval = { path = "../librustc_const_eval" }
+rustc_const_math = { path = "../librustc_const_math" }
 rustc_data_structures = { path = "../librustc_data_structures" }
 rustc_front = { path = "../librustc_front" }
 serialize = { path = "../libserialize" }
index 6b5f889fcfb8582e49d77316a4aeb0dbf08235c8..1728bec5a8d3f20026c3513c67ca7eafd2083403 100644 (file)
@@ -55,7 +55,7 @@
 extern crate rustc_data_structures;
 extern crate serialize;
 extern crate collections;
-extern crate rustc_const_eval;
+extern crate rustc_const_math;
 #[macro_use] extern crate log;
 #[macro_use] extern crate syntax;
 #[macro_use] #[no_link] extern crate rustc_bitflags;
index fca2904979c64bd4f449972b743293b56613ce7e..f685e4c0e18df00fd87cd9b01eca8922ffb845ce 100644 (file)
@@ -46,7 +46,7 @@
 use std::mem::transmute;
 use std::rc::Rc;
 
-use rustc_const_eval::*;
+use rustc_const_math::*;
 
 macro_rules! math {
     ($e:expr, $op:expr) => {
index b90738107834d659ac78e5a99338c99e74a40d23..d3b1a8d6c13332334f0039ea2734e54ec3cfb4dd 100644 (file)
@@ -10,7 +10,7 @@
 
 use graphviz::IntoCow;
 use middle::const_eval::ConstVal;
-use rustc_const_eval::{ConstUsize, ConstInt};
+use rustc_const_math::{ConstUsize, ConstInt};
 use middle::def_id::DefId;
 use ty::subst::Substs;
 use ty::{self, AdtDef, ClosureSubsts, FnOutput, Region, Ty};
index 856902bea3c3c315e29f4d14e73ceeebacba9a01..d11eea811cd75e47f324676854835e02733d67c1 100644 (file)
@@ -13,7 +13,7 @@
 use ty::subst::Substs;
 use ty::{ClosureSubsts, FnOutput, Region, Ty};
 use mir::repr::*;
-use rustc_const_eval::ConstUsize;
+use rustc_const_math::ConstUsize;
 use rustc_data_structures::tuple_slice::TupleSlice;
 use syntax::codemap::Span;
 
index d080724fac9a93848ba153493a909bb00c32f8ce..5c754fc12d7d8cc29a1e5a91b4b04669658071dc 100644 (file)
@@ -50,7 +50,7 @@
 use syntax::codemap::{DUMMY_SP, Span};
 use syntax::parse::token::InternedString;
 
-use rustc_const_eval::ConstInt;
+use rustc_const_math::ConstInt;
 
 use rustc_front::hir;
 use rustc_front::hir::{ItemImpl, ItemTrait, PatKind};
index b870dc47ec76af26cfdeb3ce0f1f006fb1497250..970c807b36f7dfb8626565f101235a2aabaafb3e 100644 (file)
@@ -22,7 +22,7 @@
 use ty::{Disr, ParameterEnvironment};
 use ty::TypeVariants::*;
 
-use rustc_const_eval::{ConstInt, ConstIsize, ConstUsize};
+use rustc_const_math::{ConstInt, ConstIsize, ConstUsize};
 
 use std::cmp;
 use std::hash::{Hash, SipHasher, Hasher};
diff --git a/src/librustc_const_eval/Cargo.toml b/src/librustc_const_eval/Cargo.toml
deleted file mode 100644 (file)
index f885e9a..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-[package]
-authors = ["The Rust Project Developers"]
-name = "rustc_const_eval"
-version = "0.0.0"
-
-[lib]
-name = "rustc_const_eval"
-path = "lib.rs"
-crate-type = ["dylib"]
-
-[dependencies]
-log = { path = "../liblog" }
-serialize = { path = "../libserialize" }
-syntax = { path = "../libsyntax" }
diff --git a/src/librustc_const_eval/err.rs b/src/librustc_const_eval/err.rs
deleted file mode 100644 (file)
index 126b382..0000000
+++ /dev/null
@@ -1,85 +0,0 @@
-// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-use syntax::ast;
-
-#[derive(Debug, PartialEq, Eq, Clone)]
-pub enum ConstMathErr {
-    NotInRange,
-    CmpBetweenUnequalTypes,
-    UnequalTypes(Op),
-    Overflow(Op),
-    ShiftNegative,
-    DivisionByZero,
-    RemainderByZero,
-    UnsignedNegation,
-    ULitOutOfRange(ast::UintTy),
-    LitOutOfRange(ast::IntTy),
-}
-pub use self::ConstMathErr::*;
-
-#[derive(Debug, PartialEq, Eq, Clone)]
-pub enum Op {
-    Add,
-    Sub,
-    Mul,
-    Div,
-    Rem,
-    Shr,
-    Shl,
-    Neg,
-    BitAnd,
-    BitOr,
-    BitXor,
-}
-
-impl ConstMathErr {
-    pub fn description(&self) -> &'static str {
-        use self::Op::*;
-        match *self {
-            NotInRange => "inferred value out of range",
-            CmpBetweenUnequalTypes => "compared two integrals of different types",
-            UnequalTypes(Add) => "tried to add two integrals of different types",
-            UnequalTypes(Sub) => "tried to subtract two integrals of different types",
-            UnequalTypes(Mul) => "tried to multiply two integrals of different types",
-            UnequalTypes(Div) => "tried to divide two integrals of different types",
-            UnequalTypes(Rem) => {
-                "tried to calculate the remainder of two integrals of different types"
-            },
-            UnequalTypes(BitAnd) => "tried to bitand two integrals of different types",
-            UnequalTypes(BitOr) => "tried to bitor two integrals of different types",
-            UnequalTypes(BitXor) => "tried to xor two integrals of different types",
-            UnequalTypes(_) => unreachable!(),
-            Overflow(Add) => "attempted to add with overflow",
-            Overflow(Sub) => "attempted to subtract with overflow",
-            Overflow(Mul) => "attempted to multiply with overflow",
-            Overflow(Div) => "attempted to divide with overflow",
-            Overflow(Rem) => "attempted to calculate the remainder with overflow",
-            Overflow(Neg) => "attempted to negate with overflow",
-            Overflow(Shr) => "attempted to shift right with overflow",
-            Overflow(Shl) => "attempted to shift left with overflow",
-            Overflow(_) => unreachable!(),
-            ShiftNegative => "attempted to shift by a negative amount",
-            DivisionByZero => "attempted to divide by zero",
-            RemainderByZero => "attempted to calculate the remainder with a divisor of zero",
-            UnsignedNegation => "unary negation of unsigned integer",
-            ULitOutOfRange(ast::UintTy::U8) => "literal out of range for u8",
-            ULitOutOfRange(ast::UintTy::U16) => "literal out of range for u16",
-            ULitOutOfRange(ast::UintTy::U32) => "literal out of range for u32",
-            ULitOutOfRange(ast::UintTy::U64) => "literal out of range for u64",
-            ULitOutOfRange(ast::UintTy::Us) => "literal out of range for usize",
-            LitOutOfRange(ast::IntTy::I8) => "literal out of range for i8",
-            LitOutOfRange(ast::IntTy::I16) => "literal out of range for i16",
-            LitOutOfRange(ast::IntTy::I32) => "literal out of range for i32",
-            LitOutOfRange(ast::IntTy::I64) => "literal out of range for i64",
-            LitOutOfRange(ast::IntTy::Is) => "literal out of range for isize",
-        }
-    }
-}
diff --git a/src/librustc_const_eval/int.rs b/src/librustc_const_eval/int.rs
deleted file mode 100644 (file)
index 7576a98..0000000
+++ /dev/null
@@ -1,569 +0,0 @@
-// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-use std::cmp::Ordering;
-use syntax::attr::IntType;
-use syntax::ast::{IntTy, UintTy};
-
-use super::is::*;
-use super::us::*;
-use super::err::*;
-
-#[derive(Copy, Clone, Debug, RustcEncodable, RustcDecodable, Hash, Eq, PartialEq)]
-pub enum ConstInt {
-    I8(i8),
-    I16(i16),
-    I32(i32),
-    I64(i64),
-    Isize(ConstIsize),
-    U8(u8),
-    U16(u16),
-    U32(u32),
-    U64(u64),
-    Usize(ConstUsize),
-    Infer(u64),
-    InferSigned(i64),
-}
-pub use self::ConstInt::*;
-
-
-macro_rules! bounds {
-    ($($t:ident $min:ident $max:ident)*) => {
-        mod as_u64 {
-            $(
-                #[allow(dead_code)]
-                pub const $min: u64 = ::std::$t::MIN as u64;
-                #[allow(dead_code)]
-                pub const $max: u64 = ::std::$t::MAX as u64;
-            )*
-        }
-        mod as_i64 {
-            $(
-                #[allow(dead_code)]
-                pub const $min: i64 = ::std::$t::MIN as i64;
-                #[allow(dead_code)]
-                pub const $max: i64 = ::std::$t::MAX as i64;
-            )*
-        }
-    }
-}
-
-bounds!{
-    i8 I8MIN I8MAX i16 I16MIN I16MAX i32 I32MIN I32MAX i64 I64MIN I64MAX isize IMIN IMAX
-    u8 U8MIN U8MAX u16 U16MIN U16MAX u32 U32MIN U32MAX u64 U64MIN U64MAX usize UMIN UMAX
-}
-
-impl ConstInt {
-    /// If either value is `Infer` or `InferSigned`, try to turn the value into the type of
-    /// the other value. If both values have no type, don't do anything
-    pub fn infer(self, other: Self) -> Result<(Self, Self), ConstMathErr> {
-        let inferred = match (self, other) {
-            (InferSigned(_), InferSigned(_))
-            | (Infer(_), Infer(_)) => self, // no inference possible
-            // kindof wrong, you could have had values > I64MAX during computation of a
-            (Infer(a @ 0...as_u64::I64MAX), InferSigned(_)) => InferSigned(a as i64),
-            (Infer(_), InferSigned(_)) => return Err(ConstMathErr::NotInRange),
-            (_, InferSigned(_))
-            | (_, Infer(_)) => return other.infer(self).map(|(b, a)| (a, b)),
-
-            (Infer(a @ 0...as_u64::I8MAX), I8(_)) => I8(a as i64 as i8),
-            (Infer(a @ 0...as_u64::I16MAX), I16(_)) => I16(a as i64 as i16),
-            (Infer(a @ 0...as_u64::I32MAX), I32(_)) => I32(a as i64 as i32),
-            (Infer(a @ 0...as_u64::I64MAX), I64(_)) => I64(a as i64),
-            (Infer(a @ 0...as_u64::I32MAX), Isize(Is32(_))) => Isize(Is32(a as i64 as i32)),
-            (Infer(a @ 0...as_u64::I64MAX), Isize(Is64(_))) => Isize(Is64(a as i64)),
-            (Infer(a @ 0...as_u64::U8MAX), U8(_)) => U8(a as u8),
-            (Infer(a @ 0...as_u64::U16MAX), U16(_)) => U16(a as u16),
-            (Infer(a @ 0...as_u64::U32MAX), U32(_)) => U32(a as u32),
-            (Infer(a), U64(_)) => U64(a),
-            (Infer(a @ 0...as_u64::U32MAX), Usize(Us32(_))) => Usize(Us32(a as u32)),
-            (Infer(a), Usize(Us64(_))) => Usize(Us64(a)),
-
-            (Infer(_), _) => return Err(ConstMathErr::NotInRange),
-
-            (InferSigned(a @ as_i64::I8MIN...as_i64::I8MAX), I8(_)) => I8(a as i8),
-            (InferSigned(a @ as_i64::I16MIN...as_i64::I16MAX), I16(_)) => I16(a as i16),
-            (InferSigned(a @ as_i64::I32MIN...as_i64::I32MAX), I32(_)) => I32(a as i32),
-            (InferSigned(a), I64(_)) => I64(a),
-            (InferSigned(a @ as_i64::I32MIN...as_i64::I32MAX), Isize(Is32(_))) => {
-                Isize(Is32(a as i32))
-            },
-            (InferSigned(a), Isize(Is64(_))) => Isize(Is64(a)),
-            (InferSigned(a @ 0...as_i64::U8MAX), U8(_)) => U8(a as u8),
-            (InferSigned(a @ 0...as_i64::U16MAX), U16(_)) => U16(a as u16),
-            (InferSigned(a @ 0...as_i64::U32MAX), U32(_)) => U32(a as u32),
-            (InferSigned(a @ 0...as_i64::I64MAX), U64(_)) => U64(a as u64),
-            (InferSigned(a @ 0...as_i64::U32MAX), Usize(Us32(_))) => Usize(Us32(a as u32)),
-            (InferSigned(a @ 0...as_i64::I64MAX), Usize(Us64(_))) => Usize(Us64(a as u64)),
-            (InferSigned(_), _) => return Err(ConstMathErr::NotInRange),
-            _ => self, // already known types
-        };
-        Ok((inferred, other))
-    }
-
-    /// Turn this value into an `Infer` or an `InferSigned`
-    pub fn erase_type(self) -> Self {
-        match self {
-            Infer(i) => Infer(i),
-            InferSigned(i) if i < 0 => InferSigned(i),
-            I8(i) if i < 0 => InferSigned(i as i64),
-            I16(i) if i < 0 => InferSigned(i as i64),
-            I32(i) if i < 0 => InferSigned(i as i64),
-            I64(i) if i < 0 => InferSigned(i as i64),
-            Isize(Is32(i)) if i < 0 => InferSigned(i as i64),
-            Isize(Is64(i)) if i < 0 => InferSigned(i as i64),
-            InferSigned(i) => Infer(i as u64),
-            I8(i) => Infer(i as u64),
-            I16(i) => Infer(i as u64),
-            I32(i) => Infer(i as u64),
-            I64(i) => Infer(i as u64),
-            Isize(Is32(i)) => Infer(i as u64),
-            Isize(Is64(i)) => Infer(i as u64),
-            U8(i) => Infer(i as u64),
-            U16(i) => Infer(i as u64),
-            U32(i) => Infer(i as u64),
-            U64(i) => Infer(i as u64),
-            Usize(Us32(i)) => Infer(i as u64),
-            Usize(Us64(i)) => Infer(i),
-        }
-    }
-
-    /// Description of the type, not the value
-    pub fn description(&self) -> &'static str {
-        match *self {
-            Infer(_) => "not yet inferred integral",
-            InferSigned(_) => "not yet inferred signed integral",
-            I8(_) => "i8",
-            I16(_) => "i16",
-            I32(_) => "i32",
-            I64(_) => "i64",
-            Isize(_) => "isize",
-            U8(_) => "u8",
-            U16(_) => "u16",
-            U32(_) => "u32",
-            U64(_) => "u64",
-            Usize(_) => "usize",
-        }
-    }
-
-    /// Erases the type and returns a u64.
-    /// This is not the same as `-5i8 as u64` but as `-5i8 as i64 as u64`
-    pub fn to_u64_unchecked(self) -> u64 {
-        match self.erase_type() {
-            ConstInt::Infer(i) => i,
-            ConstInt::InferSigned(i) => i as u64,
-            _ => unreachable!(),
-        }
-    }
-
-    /// Converts the value to a `u32` if it's in the range 0...std::u32::MAX
-    pub fn to_u32(&self) -> Option<u32> {
-        match *self {
-            I8(v) if v >= 0 => Some(v as u32),
-            I16(v) if v >= 0 => Some(v as u32),
-            I32(v) if v >= 0 => Some(v as u32),
-            InferSigned(v)
-            | Isize(Is64(v))
-            | I64(v) if v >= 0 && v <= ::std::u32::MAX as i64 => Some(v as u32),
-            Isize(Is32(v)) if v >= 0 => Some(v as u32),
-            U8(v) => Some(v as u32),
-            U16(v) => Some(v as u32),
-            U32(v) => Some(v),
-            Infer(v)
-            | Usize(Us64(v))
-            | U64(v) if v <= ::std::u32::MAX as u64 => Some(v as u32),
-            Usize(Us32(v)) => Some(v),
-            _ => None,
-        }
-    }
-
-    /// Converts the value to a `u64` if it's >= 0
-    pub fn to_u64(&self) -> Option<u64> {
-        match *self {
-            Infer(v) => Some(v),
-            InferSigned(v) if v >= 0 => Some(v as u64),
-            I8(v) if v >= 0 => Some(v as u64),
-            I16(v) if v >= 0 => Some(v as u64),
-            I32(v) if v >= 0 => Some(v as u64),
-            I64(v) if v >= 0 => Some(v as u64),
-            Isize(Is32(v)) if v >= 0 => Some(v as u64),
-            Isize(Is64(v)) if v >= 0 => Some(v as u64),
-            U8(v) => Some(v as u64),
-            U16(v) => Some(v as u64),
-            U32(v) => Some(v as u64),
-            U64(v) => Some(v),
-            Usize(Us32(v)) => Some(v as u64),
-            Usize(Us64(v)) => Some(v),
-            _ => None,
-        }
-    }
-
-    pub fn is_negative(&self) -> bool {
-        match *self {
-            I8(v) => v < 0,
-            I16(v) => v < 0,
-            I32(v) => v < 0,
-            I64(v) => v < 0,
-            Isize(Is32(v)) => v < 0,
-            Isize(Is64(v)) => v < 0,
-            InferSigned(v) => v < 0,
-            _ => false,
-        }
-    }
-
-    /// Compares the values if they are of the same type
-    pub fn try_cmp(self, rhs: Self) -> Result<::std::cmp::Ordering, ConstMathErr> {
-        match self.infer(rhs)? {
-            (I8(a), I8(b)) => Ok(a.cmp(&b)),
-            (I16(a), I16(b)) => Ok(a.cmp(&b)),
-            (I32(a), I32(b)) => Ok(a.cmp(&b)),
-            (I64(a), I64(b)) => Ok(a.cmp(&b)),
-            (Isize(Is32(a)), Isize(Is32(b))) => Ok(a.cmp(&b)),
-            (Isize(Is64(a)), Isize(Is64(b))) => Ok(a.cmp(&b)),
-            (U8(a), U8(b)) => Ok(a.cmp(&b)),
-            (U16(a), U16(b)) => Ok(a.cmp(&b)),
-            (U32(a), U32(b)) => Ok(a.cmp(&b)),
-            (U64(a), U64(b)) => Ok(a.cmp(&b)),
-            (Usize(Us32(a)), Usize(Us32(b))) => Ok(a.cmp(&b)),
-            (Usize(Us64(a)), Usize(Us64(b))) => Ok(a.cmp(&b)),
-            (Infer(a), Infer(b)) => Ok(a.cmp(&b)),
-            (InferSigned(a), InferSigned(b)) => Ok(a.cmp(&b)),
-            _ => Err(CmpBetweenUnequalTypes),
-        }
-    }
-
-    /// Adds 1 to the value and wraps around if the maximum for the type is reached
-    pub fn wrap_incr(self) -> Self {
-        macro_rules! add1 {
-            ($e:expr) => { ($e).wrapping_add(1) }
-        }
-        match self {
-            ConstInt::I8(i) => ConstInt::I8(add1!(i)),
-            ConstInt::I16(i) => ConstInt::I16(add1!(i)),
-            ConstInt::I32(i) => ConstInt::I32(add1!(i)),
-            ConstInt::I64(i) => ConstInt::I64(add1!(i)),
-            ConstInt::Isize(ConstIsize::Is32(i)) => ConstInt::Isize(ConstIsize::Is32(add1!(i))),
-            ConstInt::Isize(ConstIsize::Is64(i)) => ConstInt::Isize(ConstIsize::Is64(add1!(i))),
-            ConstInt::U8(i) => ConstInt::U8(add1!(i)),
-            ConstInt::U16(i) => ConstInt::U16(add1!(i)),
-            ConstInt::U32(i) => ConstInt::U32(add1!(i)),
-            ConstInt::U64(i) => ConstInt::U64(add1!(i)),
-            ConstInt::Usize(ConstUsize::Us32(i)) => ConstInt::Usize(ConstUsize::Us32(add1!(i))),
-            ConstInt::Usize(ConstUsize::Us64(i)) => ConstInt::Usize(ConstUsize::Us64(add1!(i))),
-            ConstInt::Infer(_) | ConstInt::InferSigned(_) => panic!("no type info for const int"),
-        }
-    }
-
-    pub fn int_type(self) -> Option<IntType> {
-        match self {
-            ConstInt::I8(_) => Some(IntType::SignedInt(IntTy::I8)),
-            ConstInt::I16(_) => Some(IntType::SignedInt(IntTy::I16)),
-            ConstInt::I32(_) => Some(IntType::SignedInt(IntTy::I32)),
-            ConstInt::I64(_) => Some(IntType::SignedInt(IntTy::I64)),
-            ConstInt::Isize(_) => Some(IntType::SignedInt(IntTy::Is)),
-            ConstInt::U8(_) => Some(IntType::UnsignedInt(UintTy::U8)),
-            ConstInt::U16(_) => Some(IntType::UnsignedInt(UintTy::U16)),
-            ConstInt::U32(_) => Some(IntType::UnsignedInt(UintTy::U32)),
-            ConstInt::U64(_) => Some(IntType::UnsignedInt(UintTy::U64)),
-            ConstInt::Usize(_) => Some(IntType::UnsignedInt(UintTy::Us)),
-            _ => None,
-        }
-    }
-}
-
-impl ::std::cmp::PartialOrd for ConstInt {
-    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
-        self.try_cmp(*other).ok()
-    }
-}
-
-impl ::std::cmp::Ord for ConstInt {
-    fn cmp(&self, other: &Self) -> Ordering {
-        self.try_cmp(*other).unwrap()
-    }
-}
-
-impl ::std::fmt::Display for ConstInt {
-    fn fmt(&self, fmt: &mut ::std::fmt::Formatter) -> Result<(), ::std::fmt::Error> {
-        match *self {
-            Infer(i) => write!(fmt, "{}", i),
-            InferSigned(i) => write!(fmt, "{}", i),
-            I8(i) => write!(fmt, "{}i8", i),
-            I16(i) => write!(fmt, "{}i16", i),
-            I32(i) => write!(fmt, "{}i32", i),
-            I64(i) => write!(fmt, "{}i64", i),
-            Isize(ConstIsize::Is64(i)) => write!(fmt, "{}isize", i),
-            Isize(ConstIsize::Is32(i)) => write!(fmt, "{}isize", i),
-            U8(i) => write!(fmt, "{}u8", i),
-            U16(i) => write!(fmt, "{}u16", i),
-            U32(i) => write!(fmt, "{}u32", i),
-            U64(i) => write!(fmt, "{}u64", i),
-            Usize(ConstUsize::Us64(i)) => write!(fmt, "{}usize", i),
-            Usize(ConstUsize::Us32(i)) => write!(fmt, "{}usize", i),
-        }
-    }
-}
-
-macro_rules! overflowing {
-    ($e:expr, $err:expr) => {{
-        if $e.1 {
-            return Err(Overflow($err));
-        } else {
-            $e.0
-        }
-    }}
-}
-
-macro_rules! impl_binop {
-    ($op:ident, $func:ident, $checked_func:ident) => {
-        impl ::std::ops::$op for ConstInt {
-            type Output = Result<Self, ConstMathErr>;
-            fn $func(self, rhs: Self) -> Result<Self, ConstMathErr> {
-                match try!(self.infer(rhs)) {
-                    (I8(a), I8(b)) => a.$checked_func(b).map(I8),
-                    (I16(a), I16(b)) => a.$checked_func(b).map(I16),
-                    (I32(a), I32(b)) => a.$checked_func(b).map(I32),
-                    (I64(a), I64(b)) => a.$checked_func(b).map(I64),
-                    (Isize(Is32(a)), Isize(Is32(b))) => a.$checked_func(b).map(Is32).map(Isize),
-                    (Isize(Is64(a)), Isize(Is64(b))) => a.$checked_func(b).map(Is64).map(Isize),
-                    (U8(a), U8(b)) => a.$checked_func(b).map(U8),
-                    (U16(a), U16(b)) => a.$checked_func(b).map(U16),
-                    (U32(a), U32(b)) => a.$checked_func(b).map(U32),
-                    (U64(a), U64(b)) => a.$checked_func(b).map(U64),
-                    (Usize(Us32(a)), Usize(Us32(b))) => a.$checked_func(b).map(Us32).map(Usize),
-                    (Usize(Us64(a)), Usize(Us64(b))) => a.$checked_func(b).map(Us64).map(Usize),
-                    (Infer(a), Infer(b)) => a.$checked_func(b).map(Infer),
-                    (InferSigned(a), InferSigned(b)) => a.$checked_func(b).map(InferSigned),
-                    _ => return Err(UnequalTypes(Op::$op)),
-                }.ok_or(Overflow(Op::$op))
-            }
-        }
-    }
-}
-
-macro_rules! derive_binop {
-    ($op:ident, $func:ident) => {
-        impl ::std::ops::$op for ConstInt {
-            type Output = Result<Self, ConstMathErr>;
-            fn $func(self, rhs: Self) -> Result<Self, ConstMathErr> {
-                match try!(self.infer(rhs)) {
-                    (I8(a), I8(b)) => Ok(I8(a.$func(b))),
-                    (I16(a), I16(b)) => Ok(I16(a.$func(b))),
-                    (I32(a), I32(b)) => Ok(I32(a.$func(b))),
-                    (I64(a), I64(b)) => Ok(I64(a.$func(b))),
-                    (Isize(Is32(a)), Isize(Is32(b))) => Ok(Isize(Is32(a.$func(b)))),
-                    (Isize(Is64(a)), Isize(Is64(b))) => Ok(Isize(Is64(a.$func(b)))),
-                    (U8(a), U8(b)) => Ok(U8(a.$func(b))),
-                    (U16(a), U16(b)) => Ok(U16(a.$func(b))),
-                    (U32(a), U32(b)) => Ok(U32(a.$func(b))),
-                    (U64(a), U64(b)) => Ok(U64(a.$func(b))),
-                    (Usize(Us32(a)), Usize(Us32(b))) => Ok(Usize(Us32(a.$func(b)))),
-                    (Usize(Us64(a)), Usize(Us64(b))) => Ok(Usize(Us64(a.$func(b)))),
-                    (Infer(a), Infer(b)) => Ok(Infer(a.$func(b))),
-                    (InferSigned(a), InferSigned(b)) => Ok(InferSigned(a.$func(b))),
-                    _ => Err(UnequalTypes(Op::$op)),
-                }
-            }
-        }
-    }
-}
-
-impl_binop!(Add, add, checked_add);
-impl_binop!(Sub, sub, checked_sub);
-impl_binop!(Mul, mul, checked_mul);
-derive_binop!(BitAnd, bitand);
-derive_binop!(BitOr, bitor);
-derive_binop!(BitXor, bitxor);
-
-fn check_division(
-    lhs: ConstInt,
-    rhs: ConstInt,
-    op: Op,
-    zerr: ConstMathErr,
-) -> Result<(), ConstMathErr> {
-    match (lhs, rhs) {
-        (I8(_), I8(0)) => Err(zerr),
-        (I16(_), I16(0)) => Err(zerr),
-        (I32(_), I32(0)) => Err(zerr),
-        (I64(_), I64(0)) => Err(zerr),
-        (Isize(_), Isize(Is32(0))) => Err(zerr),
-        (Isize(_), Isize(Is64(0))) => Err(zerr),
-        (InferSigned(_), InferSigned(0)) => Err(zerr),
-
-        (U8(_), U8(0)) => Err(zerr),
-        (U16(_), U16(0)) => Err(zerr),
-        (U32(_), U32(0)) => Err(zerr),
-        (U64(_), U64(0)) => Err(zerr),
-        (Usize(_), Usize(Us32(0))) => Err(zerr),
-        (Usize(_), Usize(Us64(0))) => Err(zerr),
-        (Infer(_), Infer(0)) => Err(zerr),
-
-        (I8(::std::i8::MIN), I8(-1)) => Err(Overflow(op)),
-        (I16(::std::i16::MIN), I16(-1)) => Err(Overflow(op)),
-        (I32(::std::i32::MIN), I32(-1)) => Err(Overflow(op)),
-        (I64(::std::i64::MIN), I64(-1)) => Err(Overflow(op)),
-        (Isize(Is32(::std::i32::MIN)), Isize(Is32(-1))) => Err(Overflow(op)),
-        (Isize(Is64(::std::i64::MIN)), Isize(Is64(-1))) => Err(Overflow(op)),
-        (InferSigned(::std::i64::MIN), InferSigned(-1)) => Err(Overflow(op)),
-
-        _ => Ok(()),
-    }
-}
-
-impl ::std::ops::Div for ConstInt {
-    type Output = Result<Self, ConstMathErr>;
-    fn div(self, rhs: Self) -> Result<Self, ConstMathErr> {
-        let (lhs, rhs) = self.infer(rhs)?;
-        check_division(lhs, rhs, Op::Div, DivisionByZero)?;
-        match (lhs, rhs) {
-            (I8(a), I8(b)) => Ok(I8(a/b)),
-            (I16(a), I16(b)) => Ok(I16(a/b)),
-            (I32(a), I32(b)) => Ok(I32(a/b)),
-            (I64(a), I64(b)) => Ok(I64(a/b)),
-            (Isize(Is32(a)), Isize(Is32(b))) => Ok(Isize(Is32(a/b))),
-            (Isize(Is64(a)), Isize(Is64(b))) => Ok(Isize(Is64(a/b))),
-            (InferSigned(a), InferSigned(b)) => Ok(InferSigned(a/b)),
-
-            (U8(a), U8(b)) => Ok(U8(a/b)),
-            (U16(a), U16(b)) => Ok(U16(a/b)),
-            (U32(a), U32(b)) => Ok(U32(a/b)),
-            (U64(a), U64(b)) => Ok(U64(a/b)),
-            (Usize(Us32(a)), Usize(Us32(b))) => Ok(Usize(Us32(a/b))),
-            (Usize(Us64(a)), Usize(Us64(b))) => Ok(Usize(Us64(a/b))),
-            (Infer(a), Infer(b)) => Ok(Infer(a/b)),
-
-            _ => Err(UnequalTypes(Op::Div)),
-        }
-    }
-}
-
-impl ::std::ops::Rem for ConstInt {
-    type Output = Result<Self, ConstMathErr>;
-    fn rem(self, rhs: Self) -> Result<Self, ConstMathErr> {
-        let (lhs, rhs) = self.infer(rhs)?;
-        // should INT_MIN%-1 be zero or an error?
-        check_division(lhs, rhs, Op::Rem, RemainderByZero)?;
-        match (lhs, rhs) {
-            (I8(a), I8(b)) => Ok(I8(a%b)),
-            (I16(a), I16(b)) => Ok(I16(a%b)),
-            (I32(a), I32(b)) => Ok(I32(a%b)),
-            (I64(a), I64(b)) => Ok(I64(a%b)),
-            (Isize(Is32(a)), Isize(Is32(b))) => Ok(Isize(Is32(a%b))),
-            (Isize(Is64(a)), Isize(Is64(b))) => Ok(Isize(Is64(a%b))),
-            (InferSigned(a), InferSigned(b)) => Ok(InferSigned(a%b)),
-
-            (U8(a), U8(b)) => Ok(U8(a%b)),
-            (U16(a), U16(b)) => Ok(U16(a%b)),
-            (U32(a), U32(b)) => Ok(U32(a%b)),
-            (U64(a), U64(b)) => Ok(U64(a%b)),
-            (Usize(Us32(a)), Usize(Us32(b))) => Ok(Usize(Us32(a%b))),
-            (Usize(Us64(a)), Usize(Us64(b))) => Ok(Usize(Us64(a%b))),
-            (Infer(a), Infer(b)) => Ok(Infer(a%b)),
-
-            _ => Err(UnequalTypes(Op::Rem)),
-        }
-    }
-}
-
-impl ::std::ops::Shl<ConstInt> for ConstInt {
-    type Output = Result<Self, ConstMathErr>;
-    fn shl(self, rhs: Self) -> Result<Self, ConstMathErr> {
-        let b = rhs.to_u32().ok_or(ShiftNegative)?;
-        match self {
-            I8(a) => Ok(I8(overflowing!(a.overflowing_shl(b), Op::Shl))),
-            I16(a) => Ok(I16(overflowing!(a.overflowing_shl(b), Op::Shl))),
-            I32(a) => Ok(I32(overflowing!(a.overflowing_shl(b), Op::Shl))),
-            I64(a) => Ok(I64(overflowing!(a.overflowing_shl(b), Op::Shl))),
-            Isize(Is32(a)) => Ok(Isize(Is32(overflowing!(a.overflowing_shl(b), Op::Shl)))),
-            Isize(Is64(a)) => Ok(Isize(Is64(overflowing!(a.overflowing_shl(b), Op::Shl)))),
-            U8(a) => Ok(U8(overflowing!(a.overflowing_shl(b), Op::Shl))),
-            U16(a) => Ok(U16(overflowing!(a.overflowing_shl(b), Op::Shl))),
-            U32(a) => Ok(U32(overflowing!(a.overflowing_shl(b), Op::Shl))),
-            U64(a) => Ok(U64(overflowing!(a.overflowing_shl(b), Op::Shl))),
-            Usize(Us32(a)) => Ok(Usize(Us32(overflowing!(a.overflowing_shl(b), Op::Shl)))),
-            Usize(Us64(a)) => Ok(Usize(Us64(overflowing!(a.overflowing_shl(b), Op::Shl)))),
-            Infer(a) => Ok(Infer(overflowing!(a.overflowing_shl(b), Op::Shl))),
-            InferSigned(a) => Ok(InferSigned(overflowing!(a.overflowing_shl(b), Op::Shl))),
-        }
-    }
-}
-
-impl ::std::ops::Shr<ConstInt> for ConstInt {
-    type Output = Result<Self, ConstMathErr>;
-    fn shr(self, rhs: Self) -> Result<Self, ConstMathErr> {
-        let b = rhs.to_u32().ok_or(ShiftNegative)?;
-        match self {
-            I8(a) => Ok(I8(overflowing!(a.overflowing_shr(b), Op::Shr))),
-            I16(a) => Ok(I16(overflowing!(a.overflowing_shr(b), Op::Shr))),
-            I32(a) => Ok(I32(overflowing!(a.overflowing_shr(b), Op::Shr))),
-            I64(a) => Ok(I64(overflowing!(a.overflowing_shr(b), Op::Shl))),
-            Isize(Is32(a)) => Ok(Isize(Is32(overflowing!(a.overflowing_shr(b), Op::Shr)))),
-            Isize(Is64(a)) => Ok(Isize(Is64(overflowing!(a.overflowing_shr(b), Op::Shr)))),
-            U8(a) => Ok(U8(overflowing!(a.overflowing_shr(b), Op::Shr))),
-            U16(a) => Ok(U16(overflowing!(a.overflowing_shr(b), Op::Shr))),
-            U32(a) => Ok(U32(overflowing!(a.overflowing_shr(b), Op::Shr))),
-            U64(a) => Ok(U64(overflowing!(a.overflowing_shr(b), Op::Shr))),
-            Usize(Us32(a)) => Ok(Usize(Us32(overflowing!(a.overflowing_shr(b), Op::Shr)))),
-            Usize(Us64(a)) => Ok(Usize(Us64(overflowing!(a.overflowing_shr(b), Op::Shr)))),
-            Infer(a) => Ok(Infer(overflowing!(a.overflowing_shr(b), Op::Shr))),
-            InferSigned(a) => Ok(InferSigned(overflowing!(a.overflowing_shr(b), Op::Shr))),
-        }
-    }
-}
-
-impl ::std::ops::Neg for ConstInt {
-    type Output = Result<Self, ConstMathErr>;
-    fn neg(self) -> Result<Self, ConstMathErr> {
-        match self {
-            I8(a) => Ok(I8(overflowing!(a.overflowing_neg(), Op::Neg))),
-            I16(a) => Ok(I16(overflowing!(a.overflowing_neg(), Op::Neg))),
-            I32(a) => Ok(I32(overflowing!(a.overflowing_neg(), Op::Neg))),
-            I64(a) => Ok(I64(overflowing!(a.overflowing_neg(), Op::Neg))),
-            Isize(Is32(a)) => Ok(Isize(Is32(overflowing!(a.overflowing_neg(), Op::Neg)))),
-            Isize(Is64(a)) => Ok(Isize(Is64(overflowing!(a.overflowing_neg(), Op::Neg)))),
-            U8(0) => Ok(U8(0)),
-            U16(0) => Ok(U16(0)),
-            U32(0) => Ok(U32(0)),
-            U64(0) => Ok(U64(0)),
-            Usize(Us32(0)) => Ok(Usize(Us32(0))),
-            Usize(Us64(0)) => Ok(Usize(Us64(0))),
-            U8(_) => Err(UnsignedNegation),
-            U16(_) => Err(UnsignedNegation),
-            U32(_) => Err(UnsignedNegation),
-            U64(_) => Err(UnsignedNegation),
-            Usize(_) => Err(UnsignedNegation),
-            Infer(a @ 0...as_u64::I64MAX) => Ok(InferSigned(-(a as i64))),
-            Infer(_) => Err(Overflow(Op::Neg)),
-            InferSigned(a) => Ok(InferSigned(overflowing!(a.overflowing_neg(), Op::Neg))),
-        }
-    }
-}
-
-impl ::std::ops::Not for ConstInt {
-    type Output = Result<Self, ConstMathErr>;
-    fn not(self) -> Result<Self, ConstMathErr> {
-        match self {
-            I8(a) => Ok(I8(!a)),
-            I16(a) => Ok(I16(!a)),
-            I32(a) => Ok(I32(!a)),
-            I64(a) => Ok(I64(!a)),
-            Isize(Is32(a)) => Ok(Isize(Is32(!a))),
-            Isize(Is64(a)) => Ok(Isize(Is64(!a))),
-            U8(a) => Ok(U8(!a)),
-            U16(a) => Ok(U16(!a)),
-            U32(a) => Ok(U32(!a)),
-            U64(a) => Ok(U64(!a)),
-            Usize(Us32(a)) => Ok(Usize(Us32(!a))),
-            Usize(Us64(a)) => Ok(Usize(Us64(!a))),
-            Infer(a) => Ok(Infer(!a)),
-            InferSigned(a) => Ok(InferSigned(!a)),
-        }
-    }
-}
diff --git a/src/librustc_const_eval/is.rs b/src/librustc_const_eval/is.rs
deleted file mode 100644 (file)
index 082c651..0000000
+++ /dev/null
@@ -1,39 +0,0 @@
-// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-use syntax::ast;
-use super::err::*;
-
-/// Depending on the target only one variant is ever used in a compilation.
-/// Anything else is an error. This invariant is checked at several locations
-#[derive(Copy, Clone, Debug, RustcEncodable, RustcDecodable, Hash, Eq, PartialEq)]
-pub enum ConstIsize {
-    Is32(i32),
-    Is64(i64),
-}
-pub use self::ConstIsize::*;
-
-impl ConstIsize {
-    pub fn as_i64(self, target_int_ty: ast::IntTy) -> i64 {
-        match (self, target_int_ty) {
-            (Is32(i), ast::IntTy::I32) => i as i64,
-            (Is64(i), ast::IntTy::I64) => i,
-            _ => panic!("got invalid isize size for target"),
-        }
-    }
-    pub fn new(i: i64, target_int_ty: ast::IntTy) -> Result<Self, ConstMathErr> {
-        match target_int_ty {
-            ast::IntTy::I32 if i as i32 as i64 == i => Ok(Is32(i as i32)),
-            ast::IntTy::I32 => Err(LitOutOfRange(ast::IntTy::Is)),
-            ast::IntTy::I64 => Ok(Is64(i)),
-            _ => unreachable!(),
-        }
-    }
-}
diff --git a/src/librustc_const_eval/lib.rs b/src/librustc_const_eval/lib.rs
deleted file mode 100644 (file)
index 80b8c75..0000000
+++ /dev/null
@@ -1,43 +0,0 @@
-// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-//! Rusty Mathematics
-//!
-//! # Note
-//!
-//! This API is completely unstable and subject to change.
-
-#![crate_name = "rustc_const_eval"]
-#![unstable(feature = "rustc_private", issue = "27812")]
-#![crate_type = "dylib"]
-#![crate_type = "rlib"]
-#![doc(html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
-      html_favicon_url = "https://doc.rust-lang.org/favicon.ico",
-      html_root_url = "https://doc.rust-lang.org/nightly/")]
-
-
-#![feature(rustc_private)]
-#![feature(staged_api)]
-#![feature(question_mark)]
-
-#[macro_use] extern crate log;
-#[macro_use] extern crate syntax;
-
-extern crate serialize as rustc_serialize; // used by deriving
-
-mod int;
-mod us;
-mod is;
-mod err;
-
-pub use int::*;
-pub use us::*;
-pub use is::*;
-pub use err::ConstMathErr;
diff --git a/src/librustc_const_eval/us.rs b/src/librustc_const_eval/us.rs
deleted file mode 100644 (file)
index e5a7086..0000000
+++ /dev/null
@@ -1,39 +0,0 @@
-// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-use syntax::ast;
-use super::err::*;
-
-/// Depending on the target only one variant is ever used in a compilation.
-/// Anything else is an error. This invariant is checked at several locations
-#[derive(Copy, Clone, Debug, RustcEncodable, RustcDecodable, Hash, Eq, PartialEq)]
-pub enum ConstUsize {
-    Us32(u32),
-    Us64(u64),
-}
-pub use self::ConstUsize::*;
-
-impl ConstUsize {
-    pub fn as_u64(self, target_uint_ty: ast::UintTy) -> u64 {
-        match (self, target_uint_ty) {
-            (Us32(i), ast::UintTy::U32) => i as u64,
-            (Us64(i), ast::UintTy::U64) => i,
-            _ => panic!("got invalid usize size for target"),
-        }
-    }
-    pub fn new(i: u64, target_uint_ty: ast::UintTy) -> Result<Self, ConstMathErr> {
-        match target_uint_ty {
-            ast::UintTy::U32 if i as u32 as u64 == i => Ok(Us32(i as u32)),
-            ast::UintTy::U32 => Err(ULitOutOfRange(ast::UintTy::Us)),
-            ast::UintTy::U64 => Ok(Us64(i)),
-            _ => unreachable!(),
-        }
-    }
-}
diff --git a/src/librustc_const_math/Cargo.toml b/src/librustc_const_math/Cargo.toml
new file mode 100644 (file)
index 0000000..10aadab
--- /dev/null
@@ -0,0 +1,14 @@
+[package]
+authors = ["The Rust Project Developers"]
+name = "rustc_const_math"
+version = "0.0.0"
+
+[lib]
+name = "rustc_const_math"
+path = "lib.rs"
+crate-type = ["dylib"]
+
+[dependencies]
+log = { path = "../liblog" }
+serialize = { path = "../libserialize" }
+syntax = { path = "../libsyntax" }
diff --git a/src/librustc_const_math/err.rs b/src/librustc_const_math/err.rs
new file mode 100644 (file)
index 0000000..126b382
--- /dev/null
@@ -0,0 +1,85 @@
+// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use syntax::ast;
+
+#[derive(Debug, PartialEq, Eq, Clone)]
+pub enum ConstMathErr {
+    NotInRange,
+    CmpBetweenUnequalTypes,
+    UnequalTypes(Op),
+    Overflow(Op),
+    ShiftNegative,
+    DivisionByZero,
+    RemainderByZero,
+    UnsignedNegation,
+    ULitOutOfRange(ast::UintTy),
+    LitOutOfRange(ast::IntTy),
+}
+pub use self::ConstMathErr::*;
+
+#[derive(Debug, PartialEq, Eq, Clone)]
+pub enum Op {
+    Add,
+    Sub,
+    Mul,
+    Div,
+    Rem,
+    Shr,
+    Shl,
+    Neg,
+    BitAnd,
+    BitOr,
+    BitXor,
+}
+
+impl ConstMathErr {
+    pub fn description(&self) -> &'static str {
+        use self::Op::*;
+        match *self {
+            NotInRange => "inferred value out of range",
+            CmpBetweenUnequalTypes => "compared two integrals of different types",
+            UnequalTypes(Add) => "tried to add two integrals of different types",
+            UnequalTypes(Sub) => "tried to subtract two integrals of different types",
+            UnequalTypes(Mul) => "tried to multiply two integrals of different types",
+            UnequalTypes(Div) => "tried to divide two integrals of different types",
+            UnequalTypes(Rem) => {
+                "tried to calculate the remainder of two integrals of different types"
+            },
+            UnequalTypes(BitAnd) => "tried to bitand two integrals of different types",
+            UnequalTypes(BitOr) => "tried to bitor two integrals of different types",
+            UnequalTypes(BitXor) => "tried to xor two integrals of different types",
+            UnequalTypes(_) => unreachable!(),
+            Overflow(Add) => "attempted to add with overflow",
+            Overflow(Sub) => "attempted to subtract with overflow",
+            Overflow(Mul) => "attempted to multiply with overflow",
+            Overflow(Div) => "attempted to divide with overflow",
+            Overflow(Rem) => "attempted to calculate the remainder with overflow",
+            Overflow(Neg) => "attempted to negate with overflow",
+            Overflow(Shr) => "attempted to shift right with overflow",
+            Overflow(Shl) => "attempted to shift left with overflow",
+            Overflow(_) => unreachable!(),
+            ShiftNegative => "attempted to shift by a negative amount",
+            DivisionByZero => "attempted to divide by zero",
+            RemainderByZero => "attempted to calculate the remainder with a divisor of zero",
+            UnsignedNegation => "unary negation of unsigned integer",
+            ULitOutOfRange(ast::UintTy::U8) => "literal out of range for u8",
+            ULitOutOfRange(ast::UintTy::U16) => "literal out of range for u16",
+            ULitOutOfRange(ast::UintTy::U32) => "literal out of range for u32",
+            ULitOutOfRange(ast::UintTy::U64) => "literal out of range for u64",
+            ULitOutOfRange(ast::UintTy::Us) => "literal out of range for usize",
+            LitOutOfRange(ast::IntTy::I8) => "literal out of range for i8",
+            LitOutOfRange(ast::IntTy::I16) => "literal out of range for i16",
+            LitOutOfRange(ast::IntTy::I32) => "literal out of range for i32",
+            LitOutOfRange(ast::IntTy::I64) => "literal out of range for i64",
+            LitOutOfRange(ast::IntTy::Is) => "literal out of range for isize",
+        }
+    }
+}
diff --git a/src/librustc_const_math/int.rs b/src/librustc_const_math/int.rs
new file mode 100644 (file)
index 0000000..7576a98
--- /dev/null
@@ -0,0 +1,569 @@
+// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use std::cmp::Ordering;
+use syntax::attr::IntType;
+use syntax::ast::{IntTy, UintTy};
+
+use super::is::*;
+use super::us::*;
+use super::err::*;
+
+#[derive(Copy, Clone, Debug, RustcEncodable, RustcDecodable, Hash, Eq, PartialEq)]
+pub enum ConstInt {
+    I8(i8),
+    I16(i16),
+    I32(i32),
+    I64(i64),
+    Isize(ConstIsize),
+    U8(u8),
+    U16(u16),
+    U32(u32),
+    U64(u64),
+    Usize(ConstUsize),
+    Infer(u64),
+    InferSigned(i64),
+}
+pub use self::ConstInt::*;
+
+
+macro_rules! bounds {
+    ($($t:ident $min:ident $max:ident)*) => {
+        mod as_u64 {
+            $(
+                #[allow(dead_code)]
+                pub const $min: u64 = ::std::$t::MIN as u64;
+                #[allow(dead_code)]
+                pub const $max: u64 = ::std::$t::MAX as u64;
+            )*
+        }
+        mod as_i64 {
+            $(
+                #[allow(dead_code)]
+                pub const $min: i64 = ::std::$t::MIN as i64;
+                #[allow(dead_code)]
+                pub const $max: i64 = ::std::$t::MAX as i64;
+            )*
+        }
+    }
+}
+
+bounds!{
+    i8 I8MIN I8MAX i16 I16MIN I16MAX i32 I32MIN I32MAX i64 I64MIN I64MAX isize IMIN IMAX
+    u8 U8MIN U8MAX u16 U16MIN U16MAX u32 U32MIN U32MAX u64 U64MIN U64MAX usize UMIN UMAX
+}
+
+impl ConstInt {
+    /// If either value is `Infer` or `InferSigned`, try to turn the value into the type of
+    /// the other value. If both values have no type, don't do anything
+    pub fn infer(self, other: Self) -> Result<(Self, Self), ConstMathErr> {
+        let inferred = match (self, other) {
+            (InferSigned(_), InferSigned(_))
+            | (Infer(_), Infer(_)) => self, // no inference possible
+            // kindof wrong, you could have had values > I64MAX during computation of a
+            (Infer(a @ 0...as_u64::I64MAX), InferSigned(_)) => InferSigned(a as i64),
+            (Infer(_), InferSigned(_)) => return Err(ConstMathErr::NotInRange),
+            (_, InferSigned(_))
+            | (_, Infer(_)) => return other.infer(self).map(|(b, a)| (a, b)),
+
+            (Infer(a @ 0...as_u64::I8MAX), I8(_)) => I8(a as i64 as i8),
+            (Infer(a @ 0...as_u64::I16MAX), I16(_)) => I16(a as i64 as i16),
+            (Infer(a @ 0...as_u64::I32MAX), I32(_)) => I32(a as i64 as i32),
+            (Infer(a @ 0...as_u64::I64MAX), I64(_)) => I64(a as i64),
+            (Infer(a @ 0...as_u64::I32MAX), Isize(Is32(_))) => Isize(Is32(a as i64 as i32)),
+            (Infer(a @ 0...as_u64::I64MAX), Isize(Is64(_))) => Isize(Is64(a as i64)),
+            (Infer(a @ 0...as_u64::U8MAX), U8(_)) => U8(a as u8),
+            (Infer(a @ 0...as_u64::U16MAX), U16(_)) => U16(a as u16),
+            (Infer(a @ 0...as_u64::U32MAX), U32(_)) => U32(a as u32),
+            (Infer(a), U64(_)) => U64(a),
+            (Infer(a @ 0...as_u64::U32MAX), Usize(Us32(_))) => Usize(Us32(a as u32)),
+            (Infer(a), Usize(Us64(_))) => Usize(Us64(a)),
+
+            (Infer(_), _) => return Err(ConstMathErr::NotInRange),
+
+            (InferSigned(a @ as_i64::I8MIN...as_i64::I8MAX), I8(_)) => I8(a as i8),
+            (InferSigned(a @ as_i64::I16MIN...as_i64::I16MAX), I16(_)) => I16(a as i16),
+            (InferSigned(a @ as_i64::I32MIN...as_i64::I32MAX), I32(_)) => I32(a as i32),
+            (InferSigned(a), I64(_)) => I64(a),
+            (InferSigned(a @ as_i64::I32MIN...as_i64::I32MAX), Isize(Is32(_))) => {
+                Isize(Is32(a as i32))
+            },
+            (InferSigned(a), Isize(Is64(_))) => Isize(Is64(a)),
+            (InferSigned(a @ 0...as_i64::U8MAX), U8(_)) => U8(a as u8),
+            (InferSigned(a @ 0...as_i64::U16MAX), U16(_)) => U16(a as u16),
+            (InferSigned(a @ 0...as_i64::U32MAX), U32(_)) => U32(a as u32),
+            (InferSigned(a @ 0...as_i64::I64MAX), U64(_)) => U64(a as u64),
+            (InferSigned(a @ 0...as_i64::U32MAX), Usize(Us32(_))) => Usize(Us32(a as u32)),
+            (InferSigned(a @ 0...as_i64::I64MAX), Usize(Us64(_))) => Usize(Us64(a as u64)),
+            (InferSigned(_), _) => return Err(ConstMathErr::NotInRange),
+            _ => self, // already known types
+        };
+        Ok((inferred, other))
+    }
+
+    /// Turn this value into an `Infer` or an `InferSigned`
+    pub fn erase_type(self) -> Self {
+        match self {
+            Infer(i) => Infer(i),
+            InferSigned(i) if i < 0 => InferSigned(i),
+            I8(i) if i < 0 => InferSigned(i as i64),
+            I16(i) if i < 0 => InferSigned(i as i64),
+            I32(i) if i < 0 => InferSigned(i as i64),
+            I64(i) if i < 0 => InferSigned(i as i64),
+            Isize(Is32(i)) if i < 0 => InferSigned(i as i64),
+            Isize(Is64(i)) if i < 0 => InferSigned(i as i64),
+            InferSigned(i) => Infer(i as u64),
+            I8(i) => Infer(i as u64),
+            I16(i) => Infer(i as u64),
+            I32(i) => Infer(i as u64),
+            I64(i) => Infer(i as u64),
+            Isize(Is32(i)) => Infer(i as u64),
+            Isize(Is64(i)) => Infer(i as u64),
+            U8(i) => Infer(i as u64),
+            U16(i) => Infer(i as u64),
+            U32(i) => Infer(i as u64),
+            U64(i) => Infer(i as u64),
+            Usize(Us32(i)) => Infer(i as u64),
+            Usize(Us64(i)) => Infer(i),
+        }
+    }
+
+    /// Description of the type, not the value
+    pub fn description(&self) -> &'static str {
+        match *self {
+            Infer(_) => "not yet inferred integral",
+            InferSigned(_) => "not yet inferred signed integral",
+            I8(_) => "i8",
+            I16(_) => "i16",
+            I32(_) => "i32",
+            I64(_) => "i64",
+            Isize(_) => "isize",
+            U8(_) => "u8",
+            U16(_) => "u16",
+            U32(_) => "u32",
+            U64(_) => "u64",
+            Usize(_) => "usize",
+        }
+    }
+
+    /// Erases the type and returns a u64.
+    /// This is not the same as `-5i8 as u64` but as `-5i8 as i64 as u64`
+    pub fn to_u64_unchecked(self) -> u64 {
+        match self.erase_type() {
+            ConstInt::Infer(i) => i,
+            ConstInt::InferSigned(i) => i as u64,
+            _ => unreachable!(),
+        }
+    }
+
+    /// Converts the value to a `u32` if it's in the range 0...std::u32::MAX
+    pub fn to_u32(&self) -> Option<u32> {
+        match *self {
+            I8(v) if v >= 0 => Some(v as u32),
+            I16(v) if v >= 0 => Some(v as u32),
+            I32(v) if v >= 0 => Some(v as u32),
+            InferSigned(v)
+            | Isize(Is64(v))
+            | I64(v) if v >= 0 && v <= ::std::u32::MAX as i64 => Some(v as u32),
+            Isize(Is32(v)) if v >= 0 => Some(v as u32),
+            U8(v) => Some(v as u32),
+            U16(v) => Some(v as u32),
+            U32(v) => Some(v),
+            Infer(v)
+            | Usize(Us64(v))
+            | U64(v) if v <= ::std::u32::MAX as u64 => Some(v as u32),
+            Usize(Us32(v)) => Some(v),
+            _ => None,
+        }
+    }
+
+    /// Converts the value to a `u64` if it's >= 0
+    pub fn to_u64(&self) -> Option<u64> {
+        match *self {
+            Infer(v) => Some(v),
+            InferSigned(v) if v >= 0 => Some(v as u64),
+            I8(v) if v >= 0 => Some(v as u64),
+            I16(v) if v >= 0 => Some(v as u64),
+            I32(v) if v >= 0 => Some(v as u64),
+            I64(v) if v >= 0 => Some(v as u64),
+            Isize(Is32(v)) if v >= 0 => Some(v as u64),
+            Isize(Is64(v)) if v >= 0 => Some(v as u64),
+            U8(v) => Some(v as u64),
+            U16(v) => Some(v as u64),
+            U32(v) => Some(v as u64),
+            U64(v) => Some(v),
+            Usize(Us32(v)) => Some(v as u64),
+            Usize(Us64(v)) => Some(v),
+            _ => None,
+        }
+    }
+
+    pub fn is_negative(&self) -> bool {
+        match *self {
+            I8(v) => v < 0,
+            I16(v) => v < 0,
+            I32(v) => v < 0,
+            I64(v) => v < 0,
+            Isize(Is32(v)) => v < 0,
+            Isize(Is64(v)) => v < 0,
+            InferSigned(v) => v < 0,
+            _ => false,
+        }
+    }
+
+    /// Compares the values if they are of the same type
+    pub fn try_cmp(self, rhs: Self) -> Result<::std::cmp::Ordering, ConstMathErr> {
+        match self.infer(rhs)? {
+            (I8(a), I8(b)) => Ok(a.cmp(&b)),
+            (I16(a), I16(b)) => Ok(a.cmp(&b)),
+            (I32(a), I32(b)) => Ok(a.cmp(&b)),
+            (I64(a), I64(b)) => Ok(a.cmp(&b)),
+            (Isize(Is32(a)), Isize(Is32(b))) => Ok(a.cmp(&b)),
+            (Isize(Is64(a)), Isize(Is64(b))) => Ok(a.cmp(&b)),
+            (U8(a), U8(b)) => Ok(a.cmp(&b)),
+            (U16(a), U16(b)) => Ok(a.cmp(&b)),
+            (U32(a), U32(b)) => Ok(a.cmp(&b)),
+            (U64(a), U64(b)) => Ok(a.cmp(&b)),
+            (Usize(Us32(a)), Usize(Us32(b))) => Ok(a.cmp(&b)),
+            (Usize(Us64(a)), Usize(Us64(b))) => Ok(a.cmp(&b)),
+            (Infer(a), Infer(b)) => Ok(a.cmp(&b)),
+            (InferSigned(a), InferSigned(b)) => Ok(a.cmp(&b)),
+            _ => Err(CmpBetweenUnequalTypes),
+        }
+    }
+
+    /// Adds 1 to the value and wraps around if the maximum for the type is reached
+    pub fn wrap_incr(self) -> Self {
+        macro_rules! add1 {
+            ($e:expr) => { ($e).wrapping_add(1) }
+        }
+        match self {
+            ConstInt::I8(i) => ConstInt::I8(add1!(i)),
+            ConstInt::I16(i) => ConstInt::I16(add1!(i)),
+            ConstInt::I32(i) => ConstInt::I32(add1!(i)),
+            ConstInt::I64(i) => ConstInt::I64(add1!(i)),
+            ConstInt::Isize(ConstIsize::Is32(i)) => ConstInt::Isize(ConstIsize::Is32(add1!(i))),
+            ConstInt::Isize(ConstIsize::Is64(i)) => ConstInt::Isize(ConstIsize::Is64(add1!(i))),
+            ConstInt::U8(i) => ConstInt::U8(add1!(i)),
+            ConstInt::U16(i) => ConstInt::U16(add1!(i)),
+            ConstInt::U32(i) => ConstInt::U32(add1!(i)),
+            ConstInt::U64(i) => ConstInt::U64(add1!(i)),
+            ConstInt::Usize(ConstUsize::Us32(i)) => ConstInt::Usize(ConstUsize::Us32(add1!(i))),
+            ConstInt::Usize(ConstUsize::Us64(i)) => ConstInt::Usize(ConstUsize::Us64(add1!(i))),
+            ConstInt::Infer(_) | ConstInt::InferSigned(_) => panic!("no type info for const int"),
+        }
+    }
+
+    pub fn int_type(self) -> Option<IntType> {
+        match self {
+            ConstInt::I8(_) => Some(IntType::SignedInt(IntTy::I8)),
+            ConstInt::I16(_) => Some(IntType::SignedInt(IntTy::I16)),
+            ConstInt::I32(_) => Some(IntType::SignedInt(IntTy::I32)),
+            ConstInt::I64(_) => Some(IntType::SignedInt(IntTy::I64)),
+            ConstInt::Isize(_) => Some(IntType::SignedInt(IntTy::Is)),
+            ConstInt::U8(_) => Some(IntType::UnsignedInt(UintTy::U8)),
+            ConstInt::U16(_) => Some(IntType::UnsignedInt(UintTy::U16)),
+            ConstInt::U32(_) => Some(IntType::UnsignedInt(UintTy::U32)),
+            ConstInt::U64(_) => Some(IntType::UnsignedInt(UintTy::U64)),
+            ConstInt::Usize(_) => Some(IntType::UnsignedInt(UintTy::Us)),
+            _ => None,
+        }
+    }
+}
+
+impl ::std::cmp::PartialOrd for ConstInt {
+    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
+        self.try_cmp(*other).ok()
+    }
+}
+
+impl ::std::cmp::Ord for ConstInt {
+    fn cmp(&self, other: &Self) -> Ordering {
+        self.try_cmp(*other).unwrap()
+    }
+}
+
+impl ::std::fmt::Display for ConstInt {
+    fn fmt(&self, fmt: &mut ::std::fmt::Formatter) -> Result<(), ::std::fmt::Error> {
+        match *self {
+            Infer(i) => write!(fmt, "{}", i),
+            InferSigned(i) => write!(fmt, "{}", i),
+            I8(i) => write!(fmt, "{}i8", i),
+            I16(i) => write!(fmt, "{}i16", i),
+            I32(i) => write!(fmt, "{}i32", i),
+            I64(i) => write!(fmt, "{}i64", i),
+            Isize(ConstIsize::Is64(i)) => write!(fmt, "{}isize", i),
+            Isize(ConstIsize::Is32(i)) => write!(fmt, "{}isize", i),
+            U8(i) => write!(fmt, "{}u8", i),
+            U16(i) => write!(fmt, "{}u16", i),
+            U32(i) => write!(fmt, "{}u32", i),
+            U64(i) => write!(fmt, "{}u64", i),
+            Usize(ConstUsize::Us64(i)) => write!(fmt, "{}usize", i),
+            Usize(ConstUsize::Us32(i)) => write!(fmt, "{}usize", i),
+        }
+    }
+}
+
+macro_rules! overflowing {
+    ($e:expr, $err:expr) => {{
+        if $e.1 {
+            return Err(Overflow($err));
+        } else {
+            $e.0
+        }
+    }}
+}
+
+macro_rules! impl_binop {
+    ($op:ident, $func:ident, $checked_func:ident) => {
+        impl ::std::ops::$op for ConstInt {
+            type Output = Result<Self, ConstMathErr>;
+            fn $func(self, rhs: Self) -> Result<Self, ConstMathErr> {
+                match try!(self.infer(rhs)) {
+                    (I8(a), I8(b)) => a.$checked_func(b).map(I8),
+                    (I16(a), I16(b)) => a.$checked_func(b).map(I16),
+                    (I32(a), I32(b)) => a.$checked_func(b).map(I32),
+                    (I64(a), I64(b)) => a.$checked_func(b).map(I64),
+                    (Isize(Is32(a)), Isize(Is32(b))) => a.$checked_func(b).map(Is32).map(Isize),
+                    (Isize(Is64(a)), Isize(Is64(b))) => a.$checked_func(b).map(Is64).map(Isize),
+                    (U8(a), U8(b)) => a.$checked_func(b).map(U8),
+                    (U16(a), U16(b)) => a.$checked_func(b).map(U16),
+                    (U32(a), U32(b)) => a.$checked_func(b).map(U32),
+                    (U64(a), U64(b)) => a.$checked_func(b).map(U64),
+                    (Usize(Us32(a)), Usize(Us32(b))) => a.$checked_func(b).map(Us32).map(Usize),
+                    (Usize(Us64(a)), Usize(Us64(b))) => a.$checked_func(b).map(Us64).map(Usize),
+                    (Infer(a), Infer(b)) => a.$checked_func(b).map(Infer),
+                    (InferSigned(a), InferSigned(b)) => a.$checked_func(b).map(InferSigned),
+                    _ => return Err(UnequalTypes(Op::$op)),
+                }.ok_or(Overflow(Op::$op))
+            }
+        }
+    }
+}
+
+macro_rules! derive_binop {
+    ($op:ident, $func:ident) => {
+        impl ::std::ops::$op for ConstInt {
+            type Output = Result<Self, ConstMathErr>;
+            fn $func(self, rhs: Self) -> Result<Self, ConstMathErr> {
+                match try!(self.infer(rhs)) {
+                    (I8(a), I8(b)) => Ok(I8(a.$func(b))),
+                    (I16(a), I16(b)) => Ok(I16(a.$func(b))),
+                    (I32(a), I32(b)) => Ok(I32(a.$func(b))),
+                    (I64(a), I64(b)) => Ok(I64(a.$func(b))),
+                    (Isize(Is32(a)), Isize(Is32(b))) => Ok(Isize(Is32(a.$func(b)))),
+                    (Isize(Is64(a)), Isize(Is64(b))) => Ok(Isize(Is64(a.$func(b)))),
+                    (U8(a), U8(b)) => Ok(U8(a.$func(b))),
+                    (U16(a), U16(b)) => Ok(U16(a.$func(b))),
+                    (U32(a), U32(b)) => Ok(U32(a.$func(b))),
+                    (U64(a), U64(b)) => Ok(U64(a.$func(b))),
+                    (Usize(Us32(a)), Usize(Us32(b))) => Ok(Usize(Us32(a.$func(b)))),
+                    (Usize(Us64(a)), Usize(Us64(b))) => Ok(Usize(Us64(a.$func(b)))),
+                    (Infer(a), Infer(b)) => Ok(Infer(a.$func(b))),
+                    (InferSigned(a), InferSigned(b)) => Ok(InferSigned(a.$func(b))),
+                    _ => Err(UnequalTypes(Op::$op)),
+                }
+            }
+        }
+    }
+}
+
+impl_binop!(Add, add, checked_add);
+impl_binop!(Sub, sub, checked_sub);
+impl_binop!(Mul, mul, checked_mul);
+derive_binop!(BitAnd, bitand);
+derive_binop!(BitOr, bitor);
+derive_binop!(BitXor, bitxor);
+
+fn check_division(
+    lhs: ConstInt,
+    rhs: ConstInt,
+    op: Op,
+    zerr: ConstMathErr,
+) -> Result<(), ConstMathErr> {
+    match (lhs, rhs) {
+        (I8(_), I8(0)) => Err(zerr),
+        (I16(_), I16(0)) => Err(zerr),
+        (I32(_), I32(0)) => Err(zerr),
+        (I64(_), I64(0)) => Err(zerr),
+        (Isize(_), Isize(Is32(0))) => Err(zerr),
+        (Isize(_), Isize(Is64(0))) => Err(zerr),
+        (InferSigned(_), InferSigned(0)) => Err(zerr),
+
+        (U8(_), U8(0)) => Err(zerr),
+        (U16(_), U16(0)) => Err(zerr),
+        (U32(_), U32(0)) => Err(zerr),
+        (U64(_), U64(0)) => Err(zerr),
+        (Usize(_), Usize(Us32(0))) => Err(zerr),
+        (Usize(_), Usize(Us64(0))) => Err(zerr),
+        (Infer(_), Infer(0)) => Err(zerr),
+
+        (I8(::std::i8::MIN), I8(-1)) => Err(Overflow(op)),
+        (I16(::std::i16::MIN), I16(-1)) => Err(Overflow(op)),
+        (I32(::std::i32::MIN), I32(-1)) => Err(Overflow(op)),
+        (I64(::std::i64::MIN), I64(-1)) => Err(Overflow(op)),
+        (Isize(Is32(::std::i32::MIN)), Isize(Is32(-1))) => Err(Overflow(op)),
+        (Isize(Is64(::std::i64::MIN)), Isize(Is64(-1))) => Err(Overflow(op)),
+        (InferSigned(::std::i64::MIN), InferSigned(-1)) => Err(Overflow(op)),
+
+        _ => Ok(()),
+    }
+}
+
+impl ::std::ops::Div for ConstInt {
+    type Output = Result<Self, ConstMathErr>;
+    fn div(self, rhs: Self) -> Result<Self, ConstMathErr> {
+        let (lhs, rhs) = self.infer(rhs)?;
+        check_division(lhs, rhs, Op::Div, DivisionByZero)?;
+        match (lhs, rhs) {
+            (I8(a), I8(b)) => Ok(I8(a/b)),
+            (I16(a), I16(b)) => Ok(I16(a/b)),
+            (I32(a), I32(b)) => Ok(I32(a/b)),
+            (I64(a), I64(b)) => Ok(I64(a/b)),
+            (Isize(Is32(a)), Isize(Is32(b))) => Ok(Isize(Is32(a/b))),
+            (Isize(Is64(a)), Isize(Is64(b))) => Ok(Isize(Is64(a/b))),
+            (InferSigned(a), InferSigned(b)) => Ok(InferSigned(a/b)),
+
+            (U8(a), U8(b)) => Ok(U8(a/b)),
+            (U16(a), U16(b)) => Ok(U16(a/b)),
+            (U32(a), U32(b)) => Ok(U32(a/b)),
+            (U64(a), U64(b)) => Ok(U64(a/b)),
+            (Usize(Us32(a)), Usize(Us32(b))) => Ok(Usize(Us32(a/b))),
+            (Usize(Us64(a)), Usize(Us64(b))) => Ok(Usize(Us64(a/b))),
+            (Infer(a), Infer(b)) => Ok(Infer(a/b)),
+
+            _ => Err(UnequalTypes(Op::Div)),
+        }
+    }
+}
+
+impl ::std::ops::Rem for ConstInt {
+    type Output = Result<Self, ConstMathErr>;
+    fn rem(self, rhs: Self) -> Result<Self, ConstMathErr> {
+        let (lhs, rhs) = self.infer(rhs)?;
+        // should INT_MIN%-1 be zero or an error?
+        check_division(lhs, rhs, Op::Rem, RemainderByZero)?;
+        match (lhs, rhs) {
+            (I8(a), I8(b)) => Ok(I8(a%b)),
+            (I16(a), I16(b)) => Ok(I16(a%b)),
+            (I32(a), I32(b)) => Ok(I32(a%b)),
+            (I64(a), I64(b)) => Ok(I64(a%b)),
+            (Isize(Is32(a)), Isize(Is32(b))) => Ok(Isize(Is32(a%b))),
+            (Isize(Is64(a)), Isize(Is64(b))) => Ok(Isize(Is64(a%b))),
+            (InferSigned(a), InferSigned(b)) => Ok(InferSigned(a%b)),
+
+            (U8(a), U8(b)) => Ok(U8(a%b)),
+            (U16(a), U16(b)) => Ok(U16(a%b)),
+            (U32(a), U32(b)) => Ok(U32(a%b)),
+            (U64(a), U64(b)) => Ok(U64(a%b)),
+            (Usize(Us32(a)), Usize(Us32(b))) => Ok(Usize(Us32(a%b))),
+            (Usize(Us64(a)), Usize(Us64(b))) => Ok(Usize(Us64(a%b))),
+            (Infer(a), Infer(b)) => Ok(Infer(a%b)),
+
+            _ => Err(UnequalTypes(Op::Rem)),
+        }
+    }
+}
+
+impl ::std::ops::Shl<ConstInt> for ConstInt {
+    type Output = Result<Self, ConstMathErr>;
+    fn shl(self, rhs: Self) -> Result<Self, ConstMathErr> {
+        let b = rhs.to_u32().ok_or(ShiftNegative)?;
+        match self {
+            I8(a) => Ok(I8(overflowing!(a.overflowing_shl(b), Op::Shl))),
+            I16(a) => Ok(I16(overflowing!(a.overflowing_shl(b), Op::Shl))),
+            I32(a) => Ok(I32(overflowing!(a.overflowing_shl(b), Op::Shl))),
+            I64(a) => Ok(I64(overflowing!(a.overflowing_shl(b), Op::Shl))),
+            Isize(Is32(a)) => Ok(Isize(Is32(overflowing!(a.overflowing_shl(b), Op::Shl)))),
+            Isize(Is64(a)) => Ok(Isize(Is64(overflowing!(a.overflowing_shl(b), Op::Shl)))),
+            U8(a) => Ok(U8(overflowing!(a.overflowing_shl(b), Op::Shl))),
+            U16(a) => Ok(U16(overflowing!(a.overflowing_shl(b), Op::Shl))),
+            U32(a) => Ok(U32(overflowing!(a.overflowing_shl(b), Op::Shl))),
+            U64(a) => Ok(U64(overflowing!(a.overflowing_shl(b), Op::Shl))),
+            Usize(Us32(a)) => Ok(Usize(Us32(overflowing!(a.overflowing_shl(b), Op::Shl)))),
+            Usize(Us64(a)) => Ok(Usize(Us64(overflowing!(a.overflowing_shl(b), Op::Shl)))),
+            Infer(a) => Ok(Infer(overflowing!(a.overflowing_shl(b), Op::Shl))),
+            InferSigned(a) => Ok(InferSigned(overflowing!(a.overflowing_shl(b), Op::Shl))),
+        }
+    }
+}
+
+impl ::std::ops::Shr<ConstInt> for ConstInt {
+    type Output = Result<Self, ConstMathErr>;
+    fn shr(self, rhs: Self) -> Result<Self, ConstMathErr> {
+        let b = rhs.to_u32().ok_or(ShiftNegative)?;
+        match self {
+            I8(a) => Ok(I8(overflowing!(a.overflowing_shr(b), Op::Shr))),
+            I16(a) => Ok(I16(overflowing!(a.overflowing_shr(b), Op::Shr))),
+            I32(a) => Ok(I32(overflowing!(a.overflowing_shr(b), Op::Shr))),
+            I64(a) => Ok(I64(overflowing!(a.overflowing_shr(b), Op::Shl))),
+            Isize(Is32(a)) => Ok(Isize(Is32(overflowing!(a.overflowing_shr(b), Op::Shr)))),
+            Isize(Is64(a)) => Ok(Isize(Is64(overflowing!(a.overflowing_shr(b), Op::Shr)))),
+            U8(a) => Ok(U8(overflowing!(a.overflowing_shr(b), Op::Shr))),
+            U16(a) => Ok(U16(overflowing!(a.overflowing_shr(b), Op::Shr))),
+            U32(a) => Ok(U32(overflowing!(a.overflowing_shr(b), Op::Shr))),
+            U64(a) => Ok(U64(overflowing!(a.overflowing_shr(b), Op::Shr))),
+            Usize(Us32(a)) => Ok(Usize(Us32(overflowing!(a.overflowing_shr(b), Op::Shr)))),
+            Usize(Us64(a)) => Ok(Usize(Us64(overflowing!(a.overflowing_shr(b), Op::Shr)))),
+            Infer(a) => Ok(Infer(overflowing!(a.overflowing_shr(b), Op::Shr))),
+            InferSigned(a) => Ok(InferSigned(overflowing!(a.overflowing_shr(b), Op::Shr))),
+        }
+    }
+}
+
+impl ::std::ops::Neg for ConstInt {
+    type Output = Result<Self, ConstMathErr>;
+    fn neg(self) -> Result<Self, ConstMathErr> {
+        match self {
+            I8(a) => Ok(I8(overflowing!(a.overflowing_neg(), Op::Neg))),
+            I16(a) => Ok(I16(overflowing!(a.overflowing_neg(), Op::Neg))),
+            I32(a) => Ok(I32(overflowing!(a.overflowing_neg(), Op::Neg))),
+            I64(a) => Ok(I64(overflowing!(a.overflowing_neg(), Op::Neg))),
+            Isize(Is32(a)) => Ok(Isize(Is32(overflowing!(a.overflowing_neg(), Op::Neg)))),
+            Isize(Is64(a)) => Ok(Isize(Is64(overflowing!(a.overflowing_neg(), Op::Neg)))),
+            U8(0) => Ok(U8(0)),
+            U16(0) => Ok(U16(0)),
+            U32(0) => Ok(U32(0)),
+            U64(0) => Ok(U64(0)),
+            Usize(Us32(0)) => Ok(Usize(Us32(0))),
+            Usize(Us64(0)) => Ok(Usize(Us64(0))),
+            U8(_) => Err(UnsignedNegation),
+            U16(_) => Err(UnsignedNegation),
+            U32(_) => Err(UnsignedNegation),
+            U64(_) => Err(UnsignedNegation),
+            Usize(_) => Err(UnsignedNegation),
+            Infer(a @ 0...as_u64::I64MAX) => Ok(InferSigned(-(a as i64))),
+            Infer(_) => Err(Overflow(Op::Neg)),
+            InferSigned(a) => Ok(InferSigned(overflowing!(a.overflowing_neg(), Op::Neg))),
+        }
+    }
+}
+
+impl ::std::ops::Not for ConstInt {
+    type Output = Result<Self, ConstMathErr>;
+    fn not(self) -> Result<Self, ConstMathErr> {
+        match self {
+            I8(a) => Ok(I8(!a)),
+            I16(a) => Ok(I16(!a)),
+            I32(a) => Ok(I32(!a)),
+            I64(a) => Ok(I64(!a)),
+            Isize(Is32(a)) => Ok(Isize(Is32(!a))),
+            Isize(Is64(a)) => Ok(Isize(Is64(!a))),
+            U8(a) => Ok(U8(!a)),
+            U16(a) => Ok(U16(!a)),
+            U32(a) => Ok(U32(!a)),
+            U64(a) => Ok(U64(!a)),
+            Usize(Us32(a)) => Ok(Usize(Us32(!a))),
+            Usize(Us64(a)) => Ok(Usize(Us64(!a))),
+            Infer(a) => Ok(Infer(!a)),
+            InferSigned(a) => Ok(InferSigned(!a)),
+        }
+    }
+}
diff --git a/src/librustc_const_math/is.rs b/src/librustc_const_math/is.rs
new file mode 100644 (file)
index 0000000..082c651
--- /dev/null
@@ -0,0 +1,39 @@
+// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use syntax::ast;
+use super::err::*;
+
+/// Depending on the target only one variant is ever used in a compilation.
+/// Anything else is an error. This invariant is checked at several locations
+#[derive(Copy, Clone, Debug, RustcEncodable, RustcDecodable, Hash, Eq, PartialEq)]
+pub enum ConstIsize {
+    Is32(i32),
+    Is64(i64),
+}
+pub use self::ConstIsize::*;
+
+impl ConstIsize {
+    pub fn as_i64(self, target_int_ty: ast::IntTy) -> i64 {
+        match (self, target_int_ty) {
+            (Is32(i), ast::IntTy::I32) => i as i64,
+            (Is64(i), ast::IntTy::I64) => i,
+            _ => panic!("got invalid isize size for target"),
+        }
+    }
+    pub fn new(i: i64, target_int_ty: ast::IntTy) -> Result<Self, ConstMathErr> {
+        match target_int_ty {
+            ast::IntTy::I32 if i as i32 as i64 == i => Ok(Is32(i as i32)),
+            ast::IntTy::I32 => Err(LitOutOfRange(ast::IntTy::Is)),
+            ast::IntTy::I64 => Ok(Is64(i)),
+            _ => unreachable!(),
+        }
+    }
+}
diff --git a/src/librustc_const_math/lib.rs b/src/librustc_const_math/lib.rs
new file mode 100644 (file)
index 0000000..9f66aac
--- /dev/null
@@ -0,0 +1,43 @@
+// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+//! Rusty Mathematics
+//!
+//! # Note
+//!
+//! This API is completely unstable and subject to change.
+
+#![crate_name = "rustc_const_math"]
+#![unstable(feature = "rustc_private", issue = "27812")]
+#![crate_type = "dylib"]
+#![crate_type = "rlib"]
+#![doc(html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
+      html_favicon_url = "https://doc.rust-lang.org/favicon.ico",
+      html_root_url = "https://doc.rust-lang.org/nightly/")]
+
+
+#![feature(rustc_private)]
+#![feature(staged_api)]
+#![feature(question_mark)]
+
+#[macro_use] extern crate log;
+#[macro_use] extern crate syntax;
+
+extern crate serialize as rustc_serialize; // used by deriving
+
+mod int;
+mod us;
+mod is;
+mod err;
+
+pub use int::*;
+pub use us::*;
+pub use is::*;
+pub use err::ConstMathErr;
diff --git a/src/librustc_const_math/us.rs b/src/librustc_const_math/us.rs
new file mode 100644 (file)
index 0000000..e5a7086
--- /dev/null
@@ -0,0 +1,39 @@
+// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use syntax::ast;
+use super::err::*;
+
+/// Depending on the target only one variant is ever used in a compilation.
+/// Anything else is an error. This invariant is checked at several locations
+#[derive(Copy, Clone, Debug, RustcEncodable, RustcDecodable, Hash, Eq, PartialEq)]
+pub enum ConstUsize {
+    Us32(u32),
+    Us64(u64),
+}
+pub use self::ConstUsize::*;
+
+impl ConstUsize {
+    pub fn as_u64(self, target_uint_ty: ast::UintTy) -> u64 {
+        match (self, target_uint_ty) {
+            (Us32(i), ast::UintTy::U32) => i as u64,
+            (Us64(i), ast::UintTy::U64) => i,
+            _ => panic!("got invalid usize size for target"),
+        }
+    }
+    pub fn new(i: u64, target_uint_ty: ast::UintTy) -> Result<Self, ConstMathErr> {
+        match target_uint_ty {
+            ast::UintTy::U32 if i as u32 as u64 == i => Ok(Us32(i as u32)),
+            ast::UintTy::U32 => Err(ULitOutOfRange(ast::UintTy::Us)),
+            ast::UintTy::U64 => Ok(Us64(i)),
+            _ => unreachable!(),
+        }
+    }
+}
index e8b5a7efdd96bf68af35bf2402c04e7abcbf47ff..65c2c2d1480a84de0819a55bc33de3ff98d0e372 100644 (file)
@@ -15,7 +15,7 @@ rbml = { path = "../librbml" }
 rustc = { path = "../librustc" }
 rustc_back = { path = "../librustc_back" }
 rustc_bitflags = { path = "../librustc_bitflags" }
-rustc_const_eval = { path = "../librustc_const_eval" }
+rustc_const_math = { path = "../librustc_const_math" }
 rustc_front = { path = "../librustc_front" }
 rustc_llvm = { path = "../librustc_llvm" }
 serialize = { path = "../libserialize" }
index e6f516ccd33bd3c8d15b315153a0dada47d59bfd..b9ebd3c3afabfc9775ba51a55fccd9122d7773a9 100644 (file)
@@ -36,7 +36,7 @@
 use rustc::ty::{ImplContainer, TraitContainer};
 use rustc::ty::{self, Ty, TyCtxt, TypeFoldable, VariantKind};
 
-use rustc_const_eval::ConstInt;
+use rustc_const_math::ConstInt;
 
 use rustc::mir;
 use rustc::mir::visit::MutVisitor;
index a6c612f5397b4227015d70520dff81799ca0a559..674106dd82ad8c6365b1717f41cef96c8ddc21f7 100644 (file)
@@ -37,7 +37,7 @@
 extern crate rustc_back;
 extern crate rustc_front;
 extern crate rustc_llvm;
-extern crate rustc_const_eval;
+extern crate rustc_const_math;
 
 pub use rustc::middle;
 
index 99237c9fa5f47bc1c4feb4ecb3c8cd20abe4229a..35c29e2cf2d2f44ffd9eb8867688a61aa199c276 100644 (file)
@@ -13,7 +13,7 @@ graphviz = { path = "../libgraphviz" }
 log = { path = "../liblog" }
 rustc = { path = "../librustc" }
 rustc_back = { path = "../librustc_back" }
-rustc_const_eval = { path = "../librustc_const_eval" }
+rustc_const_math = { path = "../librustc_const_math" }
 rustc_data_structures = { path = "../librustc_data_structures" }
 rustc_front = { path = "../librustc_front" }
 syntax = { path = "../libsyntax" }
index bac7b310dc701b3463aa1e87e5b9ccccf93e250f..ffaf02bbfee6ca936651442ec6f3a291decb357c 100644 (file)
@@ -95,7 +95,7 @@
 use syntax::codemap::{Span, DUMMY_SP};
 use syntax::parse::token::intern_and_get_ident;
 use rustc::middle::const_eval::ConstVal;
-use rustc_const_eval::ConstInt;
+use rustc_const_math::ConstInt;
 
 pub struct Scope<'tcx> {
     /// the scope-id within the scope_datas
index aa55ee3e3f72913ed73894a589ff5bd4fe6650a9..231acbfb4884ac350d80647bd136faf2a8e6effb 100644 (file)
@@ -10,7 +10,7 @@
 
 use hair::*;
 use rustc_data_structures::fnv::FnvHashMap;
-use rustc_const_eval::ConstInt;
+use rustc_const_math::ConstInt;
 use hair::cx::Cx;
 use hair::cx::block;
 use hair::cx::to_ref::ToRef;
index 30467a981d91444cbf18f40f8cb1d28ee4c4a6fd..9bd94e432bf17a4fded42198fbfd4514f1b73bfb 100644 (file)
@@ -26,7 +26,7 @@
 use syntax::codemap::Span;
 use syntax::parse::token;
 use rustc_front::hir;
-use rustc_const_eval::{ConstInt, ConstUsize};
+use rustc_const_math::{ConstInt, ConstUsize};
 
 #[derive(Copy, Clone)]
 pub struct Cx<'a, 'tcx: 'a> {
index 67bac196f4806a2c25d49177cc8dafa16a4affb8..3b55f62717c41825cd3d0b600b48ffa96927b72c 100644 (file)
@@ -32,7 +32,7 @@
 extern crate rustc_front;
 extern crate rustc_back;
 extern crate syntax;
-extern crate rustc_const_eval;
+extern crate rustc_const_math;
 
 pub mod build;
 pub mod graphviz;
index b7faafeba9aa1b9fd66a940f1af24a48a60a3bcb..e884442f03b017eba14521b13100df29f7023a44 100644 (file)
@@ -16,7 +16,7 @@ graphviz = { path = "../libgraphviz" }
 log = { path = "../liblog" }
 rustc = { path = "../librustc" }
 rustc_back = { path = "../librustc_back" }
-rustc_const_eval = { path = "../librustc_const_eval" }
+rustc_const_math = { path = "../librustc_const_math" }
 rustc_data_structures = { path = "../librustc_data_structures" }
 rustc_front = { path = "../librustc_front" }
 rustc_llvm = { path = "../librustc_llvm" }
index 8302fc0158c6af96ca31c230e65b337c3d660dc6..b2edcbd9b9e87b86d9c507314ecad5b2ee3eb13c 100644 (file)
@@ -38,7 +38,7 @@
 use rustc::ty::{self, Ty, TyCtxt};
 use rustc::ty::cast::{CastTy,IntTy};
 use util::nodemap::NodeMap;
-use rustc_const_eval::{ConstInt, ConstMathErr, ConstUsize, ConstIsize};
+use rustc_const_math::{ConstInt, ConstMathErr, ConstUsize, ConstIsize};
 
 use rustc_front::hir;
 
index 103de7e42af39ee93d4d2972b461199ef094cae5..c85008181a447da592bd13650f08b1a119a30e30 100644 (file)
@@ -51,7 +51,7 @@
 extern crate rustc_mir;
 extern crate rustc_platform_intrinsics as intrinsics;
 extern crate serialize;
-extern crate rustc_const_eval;
+extern crate rustc_const_math;
 
 #[macro_use] extern crate log;
 #[macro_use] extern crate syntax;
index be1c3f3b56b2cf6a4d85bbde0feb483ebe9d416f..cdb54eadbddcc7ea966af15cf17cba54fc85b6e5 100644 (file)
@@ -11,7 +11,7 @@
 use llvm::ValueRef;
 use rustc::ty::{Ty, TypeFoldable};
 use rustc::middle::const_eval::{self, ConstVal};
-use rustc_const_eval::ConstInt::*;
+use rustc_const_math::ConstInt::*;
 use rustc::mir::repr as mir;
 use abi;
 use common::{self, BlockAndBuilder, C_bool, C_bytes, C_floating_f64, C_integral,
index 47fa618ebad838df10c4a1f851cf94447914931b..b90be5e0ab626c902ff6bb12629dd29071e741f2 100644 (file)
@@ -12,7 +12,7 @@
 use rustc::ty::{self, Ty};
 use rustc::ty::cast::{CastTy, IntTy};
 use middle::const_eval::ConstVal;
-use rustc_const_eval::ConstInt;
+use rustc_const_math::ConstInt;
 use rustc::mir::repr as mir;
 
 use asm;
index 1c907972863b6422878adaad1759ea8aaac0d195..6e1bca87a821a9f5c1a8fd45824d2f6b6d2dbab9 100644 (file)
@@ -15,6 +15,6 @@ arena = { path = "../libarena" }
 fmt_macros = { path = "../libfmt_macros" }
 rustc = { path = "../librustc" }
 rustc_back = { path = "../librustc_back" }
-rustc_const_eval = { path = "../librustc_const_eval" }
+rustc_const_math = { path = "../librustc_const_math" }
 rustc_front = { path = "../librustc_front" }
 rustc_platform_intrinsics = { path = "../librustc_platform_intrinsics" }
index af40b845767d8d55c1a0cf2053cd2a953f5a4185..bd2e0092a89ba5e97dfe6d17c107f5c35554d8af 100644 (file)
@@ -65,7 +65,7 @@
 use util::common::{ErrorReported, FN_OUTPUT_NAME};
 use util::nodemap::FnvHashSet;
 
-use rustc_const_eval::ConstInt;
+use rustc_const_math::ConstInt;
 
 use syntax::{abi, ast};
 use syntax::codemap::{Span, Pos};
index 0b447b2009b5875746d650c0823419692b20c90e..743a2bb22113918bf6f1127b9de68cf5f1251e79 100644 (file)
@@ -81,7 +81,7 @@
 use util::nodemap::{FnvHashMap, FnvHashSet};
 use write_ty_to_tcx;
 
-use rustc_const_eval::ConstInt;
+use rustc_const_math::ConstInt;
 
 use std::cell::RefCell;
 use std::collections::HashSet;
index 9b0fdd8a2e327e16b53226a01ddfc57b4f7b185b..9c08f57b8331e8d38eb5de0ca9fdb24887afc456 100644 (file)
@@ -92,7 +92,7 @@
 extern crate rustc_platform_intrinsics as intrinsics;
 extern crate rustc_front;
 extern crate rustc_back;
-extern crate rustc_const_eval;
+extern crate rustc_const_math;
 
 pub use rustc::dep_graph;
 pub use rustc::front;
index 3e1b46522a98dc4537d21331a8bba69552c804ee..edf1c2c3a398e9a675bbf0a5aacc5eb2da521218 100644 (file)
@@ -16,7 +16,7 @@
 #[macro_use] extern crate rustc;
 extern crate rustc_front;
 extern crate rustc_plugin;
-extern crate rustc_const_eval;
+extern crate rustc_const_math;
 extern crate syntax;
 
 use rustc::mir::transform::{self, MirPass};
@@ -24,7 +24,7 @@
 use rustc::mir::visit::MutVisitor;
 use rustc::ty;
 use rustc::middle::const_eval::ConstVal;
-use rustc_const_eval::ConstInt;
+use rustc_const_math::ConstInt;
 use rustc_plugin::Registry;
 
 use syntax::ast::NodeId;