1
Fork 0

the type hint given during a cast operation is just a soft hint

This commit is contained in:
Oliver Schneider 2016-02-25 10:14:10 +01:00
parent 6ee60037f9
commit 54b15c7160
2 changed files with 33 additions and 1 deletions

View file

@ -743,7 +743,21 @@ pub fn eval_const_expr_partial<'tcx>(tcx: &TyCtxt<'tcx>,
}
};
let val = try!(eval_const_expr_partial(tcx, &base, base_hint, fn_args));
let val = match eval_const_expr_partial(tcx, &base, base_hint, fn_args) {
Ok(val) => val,
Err(ConstEvalErr { kind: InferredWrongType(val), .. }) => {
// Something like `5i8 as usize` doesn't need a type hint for the base
// instead take the type hint from the inner value
let hint = match val.int_type() {
Some(IntType::UnsignedInt(ty)) => ty_hint.checked_or(tcx.mk_mach_uint(ty)),
Some(IntType::SignedInt(ty)) => ty_hint.checked_or(tcx.mk_mach_int(ty)),
// we had a type hint, so we can't have an unknown type
None => unreachable!(),
};
try!(eval_const_expr_partial(tcx, &base, hint, fn_args))
},
Err(e) => return Err(e),
};
match cast_const(tcx, val, ety) {
Ok(val) => val,
Err(kind) => return Err(ConstEvalErr { span: e.span, kind: kind }),

View file

@ -9,6 +9,8 @@
// except according to those terms.
use std::cmp::Ordering;
use syntax::attr::IntType;
use syntax::ast::{IntTy, UintTy};
use super::is::*;
use super::us::*;
@ -258,6 +260,22 @@ impl ConstInt {
ConstInt::Infer(_) | ConstInt::InferSigned(_) => panic!("no type info for const int"),
}
}
pub fn int_type(self) -> Option<IntType> {
match self {
ConstInt::I8(_) => Some(IntType::SignedInt(IntTy::I8)),
ConstInt::I16(_) => Some(IntType::SignedInt(IntTy::I16)),
ConstInt::I32(_) => Some(IntType::SignedInt(IntTy::I32)),
ConstInt::I64(_) => Some(IntType::SignedInt(IntTy::I64)),
ConstInt::Isize(_) => Some(IntType::SignedInt(IntTy::Is)),
ConstInt::U8(_) => Some(IntType::UnsignedInt(UintTy::U8)),
ConstInt::U16(_) => Some(IntType::UnsignedInt(UintTy::U16)),
ConstInt::U32(_) => Some(IntType::UnsignedInt(UintTy::U32)),
ConstInt::U64(_) => Some(IntType::UnsignedInt(UintTy::U64)),
ConstInt::Usize(_) => Some(IntType::UnsignedInt(UintTy::Us)),
_ => None,
}
}
}
impl ::std::cmp::PartialOrd for ConstInt {