Skip to content

Commit

Permalink
Rollup merge of rust-lang#69373 - tspiteri:const_int_conversion, r=ol…
Browse files Browse the repository at this point in the history
…i-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.
  • Loading branch information
Centril authored Mar 11, 2020
2 parents c6a6a66 + 87f0dc6 commit 7ef49a3
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 19 deletions.
1 change: 0 additions & 1 deletion src/libcore/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)]
Expand Down
64 changes: 48 additions & 16 deletions src/libcore/num/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand All @@ -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()
Expand Down Expand Up @@ -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 }
}
}

Expand Down Expand Up @@ -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))
Expand Down Expand Up @@ -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))
Expand Down Expand Up @@ -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 }
}
}

Expand Down Expand Up @@ -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()
Expand All @@ -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()
Expand Down Expand Up @@ -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 }
}
}

Expand Down Expand Up @@ -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))
Expand Down Expand Up @@ -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))
Expand Down Expand Up @@ -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 }
}
}

Expand Down
2 changes: 0 additions & 2 deletions src/test/ui/consts/const-int-conversion-rpass.rs
Original file line number Diff line number Diff line change
@@ -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]);
Expand Down

0 comments on commit 7ef49a3

Please sign in to comment.