Skip to content

Commit 2e48b59

Browse files
committed
Auto merge of #30266 - oli-obk:expr_type_checked, r=luqmana
r? @eefriedman It was getting out of hand with my additions to the const evaluator
2 parents 9cadb29 + 240f686 commit 2e48b59

File tree

1 file changed

+23
-40
lines changed

1 file changed

+23
-40
lines changed

src/librustc/middle/const_eval.rs

+23-40
Original file line numberDiff line numberDiff line change
@@ -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)]
519534
pub 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

Comments
 (0)