Skip to content

Commit 2103027

Browse files
authored
Rollup merge of rust-lang#107166 - petrochenkov:nooptable, r=oli-obk
rustc_metadata: Support non-`Option` nullable values in metadata tables This is a convenience feature for cases in which "no value in the table" and "default value in the table" are equivalent. Tables using `Table<DefIndex, ()>` are migrated in this PR, some other cases can be migrated later. This helps `DocFlags` in rust-lang#107136 in particular.
2 parents b5255d2 + 91fdbd7 commit 2103027

File tree

5 files changed

+64
-76
lines changed

5 files changed

+64
-76
lines changed

compiler/rustc_metadata/src/rmeta/decoder.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -985,7 +985,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
985985
let vis = self.get_visibility(id);
986986
let span = self.get_span(id, sess);
987987
let macro_rules = match kind {
988-
DefKind::Macro(..) => self.root.tables.macro_rules.get(self, id).is_some(),
988+
DefKind::Macro(..) => self.root.tables.is_macro_rules.get(self, id),
989989
_ => false,
990990
};
991991

@@ -1283,7 +1283,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
12831283
fn get_macro(self, id: DefIndex, sess: &Session) -> ast::MacroDef {
12841284
match self.def_kind(id) {
12851285
DefKind::Macro(_) => {
1286-
let macro_rules = self.root.tables.macro_rules.get(self, id).is_some();
1286+
let macro_rules = self.root.tables.is_macro_rules.get(self, id);
12871287
let body =
12881288
self.root.tables.macro_definition.get(self, id).unwrap().decode((self, sess));
12891289
ast::MacroDef { macro_rules, body: ast::ptr::P(body) }
@@ -1595,11 +1595,11 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
15951595
}
15961596

15971597
fn get_attr_flags(self, index: DefIndex) -> AttrFlags {
1598-
self.root.tables.attr_flags.get(self, index).unwrap_or(AttrFlags::empty())
1598+
self.root.tables.attr_flags.get(self, index)
15991599
}
16001600

16011601
fn get_is_intrinsic(self, index: DefIndex) -> bool {
1602-
self.root.tables.is_intrinsic.get(self, index).is_some()
1602+
self.root.tables.is_intrinsic.get(self, index)
16031603
}
16041604
}
16051605

compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs

+1-6
Original file line numberDiff line numberDiff line change
@@ -226,12 +226,7 @@ provide! { tcx, def_id, other, cdata,
226226
deduced_param_attrs => { table }
227227
is_type_alias_impl_trait => {
228228
debug_assert_eq!(tcx.def_kind(def_id), DefKind::OpaqueTy);
229-
cdata
230-
.root
231-
.tables
232-
.is_type_alias_impl_trait
233-
.get(cdata, def_id.index)
234-
.is_some()
229+
cdata.root.tables.is_type_alias_impl_trait.get(cdata, def_id.index)
235230
}
236231
collect_return_position_impl_trait_in_trait_tys => {
237232
Ok(cdata

compiler/rustc_metadata/src/rmeta/encoder.rs

+7-7
Original file line numberDiff line numberDiff line change
@@ -483,7 +483,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
483483
self.lazy(DefPathHashMapRef::BorrowedFromTcx(self.tcx.def_path_hash_to_def_index_map()))
484484
}
485485

486-
fn encode_source_map(&mut self) -> LazyTable<u32, LazyValue<rustc_span::SourceFile>> {
486+
fn encode_source_map(&mut self) -> LazyTable<u32, Option<LazyValue<rustc_span::SourceFile>>> {
487487
let source_map = self.tcx.sess.source_map();
488488
let all_source_files = source_map.files();
489489

@@ -1130,7 +1130,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
11301130
attr_flags |= AttrFlags::IS_DOC_HIDDEN;
11311131
}
11321132
if !attr_flags.is_empty() {
1133-
self.tables.attr_flags.set(def_id.local_def_index, attr_flags);
1133+
self.tables.attr_flags.set_nullable(def_id.local_def_index, attr_flags);
11341134
}
11351135
}
11361136

@@ -1387,7 +1387,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
13871387
if impl_item.kind == ty::AssocKind::Fn {
13881388
record!(self.tables.fn_sig[def_id] <- tcx.fn_sig(def_id));
13891389
if tcx.is_intrinsic(def_id) {
1390-
self.tables.is_intrinsic.set(def_id.index, ());
1390+
self.tables.is_intrinsic.set_nullable(def_id.index, true);
13911391
}
13921392
}
13931393
}
@@ -1519,7 +1519,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
15191519
}
15201520
hir::ItemKind::Macro(ref macro_def, _) => {
15211521
if macro_def.macro_rules {
1522-
self.tables.macro_rules.set(def_id.index, ());
1522+
self.tables.is_macro_rules.set_nullable(def_id.index, true);
15231523
}
15241524
record!(self.tables.macro_definition[def_id] <- &*macro_def.body);
15251525
}
@@ -1529,7 +1529,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
15291529
hir::ItemKind::OpaqueTy(ref opaque) => {
15301530
self.encode_explicit_item_bounds(def_id);
15311531
if matches!(opaque.origin, hir::OpaqueTyOrigin::TyAlias) {
1532-
self.tables.is_type_alias_impl_trait.set(def_id.index, ());
1532+
self.tables.is_type_alias_impl_trait.set_nullable(def_id.index, true);
15331533
}
15341534
}
15351535
hir::ItemKind::Enum(..) => {
@@ -1636,7 +1636,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
16361636
if let hir::ItemKind::Fn(..) = item.kind {
16371637
record!(self.tables.fn_sig[def_id] <- tcx.fn_sig(def_id));
16381638
if tcx.is_intrinsic(def_id) {
1639-
self.tables.is_intrinsic.set(def_id.index, ());
1639+
self.tables.is_intrinsic.set_nullable(def_id.index, true);
16401640
}
16411641
}
16421642
if let hir::ItemKind::Impl { .. } = item.kind {
@@ -2038,7 +2038,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
20382038
}
20392039
if let hir::ForeignItemKind::Fn(..) = nitem.kind {
20402040
if tcx.is_intrinsic(def_id) {
2041-
self.tables.is_intrinsic.set(def_id.index, ());
2041+
self.tables.is_intrinsic.set_nullable(def_id.index, true);
20422042
}
20432043
}
20442044
}

compiler/rustc_metadata/src/rmeta/mod.rs

+22-17
Original file line numberDiff line numberDiff line change
@@ -185,9 +185,9 @@ enum LazyState {
185185
Previous(NonZeroUsize),
186186
}
187187

188-
type SyntaxContextTable = LazyTable<u32, LazyValue<SyntaxContextData>>;
189-
type ExpnDataTable = LazyTable<ExpnIndex, LazyValue<ExpnData>>;
190-
type ExpnHashTable = LazyTable<ExpnIndex, LazyValue<ExpnHash>>;
188+
type SyntaxContextTable = LazyTable<u32, Option<LazyValue<SyntaxContextData>>>;
189+
type ExpnDataTable = LazyTable<ExpnIndex, Option<LazyValue<ExpnData>>>;
190+
type ExpnHashTable = LazyTable<ExpnIndex, Option<LazyValue<ExpnHash>>>;
191191

192192
#[derive(MetadataEncodable, MetadataDecodable)]
193193
pub(crate) struct ProcMacroData {
@@ -253,7 +253,7 @@ pub(crate) struct CrateRoot {
253253

254254
def_path_hash_map: LazyValue<DefPathHashMapRef<'static>>,
255255

256-
source_map: LazyTable<u32, LazyValue<rustc_span::SourceFile>>,
256+
source_map: LazyTable<u32, Option<LazyValue<rustc_span::SourceFile>>>,
257257

258258
compiler_builtins: bool,
259259
needs_allocator: bool,
@@ -315,31 +315,43 @@ pub(crate) struct IncoherentImpls {
315315

316316
/// Define `LazyTables` and `TableBuilders` at the same time.
317317
macro_rules! define_tables {
318-
($($name:ident: Table<$IDX:ty, $T:ty>),+ $(,)?) => {
318+
(
319+
- nullable: $($name1:ident: Table<$IDX1:ty, $T1:ty>,)+
320+
- optional: $($name2:ident: Table<$IDX2:ty, $T2:ty>,)+
321+
) => {
319322
#[derive(MetadataEncodable, MetadataDecodable)]
320323
pub(crate) struct LazyTables {
321-
$($name: LazyTable<$IDX, $T>),+
324+
$($name1: LazyTable<$IDX1, $T1>,)+
325+
$($name2: LazyTable<$IDX2, Option<$T2>>,)+
322326
}
323327

324328
#[derive(Default)]
325329
struct TableBuilders {
326-
$($name: TableBuilder<$IDX, $T>),+
330+
$($name1: TableBuilder<$IDX1, $T1>,)+
331+
$($name2: TableBuilder<$IDX2, Option<$T2>>,)+
327332
}
328333

329334
impl TableBuilders {
330335
fn encode(&self, buf: &mut FileEncoder) -> LazyTables {
331336
LazyTables {
332-
$($name: self.$name.encode(buf)),+
337+
$($name1: self.$name1.encode(buf),)+
338+
$($name2: self.$name2.encode(buf),)+
333339
}
334340
}
335341
}
336342
}
337343
}
338344

339345
define_tables! {
346+
- nullable:
347+
is_intrinsic: Table<DefIndex, bool>,
348+
is_macro_rules: Table<DefIndex, bool>,
349+
is_type_alias_impl_trait: Table<DefIndex, bool>,
350+
attr_flags: Table<DefIndex, AttrFlags>,
351+
352+
- optional:
340353
attributes: Table<DefIndex, LazyArray<ast::Attribute>>,
341354
children: Table<DefIndex, LazyArray<DefIndex>>,
342-
343355
opt_def_kind: Table<DefIndex, DefKind>,
344356
visibility: Table<DefIndex, LazyValue<ty::Visibility<DefIndex>>>,
345357
def_span: Table<DefIndex, LazyValue<Span>>,
@@ -370,7 +382,6 @@ define_tables! {
370382
impl_parent: Table<DefIndex, RawDefId>,
371383
impl_polarity: Table<DefIndex, ty::ImplPolarity>,
372384
constness: Table<DefIndex, hir::Constness>,
373-
is_intrinsic: Table<DefIndex, ()>,
374385
impl_defaultness: Table<DefIndex, hir::Defaultness>,
375386
// FIXME(eddyb) perhaps compute this on the fly if cheap enough?
376387
coerce_unsized_info: Table<DefIndex, LazyValue<ty::adjustment::CoerceUnsizedInfo>>,
@@ -380,7 +391,6 @@ define_tables! {
380391
fn_arg_names: Table<DefIndex, LazyArray<Ident>>,
381392
generator_kind: Table<DefIndex, LazyValue<hir::GeneratorKind>>,
382393
trait_def: Table<DefIndex, LazyValue<ty::TraitDef>>,
383-
384394
trait_item_def_id: Table<DefIndex, RawDefId>,
385395
inherent_impls: Table<DefIndex, LazyArray<DefIndex>>,
386396
expn_that_defined: Table<DefIndex, LazyValue<ExpnId>>,
@@ -395,18 +405,12 @@ define_tables! {
395405
def_path_hashes: Table<DefIndex, DefPathHash>,
396406
proc_macro_quoted_spans: Table<usize, LazyValue<Span>>,
397407
generator_diagnostic_data: Table<DefIndex, LazyValue<GeneratorDiagnosticData<'static>>>,
398-
attr_flags: Table<DefIndex, AttrFlags>,
399408
variant_data: Table<DefIndex, LazyValue<VariantData>>,
400409
assoc_container: Table<DefIndex, ty::AssocItemContainer>,
401-
// Slot is full when macro is macro_rules.
402-
macro_rules: Table<DefIndex, ()>,
403410
macro_definition: Table<DefIndex, LazyValue<ast::DelimArgs>>,
404411
proc_macro: Table<DefIndex, MacroKind>,
405412
module_reexports: Table<DefIndex, LazyArray<ModChild>>,
406413
deduced_param_attrs: Table<DefIndex, LazyArray<DeducedParamAttrs>>,
407-
// Slot is full when opaque is TAIT.
408-
is_type_alias_impl_trait: Table<DefIndex, ()>,
409-
410414
trait_impl_trait_tys: Table<DefIndex, LazyValue<FxHashMap<DefId, Ty<'static>>>>,
411415
}
412416

@@ -419,6 +423,7 @@ struct VariantData {
419423
}
420424

421425
bitflags::bitflags! {
426+
#[derive(Default)]
422427
pub struct AttrFlags: u8 {
423428
const MAY_HAVE_DOC_LINKS = 1 << 0;
424429
const IS_DOC_HIDDEN = 1 << 1;

compiler/rustc_metadata/src/rmeta/table.rs

+30-42
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ use std::num::NonZeroUsize;
1616
/// but this has no impact on safety.
1717
pub(super) trait FixedSizeEncoding: Default {
1818
/// This should be `[u8; BYTE_LEN]`;
19+
/// Cannot use an associated `const BYTE_LEN: usize` instead due to const eval limitations.
1920
type ByteArray;
2021

2122
fn from_bytes(b: &Self::ByteArray) -> Self;
@@ -199,31 +200,31 @@ impl FixedSizeEncoding for Option<RawDefId> {
199200
}
200201
}
201202

202-
impl FixedSizeEncoding for Option<AttrFlags> {
203+
impl FixedSizeEncoding for AttrFlags {
203204
type ByteArray = [u8; 1];
204205

205206
#[inline]
206207
fn from_bytes(b: &[u8; 1]) -> Self {
207-
(b[0] != 0).then(|| AttrFlags::from_bits_truncate(b[0]))
208+
AttrFlags::from_bits_truncate(b[0])
208209
}
209210

210211
#[inline]
211212
fn write_to_bytes(self, b: &mut [u8; 1]) {
212-
b[0] = self.map_or(0, |flags| flags.bits())
213+
b[0] = self.bits();
213214
}
214215
}
215216

216-
impl FixedSizeEncoding for Option<()> {
217+
impl FixedSizeEncoding for bool {
217218
type ByteArray = [u8; 1];
218219

219220
#[inline]
220221
fn from_bytes(b: &[u8; 1]) -> Self {
221-
(b[0] != 0).then(|| ())
222+
b[0] != 0
222223
}
223224

224225
#[inline]
225226
fn write_to_bytes(self, b: &mut [u8; 1]) {
226-
b[0] = self.is_some() as u8
227+
b[0] = self as u8
227228
}
228229
}
229230

@@ -273,44 +274,38 @@ impl<T> FixedSizeEncoding for Option<LazyArray<T>> {
273274
}
274275

275276
/// Helper for constructing a table's serialization (also see `Table`).
276-
pub(super) struct TableBuilder<I: Idx, T>
277-
where
278-
Option<T>: FixedSizeEncoding,
279-
{
280-
blocks: IndexVec<I, <Option<T> as FixedSizeEncoding>::ByteArray>,
277+
pub(super) struct TableBuilder<I: Idx, T: FixedSizeEncoding> {
278+
blocks: IndexVec<I, T::ByteArray>,
281279
_marker: PhantomData<T>,
282280
}
283281

284-
impl<I: Idx, T> Default for TableBuilder<I, T>
285-
where
286-
Option<T>: FixedSizeEncoding,
287-
{
282+
impl<I: Idx, T: FixedSizeEncoding> Default for TableBuilder<I, T> {
288283
fn default() -> Self {
289284
TableBuilder { blocks: Default::default(), _marker: PhantomData }
290285
}
291286
}
292287

293-
impl<I: Idx, T> TableBuilder<I, T>
288+
impl<I: Idx, const N: usize, T> TableBuilder<I, Option<T>>
294289
where
295-
Option<T>: FixedSizeEncoding,
290+
Option<T>: FixedSizeEncoding<ByteArray = [u8; N]>,
296291
{
297-
pub(crate) fn set<const N: usize>(&mut self, i: I, value: T)
298-
where
299-
Option<T>: FixedSizeEncoding<ByteArray = [u8; N]>,
300-
{
292+
pub(crate) fn set(&mut self, i: I, value: T) {
293+
self.set_nullable(i, Some(value))
294+
}
295+
}
296+
297+
impl<I: Idx, const N: usize, T: FixedSizeEncoding<ByteArray = [u8; N]>> TableBuilder<I, T> {
298+
pub(crate) fn set_nullable(&mut self, i: I, value: T) {
301299
// FIXME(eddyb) investigate more compact encodings for sparse tables.
302300
// On the PR @michaelwoerister mentioned:
303301
// > Space requirements could perhaps be optimized by using the HAMT `popcnt`
304302
// > trick (i.e. divide things into buckets of 32 or 64 items and then
305303
// > store bit-masks of which item in each bucket is actually serialized).
306304
self.blocks.ensure_contains_elem(i, || [0; N]);
307-
Some(value).write_to_bytes(&mut self.blocks[i]);
305+
value.write_to_bytes(&mut self.blocks[i]);
308306
}
309307

310-
pub(crate) fn encode<const N: usize>(&self, buf: &mut FileEncoder) -> LazyTable<I, T>
311-
where
312-
Option<T>: FixedSizeEncoding<ByteArray = [u8; N]>,
313-
{
308+
pub(crate) fn encode(&self, buf: &mut FileEncoder) -> LazyTable<I, T> {
314309
let pos = buf.position();
315310
for block in &self.blocks {
316311
buf.emit_raw_bytes(block);
@@ -323,34 +318,27 @@ where
323318
}
324319
}
325320

326-
impl<I: Idx, T: ParameterizedOverTcx> LazyTable<I, T>
321+
impl<I: Idx, const N: usize, T: FixedSizeEncoding<ByteArray = [u8; N]> + ParameterizedOverTcx>
322+
LazyTable<I, T>
327323
where
328-
Option<T>: FixedSizeEncoding,
324+
for<'tcx> T::Value<'tcx>: FixedSizeEncoding<ByteArray = [u8; N]>,
329325
{
330326
/// Given the metadata, extract out the value at a particular index (if any).
331327
#[inline(never)]
332-
pub(super) fn get<'a, 'tcx, M: Metadata<'a, 'tcx>, const N: usize>(
333-
&self,
334-
metadata: M,
335-
i: I,
336-
) -> Option<T::Value<'tcx>>
337-
where
338-
Option<T::Value<'tcx>>: FixedSizeEncoding<ByteArray = [u8; N]>,
339-
{
328+
pub(super) fn get<'a, 'tcx, M: Metadata<'a, 'tcx>>(&self, metadata: M, i: I) -> T::Value<'tcx> {
340329
debug!("LazyTable::lookup: index={:?} len={:?}", i, self.encoded_size);
341330

342331
let start = self.position.get();
343332
let bytes = &metadata.blob()[start..start + self.encoded_size];
344333
let (bytes, []) = bytes.as_chunks::<N>() else { panic!() };
345-
let bytes = bytes.get(i.index())?;
346-
FixedSizeEncoding::from_bytes(bytes)
334+
match bytes.get(i.index()) {
335+
Some(bytes) => FixedSizeEncoding::from_bytes(bytes),
336+
None => FixedSizeEncoding::from_bytes(&[0; N]),
337+
}
347338
}
348339

349340
/// Size of the table in entries, including possible gaps.
350-
pub(super) fn size<const N: usize>(&self) -> usize
351-
where
352-
for<'tcx> Option<T::Value<'tcx>>: FixedSizeEncoding<ByteArray = [u8; N]>,
353-
{
341+
pub(super) fn size(&self) -> usize {
354342
self.encoded_size / N
355343
}
356344
}

0 commit comments

Comments
 (0)