Skip to content

Commit 5afc2e4

Browse files
authored
Rollup merge of rust-lang#136083 - bend-n:⃤⃤, r=lcnr
Suggest {to,from}_ne_bytes for transmutations between arrays and integers, etc implements rust-lang#136067 Rust has helper methods for many kinds of safe transmutes, for example integer<->bytes. This is a lint against using transmute for these cases. ```rs fn bytes_at_home(x: [u8; 4]) -> u32 { transmute(x) } // other examples transmute::<[u8; 2], u16>(); transmute::<[u8; 8], f64>(); transmute::<u32, [u8; 4]>(); transmute::<char, u32>(); transmute::<u32, char>(); ``` It would be handy to suggest `u32::from_ne_bytes(x)`. This is implemented for `[u8; _]` -> `{float int}` This also implements the cases: `fXX` <-> `uXX` = `{from_bits, to_bits}` `uXX` -> `iXX` via `cast_unsigned` and `cast_signed` {`char` -> `u32`, `bool` -> `n8`} via `from` `u32` -> `char` via `from_u32_unchecked` (note: notes `from_u32().unwrap()`) (contested) `u8` -> `bool` via `==` (debatable) --- try-job: aarch64-gnu try-job: test-various
2 parents f6cec8b + e5bd667 commit 5afc2e4

File tree

10 files changed

+19
-5
lines changed

10 files changed

+19
-5
lines changed

alloctests/tests/fmt.rs

+1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#![deny(warnings)]
22
// FIXME(static_mut_refs): Do not allow `static_mut_refs` lint
33
#![allow(static_mut_refs)]
4+
#![cfg_attr(not(bootstrap), allow(unnecessary_transmutes))]
45

56
use std::cell::RefCell;
67
use std::fmt::{self, Write};

core/src/char/convert.rs

