]> git.lizzy.rs Git - rust.git/commitdiff
Made std::intrinsics::transmute() const fn.
authorthedarkula <thedarkula2049@gmail.com>
Mon, 20 Aug 2018 18:51:48 +0000 (19:51 +0100)
committerthedarkula <thedarkula2049@gmail.com>
Thu, 30 Aug 2018 12:06:20 +0000 (13:06 +0100)
12 files changed:
src/librustc_mir/interpret/intrinsics.rs
src/librustc_mir/transform/qualify_consts.rs
src/libsyntax/feature_gate.rs
src/test/run-pass/ctfe/transmute-const.rs [new file with mode: 0644]
src/test/ui/consts/const-eval/transmute-const-promotion.rs [new file with mode: 0644]
src/test/ui/consts/const-eval/transmute-const-promotion.stderr [new file with mode: 0644]
src/test/ui/consts/const-eval/transmute-const.rs [new file with mode: 0644]
src/test/ui/consts/const-eval/transmute-const.stderr [new file with mode: 0644]
src/test/ui/consts/const-fn-not-safe-for-const.rs
src/test/ui/consts/const-fn-not-safe-for-const.stderr
src/test/ui/feature-gates/feature-gate-const_transmute.rs [new file with mode: 0644]
src/test/ui/feature-gates/feature-gate-const_transmute.stderr [new file with mode: 0644]

index 35e3253ca7f8e8414c1092a5afb40ecfc9e13878..e809830fad1cf8c0d1d6301c8e98c6ecf6aec728 100644 (file)
@@ -103,6 +103,13 @@ pub fn emulate_intrinsic(
                 };
                 self.write_scalar(out_val, dest)?;
             }
+            "transmute" => {
+                // Go through an allocation, to make sure the completely different layouts
+                // do not pose a problem.  (When the user transmutes through a union,
+                // there will not be a layout mismatch.)
+                let dest = self.force_allocation(dest)?;
+                self.copy_op(args[0], dest.into())?;
+            }
 
             _ => return Ok(false),
         }
