Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Stabilize const_fn_transmute, const_fn_union #85769

Merged
merged 3 commits into from
Jul 28, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion compiler/rustc_ast/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
)]
#![feature(box_syntax)]
#![feature(box_patterns)]
#![feature(const_fn_transmute)]
#![cfg_attr(bootstrap, feature(const_fn_transmute))]
#![feature(crate_visibility_modifier)]
#![feature(iter_zip)]
#![feature(label_break_value)]
Expand Down
4 changes: 4 additions & 0 deletions compiler/rustc_feature/src/accepted.rs
Original file line number Diff line number Diff line change
Expand Up @@ -290,6 +290,10 @@ declare_features! (
/// Allows bindings in the subpattern of a binding pattern.
/// For example, you can write `x @ Some(y)`.
(accepted, bindings_after_at, "1.54.0", Some(65490), None),
/// Allows calling `transmute` in const fn
(accepted, const_fn_transmute, "1.56.0", Some(53605), None),
/// Allows accessing fields of unions inside `const` functions.
(accepted, const_fn_union, "1.56.0", Some(51909), None),

// -------------------------------------------------------------------------
// feature-group-end: accepted features
Expand Down
6 changes: 0 additions & 6 deletions compiler/rustc_feature/src/active.rs
Original file line number Diff line number Diff line change
Expand Up @@ -413,9 +413,6 @@ declare_features! (
/// Allows inferring `'static` outlives requirements (RFC 2093).
(active, infer_static_outlives_requirements, "1.26.0", Some(54185), None),

/// Allows accessing fields of unions inside `const` functions.
(active, const_fn_union, "1.27.0", Some(51909), None),

/// Allows dereferencing raw pointers during const eval.
(active, const_raw_ptr_deref, "1.27.0", Some(51911), None),

Expand Down Expand Up @@ -565,9 +562,6 @@ declare_features! (
/// Lazily evaluate constants. This allows constants to depend on type parameters.
(incomplete, lazy_normalization_consts, "1.46.0", Some(72219), None),

/// Allows calling `transmute` in const fn
(active, const_fn_transmute, "1.46.0", Some(53605), None),

/// Allows `if let` guard in match arms.
(incomplete, if_let_guard, "1.47.0", Some(51114), None),

Expand Down
16 changes: 1 addition & 15 deletions compiler/rustc_mir/src/transform/check_consts/check.rs
Original file line number Diff line number Diff line change
Expand Up @@ -748,12 +748,7 @@ impl Visitor<'tcx> for Checker<'mir, 'tcx> {
| ProjectionElem::Downcast(..)
| ProjectionElem::Subslice { .. }
| ProjectionElem::Field(..)
| ProjectionElem::Index(_) => {
let base_ty = Place::ty_from(place_local, proj_base, self.body, self.tcx).ty;
if base_ty.is_union() {
self.check_op(ops::UnionAccess);
}
}
| ProjectionElem::Index(_) => {}
}
}

Expand Down Expand Up @@ -876,15 +871,6 @@ impl Visitor<'tcx> for Checker<'mir, 'tcx> {

let is_intrinsic = tcx.fn_sig(callee).abi() == RustIntrinsic;

// HACK: This is to "unstabilize" the `transmute` intrinsic
// within const fns. `transmute` is allowed in all other const contexts.
// This won't really scale to more intrinsics or functions. Let's allow const
// transmutes in const fn before we add more hacks to this.
if is_intrinsic && tcx.item_name(callee) == sym::transmute {
self.check_op(ops::Transmute);
return;
}

if !tcx.is_const_fn_raw(callee) {
let mut permitted = false;

Expand Down
45 changes: 0 additions & 45 deletions compiler/rustc_mir/src/transform/check_consts/ops.rs
Original file line number Diff line number Diff line change
Expand Up @@ -501,51 +501,6 @@ impl NonConstOp for ThreadLocalAccess {
}
}

#[derive(Debug)]
pub struct Transmute;
impl NonConstOp for Transmute {
fn status_in_item(&self, ccx: &ConstCx<'_, '_>) -> Status {
if ccx.const_kind() != hir::ConstContext::ConstFn {
Status::Allowed
} else {
Status::Unstable(sym::const_fn_transmute)
}
}

fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx> {
let mut err = feature_err(
&ccx.tcx.sess.parse_sess,
sym::const_fn_transmute,
span,
&format!("`transmute` is not allowed in {}s", ccx.const_kind()),
);
err.note("`transmute` is only allowed in constants and statics for now");
err
}
}

#[derive(Debug)]
pub struct UnionAccess;
impl NonConstOp for UnionAccess {
fn status_in_item(&self, ccx: &ConstCx<'_, '_>) -> Status {
// Union accesses are stable in all contexts except `const fn`.
if ccx.const_kind() != hir::ConstContext::ConstFn {
Status::Allowed
} else {
Status::Unstable(sym::const_fn_union)
}
}

fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx> {
feature_err(
&ccx.tcx.sess.parse_sess,
sym::const_fn_union,
span,
"unions in const fn are unstable",
)
}
}

// Types that cannot appear in the signature or locals of a `const fn`.
pub mod ty {
use super::*;
Expand Down
5 changes: 3 additions & 2 deletions library/core/src/intrinsics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -911,6 +911,9 @@ extern "rust-intrinsic" {
/// cause [undefined behavior][ub] with this function. `transmute` should be
/// the absolute last resort.
///
/// Transmuting pointers to integers in a `const` context is [undefined behavior][ub].
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

my understanding is that transmuting pointers to integers is currently UB in all contexts, const-time or run-time.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well, nothing in this list makes it UB, but it is also not explicitly allowed anywhere to my knowledge. It exists in the grey area of unspecified Rust. There are reasons we might want to make it UB, but I wouldn't know that there is T-lang consensus for that.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right, but isn't it the case that llvm already cannot perform the transmute properly and will already miscompile in some situations? Because if it's just plain broken we should just come clean about it, even if we do relax the rule again later once things are fixed.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are theoretical miscompilations, yes.

/// Any attempt to use the resulting value for integer operations will abort const-evaluation.
///
/// The [nomicon](../../nomicon/transmutes.html) has additional
/// documentation.
///
Expand Down Expand Up @@ -1128,8 +1131,6 @@ extern "rust-intrinsic" {
/// }
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
// NOTE: While this makes the intrinsic const stable, we have some custom code in const fn
// checks that prevent its use within `const fn`.
#[rustc_const_stable(feature = "const_transmute", since = "1.46.0")]
#[rustc_diagnostic_item = "transmute"]
pub fn transmute<T, U>(e: T) -> U;
Expand Down
4 changes: 2 additions & 2 deletions library/core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@
#![feature(const_refs_to_cell)]
#![feature(const_panic)]
#![feature(const_pin)]
#![feature(const_fn_union)]
#![cfg_attr(bootstrap, feature(const_fn_union))]
#![feature(const_impl_trait)]
#![feature(const_fn_floating_point_arithmetic)]
#![feature(const_fn_fn_ptr_basics)]
Expand Down Expand Up @@ -159,7 +159,7 @@
#![feature(rtm_target_feature)]
#![feature(f16c_target_feature)]
#![feature(hexagon_target_feature)]
#![feature(const_fn_transmute)]
#![cfg_attr(bootstrap, feature(const_fn_transmute))]
#![feature(abi_unadjusted)]
#![feature(adx_target_feature)]
#![feature(associated_type_bounds)]
Expand Down
4 changes: 2 additions & 2 deletions library/core/src/num/int_macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2096,7 +2096,7 @@ macro_rules! int_impl {
#[rustc_const_stable(feature = "const_int_conversion", since = "1.44.0")]
// SAFETY: const sound because integers are plain old datatypes so we can always
// transmute them to arrays of bytes
#[rustc_allow_const_fn_unstable(const_fn_transmute)]
#[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(const_fn_transmute))]
#[inline]
pub const fn to_ne_bytes(self) -> [u8; mem::size_of::<Self>()] {
// SAFETY: integers are plain old datatypes so we can always transmute them to
Expand Down Expand Up @@ -2202,7 +2202,7 @@ macro_rules! int_impl {
#[rustc_const_stable(feature = "const_int_conversion", since = "1.44.0")]
// SAFETY: const sound because integers are plain old datatypes so we can always
// transmute to them
#[rustc_allow_const_fn_unstable(const_fn_transmute)]
#[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(const_fn_transmute))]
#[inline]
pub const fn from_ne_bytes(bytes: [u8; mem::size_of::<Self>()]) -> Self {
// SAFETY: integers are plain old datatypes so we can always transmute to them
Expand Down
4 changes: 2 additions & 2 deletions library/core/src/num/uint_macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1926,7 +1926,7 @@ macro_rules! uint_impl {
#[rustc_const_stable(feature = "const_int_conversion", since = "1.44.0")]
// SAFETY: const sound because integers are plain old datatypes so we can always
// transmute them to arrays of bytes
#[rustc_allow_const_fn_unstable(const_fn_transmute)]
#[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(const_fn_transmute))]
#[inline]
pub const fn to_ne_bytes(self) -> [u8; mem::size_of::<Self>()] {
// SAFETY: integers are plain old datatypes so we can always transmute them to
Expand Down Expand Up @@ -2032,7 +2032,7 @@ macro_rules! uint_impl {
#[rustc_const_stable(feature = "const_int_conversion", since = "1.44.0")]
// SAFETY: const sound because integers are plain old datatypes so we can always
// transmute to them
#[rustc_allow_const_fn_unstable(const_fn_transmute)]
#[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(const_fn_transmute))]
#[inline]
pub const fn from_ne_bytes(bytes: [u8; mem::size_of::<Self>()]) -> Self {
// SAFETY: integers are plain old datatypes so we can always transmute to them
Expand Down
2 changes: 1 addition & 1 deletion library/core/src/slice/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ impl<T> [T] {
#[rustc_const_stable(feature = "const_slice_len", since = "1.39.0")]
#[inline]
// SAFETY: const sound because we transmute out the length field as a usize (which it must be)
#[rustc_allow_const_fn_unstable(const_fn_union)]
#[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(const_fn_union))]
pub const fn len(&self) -> usize {
// FIXME: Replace with `crate::ptr::metadata(self)` when that is const-stable.
// As of this writing this causes a "Const-stable functions can only call other
Expand Down
2 changes: 1 addition & 1 deletion library/core/src/str/converts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,7 @@ pub fn from_utf8_mut(v: &mut [u8]) -> Result<&mut str, Utf8Error> {
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_const_stable(feature = "const_str_from_utf8_unchecked", since = "1.55.0")]
#[rustc_allow_const_fn_unstable(const_fn_transmute)]
#[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(const_fn_transmute))]
pub const unsafe fn from_utf8_unchecked(v: &[u8]) -> &str {
// SAFETY: the caller must guarantee that the bytes `v` are valid UTF-8.
// Also relies on `&str` and `&[u8]` having the same layout.
Expand Down
2 changes: 1 addition & 1 deletion library/core/src/str/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -231,7 +231,7 @@ impl str {
#[rustc_const_stable(feature = "str_as_bytes", since = "1.39.0")]
#[inline(always)]
#[allow(unused_attributes)]
#[rustc_allow_const_fn_unstable(const_fn_transmute)]
#[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(const_fn_transmute))]
pub const fn as_bytes(&self) -> &[u8] {
// SAFETY: const sound because we transmute two types with the same layout
unsafe { mem::transmute(self) }
Expand Down
2 changes: 1 addition & 1 deletion library/std/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -246,7 +246,7 @@
#![feature(const_cstr_unchecked)]
#![feature(const_fn_floating_point_arithmetic)]
#![feature(const_fn_fn_ptr_basics)]
#![feature(const_fn_transmute)]
#![cfg_attr(bootstrap, feature(const_fn_transmute))]
#![feature(const_io_structs)]
#![feature(const_ip)]
#![feature(const_ipv4)]
Expand Down
4 changes: 2 additions & 2 deletions library/std/src/net/ip.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1087,7 +1087,7 @@ impl Ipv6Addr {
///
/// let addr = Ipv6Addr::new(0, 0, 0, 0, 0, 0xffff, 0xc00a, 0x2ff);
/// ```
#[rustc_allow_const_fn_unstable(const_fn_transmute)]
#[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(const_fn_transmute))]
#[rustc_const_stable(feature = "const_ipv6", since = "1.32.0")]
#[stable(feature = "rust1", since = "1.0.0")]
#[inline]
Expand Down Expand Up @@ -1149,7 +1149,7 @@ impl Ipv6Addr {
/// assert_eq!(Ipv6Addr::new(0, 0, 0, 0, 0, 0xffff, 0xc00a, 0x2ff).segments(),
/// [0, 0, 0, 0, 0, 0xffff, 0xc00a, 0x2ff]);
/// ```
#[rustc_allow_const_fn_unstable(const_fn_transmute)]
#[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(const_fn_transmute))]
#[rustc_const_stable(feature = "const_ipv6", since = "1.50.0")]
#[stable(feature = "rust1", since = "1.0.0")]
#[inline]
Expand Down
4 changes: 1 addition & 3 deletions src/test/mir-opt/issues/issue-75439.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
// EMIT_MIR issue_75439.foo.MatchBranchSimplification.diff

#![feature(const_fn_transmute)]

use std::mem::transmute;

pub fn foo(bytes: [u8; 16]) -> Option<[u8; 4]> {
Expand All @@ -16,5 +14,5 @@ pub fn foo(bytes: [u8; 16]) -> Option<[u8; 4]> {
}

fn main() {
let _ = foo([0; 16]);
let _ = foo([0; 16]);
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,17 @@
+ // MIR for `foo` after MatchBranchSimplification

fn foo(_1: [u8; 16]) -> Option<[u8; 4]> {
debug bytes => _1; // in scope 0 at $DIR/issue-75439.rs:7:12: 7:17
let mut _0: std::option::Option<[u8; 4]>; // return place in scope 0 at $DIR/issue-75439.rs:7:32: 7:47
let _2: [u32; 4]; // in scope 0 at $DIR/issue-75439.rs:9:9: 9:15
let mut _3: [u8; 16]; // in scope 0 at $DIR/issue-75439.rs:9:47: 9:52
let mut _5: [u8; 4]; // in scope 0 at $DIR/issue-75439.rs:12:14: 12:38
let mut _6: u32; // in scope 0 at $DIR/issue-75439.rs:12:33: 12:35
debug bytes => _1; // in scope 0 at $DIR/issue-75439.rs:5:12: 5:17
let mut _0: std::option::Option<[u8; 4]>; // return place in scope 0 at $DIR/issue-75439.rs:5:32: 5:47
let _2: [u32; 4]; // in scope 0 at $DIR/issue-75439.rs:7:9: 7:15
let mut _3: [u8; 16]; // in scope 0 at $DIR/issue-75439.rs:7:47: 7:52
let mut _5: [u8; 4]; // in scope 0 at $DIR/issue-75439.rs:10:14: 10:38
let mut _6: u32; // in scope 0 at $DIR/issue-75439.rs:10:33: 10:35
scope 1 {
debug dwords => _2; // in scope 1 at $DIR/issue-75439.rs:9:9: 9:15
let _4: u32; // in scope 1 at $DIR/issue-75439.rs:11:27: 11:29
debug dwords => _2; // in scope 1 at $DIR/issue-75439.rs:7:9: 7:15
let _4: u32; // in scope 1 at $DIR/issue-75439.rs:9:27: 9:29
scope 3 {
debug ip => _4; // in scope 3 at $DIR/issue-75439.rs:11:27: 11:29
debug ip => _4; // in scope 3 at $DIR/issue-75439.rs:9:27: 9:29
scope 4 {
}
}
Expand All @@ -21,67 +21,67 @@
}

bb0: {
StorageLive(_2); // scope 0 at $DIR/issue-75439.rs:9:9: 9:15
StorageLive(_3); // scope 2 at $DIR/issue-75439.rs:9:47: 9:52
_3 = _1; // scope 2 at $DIR/issue-75439.rs:9:47: 9:52
_2 = transmute::<[u8; 16], [u32; 4]>(move _3) -> bb1; // scope 2 at $DIR/issue-75439.rs:9:37: 9:53
StorageLive(_2); // scope 0 at $DIR/issue-75439.rs:7:9: 7:15
StorageLive(_3); // scope 2 at $DIR/issue-75439.rs:7:47: 7:52
_3 = _1; // scope 2 at $DIR/issue-75439.rs:7:47: 7:52
_2 = transmute::<[u8; 16], [u32; 4]>(move _3) -> bb1; // scope 2 at $DIR/issue-75439.rs:7:37: 7:53
// mir::Constant
// + span: $DIR/issue-75439.rs:9:37: 9:46
// + span: $DIR/issue-75439.rs:7:37: 7:46
// + literal: Const { ty: unsafe extern "rust-intrinsic" fn([u8; 16]) -> [u32; 4] {std::intrinsics::transmute::<[u8; 16], [u32; 4]>}, val: Value(Scalar(<ZST>)) }
}

bb1: {
StorageDead(_3); // scope 2 at $DIR/issue-75439.rs:9:52: 9:53
switchInt(_2[0 of 4]) -> [0_u32: bb2, otherwise: bb4]; // scope 1 at $DIR/issue-75439.rs:11:13: 11:14
StorageDead(_3); // scope 2 at $DIR/issue-75439.rs:7:52: 7:53
switchInt(_2[0 of 4]) -> [0_u32: bb2, otherwise: bb4]; // scope 1 at $DIR/issue-75439.rs:9:13: 9:14
}

bb2: {
switchInt(_2[1 of 4]) -> [0_u32: bb3, otherwise: bb4]; // scope 1 at $DIR/issue-75439.rs:11:16: 11:17
switchInt(_2[1 of 4]) -> [0_u32: bb3, otherwise: bb4]; // scope 1 at $DIR/issue-75439.rs:9:16: 9:17
}

bb3: {
switchInt(_2[2 of 4]) -> [0_u32: bb6, 4294901760_u32: bb7, otherwise: bb4]; // scope 1 at $DIR/issue-75439.rs:11:19: 11:20
switchInt(_2[2 of 4]) -> [0_u32: bb6, 4294901760_u32: bb7, otherwise: bb4]; // scope 1 at $DIR/issue-75439.rs:9:19: 9:20
}

bb4: {
discriminant(_0) = 0; // scope 1 at $DIR/issue-75439.rs:14:9: 14:13
goto -> bb9; // scope 1 at $DIR/issue-75439.rs:11:5: 15:6
discriminant(_0) = 0; // scope 1 at $DIR/issue-75439.rs:12:9: 12:13
goto -> bb9; // scope 1 at $DIR/issue-75439.rs:9:5: 13:6
}

bb5: {
StorageLive(_5); // scope 3 at $DIR/issue-75439.rs:12:14: 12:38
StorageLive(_6); // scope 4 at $DIR/issue-75439.rs:12:33: 12:35
_6 = _4; // scope 4 at $DIR/issue-75439.rs:12:33: 12:35
_5 = transmute::<u32, [u8; 4]>(move _6) -> bb8; // scope 4 at $DIR/issue-75439.rs:12:23: 12:36
StorageLive(_5); // scope 3 at $DIR/issue-75439.rs:10:14: 10:38
StorageLive(_6); // scope 4 at $DIR/issue-75439.rs:10:33: 10:35
_6 = _4; // scope 4 at $DIR/issue-75439.rs:10:33: 10:35
_5 = transmute::<u32, [u8; 4]>(move _6) -> bb8; // scope 4 at $DIR/issue-75439.rs:10:23: 10:36
// mir::Constant
// + span: $DIR/issue-75439.rs:12:23: 12:32
// + span: $DIR/issue-75439.rs:10:23: 10:32
// + literal: Const { ty: unsafe extern "rust-intrinsic" fn(u32) -> [u8; 4] {std::intrinsics::transmute::<u32, [u8; 4]>}, val: Value(Scalar(<ZST>)) }
}

bb6: {
StorageLive(_4); // scope 1 at $DIR/issue-75439.rs:11:27: 11:29
_4 = _2[3 of 4]; // scope 1 at $DIR/issue-75439.rs:11:27: 11:29
goto -> bb5; // scope 1 at $DIR/issue-75439.rs:11:5: 15:6
StorageLive(_4); // scope 1 at $DIR/issue-75439.rs:9:27: 9:29
_4 = _2[3 of 4]; // scope 1 at $DIR/issue-75439.rs:9:27: 9:29
goto -> bb5; // scope 1 at $DIR/issue-75439.rs:9:5: 13:6
}

bb7: {
StorageLive(_4); // scope 1 at $DIR/issue-75439.rs:11:27: 11:29
_4 = _2[3 of 4]; // scope 1 at $DIR/issue-75439.rs:11:27: 11:29
goto -> bb5; // scope 1 at $DIR/issue-75439.rs:11:5: 15:6
StorageLive(_4); // scope 1 at $DIR/issue-75439.rs:9:27: 9:29
_4 = _2[3 of 4]; // scope 1 at $DIR/issue-75439.rs:9:27: 9:29
goto -> bb5; // scope 1 at $DIR/issue-75439.rs:9:5: 13:6
}

bb8: {
StorageDead(_6); // scope 4 at $DIR/issue-75439.rs:12:35: 12:36
((_0 as Some).0: [u8; 4]) = move _5; // scope 3 at $DIR/issue-75439.rs:12:9: 12:39
discriminant(_0) = 1; // scope 3 at $DIR/issue-75439.rs:12:9: 12:39
StorageDead(_5); // scope 3 at $DIR/issue-75439.rs:12:38: 12:39
StorageDead(_4); // scope 1 at $DIR/issue-75439.rs:13:5: 13:6
goto -> bb9; // scope 1 at $DIR/issue-75439.rs:11:5: 15:6
StorageDead(_6); // scope 4 at $DIR/issue-75439.rs:10:35: 10:36
((_0 as Some).0: [u8; 4]) = move _5; // scope 3 at $DIR/issue-75439.rs:10:9: 10:39
discriminant(_0) = 1; // scope 3 at $DIR/issue-75439.rs:10:9: 10:39
StorageDead(_5); // scope 3 at $DIR/issue-75439.rs:10:38: 10:39
StorageDead(_4); // scope 1 at $DIR/issue-75439.rs:11:5: 11:6
goto -> bb9; // scope 1 at $DIR/issue-75439.rs:9:5: 13:6
}

bb9: {
StorageDead(_2); // scope 0 at $DIR/issue-75439.rs:16:1: 16:2
return; // scope 0 at $DIR/issue-75439.rs:16:2: 16:2
StorageDead(_2); // scope 0 at $DIR/issue-75439.rs:14:1: 14:2
return; // scope 0 at $DIR/issue-75439.rs:14:2: 14:2
}
}

1 change: 0 additions & 1 deletion src/test/ui/consts/const-eval/const_transmute.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
// run-pass

#![feature(const_fn_union)]
#![allow(dead_code)]

#[repr(C)]
Expand Down