+2
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ pub(super) const fn from_u32(i: u32) -> Option<char> {
2121
/// Converts a `u32` to a `char`, ignoring validity. See [`char::from_u32_unchecked`].
2222
#[inline]
2323
#[must_use]
24+
#[cfg_attr(not(bootstrap), allow(unnecessary_transmutes))]
2425
pub(super) const unsafe fn from_u32_unchecked(i: u32) -> char {
2526
// SAFETY: the caller must guarantee that `i` is a valid char value.
2627
unsafe {
@@ -221,6 +222,7 @@ impl FromStr for char {
221222
}
222223

223224
#[inline]
225+
#[cfg_attr(not(bootstrap), allow(unnecessary_transmutes))]
224226
const fn char_try_from_u32(i: u32) -> Result<char, CharTryFromError> {
225227
// This is an optimized version of the check
226228
// (i > MAX as u32) || (i >= 0xD800 && i <= 0xDFFF),

core/src/intrinsics/mod.rs

+1
Original file line numberDiff line numberDiff line change
@@ -1497,6 +1497,7 @@ pub const fn forget<T: ?Sized>(_: T);
14971497
/// Turning raw bytes (`[u8; SZ]`) into `u32`, `f64`, etc.:
14981498
///
14991499
/// ```
1500+
/// # #![cfg_attr(not(bootstrap), allow(unnecessary_transmutes))]
15001501
/// let raw_bytes = [0x78, 0x56, 0x34, 0x12];
15011502
///
15021503
/// let num = unsafe {

core/src/num/f128.rs

+2
Original file line numberDiff line numberDiff line change
@@ -904,6 +904,7 @@ impl f128 {
904904
#[inline]
905905
#[unstable(feature = "f128", issue = "116909")]
906906
#[must_use = "this returns the result of the operation, without modifying the original"]
907+
#[cfg_attr(not(bootstrap), allow(unnecessary_transmutes))]
907908
pub const fn to_bits(self) -> u128 {
908909
// SAFETY: `u128` is a plain old datatype so we can always transmute to it.
909910
unsafe { mem::transmute(self) }
@@ -951,6 +952,7 @@ impl f128 {
951952
#[inline]
952953
#[must_use]
953954
#[unstable(feature = "f128", issue = "116909")]
955+
#[cfg_attr(not(bootstrap), allow(unnecessary_transmutes))]
954956
pub const fn from_bits(v: u128) -> Self {
955957
// It turns out the safety issues with sNaN were overblown! Hooray!
956958
// SAFETY: `u128` is a plain old datatype so we can always transmute from it.

core/src/num/f16.rs

+2
Original file line numberDiff line numberDiff line change
@@ -892,6 +892,7 @@ impl f16 {
892892
#[inline]
893893
#[unstable(feature = "f16", issue = "116909")]
894894
#[must_use = "this returns the result of the operation, without modifying the original"]
895+
#[cfg_attr(not(bootstrap), allow(unnecessary_transmutes))]
895896
pub const fn to_bits(self) -> u16 {
896897
// SAFETY: `u16` is a plain old datatype so we can always transmute to it.
897898
unsafe { mem::transmute(self) }
@@ -938,6 +939,7 @@ impl f16 {
938939
#[inline]
939940
#[must_use]
940941
#[unstable(feature = "f16", issue = "116909")]
942+
#[cfg_attr(not(bootstrap), allow(unnecessary_transmutes))]
941943
pub const fn from_bits(v: u16) -> Self {
942944
// It turns out the safety issues with sNaN were overblown! Hooray!
943945
// SAFETY: `u16` is a plain old datatype so we can always transmute from it.

core/src/num/f32.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -710,8 +710,7 @@ impl f32 {
710710
pub const fn is_sign_negative(self) -> bool {
711711
// IEEE754 says: isSignMinus(x) is true if and only if x has negative sign. isSignMinus
712712
// applies to zeros and NaNs as well.
713-
// SAFETY: This is just transmuting to get the sign bit, it's fine.
714-
unsafe { mem::transmute::<f32, u32>(self) & 0x8000_0000 != 0 }
713+
self.to_bits() & 0x8000_0000 != 0
715714
}
716715

717716
/// Returns the least number greater than `self`.
@@ -1097,6 +1096,7 @@ impl f32 {
10971096
#[stable(feature = "float_bits_conv", since = "1.20.0")]
10981097
#[rustc_const_stable(feature = "const_float_bits_conv", since = "1.83.0")]
10991098
#[inline]
1099+
#[cfg_attr(not(bootstrap), allow(unnecessary_transmutes))]
11001100
pub const fn to_bits(self) -> u32 {
11011101
// SAFETY: `u32` is a plain old datatype so we can always transmute to it.
11021102
unsafe { mem::transmute(self) }
@@ -1142,6 +1142,7 @@ impl f32 {
11421142
#[rustc_const_stable(feature = "const_float_bits_conv", since = "1.83.0")]
11431143
#[must_use]
11441144
#[inline]
1145+
#[cfg_attr(not(bootstrap), allow(unnecessary_transmutes))]
11451146
pub const fn from_bits(v: u32) -> Self {
11461147
// It turns out the safety issues with sNaN were overblown! Hooray!
11471148
// SAFETY: `u32` is a plain old datatype so we can always transmute from it.

core/src/num/f64.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -718,8 +718,7 @@ impl f64 {
718718
pub const fn is_sign_negative(self) -> bool {
719719
// IEEE754 says: isSignMinus(x) is true if and only if x has negative sign. isSignMinus
720720
// applies to zeros and NaNs as well.
721-
// SAFETY: This is just transmuting to get the sign bit, it's fine.
722-
unsafe { mem::transmute::<f64, u64>(self) & Self::SIGN_MASK != 0 }
721+
self.to_bits() & Self::SIGN_MASK != 0
723722
}
724723

725724
#[must_use]
@@ -1095,6 +1094,7 @@ impl f64 {
10951094
without modifying the original"]
10961095
#[stable(feature = "float_bits_conv", since = "1.20.0")]
10971096
#[rustc_const_stable(feature = "const_float_bits_conv", since = "1.83.0")]
1097+
#[cfg_attr(not(bootstrap), allow(unnecessary_transmutes))]
10981098
#[inline]
10991099
pub const fn to_bits(self) -> u64 {
11001100
// SAFETY: `u64` is a plain old datatype so we can always transmute to it.
@@ -1141,6 +1141,7 @@ impl f64 {
11411141
#[rustc_const_stable(feature = "const_float_bits_conv", since = "1.83.0")]
11421142
#[must_use]
11431143
#[inline]
1144+
#[cfg_attr(not(bootstrap), allow(unnecessary_transmutes))]
11441145
pub const fn from_bits(v: u64) -> Self {
11451146
// It turns out the safety issues with sNaN were overblown! Hooray!
11461147
// SAFETY: `u64` is a plain old datatype so we can always transmute from it.

core/src/num/int_macros.rs

+2
Original file line numberDiff line numberDiff line change
@@ -3675,6 +3675,7 @@ macro_rules! int_impl {
36753675
/// ```
36763676
#[stable(feature = "int_to_from_bytes", since = "1.32.0")]
36773677
#[rustc_const_stable(feature = "const_int_conversion", since = "1.44.0")]
3678+
#[cfg_attr(not(bootstrap), allow(unnecessary_transmutes))]
36783679
// SAFETY: const sound because integers are plain old datatypes so we can always
36793680
// transmute them to arrays of bytes
36803681
#[must_use = "this returns the result of the operation, \
@@ -3778,6 +3779,7 @@ macro_rules! int_impl {
37783779
/// ```
37793780
#[stable(feature = "int_to_from_bytes", since = "1.32.0")]
37803781
#[rustc_const_stable(feature = "const_int_conversion", since = "1.44.0")]
3782+
#[cfg_attr(not(bootstrap), allow(unnecessary_transmutes))]
37813783
#[must_use]
37823784
// SAFETY: const sound because integers are plain old datatypes so we can always
37833785
// transmute to them

core/src/num/uint_macros.rs

+2
Original file line numberDiff line numberDiff line change
@@ -3523,6 +3523,7 @@ macro_rules! uint_impl {
35233523
#[rustc_const_stable(feature = "const_int_conversion", since = "1.44.0")]
35243524
#[must_use = "this returns the result of the operation, \
35253525
without modifying the original"]
3526+
#[cfg_attr(not(bootstrap), allow(unnecessary_transmutes))]
35263527
// SAFETY: const sound because integers are plain old datatypes so we can always
35273528
// transmute them to arrays of bytes
35283529
#[inline]
@@ -3624,6 +3625,7 @@ macro_rules! uint_impl {
36243625
/// ```
36253626
#[stable(feature = "int_to_from_bytes", since = "1.32.0")]
36263627
#[rustc_const_stable(feature = "const_int_conversion", since = "1.44.0")]
3628+
#[cfg_attr(not(bootstrap), allow(unnecessary_transmutes))]
36273629
#[must_use]
36283630
// SAFETY: const sound because integers are plain old datatypes so we can always
36293631
// transmute to them

stdarch

+1-1
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
Subproject commit 4666c7376f25a265c74535585d622da3da6dfeb1
1+
Subproject commit 1245618ccf5b2df7ab1ebb0279b9f3f726670161

0 commit comments

Comments
 (0)