Skip to content

Commit 54b15c7

Browse files
committed
the type hint given during a cast operation is just a soft hint
1 parent 6ee6003 commit 54b15c7

File tree

2 files changed

+33
-1
lines changed

2 files changed

+33
-1
lines changed

src/librustc/middle/const_eval.rs

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -743,7 +743,21 @@ pub fn eval_const_expr_partial<'tcx>(tcx: &TyCtxt<'tcx>,
743743
}
744744
};
745745

746-
let val = try!(eval_const_expr_partial(tcx, &base, base_hint, fn_args));
746+
let val = match eval_const_expr_partial(tcx, &base, base_hint, fn_args) {
747+
Ok(val) => val,
748+
Err(ConstEvalErr { kind: InferredWrongType(val), .. }) => {
749+
// Something like `5i8 as usize` doesn't need a type hint for the base
750+
// instead take the type hint from the inner value
751+
let hint = match val.int_type() {
752+
Some(IntType::UnsignedInt(ty)) => ty_hint.checked_or(tcx.mk_mach_uint(ty)),
753+
Some(IntType::SignedInt(ty)) => ty_hint.checked_or(tcx.mk_mach_int(ty)),
754+
// we had a type hint, so we can't have an unknown type
755+
None => unreachable!(),
756+
};
757+
try!(eval_const_expr_partial(tcx, &base, hint, fn_args))
758+
},
759+
Err(e) => return Err(e),
760+
};
747761
match cast_const(tcx, val, ety) {
748762
Ok(val) => val,
749763
Err(kind) => return Err(ConstEvalErr { span: e.span, kind: kind }),

src/librustc_const_eval/int.rs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99
// except according to those terms.
1010

1111
use std::cmp::Ordering;
12+
use syntax::attr::IntType;
13+
use syntax::ast::{IntTy, UintTy};
1214

1315
use super::is::*;
1416
use super::us::*;
@@ -258,6 +260,22 @@ impl ConstInt {
258260
ConstInt::Infer(_) | ConstInt::InferSigned(_) => panic!("no type info for const int"),
259261
}
260262
}
263+
264+
pub fn int_type(self) -> Option<IntType> {
265+
match self {
266+
ConstInt::I8(_) => Some(IntType::SignedInt(IntTy::I8)),
267+
ConstInt::I16(_) => Some(IntType::SignedInt(IntTy::I16)),
268+
ConstInt::I32(_) => Some(IntType::SignedInt(IntTy::I32)),
269+
ConstInt::I64(_) => Some(IntType::SignedInt(IntTy::I64)),
270+
ConstInt::Isize(_) => Some(IntType::SignedInt(IntTy::Is)),
271+
ConstInt::U8(_) => Some(IntType::UnsignedInt(UintTy::U8)),
272+
ConstInt::U16(_) => Some(IntType::UnsignedInt(UintTy::U16)),
273+
ConstInt::U32(_) => Some(IntType::UnsignedInt(UintTy::U32)),
274+
ConstInt::U64(_) => Some(IntType::UnsignedInt(UintTy::U64)),
275+
ConstInt::Usize(_) => Some(IntType::UnsignedInt(UintTy::Us)),
276+
_ => None,
277+
}
278+
}
261279
}
262280

263281
impl ::std::cmp::PartialOrd for ConstInt {

0 commit comments

Comments
 (0)