Skip to content

Commit 278227e

Browse files
committed
Fix rust-lang#23890: const-eval _ as usize, _ as isize must dispatch to target type.
1 parent e741a40 commit 278227e

File tree

1 file changed

+42
-32
lines changed

1 file changed

+42
-32
lines changed

src/librustc/middle/const_eval.rs

+42-32
Original file line numberDiff line numberDiff line change
@@ -509,7 +509,7 @@ pub fn eval_const_expr_partial<'tcx>(tcx: &ty::ctxt<'tcx>,
509509
// Prefer known type to noop, but always have a type hint.
510510
let base_hint = ty::expr_ty_opt(tcx, &**base).unwrap_or(ety);
511511
let val = try!(eval_const_expr_partial(tcx, &**base, Some(base_hint)));
512-
match cast_const(val, ety) {
512+
match cast_const(tcx, val, ety) {
513513
Ok(val) => val,
514514
Err(kind) => return Err(ConstEvalErr { span: e.span, kind: kind }),
515515
}
@@ -607,39 +607,49 @@ pub fn eval_const_expr_partial<'tcx>(tcx: &ty::ctxt<'tcx>,
607607
Ok(result)
608608
}
609609

610-
fn cast_const(val: const_val, ty: Ty) -> Result<const_val, ErrKind> {
611-
macro_rules! define_casts {
612-
($($ty_pat:pat => (
613-
$intermediate_ty:ty,
614-
$const_type:ident,
615-
$target_ty:ty
616-
)),*) => (match ty.sty {
617-
$($ty_pat => {
618-
match val {
619-
const_bool(b) => Ok($const_type(b as $intermediate_ty as $target_ty)),
620-
const_uint(u) => Ok($const_type(u as $intermediate_ty as $target_ty)),
621-
const_int(i) => Ok($const_type(i as $intermediate_ty as $target_ty)),
622-
const_float(f) => Ok($const_type(f as $intermediate_ty as $target_ty)),
623-
_ => Err(ErrKind::CannotCastTo(stringify!($const_type))),
624-
}
625-
},)*
626-
_ => Err(ErrKind::CannotCast),
627-
})
610+
fn cast_const<'tcx>(tcx: &ty::ctxt<'tcx>, val: const_val, ty: Ty) -> Result<const_val, ErrKind> {
611+
macro_rules! convert_val {
612+
($intermediate_ty:ty, $const_type:ident, $target_ty:ty) => {
613+
match val {
614+
const_bool(b) => Ok($const_type(b as $intermediate_ty as $target_ty)),
615+
const_uint(u) => Ok($const_type(u as $intermediate_ty as $target_ty)),
616+
const_int(i) => Ok($const_type(i as $intermediate_ty as $target_ty)),
617+
const_float(f) => Ok($const_type(f as $intermediate_ty as $target_ty)),
618+
_ => Err(ErrKind::CannotCastTo(stringify!($const_type))),
619+
}
620+
}
621+
}
622+
623+
// Issue #23890: If isize/usize, then dispatch to appropriate target representation type
624+
match (&ty.sty, tcx.sess.target.int_type, tcx.sess.target.uint_type) {
625+
(&ty::ty_int(ast::TyIs), ast::TyI32, _) => return convert_val!(i32, const_int, i64),
626+
(&ty::ty_int(ast::TyIs), ast::TyI64, _) => return convert_val!(i64, const_int, i64),
627+
(&ty::ty_int(ast::TyIs), _, _) => panic!("unexpected target.int_type"),
628+
629+
(&ty::ty_uint(ast::TyUs), _, ast::TyU32) => return convert_val!(u32, const_uint, u64),
630+
(&ty::ty_uint(ast::TyUs), _, ast::TyU64) => return convert_val!(u64, const_uint, u64),
631+
(&ty::ty_uint(ast::TyUs), _, _) => panic!("unexpected target.uint_type"),
632+
633+
_ => {}
628634
}
629635

630-
define_casts!{
631-
ty::ty_int(ast::TyIs) => (isize, const_int, i64),
632-
ty::ty_int(ast::TyI8) => (i8, const_int, i64),
633-
ty::ty_int(ast::TyI16) => (i16, const_int, i64),
634-
ty::ty_int(ast::TyI32) => (i32, const_int, i64),
635-
ty::ty_int(ast::TyI64) => (i64, const_int, i64),
636-
ty::ty_uint(ast::TyUs) => (usize, const_uint, u64),
637-
ty::ty_uint(ast::TyU8) => (u8, const_uint, u64),
638-
ty::ty_uint(ast::TyU16) => (u16, const_uint, u64),
639-
ty::ty_uint(ast::TyU32) => (u32, const_uint, u64),
640-
ty::ty_uint(ast::TyU64) => (u64, const_uint, u64),
641-
ty::ty_float(ast::TyF32) => (f32, const_float, f64),
642-
ty::ty_float(ast::TyF64) => (f64, const_float, f64)
636+
match ty.sty {
637+
ty::ty_int(ast::TyIs) => unreachable!(),
638+
ty::ty_uint(ast::TyUs) => unreachable!(),
639+
640+
ty::ty_int(ast::TyI8) => convert_val!(i8, const_int, i64),
641+
ty::ty_int(ast::TyI16) => convert_val!(i16, const_int, i64),
642+
ty::ty_int(ast::TyI32) => convert_val!(i32, const_int, i64),
643+
ty::ty_int(ast::TyI64) => convert_val!(i64, const_int, i64),
644+
645+
ty::ty_uint(ast::TyU8) => convert_val!(u8, const_uint, u64),
646+
ty::ty_uint(ast::TyU16) => convert_val!(u16, const_uint, u64),
647+
ty::ty_uint(ast::TyU32) => convert_val!(u32, const_uint, u64),
648+
ty::ty_uint(ast::TyU64) => convert_val!(u64, const_uint, u64),
649+
650+
ty::ty_float(ast::TyF32) => convert_val!(f32, const_float, f64),
651+
ty::ty_float(ast::TyF64) => convert_val!(f64, const_float, f64),
652+
_ => Err(ErrKind::CannotCast),
643653
}
644654
}
645655

0 commit comments

Comments
 (0)