]> git.lizzy.rs Git - rust.git/commitdiff
rollup merge of #17085 : jakub-/issue-17074
authorAlex Crichton <alex@alexcrichton.com>
Tue, 9 Sep 2014 14:38:54 +0000 (07:38 -0700)
committerAlex Crichton <alex@alexcrichton.com>
Tue, 9 Sep 2014 19:07:13 +0000 (12:07 -0700)
src/librustc/middle/const_eval.rs
src/test/run-pass/issue-17074.rs [new file with mode: 0644]

index e853b5961ec4fa4b2ef60246efa8764d33d07ed1..605c90a49c6674a375a6611e3199a819a8e7b4f5 100644 (file)
@@ -500,42 +500,44 @@ fn fromb(b: bool) -> Result<const_val, String> { Ok(const_int(b as i64)) }
                                         "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 (file)
index 0000000..e346148
--- /dev/null
@@ -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);
+}