Skip to content

Stabilize const_fn_transmute, const_fn_union #85769

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

Merged
merged 3 commits into from
Jul 28, 2021
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
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
@@ -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)]
4 changes: 4 additions & 0 deletions compiler/rustc_feature/src/accepted.rs
Original file line number Diff line number Diff line change
@@ -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
6 changes: 0 additions & 6 deletions compiler/rustc_feature/src/active.rs
Original file line number Diff line number Diff line change
@@ -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),

@@ -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),

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
@@ -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(_) => {}
}
}

@@ -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;

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
@@ -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::*;
5 changes: 3 additions & 2 deletions library/core/src/intrinsics.rs
Original file line number Diff line number Diff line change
@@ -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.
///
@@ -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;
4 changes: 2 additions & 2 deletions library/core/src/lib.rs
Original file line number Diff line number Diff line change
@@ -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)]
@@ -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)]
4 changes: 2 additions & 2 deletions library/core/src/num/int_macros.rs
Original file line number Diff line number Diff line change
@@ -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
@@ -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
4 changes: 2 additions & 2 deletions library/core/src/num/uint_macros.rs
Original file line number Diff line number Diff line change
@@ -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
@@ -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
2 changes: 1 addition & 1 deletion library/core/src/slice/mod.rs
Original file line number Diff line number Diff line change
@@ -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
2 changes: 1 addition & 1 deletion library/core/src/str/converts.rs
Original file line number Diff line number Diff line change
@@ -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.
2 changes: 1 addition & 1 deletion library/core/src/str/mod.rs
Original file line number Diff line number Diff line change
@@ -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) }
2 changes: 1 addition & 1 deletion library/std/src/lib.rs
Original file line number Diff line number Diff line change
@@ -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)]
4 changes: 2 additions & 2 deletions library/std/src/net/ip.rs
Original file line number Diff line number Diff line change
@@ -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]
@@ -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]
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]> {
@@ -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
@@ -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 {
}
}
@@ -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)]
11 changes: 0 additions & 11 deletions src/test/ui/consts/const-eval/feature-gate-const_fn_union.rs

This file was deleted.

12 changes: 0 additions & 12 deletions src/test/ui/consts/const-eval/feature-gate-const_fn_union.stderr

This file was deleted.

1 change: 0 additions & 1 deletion src/test/ui/consts/const-eval/issue-49296.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
// issue-49296: Unsafe shenigans in constants can result in missing errors

#![feature(const_fn_union)]
#![feature(const_fn_trait_bound)]

const unsafe fn transmute<T: Copy, U: Copy>(t: T) -> U {
2 changes: 1 addition & 1 deletion src/test/ui/consts/const-eval/issue-49296.stderr
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
error[E0080]: evaluation of constant value failed
--> $DIR/issue-49296.rs:19:16
--> $DIR/issue-49296.rs:18:16
|
LL | const X: u64 = *wat(42);
| ^^^^^^^^ pointer to alloc2 was dereferenced after this allocation got freed
2 changes: 0 additions & 2 deletions src/test/ui/consts/const-eval/promoted_const_fn_fail.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
#![feature(const_fn_union)]

#![allow(const_err)]

#[repr(C)]
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
error[E0716]: temporary value dropped while borrowed
--> $DIR/promoted_const_fn_fail.rs:21:27
--> $DIR/promoted_const_fn_fail.rs:19:27
|
LL | let x: &'static u8 = &(bar() + 1);
| ----------- ^^^^^^^^^^^ creates a temporary which is freed while still in use
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
#![feature(const_fn_union)]

#![deny(const_err)]

#[repr(C)]
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
error[E0716]: temporary value dropped while borrowed
--> $DIR/promoted_const_fn_fail_deny_const_err.rs:22:27
--> $DIR/promoted_const_fn_fail_deny_const_err.rs:20:27
|
LL | let x: &'static u8 = &(bar() + 1);
| ----------- ^^^^^^^^^^^ creates a temporary which is freed while still in use
6 changes: 3 additions & 3 deletions src/test/ui/consts/const-eval/ref_to_int_match.32bit.stderr
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
error[E0080]: it is undefined behavior to use this value
--> $DIR/ref_to_int_match.rs:26:1
--> $DIR/ref_to_int_match.rs:25:1
|
LL | const BAR: Int = unsafe { Foo { r: &42 }.f };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered pointer to alloc3, but expected initialized plain (non-pointer) bytes
@@ -10,13 +10,13 @@ LL | const BAR: Int = unsafe { Foo { r: &42 }.f };
}

