Skip to content
This repository was archived by the owner on May 28, 2025. It is now read-only.

Commit 02131f4

Browse files
committed
Use packed struct instead of manually packing into an array
1 parent ed7a4ad commit 02131f4

File tree

3 files changed

+41
-38
lines changed

3 files changed

+41
-38
lines changed

compiler/rustc_middle/src/ty/consts/int.rs

Lines changed: 34 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ use crate::mir::interpret::{sign_extend, truncate, InterpErrorInfo, InterpResult
22
use crate::throw_ub;
33
use rustc_apfloat::ieee::{Double, Single};
44
use rustc_apfloat::Float;
5-
use rustc_macros::HashStable;
65
use rustc_serialize::{Decodable, Decoder, Encodable, Encoder};
76
use rustc_target::abi::{Size, TargetDataLayout};
87
use std::convert::{TryFrom, TryInto};
@@ -29,7 +28,7 @@ impl std::fmt::Debug for ConstInt {
2928
fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
3029
let Self { int, signed, is_ptr_sized_integral } = *self;
3130
let size = int.size().bytes();
32-
let raw = int.data();
31+
let raw = int.data;
3332
if signed {
3433
let bit_size = size * 8;
3534
let min = 1u128 << (bit_size - 1);
@@ -116,41 +115,46 @@ impl std::fmt::Debug for ConstInt {
116115

117116
// FIXME: reuse in `super::int::ConstInt` and `Scalar::Bits`
118117
/// The raw bytes of a simple value.
118+
///
119+
/// This is a packed struct in order to allow this type to be optimally embedded in enums
120+
/// (like Scalar).
119121
#[derive(Clone, Copy, Eq, PartialEq, Ord, PartialOrd, Hash)]
120-
#[derive(HashStable)]
122+
#[repr(packed)]
121123
pub struct ScalarInt {
122124
/// The first `size` bytes of `data` are the value.
123125
/// Do not try to read less or more bytes than that. The remaining bytes must be 0.
124-
///
125-
/// This is an array in order to allow this type to be optimally embedded in enums
126-
/// (like Scalar).
127-
bytes: [u8; 16],
126+
data: u128,
128127
size: u8,
129128
}
130129

130+
// Cannot derive these, as the derives take references to the fields, and we
131+
// can't take references to fields of packed structs.
132+
impl<CTX> crate::ty::HashStable<CTX> for ScalarInt {
133+
fn hash_stable(&self, hcx: &mut CTX, hasher: &mut crate::ty::StableHasher) {
134+
{ self.data }.hash_stable(hcx, hasher);
135+
self.size.hash_stable(hcx, hasher);
136+
}
137+
}
138+
131139
impl<S: Encoder> Encodable<S> for ScalarInt {
132140
fn encode(&self, s: &mut S) -> Result<(), S::Error> {
133-
s.emit_u128(self.data())?;
141+
s.emit_u128(self.data)?;
134142
s.emit_u8(self.size)
135143
}
136144
}
137145

138146
impl<D: Decoder> Decodable<D> for ScalarInt {
139147
fn decode(d: &mut D) -> Result<ScalarInt, D::Error> {
140-
Ok(ScalarInt { bytes: d.read_u128()?.to_ne_bytes(), size: d.read_u8()? })
148+
Ok(ScalarInt { data: d.read_u128()?, size: d.read_u8()? })
141149
}
142150
}
143151

144152
impl ScalarInt {
145-
pub const TRUE: ScalarInt = ScalarInt { bytes: 1_u128.to_ne_bytes(), size: 1 };
153+
pub const TRUE: ScalarInt = ScalarInt { data: 1_u128, size: 1 };
146154

147-
pub const FALSE: ScalarInt = ScalarInt { bytes: 0_u128.to_ne_bytes(), size: 1 };
155+
pub const FALSE: ScalarInt = ScalarInt { data: 0_u128, size: 1 };
148156

149-
pub const ZST: ScalarInt = ScalarInt { bytes: 0_u128.to_ne_bytes(), size: 0 };
150-
151-
fn data(self) -> u128 {
152-
u128::from_ne_bytes(self.bytes)
153-
}
157+
pub const ZST: ScalarInt = ScalarInt { data: 0_u128, size: 0 };
154158

155159
#[inline]
156160
pub fn size(self) -> Size {
@@ -164,10 +168,10 @@ impl ScalarInt {
164168
#[inline(always)]
165169
fn check_data(self) {
166170
debug_assert_eq!(
167-
truncate(self.data(), self.size()),
168-
self.data(),
171+
truncate(self.data, self.size()),
172+
{ self.data },
169173
"Scalar value {:#x} exceeds size of {} bytes",
170-
self.data(),
174+
{ self.data },
171175
self.size
172176
);
173177
}
@@ -179,7 +183,7 @@ impl ScalarInt {
179183

180184
#[inline]
181185
pub fn null(size: Size) -> Self {
182-
Self { bytes: [0; 16], size: size.bytes() as u8 }
186+
Self { data: 0, size: size.bytes() as u8 }
183187
}
184188

185189
pub(crate) fn ptr_sized_op<'tcx>(
@@ -188,17 +192,14 @@ impl ScalarInt {
188192
f_int: impl FnOnce(u64) -> InterpResult<'tcx, u64>,
189193
) -> InterpResult<'tcx, Self> {
190194
assert_eq!(u64::from(self.size), dl.pointer_size.bytes());
191-
Ok(Self {
192-
bytes: u128::from(f_int(u64::try_from(self.data()).unwrap())?).to_ne_bytes(),
193-
size: self.size,
194-
})
195+
Ok(Self { data: u128::from(f_int(u64::try_from(self.data).unwrap())?), size: self.size })
195196
}
196197

197198
#[inline]
198199
pub fn try_from_uint(i: impl Into<u128>, size: Size) -> Option<Self> {
199200
let data = i.into();
200201
if truncate(data, size) == data {
201-
Some(Self { bytes: data.to_ne_bytes(), size: size.bytes() as u8 })
202+
Some(Self { data, size: size.bytes() as u8 })
202203
} else {
203204
None
204205
}
@@ -210,7 +211,7 @@ impl ScalarInt {
210211
// `into` performed sign extension, we have to truncate
211212
let truncated = truncate(i as u128, size);
212213
if sign_extend(truncated, size) as i128 == i {
213-
Some(Self { bytes: truncated.to_ne_bytes(), size: size.bytes() as u8 })
214+
Some(Self { data: truncated, size: size.bytes() as u8 })
214215
} else {
215216
None
216217
}
@@ -221,7 +222,7 @@ impl ScalarInt {
221222
assert_ne!(target_size.bytes(), 0, "you should never look at the bits of a ZST");
222223
assert_eq!(target_size.bytes(), u64::from(self.size));
223224
self.check_data();
224-
self.data()
225+
self.data
225226
}
226227

227228
#[inline]
@@ -234,7 +235,7 @@ impl ScalarInt {
234235
});
235236
}
236237
self.check_data();
237-
Ok(self.data())
238+
Ok(self.data)
238239
}
239240
}
240241

@@ -245,7 +246,7 @@ macro_rules! from {
245246
#[inline]
246247
fn from(u: $ty) -> Self {
247248
Self {
248-
bytes: u128::from(u).to_ne_bytes(),
249+
data: u128::from(u),
249250
size: std::mem::size_of::<$ty>() as u8,
250251
}
251252
}
@@ -274,7 +275,7 @@ try_from!(u8, u16, u32, u64, u128);
274275
impl From<char> for ScalarInt {
275276
#[inline]
276277
fn from(c: char) -> Self {
277-
Self { bytes: (c as u128).to_ne_bytes(), size: std::mem::size_of::<char>() as u8 }
278+
Self { data: c as u128, size: std::mem::size_of::<char>() as u8 }
278279
}
279280
}
280281

@@ -291,7 +292,7 @@ impl From<Single> for ScalarInt {
291292
#[inline]
292293
fn from(f: Single) -> Self {
293294
// We trust apfloat to give us properly truncated data.
294-
Self { bytes: f.to_bits().to_ne_bytes(), size: 4 }
295+
Self { data: f.to_bits(), size: 4 }
295296
}
296297
}
297298

@@ -307,7 +308,7 @@ impl From<Double> for ScalarInt {
307308
#[inline]
308309
fn from(f: Double) -> Self {
309310
// We trust apfloat to give us properly truncated data.
310-
Self { bytes: f.to_bits().to_ne_bytes(), size: 8 }
311+
Self { data: f.to_bits(), size: 8 }
311312
}
312313
}
313314

@@ -335,6 +336,6 @@ impl fmt::LowerHex for ScalarInt {
335336
self.check_data();
336337
// Format as hex number wide enough to fit any value of the given `size`.
337338
// So data=20, size=1 will be "0x14", but with size=4 it'll be "0x00000014".
338-
write!(f, "{:01$x}", self.data(), self.size as usize * 2)
339+
write!(f, "{:01$x}", { self.data }, self.size as usize * 2)
339340
}
340341
}

compiler/rustc_middle/src/ty/print/pretty.rs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -982,8 +982,8 @@ pub trait PrettyPrinter<'tcx>:
982982
None => p!("<dangling pointer>"),
983983
},
984984
// Bool
985-
(Scalar::Raw(ScalarInt::FALSE), ty::Bool) => p!("false"),
986-
(Scalar::Raw(ScalarInt::TRUE), ty::Bool) => p!("true"),
985+
(Scalar::Raw(int), ty::Bool) if int == ScalarInt::FALSE => p!("false"),
986+
(Scalar::Raw(int), ty::Bool) if int == ScalarInt::TRUE => p!("true"),
987987
// Float
988988
(Scalar::Raw(int), ty::Float(ast::FloatTy::F32)) => {
989989
p!(write("{}f32", Single::try_from(int).unwrap()))
@@ -1025,7 +1025,9 @@ pub trait PrettyPrinter<'tcx>:
10251025
)?;
10261026
}
10271027
// For function type zsts just printing the path is enough
1028-
(Scalar::Raw(ScalarInt::ZST), ty::FnDef(d, s)) => p!(print_value_path(*d, s)),
1028+
(Scalar::Raw(int), ty::FnDef(d, s)) if int == ScalarInt::ZST => {
1029+
p!(print_value_path(*d, s))
1030+
}
10291031
// Nontrivial types with scalar bit representation
10301032
(Scalar::Raw(int), _) => {
10311033
let print = |mut this: Self| {

src/test/ui/symbol-names/impl1.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@
33
// revisions: legacy v0
44
//[legacy]compile-flags: -Z symbol-mangling-version=legacy
55
//[v0]compile-flags: -Z symbol-mangling-version=v0
6-
//[legacy]normalize-stderr-32bit: "h30edc7aa010c48ae" -> "SYMBOL_HASH"
7-
//[legacy]normalize-stderr-64bit: "h56362331c4f93d19" -> "SYMBOL_HASH"
6+
//[legacy]normalize-stderr-32bit: "hee444285569b39c2" -> "SYMBOL_HASH"
7+
//[legacy]normalize-stderr-64bit: "h310ea0259fc3d32d" -> "SYMBOL_HASH"
88

99
#![feature(optin_builtin_traits, rustc_attrs)]
1010
#![allow(dead_code)]

0 commit comments

Comments
 (0)