From 441b9940ecc2056f04065f8d08ae7cde8bdae684 Mon Sep 17 00:00:00 2001 From: Oliver Schneider Date: Mon, 13 Jul 2015 10:53:16 +0200 Subject: [PATCH] simplify processing of ConstVal objects when not all variants are legal --- src/librustc/middle/const_eval.rs | 52 ++++++++++++--------------- src/librustc/middle/ty.rs | 8 +---- src/test/compile-fail/repeat_count.rs | 45 ++++++++++++++--------- 3 files changed, 51 insertions(+), 54 deletions(-) diff --git a/src/librustc/middle/const_eval.rs b/src/librustc/middle/const_eval.rs index 7d54b8c284f1f..cf71c53e4032b 100644 --- a/src/librustc/middle/const_eval.rs +++ b/src/librustc/middle/const_eval.rs @@ -273,6 +273,22 @@ pub enum ConstVal { Tuple(ast::NodeId), } +impl ConstVal { + pub fn description(&self) -> &'static str { + match *self { + Float(_) => "float", + Int(i) if i < 0 => "negative integer", + Int(_) => "positive integer", + Uint(_) => "unsigned integer", + Str(_) => "string literal", + Binary(_) => "binary array", + Bool(_) => "boolean", + Struct(_) => "struct", + Tuple(_) => "tuple", + } + } +} + pub fn const_expr_to_pat(tcx: &ty::ctxt, expr: &Expr, span: Span) -> P { let pat = match expr.node { ast::ExprTup(ref exprs) => @@ -352,16 +368,8 @@ pub enum ErrKind { InvalidOpForFloats(ast::BinOp_), InvalidOpForIntUint(ast::BinOp_), InvalidOpForUintInt(ast::BinOp_), - NegateOnString, - NegateOnBoolean, - NegateOnBinary, - NegateOnStruct, - NegateOnTuple, - NotOnFloat, - NotOnString, - NotOnBinary, - NotOnStruct, - NotOnTuple, + NegateOn(ConstVal), + NotOn(ConstVal), NegateWithOverflow(i64), AddiWithOverflow(i64, i64), @@ -397,16 +405,8 @@ impl ConstEvalErr { InvalidOpForFloats(_) => "can't do this op on floats".into_cow(), InvalidOpForIntUint(..) => "can't do this op on an isize and usize".into_cow(), InvalidOpForUintInt(..) => "can't do this op on a usize and isize".into_cow(), - NegateOnString => "negate on string".into_cow(), - NegateOnBoolean => "negate on boolean".into_cow(), - NegateOnBinary => "negate on binary literal".into_cow(), - NegateOnStruct => "negate on struct".into_cow(), - NegateOnTuple => "negate on tuple".into_cow(), - NotOnFloat => "not on float or string".into_cow(), - NotOnString => "not on float or string".into_cow(), - NotOnBinary => "not on binary literal".into_cow(), - NotOnStruct => "not on struct".into_cow(), - NotOnTuple => "not on tuple".into_cow(), + NegateOn(ref const_val) => format!("negate on {}", const_val.description()).into_cow(), + NotOn(ref const_val) => format!("not on {}", const_val.description()).into_cow(), NegateWithOverflow(..) => "attempted to negate with overflow".into_cow(), AddiWithOverflow(..) => "attempted to add with overflow".into_cow(), @@ -754,11 +754,7 @@ pub fn eval_const_expr_with_substs<'tcx, S>(tcx: &ty::ctxt<'tcx>, } try!(const_uint_checked_neg(i, e, expr_uint_type)) } - Str(_) => signal!(e, NegateOnString), - Bool(_) => signal!(e, NegateOnBoolean), - Binary(_) => signal!(e, NegateOnBinary), - Tuple(_) => signal!(e, NegateOnTuple), - Struct(..) => signal!(e, NegateOnStruct), + const_val => signal!(e, NegateOn(const_val)), } } ast::ExprUnary(ast::UnNot, ref inner) => { @@ -766,11 +762,7 @@ pub fn eval_const_expr_with_substs<'tcx, S>(tcx: &ty::ctxt<'tcx>, Int(i) => Int(!i), Uint(i) => const_uint_not(i, expr_uint_type), Bool(b) => Bool(!b), - Str(_) => signal!(e, NotOnString), - Float(_) => signal!(e, NotOnFloat), - Binary(_) => signal!(e, NotOnBinary), - Tuple(_) => signal!(e, NotOnTuple), - Struct(..) => signal!(e, NotOnStruct), + const_val => signal!(e, NotOn(const_val)), } } ast::ExprBinary(op, ref a, ref b) => { diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs index b4b8fbf2064ad..705e11f0597f1 100644 --- a/src/librustc/middle/ty.rs +++ b/src/librustc/middle/ty.rs @@ -6100,13 +6100,7 @@ impl<'tcx> ctxt<'tcx> { let found = match val { ConstVal::Uint(count) => return count as usize, ConstVal::Int(count) if count >= 0 => return count as usize, - ConstVal::Int(_) => "negative integer", - ConstVal::Float(_) => "float", - ConstVal::Str(_) => "string", - ConstVal::Bool(_) => "boolean", - ConstVal::Binary(_) => "binary array", - ConstVal::Struct(..) => "struct", - ConstVal::Tuple(_) => "tuple" + const_val => const_val.description(), }; span_err!(self.sess, count_expr.span, E0306, "expected positive integer for repeat count, found {}", diff --git a/src/test/compile-fail/repeat_count.rs b/src/test/compile-fail/repeat_count.rs index 121581412202c..7a0623ba44f02 100644 --- a/src/test/compile-fail/repeat_count.rs +++ b/src/test/compile-fail/repeat_count.rs @@ -12,47 +12,58 @@ fn main() { let n = 1; - let a = [0; n]; //~ ERROR expected constant integer for repeat count, found variable + let a = [0; n]; + //~^ ERROR expected constant integer for repeat count, found variable [E0307] let b = [0; ()]; -//~^ ERROR mismatched types -//~| expected `usize` -//~| found `()` -//~| expected usize -//~| found () -//~| ERROR expected positive integer for repeat count, found tuple + //~^ ERROR mismatched types + //~| expected `usize` + //~| found `()` + //~| expected usize + //~| found ()) [E0308] + //~| ERROR expected positive integer for repeat count, found tuple [E0306] let c = [0; true]; //~^ ERROR mismatched types //~| expected `usize` //~| found `bool` //~| expected usize - //~| found bool - //~| ERROR expected positive integer for repeat count, found boolean + //~| found bool) [E0308] + //~| ERROR expected positive integer for repeat count, found boolean [E0306] let d = [0; 0.5]; //~^ ERROR mismatched types //~| expected `usize` //~| found `_` //~| expected usize - //~| found floating-point variable - //~| ERROR expected positive integer for repeat count, found float + //~| found floating-point variable) [E0308] + //~| ERROR expected positive integer for repeat count, found float [E0306] let e = [0; "foo"]; //~^ ERROR mismatched types //~| expected `usize` //~| found `&'static str` //~| expected usize - //~| found &-ptr - //~| ERROR expected positive integer for repeat count, found string + //~| found &-ptr) [E0308] + //~| ERROR expected positive integer for repeat count, found string literal [E0306] let f = [0; -4_isize]; //~^ ERROR mismatched types //~| expected `usize` //~| found `isize` //~| expected usize - //~| found isize - //~| ERROR expected positive integer for repeat count, found negative integer + //~| found isize) [E0308] + //~| ERROR expected positive integer for repeat count, found negative integer [E0306] let f = [0_usize; -1_isize]; //~^ ERROR mismatched types //~| expected `usize` //~| found `isize` //~| expected usize - //~| found isize - //~| ERROR expected positive integer for repeat count, found negative integer + //~| found isize) [E0308] + //~| ERROR expected positive integer for repeat count, found negative integer [E0306] + struct G { + g: (), + } + let g = [0; G { g: () }]; + //~^ ERROR mismatched types + //~| expected `usize` + //~| found `main::G` + //~| expected usize + //~| found struct `main::G`) [E0308] + //~| ERROR expected positive integer for repeat count, found struct [E0306] }