error: could not evaluate constant pattern
--> $DIR/ref_to_int_match.rs:8:14
--> $DIR/ref_to_int_match.rs:7:14
|
LL | 10..=BAR => {},
| ^^^

error: could not evaluate constant pattern
--> $DIR/ref_to_int_match.rs:8:14
--> $DIR/ref_to_int_match.rs:7:14
|
LL | 10..=BAR => {},
| ^^^
6 changes: 3 additions & 3 deletions src/test/ui/consts/const-eval/ref_to_int_match.64bit.stderr
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
error[E0080]: it is undefined behavior to use this value
--> $DIR/ref_to_int_match.rs:26:1
--> $DIR/ref_to_int_match.rs:25:1
|
LL | const BAR: Int = unsafe { Foo { r: &42 }.f };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered pointer to alloc3, but expected initialized plain (non-pointer) bytes
@@ -10,13 +10,13 @@ LL | const BAR: Int = unsafe { Foo { r: &42 }.f };
}

error: could not evaluate constant pattern
--> $DIR/ref_to_int_match.rs:8:14
--> $DIR/ref_to_int_match.rs:7:14
|
LL | 10..=BAR => {},
| ^^^

error: could not evaluate constant pattern
--> $DIR/ref_to_int_match.rs:8:14
--> $DIR/ref_to_int_match.rs:7:14
|
LL | 10..=BAR => {},
| ^^^
1 change: 0 additions & 1 deletion src/test/ui/consts/const-eval/ref_to_int_match.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
// stderr-per-bitwidth
#![feature(const_fn_union)]

