From b8f9c88c2d86135f4d1c170be67d9d15c63b358a Mon Sep 17 00:00:00 2001 From: Oliver Schneider Date: Mon, 27 Jun 2016 11:42:52 +0200 Subject: [PATCH] Revert "skip double negation in const eval" This reverts commit 735c018974e5570ea13fd887aa70a011a5b8e7b8. --- src/librustc_const_eval/eval.rs | 89 +++++++++----------- src/test/compile-fail/lint-type-overflow2.rs | 1 + 2 files changed, 42 insertions(+), 48 deletions(-) diff --git a/src/librustc_const_eval/eval.rs b/src/librustc_const_eval/eval.rs index 34dce44004823..4018260263c2c 100644 --- a/src/librustc_const_eval/eval.rs +++ b/src/librustc_const_eval/eval.rs @@ -543,54 +543,47 @@ pub fn eval_const_expr_partial<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, let result = match e.node { hir::ExprUnary(hir::UnNeg, ref inner) => { // unary neg literals already got their sign during creation - match inner.node { - hir::ExprLit(ref lit) => { - use syntax::ast::*; - use syntax::ast::LitIntType::*; - const I8_OVERFLOW: u64 = ::std::i8::MAX as u64 + 1; - const I16_OVERFLOW: u64 = ::std::i16::MAX as u64 + 1; - const I32_OVERFLOW: u64 = ::std::i32::MAX as u64 + 1; - const I64_OVERFLOW: u64 = ::std::i64::MAX as u64 + 1; - match (&lit.node, ety.map(|t| &t.sty)) { - (&LitKind::Int(I8_OVERFLOW, Unsuffixed), Some(&ty::TyInt(IntTy::I8))) | - (&LitKind::Int(I8_OVERFLOW, Signed(IntTy::I8)), _) => { - return Ok(Integral(I8(::std::i8::MIN))) - }, - (&LitKind::Int(I16_OVERFLOW, Unsuffixed), Some(&ty::TyInt(IntTy::I16))) | - (&LitKind::Int(I16_OVERFLOW, Signed(IntTy::I16)), _) => { - return Ok(Integral(I16(::std::i16::MIN))) - }, - (&LitKind::Int(I32_OVERFLOW, Unsuffixed), Some(&ty::TyInt(IntTy::I32))) | - (&LitKind::Int(I32_OVERFLOW, Signed(IntTy::I32)), _) => { - return Ok(Integral(I32(::std::i32::MIN))) - }, - (&LitKind::Int(I64_OVERFLOW, Unsuffixed), Some(&ty::TyInt(IntTy::I64))) | - (&LitKind::Int(I64_OVERFLOW, Signed(IntTy::I64)), _) => { - return Ok(Integral(I64(::std::i64::MIN))) - }, - (&LitKind::Int(n, Unsuffixed), Some(&ty::TyInt(IntTy::Is))) | - (&LitKind::Int(n, Signed(IntTy::Is)), _) => { - match tcx.sess.target.int_type { - IntTy::I16 => if n == I16_OVERFLOW { - return Ok(Integral(Isize(Is16(::std::i16::MIN)))); - }, - IntTy::I32 => if n == I32_OVERFLOW { - return Ok(Integral(Isize(Is32(::std::i32::MIN)))); - }, - IntTy::I64 => if n == I64_OVERFLOW { - return Ok(Integral(Isize(Is64(::std::i64::MIN)))); - }, - _ => bug!(), - } - }, - _ => {}, - } - }, - hir::ExprUnary(hir::UnNeg, ref inner) => { - // skip `--$expr` - return eval_const_expr_partial(tcx, inner, ty_hint, fn_args); - }, - _ => {}, + if let hir::ExprLit(ref lit) = inner.node { + use syntax::ast::*; + use syntax::ast::LitIntType::*; + const I8_OVERFLOW: u64 = ::std::i8::MAX as u64 + 1; + const I16_OVERFLOW: u64 = ::std::i16::MAX as u64 + 1; + const I32_OVERFLOW: u64 = ::std::i32::MAX as u64 + 1; + const I64_OVERFLOW: u64 = ::std::i64::MAX as u64 + 1; + match (&lit.node, ety.map(|t| &t.sty)) { + (&LitKind::Int(I8_OVERFLOW, Unsuffixed), Some(&ty::TyInt(IntTy::I8))) | + (&LitKind::Int(I8_OVERFLOW, Signed(IntTy::I8)), _) => { + return Ok(Integral(I8(::std::i8::MIN))) + }, + (&LitKind::Int(I16_OVERFLOW, Unsuffixed), Some(&ty::TyInt(IntTy::I16))) | + (&LitKind::Int(I16_OVERFLOW, Signed(IntTy::I16)), _) => { + return Ok(Integral(I16(::std::i16::MIN))) + }, + (&LitKind::Int(I32_OVERFLOW, Unsuffixed), Some(&ty::TyInt(IntTy::I32))) | + (&LitKind::Int(I32_OVERFLOW, Signed(IntTy::I32)), _) => { + return Ok(Integral(I32(::std::i32::MIN))) + }, + (&LitKind::Int(I64_OVERFLOW, Unsuffixed), Some(&ty::TyInt(IntTy::I64))) | + (&LitKind::Int(I64_OVERFLOW, Signed(IntTy::I64)), _) => { + return Ok(Integral(I64(::std::i64::MIN))) + }, + (&LitKind::Int(n, Unsuffixed), Some(&ty::TyInt(IntTy::Is))) | + (&LitKind::Int(n, Signed(IntTy::Is)), _) => { + match tcx.sess.target.int_type { + IntTy::I16 => if n == I16_OVERFLOW { + return Ok(Integral(Isize(Is16(::std::i16::MIN)))); + }, + IntTy::I32 => if n == I32_OVERFLOW { + return Ok(Integral(Isize(Is32(::std::i32::MIN)))); + }, + IntTy::I64 => if n == I64_OVERFLOW { + return Ok(Integral(Isize(Is64(::std::i64::MIN)))); + }, + _ => bug!(), + } + }, + _ => {}, + } } match eval_const_expr_partial(tcx, &inner, ty_hint, fn_args)? { Float(f) => Float(-f), diff --git a/src/test/compile-fail/lint-type-overflow2.rs b/src/test/compile-fail/lint-type-overflow2.rs index 9499d732a3835..e99dfb9aa0f0e 100644 --- a/src/test/compile-fail/lint-type-overflow2.rs +++ b/src/test/compile-fail/lint-type-overflow2.rs @@ -15,6 +15,7 @@ #[allow(unused_variables)] fn main() { let x2: i8 = --128; //~ error: literal out of range for i8 + //~^ error: attempted to negate with overflow let x = -3.40282348e+38_f32; //~ error: literal out of range for f32 let x = 3.40282348e+38_f32; //~ error: literal out of range for f32