Add a macro for defaulted enum encoding, use it for hir::Defaultness and deduplicate the logic for other similar enums
This commit is contained in:
parent
c489b92845
commit
b93f2d8b26
4 changed files with 68 additions and 99 deletions
|
|
@ -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,
|
||||
}
|
||||
|
||||
|
|
@ -4231,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,
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1753,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);
|
||||
|
|
@ -2155,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(
|
||||
|
|
|
|||
|
|
@ -403,6 +403,7 @@ define_tables! {
|
|||
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>>,
|
||||
|
|
@ -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>>,
|
||||
|
|
|
|||
|
|
@ -25,33 +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 {
|
||||
hir::Constness::Const => false,
|
||||
hir::Constness::NotConst => true,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl IsDefault for hir::Safety {
|
||||
fn is_default(&self) -> bool {
|
||||
match self {
|
||||
hir::Safety::Safe => false,
|
||||
hir::Safety::Unsafe => true,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl IsDefault for u32 {
|
||||
fn is_default(&self) -> bool {
|
||||
*self == 0
|
||||
|
|
@ -139,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())|+))
|
||||
|
|
@ -205,7 +215,7 @@ fixed_size_enum! {
|
|||
}
|
||||
}
|
||||
|
||||
fixed_size_enum! {
|
||||
defaulted_enum! {
|
||||
hir::Defaultness {
|
||||
( Final )
|
||||
( Default { has_value: false } )
|
||||
|
|
@ -213,6 +223,27 @@ fixed_size_enum! {
|
|||
}
|
||||
}
|
||||
|
||||
defaulted_enum! {
|
||||
ty::Asyncness {
|
||||
( No )
|
||||
( Yes )
|
||||
}
|
||||
}
|
||||
|
||||
defaulted_enum! {
|
||||
hir::Constness {
|
||||
( Const )
|
||||
( NotConst )
|
||||
}
|
||||
}
|
||||
|
||||
defaulted_enum! {
|
||||
hir::Safety {
|
||||
( Unsafe )
|
||||
( Safe )
|
||||
}
|
||||
}
|
||||
|
||||
fixed_size_enum! {
|
||||
hir::CoroutineKind {
|
||||
( Coroutine(hir::Movability::Movable) )
|
||||
|
|
@ -301,72 +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,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl FixedSizeEncoding for hir::Safety {
|
||||
type ByteArray = [u8; 1];
|
||||
|
||||
#[inline]
|
||||
fn from_bytes(b: &[u8; 1]) -> Self {
|
||||
match b[0] {
|
||||
0 => hir::Safety::Unsafe,
|
||||
1 => hir::Safety::Safe,
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn write_to_bytes(self, b: &mut [u8; 1]) {
|
||||
debug_assert!(!self.is_default());
|
||||
b[0] = match self {
|
||||
hir::Safety::Unsafe => 0,
|
||||
hir::Safety::Safe => 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`.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue