Skip to content

Commit e6b0784

Browse files
committed
rollup merge of rust-lang#17085 : jakub-/issue-17074
2 parents b8dd7d5 + c98a80e commit e6b0784

File tree

2 files changed

+57
-35
lines changed

2 files changed

+57
-35
lines changed

src/librustc/middle/const_eval.rs

Lines changed: 37 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -500,42 +500,44 @@ pub fn eval_const_expr_partial(tcx: &ty::ctxt, e: &Expr) -> Result<const_val, St
500500
"target type not found for const cast")
501501
});
502502

503-
let base = eval_const_expr_partial(tcx, &**base);
504-
match base {
505-
Err(_) => base,
506-
Ok(val) => {
507-
match ty::get(ety).sty {
508-
ty::ty_float(_) => {
509-
match val {
510-
const_bool(b) => Ok(const_float(b as f64)),
511-
const_uint(u) => Ok(const_float(u as f64)),
512-
const_int(i) => Ok(const_float(i as f64)),
513-
const_float(f) => Ok(const_float(f)),
514-
_ => Err("can't cast this type to float".to_string()),
515-
}
503+
macro_rules! define_casts(
504+
($val:ident, {
505+
$($ty_pat:pat => (
506+
$intermediate_ty:ty,
507+
$const_type:ident,
508+
$target_ty:ty
509+
)),*
510+
}) => (match ty::get(ety).sty {
511+
$($ty_pat => {
512+
match $val {
513+
const_bool(b) => Ok($const_type(b as $intermediate_ty as $target_ty)),
514+
const_uint(u) => Ok($const_type(u as $intermediate_ty as $target_ty)),
515+
const_int(i) => Ok($const_type(i as $intermediate_ty as $target_ty)),
516+
const_float(f) => Ok($const_type(f as $intermediate_ty as $target_ty)),
517+
_ => Err(concat!(
518+
"can't cast this type to ", stringify!($const_type)
519+
).to_string())
516520
}
517-
ty::ty_uint(_) => {
518-
match val {
519-
const_bool(b) => Ok(const_uint(b as u64)),
520-
const_uint(u) => Ok(const_uint(u)),
521-
const_int(i) => Ok(const_uint(i as u64)),
522-
const_float(f) => Ok(const_uint(f as u64)),
523-
_ => Err("can't cast this type to uint".to_string()),
524-
}
525-
}
526-
ty::ty_int(_) => {
527-
match val {
528-
const_bool(b) => Ok(const_int(b as i64)),
529-
const_uint(u) => Ok(const_int(u as i64)),
530-
const_int(i) => Ok(const_int(i)),
531-
const_float(f) => Ok(const_int(f as i64)),
532-
_ => Err("can't cast this type to int".to_string()),
533-
}
534-
}
535-
_ => Err("can't cast this type".to_string())
536-
}
537-
}
538-
}
521+
},)*
522+
_ => Err("can't cast this type".to_string())
523+
})
524+
)
525+
526+
eval_const_expr_partial(tcx, &**base)
527+
.and_then(|val| define_casts!(val, {
528+
ty::ty_int(ast::TyI) => (int, const_int, i64),
529+
ty::ty_int(ast::TyI8) => (i8, const_int, i64),
530+
ty::ty_int(ast::TyI16) => (i16, const_int, i64),
531+
ty::ty_int(ast::TyI32) => (i32, const_int, i64),
532+
ty::ty_int(ast::TyI64) => (i64, const_int, i64),
533+
ty::ty_uint(ast::TyU) => (uint, const_uint, u64),
534+
ty::ty_uint(ast::TyU8) => (u8, const_uint, u64),
535+
ty::ty_uint(ast::TyU16) => (u16, const_uint, u64),
536+
ty::ty_uint(ast::TyU32) => (u32, const_uint, u64),
537+
ty::ty_uint(ast::TyU64) => (u64, const_uint, u64),
538+
ty::ty_float(ast::TyF32) => (f32, const_float, f64),
539+
ty::ty_float(ast::TyF64) => (f64, const_float, f64)
540+
}))
539541
}
540542
ExprPath(_) => {
541543
match lookup_const(tcx, e) {

src/test/run-pass/issue-17074.rs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
static X: u64 = -1 as u16 as u64;
12+
static Y: u64 = -1 as u32 as u64;
13+
14+
fn main() {
15+
assert_eq!(match 1 {
16+
X => unreachable!(),
17+
Y => unreachable!(),
18+
_ => 1i
19+
}, 1);
20+
}

0 commit comments

Comments
 (0)