fn main() {
let n: Int = 40;
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
error[E0080]: evaluation of constant value failed
--> $DIR/validate_uninhabited_zsts.rs:5:14
--> $DIR/validate_uninhabited_zsts.rs:4:14
|
LL | unsafe { std::mem::transmute(()) }
| ^^^^^^^^^^^^^^^^^^^^^^^
| |
| transmuting to uninhabited type
| inside `foo` at $DIR/validate_uninhabited_zsts.rs:5:14
| inside `foo` at $DIR/validate_uninhabited_zsts.rs:4:14
...
LL | const FOO: [Empty; 3] = [foo(); 3];
| ----- inside `FOO` at $DIR/validate_uninhabited_zsts.rs:14:26
| ----- inside `FOO` at $DIR/validate_uninhabited_zsts.rs:13:26

error[E0080]: it is undefined behavior to use this value
--> $DIR/validate_uninhabited_zsts.rs:17:1
--> $DIR/validate_uninhabited_zsts.rs:16:1
|
LL | const BAR: [Empty; 3] = [unsafe { std::mem::transmute(()) }; 3];
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed at [0]: encountered a value of uninhabited type Empty
@@ -20,7 +20,7 @@ LL | const BAR: [Empty; 3] = [unsafe { std::mem::transmute(()) }; 3];
= note: the raw bytes of the constant (size: 0, align: 1) {}

warning: the type `!` does not permit zero-initialization
--> $DIR/validate_uninhabited_zsts.rs:5:14
--> $DIR/validate_uninhabited_zsts.rs:4:14
|
LL | unsafe { std::mem::transmute(()) }
| ^^^^^^^^^^^^^^^^^^^^^^^
@@ -32,7 +32,7 @@ LL | unsafe { std::mem::transmute(()) }
= note: the `!` type has no valid value

warning: the type `Empty` does not permit zero-initialization
--> $DIR/validate_uninhabited_zsts.rs:17:35
--> $DIR/validate_uninhabited_zsts.rs:16:35
|
LL | const BAR: [Empty; 3] = [unsafe { std::mem::transmute(()) }; 3];
| ^^^^^^^^^^^^^^^^^^^^^^^
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
error[E0080]: evaluation of constant value failed
--> $DIR/validate_uninhabited_zsts.rs:5:14
--> $DIR/validate_uninhabited_zsts.rs:4:14
|
LL | unsafe { std::mem::transmute(()) }
| ^^^^^^^^^^^^^^^^^^^^^^^
| |
| transmuting to uninhabited type
| inside `foo` at $DIR/validate_uninhabited_zsts.rs:5:14
| inside `foo` at $DIR/validate_uninhabited_zsts.rs:4:14
...
LL | const FOO: [Empty; 3] = [foo(); 3];
| ----- inside `FOO` at $DIR/validate_uninhabited_zsts.rs:14:26
| ----- inside `FOO` at $DIR/validate_uninhabited_zsts.rs:13:26

error[E0080]: it is undefined behavior to use this value
--> $DIR/validate_uninhabited_zsts.rs:17:1
--> $DIR/validate_uninhabited_zsts.rs:16:1
|
LL | const BAR: [Empty; 3] = [unsafe { std::mem::transmute(()) }; 3];
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed at [0]: encountered a value of uninhabited type Empty
@@ -20,7 +20,7 @@ LL | const BAR: [Empty; 3] = [unsafe { std::mem::transmute(()) }; 3];
= note: the raw bytes of the constant (size: 0, align: 1) {}

warning: the type `!` does not permit zero-initialization
--> $DIR/validate_uninhabited_zsts.rs:5:14
--> $DIR/validate_uninhabited_zsts.rs:4:14
|
LL | unsafe { std::mem::transmute(()) }
| ^^^^^^^^^^^^^^^^^^^^^^^
@@ -32,7 +32,7 @@ LL | unsafe { std::mem::transmute(()) }
= note: the `!` type has no valid value

warning: the type `Empty` does not permit zero-initialization
--> $DIR/validate_uninhabited_zsts.rs:17:35
--> $DIR/validate_uninhabited_zsts.rs:16:35
|
LL | const BAR: [Empty; 3] = [unsafe { std::mem::transmute(()) }; 3];
| ^^^^^^^^^^^^^^^^^^^^^^^
1 change: 0 additions & 1 deletion src/test/ui/consts/const-eval/validate_uninhabited_zsts.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
// stderr-per-bitwidth
#![feature(const_fn_transmute)]

const fn foo() -> ! {
unsafe { std::mem::transmute(()) }
10 changes: 5 additions & 5 deletions src/test/ui/consts/const-fn-not-safe-for-const.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
// Test that we can't call random fns in a const fn or do other bad things.

#![feature(const_fn_transmute)]

use std::mem::transmute;

fn random() -> u32 { 0 }
fn random() -> u32 {
0
}

const fn sub(x: &u32) -> usize {
unsafe { transmute(x) }
@@ -18,12 +18,12 @@ static Y: u32 = 0;

const fn get_Y() -> u32 {
Y
//~^ ERROR E0013
//~^ ERROR E0013
}

const fn get_Y_addr() -> &'static u32 {
&Y
//~^ ERROR E0013
//~^ ERROR E0013
}

const fn get() -> u32 {
1 change: 0 additions & 1 deletion src/test/ui/consts/issue-69532.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
// run-pass
#![feature(const_fn_transmute)]

const fn make_nans() -> (f64, f64, f32, f32) {
let nan1: f64 = unsafe { std::mem::transmute(0x7FF0_0001_0000_0001u64) };
6 changes: 0 additions & 6 deletions src/test/ui/consts/min_const_fn/min_const_fn_unsafe_bad.rs
Original file line number Diff line number Diff line change
@@ -8,9 +8,3 @@ const unsafe fn bad_const_unsafe_deref_raw_ref(x: *mut usize) -> &'static usize
//~^ dereferencing raw pointers in constant functions

fn main() {}

const unsafe fn no_union() {
union Foo { x: (), y: () }
Foo { x: () }.y
//~^ unions in const fn
}
11 changes: 1 addition & 10 deletions src/test/ui/consts/min_const_fn/min_const_fn_unsafe_bad.stderr
Original file line number Diff line number Diff line change
@@ -25,15 +25,6 @@ LL | const unsafe fn bad_const_unsafe_deref_raw_ref(x: *mut usize) -> &'static u
= note: see issue #51911 <https://github.com/rust-lang/rust/issues/51911> for more information
= help: add `#![feature(const_raw_ptr_deref)]` to the crate attributes to enable

error[E0658]: unions in const fn are unstable
--> $DIR/min_const_fn_unsafe_bad.rs:14:5
|
LL | Foo { x: () }.y
| ^^^^^^^^^^^^^^^
|
= note: see issue #51909 <https://github.com/rust-lang/rust/issues/51909> for more information
= help: add `#![feature(const_fn_union)]` to the crate attributes to enable

error: aborting due to 4 previous errors
error: aborting due to 3 previous errors

For more information about this error, try `rustc --explain E0658`.
1 change: 0 additions & 1 deletion src/test/ui/consts/promote-not.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
// ignore-tidy-linelength
// Test various things that we do not want to promote.
#![allow(unconditional_panic, const_err)]
#![feature(const_fn_union)]

use std::cell::Cell;

26 changes: 13 additions & 13 deletions src/test/ui/consts/promote-not.stderr
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
error[E0716]: temporary value dropped while borrowed
--> $DIR/promote-not.rs:9:50
--> $DIR/promote-not.rs:8:50
|
LL | static mut TEST1: Option<&mut [i32]> = Some(&mut [1, 2, 3]);
| ----------^^^^^^^^^-
@@ -9,7 +9,7 @@ LL | static mut TEST1: Option<&mut [i32]> = Some(&mut [1, 2, 3]);
| using this value as a static requires that borrow lasts for `'static`

error[E0716]: temporary value dropped while borrowed
--> $DIR/promote-not.rs:12:18
--> $DIR/promote-not.rs:11:18
|
LL | let x = &mut [1,2,3];
| ^^^^^^^ creates a temporary which is freed while still in use
@@ -19,7 +19,7 @@ LL | };
| - temporary value is freed at the end of this statement

error[E0716]: temporary value dropped while borrowed
--> $DIR/promote-not.rs:21:32
--> $DIR/promote-not.rs:20:32
|
LL | let _x: &'static () = &foo();
| ----------- ^^^^^ creates a temporary which is freed while still in use
@@ -29,7 +29,7 @@ LL | }
| - temporary value is freed at the end of this statement

error[E0716]: temporary value dropped while borrowed
--> $DIR/promote-not.rs:29:29
--> $DIR/promote-not.rs:28:29
|
LL | let _x: &'static i32 = &unsafe { U { x: 0 }.x };
| ------------ ^^^^^^^^^^^^^^^^^^^^^^^ creates a temporary which is freed while still in use
@@ -39,7 +39,7 @@ LL | }
| - temporary value is freed at the end of this statement

error[E0716]: temporary value dropped while borrowed
--> $DIR/promote-not.rs:34:29
--> $DIR/promote-not.rs:33:29
|
LL | let _x: &'static i32 = &unsafe { U { x: 0 }.x };
| ------------ ^^^^^^^^^^^^^^^^^^^^^^^ creates a temporary which is freed while still in use
@@ -49,7 +49,7 @@ LL | };
| - temporary value is freed at the end of this statement

