From 7f7b5514a424a49c16a2c2b2833f3f959c2b077c Mon Sep 17 00:00:00 2001 From: Andre Bogus Date: Fri, 17 Dec 2021 00:44:50 +0100 Subject: [PATCH] Make `DefId` `repr(C)`, optimize big-endian field order --- compiler/rustc_span/src/def_id.rs | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_span/src/def_id.rs b/compiler/rustc_span/src/def_id.rs index 64c2ef30b4d..7d854f50ae7 100644 --- a/compiler/rustc_span/src/def_id.rs +++ b/compiler/rustc_span/src/def_id.rs @@ -221,10 +221,17 @@ impl Decodable for DefIndex { #[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Copy)] // On below-64 bit systems we can simply use the derived `Hash` impl #[cfg_attr(not(target_pointer_width = "64"), derive(Hash))] -// Note that the order is essential here, see below why +#[repr(C)] +// We guarantee field order. Note that the order is essential here, see below why. pub struct DefId { + // cfg-ing the order of fields so that the `DefIndex` which is high entropy always ends up in + // the lower bits no matter the endianness. This allows the compiler to turn that `Hash` impl + // into a direct call to 'u64::hash(_)`. + #[cfg(not(all(target_pointer_width = "64", target_endian = "big")))] pub index: DefIndex, pub krate: CrateNum, + #[cfg(all(target_pointer_width = "64", target_endian = "big"))] + pub index: DefIndex, } // On 64-bit systems, we can hash the whole `DefId` as one `u64` instead of two `u32`s. This