about summary refs log tree commit diff
diff options
context:
space:
mode:
authoroli <github35764891676564198441@oli-obk.de>2020-10-29 10:15:54 +0000
committeroli <github35764891676564198441@oli-obk.de>2020-11-04 10:09:10 +0000
commit02131f4dcd0c85f6b3cc7e8d6a5845a6bdd30ff5 (patch)
tree47b692e95cdc33620c4b6431748e020e3b00ddb9
parented7a4adeb326c9957b4a2514a69cbae4276ab028 (diff)
downloadrust-02131f4dcd0c85f6b3cc7e8d6a5845a6bdd30ff5.tar.gz
rust-02131f4dcd0c85f6b3cc7e8d6a5845a6bdd30ff5.zip
Use packed struct instead of manually packing into an array
-rw-r--r--compiler/rustc_middle/src/ty/consts/int.rs67
-rw-r--r--compiler/rustc_middle/src/ty/print/pretty.rs8
-rw-r--r--src/test/ui/symbol-names/impl1.rs4
3 files changed, 41 insertions, 38 deletions
diff --git a/compiler/rustc_middle/src/ty/consts/int.rs b/compiler/rustc_middle/src/ty/consts/int.rs
index cd6c86916d0..6b8e9edc13c 100644
--- a/compiler/rustc_middle/src/ty/consts/int.rs
+++ b/compiler/rustc_middle/src/ty/consts/int.rs
@@ -2,7 +2,6 @@ use crate::mir::interpret::{sign_extend, truncate, InterpErrorInfo, InterpResult
 use crate::throw_ub;
 use rustc_apfloat::ieee::{Double, Single};
 use rustc_apfloat::Float;
-use rustc_macros::HashStable;
 use rustc_serialize::{Decodable, Decoder, Encodable, Encoder};
 use rustc_target::abi::{Size, TargetDataLayout};
 use std::convert::{TryFrom, TryInto};
@@ -29,7 +28,7 @@ impl std::fmt::Debug for ConstInt {
     fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
         let Self { int, signed, is_ptr_sized_integral } = *self;
         let size = int.size().bytes();
-        let raw = int.data();
+        let raw = int.data;
         if signed {
             let bit_size = size * 8;
             let min = 1u128 << (bit_size - 1);
@@ -116,41 +115,46 @@ impl std::fmt::Debug for ConstInt {
 
 // FIXME: reuse in `super::int::ConstInt` and `Scalar::Bits`
 /// The raw bytes of a simple value.
+///
+/// This is a packed struct in order to allow this type to be optimally embedded in enums
+/// (like Scalar).
 #[derive(Clone, Copy, Eq, PartialEq, Ord, PartialOrd, Hash)]
-#[derive(HashStable)]
+#[repr(packed)]
 pub struct ScalarInt {
     /// The first `size` bytes of `data` are the value.
     /// Do not try to read less or more bytes than that. The remaining bytes must be 0.
-    ///
-    /// This is an array in order to allow this type to be optimally embedded in enums
-    /// (like Scalar).
-    bytes: [u8; 16],
+    data: u128,
     size: u8,
 }
 
+// Cannot derive these, as the derives take references to the fields, and we
+// can't take references to fields of packed structs.
+impl<CTX> crate::ty::HashStable<CTX> for ScalarInt {
+    fn hash_stable(&self, hcx: &mut CTX, hasher: &mut crate::ty::StableHasher) {
+        { self.data }.hash_stable(hcx, hasher);
+        self.size.hash_stable(hcx, hasher);
+    }
+}
+
 impl<S: Encoder> Encodable<S> for ScalarInt {
     fn encode(&self, s: &mut S) -> Result<(), S::Error> {
-        s.emit_u128(self.data())?;
+        s.emit_u128(self.data)?;
         s.emit_u8(self.size)
     }
 }
 
 impl<D: Decoder> Decodable<D> for ScalarInt {
     fn decode(d: &mut D) -> Result<ScalarInt, D::Error> {
-        Ok(ScalarInt { bytes: d.read_u128()?.to_ne_bytes(), size: d.read_u8()? })
+        Ok(ScalarInt { data: d.read_u128()?, size: d.read_u8()? })
     }
 }
 
 impl ScalarInt {
-    pub const TRUE: ScalarInt = ScalarInt { bytes: 1_u128.to_ne_bytes(), size: 1 };
+    pub const TRUE: ScalarInt = ScalarInt { data: 1_u128, size: 1 };
 
-    pub const FALSE: ScalarInt = ScalarInt { bytes: 0_u128.to_ne_bytes(), size: 1 };
+    pub const FALSE: ScalarInt = ScalarInt { data: 0_u128, size: 1 };
 
-    pub const ZST: ScalarInt = ScalarInt { bytes: 0_u128.to_ne_bytes(), size: 0 };
-
-    fn data(self) -> u128 {
-        u128::from_ne_bytes(self.bytes)
-    }
+    pub const ZST: ScalarInt = ScalarInt { data: 0_u128, size: 0 };
 
     #[inline]
     pub fn size(self) -> Size {
@@ -164,10 +168,10 @@ impl ScalarInt {
     #[inline(always)]
     fn check_data(self) {
         debug_assert_eq!(
-            truncate(self.data(), self.size()),
-            self.data(),
+            truncate(self.data, self.size()),
+            { self.data },
             "Scalar value {:#x} exceeds size of {} bytes",
-            self.data(),
+            { self.data },
             self.size
         );
     }
@@ -179,7 +183,7 @@ impl ScalarInt {
 
     #[inline]
     pub fn null(size: Size) -> Self {
-        Self { bytes: [0; 16], size: size.bytes() as u8 }
+        Self { data: 0, size: size.bytes() as u8 }
     }
 
     pub(crate) fn ptr_sized_op<'tcx>(
@@ -188,17 +192,14 @@ impl ScalarInt {
         f_int: impl FnOnce(u64) -> InterpResult<'tcx, u64>,
     ) -> InterpResult<'tcx, Self> {
         assert_eq!(u64::from(self.size), dl.pointer_size.bytes());
-        Ok(Self {
-            bytes: u128::from(f_int(u64::try_from(self.data()).unwrap())?).to_ne_bytes(),
-            size: self.size,
-        })
+        Ok(Self { data: u128::from(f_int(u64::try_from(self.data).unwrap())?), size: self.size })
     }
 
     #[inline]
     pub fn try_from_uint(i: impl Into<u128>, size: Size) -> Option<Self> {
         let data = i.into();
         if truncate(data, size) == data {
-            Some(Self { bytes: data.to_ne_bytes(), size: size.bytes() as u8 })
+            Some(Self { data, size: size.bytes() as u8 })
         } else {
             None
         }
@@ -210,7 +211,7 @@ impl ScalarInt {
         // `into` performed sign extension, we have to truncate
         let truncated = truncate(i as u128, size);
         if sign_extend(truncated, size) as i128 == i {
-            Some(Self { bytes: truncated.to_ne_bytes(), size: size.bytes() as u8 })
+            Some(Self { data: truncated, size: size.bytes() as u8 })
         } else {
             None
         }
@@ -221,7 +222,7 @@ impl ScalarInt {
         assert_ne!(target_size.bytes(), 0, "you should never look at the bits of a ZST");
         assert_eq!(target_size.bytes(), u64::from(self.size));
         self.check_data();
-        self.data()
+        self.data
     }
 
     #[inline]
@@ -234,7 +235,7 @@ impl ScalarInt {
             });
         }
         self.check_data();
-        Ok(self.data())
+        Ok(self.data)
     }
 }
 
@@ -245,7 +246,7 @@ macro_rules! from {
                 #[inline]
                 fn from(u: $ty) -> Self {
                     Self {
-                        bytes: u128::from(u).to_ne_bytes(),
+                        data: u128::from(u),
                         size: std::mem::size_of::<$ty>() as u8,
                     }
                 }
@@ -274,7 +275,7 @@ try_from!(u8, u16, u32, u64, u128);
 impl From<char> for ScalarInt {
     #[inline]
     fn from(c: char) -> Self {
-        Self { bytes: (c as u128).to_ne_bytes(), size: std::mem::size_of::<char>() as u8 }
+        Self { data: c as u128, size: std::mem::size_of::<char>() as u8 }
     }
 }
 
@@ -291,7 +292,7 @@ impl From<Single> for ScalarInt {
     #[inline]
     fn from(f: Single) -> Self {
         // We trust apfloat to give us properly truncated data.
-        Self { bytes: f.to_bits().to_ne_bytes(), size: 4 }
+        Self { data: f.to_bits(), size: 4 }
     }
 }
 
@@ -307,7 +308,7 @@ impl From<Double> for ScalarInt {
     #[inline]
     fn from(f: Double) -> Self {
         // We trust apfloat to give us properly truncated data.
-        Self { bytes: f.to_bits().to_ne_bytes(), size: 8 }
+        Self { data: f.to_bits(), size: 8 }
     }
 }
 
@@ -335,6 +336,6 @@ impl fmt::LowerHex for ScalarInt {
         self.check_data();
         // Format as hex number wide enough to fit any value of the given `size`.
         // So data=20, size=1 will be "0x14", but with size=4 it'll be "0x00000014".
-        write!(f, "{:01$x}", self.data(), self.size as usize * 2)
+        write!(f, "{:01$x}", { self.data }, self.size as usize * 2)
     }
 }
diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs
index f972a4cc1ac..27ba6c9d49c 100644
--- a/compiler/rustc_middle/src/ty/print/pretty.rs
+++ b/compiler/rustc_middle/src/ty/print/pretty.rs
@@ -982,8 +982,8 @@ pub trait PrettyPrinter<'tcx>:
                 None => p!("<dangling pointer>"),
             },
             // Bool
-            (Scalar::Raw(ScalarInt::FALSE), ty::Bool) => p!("false"),
-            (Scalar::Raw(ScalarInt::TRUE), ty::Bool) => p!("true"),
+            (Scalar::Raw(int), ty::Bool) if int == ScalarInt::FALSE => p!("false"),
+            (Scalar::Raw(int), ty::Bool) if int == ScalarInt::TRUE => p!("true"),
             // Float
             (Scalar::Raw(int), ty::Float(ast::FloatTy::F32)) => {
                 p!(write("{}f32", Single::try_from(int).unwrap()))
@@ -1025,7 +1025,9 @@ pub trait PrettyPrinter<'tcx>:
                 )?;
             }
             // For function type zsts just printing the path is enough
-            (Scalar::Raw(ScalarInt::ZST), ty::FnDef(d, s)) => p!(print_value_path(*d, s)),
+            (Scalar::Raw(int), ty::FnDef(d, s)) if int == ScalarInt::ZST => {
+                p!(print_value_path(*d, s))
+            }
             // Nontrivial types with scalar bit representation
             (Scalar::Raw(int), _) => {
                 let print = |mut this: Self| {
diff --git a/src/test/ui/symbol-names/impl1.rs b/src/test/ui/symbol-names/impl1.rs
index ff4a8b1ad0a..1ada54cc102 100644
--- a/src/test/ui/symbol-names/impl1.rs
+++ b/src/test/ui/symbol-names/impl1.rs
@@ -3,8 +3,8 @@
 // revisions: legacy v0
 //[legacy]compile-flags: -Z symbol-mangling-version=legacy
     //[v0]compile-flags: -Z symbol-mangling-version=v0
-//[legacy]normalize-stderr-32bit: "h30edc7aa010c48ae" -> "SYMBOL_HASH"
-//[legacy]normalize-stderr-64bit: "h56362331c4f93d19" -> "SYMBOL_HASH"
+//[legacy]normalize-stderr-32bit: "hee444285569b39c2" -> "SYMBOL_HASH"
+//[legacy]normalize-stderr-64bit: "h310ea0259fc3d32d" -> "SYMBOL_HASH"
 
 #![feature(optin_builtin_traits, rustc_attrs)]
 #![allow(dead_code)]