error[E0716]: temporary value dropped while borrowed
--> $DIR/promote-not.rs:40:29
--> $DIR/promote-not.rs:39:29
|
LL | let _val: &'static _ = &(Cell::new(1), 2).1;
| ---------- ^^^^^^^^^^^^^^^^^ creates a temporary which is freed while still in use
@@ -59,7 +59,7 @@ LL | };
| - temporary value is freed at the end of this statement

error[E0716]: temporary value dropped while borrowed
--> $DIR/promote-not.rs:45:29
--> $DIR/promote-not.rs:44:29
|
LL | let _val: &'static _ = &(Cell::new(1), 2).0;
| ---------- ^^^^^^^^^^^^^^^^^ creates a temporary which is freed while still in use
@@ -70,7 +70,7 @@ LL | }
| - temporary value is freed at the end of this statement

error[E0716]: temporary value dropped while borrowed
--> $DIR/promote-not.rs:46:29
--> $DIR/promote-not.rs:45:29
|
LL | let _val: &'static _ = &(Cell::new(1), 2).1;
| ---------- ^^^^^^^^^^^^^^^^^ creates a temporary which is freed while still in use
@@ -81,7 +81,7 @@ LL | }
| - temporary value is freed at the end of this statement

error[E0716]: temporary value dropped while borrowed
--> $DIR/promote-not.rs:49:29
--> $DIR/promote-not.rs:48:29
|
LL | let _val: &'static _ = &(1/0);
| ---------- ^^^^^ creates a temporary which is freed while still in use
@@ -92,7 +92,7 @@ LL | }
| - temporary value is freed at the end of this statement