index 7582792b10d98396b1c1dbcafdf1ccc0ea1af541..36dcd1714716cdd67a2df18b64e017ae5c7c1a43 100644 (file)
@@ -830,6 +830,18 @@ fn visit_terminator_kind(&mut self,
                             | "cttz_nonzero"
                             | "ctlz"
                             | "ctlz_nonzero" => is_const_fn = Some(def_id),
+                            "transmute" => {
+                                if self.mode != Mode::Fn {
+                                    is_const_fn = Some(def_id);
+                                    if !self.tcx.sess.features_untracked().const_transmute {
+                                        emit_feature_err(
+                                            &self.tcx.sess.parse_sess, "const_transmute",
+                                            self.span, GateIssue::Language,
+                                            &format!("The use of std::mem::transmute() \
+                                            is gated in {}s", self.mode));
+                                    }
+                                }
+                            }
 
                             name if name.starts_with("simd_shuffle") => {
                                 is_shuffle = true;
index 6dd788bf6e2ac79fe19f730da425d052068c7eb7..bb5d929a3234573493d8158a259c91b1a68ced3d 100644 (file)
@@ -221,6 +221,9 @@ pub fn walk_feature_fields<F>(&self, mut f: F)
     // Allows dereferencing raw pointers during const eval
     (active, const_raw_ptr_deref, "1.27.0", Some(51911), None),
 
+    // Allows reinterpretation of the bits of a value of one type as another type during const eval
+    (active, const_transmute, "1.29.0", Some(53605), None),
+
     // Allows comparing raw pointers during const eval
     (active, const_compare_raw_pointers, "1.27.0", Some(53020), None),
 
diff --git a/src/test/run-pass/ctfe/transmute-const.rs b/src/test/run-pass/ctfe/transmute-const.rs
new file mode 100644 (file)
index 0000000..bf9459a
--- /dev/null
@@ -0,0 +1,22 @@
+// Copyright 2018 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.
+
+#![feature(const_transmute)]
+
+use std::mem;
+
+#[repr(transparent)]
+struct Foo(u32);
+
+const TRANSMUTED_U32: u32 = unsafe { mem::transmute(Foo(3)) };
+
+fn main() {
+    assert_eq!(TRANSMUTED_U32, 3);
+}
diff --git a/src/test/ui/consts/const-eval/transmute-const-promotion.rs b/src/test/ui/consts/const-eval/transmute-const-promotion.rs
new file mode 100644 (file)
index 0000000..ea55584
--- /dev/null
@@ -0,0 +1,18 @@
+// Copyright 2018 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.
+
+#![feature(const_transmute)]
+
+use std::mem;
+
+fn main() {
+    let x: &'static u32 = unsafe { &mem::transmute(3.0f32) };
+    //~^ ERROR value does not live long enough
+}
diff --git a/src/test/ui/consts/const-eval/transmute-const-promotion.stderr b/src/test/ui/consts/const-eval/transmute-const-promotion.stderr
new file mode 100644 (file)
index 0000000..2f46684
--- /dev/null
@@ -0,0 +1,14 @@
+error[E0597]: borrowed value does not live long enough
+  --> $DIR/transmute-const-promotion.rs:16:37
+   |
+LL |     let x: &'static u32 = unsafe { &mem::transmute(3.0f32) };
+   |                                     ^^^^^^^^^^^^^^^^^^^^^^ temporary value does not live long enough
+LL |     //~^ ERROR value does not live long enough
+LL | }
+   | - temporary value only lives until here
+   |
+   = note: borrowed value must be valid for the static lifetime...
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0597`.
diff --git a/src/test/ui/consts/const-eval/transmute-const.rs b/src/test/ui/consts/const-eval/transmute-const.rs
new file mode 100644 (file)
index 0000000..a585a44
--- /dev/null
@@ -0,0 +1,19 @@
+// Copyright 2018 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.
+
+#![feature(const_transmute)]
+
+use std::mem;
+
+static FOO: bool = unsafe { mem::transmute(3u8) };
+//~^ ERROR this static likely exhibits undefined behavior
+//~^^ type validation failed: encountered 3, but expected something in the range 0..=1
+
+fn main() {}
diff --git a/src/test/ui/consts/const-eval/transmute-const.stderr b/src/test/ui/consts/const-eval/transmute-const.stderr
new file mode 100644 (file)
index 0000000..c9beca7
--- /dev/null
@@ -0,0 +1,11 @@
+error[E0080]: this static likely exhibits undefined behavior
+  --> $DIR/transmute-const.rs:15:1
+   |
+LL | static FOO: bool = unsafe { mem::transmute(3u8) };
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered 3, but expected something in the range 0..=1
+   |
+   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0080`.
index 341cc7bb49116d8bfb3ef1f28968f8cd44616ce1..30a738a83a3b67d2b769f8be34840c1c3cb02464 100644 (file)
 
 // Test that we can't call random fns in a const fn or do other bad things.
 
-#![feature(const_fn)]
+#![feature(const_fn, const_transmute)]
 
 use std::mem::transmute;
 
 fn random() -> u32 { 0 }
 
 const fn sub(x: &u32) -> usize {
-    unsafe { transmute(x) } //~ ERROR E0015
+    unsafe { transmute(x) }
 }
 
 const fn sub1() -> u32 {
index 1e99a4378faf366480298cc4e844a022360da143..613670acc93264ede0300a5364baacd94f7fe917 100644 (file)
@@ -1,9 +1,3 @@
-error[E0015]: calls in constant functions are limited to constant functions, tuple structs and tuple variants
-  --> $DIR/const-fn-not-safe-for-const.rs:20:14
-   |
-LL |     unsafe { transmute(x) } //~ ERROR E0015
-   |              ^^^^^^^^^^^^
-
 error[E0015]: calls in constant functions are limited to constant functions, tuple structs and tuple variants
   --> $DIR/const-fn-not-safe-for-const.rs:24:5
    |
@@ -70,7 +64,7 @@ LL |     x + y
    |
    = help: add #![feature(const_let)] to the crate attributes to enable
 
-error: aborting due to 10 previous errors
+error: aborting due to 9 previous errors
 
 Some errors occurred: E0013, E0015, E0658.
 For more information about an error, try `rustc --explain E0013`.
diff --git a/src/test/ui/feature-gates/feature-gate-const_transmute.rs b/src/test/ui/feature-gates/feature-gate-const_transmute.rs
new file mode 100644 (file)
index 0000000..c879ab5
--- /dev/null
@@ -0,0 +1,19 @@
+// Copyright 2018 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.
+
+use std::mem;
+
+#[repr(transparent)]
+struct Foo(u32);
+
+const TRANSMUTED_U32: u32 = unsafe { mem::transmute(Foo(3)) };
+//~^ ERROR The use of std::mem::transmute() is gated in constants (see issue #53605)
+
+fn main() {}
diff --git a/src/test/ui/feature-gates/feature-gate-const_transmute.stderr b/src/test/ui/feature-gates/feature-gate-const_transmute.stderr
new file mode 100644 (file)
index 0000000..bb09b93
--- /dev/null
@@ -0,0 +1,11 @@
+error[E0658]: The use of std::mem::transmute() is gated in constants (see issue #53605)
+  --> $DIR/feature-gate-const_transmute.rs:16:38
+   |
+LL | const TRANSMUTED_U32: u32 = unsafe { mem::transmute(Foo(3)) };
+   |                                      ^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = help: add #![feature(const_transmute)] to the crate attributes to enable
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0658`.