Skip to content

Commit 4e23179

Browse files
committed
Incorporated second review suggestion from eddyb.
1 parent 11057fe commit 4e23179

File tree

1 file changed

+71
-67
lines changed

1 file changed

+71
-67
lines changed

src/librustc/middle/const_eval.rs

Lines changed: 71 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -225,8 +225,10 @@ pub enum ErrKind {
225225
InvalidOpForUintInt(ast::BinOp_),
226226
NegateOnString,
227227
NegateOnBoolean,
228+
NegateOnBinary,
228229
NotOnFloat,
229230
NotOnString,
231+
NotOnBinary,
230232

231233
AddiWithOverflow(i64, i64),
232234
SubiWithOverflow(i64, i64),
@@ -259,8 +261,10 @@ impl ConstEvalErr {
259261
InvalidOpForUintInt(..) => "can't do this op on a uint and int".into_cow(),
260262
NegateOnString => "negate on string".into_cow(),
261263
NegateOnBoolean => "negate on boolean".into_cow(),
264+
NegateOnBinary => "negate on binary literal".into_cow(),
262265
NotOnFloat => "not on float or string".into_cow(),
263266
NotOnString => "not on float or string".into_cow(),
267+
NotOnBinary => "not on binary literal".into_cow(),
264268

265269
AddiWithOverflow(..) => "attempted to add with overflow".into_cow(),
266270
SubiWithOverflow(..) => "attempted to sub with overflow".into_cow(),
@@ -324,45 +328,45 @@ pub fn eval_const_expr_partial<'tcx>(tcx: &ty::ctxt<'tcx>,
324328
e: &Expr,
325329
ty_hint: Option<Ty<'tcx>>)
326330
-> Result<const_val, ConstEvalErr> {
327-
fn fromb<T>(b: bool) -> Result<const_val, T> { Ok(const_int(b as i64)) }
331+
fn fromb(b: bool) -> const_val { const_int(b as i64) }
328332

329333
let ety = ty_hint.or_else(|| ty::expr_ty_opt(tcx, e));
330334

331-
match e.node {
335+
let result = match e.node {
332336
ast::ExprUnary(ast::UnNeg, ref inner) => {
333-
match eval_const_expr_partial(tcx, &**inner, ety) {
334-
Ok(const_float(f)) => Ok(const_float(-f)),
335-
Ok(const_int(i)) => Ok(const_int(-i)),
336-
Ok(const_uint(i)) => Ok(const_uint(-i)),
337-
Ok(const_str(_)) => signal!(e, NegateOnString),
338-
Ok(const_bool(_)) => signal!(e, NegateOnBoolean),
339-
err => err
337+
match try!(eval_const_expr_partial(tcx, &**inner, ety)) {
338+
const_float(f) => const_float(-f),
339+
const_int(i) => const_int(-i),
340+
const_uint(i) => const_uint(-i),
341+
const_str(_) => signal!(e, NegateOnString),
342+
const_bool(_) => signal!(e, NegateOnBoolean),
343+
const_binary(_) => signal!(e, NegateOnBinary),
340344
}
341345
}
342346
ast::ExprUnary(ast::UnNot, ref inner) => {
343-
match eval_const_expr_partial(tcx, &**inner, ety) {
344-
Ok(const_int(i)) => Ok(const_int(!i)),
345-
Ok(const_uint(i)) => Ok(const_uint(!i)),
346-
Ok(const_bool(b)) => Ok(const_bool(!b)),
347-
Ok(const_str(_)) => signal!(e, NotOnString),
348-
Ok(const_float(_)) => signal!(e, NotOnFloat),
349-
err => err
347+
match try!(eval_const_expr_partial(tcx, &**inner, ety)) {
348+
const_int(i) => const_int(!i),
349+
const_uint(i) => const_uint(!i),
350+
const_bool(b) => const_bool(!b),
351+
const_str(_) => signal!(e, NotOnString),
352+
const_float(_) => signal!(e, NotOnFloat),
353+
const_binary(_) => signal!(e, NotOnBinary),
350354
}
351355
}
352356
ast::ExprBinary(op, ref a, ref b) => {
353357
let b_ty = match op.node {
354358
ast::BiShl | ast::BiShr => Some(tcx.types.uint),
355359
_ => ety
356360
};
357-
match (eval_const_expr_partial(tcx, &**a, ety),
358-
eval_const_expr_partial(tcx, &**b, b_ty)) {
359-
(Ok(const_float(a)), Ok(const_float(b))) => {
361+
match (try!(eval_const_expr_partial(tcx, &**a, ety)),
362+
try!(eval_const_expr_partial(tcx, &**b, b_ty))) {
363+
(const_float(a), const_float(b)) => {
360364
match op.node {
361-
ast::BiAdd => Ok(const_float(a + b)),
362-
ast::BiSub => Ok(const_float(a - b)),
363-
ast::BiMul => Ok(const_float(a * b)),
364-
ast::BiDiv => Ok(const_float(a / b)),
365-
ast::BiRem => Ok(const_float(a % b)),
365+
ast::BiAdd => const_float(a + b),
366+
ast::BiSub => const_float(a - b),
367+
ast::BiMul => const_float(a * b),
368+
ast::BiDiv => const_float(a / b),
369+
ast::BiRem => const_float(a % b),
366370
ast::BiEq => fromb(a == b),
367371
ast::BiLt => fromb(a < b),
368372
ast::BiLe => fromb(a <= b),
@@ -372,7 +376,7 @@ pub fn eval_const_expr_partial<'tcx>(tcx: &ty::ctxt<'tcx>,
372376
_ => signal!(e, InvalidOpForFloats(op.node))
373377
}
374378
}
375-
(Ok(const_int(a)), Ok(const_int(b))) => {
379+
(const_int(a), const_int(b)) => {
376380
let is_a_min_value = || {
377381
let int_ty = match ty::expr_ty_opt(tcx, e).map(|ty| &ty.sty) {
378382
Some(&ty::ty_int(int_ty)) => int_ty,
@@ -392,16 +396,16 @@ pub fn eval_const_expr_partial<'tcx>(tcx: &ty::ctxt<'tcx>,
392396
}
393397
};
394398
match op.node {
395-
ast::BiAdd => checked_add_int(e, a, b),
396-
ast::BiSub => checked_sub_int(e, a, b),
397-
ast::BiMul => checked_mul_int(e, a, b),
399+
ast::BiAdd => try!(checked_add_int(e, a, b)),
400+
ast::BiSub => try!(checked_sub_int(e, a, b)),
401+
ast::BiMul => try!(checked_mul_int(e, a, b)),
398402
ast::BiDiv => {
399403
if b == 0 {
400404
signal!(e, DivideByZero);
401405
} else if b == -1 && is_a_min_value() {
402406
signal!(e, DivideWithOverflow);
403407
} else {
404-
Ok(const_int(a / b))
408+
const_int(a / b)
405409
}
406410
}
407411
ast::BiRem => {
@@ -410,14 +414,14 @@ pub fn eval_const_expr_partial<'tcx>(tcx: &ty::ctxt<'tcx>,
410414
} else if b == -1 && is_a_min_value() {
411415
signal!(e, ModuloWithOverflow)
412416
} else {
413-
Ok(const_int(a % b))
417+
const_int(a % b)
414418
}
415419
}
416-
ast::BiAnd | ast::BiBitAnd => Ok(const_int(a & b)),
417-
ast::BiOr | ast::BiBitOr => Ok(const_int(a | b)),
418-
ast::BiBitXor => Ok(const_int(a ^ b)),
419-
ast::BiShl => Ok(const_int(a << b as uint)),
420-
ast::BiShr => Ok(const_int(a >> b as uint)),
420+
ast::BiAnd | ast::BiBitAnd => const_int(a & b),
421+
ast::BiOr | ast::BiBitOr => const_int(a | b),
422+
ast::BiBitXor => const_int(a ^ b),
423+
ast::BiShl => const_int(a << b as uint),
424+
ast::BiShr => const_int(a >> b as uint),
421425
ast::BiEq => fromb(a == b),
422426
ast::BiLt => fromb(a < b),
423427
ast::BiLe => fromb(a <= b),
@@ -426,20 +430,20 @@ pub fn eval_const_expr_partial<'tcx>(tcx: &ty::ctxt<'tcx>,
426430
ast::BiGt => fromb(a > b)
427431
}
428432
}
429-
(Ok(const_uint(a)), Ok(const_uint(b))) => {
433+
(const_uint(a), const_uint(b)) => {
430434
match op.node {
431-
ast::BiAdd => checked_add_uint(e, a, b),
432-
ast::BiSub => checked_sub_uint(e, a, b),
433-
ast::BiMul => checked_mul_uint(e, a, b),
435+
ast::BiAdd => try!(checked_add_uint(e, a, b)),
436+
ast::BiSub => try!(checked_sub_uint(e, a, b)),
437+
ast::BiMul => try!(checked_mul_uint(e, a, b)),
434438
ast::BiDiv if b == 0 => signal!(e, DivideByZero),
435-
ast::BiDiv => Ok(const_uint(a / b)),
439+
ast::BiDiv => const_uint(a / b),
436440
ast::BiRem if b == 0 => signal!(e, ModuloByZero),
437-
ast::BiRem => Ok(const_uint(a % b)),
438-
ast::BiAnd | ast::BiBitAnd => Ok(const_uint(a & b)),
439-
ast::BiOr | ast::BiBitOr => Ok(const_uint(a | b)),
440-
ast::BiBitXor => Ok(const_uint(a ^ b)),
441-
ast::BiShl => Ok(const_uint(a << b as uint)),
442-
ast::BiShr => Ok(const_uint(a >> b as uint)),
441+
ast::BiRem => const_uint(a % b),
442+
ast::BiAnd | ast::BiBitAnd => const_uint(a & b),
443+
ast::BiOr | ast::BiBitOr => const_uint(a | b),
444+
ast::BiBitXor => const_uint(a ^ b),
445+
ast::BiShl => const_uint(a << b as uint),
446+
ast::BiShr => const_uint(a >> b as uint),
443447
ast::BiEq => fromb(a == b),
444448
ast::BiLt => fromb(a < b),
445449
ast::BiLe => fromb(a <= b),
@@ -449,22 +453,22 @@ pub fn eval_const_expr_partial<'tcx>(tcx: &ty::ctxt<'tcx>,
449453
}
450454
}
451455
// shifts can have any integral type as their rhs
452-
(Ok(const_int(a)), Ok(const_uint(b))) => {
456+
(const_int(a), const_uint(b)) => {
453457
match op.node {
454-
ast::BiShl => Ok(const_int(a << b as uint)),
455-
ast::BiShr => Ok(const_int(a >> b as uint)),
458+
ast::BiShl => const_int(a << b as uint),
459+
ast::BiShr => const_int(a >> b as uint),
456460
_ => signal!(e, InvalidOpForIntUint(op.node)),
457461
}
458462
}
459-
(Ok(const_uint(a)), Ok(const_int(b))) => {
463+
(const_uint(a), const_int(b)) => {
460464
match op.node {
461-
ast::BiShl => Ok(const_uint(a << b as uint)),
462-
ast::BiShr => Ok(const_uint(a >> b as uint)),
465+
ast::BiShl => const_uint(a << b as uint),
466+
ast::BiShr => const_uint(a >> b as uint),
463467
_ => signal!(e, InvalidOpForUintInt(op.node)),
464468
}
465469
}
466-
(Ok(const_bool(a)), Ok(const_bool(b))) => {
467-
Ok(const_bool(match op.node {
470+
(const_bool(a), const_bool(b)) => {
471+
const_bool(match op.node {
468472
ast::BiAnd => a && b,
469473
ast::BiOr => a || b,
470474
ast::BiBitXor => a ^ b,
@@ -473,10 +477,8 @@ pub fn eval_const_expr_partial<'tcx>(tcx: &ty::ctxt<'tcx>,
473477
ast::BiEq => a == b,
474478
ast::BiNe => a != b,
475479
_ => signal!(e, InvalidOpForBools(op.node)),
476-
}))
480+
})
477481
}
478-
(err @ Err(..), _) |
479-
(_, err @ Err(..)) => err,
480482

481483
_ => signal!(e, MiscBinaryOp),
482484
}
@@ -494,8 +496,8 @@ pub fn eval_const_expr_partial<'tcx>(tcx: &ty::ctxt<'tcx>,
494496
let base_hint = ty::expr_ty_opt(tcx, &**base).unwrap_or(ety);
495497
let val = try!(eval_const_expr_partial(tcx, &**base, Some(base_hint)));
496498
match cast_const(val, ety) {
497-
Ok(val) => Ok(val),
498-
Err(kind) => Err(ConstEvalErr { span: e.span, kind: kind }),
499+
Ok(val) => val,
500+
Err(kind) => return Err(ConstEvalErr { span: e.span, kind: kind }),
499501
}
500502
}
501503
ast::ExprPath(..) => {
@@ -526,24 +528,24 @@ pub fn eval_const_expr_partial<'tcx>(tcx: &ty::ctxt<'tcx>,
526528
None => signal!(e, NonConstPath)
527529
};
528530
let ety = ety.or_else(|| const_ty.and_then(|ty| ast_ty_to_prim_ty(tcx, ty)));
529-
eval_const_expr_partial(tcx, const_expr, ety)
531+
try!(eval_const_expr_partial(tcx, const_expr, ety))
530532
}
531533
ast::ExprLit(ref lit) => {
532-
Ok(lit_to_const(&**lit, ety))
534+
lit_to_const(&**lit, ety)
533535
}
534-
ast::ExprParen(ref e) => eval_const_expr_partial(tcx, &**e, ety),
536+
ast::ExprParen(ref e) => try!(eval_const_expr_partial(tcx, &**e, ety)),
535537
ast::ExprBlock(ref block) => {
536538
match block.expr {
537-
Some(ref expr) => eval_const_expr_partial(tcx, &**expr, ety),
538-
None => Ok(const_int(0i64))
539+
Some(ref expr) => try!(eval_const_expr_partial(tcx, &**expr, ety)),
540+
None => const_int(0i64)
539541
}
540542
}
541543
ast::ExprTupField(ref base, index) => {
542544
// Get the base tuple if it is constant
543545
if let Some(&ast::ExprTup(ref fields)) = lookup_const(tcx, &**base).map(|s| &s.node) {
544546
// Check that the given index is within bounds and evaluate its value
545547
if fields.len() > index.node {
546-
return eval_const_expr_partial(tcx, &*fields[index.node], None)
548+
return eval_const_expr_partial(tcx, &*fields[index.node], None);
547549
} else {
548550
signal!(e, TupleIndexOutOfBounds);
549551
}
@@ -558,7 +560,7 @@ pub fn eval_const_expr_partial<'tcx>(tcx: &ty::ctxt<'tcx>,
558560
// Check that the given field exists and evaluate it
559561
if let Some(f) = fields.iter().find(|f|
560562
f.ident.node.as_str() == field_name.node.as_str()) {
561-
return eval_const_expr_partial(tcx, &*f.expr, None)
563+
return eval_const_expr_partial(tcx, &*f.expr, None);
562564
} else {
563565
signal!(e, MissingStructField);
564566
}
@@ -567,7 +569,9 @@ pub fn eval_const_expr_partial<'tcx>(tcx: &ty::ctxt<'tcx>,
567569
signal!(e, NonConstStruct);
568570
}
569571
_ => signal!(e, MiscCatchAll)
570-
}
572+
};
573+
574+
Ok(result)
571575
}
572576

573577
fn cast_const(val: const_val, ty: Ty) -> Result<const_val, ErrKind> {

0 commit comments

Comments
 (0)