@@ -225,8 +225,10 @@ pub enum ErrKind {
225
225
InvalidOpForUintInt ( ast:: BinOp_ ) ,
226
226
NegateOnString ,
227
227
NegateOnBoolean ,
228
+ NegateOnBinary ,
228
229
NotOnFloat ,
229
230
NotOnString ,
231
+ NotOnBinary ,
230
232
231
233
AddiWithOverflow ( i64 , i64 ) ,
232
234
SubiWithOverflow ( i64 , i64 ) ,
@@ -259,8 +261,10 @@ impl ConstEvalErr {
259
261
InvalidOpForUintInt ( ..) => "can't do this op on a uint and int" . into_cow ( ) ,
260
262
NegateOnString => "negate on string" . into_cow ( ) ,
261
263
NegateOnBoolean => "negate on boolean" . into_cow ( ) ,
264
+ NegateOnBinary => "negate on binary literal" . into_cow ( ) ,
262
265
NotOnFloat => "not on float or string" . into_cow ( ) ,
263
266
NotOnString => "not on float or string" . into_cow ( ) ,
267
+ NotOnBinary => "not on binary literal" . into_cow ( ) ,
264
268
265
269
AddiWithOverflow ( ..) => "attempted to add with overflow" . into_cow ( ) ,
266
270
SubiWithOverflow ( ..) => "attempted to sub with overflow" . into_cow ( ) ,
@@ -324,45 +328,45 @@ pub fn eval_const_expr_partial<'tcx>(tcx: &ty::ctxt<'tcx>,
324
328
e : & Expr ,
325
329
ty_hint : Option < Ty < ' tcx > > )
326
330
-> 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 ) }
328
332
329
333
let ety = ty_hint. or_else ( || ty:: expr_ty_opt ( tcx, e) ) ;
330
334
331
- match e. node {
335
+ let result = match e. node {
332
336
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 ) ,
340
344
}
341
345
}
342
346
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 ) ,
350
354
}
351
355
}
352
356
ast:: ExprBinary ( op, ref a, ref b) => {
353
357
let b_ty = match op. node {
354
358
ast:: BiShl | ast:: BiShr => Some ( tcx. types . uint ) ,
355
359
_ => ety
356
360
} ;
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) ) => {
360
364
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) ,
366
370
ast:: BiEq => fromb ( a == b) ,
367
371
ast:: BiLt => fromb ( a < b) ,
368
372
ast:: BiLe => fromb ( a <= b) ,
@@ -372,7 +376,7 @@ pub fn eval_const_expr_partial<'tcx>(tcx: &ty::ctxt<'tcx>,
372
376
_ => signal ! ( e, InvalidOpForFloats ( op. node) )
373
377
}
374
378
}
375
- ( Ok ( const_int( a) ) , Ok ( const_int( b) ) ) => {
379
+ ( const_int( a) , const_int( b) ) => {
376
380
let is_a_min_value = || {
377
381
let int_ty = match ty:: expr_ty_opt ( tcx, e) . map ( |ty| & ty. sty ) {
378
382
Some ( & ty:: ty_int( int_ty) ) => int_ty,
@@ -392,16 +396,16 @@ pub fn eval_const_expr_partial<'tcx>(tcx: &ty::ctxt<'tcx>,
392
396
}
393
397
} ;
394
398
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) ) ,
398
402
ast:: BiDiv => {
399
403
if b == 0 {
400
404
signal ! ( e, DivideByZero ) ;
401
405
} else if b == -1 && is_a_min_value ( ) {
402
406
signal ! ( e, DivideWithOverflow ) ;
403
407
} else {
404
- Ok ( const_int ( a / b) )
408
+ const_int ( a / b)
405
409
}
406
410
}
407
411
ast:: BiRem => {
@@ -410,14 +414,14 @@ pub fn eval_const_expr_partial<'tcx>(tcx: &ty::ctxt<'tcx>,
410
414
} else if b == -1 && is_a_min_value ( ) {
411
415
signal ! ( e, ModuloWithOverflow )
412
416
} else {
413
- Ok ( const_int ( a % b) )
417
+ const_int ( a % b)
414
418
}
415
419
}
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 ) ,
421
425
ast:: BiEq => fromb ( a == b) ,
422
426
ast:: BiLt => fromb ( a < b) ,
423
427
ast:: BiLe => fromb ( a <= b) ,
@@ -426,20 +430,20 @@ pub fn eval_const_expr_partial<'tcx>(tcx: &ty::ctxt<'tcx>,
426
430
ast:: BiGt => fromb ( a > b)
427
431
}
428
432
}
429
- ( Ok ( const_uint( a) ) , Ok ( const_uint( b) ) ) => {
433
+ ( const_uint( a) , const_uint( b) ) => {
430
434
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) ) ,
434
438
ast:: BiDiv if b == 0 => signal ! ( e, DivideByZero ) ,
435
- ast:: BiDiv => Ok ( const_uint ( a / b) ) ,
439
+ ast:: BiDiv => const_uint ( a / b) ,
436
440
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 ) ,
443
447
ast:: BiEq => fromb ( a == b) ,
444
448
ast:: BiLt => fromb ( a < b) ,
445
449
ast:: BiLe => fromb ( a <= b) ,
@@ -449,22 +453,22 @@ pub fn eval_const_expr_partial<'tcx>(tcx: &ty::ctxt<'tcx>,
449
453
}
450
454
}
451
455
// 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) ) => {
453
457
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 ) ,
456
460
_ => signal ! ( e, InvalidOpForIntUint ( op. node) ) ,
457
461
}
458
462
}
459
- ( Ok ( const_uint( a) ) , Ok ( const_int( b) ) ) => {
463
+ ( const_uint( a) , const_int( b) ) => {
460
464
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 ) ,
463
467
_ => signal ! ( e, InvalidOpForUintInt ( op. node) ) ,
464
468
}
465
469
}
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 {
468
472
ast:: BiAnd => a && b,
469
473
ast:: BiOr => a || b,
470
474
ast:: BiBitXor => a ^ b,
@@ -473,10 +477,8 @@ pub fn eval_const_expr_partial<'tcx>(tcx: &ty::ctxt<'tcx>,
473
477
ast:: BiEq => a == b,
474
478
ast:: BiNe => a != b,
475
479
_ => signal ! ( e, InvalidOpForBools ( op. node) ) ,
476
- } ) )
480
+ } )
477
481
}
478
- ( err @ Err ( ..) , _) |
479
- ( _, err @ Err ( ..) ) => err,
480
482
481
483
_ => signal ! ( e, MiscBinaryOp ) ,
482
484
}
@@ -494,8 +496,8 @@ pub fn eval_const_expr_partial<'tcx>(tcx: &ty::ctxt<'tcx>,
494
496
let base_hint = ty:: expr_ty_opt ( tcx, & * * base) . unwrap_or ( ety) ;
495
497
let val = try!( eval_const_expr_partial ( tcx, & * * base, Some ( base_hint) ) ) ;
496
498
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 } ) ,
499
501
}
500
502
}
501
503
ast:: ExprPath ( ..) => {
@@ -526,24 +528,24 @@ pub fn eval_const_expr_partial<'tcx>(tcx: &ty::ctxt<'tcx>,
526
528
None => signal ! ( e, NonConstPath )
527
529
} ;
528
530
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) )
530
532
}
531
533
ast:: ExprLit ( ref lit) => {
532
- Ok ( lit_to_const ( & * * lit, ety) )
534
+ lit_to_const ( & * * lit, ety)
533
535
}
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) ) ,
535
537
ast:: ExprBlock ( ref block) => {
536
538
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 )
539
541
}
540
542
}
541
543
ast:: ExprTupField ( ref base, index) => {
542
544
// Get the base tuple if it is constant
543
545
if let Some ( & ast:: ExprTup ( ref fields) ) = lookup_const ( tcx, & * * base) . map ( |s| & s. node ) {
544
546
// Check that the given index is within bounds and evaluate its value
545
547
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 ) ;
547
549
} else {
548
550
signal ! ( e, TupleIndexOutOfBounds ) ;
549
551
}
@@ -558,7 +560,7 @@ pub fn eval_const_expr_partial<'tcx>(tcx: &ty::ctxt<'tcx>,
558
560
// Check that the given field exists and evaluate it
559
561
if let Some ( f) = fields. iter ( ) . find ( |f|
560
562
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 ) ;
562
564
} else {
563
565
signal ! ( e, MissingStructField ) ;
564
566
}
@@ -567,7 +569,9 @@ pub fn eval_const_expr_partial<'tcx>(tcx: &ty::ctxt<'tcx>,
567
569
signal ! ( e, NonConstStruct ) ;
568
570
}
569
571
_ => signal ! ( e, MiscCatchAll )
570
- }
572
+ } ;
573
+
574
+ Ok ( result)
571
575
}
572
576
573
577
fn cast_const ( val : const_val , ty : Ty ) -> Result < const_val , ErrKind > {
0 commit comments