Rollup merge of #69373 - tspiteri:const_int_conversion, r=oli-obk

Stabilize const for integer {to,from}_{be,le,ne}_bytes methods

All of these functions can be implemented simply and naturally as const functions, e.g. `u32::from_le_bytes` can be implemented as
```rust
(bytes[0] as u32)
    | (bytes[1] as u32) << 8
    | (bytes[2] as u32) << 16
    | (bytes[3] as u32) << 24
```
So stabilizing the constness will not expose that internally they are implemented using transmute which is not const in stable.
This commit is contained in:
Mazdak Farrokhzad 2020-03-11 10:36:18 +01:00 committed by GitHub
commit 43079147f4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 48 additions and 19 deletions

View File

@ -130,7 +130,6 @@
#![feature(rtm_target_feature)]
#![feature(f16c_target_feature)]
#![feature(hexagon_target_feature)]
#![feature(const_int_conversion)]
#![feature(const_transmute)]
#![feature(structural_match)]
#![feature(abi_unadjusted)]

View File

@ -2154,7 +2154,7 @@ let bytes = ", $swap_op, stringify!($SelfT), ".to_be_bytes();
assert_eq!(bytes, ", $be_bytes, ");
```"),
#[stable(feature = "int_to_from_bytes", since = "1.32.0")]
#[rustc_const_unstable(feature = "const_int_conversion", issue = "53718")]
#[rustc_const_stable(feature = "const_int_conversion", since = "1.43.0")]
#[inline]
pub const fn to_be_bytes(self) -> [u8; mem::size_of::<Self>()] {
self.to_be().to_ne_bytes()
@ -2174,7 +2174,7 @@ let bytes = ", $swap_op, stringify!($SelfT), ".to_le_bytes();
assert_eq!(bytes, ", $le_bytes, ");
```"),
#[stable(feature = "int_to_from_bytes", since = "1.32.0")]
#[rustc_const_unstable(feature = "const_int_conversion", issue = "53718")]
#[rustc_const_stable(feature = "const_int_conversion", since = "1.43.0")]
#[inline]
pub const fn to_le_bytes(self) -> [u8; mem::size_of::<Self>()] {
self.to_le().to_ne_bytes()
@ -2209,12 +2209,20 @@ assert_eq!(
);
```"),
#[stable(feature = "int_to_from_bytes", since = "1.32.0")]
#[rustc_const_unstable(feature = "const_int_conversion", issue = "53718")]
#[rustc_const_stable(feature = "const_int_conversion", since = "1.43.0")]
// SAFETY: const sound because integers are plain old datatypes so we can always
// transmute them to arrays of bytes
#[allow_internal_unstable(const_fn_union)]
#[inline]
pub const fn to_ne_bytes(self) -> [u8; mem::size_of::<Self>()] {
#[repr(C)]
union Bytes {
val: $SelfT,
bytes: [u8; mem::size_of::<$SelfT>()],
}
// SAFETY: integers are plain old datatypes so we can always transmute them to
// arrays of bytes
unsafe { mem::transmute(self) }
unsafe { Bytes { val: self }.bytes }
}
}
@ -2243,7 +2251,7 @@ fn read_be_", stringify!($SelfT), "(input: &mut &[u8]) -> ", stringify!($SelfT),
}
```"),
#[stable(feature = "int_to_from_bytes", since = "1.32.0")]
#[rustc_const_unstable(feature = "const_int_conversion", issue = "53718")]
#[rustc_const_stable(feature = "const_int_conversion", since = "1.43.0")]
#[inline]
pub const fn from_be_bytes(bytes: [u8; mem::size_of::<Self>()]) -> Self {
Self::from_be(Self::from_ne_bytes(bytes))
@ -2276,7 +2284,7 @@ fn read_le_", stringify!($SelfT), "(input: &mut &[u8]) -> ", stringify!($SelfT),
}
```"),
#[stable(feature = "int_to_from_bytes", since = "1.32.0")]
#[rustc_const_unstable(feature = "const_int_conversion", issue = "53718")]
#[rustc_const_stable(feature = "const_int_conversion", since = "1.43.0")]
#[inline]
pub const fn from_le_bytes(bytes: [u8; mem::size_of::<Self>()]) -> Self {
Self::from_le(Self::from_ne_bytes(bytes))
@ -2319,11 +2327,19 @@ fn read_ne_", stringify!($SelfT), "(input: &mut &[u8]) -> ", stringify!($SelfT),
}
```"),
#[stable(feature = "int_to_from_bytes", since = "1.32.0")]
#[rustc_const_unstable(feature = "const_int_conversion", issue = "53718")]
#[rustc_const_stable(feature = "const_int_conversion", since = "1.43.0")]
// SAFETY: const sound because integers are plain old datatypes so we can always
// transmute to them
#[allow_internal_unstable(const_fn_union)]
#[inline]
pub const fn from_ne_bytes(bytes: [u8; mem::size_of::<Self>()]) -> Self {
#[repr(C)]
union Bytes {
val: $SelfT,
bytes: [u8; mem::size_of::<$SelfT>()],
}
// SAFETY: integers are plain old datatypes so we can always transmute to them
unsafe { mem::transmute(bytes) }
unsafe { Bytes { bytes }.val }
}
}
@ -4099,7 +4115,7 @@ let bytes = ", $swap_op, stringify!($SelfT), ".to_be_bytes();
assert_eq!(bytes, ", $be_bytes, ");
```"),
#[stable(feature = "int_to_from_bytes", since = "1.32.0")]
#[rustc_const_unstable(feature = "const_int_conversion", issue = "53718")]
#[rustc_const_stable(feature = "const_int_conversion", since = "1.43.0")]
#[inline]
pub const fn to_be_bytes(self) -> [u8; mem::size_of::<Self>()] {
self.to_be().to_ne_bytes()
@ -4119,7 +4135,7 @@ let bytes = ", $swap_op, stringify!($SelfT), ".to_le_bytes();
assert_eq!(bytes, ", $le_bytes, ");
```"),
#[stable(feature = "int_to_from_bytes", since = "1.32.0")]
#[rustc_const_unstable(feature = "const_int_conversion", issue = "53718")]
#[rustc_const_stable(feature = "const_int_conversion", since = "1.43.0")]
#[inline]
pub const fn to_le_bytes(self) -> [u8; mem::size_of::<Self>()] {
self.to_le().to_ne_bytes()
@ -4154,12 +4170,20 @@ assert_eq!(
);
```"),
#[stable(feature = "int_to_from_bytes", since = "1.32.0")]
#[rustc_const_unstable(feature = "const_int_conversion", issue = "53718")]
#[rustc_const_stable(feature = "const_int_conversion", since = "1.43.0")]
// SAFETY: const sound because integers are plain old datatypes so we can always
// transmute them to arrays of bytes
#[allow_internal_unstable(const_fn_union)]
#[inline]
pub const fn to_ne_bytes(self) -> [u8; mem::size_of::<Self>()] {
#[repr(C)]
union Bytes {
val: $SelfT,
bytes: [u8; mem::size_of::<$SelfT>()],
}
// SAFETY: integers are plain old datatypes so we can always transmute them to
// arrays of bytes
unsafe { mem::transmute(self) }
unsafe { Bytes { val: self }.bytes }
}
}
@ -4188,7 +4212,7 @@ fn read_be_", stringify!($SelfT), "(input: &mut &[u8]) -> ", stringify!($SelfT),
}
```"),
#[stable(feature = "int_to_from_bytes", since = "1.32.0")]
#[rustc_const_unstable(feature = "const_int_conversion", issue = "53718")]
#[rustc_const_stable(feature = "const_int_conversion", since = "1.43.0")]
#[inline]
pub const fn from_be_bytes(bytes: [u8; mem::size_of::<Self>()]) -> Self {
Self::from_be(Self::from_ne_bytes(bytes))
@ -4221,7 +4245,7 @@ fn read_le_", stringify!($SelfT), "(input: &mut &[u8]) -> ", stringify!($SelfT),
}
```"),
#[stable(feature = "int_to_from_bytes", since = "1.32.0")]
#[rustc_const_unstable(feature = "const_int_conversion", issue = "53718")]
#[rustc_const_stable(feature = "const_int_conversion", since = "1.43.0")]
#[inline]
pub const fn from_le_bytes(bytes: [u8; mem::size_of::<Self>()]) -> Self {
Self::from_le(Self::from_ne_bytes(bytes))
@ -4264,11 +4288,19 @@ fn read_ne_", stringify!($SelfT), "(input: &mut &[u8]) -> ", stringify!($SelfT),
}
```"),
#[stable(feature = "int_to_from_bytes", since = "1.32.0")]
#[rustc_const_unstable(feature = "const_int_conversion", issue = "53718")]
#[rustc_const_stable(feature = "const_int_conversion", since = "1.43.0")]
// SAFETY: const sound because integers are plain old datatypes so we can always
// transmute to them
#[allow_internal_unstable(const_fn_union)]
#[inline]
pub const fn from_ne_bytes(bytes: [u8; mem::size_of::<Self>()]) -> Self {
#[repr(C)]
union Bytes {
val: $SelfT,
bytes: [u8; mem::size_of::<$SelfT>()],
}
// SAFETY: integers are plain old datatypes so we can always transmute to them
unsafe { mem::transmute(bytes) }
unsafe { Bytes { bytes }.val }
}
}

View File

@ -1,7 +1,5 @@
// run-pass
#![feature(const_int_conversion)]
const REVERSE: u32 = 0x12345678_u32.reverse_bits();
const FROM_BE_BYTES: i32 = i32::from_be_bytes([0x12, 0x34, 0x56, 0x78]);
const FROM_LE_BYTES: i32 = i32::from_le_bytes([0x12, 0x34, 0x56, 0x78]);