Rollup merge of #129555 - RalfJung:const_float_bits_conv, r=dtolnay

stabilize const_float_bits_conv

This stabilizes `const_float_bits_conv`, and thus fixes https://github.com/rust-lang/rust/issues/72447. With https://github.com/rust-lang/rust/pull/128596 having landed, this is entirely a libs-only question now.

```rust
impl f32 {
    pub const fn to_bits(self) -> u32;
    pub const fn from_bits(v: u32) -> Self;
    pub const fn to_be_bytes(self) -> [u8; 4];
    pub const fn to_le_bytes(self) -> [u8; 4]
    pub const fn to_ne_bytes(self) -> [u8; 4];
    pub const fn from_be_bytes(bytes: [u8; 4]) -> Self;
    pub const fn from_le_bytes(bytes: [u8; 4]) -> Self;
    pub const fn from_ne_bytes(bytes: [u8; 4]) -> Self;
}

impl f64 {
    pub const fn to_bits(self) -> u64;
    pub const fn from_bits(v: u64) -> Self;
    pub const fn to_be_bytes(self) -> [u8; 8];
    pub const fn to_le_bytes(self) -> [u8; 8]
    pub const fn to_ne_bytes(self) -> [u8; 8];
    pub const fn from_be_bytes(bytes: [u8; 8]) -> Self;
    pub const fn from_le_bytes(bytes: [u8; 8]) -> Self;
    pub const fn from_ne_bytes(bytes: [u8; 8]) -> Self;
}
````

Cc `@rust-lang/wg-const-eval` `@rust-lang/libs-api`
This commit is contained in:
Matthias Krüger 2024-09-07 23:30:11 +02:00 committed by GitHub
commit c8f5136fe8
9 changed files with 186 additions and 46 deletions

View File

@ -619,10 +619,10 @@ fn check_expr(&mut self, cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) {
| transmute_ref_to_ref::check(cx, e, from_ty, to_ty, arg, const_context) | transmute_ref_to_ref::check(cx, e, from_ty, to_ty, arg, const_context)
| transmute_ptr_to_ptr::check(cx, e, from_ty, to_ty, arg, &self.msrv) | transmute_ptr_to_ptr::check(cx, e, from_ty, to_ty, arg, &self.msrv)
| transmute_int_to_bool::check(cx, e, from_ty, to_ty, arg) | transmute_int_to_bool::check(cx, e, from_ty, to_ty, arg)
| transmute_int_to_float::check(cx, e, from_ty, to_ty, arg, const_context) | transmute_int_to_float::check(cx, e, from_ty, to_ty, arg)
| transmute_int_to_non_zero::check(cx, e, from_ty, to_ty, arg) | transmute_int_to_non_zero::check(cx, e, from_ty, to_ty, arg)
| transmute_float_to_int::check(cx, e, from_ty, to_ty, arg, const_context) | transmute_float_to_int::check(cx, e, from_ty, to_ty, arg)
| transmute_num_to_bytes::check(cx, e, from_ty, to_ty, arg, const_context) | transmute_num_to_bytes::check(cx, e, from_ty, to_ty, arg)
| (unsound_collection_transmute::check(cx, e, from_ty, to_ty) | (unsound_collection_transmute::check(cx, e, from_ty, to_ty)
|| transmute_undefined_repr::check(cx, e, from_ty, to_ty)) || transmute_undefined_repr::check(cx, e, from_ty, to_ty))
| (eager_transmute::check(cx, e, arg, from_ty, to_ty)); | (eager_transmute::check(cx, e, arg, from_ty, to_ty));

View File

@ -15,10 +15,9 @@ pub(super) fn check<'tcx>(
from_ty: Ty<'tcx>, from_ty: Ty<'tcx>,
to_ty: Ty<'tcx>, to_ty: Ty<'tcx>,
mut arg: &'tcx Expr<'_>, mut arg: &'tcx Expr<'_>,
const_context: bool,
) -> bool { ) -> bool {
match (&from_ty.kind(), &to_ty.kind()) { match (&from_ty.kind(), &to_ty.kind()) {
(ty::Float(float_ty), ty::Int(_) | ty::Uint(_)) if !const_context => { (ty::Float(float_ty), ty::Int(_) | ty::Uint(_)) => {
span_lint_and_then( span_lint_and_then(
cx, cx,
TRANSMUTE_FLOAT_TO_INT, TRANSMUTE_FLOAT_TO_INT,

View File

@ -14,10 +14,9 @@ pub(super) fn check<'tcx>(
from_ty: Ty<'tcx>, from_ty: Ty<'tcx>,
to_ty: Ty<'tcx>, to_ty: Ty<'tcx>,
arg: &'tcx Expr<'_>, arg: &'tcx Expr<'_>,
const_context: bool,
) -> bool { ) -> bool {
match (&from_ty.kind(), &to_ty.kind()) { match (&from_ty.kind(), &to_ty.kind()) {
(ty::Int(_) | ty::Uint(_), ty::Float(_)) if !const_context => { (ty::Int(_) | ty::Uint(_), ty::Float(_)) => {
span_lint_and_then( span_lint_and_then(
cx, cx,
TRANSMUTE_INT_TO_FLOAT, TRANSMUTE_INT_TO_FLOAT,

View File

@ -14,18 +14,12 @@ pub(super) fn check<'tcx>(
from_ty: Ty<'tcx>, from_ty: Ty<'tcx>,
to_ty: Ty<'tcx>, to_ty: Ty<'tcx>,
arg: &'tcx Expr<'_>, arg: &'tcx Expr<'_>,
const_context: bool,
) -> bool { ) -> bool {
match (&from_ty.kind(), &to_ty.kind()) { match (&from_ty.kind(), &to_ty.kind()) {
(ty::Int(_) | ty::Uint(_) | ty::Float(_), ty::Array(arr_ty, _)) => { (ty::Int(_) | ty::Uint(_) | ty::Float(_), ty::Array(arr_ty, _)) => {
if !matches!(arr_ty.kind(), ty::Uint(UintTy::U8)) { if !matches!(arr_ty.kind(), ty::Uint(UintTy::U8)) {
return false; return false;
} }
if matches!(from_ty.kind(), ty::Float(_)) && const_context {
// TODO: Remove when const_float_bits_conv is stabilized
// rust#72447
return false;
}
span_lint_and_then( span_lint_and_then(
cx, cx,

View File

@ -140,24 +140,32 @@ fn test() {
mod issue_5747 { mod issue_5747 {
const VALUE16: f16 = unsafe { std::mem::transmute(0_u16) }; const VALUE16: f16 = unsafe { std::mem::transmute(0_u16) };
//~^ ERROR: transmute from a `u16` to a `f16`
const VALUE32: f32 = unsafe { std::mem::transmute(0_u32) }; const VALUE32: f32 = unsafe { std::mem::transmute(0_u32) };
//~^ ERROR: transmute from a `u32` to a `f32`
const VALUE64: f64 = unsafe { std::mem::transmute(0_i64) }; const VALUE64: f64 = unsafe { std::mem::transmute(0_i64) };
//~^ ERROR: transmute from a `i64` to a `f64`
const VALUE128: f128 = unsafe { std::mem::transmute(0_i128) }; const VALUE128: f128 = unsafe { std::mem::transmute(0_i128) };
//~^ ERROR: transmute from a `i128` to a `f128`
const fn from_bits_16(v: i16) -> f16 { const fn from_bits_16(v: i16) -> f16 {
unsafe { std::mem::transmute(v) } unsafe { std::mem::transmute(v) }
//~^ ERROR: transmute from a `i16` to a `f16`
} }
const fn from_bits_32(v: i32) -> f32 { const fn from_bits_32(v: i32) -> f32 {
unsafe { std::mem::transmute(v) } unsafe { std::mem::transmute(v) }
//~^ ERROR: transmute from a `i32` to a `f32`
} }
const fn from_bits_64(v: u64) -> f64 { const fn from_bits_64(v: u64) -> f64 {
unsafe { std::mem::transmute(v) } unsafe { std::mem::transmute(v) }
//~^ ERROR: transmute from a `u64` to a `f64`
} }
const fn from_bits_128(v: u128) -> f128 { const fn from_bits_128(v: u128) -> f128 {
unsafe { std::mem::transmute(v) } unsafe { std::mem::transmute(v) }
//~^ ERROR: transmute from a `u128` to a `f128`
} }
} }
} }
@ -205,9 +213,13 @@ const fn test_const() {
//~^ ERROR: transmute from a `i128` to a `[u8; 16]` //~^ ERROR: transmute from a `i128` to a `[u8; 16]`
let _: [u8; 2] = std::mem::transmute(0.0f16); let _: [u8; 2] = std::mem::transmute(0.0f16);
//~^ ERROR: transmute from a `f16` to a `[u8; 2]`
let _: [u8; 4] = std::mem::transmute(0.0f32); let _: [u8; 4] = std::mem::transmute(0.0f32);
//~^ ERROR: transmute from a `f32` to a `[u8; 4]`
let _: [u8; 8] = std::mem::transmute(0.0f64); let _: [u8; 8] = std::mem::transmute(0.0f64);
//~^ ERROR: transmute from a `f64` to a `[u8; 8]`
let _: [u8; 16] = std::mem::transmute(0.0f128); let _: [u8; 16] = std::mem::transmute(0.0f128);
//~^ ERROR: transmute from a `f128` to a `[u8; 16]`
} }
} }
} }

View File

@ -148,8 +148,56 @@ error: transmute from a `i128` to a `f128`
LL | let _: f128 = unsafe { std::mem::transmute(0_i128) }; LL | let _: f128 = unsafe { std::mem::transmute(0_i128) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `f128::from_bits(0_i128 as u128)` | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `f128::from_bits(0_i128 as u128)`
error: transmute from a `u16` to a `f16`
--> tests/ui/transmute.rs:142:39
|
LL | const VALUE16: f16 = unsafe { std::mem::transmute(0_u16) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `f16::from_bits(0_u16)`
error: transmute from a `u32` to a `f32`
--> tests/ui/transmute.rs:144:39
|
LL | const VALUE32: f32 = unsafe { std::mem::transmute(0_u32) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `f32::from_bits(0_u32)`
error: transmute from a `i64` to a `f64`
--> tests/ui/transmute.rs:146:39
|
LL | const VALUE64: f64 = unsafe { std::mem::transmute(0_i64) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `f64::from_bits(0_i64 as u64)`
error: transmute from a `i128` to a `f128`
--> tests/ui/transmute.rs:148:41
|
LL | const VALUE128: f128 = unsafe { std::mem::transmute(0_i128) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `f128::from_bits(0_i128 as u128)`
error: transmute from a `i16` to a `f16`
--> tests/ui/transmute.rs:152:22
|
LL | unsafe { std::mem::transmute(v) }
| ^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `f16::from_bits(v as u16)`
error: transmute from a `i32` to a `f32`
--> tests/ui/transmute.rs:157:22
|
LL | unsafe { std::mem::transmute(v) }
| ^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `f32::from_bits(v as u32)`
error: transmute from a `u64` to a `f64`
--> tests/ui/transmute.rs:162:22
|
LL | unsafe { std::mem::transmute(v) }
| ^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `f64::from_bits(v)`
error: transmute from a `u128` to a `f128`
--> tests/ui/transmute.rs:167:22
|
LL | unsafe { std::mem::transmute(v) }
| ^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `f128::from_bits(v)`
error: transmute from a `u8` to a `[u8; 1]` error: transmute from a `u8` to a `[u8; 1]`
--> tests/ui/transmute.rs:168:30 --> tests/ui/transmute.rs:176:30
| |
LL | let _: [u8; 1] = std::mem::transmute(0u8); LL | let _: [u8; 1] = std::mem::transmute(0u8);
| ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0u8.to_ne_bytes()` | ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0u8.to_ne_bytes()`
@ -158,97 +206,121 @@ LL | let _: [u8; 1] = std::mem::transmute(0u8);
= help: to override `-D warnings` add `#[allow(clippy::transmute_num_to_bytes)]` = help: to override `-D warnings` add `#[allow(clippy::transmute_num_to_bytes)]`
error: transmute from a `u32` to a `[u8; 4]` error: transmute from a `u32` to a `[u8; 4]`
--> tests/ui/transmute.rs:171:30 --> tests/ui/transmute.rs:179:30
| |
LL | let _: [u8; 4] = std::mem::transmute(0u32); LL | let _: [u8; 4] = std::mem::transmute(0u32);
| ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0u32.to_ne_bytes()` | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0u32.to_ne_bytes()`
error: transmute from a `u128` to a `[u8; 16]` error: transmute from a `u128` to a `[u8; 16]`
--> tests/ui/transmute.rs:173:31 --> tests/ui/transmute.rs:181:31
| |
LL | let _: [u8; 16] = std::mem::transmute(0u128); LL | let _: [u8; 16] = std::mem::transmute(0u128);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0u128.to_ne_bytes()` | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0u128.to_ne_bytes()`
error: transmute from a `i8` to a `[u8; 1]` error: transmute from a `i8` to a `[u8; 1]`
--> tests/ui/transmute.rs:175:30 --> tests/ui/transmute.rs:183:30
| |
LL | let _: [u8; 1] = std::mem::transmute(0i8); LL | let _: [u8; 1] = std::mem::transmute(0i8);
| ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0i8.to_ne_bytes()` | ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0i8.to_ne_bytes()`
error: transmute from a `i32` to a `[u8; 4]` error: transmute from a `i32` to a `[u8; 4]`
--> tests/ui/transmute.rs:177:30 --> tests/ui/transmute.rs:185:30
| |
LL | let _: [u8; 4] = std::mem::transmute(0i32); LL | let _: [u8; 4] = std::mem::transmute(0i32);
| ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0i32.to_ne_bytes()` | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0i32.to_ne_bytes()`
error: transmute from a `i128` to a `[u8; 16]` error: transmute from a `i128` to a `[u8; 16]`
--> tests/ui/transmute.rs:179:31 --> tests/ui/transmute.rs:187:31
| |
LL | let _: [u8; 16] = std::mem::transmute(0i128); LL | let _: [u8; 16] = std::mem::transmute(0i128);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0i128.to_ne_bytes()` | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0i128.to_ne_bytes()`
error: transmute from a `f16` to a `[u8; 2]` error: transmute from a `f16` to a `[u8; 2]`
--> tests/ui/transmute.rs:182:30 --> tests/ui/transmute.rs:190:30
| |
LL | let _: [u8; 2] = std::mem::transmute(0.0f16); LL | let _: [u8; 2] = std::mem::transmute(0.0f16);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0.0f16.to_ne_bytes()` | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0.0f16.to_ne_bytes()`
error: transmute from a `f32` to a `[u8; 4]` error: transmute from a `f32` to a `[u8; 4]`
--> tests/ui/transmute.rs:184:30 --> tests/ui/transmute.rs:192:30
| |
LL | let _: [u8; 4] = std::mem::transmute(0.0f32); LL | let _: [u8; 4] = std::mem::transmute(0.0f32);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0.0f32.to_ne_bytes()` | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0.0f32.to_ne_bytes()`
error: transmute from a `f64` to a `[u8; 8]` error: transmute from a `f64` to a `[u8; 8]`
--> tests/ui/transmute.rs:186:30 --> tests/ui/transmute.rs:194:30
| |
LL | let _: [u8; 8] = std::mem::transmute(0.0f64); LL | let _: [u8; 8] = std::mem::transmute(0.0f64);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0.0f64.to_ne_bytes()` | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0.0f64.to_ne_bytes()`
error: transmute from a `f128` to a `[u8; 16]` error: transmute from a `f128` to a `[u8; 16]`
--> tests/ui/transmute.rs:188:31 --> tests/ui/transmute.rs:196:31
| |
LL | let _: [u8; 16] = std::mem::transmute(0.0f128); LL | let _: [u8; 16] = std::mem::transmute(0.0f128);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0.0f128.to_ne_bytes()` | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0.0f128.to_ne_bytes()`
error: transmute from a `u8` to a `[u8; 1]` error: transmute from a `u8` to a `[u8; 1]`
--> tests/ui/transmute.rs:194:30 --> tests/ui/transmute.rs:202:30
| |
LL | let _: [u8; 1] = std::mem::transmute(0u8); LL | let _: [u8; 1] = std::mem::transmute(0u8);
| ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0u8.to_ne_bytes()` | ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0u8.to_ne_bytes()`
error: transmute from a `u32` to a `[u8; 4]` error: transmute from a `u32` to a `[u8; 4]`
--> tests/ui/transmute.rs:196:30 --> tests/ui/transmute.rs:204:30
| |
LL | let _: [u8; 4] = std::mem::transmute(0u32); LL | let _: [u8; 4] = std::mem::transmute(0u32);
| ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0u32.to_ne_bytes()` | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0u32.to_ne_bytes()`
error: transmute from a `u128` to a `[u8; 16]` error: transmute from a `u128` to a `[u8; 16]`
--> tests/ui/transmute.rs:198:31 --> tests/ui/transmute.rs:206:31
| |
LL | let _: [u8; 16] = std::mem::transmute(0u128); LL | let _: [u8; 16] = std::mem::transmute(0u128);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0u128.to_ne_bytes()` | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0u128.to_ne_bytes()`
error: transmute from a `i8` to a `[u8; 1]` error: transmute from a `i8` to a `[u8; 1]`
--> tests/ui/transmute.rs:200:30 --> tests/ui/transmute.rs:208:30
| |
LL | let _: [u8; 1] = std::mem::transmute(0i8); LL | let _: [u8; 1] = std::mem::transmute(0i8);
| ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0i8.to_ne_bytes()` | ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0i8.to_ne_bytes()`
error: transmute from a `i32` to a `[u8; 4]` error: transmute from a `i32` to a `[u8; 4]`
--> tests/ui/transmute.rs:202:30 --> tests/ui/transmute.rs:210:30
| |
LL | let _: [u8; 4] = std::mem::transmute(0i32); LL | let _: [u8; 4] = std::mem::transmute(0i32);
| ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0i32.to_ne_bytes()` | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0i32.to_ne_bytes()`
error: transmute from a `i128` to a `[u8; 16]` error: transmute from a `i128` to a `[u8; 16]`
--> tests/ui/transmute.rs:204:31 --> tests/ui/transmute.rs:212:31
| |
LL | let _: [u8; 16] = std::mem::transmute(0i128); LL | let _: [u8; 16] = std::mem::transmute(0i128);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0i128.to_ne_bytes()` | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0i128.to_ne_bytes()`
error: transmute from a `f16` to a `[u8; 2]`
--> tests/ui/transmute.rs:215:30
|
LL | let _: [u8; 2] = std::mem::transmute(0.0f16);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0.0f16.to_ne_bytes()`
error: transmute from a `f32` to a `[u8; 4]`
--> tests/ui/transmute.rs:217:30
|
LL | let _: [u8; 4] = std::mem::transmute(0.0f32);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0.0f32.to_ne_bytes()`
error: transmute from a `f64` to a `[u8; 8]`
--> tests/ui/transmute.rs:219:30
|
LL | let _: [u8; 8] = std::mem::transmute(0.0f64);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0.0f64.to_ne_bytes()`
error: transmute from a `f128` to a `[u8; 16]`
--> tests/ui/transmute.rs:221:31
|
LL | let _: [u8; 16] = std::mem::transmute(0.0f128);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0.0f128.to_ne_bytes()`
error: transmute from a `&[u8]` to a `&str` error: transmute from a `&[u8]` to a `&str`
--> tests/ui/transmute.rs:218:28 --> tests/ui/transmute.rs:230:28
| |
LL | let _: &str = unsafe { std::mem::transmute(B) }; LL | let _: &str = unsafe { std::mem::transmute(B) };
| ^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::str::from_utf8(B).unwrap()` | ^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::str::from_utf8(B).unwrap()`
@ -257,16 +329,16 @@ LL | let _: &str = unsafe { std::mem::transmute(B) };
= help: to override `-D warnings` add `#[allow(clippy::transmute_bytes_to_str)]` = help: to override `-D warnings` add `#[allow(clippy::transmute_bytes_to_str)]`
error: transmute from a `&mut [u8]` to a `&mut str` error: transmute from a `&mut [u8]` to a `&mut str`
--> tests/ui/transmute.rs:221:32 --> tests/ui/transmute.rs:233:32
| |
LL | let _: &mut str = unsafe { std::mem::transmute(mb) }; LL | let _: &mut str = unsafe { std::mem::transmute(mb) };
| ^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::str::from_utf8_mut(mb).unwrap()` | ^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::str::from_utf8_mut(mb).unwrap()`
error: transmute from a `&[u8]` to a `&str` error: transmute from a `&[u8]` to a `&str`
--> tests/ui/transmute.rs:223:30 --> tests/ui/transmute.rs:235:30
| |
LL | const _: &str = unsafe { std::mem::transmute(B) }; LL | const _: &str = unsafe { std::mem::transmute(B) };
| ^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::str::from_utf8_unchecked(B)` | ^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::str::from_utf8_unchecked(B)`
error: aborting due to 42 previous errors error: aborting due to 54 previous errors

