Skip to content

Commit

Permalink
Auto merge of #53535 - TheDarkula:master, r=oli-obk
Browse files Browse the repository at this point in the history
Made std::intrinsics::transmute() const fn.

r? @oli-obk

tracking issue: #53605
  • Loading branch information
bors committed Aug 30, 2018
2 parents 0e98621 + c5cae79 commit 685fb54
Show file tree
Hide file tree
Showing 12 changed files with 139 additions and 9 deletions.
7 changes: 7 additions & 0 deletions src/librustc_mir/interpret/intrinsics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,13 @@ impl<'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M> {
};
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),
}
Expand Down
12 changes: 12 additions & 0 deletions src/librustc_mir/transform/qualify_consts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -830,6 +830,18 @@ impl<'a, 'tcx> Visitor<'tcx> for Qualifier<'a, 'tcx, 'tcx> {
| "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;
Expand Down
3 changes: 3 additions & 0 deletions src/libsyntax/feature_gate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,9 @@ declare_features! (
// 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),

Expand Down
22 changes: 22 additions & 0 deletions src/test/run-pass/ctfe/transmute-const.rs
Original file line number Diff line number Diff line change
@@ -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);
}
18 changes: 18 additions & 0 deletions src/test/ui/consts/const-eval/transmute-const-promotion.rs
Original file line number Diff line number Diff line change
@@ -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
}
14 changes: 14 additions & 0 deletions src/test/ui/consts/const-eval/transmute-const-promotion.stderr
Original file line number Diff line number Diff line change
@@ -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`.
19 changes: 19 additions & 0 deletions src/test/ui/consts/const-eval/transmute-const.rs
Original file line number Diff line number Diff line change
@@ -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() {}
11 changes: 11 additions & 0 deletions src/test/ui/consts/const-eval/transmute-const.stderr
Original file line number Diff line number Diff line change
@@ -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`.
4 changes: 2 additions & 2 deletions src/test/ui/consts/const-fn-not-safe-for-const.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,14 @@

// 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 {
Expand Down
8 changes: 1 addition & 7 deletions src/test/ui/consts/const-fn-not-safe-for-const.stderr
Original file line number Diff line number Diff line change
@@ -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
|
Expand Down Expand Up @@ -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`.
19 changes: 19 additions & 0 deletions src/test/ui/feature-gates/feature-gate-const_transmute.rs
Original file line number Diff line number Diff line change
@@ -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() {}
11 changes: 11 additions & 0 deletions src/test/ui/feature-gates/feature-gate-const_transmute.stderr
Original file line number Diff line number Diff line change
@@ -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`.

0 comments on commit 685fb54

Please sign in to comment.