error[E0716]: temporary value dropped while borrowed
--> $DIR/promote-not.rs:50:29
--> $DIR/promote-not.rs:49:29
|
LL | let _val: &'static _ = &(1/(1-1));
| ---------- ^^^^^^^^^ creates a temporary which is freed while still in use
@@ -103,7 +103,7 @@ LL | }
| - temporary value is freed at the end of this statement

error[E0716]: temporary value dropped while borrowed
--> $DIR/promote-not.rs:51:29
--> $DIR/promote-not.rs:50:29
|
LL | let _val: &'static _ = &(1%0);
| ---------- ^^^^^ creates a temporary which is freed while still in use
@@ -114,7 +114,7 @@ LL | }
| - temporary value is freed at the end of this statement

error[E0716]: temporary value dropped while borrowed
--> $DIR/promote-not.rs:52:29
--> $DIR/promote-not.rs:51:29
|
LL | let _val: &'static _ = &(1%(1-1));
| ---------- ^^^^^^^^^ creates a temporary which is freed while still in use
@@ -125,7 +125,7 @@ LL | }
| - temporary value is freed at the end of this statement

error[E0716]: temporary value dropped while borrowed
--> $DIR/promote-not.rs:53:29
--> $DIR/promote-not.rs:52:29
|
LL | let _val: &'static _ = &([1,2,3][4]+1);
| ---------- ^^^^^^^^^^^^^^ creates a temporary which is freed while still in use
118 changes: 0 additions & 118 deletions src/test/ui/feature-gates/feature-gate-const_fn_transmute.mir.stderr

This file was deleted.

41 changes: 0 additions & 41 deletions src/test/ui/feature-gates/feature-gate-const_fn_transmute.rs

This file was deleted.

118 changes: 0 additions & 118 deletions src/test/ui/feature-gates/feature-gate-const_fn_transmute.thir.stderr

This file was deleted.

7 changes: 3 additions & 4 deletions src/test/ui/internal/internal-unstable-const.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
// Don't allow unstable features in stable functions without `allow_internal_unstable`.

