Auto merge of #149140 - oli-obk:more-encoder-minimization, r=jdonszelmann

More encoder minimizations

follow-up to https://github.com/rust-lang/rust/pull/149054
This commit is contained in:
bors 2025-11-26 11:57:29 +00:00
commit c797096598
5 changed files with 73 additions and 95 deletions

View file

@ -3841,8 +3841,12 @@ impl IsAsync {
}
#[derive(Copy, Clone, PartialEq, Eq, Debug, Encodable, Decodable, HashStable_Generic)]
#[derive(Default)]
pub enum Defaultness {
Default { has_value: bool },
Default {
has_value: bool,
},
#[default]
Final,
}
@ -4186,8 +4190,13 @@ impl<'hir> Item<'hir> {
}
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
#[derive(Encodable, Decodable, HashStable_Generic)]
#[derive(Encodable, Decodable, HashStable_Generic, Default)]
pub enum Safety {
/// This is the default variant, because the compiler messing up
/// metadata encoding and failing to encode a `Safe` flag, means
/// downstream crates think a thing is `Unsafe` instead of silently
/// treating an unsafe thing as safe.
#[default]
Unsafe,
Safe,
}
@ -4226,8 +4235,8 @@ impl fmt::Display for Safety {
#[derive(Copy, Clone, PartialEq, Eq, Debug, Encodable, Decodable, HashStable_Generic)]
#[derive(Default)]
pub enum Constness {
Const,
#[default]
Const,
NotConst,
}

View file

@ -1187,7 +1187,7 @@ impl<'a> CrateMetadataRef<'a> {
}
fn get_safety(self, id: DefIndex) -> Safety {
self.root.tables.safety.get(self, id).unwrap_or_else(|| self.missing("safety", id))
self.root.tables.safety.get(self, id)
}
fn get_default_field(self, id: DefIndex) -> Option<DefId> {

View file

@ -1524,17 +1524,11 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
}
if should_encode_constness(def_kind) {
let constness = self.tcx.constness(def_id);
match constness {
hir::Constness::Const => self.tables.constness.set(def_id.index, constness),
hir::Constness::NotConst => {}
}
self.tables.constness.set(def_id.index, constness);
}
if let DefKind::Fn | DefKind::AssocFn = def_kind {
let asyncness = tcx.asyncness(def_id);
match asyncness {
ty::Asyncness::Yes => self.tables.asyncness.set(def_id.index, asyncness),
ty::Asyncness::No => {}
}
self.tables.asyncness.set(def_id.index, asyncness);
record_array!(self.tables.fn_arg_idents[def_id] <- tcx.fn_arg_idents(def_id));
}
if let Some(name) = tcx.intrinsic(def_id) {
@ -1697,7 +1691,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
}));
for field in &variant.fields {
self.tables.safety.set_some(field.did.index, field.safety);
self.tables.safety.set(field.did.index, field.safety);
}
if let Some((CtorKind::Fn, ctor_def_id)) = variant.ctor {
@ -1759,7 +1753,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
let item = tcx.associated_item(def_id);
if matches!(item.container, AssocContainer::Trait | AssocContainer::TraitImpl(_)) {
self.tables.defaultness.set_some(def_id.index, item.defaultness(tcx));
self.tables.defaultness.set(def_id.index, item.defaultness(tcx));
}
record!(self.tables.assoc_container[def_id] <- item.container);
@ -2161,7 +2155,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
let header = tcx.impl_trait_header(def_id);
record!(self.tables.impl_trait_header[def_id] <- header);
self.tables.defaultness.set_some(def_id.index, tcx.defaultness(def_id));
self.tables.defaultness.set(def_id.index, tcx.defaultness(def_id));
let trait_ref = header.trait_ref.instantiate_identity();
let simplified_self_ty = fast_reject::simplify_type(

View file

@ -402,6 +402,8 @@ define_tables! {
cross_crate_inlinable: Table<DefIndex, bool>,
asyncness: Table<DefIndex, ty::Asyncness>,
constness: Table<DefIndex, hir::Constness>,
safety: Table<DefIndex, hir::Safety>,
defaultness: Table<DefIndex, hir::Defaultness>,
- optional:
attributes: Table<DefIndex, LazyArray<hir::Attribute>>,
@ -411,7 +413,6 @@ define_tables! {
associated_item_or_field_def_ids: Table<DefIndex, LazyArray<DefIndex>>,
def_kind: Table<DefIndex, DefKind>,
visibility: Table<DefIndex, LazyValue<ty::Visibility<DefIndex>>>,
safety: Table<DefIndex, hir::Safety>,
def_span: Table<DefIndex, LazyValue<Span>>,
def_ident_span: Table<DefIndex, LazyValue<Span>>,
lookup_stability: Table<DefIndex, LazyValue<hir::Stability>>,
@ -436,7 +437,6 @@ define_tables! {
thir_abstract_const: Table<DefIndex, LazyValue<ty::EarlyBinder<'static, ty::Const<'static>>>>,
impl_parent: Table<DefIndex, RawDefId>,
const_conditions: Table<DefIndex, LazyValue<ty::ConstConditions<'static>>>,
defaultness: Table<DefIndex, hir::Defaultness>,
// FIXME(eddyb) perhaps compute this on the fly if cheap enough?
coerce_unsized_info: Table<DefIndex, LazyValue<ty::adjustment::CoerceUnsizedInfo>>,
mir_const_qualif: Table<DefIndex, LazyValue<mir::ConstQualifs>>,

View file

@ -25,24 +25,6 @@ impl IsDefault for bool {
}
}
impl IsDefault for ty::Asyncness {
fn is_default(&self) -> bool {
match self {
ty::Asyncness::Yes => false,
ty::Asyncness::No => true,
}
}
}
impl IsDefault for hir::Constness {
fn is_default(&self) -> bool {
match self {
rustc_hir::Constness::Const => false,
rustc_hir::Constness::NotConst => true,
}
}
}
impl IsDefault for u32 {
fn is_default(&self) -> bool {
*self == 0
@ -130,6 +112,43 @@ macro_rules! fixed_size_enum {
}
}
macro_rules! defaulted_enum {
($ty:ty { $(($($pat:tt)*))* } $( unreachable { $(($($upat:tt)*))+ } )?) => {
impl FixedSizeEncoding for $ty {
type ByteArray = [u8; 1];
#[inline]
fn from_bytes(b: &[u8; 1]) -> Self {
use $ty::*;
let val = match b[0] {
$(${index()} => $($pat)*,)*
_ => panic!("Unexpected {} code: {:?}", stringify!($ty), b[0]),
};
// Make sure the first entry is always the default value,
// and none of the other values are the default value
debug_assert_ne!((b[0] != 0), IsDefault::is_default(&val));
val
}
#[inline]
fn write_to_bytes(self, b: &mut [u8; 1]) {
debug_assert!(!IsDefault::is_default(&self));
use $ty::*;
b[0] = match self {
$($($pat)* => ${index()},)*
$($($($upat)*)|+ => unreachable!(),)?
};
debug_assert_ne!(b[0], 0);
}
}
impl IsDefault for $ty {
fn is_default(&self) -> bool {
<$ty as Default>::default() == *self
}
}
}
}
// Workaround; need const traits to construct bitflags in a const
macro_rules! const_macro_kinds {
($($name:ident),+$(,)?) => (MacroKinds::from_bits_truncate($(MacroKinds::$name.bits())|+))
@ -196,14 +215,7 @@ fixed_size_enum! {
}
}
fixed_size_enum! {
hir::Constness {
( NotConst )
( Const )
}
}
fixed_size_enum! {
defaulted_enum! {
hir::Defaultness {
( Final )
( Default { has_value: false } )
@ -211,17 +223,24 @@ fixed_size_enum! {
}
}
fixed_size_enum! {
hir::Safety {
( Unsafe )
( Safe )
defaulted_enum! {
ty::Asyncness {
( No )
( Yes )
}
}
fixed_size_enum! {
ty::Asyncness {
( Yes )
( No )
defaulted_enum! {
hir::Constness {
( Const )
( NotConst )
}
}
defaulted_enum! {
hir::Safety {
( Unsafe )
( Safe )
}
}
@ -313,50 +332,6 @@ impl FixedSizeEncoding for bool {
}
}
impl FixedSizeEncoding for ty::Asyncness {
type ByteArray = [u8; 1];
#[inline]
fn from_bytes(b: &[u8; 1]) -> Self {
match b[0] {
0 => ty::Asyncness::No,
1 => ty::Asyncness::Yes,
_ => unreachable!(),
}
}
#[inline]
fn write_to_bytes(self, b: &mut [u8; 1]) {
debug_assert!(!self.is_default());
b[0] = match self {
ty::Asyncness::No => 0,
ty::Asyncness::Yes => 1,
}
}
}
impl FixedSizeEncoding for hir::Constness {
type ByteArray = [u8; 1];
#[inline]
fn from_bytes(b: &[u8; 1]) -> Self {
match b[0] {
0 => hir::Constness::NotConst,
1 => hir::Constness::Const,
_ => unreachable!(),
}
}
#[inline]
fn write_to_bytes(self, b: &mut [u8; 1]) {
debug_assert!(!self.is_default());
b[0] = match self {
hir::Constness::NotConst => 0,
hir::Constness::Const => 1,
}
}
}
// NOTE(eddyb) there could be an impl for `usize`, which would enable a more
// generic `LazyValue<T>` impl, but in the general case we might not need / want
// to fit every `usize` in `u32`.