Skip to content

Commit b93f2d8

Browse files
committed
Add a macro for defaulted enum encoding, use it for hir::Defaultness and deduplicate the logic for other similar enums
1 parent c489b92 commit b93f2d8

File tree

4 files changed

+68
-99
lines changed

4 files changed

+68
-99
lines changed

compiler/rustc_hir/src/hir.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3841,8 +3841,12 @@ impl IsAsync {
38413841
}
38423842

38433843
#[derive(Copy, Clone, PartialEq, Eq, Debug, Encodable, Decodable, HashStable_Generic)]
3844+
#[derive(Default)]
38443845
pub enum Defaultness {
3845-
Default { has_value: bool },
3846+
Default {
3847+
has_value: bool,
3848+
},
3849+
#[default]
38463850
Final,
38473851
}
38483852

@@ -4231,8 +4235,8 @@ impl fmt::Display for Safety {
42314235
#[derive(Copy, Clone, PartialEq, Eq, Debug, Encodable, Decodable, HashStable_Generic)]
42324236
#[derive(Default)]
42334237
pub enum Constness {
4234-
Const,
42354238
#[default]
4239+
Const,
42364240
NotConst,
42374241
}
42384242

compiler/rustc_metadata/src/rmeta/encoder.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1753,7 +1753,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
17531753
let item = tcx.associated_item(def_id);
17541754

17551755
if matches!(item.container, AssocContainer::Trait | AssocContainer::TraitImpl(_)) {
1756-
self.tables.defaultness.set_some(def_id.index, item.defaultness(tcx));
1756+
self.tables.defaultness.set(def_id.index, item.defaultness(tcx));
17571757
}
17581758

17591759
record!(self.tables.assoc_container[def_id] <- item.container);
@@ -2155,7 +2155,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
21552155
let header = tcx.impl_trait_header(def_id);
21562156
record!(self.tables.impl_trait_header[def_id] <- header);
21572157

2158-
self.tables.defaultness.set_some(def_id.index, tcx.defaultness(def_id));
2158+
self.tables.defaultness.set(def_id.index, tcx.defaultness(def_id));
21592159

21602160
let trait_ref = header.trait_ref.instantiate_identity();
21612161
let simplified_self_ty = fast_reject::simplify_type(

compiler/rustc_metadata/src/rmeta/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -403,6 +403,7 @@ define_tables! {
403403
asyncness: Table<DefIndex, ty::Asyncness>,
404404
constness: Table<DefIndex, hir::Constness>,
405405
safety: Table<DefIndex, hir::Safety>,
406+
defaultness: Table<DefIndex, hir::Defaultness>,
406407

407408
- optional:
408409
attributes: Table<DefIndex, LazyArray<hir::Attribute>>,
@@ -436,7 +437,6 @@ define_tables! {
436437
thir_abstract_const: Table<DefIndex, LazyValue<ty::EarlyBinder<'static, ty::Const<'static>>>>,
437438
impl_parent: Table<DefIndex, RawDefId>,
438439
const_conditions: Table<DefIndex, LazyValue<ty::ConstConditions<'static>>>,
439-
defaultness: Table<DefIndex, hir::Defaultness>,
440440
// FIXME(eddyb) perhaps compute this on the fly if cheap enough?
441441
coerce_unsized_info: Table<DefIndex, LazyValue<ty::adjustment::CoerceUnsizedInfo>>,
442442
mir_const_qualif: Table<DefIndex, LazyValue<mir::ConstQualifs>>,

compiler/rustc_metadata/src/rmeta/table.rs

Lines changed: 59 additions & 94 deletions
Original file line numberDiff line numberDiff line change
@@ -25,33 +25,6 @@ impl IsDefault for bool {
2525
}
2626
}
2727

28-
impl IsDefault for ty::Asyncness {
29-
fn is_default(&self) -> bool {
30-
match self {
31-
ty::Asyncness::Yes => false,
32-
ty::Asyncness::No => true,
33-
}
34-
}
35-
}
36-
37-
impl IsDefault for hir::Constness {
38-
fn is_default(&self) -> bool {
39-
match self {
40-
hir::Constness::Const => false,
41-
hir::Constness::NotConst => true,
42-
}
43-
}
44-
}
45-
46-
impl IsDefault for hir::Safety {
47-
fn is_default(&self) -> bool {
48-
match self {
49-
hir::Safety::Safe => false,
50-
hir::Safety::Unsafe => true,
51-
}
52-
}
53-
}
54-
5528
impl IsDefault for u32 {
5629
fn is_default(&self) -> bool {
5730
*self == 0
@@ -139,6 +112,43 @@ macro_rules! fixed_size_enum {
139112
}
140113
}
141114

115+
macro_rules! defaulted_enum {
116+
($ty:ty { $(($($pat:tt)*))* } $( unreachable { $(($($upat:tt)*))+ } )?) => {
117+
impl FixedSizeEncoding for $ty {
118+
type ByteArray = [u8; 1];
119+
120+
#[inline]
121+
fn from_bytes(b: &[u8; 1]) -> Self {
122+
use $ty::*;
123+
let val = match b[0] {
124+
$(${index()} => $($pat)*,)*
125+
_ => panic!("Unexpected {} code: {:?}", stringify!($ty), b[0]),
126+
};
127+
// Make sure the first entry is always the default value,
128+
// and none of the other values are the default value
129+
debug_assert_ne!((b[0] != 0), IsDefault::is_default(&val));
130+
val
131+
}
132+
133+
#[inline]
134+
fn write_to_bytes(self, b: &mut [u8; 1]) {
135+
debug_assert!(!IsDefault::is_default(&self));
136+
use $ty::*;
137+
b[0] = match self {
138+
$($($pat)* => ${index()},)*
139+
$($($($upat)*)|+ => unreachable!(),)?
140+
};
141+
debug_assert_ne!(b[0], 0);
142+
}
143+
}
144+
impl IsDefault for $ty {
145+
fn is_default(&self) -> bool {
146+
<$ty as Default>::default() == *self
147+
}
148+
}
149+
}
150+
}
151+
142152
// Workaround; need const traits to construct bitflags in a const
143153
macro_rules! const_macro_kinds {
144154
($($name:ident),+$(,)?) => (MacroKinds::from_bits_truncate($(MacroKinds::$name.bits())|+))
@@ -205,14 +215,35 @@ fixed_size_enum! {
205215
}
206216
}
207217

208-
fixed_size_enum! {
218+
defaulted_enum! {
209219
hir::Defaultness {
210220
( Final )
211221
( Default { has_value: false } )
212222
( Default { has_value: true } )
213223
}
214224
}
215225

226+
defaulted_enum! {
227+
ty::Asyncness {
228+
( No )
229+
( Yes )
230+
}
231+
}
232+
233+
defaulted_enum! {
234+
hir::Constness {
235+
( Const )
236+
( NotConst )
237+
}
238+
}
239+
240+
defaulted_enum! {
241+
hir::Safety {
242+
( Unsafe )
243+
( Safe )
244+
}
245+
}
246+
216247
fixed_size_enum! {
217248
hir::CoroutineKind {
218249
( Coroutine(hir::Movability::Movable) )
@@ -301,72 +332,6 @@ impl FixedSizeEncoding for bool {
301332
}
302333
}
303334

304-
impl FixedSizeEncoding for ty::Asyncness {
305-
type ByteArray = [u8; 1];
306-
307-
#[inline]
308-
fn from_bytes(b: &[u8; 1]) -> Self {
309-
match b[0] {
310-
0 => ty::Asyncness::No,
311-
1 => ty::Asyncness::Yes,
312-
_ => unreachable!(),
313-
}
314-
}
315-
316-
#[inline]
317-
fn write_to_bytes(self, b: &mut [u8; 1]) {
318-
debug_assert!(!self.is_default());
319-
b[0] = match self {
320-
ty::Asyncness::No => 0,
321-
ty::Asyncness::Yes => 1,
322-
}
323-
}
324-
}
325-
326-
impl FixedSizeEncoding for hir::Constness {
327-
type ByteArray = [u8; 1];
328-
329-
#[inline]
330-
fn from_bytes(b: &[u8; 1]) -> Self {
331-
match b[0] {
332-
0 => hir::Constness::NotConst,
333-
1 => hir::Constness::Const,
334-
_ => unreachable!(),
335-
}
336-
}
337-
338-
#[inline]
339-
fn write_to_bytes(self, b: &mut [u8; 1]) {
340-
debug_assert!(!self.is_default());
341-
b[0] = match self {
342-
hir::Constness::NotConst => 0,
343-
hir::Constness::Const => 1,
344-
}
345-
}
346-
}
347-
348-
impl FixedSizeEncoding for hir::Safety {
349-
type ByteArray = [u8; 1];
350-
351-
#[inline]
352-
fn from_bytes(b: &[u8; 1]) -> Self {
353-
match b[0] {
354-
0 => hir::Safety::Unsafe,
355-
1 => hir::Safety::Safe,
356-
_ => unreachable!(),
357-
}
358-
}
359-
360-
#[inline]
361-
fn write_to_bytes(self, b: &mut [u8; 1]) {
362-
debug_assert!(!self.is_default());
363-
b[0] = match self {
364-
hir::Safety::Unsafe => 0,
365-
hir::Safety::Safe => 1,
366-
}
367-
}
368-
}
369-
370335
// NOTE(eddyb) there could be an impl for `usize`, which would enable a more
371336
// generic `LazyValue<T>` impl, but in the general case we might not need / want
372337
// to fit every `usize` in `u32`.

0 commit comments

Comments
 (0)