@@ -515,6 +515,21 @@ pub enum EvalHint<'tcx> {
515515 UncheckedExprNoHint ,
516516}
517517
518+ impl < ' tcx > EvalHint < ' tcx > {
519+ fn erase_hint ( & self ) -> EvalHint < ' tcx > {
520+ match * self {
521+ ExprTypeChecked => ExprTypeChecked ,
522+ UncheckedExprHint ( _) | UncheckedExprNoHint => UncheckedExprNoHint ,
523+ }
524+ }
525+ fn checked_or ( & self , ty : Ty < ' tcx > ) -> EvalHint < ' tcx > {
526+ match * self {
527+ ExprTypeChecked => ExprTypeChecked ,
528+ _ => UncheckedExprHint ( ty) ,
529+ }
530+ }
531+ }
532+
518533#[ derive( Copy , Clone , PartialEq , Debug ) ]
519534pub enum IntTy { I8 , I16 , I32 , I64 }
520535#[ derive( Copy , Clone , PartialEq , Debug ) ]
@@ -846,13 +861,7 @@ pub fn eval_const_expr_partial<'tcx>(tcx: &ty::ctxt<'tcx>,
846861 }
847862 hir:: ExprBinary ( op, ref a, ref b) => {
848863 let b_ty = match op. node {
849- hir:: BiShl | hir:: BiShr => {
850- if let ExprTypeChecked = ty_hint {
851- ExprTypeChecked
852- } else {
853- UncheckedExprHint ( tcx. types . usize )
854- }
855- }
864+ hir:: BiShl | hir:: BiShr => ty_hint. checked_or ( tcx. types . usize ) ,
856865 _ => ty_hint
857866 } ;
858867 match ( try!( eval_const_expr_partial ( tcx, & * * a, ty_hint, fn_args) ) ,
@@ -1072,11 +1081,7 @@ pub fn eval_const_expr_partial<'tcx>(tcx: &ty::ctxt<'tcx>,
10721081 try!( eval_const_expr_partial ( tcx, const_expr, item_hint, fn_args) )
10731082 }
10741083 hir:: ExprCall ( ref callee, ref args) => {
1075- let sub_ty_hint = if let ExprTypeChecked = ty_hint {
1076- ExprTypeChecked
1077- } else {
1078- UncheckedExprNoHint // we cannot reason about UncheckedExprHint here
1079- } ;
1084+ let sub_ty_hint = ty_hint. erase_hint ( ) ;
10801085 let callee_val = try!( eval_const_expr_partial ( tcx, callee, sub_ty_hint, fn_args) ) ;
10811086 let ( decl, block, constness) = try!( get_fn_def ( tcx, e, callee_val) ) ;
10821087 match ( ty_hint, constness) {
@@ -1109,9 +1114,7 @@ pub fn eval_const_expr_partial<'tcx>(tcx: &ty::ctxt<'tcx>,
11091114 debug ! ( "const call({:?})" , call_args) ;
11101115 try!( eval_const_expr_partial ( tcx, & * * result, ty_hint, Some ( & call_args) ) )
11111116 } ,
1112- hir:: ExprLit ( ref lit) => {
1113- lit_to_const ( & * * lit, ety)
1114- }
1117+ hir:: ExprLit ( ref lit) => lit_to_const ( & * * lit, ety) ,
11151118 hir:: ExprBlock ( ref block) => {
11161119 match block. expr {
11171120 Some ( ref expr) => try!( eval_const_expr_partial ( tcx, & * * expr, ty_hint, fn_args) ) ,
@@ -1124,17 +1127,9 @@ pub fn eval_const_expr_partial<'tcx>(tcx: &ty::ctxt<'tcx>,
11241127 if !tcx. sess . features . borrow ( ) . const_indexing {
11251128 signal ! ( e, IndexOpFeatureGated ) ;
11261129 }
1127- let arr_hint = if let ExprTypeChecked = ty_hint {
1128- ExprTypeChecked
1129- } else {
1130- UncheckedExprNoHint
1131- } ;
1130+ let arr_hint = ty_hint. erase_hint ( ) ;
11321131 let arr = try!( eval_const_expr_partial ( tcx, arr, arr_hint, fn_args) ) ;
1133- let idx_hint = if let ExprTypeChecked = ty_hint {
1134- ExprTypeChecked
1135- } else {
1136- UncheckedExprHint ( tcx. types . usize )
1137- } ;
1132+ let idx_hint = ty_hint. checked_or ( tcx. types . usize ) ;
11381133 let idx = match try!( eval_const_expr_partial ( tcx, idx, idx_hint, fn_args) ) {
11391134 Int ( i) if i >= 0 => i as u64 ,
11401135 Int ( _) => signal ! ( idx, IndexNegative ) ,
@@ -1169,11 +1164,7 @@ pub fn eval_const_expr_partial<'tcx>(tcx: &ty::ctxt<'tcx>,
11691164 }
11701165 hir:: ExprVec ( ref v) => Array ( e. id , v. len ( ) as u64 ) ,
11711166 hir:: ExprRepeat ( _, ref n) => {
1172- let len_hint = if let ExprTypeChecked = ty_hint {
1173- ExprTypeChecked
1174- } else {
1175- UncheckedExprHint ( tcx. types . usize )
1176- } ;
1167+ let len_hint = ty_hint. checked_or ( tcx. types . usize ) ;
11771168 Repeat (
11781169 e. id ,
11791170 match try!( eval_const_expr_partial ( tcx, & * * n, len_hint, fn_args) ) {
@@ -1185,11 +1176,7 @@ pub fn eval_const_expr_partial<'tcx>(tcx: &ty::ctxt<'tcx>,
11851176 )
11861177 } ,
11871178 hir:: ExprTupField ( ref base, index) => {
1188- let base_hint = if let ExprTypeChecked = ty_hint {
1189- ExprTypeChecked
1190- } else {
1191- UncheckedExprNoHint
1192- } ;
1179+ let base_hint = ty_hint. erase_hint ( ) ;
11931180 if let Ok ( c) = eval_const_expr_partial ( tcx, base, base_hint, fn_args) {
11941181 if let Tuple ( tup_id) = c {
11951182 if let hir:: ExprTup ( ref fields) = tcx. map . expect_expr ( tup_id) . node {
@@ -1209,12 +1196,8 @@ pub fn eval_const_expr_partial<'tcx>(tcx: &ty::ctxt<'tcx>,
12091196 }
12101197 }
12111198 hir:: ExprField ( ref base, field_name) => {
1199+ let base_hint = ty_hint. erase_hint ( ) ;
12121200 // Get the base expression if it is a struct and it is constant
1213- let base_hint = if let ExprTypeChecked = ty_hint {
1214- ExprTypeChecked
1215- } else {
1216- UncheckedExprNoHint
1217- } ;
12181201 if let Ok ( c) = eval_const_expr_partial ( tcx, base, base_hint, fn_args) {
12191202 if let Struct ( struct_id) = c {
12201203 if let hir:: ExprStruct ( _, ref fields, _) = tcx. map . expect_expr ( struct_id) . node {
0 commit comments