Skip to content

Commit

Permalink
simplify processing of ConstVal objects when not all variants are legal
Browse files Browse the repository at this point in the history
  • Loading branch information
Oliver Schneider committed Jul 13, 2015
1 parent 67256df commit 441b994
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 54 deletions.
52 changes: 22 additions & 30 deletions src/librustc/middle/const_eval.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<ast::Pat> {
let pat = match expr.node {
ast::ExprTup(ref exprs) =>
Expand Down Expand Up @@ -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),
Expand Down Expand Up @@ -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(),
Expand Down Expand Up @@ -754,23 +754,15 @@ 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) => {
match try!(eval_const_expr_partial(tcx, &**inner, ety)) {
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) => {
Expand Down
8 changes: 1 addition & 7 deletions src/librustc/middle/ty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {}",
Expand Down
45 changes: 28 additions & 17 deletions src/test/compile-fail/repeat_count.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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]
}

0 comments on commit 441b994

Please sign in to comment.