Incorporated first review sugestion from eddyb.
Suggestion was here: https://github.com/rust-lang/rust/pull/22532#discussion_r25505609
This commit is contained in:
parent
b85b3c9b2b
commit
11057fee08
@ -283,106 +283,40 @@ impl ConstEvalErr {
|
||||
}
|
||||
}
|
||||
|
||||
fn invalid_op_for_bools(e: &Expr, op: ast::BinOp_) -> ConstEvalErr {
|
||||
ConstEvalErr { span: e.span, kind: ErrKind::InvalidOpForBools(op) }
|
||||
}
|
||||
fn invalid_op_for_floats(e: &Expr, op: ast::BinOp_) -> ConstEvalErr {
|
||||
ConstEvalErr { span: e.span, kind: ErrKind::InvalidOpForFloats(op) }
|
||||
}
|
||||
fn invalid_op_for_int_uint(e: &Expr, op: ast::BinOp_) -> ConstEvalErr {
|
||||
ConstEvalErr { span: e.span, kind: ErrKind::InvalidOpForIntUint(op) }
|
||||
}
|
||||
fn invalid_op_for_uint_int(e: &Expr, op: ast::BinOp_) -> ConstEvalErr {
|
||||
ConstEvalErr { span: e.span, kind: ErrKind::InvalidOpForUintInt(op) }
|
||||
}
|
||||
fn negate_on_string(e: &Expr) -> ConstEvalErr {
|
||||
ConstEvalErr { span: e.span, kind: ErrKind::NegateOnString }
|
||||
}
|
||||
fn negate_on_boolean(e: &Expr) -> ConstEvalErr {
|
||||
ConstEvalErr { span: e.span, kind: ErrKind::NegateOnBoolean }
|
||||
}
|
||||
fn not_on_float(e: &Expr) -> ConstEvalErr {
|
||||
ConstEvalErr { span: e.span, kind: ErrKind::NotOnFloat }
|
||||
}
|
||||
fn not_on_string(e: &Expr) -> ConstEvalErr {
|
||||
ConstEvalErr { span: e.span, kind: ErrKind::NotOnString }
|
||||
}
|
||||
macro_rules! signal {
|
||||
($e:expr, $ctor:ident) => {
|
||||
return Err(ConstEvalErr { span: $e.span, kind: ErrKind::$ctor })
|
||||
};
|
||||
|
||||
fn addi_with_overflow(e: &Expr, a: i64, b: i64) -> ConstEvalErr {
|
||||
ConstEvalErr { span: e.span, kind: ErrKind::AddiWithOverflow(a, b) }
|
||||
($e:expr, $ctor:ident($($arg:expr),*)) => {
|
||||
return Err(ConstEvalErr { span: $e.span, kind: ErrKind::$ctor($($arg),*) })
|
||||
}
|
||||
}
|
||||
fn subi_with_overflow(e: &Expr, a: i64, b: i64) -> ConstEvalErr {
|
||||
ConstEvalErr { span: e.span, kind: ErrKind::SubiWithOverflow(a, b) }
|
||||
}
|
||||
fn muli_with_overflow(e: &Expr, a: i64, b: i64) -> ConstEvalErr {
|
||||
ConstEvalErr { span: e.span, kind: ErrKind::MuliWithOverflow(a, b) }
|
||||
}
|
||||
fn addu_with_overflow(e: &Expr, a: u64, b: u64) -> ConstEvalErr {
|
||||
ConstEvalErr { span: e.span, kind: ErrKind::AdduWithOverflow(a, b) }
|
||||
}
|
||||
fn subu_with_overflow(e: &Expr, a: u64, b: u64) -> ConstEvalErr {
|
||||
ConstEvalErr { span: e.span, kind: ErrKind::SubuWithOverflow(a, b) }
|
||||
}
|
||||
fn mulu_with_overflow(e: &Expr, a: u64, b: u64) -> ConstEvalErr {
|
||||
ConstEvalErr { span: e.span, kind: ErrKind::MuluWithOverflow(a, b) }
|
||||
}
|
||||
fn divide_by_zero(e: &Expr) -> ConstEvalErr {
|
||||
ConstEvalErr { span: e.span, kind: ErrKind::DivideByZero }
|
||||
}
|
||||
fn divide_with_overflow(e: &Expr) -> ConstEvalErr {
|
||||
ConstEvalErr { span: e.span, kind: ErrKind::DivideWithOverflow }
|
||||
}
|
||||
fn modulo_by_zero(e: &Expr) -> ConstEvalErr {
|
||||
ConstEvalErr { span: e.span, kind: ErrKind::ModuloByZero }
|
||||
}
|
||||
fn modulo_with_overflow(e: &Expr) -> ConstEvalErr {
|
||||
ConstEvalErr { span: e.span, kind: ErrKind::ModuloWithOverflow }
|
||||
}
|
||||
fn missing_struct_field(e: &Expr) -> ConstEvalErr {
|
||||
ConstEvalErr { span: e.span, kind: ErrKind::MissingStructField }
|
||||
}
|
||||
fn non_const_path(e: &Expr) -> ConstEvalErr {
|
||||
ConstEvalErr { span: e.span, kind: ErrKind::NonConstPath }
|
||||
}
|
||||
fn non_const_struct(e: &Expr) -> ConstEvalErr {
|
||||
ConstEvalErr { span: e.span, kind: ErrKind::NonConstStruct }
|
||||
}
|
||||
fn tuple_index_out_of_bounds(e: &Expr) -> ConstEvalErr {
|
||||
ConstEvalErr { span: e.span, kind: ErrKind::TupleIndexOutOfBounds }
|
||||
}
|
||||
|
||||
fn misc_binary_op(e: &Expr) -> ConstEvalErr {
|
||||
ConstEvalErr { span: e.span, kind: ErrKind::MiscBinaryOp }
|
||||
}
|
||||
fn misc_catch_all(e: &Expr) -> ConstEvalErr {
|
||||
ConstEvalErr { span: e.span, kind: ErrKind::MiscCatchAll }
|
||||
}
|
||||
|
||||
|
||||
fn checked_add_int(e: &Expr, a: i64, b: i64) -> Result<const_val, ConstEvalErr> {
|
||||
let (ret, oflo) = a.overflowing_add(b);
|
||||
if !oflo { Ok(const_int(ret)) } else { Err(addi_with_overflow(e, a, b)) }
|
||||
if !oflo { Ok(const_int(ret)) } else { signal!(e, AddiWithOverflow(a, b)) }
|
||||
}
|
||||
fn checked_sub_int(e: &Expr, a: i64, b: i64) -> Result<const_val, ConstEvalErr> {
|
||||
let (ret, oflo) = a.overflowing_sub(b);
|
||||
if !oflo { Ok(const_int(ret)) } else { Err(subi_with_overflow(e, a, b)) }
|
||||
if !oflo { Ok(const_int(ret)) } else { signal!(e, SubiWithOverflow(a, b)) }
|
||||
}
|
||||
fn checked_mul_int(e: &Expr, a: i64, b: i64) -> Result<const_val, ConstEvalErr> {
|
||||
let (ret, oflo) = a.overflowing_mul(b);
|
||||
if !oflo { Ok(const_int(ret)) } else { Err(muli_with_overflow(e, a, b)) }
|
||||
if !oflo { Ok(const_int(ret)) } else { signal!(e, MuliWithOverflow(a, b)) }
|
||||
}
|
||||
|
||||
fn checked_add_uint(e: &Expr, a: u64, b: u64) -> Result<const_val, ConstEvalErr> {
|
||||
let (ret, oflo) = a.overflowing_add(b);
|
||||
if !oflo { Ok(const_uint(ret)) } else { Err(addu_with_overflow(e, a, b)) }
|
||||
if !oflo { Ok(const_uint(ret)) } else { signal!(e, AdduWithOverflow(a, b)) }
|
||||
}
|
||||
fn checked_sub_uint(e: &Expr, a: u64, b: u64) -> Result<const_val, ConstEvalErr> {
|
||||
let (ret, oflo) = a.overflowing_sub(b);
|
||||
if !oflo { Ok(const_uint(ret)) } else { Err(subu_with_overflow(e, a, b)) }
|
||||
if !oflo { Ok(const_uint(ret)) } else { signal!(e, SubuWithOverflow(a, b)) }
|
||||
}
|
||||
fn checked_mul_uint(e: &Expr, a: u64, b: u64) -> Result<const_val, ConstEvalErr> {
|
||||
let (ret, oflo) = a.overflowing_mul(b);
|
||||
if !oflo { Ok(const_uint(ret)) } else { Err(mulu_with_overflow(e, a, b)) }
|
||||
if !oflo { Ok(const_uint(ret)) } else { signal!(e, MuluWithOverflow(a, b)) }
|
||||
}
|
||||
|
||||
|
||||
@ -400,8 +334,8 @@ pub fn eval_const_expr_partial<'tcx>(tcx: &ty::ctxt<'tcx>,
|
||||
Ok(const_float(f)) => Ok(const_float(-f)),
|
||||
Ok(const_int(i)) => Ok(const_int(-i)),
|
||||
Ok(const_uint(i)) => Ok(const_uint(-i)),
|
||||
Ok(const_str(_)) => Err(negate_on_string(e)),
|
||||
Ok(const_bool(_)) => Err(negate_on_boolean(e)),
|
||||
Ok(const_str(_)) => signal!(e, NegateOnString),
|
||||
Ok(const_bool(_)) => signal!(e, NegateOnBoolean),
|
||||
err => err
|
||||
}
|
||||
}
|
||||
@ -410,8 +344,8 @@ pub fn eval_const_expr_partial<'tcx>(tcx: &ty::ctxt<'tcx>,
|
||||
Ok(const_int(i)) => Ok(const_int(!i)),
|
||||
Ok(const_uint(i)) => Ok(const_uint(!i)),
|
||||
Ok(const_bool(b)) => Ok(const_bool(!b)),
|
||||
Ok(const_str(_)) => Err(not_on_string(e)),
|
||||
Ok(const_float(_)) => Err(not_on_float(e)),
|
||||
Ok(const_str(_)) => signal!(e, NotOnString),
|
||||
Ok(const_float(_)) => signal!(e, NotOnFloat),
|
||||
err => err
|
||||
}
|
||||
}
|
||||
@ -435,7 +369,7 @@ pub fn eval_const_expr_partial<'tcx>(tcx: &ty::ctxt<'tcx>,
|
||||
ast::BiNe => fromb(a != b),
|
||||
ast::BiGe => fromb(a >= b),
|
||||
ast::BiGt => fromb(a > b),
|
||||
_ => Err(invalid_op_for_floats(e, op.node)),
|
||||
_ => signal!(e, InvalidOpForFloats(op.node))
|
||||
}
|
||||
}
|
||||
(Ok(const_int(a)), Ok(const_int(b))) => {
|
||||
@ -463,18 +397,18 @@ pub fn eval_const_expr_partial<'tcx>(tcx: &ty::ctxt<'tcx>,
|
||||
ast::BiMul => checked_mul_int(e, a, b),
|
||||
ast::BiDiv => {
|
||||
if b == 0 {
|
||||
Err(divide_by_zero(e))
|
||||
signal!(e, DivideByZero);
|
||||
} else if b == -1 && is_a_min_value() {
|
||||
Err(divide_with_overflow(e))
|
||||
signal!(e, DivideWithOverflow);
|
||||
} else {
|
||||
Ok(const_int(a / b))
|
||||
}
|
||||
}
|
||||
ast::BiRem => {
|
||||
if b == 0 {
|
||||
Err(modulo_by_zero(e))
|
||||
signal!(e, ModuloByZero)
|
||||
} else if b == -1 && is_a_min_value() {
|
||||
Err(modulo_with_overflow(e))
|
||||
signal!(e, ModuloWithOverflow)
|
||||
} else {
|
||||
Ok(const_int(a % b))
|
||||
}
|
||||
@ -497,9 +431,9 @@ pub fn eval_const_expr_partial<'tcx>(tcx: &ty::ctxt<'tcx>,
|
||||
ast::BiAdd => checked_add_uint(e, a, b),
|
||||
ast::BiSub => checked_sub_uint(e, a, b),
|
||||
ast::BiMul => checked_mul_uint(e, a, b),
|
||||
ast::BiDiv if b == 0 => Err(divide_by_zero(e)),
|
||||
ast::BiDiv if b == 0 => signal!(e, DivideByZero),
|
||||
ast::BiDiv => Ok(const_uint(a / b)),
|
||||
ast::BiRem if b == 0 => Err(modulo_by_zero(e)),
|
||||
ast::BiRem if b == 0 => signal!(e, ModuloByZero),
|
||||
ast::BiRem => Ok(const_uint(a % b)),
|
||||
ast::BiAnd | ast::BiBitAnd => Ok(const_uint(a & b)),
|
||||
ast::BiOr | ast::BiBitOr => Ok(const_uint(a | b)),
|
||||
@ -519,14 +453,14 @@ pub fn eval_const_expr_partial<'tcx>(tcx: &ty::ctxt<'tcx>,
|
||||
match op.node {
|
||||
ast::BiShl => Ok(const_int(a << b as uint)),
|
||||
ast::BiShr => Ok(const_int(a >> b as uint)),
|
||||
_ => Err(invalid_op_for_int_uint(e, op.node)),
|
||||
_ => signal!(e, InvalidOpForIntUint(op.node)),
|
||||
}
|
||||
}
|
||||
(Ok(const_uint(a)), Ok(const_int(b))) => {
|
||||
match op.node {
|
||||
ast::BiShl => Ok(const_uint(a << b as uint)),
|
||||
ast::BiShr => Ok(const_uint(a >> b as uint)),
|
||||
_ => Err(invalid_op_for_uint_int(e, op.node)),
|
||||
_ => signal!(e, InvalidOpForUintInt(op.node)),
|
||||
}
|
||||
}
|
||||
(Ok(const_bool(a)), Ok(const_bool(b))) => {
|
||||
@ -538,13 +472,13 @@ pub fn eval_const_expr_partial<'tcx>(tcx: &ty::ctxt<'tcx>,
|
||||
ast::BiBitOr => a | b,
|
||||
ast::BiEq => a == b,
|
||||
ast::BiNe => a != b,
|
||||
_ => return Err(invalid_op_for_bools(e, op.node)),
|
||||
_ => signal!(e, InvalidOpForBools(op.node)),
|
||||
}))
|
||||
}
|
||||
(err @ Err(..), _) |
|
||||
(_, err @ Err(..)) => err,
|
||||
|
||||
_ => Err(misc_binary_op(e)),
|
||||
_ => signal!(e, MiscBinaryOp),
|
||||
}
|
||||
}
|
||||
ast::ExprCast(ref base, ref target_ty) => {
|
||||
@ -589,7 +523,7 @@ pub fn eval_const_expr_partial<'tcx>(tcx: &ty::ctxt<'tcx>,
|
||||
};
|
||||
let const_expr = match const_expr {
|
||||
Some(actual_e) => actual_e,
|
||||
None => return Err(non_const_path(e)),
|
||||
None => signal!(e, NonConstPath)
|
||||
};
|
||||
let ety = ety.or_else(|| const_ty.and_then(|ty| ast_ty_to_prim_ty(tcx, ty)));
|
||||
eval_const_expr_partial(tcx, const_expr, ety)
|
||||
@ -611,11 +545,11 @@ pub fn eval_const_expr_partial<'tcx>(tcx: &ty::ctxt<'tcx>,
|
||||
if fields.len() > index.node {
|
||||
return eval_const_expr_partial(tcx, &*fields[index.node], None)
|
||||
} else {
|
||||
return Err(tuple_index_out_of_bounds(e))
|
||||
signal!(e, TupleIndexOutOfBounds);
|
||||
}
|
||||
}
|
||||
|
||||
Err(non_const_struct(e))
|
||||
signal!(e, NonConstStruct);
|
||||
}
|
||||
ast::ExprField(ref base, field_name) => {
|
||||
// Get the base expression if it is a struct and it is constant
|
||||
@ -626,13 +560,13 @@ pub fn eval_const_expr_partial<'tcx>(tcx: &ty::ctxt<'tcx>,
|
||||
f.ident.node.as_str() == field_name.node.as_str()) {
|
||||
return eval_const_expr_partial(tcx, &*f.expr, None)
|
||||
} else {
|
||||
return Err(missing_struct_field(e));
|
||||
signal!(e, MissingStructField);
|
||||
}
|
||||
}
|
||||
|
||||
Err(non_const_struct(e))
|
||||
signal!(e, NonConstStruct);
|
||||
}
|
||||
_ => Err(misc_catch_all(e))
|
||||
_ => signal!(e, MiscCatchAll)
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user