#![stable(feature = "rust1", since = "1.0.0")]

#![feature(staged_api)]
#![feature(const_transmute)]
#![feature(const_fn_floating_point_arithmetic)]

#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_const_stable(feature = "rust1", since = "1.0.0")]
pub const fn foo() -> i32 {
unsafe { std::mem::transmute(4u32) } //~ ERROR `transmute`
pub const fn foo() -> f32 {
1.0 + 1.0 //~ ERROR const-stable function cannot use `#[feature(const_fn_floating_point_arithmetic)]`
}

fn main() {}
20 changes: 12 additions & 8 deletions src/test/ui/internal/internal-unstable-const.stderr
Original file line number Diff line number Diff line change
@@ -1,13 +1,17 @@
error[E0658]: `transmute` is not allowed in constant functions
--> $DIR/internal-unstable-const.rs:11:14
error: const-stable function cannot use `#[feature(const_fn_floating_point_arithmetic)]`
--> $DIR/internal-unstable-const.rs:10:5
|
LL | unsafe { std::mem::transmute(4u32) }
| ^^^^^^^^^^^^^^^^^^^^^^^^^
LL | 1.0 + 1.0
| ^^^^^^^^^
|
help: if it is not part of the public API, make this function unstably const
|
LL | #[rustc_const_unstable(feature = "...", issue = "...")]
|
help: otherwise `#[rustc_allow_const_fn_unstable]` can be used to bypass stability checks
|
LL | #[rustc_allow_const_fn_unstable(const_fn_floating_point_arithmetic)]
Copy link
Member

Choose a reason for hiding this comment

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

Oh fancy, it's a completely different error that previously... @oli-obk is that expected? Seems like a bug that the fancy error was not already used before.

Anyway, the new test looks good!

Copy link
Contributor

Choose a reason for hiding this comment

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

yea, the way I unstabilized transmute was not a point of pride

|
= note: see issue #53605 <https://github.com/rust-lang/rust/issues/53605> for more information
= help: add `#![feature(const_fn_transmute)]` to the crate attributes to enable
= note: `transmute` is only allowed in constants and statics for now

error: aborting due to previous error

For more information about this error, try `rustc --explain E0658`.
4 changes: 1 addition & 3 deletions src/test/ui/union/union-const-eval.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
// build-pass (FIXME(62277): could be check-pass?)
// check-pass
// revisions: mirunsafeck thirunsafeck
// [thirunsafeck]compile-flags: -Z thir-unsafeck

#![feature(const_fn_union)]

union U {
a: usize,
b: usize,
1 change: 0 additions & 1 deletion src/tools/clippy/tests/ui/transmute.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
#![feature(const_fn_transmute)]
#![allow(dead_code)]

extern crate core;
48 changes: 24 additions & 24 deletions src/tools/clippy/tests/ui/transmute.stderr
Original file line number Diff line number Diff line change
@@ -1,155 +1,155 @@
error: transmute from a type (`&T`) to itself
--> $DIR/transmute.rs:20:20
--> $DIR/transmute.rs:19:20
|
LL | let _: &'a T = core::intrinsics::transmute(t);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: `-D clippy::useless-transmute` implied by `-D warnings`

error: transmute from a reference to a pointer
--> $DIR/transmute.rs:24:23
--> $DIR/transmute.rs:23:23
|
LL | let _: *const T = core::intrinsics::transmute(t);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `t as *const T`

error: transmute from a reference to a pointer
--> $DIR/transmute.rs:26:21
--> $DIR/transmute.rs:25:21
|
LL | let _: *mut T = core::intrinsics::transmute(t);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `t as *const T as *mut T`

error: transmute from a reference to a pointer
--> $DIR/transmute.rs:28:23
--> $DIR/transmute.rs:27:23
|
LL | let _: *const U = core::intrinsics::transmute(t);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `t as *const T as *const U`

error: transmute from a type (`std::vec::Vec<i32>`) to itself
--> $DIR/transmute.rs:34:27
--> $DIR/transmute.rs:33:27
|
LL | let _: Vec<i32> = core::intrinsics::transmute(my_vec());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

error: transmute from a type (`std::vec::Vec<i32>`) to itself
--> $DIR/transmute.rs:36:27
--> $DIR/transmute.rs:35:27
|
LL | let _: Vec<i32> = core::mem::transmute(my_vec());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

error: transmute from a type (`std::vec::Vec<i32>`) to itself
--> $DIR/transmute.rs:38:27
--> $DIR/transmute.rs:37:27
|
LL | let _: Vec<i32> = std::intrinsics::transmute(my_vec());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

error: transmute from a type (`std::vec::Vec<i32>`) to itself
--> $DIR/transmute.rs:40:27
--> $DIR/transmute.rs:39:27
|
LL | let _: Vec<i32> = std::mem::transmute(my_vec());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

error: transmute from a type (`std::vec::Vec<i32>`) to itself
--> $DIR/transmute.rs:42:27
--> $DIR/transmute.rs:41:27
|
LL | let _: Vec<i32> = my_transmute(my_vec());
| ^^^^^^^^^^^^^^^^^^^^^^

error: transmute from an integer to a pointer
--> $DIR/transmute.rs:44:31
--> $DIR/transmute.rs:43:31
|
LL | let _: *const usize = std::mem::transmute(5_isize);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `5_isize as *const usize`

error: transmute from an integer to a pointer
--> $DIR/transmute.rs:48:31
--> $DIR/transmute.rs:47:31
|
LL | let _: *const usize = std::mem::transmute(1 + 1usize);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `(1 + 1usize) as *const usize`

error: transmute from a type (`*const Usize`) to the type that it points to (`Usize`)
--> $DIR/transmute.rs:63:24
--> $DIR/transmute.rs:62:24
|
LL | let _: Usize = core::intrinsics::transmute(int_const_ptr);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: `-D clippy::crosspointer-transmute` implied by `-D warnings`

error: transmute from a type (`*mut Usize`) to the type that it points to (`Usize`)
--> $DIR/transmute.rs:65:24
--> $DIR/transmute.rs:64:24
|
LL | let _: Usize = core::intrinsics::transmute(int_mut_ptr);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

error: transmute from a type (`Usize`) to a pointer to that type (`*const Usize`)
--> $DIR/transmute.rs:67:31
--> $DIR/transmute.rs:66:31
|
LL | let _: *const Usize = core::intrinsics::transmute(my_int());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

error: transmute from a type (`Usize`) to a pointer to that type (`*mut Usize`)
--> $DIR/transmute.rs:69:29
--> $DIR/transmute.rs:68:29
|
LL | let _: *mut Usize = core::intrinsics::transmute(my_int());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

error: transmute from a `u32` to a `char`
--> $DIR/transmute.rs:75:28
--> $DIR/transmute.rs:74:28
|
LL | let _: char = unsafe { std::mem::transmute(0_u32) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::char::from_u32(0_u32).unwrap()`
|
= note: `-D clippy::transmute-int-to-char` implied by `-D warnings`

error: transmute from a `i32` to a `char`
--> $DIR/transmute.rs:76:28
--> $DIR/transmute.rs:75:28
|
LL | let _: char = unsafe { std::mem::transmute(0_i32) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::char::from_u32(0_i32 as u32).unwrap()`

error: transmute from a `u8` to a `bool`
--> $DIR/transmute.rs:81:28
--> $DIR/transmute.rs:80:28
|
LL | let _: bool = unsafe { std::mem::transmute(0_u8) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `0_u8 != 0`
|
= note: `-D clippy::transmute-int-to-bool` implied by `-D warnings`

error: transmute from a `u32` to a `f32`
--> $DIR/transmute.rs:87:31
--> $DIR/transmute.rs:86:31
|
LL | let _: f32 = unsafe { std::mem::transmute(0_u32) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `f32::from_bits(0_u32)`
|
= note: `-D clippy::transmute-int-to-float` implied by `-D warnings`

error: transmute from a `i32` to a `f32`
--> $DIR/transmute.rs:88:31
--> $DIR/transmute.rs:87:31
|
LL | let _: f32 = unsafe { std::mem::transmute(0_i32) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `f32::from_bits(0_i32 as u32)`

error: transmute from a `u64` to a `f64`
--> $DIR/transmute.rs:89:31
--> $DIR/transmute.rs:88:31
|
LL | let _: f64 = unsafe { std::mem::transmute(0_u64) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `f64::from_bits(0_u64)`

error: transmute from a `i64` to a `f64`
--> $DIR/transmute.rs:90:31
--> $DIR/transmute.rs:89:31
|
LL | let _: f64 = unsafe { std::mem::transmute(0_i64) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `f64::from_bits(0_i64 as u64)`

error: transmute from a `&[u8]` to a `&str`
--> $DIR/transmute.rs:108:28
--> $DIR/transmute.rs:107:28
|
LL | let _: &str = unsafe { std::mem::transmute(b) };
| ^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::str::from_utf8(b).unwrap()`
|
= note: `-D clippy::transmute-bytes-to-str` implied by `-D warnings`

error: transmute from a `&mut [u8]` to a `&mut str`
--> $DIR/transmute.rs:109:32
--> $DIR/transmute.rs:108:32
|
LL | let _: &mut str = unsafe { std::mem::transmute(mb) };
| ^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::str::from_utf8_mut(mb).unwrap()`
1 change: 0 additions & 1 deletion src/tools/clippy/tests/ui/transmute_float_to_int.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
#![feature(const_fn_transmute)]
#![warn(clippy::transmute_float_to_int)]

fn float_to_int() {
12 changes: 6 additions & 6 deletions src/tools/clippy/tests/ui/transmute_float_to_int.stderr
Original file line number Diff line number Diff line change
@@ -1,37 +1,37 @@
error: transmute from a `f32` to a `u32`
--> $DIR/transmute_float_to_int.rs:5:27
--> $DIR/transmute_float_to_int.rs:4:27
|
LL | let _: u32 = unsafe { std::mem::transmute(1f32) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `1f32.to_bits()`
|
= note: `-D clippy::transmute-float-to-int` implied by `-D warnings`

error: transmute from a `f32` to a `i32`
--> $DIR/transmute_float_to_int.rs:6:27
--> $DIR/transmute_float_to_int.rs:5:27
|
LL | let _: i32 = unsafe { std::mem::transmute(1f32) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `1f32.to_bits() as i32`

error: transmute from a `f64` to a `u64`
--> $DIR/transmute_float_to_int.rs:7:27
--> $DIR/transmute_float_to_int.rs:6:27
|
LL | let _: u64 = unsafe { std::mem::transmute(1f64) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `1f64.to_bits()`

error: transmute from a `f64` to a `i64`
--> $DIR/transmute_float_to_int.rs:8:27
--> $DIR/transmute_float_to_int.rs:7:27
|
LL | let _: i64 = unsafe { std::mem::transmute(1f64) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `1f64.to_bits() as i64`

error: transmute from a `f64` to a `u64`
--> $DIR/transmute_float_to_int.rs:9:27
--> $DIR/transmute_float_to_int.rs:8:27
|
LL | let _: u64 = unsafe { std::mem::transmute(1.0) };
| ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `1.0f64.to_bits()`

error: transmute from a `f64` to a `u64`
--> $DIR/transmute_float_to_int.rs:10:27
--> $DIR/transmute_float_to_int.rs:9:27
|
LL | let _: u64 = unsafe { std::mem::transmute(-1.0) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `(-1.0f64).to_bits()`