diff options
| author | Alex Crichton <alex@alexcrichton.com> | 2014-09-09 07:38:54 -0700 |
|---|---|---|
| committer | Alex Crichton <alex@alexcrichton.com> | 2014-09-09 12:07:13 -0700 |
| commit | e6b07849038bd3691bb46db6a14bd5aaddfcd45a (patch) | |
| tree | 0fdb3e772ce9ea6d4f428233055cd88bbdf12c30 /src | |
| parent | b8dd7d5056012052941dad6c1a7d622d356a81ce (diff) | |
| parent | c98a80e472e5b090b53b1205417b06d0b8aa25b8 (diff) | |
| download | rust-e6b07849038bd3691bb46db6a14bd5aaddfcd45a.tar.gz rust-e6b07849038bd3691bb46db6a14bd5aaddfcd45a.zip | |
rollup merge of #17085 : jakub-/issue-17074
Diffstat (limited to 'src')
| -rw-r--r-- | src/librustc/middle/const_eval.rs | 72 | ||||
| -rw-r--r-- | src/test/run-pass/issue-17074.rs | 20 |
2 files changed, 57 insertions, 35 deletions
diff --git a/src/librustc/middle/const_eval.rs b/src/librustc/middle/const_eval.rs index e853b5961ec..605c90a49c6 100644 --- a/src/librustc/middle/const_eval.rs +++ b/src/librustc/middle/const_eval.rs @@ -500,42 +500,44 @@ pub fn eval_const_expr_partial(tcx: &ty::ctxt, e: &Expr) -> Result<const_val, St "target type not found for const cast") }); - let base = eval_const_expr_partial(tcx, &**base); - match base { - Err(_) => base, - Ok(val) => { - match ty::get(ety).sty { - ty::ty_float(_) => { - match val { - const_bool(b) => Ok(const_float(b as f64)), - const_uint(u) => Ok(const_float(u as f64)), - const_int(i) => Ok(const_float(i as f64)), - const_float(f) => Ok(const_float(f)), - _ => Err("can't cast this type to float".to_string()), - } + macro_rules! define_casts( + ($val:ident, { + $($ty_pat:pat => ( + $intermediate_ty:ty, + $const_type:ident, + $target_ty:ty + )),* + }) => (match ty::get(ety).sty { + $($ty_pat => { + match $val { + const_bool(b) => Ok($const_type(b as $intermediate_ty as $target_ty)), + const_uint(u) => Ok($const_type(u as $intermediate_ty as $target_ty)), + const_int(i) => Ok($const_type(i as $intermediate_ty as $target_ty)), + const_float(f) => Ok($const_type(f as $intermediate_ty as $target_ty)), + _ => Err(concat!( + "can't cast this type to ", stringify!($const_type) + ).to_string()) } - ty::ty_uint(_) => { - match val { - const_bool(b) => Ok(const_uint(b as u64)), - const_uint(u) => Ok(const_uint(u)), - const_int(i) => Ok(const_uint(i as u64)), - const_float(f) => Ok(const_uint(f as u64)), - _ => Err("can't cast this type to uint".to_string()), - } - } - ty::ty_int(_) => { - match val { - const_bool(b) => Ok(const_int(b as i64)), - const_uint(u) => Ok(const_int(u as i64)), - const_int(i) => Ok(const_int(i)), - const_float(f) => Ok(const_int(f as i64)), - _ => Err("can't cast this type to int".to_string()), - } - } - _ => Err("can't cast this type".to_string()) - } - } - } + },)* + _ => Err("can't cast this type".to_string()) + }) + ) + + eval_const_expr_partial(tcx, &**base) + .and_then(|val| define_casts!(val, { + ty::ty_int(ast::TyI) => (int, const_int, i64), + ty::ty_int(ast::TyI8) => (i8, const_int, i64), + ty::ty_int(ast::TyI16) => (i16, const_int, i64), + ty::ty_int(ast::TyI32) => (i32, const_int, i64), + ty::ty_int(ast::TyI64) => (i64, const_int, i64), + ty::ty_uint(ast::TyU) => (uint, const_uint, u64), + ty::ty_uint(ast::TyU8) => (u8, const_uint, u64), + ty::ty_uint(ast::TyU16) => (u16, const_uint, u64), + ty::ty_uint(ast::TyU32) => (u32, const_uint, u64), + ty::ty_uint(ast::TyU64) => (u64, const_uint, u64), + ty::ty_float(ast::TyF32) => (f32, const_float, f64), + ty::ty_float(ast::TyF64) => (f64, const_float, f64) + })) } ExprPath(_) => { match lookup_const(tcx, e) { diff --git a/src/test/run-pass/issue-17074.rs b/src/test/run-pass/issue-17074.rs new file mode 100644 index 00000000000..e346148691d --- /dev/null +++ b/src/test/run-pass/issue-17074.rs @@ -0,0 +1,20 @@ +// Copyright 2014 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +static X: u64 = -1 as u16 as u64; +static Y: u64 = -1 as u32 as u64; + +fn main() { + assert_eq!(match 1 { + X => unreachable!(), + Y => unreachable!(), + _ => 1i + }, 1); +} |