View File

@ -1,7 +1,7 @@
#![warn(clippy::transmute_float_to_int)] #![warn(clippy::transmute_float_to_int)]
#![allow(clippy::missing_transmute_annotations)] #![allow(clippy::missing_transmute_annotations)]
#![feature(f128)] #![feature(f128, f128_const)]
#![feature(f16)] #![feature(f16, f16_const)]
fn float_to_int() { fn float_to_int() {
let _: u32 = unsafe { 1f32.to_bits() }; let _: u32 = unsafe { 1f32.to_bits() };
@ -20,25 +20,33 @@ fn float_to_int() {
} }
mod issue_5747 { mod issue_5747 {
const VALUE16: i16 = unsafe { std::mem::transmute(1f16) }; const VALUE16: i16 = unsafe { 1f16.to_bits() as i16 };
const VALUE32: i32 = unsafe { std::mem::transmute(1f32) }; //~^ ERROR: transmute from a `f16` to a `i16`
const VALUE64: u64 = unsafe { std::mem::transmute(1f64) }; const VALUE32: i32 = unsafe { 1f32.to_bits() as i32 };
const VALUE128: u128 = unsafe { std::mem::transmute(1f128) }; //~^ ERROR: transmute from a `f32` to a `i32`
const VALUE64: u64 = unsafe { 1f64.to_bits() };
//~^ ERROR: transmute from a `f64` to a `u64`
const VALUE128: u128 = unsafe { 1f128.to_bits() };
//~^ ERROR: transmute from a `f128` to a `u128`
const fn to_bits_16(v: f16) -> u16 { const fn to_bits_16(v: f16) -> u16 {
unsafe { std::mem::transmute(v) } unsafe { v.to_bits() }
//~^ ERROR: transmute from a `f16` to a `u16`
} }
const fn to_bits_32(v: f32) -> u32 { const fn to_bits_32(v: f32) -> u32 {
unsafe { std::mem::transmute(v) } unsafe { v.to_bits() }
//~^ ERROR: transmute from a `f32` to a `u32`
} }
const fn to_bits_64(v: f64) -> i64 { const fn to_bits_64(v: f64) -> i64 {
unsafe { std::mem::transmute(v) } unsafe { v.to_bits() as i64 }
//~^ ERROR: transmute from a `f64` to a `i64`
} }
const fn to_bits_128(v: f128) -> i128 { const fn to_bits_128(v: f128) -> i128 {
unsafe { std::mem::transmute(v) } unsafe { v.to_bits() as i128 }
//~^ ERROR: transmute from a `f128` to a `i128`
} }
} }

View File

@ -1,7 +1,7 @@
#![warn(clippy::transmute_float_to_int)] #![warn(clippy::transmute_float_to_int)]
#![allow(clippy::missing_transmute_annotations)] #![allow(clippy::missing_transmute_annotations)]
#![feature(f128)] #![feature(f128, f128_const)]
#![feature(f16)] #![feature(f16, f16_const)]
fn float_to_int() { fn float_to_int() {
let _: u32 = unsafe { std::mem::transmute(1f32) }; let _: u32 = unsafe { std::mem::transmute(1f32) };
@ -21,24 +21,32 @@ fn float_to_int() {
mod issue_5747 { mod issue_5747 {
const VALUE16: i16 = unsafe { std::mem::transmute(1f16) }; const VALUE16: i16 = unsafe { std::mem::transmute(1f16) };
//~^ ERROR: transmute from a `f16` to a `i16`
const VALUE32: i32 = unsafe { std::mem::transmute(1f32) }; const VALUE32: i32 = unsafe { std::mem::transmute(1f32) };
//~^ ERROR: transmute from a `f32` to a `i32`
const VALUE64: u64 = unsafe { std::mem::transmute(1f64) }; const VALUE64: u64 = unsafe { std::mem::transmute(1f64) };
//~^ ERROR: transmute from a `f64` to a `u64`
const VALUE128: u128 = unsafe { std::mem::transmute(1f128) }; const VALUE128: u128 = unsafe { std::mem::transmute(1f128) };
//~^ ERROR: transmute from a `f128` to a `u128`
const fn to_bits_16(v: f16) -> u16 { const fn to_bits_16(v: f16) -> u16 {
unsafe { std::mem::transmute(v) } unsafe { std::mem::transmute(v) }
//~^ ERROR: transmute from a `f16` to a `u16`
} }
const fn to_bits_32(v: f32) -> u32 { const fn to_bits_32(v: f32) -> u32 {
unsafe { std::mem::transmute(v) } unsafe { std::mem::transmute(v) }
//~^ ERROR: transmute from a `f32` to a `u32`
} }
const fn to_bits_64(v: f64) -> i64 { const fn to_bits_64(v: f64) -> i64 {
unsafe { std::mem::transmute(v) } unsafe { std::mem::transmute(v) }
//~^ ERROR: transmute from a `f64` to a `i64`
} }
const fn to_bits_128(v: f128) -> i128 { const fn to_bits_128(v: f128) -> i128 {
unsafe { std::mem::transmute(v) } unsafe { std::mem::transmute(v) }
//~^ ERROR: transmute from a `f128` to a `i128`
} }
} }

View File

@ -37,5 +37,53 @@ error: transmute from a `f64` to a `u64`
LL | let _: u64 = unsafe { std::mem::transmute(-1.0) }; LL | let _: u64 = unsafe { std::mem::transmute(-1.0) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `(-1.0f64).to_bits()` | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `(-1.0f64).to_bits()`
error: aborting due to 6 previous errors error: transmute from a `f16` to a `i16`
--> tests/ui/transmute_float_to_int.rs:23:35
|
LL | const VALUE16: i16 = unsafe { std::mem::transmute(1f16) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `1f16.to_bits() as i16`
error: transmute from a `f32` to a `i32`
--> tests/ui/transmute_float_to_int.rs:25:35
|
LL | const VALUE32: i32 = unsafe { std::mem::transmute(1f32) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `1f32.to_bits() as i32`
error: transmute from a `f64` to a `u64`
--> tests/ui/transmute_float_to_int.rs:27:35
|
LL | const VALUE64: u64 = unsafe { std::mem::transmute(1f64) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `1f64.to_bits()`
error: transmute from a `f128` to a `u128`
--> tests/ui/transmute_float_to_int.rs:29:37
|
LL | const VALUE128: u128 = unsafe { std::mem::transmute(1f128) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `1f128.to_bits()`
error: transmute from a `f16` to a `u16`
--> tests/ui/transmute_float_to_int.rs:33:18
|
LL | unsafe { std::mem::transmute(v) }
| ^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `v.to_bits()`
error: transmute from a `f32` to a `u32`
--> tests/ui/transmute_float_to_int.rs:38:18
|
LL | unsafe { std::mem::transmute(v) }
| ^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `v.to_bits()`
error: transmute from a `f64` to a `i64`
--> tests/ui/transmute_float_to_int.rs:43:18
|
LL | unsafe { std::mem::transmute(v) }
| ^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `v.to_bits() as i64`
error: transmute from a `f128` to a `i128`
--> tests/ui/transmute_float_to_int.rs:48:18
|
LL | unsafe { std::mem::transmute(v) }
| ^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `v.to_bits() as i128`
error: aborting due to 14 previous errors