From e3766b45f772414156fce75210a64da5212d4797 Mon Sep 17 00:00:00 2001 From: aerooneqq Date: Thu, 17 Sep 2026 15:51:50 +0300 Subject: [PATCH 1/9] Introduce `record_non_lazy` and `record_defaulted` macros to write to metadata tables --- compiler/rustc_metadata/src/rmeta/encoder.rs | 86 ++++++++++++-------- 1 file changed, 50 insertions(+), 36 deletions(-) diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs index afa5646bea80e..9893229df46ee 100644 --- a/compiler/rustc_metadata/src/rmeta/encoder.rs +++ b/compiler/rustc_metadata/src/rmeta/encoder.rs @@ -404,6 +404,7 @@ impl<'a, 'tcx> TyEncoder<'tcx> for EncodeContext<'a, 'tcx> { // Shorthand for `$self.$tables.$table.set_some($def_id.index, $self.lazy($value))`, which would // normally need extra variables to avoid errors about multiple mutable borrows. +// Also those macros greatly simplify refactorings and modifications of writing to tables. macro_rules! record { ($self:ident.$tables:ident.$table:ident[$def_id:expr] <- $value:expr) => {{ { @@ -414,6 +415,22 @@ macro_rules! record { }}; } +macro_rules! record_non_lazy { + ($self:ident.$tables:ident.$table:ident[$def_id:expr] <- $value:expr) => {{ + { + $self.$tables.$table.set_some($def_id.index, $value); + } + }}; +} + +macro_rules! record_defaulted { + ($self:ident.$tables:ident.$table:ident[$def_id:expr] <- $value:expr) => {{ + { + $self.$tables.$table.set($def_id.index, $value); + } + }}; +} + // Shorthand for `$self.$tables.$table.set_some($def_id.index, $self.lazy_array($value))`, which would // normally need extra variables to avoid errors about multiple mutable borrows. macro_rules! record_array { @@ -527,18 +544,18 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { for def_id in std::iter::once(CRATE_DEF_ID) .chain(self.tcx.resolutions(()).proc_macros.iter().copied()) { - let def_key = self.lazy(defs.def_key(def_id)); + let def_key = defs.def_key(def_id); let def_path_hash = defs.def_path_hash(def_id); - self.tables.def_keys.set_some(def_id.local_def_index, def_key); - self.tables - .def_path_hashes - .set(def_id.local_def_index, def_path_hash.local_hash().as_u64()); + let def_id = def_id.to_def_id(); + + record!(self.tables.def_keys[def_id] <- def_key); + record_defaulted!(self.tables.def_path_hashes[def_id] <- def_path_hash.local_hash().as_u64()) } } else { for (def_index, def_key, def_path_hash) in defs.enumerated_keys_and_path_hashes() { - let def_key = self.lazy(def_key); - self.tables.def_keys.set_some(def_index, def_key); - self.tables.def_path_hashes.set(def_index, def_path_hash.local_hash().as_u64()); + let def_id = LocalDefId { local_def_index: def_index }.to_def_id(); + record!(self.tables.def_keys[def_id] <- def_key); + record_defaulted!(self.tables.def_path_hashes[def_id] <- def_path_hash.local_hash().as_u64()) } } } @@ -1442,7 +1459,8 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { if state.is_doc_hidden { attr_flags |= AttrFlags::IS_DOC_HIDDEN; } - self.tables.attr_flags.set(def_id.local_def_index, attr_flags); + + record_defaulted!(self.tables.attr_flags[def_id.to_def_id()] <- attr_flags) } fn encode_def_ids(&mut self) { @@ -1459,7 +1477,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { for local_id in tcx.iter_local_def_id() { let def_id = local_id.to_def_id(); let def_kind = tcx.def_kind(local_id); - self.tables.def_kind.set_some(def_id.index, def_kind); + record_non_lazy!(self.tables.def_kind[def_id] <- def_kind); // The `DefCollector` will sometimes create unnecessary `DefId`s // for trivial const arguments which are directly lowered to @@ -1543,11 +1561,11 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { } if should_encode_constness(def_kind) { let constness = self.tcx.constness(def_id); - self.tables.constness.set(def_id.index, constness); + record_defaulted!(self.tables.constness[def_id] <- constness) } if let DefKind::Fn | DefKind::AssocFn = def_kind { let asyncness = tcx.asyncness(def_id); - self.tables.asyncness.set(def_id.index, asyncness); + record_defaulted!(self.tables.asyncness[def_id] <- asyncness); record_array!(self.tables.fn_arg_idents[def_id] <- tcx.fn_arg_idents(def_id)); } if let Some(name) = tcx.intrinsic(def_id) { @@ -1593,22 +1611,20 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { if let DefKind::Closure | DefKind::SyntheticCoroutineBody = def_kind && let Some(coroutine_kind) = self.tcx.coroutine_kind(def_id) { - self.tables.coroutine_kind.set(def_id.index, Some(coroutine_kind)) + record_defaulted!(self.tables.coroutine_kind[def_id] <- Some(coroutine_kind)) } if def_kind == DefKind::Closure && tcx.type_of(def_id).skip_binder().is_coroutine_closure() { let coroutine_for_closure = self.tcx.coroutine_for_closure(def_id); - self.tables - .coroutine_for_closure - .set_some(def_id.index, coroutine_for_closure.into()); + record_non_lazy!(self.tables.coroutine_for_closure[def_id] <- coroutine_for_closure.into()); // If this async closure has a by-move body, record it too. if tcx.needs_coroutine_by_move_body_def_id(coroutine_for_closure) { - self.tables.coroutine_by_move_body_def_id.set_some( - coroutine_for_closure.index, - self.tcx.coroutine_by_move_body_def_id(coroutine_for_closure).into(), - ); + let id = self.tcx.coroutine_by_move_body_def_id(coroutine_for_closure); + record_non_lazy!( + self.tables.coroutine_by_move_body_def_id[coroutine_for_closure] <- id.into() + ) } } if let DefKind::Static { .. } = def_kind { @@ -1638,9 +1654,8 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { self.encode_info_for_macro(local_id); } if let DefKind::TyAlias = def_kind { - self.tables - .type_alias_is_checked - .set(def_id.index, self.tcx.type_alias_is_checked(def_id)); + record_defaulted!(self.tables.type_alias_is_checked[def_id] <- self.tcx.type_alias_is_checked(def_id)); + if self.tcx.type_alias_is_checked(def_id) { record!(self.tables.args_known_to_outlive_alias_params[def_id] <- tcx.args_known_to_outlive_alias_params(def_id)); } @@ -1751,7 +1766,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { })); for field in &variant.fields { - self.tables.safety.set(field.did.index, field.safety); + record_defaulted!(self.tables.safety[field.did] <- field.safety); record!( self.tables.mut_restriction[field.did] <- field.mut_restriction ); @@ -1824,7 +1839,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(def_id.index, item.defaultness(tcx)); + record_defaulted!(self.tables.defaultness[def_id] <- item.defaultness(tcx)); } record!(self.tables.assoc_container[def_id] <- item.container); @@ -1877,9 +1892,9 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { debug!("EntryBuilder::encode_mir({:?})", def_id); if encode_opt { record!(self.tables.optimized_mir[def_id.to_def_id()] <- tcx.optimized_mir(def_id)); - self.tables - .cross_crate_inlinable - .set(def_id.to_def_id().index, self.tcx.cross_crate_inlinable(def_id)); + + record_defaulted!(self.tables.cross_crate_inlinable[def_id.to_def_id()] <- self.tcx.cross_crate_inlinable(def_id)); + record!(self.tables.closure_saved_names_of_captured_variables[def_id.to_def_id()] <- tcx.closure_saved_names_of_captured_variables(def_id)); @@ -1987,7 +2002,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { let tcx = self.tcx; let (_, macro_def, _) = tcx.hir_expect_item(def_id).expect_macro(); - self.tables.is_macro_rules.set(def_id.local_def_index, macro_def.macro_rules); + record_defaulted!(self.tables.is_macro_rules[def_id.to_def_id()] <- macro_def.macro_rules); record!(self.tables.macro_definition[def_id.to_def_id()] <- &*macro_def.body); } @@ -2042,7 +2057,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { self.tables.proc_macro_quoted_spans.set_some(i, span); } - self.tables.def_kind.set_some(LOCAL_CRATE.as_def_id().index, DefKind::Mod); + record_non_lazy!(self.tables.def_kind[LOCAL_CRATE.as_def_id()] <- DefKind::Mod); record!(self.tables.def_span[LOCAL_CRATE.as_def_id()] <- tcx.def_span(LOCAL_CRATE.as_def_id())); self.encode_attrs(LOCAL_CRATE.as_def_id().expect_local()); let vis = tcx @@ -2101,7 +2116,8 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { def_key.disambiguated_data.data = DefPathData::MacroNs(name); let def_id = id.to_def_id(); - self.tables.def_kind.set_some(def_id.index, DefKind::Macro(macro_kind.into())); + record_non_lazy!(self.tables.def_kind[def_id] <- DefKind::Macro(macro_kind.into())); + self.encode_attrs(id); record!(self.tables.def_keys[def_id] <- def_key); record!(self.tables.def_ident_span[def_id] <- span); @@ -2265,11 +2281,9 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { let impl_is_fully_generic_for_reflection = tcx.impl_is_fully_generic_for_reflection(def_id); - self.tables - .impl_is_fully_generic_for_reflection - .set(def_id.index, impl_is_fully_generic_for_reflection); - self.tables.defaultness.set(def_id.index, tcx.defaultness(def_id)); + record_defaulted!(self.tables.impl_is_fully_generic_for_reflection[def_id] <- impl_is_fully_generic_for_reflection); + record_defaulted!(self.tables.defaultness[def_id] <- tcx.defaultness(def_id)); let trait_ref = header.trait_ref.instantiate_identity().skip_norm_wip(); let simplified_self_ty = fast_reject::simplify_type( @@ -2286,7 +2300,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { if let Ok(mut an) = trait_def.ancestors(tcx, def_id) && let Some(specialization_graph::Node::Impl(parent)) = an.nth(1) { - self.tables.impl_parent.set_some(def_id.index, parent.into()); + record_non_lazy!(self.tables.impl_parent[def_id] <- parent.into()); } // if this is an impl of `CoerceUnsized`, create its From 5162fc66b54419862b67304ab18c14787c61106a Mon Sep 17 00:00:00 2001 From: aerooneqq Date: Fri, 18 Sep 2026 12:04:18 +0300 Subject: [PATCH 2/9] Move `proc_macro_quoted_spans` to `ProcMacroData`, as it is filled only when `ProcMacroData` is `Some` --- compiler/rustc_metadata/src/rmeta/decoder.rs | 6 ++++-- compiler/rustc_metadata/src/rmeta/encoder.rs | 18 +++++++++++++----- compiler/rustc_metadata/src/rmeta/mod.rs | 2 +- 3 files changed, 18 insertions(+), 8 deletions(-) diff --git a/compiler/rustc_metadata/src/rmeta/decoder.rs b/compiler/rustc_metadata/src/rmeta/decoder.rs index 27b36c23daf46..2dd639f720e09 100644 --- a/compiler/rustc_metadata/src/rmeta/decoder.rs +++ b/compiler/rustc_metadata/src/rmeta/decoder.rs @@ -1544,10 +1544,12 @@ impl CrateMetadata { fn get_proc_macro_quoted_span(&self, tcx: TyCtxt<'_>, index: usize) -> Span { self.root - .tables + .proc_macro_data + .as_ref() + .unwrap_or_else(|| panic!("missing proc macro data")) .proc_macro_quoted_spans .get(self, index) - .unwrap_or_else(|| panic!("Missing proc macro quoted span: {index:?}")) + .unwrap_or_else(|| panic!("missing proc macro quoted span: {index:?}")) .decode((self, tcx)) } diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs index 9893229df46ee..cb75c76fd754f 100644 --- a/compiler/rustc_metadata/src/rmeta/encoder.rs +++ b/compiler/rustc_metadata/src/rmeta/encoder.rs @@ -2052,10 +2052,6 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { let tcx = self.tcx; let proc_macro_decls_static = tcx.proc_macro_decls_static(()).unwrap().local_def_index; let stability = tcx.lookup_stability(CRATE_DEF_ID); - for (i, span) in self.tcx.sess.proc_macro_quoted_spans() { - let span = self.lazy(span); - self.tables.proc_macro_quoted_spans.set_some(i, span); - } record_non_lazy!(self.tables.def_kind[LOCAL_CRATE.as_def_id()] <- DefKind::Mod); record!(self.tables.def_span[LOCAL_CRATE.as_def_id()] <- tcx.def_span(LOCAL_CRATE.as_def_id())); @@ -2130,7 +2126,19 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { let macros = self.lazy_array(macros); - Some(ProcMacroData { proc_macro_decls_static, stability, macros }) + let mut proc_macro_quoted_spans = TableBuilder::default(); + for (i, span) in self.tcx.sess.proc_macro_quoted_spans() { + proc_macro_quoted_spans.set_some(i, self.lazy(span)); + } + + let proc_macro_quoted_spans = proc_macro_quoted_spans.encode(&mut self.opaque); + + Some(ProcMacroData { + proc_macro_decls_static, + stability, + macros, + proc_macro_quoted_spans, + }) } else { None } diff --git a/compiler/rustc_metadata/src/rmeta/mod.rs b/compiler/rustc_metadata/src/rmeta/mod.rs index e3f3257acc137..2b42f91f4ea05 100644 --- a/compiler/rustc_metadata/src/rmeta/mod.rs +++ b/compiler/rustc_metadata/src/rmeta/mod.rs @@ -208,6 +208,7 @@ pub(crate) struct ProcMacroData { proc_macro_decls_static: DefIndex, stability: Option, macros: LazyArray<(DefIndex, LazyValue)>, + proc_macro_quoted_spans: LazyTable>>, } #[derive(MetadataEncodable, LazyDecodable)] @@ -497,7 +498,6 @@ define_tables! { // `DefPathTable` up front, since we may only ever use a few // definitions from any given crate. def_keys: Table>, - proc_macro_quoted_spans: Table>, variant_data: Table>, assoc_container: Table>, macro_definition: Table>, From 08609b56761fe02f15e71115ce77ebd3a07b84d6 Mon Sep 17 00:00:00 2001 From: aerooneqq Date: Fri, 18 Sep 2026 15:42:52 +0300 Subject: [PATCH 3/9] Rename `record` -> `record_some_lazy`, `record_non_lazy` -> `record_some` and `record_defaulted` -> `record_value` --- compiler/rustc_metadata/src/rmeta/encoder.rs | 176 ++++++++++--------- 1 file changed, 89 insertions(+), 87 deletions(-) diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs index cb75c76fd754f..e8bc9bcb7697d 100644 --- a/compiler/rustc_metadata/src/rmeta/encoder.rs +++ b/compiler/rustc_metadata/src/rmeta/encoder.rs @@ -405,7 +405,7 @@ impl<'a, 'tcx> TyEncoder<'tcx> for EncodeContext<'a, 'tcx> { // Shorthand for `$self.$tables.$table.set_some($def_id.index, $self.lazy($value))`, which would // normally need extra variables to avoid errors about multiple mutable borrows. // Also those macros greatly simplify refactorings and modifications of writing to tables. -macro_rules! record { +macro_rules! record_some_lazy { ($self:ident.$tables:ident.$table:ident[$def_id:expr] <- $value:expr) => {{ { let value = $value; @@ -415,7 +415,7 @@ macro_rules! record { }}; } -macro_rules! record_non_lazy { +macro_rules! record_some { ($self:ident.$tables:ident.$table:ident[$def_id:expr] <- $value:expr) => {{ { $self.$tables.$table.set_some($def_id.index, $value); @@ -423,7 +423,7 @@ macro_rules! record_non_lazy { }}; } -macro_rules! record_defaulted { +macro_rules! record_value { ($self:ident.$tables:ident.$table:ident[$def_id:expr] <- $value:expr) => {{ { $self.$tables.$table.set($def_id.index, $value); @@ -548,14 +548,14 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { let def_path_hash = defs.def_path_hash(def_id); let def_id = def_id.to_def_id(); - record!(self.tables.def_keys[def_id] <- def_key); - record_defaulted!(self.tables.def_path_hashes[def_id] <- def_path_hash.local_hash().as_u64()) + record_some_lazy!(self.tables.def_keys[def_id] <- def_key); + record_value!(self.tables.def_path_hashes[def_id] <- def_path_hash.local_hash().as_u64()) } } else { for (def_index, def_key, def_path_hash) in defs.enumerated_keys_and_path_hashes() { let def_id = LocalDefId { local_def_index: def_index }.to_def_id(); - record!(self.tables.def_keys[def_id] <- def_key); - record_defaulted!(self.tables.def_path_hashes[def_id] <- def_path_hash.local_hash().as_u64()) + record_some_lazy!(self.tables.def_keys[def_id] <- def_key); + record_value!(self.tables.def_path_hashes[def_id] <- def_path_hash.local_hash().as_u64()) } } } @@ -1460,7 +1460,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { attr_flags |= AttrFlags::IS_DOC_HIDDEN; } - record_defaulted!(self.tables.attr_flags[def_id.to_def_id()] <- attr_flags) + record_value!(self.tables.attr_flags[def_id.to_def_id()] <- attr_flags) } fn encode_def_ids(&mut self) { @@ -1477,7 +1477,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { for local_id in tcx.iter_local_def_id() { let def_id = local_id.to_def_id(); let def_kind = tcx.def_kind(local_id); - record_non_lazy!(self.tables.def_kind[def_id] <- def_kind); + record_some!(self.tables.def_kind[def_id] <- def_kind); // The `DefCollector` will sometimes create unnecessary `DefId`s // for trivial const arguments which are directly lowered to @@ -1498,33 +1498,33 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { && let hir::Node::Field(field) = tcx.hir_node_by_def_id(local_id) && let Some(anon) = field.default { - record!(self.tables.default_fields[def_id] <- anon.def_id.to_def_id()); + record_some_lazy!(self.tables.default_fields[def_id] <- anon.def_id.to_def_id()); } if should_encode_span(def_kind) { let def_span = tcx.def_span(local_id); - record!(self.tables.def_span[def_id] <- def_span); + record_some_lazy!(self.tables.def_span[def_id] <- def_span); } if should_encode_attrs(def_kind) { self.encode_attrs(local_id); } if should_encode_expn_that_defined(def_kind) { - record!(self.tables.expn_that_defined[def_id] <- self.tcx.expn_that_defined(def_id)); + record_some_lazy!(self.tables.expn_that_defined[def_id] <- self.tcx.expn_that_defined(def_id)); } if should_encode_span(def_kind) && let Some(ident_span) = tcx.def_ident_span(def_id) { - record!(self.tables.def_ident_span[def_id] <- ident_span); + record_some_lazy!(self.tables.def_ident_span[def_id] <- ident_span); } if def_kind.has_codegen_attrs() { - record!(self.tables.codegen_fn_attrs[def_id] <- self.tcx.codegen_fn_attrs(def_id)); + record_some_lazy!(self.tables.codegen_fn_attrs[def_id] <- self.tcx.codegen_fn_attrs(def_id)); } if should_encode_visibility(def_kind) { let vis = self .tcx .local_visibility(local_id) .map_id(|mod_id| mod_id.to_local_def_id().local_def_index); - record!(self.tables.visibility[def_id] <- vis); + record_some_lazy!(self.tables.visibility[def_id] <- vis); } if should_encode_stability(def_kind) { self.encode_stability(def_id); @@ -1537,46 +1537,46 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { record_array!(self.tables.variances_of[def_id] <- v); } if should_encode_fn_sig(def_kind) { - record!(self.tables.fn_sig[def_id] <- tcx.fn_sig(def_id)); + record_some_lazy!(self.tables.fn_sig[def_id] <- tcx.fn_sig(def_id)); } if should_encode_generics(def_kind) { let g = tcx.generics_of(def_id); - record!(self.tables.generics_of[def_id] <- g); - record!(self.tables.explicit_clauses_of[def_id] <- self.tcx.explicit_clauses_of(def_id)); + record_some_lazy!(self.tables.generics_of[def_id] <- g); + record_some_lazy!(self.tables.explicit_clauses_of[def_id] <- self.tcx.explicit_clauses_of(def_id)); let inferred_outlives = self.tcx.inferred_outlives_of(def_id); record_defaulted_array!(self.tables.inferred_outlives_of[def_id] <- inferred_outlives); for param in &g.own_params { if let ty::GenericParamDefKind::Const { has_default: true, .. } = param.kind { let default = self.tcx.const_param_default(param.def_id); - record!(self.tables.const_param_default[param.def_id] <- default); + record_some_lazy!(self.tables.const_param_default[param.def_id] <- default); } } } if tcx.is_conditionally_const(def_id) { - record!(self.tables.const_conditions[def_id] <- self.tcx.const_conditions(def_id)); + record_some_lazy!(self.tables.const_conditions[def_id] <- self.tcx.const_conditions(def_id)); } if should_encode_type(tcx, local_id, def_kind) { - record!(self.tables.type_of[def_id] <- self.tcx.type_of(def_id)); + record_some_lazy!(self.tables.type_of[def_id] <- self.tcx.type_of(def_id)); } if should_encode_constness(def_kind) { let constness = self.tcx.constness(def_id); - record_defaulted!(self.tables.constness[def_id] <- constness) + record_value!(self.tables.constness[def_id] <- constness) } if let DefKind::Fn | DefKind::AssocFn = def_kind { let asyncness = tcx.asyncness(def_id); - record_defaulted!(self.tables.asyncness[def_id] <- asyncness); + record_value!(self.tables.asyncness[def_id] <- asyncness); record_array!(self.tables.fn_arg_idents[def_id] <- tcx.fn_arg_idents(def_id)); } if let Some(name) = tcx.intrinsic(def_id) { - record!(self.tables.intrinsic[def_id] <- name); + record_some_lazy!(self.tables.intrinsic[def_id] <- name); } if let DefKind::TyParam | DefKind::Trait = def_kind { let default = self.tcx.object_lifetime_default(def_id); - record!(self.tables.object_lifetime_default[def_id] <- default); + record_some_lazy!(self.tables.object_lifetime_default[def_id] <- default); } if let DefKind::Trait = def_kind { - record!(self.tables.trait_def[def_id] <- self.tcx.trait_def(def_id)); + record_some_lazy!(self.tables.trait_def[def_id] <- self.tcx.trait_def(def_id)); record_defaulted_array!(self.tables.explicit_super_clauses_of[def_id] <- self.tcx.explicit_super_clauses_of(def_id).skip_binder()); record_defaulted_array!(self.tables.explicit_implied_clauses_of[def_id] <- @@ -1590,7 +1590,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { } } if let DefKind::TraitAlias = def_kind { - record!(self.tables.trait_def[def_id] <- self.tcx.trait_def(def_id)); + record_some_lazy!(self.tables.trait_def[def_id] <- self.tcx.trait_def(def_id)); record_defaulted_array!(self.tables.explicit_super_clauses_of[def_id] <- self.tcx.explicit_super_clauses_of(def_id).skip_binder()); record_defaulted_array!(self.tables.explicit_implied_clauses_of[def_id] <- @@ -1611,18 +1611,18 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { if let DefKind::Closure | DefKind::SyntheticCoroutineBody = def_kind && let Some(coroutine_kind) = self.tcx.coroutine_kind(def_id) { - record_defaulted!(self.tables.coroutine_kind[def_id] <- Some(coroutine_kind)) + record_value!(self.tables.coroutine_kind[def_id] <- Some(coroutine_kind)) } if def_kind == DefKind::Closure && tcx.type_of(def_id).skip_binder().is_coroutine_closure() { let coroutine_for_closure = self.tcx.coroutine_for_closure(def_id); - record_non_lazy!(self.tables.coroutine_for_closure[def_id] <- coroutine_for_closure.into()); + record_some!(self.tables.coroutine_for_closure[def_id] <- coroutine_for_closure.into()); // If this async closure has a by-move body, record it too. if tcx.needs_coroutine_by_move_body_def_id(coroutine_for_closure) { let id = self.tcx.coroutine_by_move_body_def_id(coroutine_for_closure); - record_non_lazy!( + record_some!( self.tables.coroutine_by_move_body_def_id[coroutine_for_closure] <- id.into() ) } @@ -1630,7 +1630,9 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { if let DefKind::Static { .. } = def_kind { if !self.tcx.is_foreign_item(def_id) { match self.tcx.eval_static_initializer(def_id) { - Ok(data) => record!(self.tables.eval_static_initializer[def_id] <- data), + Ok(data) => { + record_some_lazy!(self.tables.eval_static_initializer[def_id] <- data) + } Err(err) => match err { interpret::ErrorHandled::Reported(_, _) => { self.tcx.dcx().delayed_bug(format!( @@ -1654,49 +1656,49 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { self.encode_info_for_macro(local_id); } if let DefKind::TyAlias = def_kind { - record_defaulted!(self.tables.type_alias_is_checked[def_id] <- self.tcx.type_alias_is_checked(def_id)); + record_value!(self.tables.type_alias_is_checked[def_id] <- self.tcx.type_alias_is_checked(def_id)); if self.tcx.type_alias_is_checked(def_id) { - record!(self.tables.args_known_to_outlive_alias_params[def_id] <- tcx.args_known_to_outlive_alias_params(def_id)); + record_some_lazy!(self.tables.args_known_to_outlive_alias_params[def_id] <- tcx.args_known_to_outlive_alias_params(def_id)); } } if let DefKind::OpaqueTy = def_kind { self.encode_explicit_item_bounds(def_id); self.encode_explicit_item_self_bounds(def_id); - record!(self.tables.opaque_ty_origin[def_id] <- self.tcx.opaque_ty_origin(def_id)); + record_some_lazy!(self.tables.opaque_ty_origin[def_id] <- self.tcx.opaque_ty_origin(def_id)); self.encode_precise_capturing_args(def_id); if tcx.is_conditionally_const(def_id) { record_defaulted_array!(self.tables.explicit_implied_const_bounds[def_id] <- tcx.explicit_implied_const_bounds(def_id).skip_binder()); } - record!(self.tables.args_known_to_outlive_alias_params[def_id] <- tcx.args_known_to_outlive_alias_params(def_id)); + record_some_lazy!(self.tables.args_known_to_outlive_alias_params[def_id] <- tcx.args_known_to_outlive_alias_params(def_id)); } if let DefKind::AssocTy = def_kind { let assoc_item = tcx.associated_item(def_id); match assoc_item.container { ty::AssocContainer::Trait => { - record!(self.tables.args_known_to_outlive_alias_params[def_id] <- tcx.args_known_to_outlive_alias_params(def_id)); + record_some_lazy!(self.tables.args_known_to_outlive_alias_params[def_id] <- tcx.args_known_to_outlive_alias_params(def_id)); } ty::AssocContainer::InherentImpl => { - record!(self.tables.args_known_to_outlive_alias_params[def_id] <- tcx.args_known_to_outlive_alias_params(def_id)); + record_some_lazy!(self.tables.args_known_to_outlive_alias_params[def_id] <- tcx.args_known_to_outlive_alias_params(def_id)); } ty::AssocContainer::TraitImpl(_) => {} } } if let DefKind::AnonConst = def_kind { - record!(self.tables.anon_const_kind[def_id] <- self.tcx.anon_const_kind(def_id)); + record_some_lazy!(self.tables.anon_const_kind[def_id] <- self.tcx.anon_const_kind(def_id)); } if let DefKind::Const | DefKind::AssocConst = def_kind { - record!(self.tables.const_of_item[def_id] <- self.tcx.const_of_item(def_id)); + record_some_lazy!(self.tables.const_of_item[def_id] <- self.tcx.const_of_item(def_id)); } if tcx.impl_method_has_trait_impl_trait_tys(def_id) && let Ok(table) = self.tcx.collect_return_position_impl_trait_in_trait_tys(def_id) { - record!(self.tables.collect_return_position_impl_trait_in_trait_tys[def_id] <- table); + record_some_lazy!(self.tables.collect_return_position_impl_trait_in_trait_tys[def_id] <- table); } if let DefKind::Impl { .. } | DefKind::Trait = def_kind { let table = tcx.associated_types_for_impl_traits_in_trait_or_impl(def_id); - record!(self.tables.associated_types_for_impl_traits_in_trait_or_impl[def_id] <- table); + record_some_lazy!(self.tables.associated_types_for_impl_traits_in_trait_or_impl[def_id] <- table); } } @@ -1708,7 +1710,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { } for (def_id, res_map) in &tcx.resolutions(()).doc_link_resolutions { - record!(self.tables.doc_link_resolutions[def_id.to_def_id()] <- res_map); + record_some_lazy!(self.tables.doc_link_resolutions[def_id.to_def_id()] <- res_map); } for (def_id, traits) in &tcx.resolutions(()).doc_link_traits_in_scope { @@ -1735,10 +1737,10 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { let def_id = local_def_id.to_def_id(); let tcx = self.tcx; let adt_def = tcx.adt_def(def_id); - record!(self.tables.repr_options[def_id] <- adt_def.repr()); + record_some_lazy!(self.tables.repr_options[def_id] <- adt_def.repr()); let params_in_repr = self.tcx.params_in_repr(def_id); - record!(self.tables.params_in_repr[def_id] <- params_in_repr); + record_some_lazy!(self.tables.params_in_repr[def_id] <- params_in_repr); if adt_def.is_enum() { let module_children = tcx.module_children_local(local_def_id); @@ -1758,7 +1760,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { ctor: variant.ctor.map(|(kind, def_id)| (kind, def_id.index)), is_non_exhaustive: variant.is_field_list_non_exhaustive(), }; - record!(self.tables.variant_data[variant.def_id] <- data); + record_some_lazy!(self.tables.variant_data[variant.def_id] <- data); record_array!(self.tables.associated_item_or_field_def_ids[variant.def_id] <- variant.fields.iter().map(|f| { assert!(f.did.is_local()); @@ -1766,8 +1768,8 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { })); for field in &variant.fields { - record_defaulted!(self.tables.safety[field.did] <- field.safety); - record!( + record_value!(self.tables.safety[field.did] <- field.safety); + record_some_lazy!( self.tables.mut_restriction[field.did] <- field.mut_restriction ); } @@ -1775,16 +1777,16 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { if let Some((CtorKind::Fn, ctor_def_id)) = variant.ctor { let fn_sig = tcx.fn_sig(ctor_def_id); // FIXME only encode signature for ctor_def_id - record!(self.tables.fn_sig[variant.def_id] <- fn_sig); + record_some_lazy!(self.tables.fn_sig[variant.def_id] <- fn_sig); } } if let Some(destructor) = tcx.adt_destructor(local_def_id) { - record!(self.tables.adt_destructor[def_id] <- destructor); + record_some_lazy!(self.tables.adt_destructor[def_id] <- destructor); } if let Some(destructor) = tcx.adt_async_destructor(local_def_id) { - record!(self.tables.adt_async_destructor[def_id] <- destructor); + record_some_lazy!(self.tables.adt_async_destructor[def_id] <- destructor); } } @@ -1800,7 +1802,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { // items - we encode information about proc-macros later on. if self.is_proc_macro { // Encode this here because we don't do it in encode_def_ids. - record!(self.tables.expn_that_defined[def_id] <- tcx.expn_that_defined(local_def_id)); + record_some_lazy!(self.tables.expn_that_defined[def_id] <- tcx.expn_that_defined(local_def_id)); } else { let module_children = tcx.module_children_local(local_def_id); @@ -1839,10 +1841,10 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { let item = tcx.associated_item(def_id); if matches!(item.container, AssocContainer::Trait | AssocContainer::TraitImpl(_)) { - record_defaulted!(self.tables.defaultness[def_id] <- item.defaultness(tcx)); + record_value!(self.tables.defaultness[def_id] <- item.defaultness(tcx)); } - record!(self.tables.assoc_container[def_id] <- item.container); + record_some_lazy!(self.tables.assoc_container[def_id] <- item.container); if let AssocContainer::Trait = item.container && item.is_type() @@ -1855,7 +1857,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { } } if let ty::AssocKind::Type { data: ty::AssocTypeData::Rpitit(rpitit_info) } = item.kind { - record!(self.tables.opt_rpitit_info[def_id] <- rpitit_info); + record_some_lazy!(self.tables.opt_rpitit_info[def_id] <- rpitit_info); if matches!(rpitit_info, ty::ImplTraitInTraitData::Trait { .. }) { record_array!( self.tables.assumed_wf_types_for_rpitit[def_id] @@ -1891,53 +1893,53 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { debug!("EntryBuilder::encode_mir({:?})", def_id); if encode_opt { - record!(self.tables.optimized_mir[def_id.to_def_id()] <- tcx.optimized_mir(def_id)); + record_some_lazy!(self.tables.optimized_mir[def_id.to_def_id()] <- tcx.optimized_mir(def_id)); - record_defaulted!(self.tables.cross_crate_inlinable[def_id.to_def_id()] <- self.tcx.cross_crate_inlinable(def_id)); + record_value!(self.tables.cross_crate_inlinable[def_id.to_def_id()] <- self.tcx.cross_crate_inlinable(def_id)); - record!(self.tables.closure_saved_names_of_captured_variables[def_id.to_def_id()] + record_some_lazy!(self.tables.closure_saved_names_of_captured_variables[def_id.to_def_id()] <- tcx.closure_saved_names_of_captured_variables(def_id)); if self.tcx.is_coroutine(def_id.to_def_id()) && let Some(witnesses) = tcx.mir_coroutine_witnesses(def_id) { - record!(self.tables.mir_coroutine_witnesses[def_id.to_def_id()] <- witnesses); + record_some_lazy!(self.tables.mir_coroutine_witnesses[def_id.to_def_id()] <- witnesses); } } let mut is_trivial = false; if encode_const { if let Some((val, ty)) = tcx.trivial_const(def_id) { is_trivial = true; - record!(self.tables.trivial_const[def_id.to_def_id()] <- (val, ty)); + record_some_lazy!(self.tables.trivial_const[def_id.to_def_id()] <- (val, ty)); } else { is_trivial = false; - record!(self.tables.mir_for_ctfe[def_id.to_def_id()] <- tcx.mir_for_ctfe(def_id)); + record_some_lazy!(self.tables.mir_for_ctfe[def_id.to_def_id()] <- tcx.mir_for_ctfe(def_id)); } // FIXME(generic_const_exprs): this feels wrong to have in `encode_mir` let abstract_const = tcx.thir_abstract_const(def_id); if let Ok(Some(abstract_const)) = abstract_const { - record!(self.tables.thir_abstract_const[def_id.to_def_id()] <- abstract_const); + record_some_lazy!(self.tables.thir_abstract_const[def_id.to_def_id()] <- abstract_const); } if should_encode_const(tcx.def_kind(def_id)) { let qualifs = tcx.mir_const_qualif(def_id); - record!(self.tables.mir_const_qualif[def_id.to_def_id()] <- qualifs); + record_some_lazy!(self.tables.mir_const_qualif[def_id.to_def_id()] <- qualifs); let body = tcx.hir_maybe_body_owned_by(def_id); if let Some(body) = body { let const_data = rendered_const(self.tcx, &body, def_id); - record!(self.tables.rendered_const[def_id.to_def_id()] <- const_data); + record_some_lazy!(self.tables.rendered_const[def_id.to_def_id()] <- const_data); } } } if !is_trivial { - record!(self.tables.promoted_mir[def_id.to_def_id()] <- tcx.promoted_mir(def_id)); + record_some_lazy!(self.tables.promoted_mir[def_id.to_def_id()] <- tcx.promoted_mir(def_id)); } if self.tcx.is_coroutine(def_id.to_def_id()) && let Some(witnesses) = tcx.mir_coroutine_witnesses(def_id) { - record!(self.tables.mir_coroutine_witnesses[def_id.to_def_id()] <- witnesses); + record_some_lazy!(self.tables.mir_coroutine_witnesses[def_id.to_def_id()] <- witnesses); } } @@ -1963,7 +1965,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { // the stability attributes are even enabled before using their queries. if self.feat.staged_api() || self.tcx.sess.opts.unstable_opts.force_unstable_if_unmarked { if let Some(stab) = self.tcx.lookup_stability(def_id) { - record!(self.tables.lookup_stability[def_id] <- stab) + record_some_lazy!(self.tables.lookup_stability[def_id] <- stab) } } } @@ -1974,7 +1976,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { // the stability attributes are even enabled before using their queries. if self.feat.staged_api() || self.tcx.sess.opts.unstable_opts.force_unstable_if_unmarked { if let Some(stab) = self.tcx.lookup_const_stability(def_id) { - record!(self.tables.lookup_const_stability[def_id] <- stab) + record_some_lazy!(self.tables.lookup_const_stability[def_id] <- stab) } } } @@ -1985,7 +1987,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { // the stability attributes are even enabled before using their queries. if self.feat.staged_api() || self.tcx.sess.opts.unstable_opts.force_unstable_if_unmarked { if let Some(stab) = self.tcx.lookup_default_body_stability(def_id) { - record!(self.tables.lookup_default_body_stability[def_id] <- stab) + record_some_lazy!(self.tables.lookup_default_body_stability[def_id] <- stab) } } } @@ -1993,7 +1995,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { #[instrument(level = "debug", skip(self))] fn encode_deprecation(&mut self, def_id: DefId) { if let Some(depr) = self.tcx.lookup_deprecation(def_id) { - record!(self.tables.lookup_deprecation_entry[def_id] <- depr); + record_some_lazy!(self.tables.lookup_deprecation_entry[def_id] <- depr); } } @@ -2002,8 +2004,8 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { let tcx = self.tcx; let (_, macro_def, _) = tcx.hir_expect_item(def_id).expect_macro(); - record_defaulted!(self.tables.is_macro_rules[def_id.to_def_id()] <- macro_def.macro_rules); - record!(self.tables.macro_definition[def_id.to_def_id()] <- &*macro_def.body); + record_value!(self.tables.is_macro_rules[def_id.to_def_id()] <- macro_def.macro_rules); + record_some_lazy!(self.tables.macro_definition[def_id.to_def_id()] <- &*macro_def.body); } fn encode_native_libraries(&mut self) -> LazyArray { @@ -2053,19 +2055,19 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { let proc_macro_decls_static = tcx.proc_macro_decls_static(()).unwrap().local_def_index; let stability = tcx.lookup_stability(CRATE_DEF_ID); - record_non_lazy!(self.tables.def_kind[LOCAL_CRATE.as_def_id()] <- DefKind::Mod); - record!(self.tables.def_span[LOCAL_CRATE.as_def_id()] <- tcx.def_span(LOCAL_CRATE.as_def_id())); + record_some!(self.tables.def_kind[LOCAL_CRATE.as_def_id()] <- DefKind::Mod); + record_some_lazy!(self.tables.def_span[LOCAL_CRATE.as_def_id()] <- tcx.def_span(LOCAL_CRATE.as_def_id())); self.encode_attrs(LOCAL_CRATE.as_def_id().expect_local()); let vis = tcx .local_visibility(CRATE_DEF_ID) .map_id(|mod_id| mod_id.to_local_def_id().local_def_index); - record!(self.tables.visibility[LOCAL_CRATE.as_def_id()] <- vis); + record_some_lazy!(self.tables.visibility[LOCAL_CRATE.as_def_id()] <- vis); if let Some(stability) = stability { - record!(self.tables.lookup_stability[LOCAL_CRATE.as_def_id()] <- stability); + record_some_lazy!(self.tables.lookup_stability[LOCAL_CRATE.as_def_id()] <- stability); } self.encode_deprecation(LOCAL_CRATE.as_def_id()); if let Some(res_map) = tcx.resolutions(()).doc_link_resolutions.get(&CRATE_MOD_ID) { - record!(self.tables.doc_link_resolutions[LOCAL_CRATE.as_def_id()] <- res_map); + record_some_lazy!(self.tables.doc_link_resolutions[LOCAL_CRATE.as_def_id()] <- res_map); } if let Some(traits) = tcx.resolutions(()).doc_link_traits_in_scope.get(&CRATE_MOD_ID) { record_array!(self.tables.doc_link_traits_in_scope[LOCAL_CRATE.as_def_id()] <- traits); @@ -2112,15 +2114,15 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { def_key.disambiguated_data.data = DefPathData::MacroNs(name); let def_id = id.to_def_id(); - record_non_lazy!(self.tables.def_kind[def_id] <- DefKind::Macro(macro_kind.into())); + record_some!(self.tables.def_kind[def_id] <- DefKind::Macro(macro_kind.into())); self.encode_attrs(id); - record!(self.tables.def_keys[def_id] <- def_key); - record!(self.tables.def_ident_span[def_id] <- span); - record!(self.tables.def_span[def_id] <- span); - record!(self.tables.visibility[def_id] <- ty::Visibility::Public); + record_some_lazy!(self.tables.def_keys[def_id] <- def_key); + record_some_lazy!(self.tables.def_ident_span[def_id] <- span); + record_some_lazy!(self.tables.def_span[def_id] <- span); + record_some_lazy!(self.tables.visibility[def_id] <- ty::Visibility::Public); if let Some(stability) = stability { - record!(self.tables.lookup_stability[def_id] <- stability); + record_some_lazy!(self.tables.lookup_stability[def_id] <- stability); } } @@ -2285,13 +2287,13 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { if of_trait { let header = tcx.impl_trait_header(def_id); - record!(self.tables.impl_trait_header[def_id] <- header); + record_some_lazy!(self.tables.impl_trait_header[def_id] <- header); let impl_is_fully_generic_for_reflection = tcx.impl_is_fully_generic_for_reflection(def_id); - record_defaulted!(self.tables.impl_is_fully_generic_for_reflection[def_id] <- impl_is_fully_generic_for_reflection); - record_defaulted!(self.tables.defaultness[def_id] <- tcx.defaultness(def_id)); + record_value!(self.tables.impl_is_fully_generic_for_reflection[def_id] <- impl_is_fully_generic_for_reflection); + record_value!(self.tables.defaultness[def_id] <- tcx.defaultness(def_id)); let trait_ref = header.trait_ref.instantiate_identity().skip_norm_wip(); let simplified_self_ty = fast_reject::simplify_type( @@ -2308,14 +2310,14 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { if let Ok(mut an) = trait_def.ancestors(tcx, def_id) && let Some(specialization_graph::Node::Impl(parent)) = an.nth(1) { - record_non_lazy!(self.tables.impl_parent[def_id] <- parent.into()); + record_some!(self.tables.impl_parent[def_id] <- parent.into()); } // if this is an impl of `CoerceUnsized`, create its // "unsized info", else just store None if tcx.is_lang_item(trait_ref.def_id, LangItem::CoerceUnsized) { let coerce_unsized_info = tcx.coerce_unsized_info(def_id).unwrap(); - record!(self.tables.coerce_unsized_info[def_id] <- coerce_unsized_info); + record_some_lazy!(self.tables.coerce_unsized_info[def_id] <- coerce_unsized_info); } } } From 012aa526ba6363879a4a0f23cb58f46c260a3628 Mon Sep 17 00:00:00 2001 From: aerooneqq Date: Mon, 28 Sep 2026 14:03:22 +0300 Subject: [PATCH 4/9] Create `LocalDefIndex` for metadata encoding --- compiler/rustc_hir_id/src/definitions.rs | 2 +- compiler/rustc_metadata/src/rmeta/decoder.rs | 33 ++- compiler/rustc_metadata/src/rmeta/encoder.rs | 109 ++++--- compiler/rustc_metadata/src/rmeta/mod.rs | 265 +++++++++++------- .../rustc_metadata/src/rmeta/parameterized.rs | 8 +- compiler/rustc_metadata/src/rmeta/table.rs | 8 +- 6 files changed, 263 insertions(+), 162 deletions(-) diff --git a/compiler/rustc_hir_id/src/definitions.rs b/compiler/rustc_hir_id/src/definitions.rs index 50f7a15b19adf..f7aa72597722a 100644 --- a/compiler/rustc_hir_id/src/definitions.rs +++ b/compiler/rustc_hir_id/src/definitions.rs @@ -58,7 +58,7 @@ pub struct Definitions { /// A unique identifier that we can use to lookup a definition /// precisely. It combines the index of the definition's parent (if /// any) with a `DisambiguatedDefPathData`. -#[derive(Copy, Clone, PartialEq, Debug, Encodable, BlobDecodable)] +#[derive(Copy, Clone, PartialEq, Debug, BlobDecodable)] pub struct DefKey { /// The parent path. pub parent: Option, diff --git a/compiler/rustc_metadata/src/rmeta/decoder.rs b/compiler/rustc_metadata/src/rmeta/decoder.rs index 2dd639f720e09..ef4e88303a338 100644 --- a/compiler/rustc_metadata/src/rmeta/decoder.rs +++ b/compiler/rustc_metadata/src/rmeta/decoder.rs @@ -100,12 +100,12 @@ pub(crate) struct CrateMetadata { /// Trait impl data. /// FIXME: Used only from queries and can use query cache, /// so pre-decoding can probably be avoided. - trait_impls: FxIndexMap<(u32, DefIndex), LazyArray<(DefIndex, Option)>>, + trait_impls: FxIndexMap<(u32, u32), LazyArray<(LocalDefIndex, Option)>>, /// Inherent impls which do not follow the normal coherence rules. /// /// These can be introduced using either `#![rustc_coherence_is_core]` /// or `#[rustc_allow_incoherent_impl]`. - incoherent_impls: FxIndexMap>, + incoherent_impls: FxIndexMap>, /// Proc macro function pointers for this crate, if it's a proc macro crate. raw_proc_macros: Option<&'static [ProcMacroClient]>, /// Source maps for code from the crate. @@ -831,7 +831,7 @@ impl MetadataBlob { out, "{} = crate{}", lang_item.name(), - DefPath::make(LOCAL_CRATE, id, |parent| root + DefPath::make(LOCAL_CRATE, id.into(), |parent| root .tables .def_keys .get(self, parent) @@ -891,7 +891,7 @@ impl MetadataBlob { |index| { format!( "crate{}", - DefPath::make(LOCAL_CRATE, index, |parent| root + DefPath::make(LOCAL_CRATE, index.into(), |parent| root .tables .def_keys .get(blob, parent) @@ -915,7 +915,7 @@ impl MetadataBlob { { write!(out, "\n")?; for child in children.decode(blob) { - print_item(blob, out, child, indent + 4)?; + print_item(blob, out, child.into(), indent + 4)?; } writeln!(out, "{nil: None, @@ -1276,7 +1277,7 @@ impl CrateMetadata { .root .stripped_cfg_items .decode((self, tcx)) - .map(|item| item.map_scope_id(|index| DefId { krate: cnum, index })); + .map(|item| item.map_scope_id(|index| DefId { krate: cnum, index: index.into() })); tcx.arena.alloc_from_iter(item_names) } @@ -1343,7 +1344,7 @@ impl CrateMetadata { // the view of this crate as a proc macro crate. if id == CRATE_DEF_INDEX { for (child_index, _) in data.macros.decode((self, tcx)) { - yield self.get_mod_child(tcx, child_index); + yield self.get_mod_child(tcx, child_index.into()); } } } else { @@ -1352,7 +1353,7 @@ impl CrateMetadata { let non_reexports = non_reexports.expect("provided `DefIndex` must refer to a module-like item"); for child_index in non_reexports.decode((self, tcx)) { - yield self.get_mod_child(tcx, child_index); + yield self.get_mod_child(tcx, child_index.into()); } let reexports = self.root.tables.module_children_reexports.get(self, id); @@ -1523,7 +1524,7 @@ impl CrateMetadata { // Do a reverse lookup beforehand to avoid touching the crate_num // hash map in the loop below. let key = match self.reverse_translate_def_id(trait_def_id) { - Some(def_id) => (def_id.krate.as_u32(), def_id.index), + Some(def_id) => (def_id.krate.as_u32(), def_id.index.as_u32()), None => return &[], }; @@ -1549,7 +1550,7 @@ impl CrateMetadata { .unwrap_or_else(|| panic!("missing proc macro data")) .proc_macro_quoted_spans .get(self, index) - .unwrap_or_else(|| panic!("missing proc macro quoted span: {index:?}")) + .unwrap_or_else(|| panic!("Missing proc macro quoted span: {index:?}")) .decode((self, tcx)) } @@ -2107,8 +2108,10 @@ impl CrateMetadata { ) -> impl Iterator { gen move { if let Some(data) = &self.root.proc_macro_data { - for def_id in - data.macros.decode((self, tcx)).map(move |(index, _)| DefId { index, krate }) + for def_id in data + .macros + .decode((self, tcx)) + .map(move |(index, _)| DefId { index: index.into(), krate }) { yield def_id; } @@ -2132,8 +2135,8 @@ impl CrateMetadata { self.root.tables.def_keys.size() } - fn local_def_id(&self, index: DefIndex) -> DefId { - DefId { krate: self.cnum, index } + fn local_def_id(&self, index: impl Into) -> DefId { + DefId { krate: self.cnum, index: index.into() } } // Translate a DefId from the current compilation environment to a DefId diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs index e8bc9bcb7697d..efd48ee26c8e2 100644 --- a/compiler/rustc_metadata/src/rmeta/encoder.rs +++ b/compiler/rustc_metadata/src/rmeta/encoder.rs @@ -155,13 +155,14 @@ impl<'a, 'tcx> SpanEncoder for EncodeContext<'a, 'tcx> { self.emit_u32(crate_num.as_u32()); } - fn encode_def_index(&mut self, def_index: DefIndex) { - self.emit_u32(def_index.as_u32()); + fn encode_def_index(&mut self, _: DefIndex) { + panic!("use LocalDefIndex or DefId or encode DefIndex manually") } fn encode_def_id(&mut self, def_id: DefId) { def_id.krate.encode(self); - def_id.index.encode(self); + + self.emit_u32(def_id.index.as_u32()); } fn encode_syntax_context(&mut self, syntax_context: SyntaxContext) { @@ -380,6 +381,13 @@ impl<'a, 'tcx> Encodable> for [u8] { } } +impl Encodable> for DefKey { + fn encode(&self, e: &mut EncodeContext<'_, '_>) { + self.parent.as_ref().map(|p| LocalDefIndex::from_def_index(*p)).encode(e); + self.disambiguated_data.encode(e); + } +} + impl<'a, 'tcx> TyEncoder<'tcx> for EncodeContext<'a, 'tcx> { const CLEAR_CROSS_CRATE: bool = true; @@ -410,7 +418,8 @@ macro_rules! record_some_lazy { { let value = $value; let lazy = $self.lazy(value); - $self.$tables.$table.set_some($def_id.index, lazy); + let index = LocalDefIndex::from($def_id); + $self.$tables.$table.set_some(index, lazy); } }}; } @@ -418,7 +427,8 @@ macro_rules! record_some_lazy { macro_rules! record_some { ($self:ident.$tables:ident.$table:ident[$def_id:expr] <- $value:expr) => {{ { - $self.$tables.$table.set_some($def_id.index, $value); + let index = LocalDefIndex::from($def_id); + $self.$tables.$table.set_some(index, $value); } }}; } @@ -426,7 +436,8 @@ macro_rules! record_some { macro_rules! record_value { ($self:ident.$tables:ident.$table:ident[$def_id:expr] <- $value:expr) => {{ { - $self.$tables.$table.set($def_id.index, $value); + let index = LocalDefIndex::from($def_id); + $self.$tables.$table.set(index, $value); } }}; } @@ -438,7 +449,8 @@ macro_rules! record_array { { let value = $value; let lazy = $self.lazy_array(value); - $self.$tables.$table.set_some($def_id.index, lazy); + let index = LocalDefIndex::from($def_id); + $self.$tables.$table.set_some(index, lazy); } }}; } @@ -448,7 +460,8 @@ macro_rules! record_defaulted_array { { let value = $value; let lazy = $self.lazy_array(value); - $self.$tables.$table.set($def_id.index, lazy); + let index = LocalDefIndex::from($def_id); + $self.$tables.$table.set(index, lazy); } }}; } @@ -1523,7 +1536,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { let vis = self .tcx .local_visibility(local_id) - .map_id(|mod_id| mod_id.to_local_def_id().local_def_index); + .map_id(|mod_id| mod_id.to_local_def_id().into()); record_some_lazy!(self.tables.visibility[def_id] <- vis); } if should_encode_stability(def_kind) { @@ -1583,7 +1596,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { self.tcx.explicit_implied_clauses_of(def_id).skip_binder()); let module_children = self.tcx.module_children_local(local_id); record_array!(self.tables.module_children_non_reexports[def_id] <- - module_children.iter().map(|child| child.res.def_id().index)); + module_children.iter().map(|child| LocalDefIndex::from(child.res.def_id()))); if self.tcx.is_const_trait(def_id) { record_defaulted_array!(self.tables.explicit_implied_const_bounds[def_id] <- self.tcx.explicit_implied_const_bounds(def_id).skip_binder()); @@ -1600,8 +1613,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { let associated_item_def_ids = self.tcx.associated_item_def_ids(def_id); record_array!(self.tables.associated_item_or_field_def_ids[def_id] <- associated_item_def_ids.iter().map(|&def_id| { - assert!(def_id.is_local()); - def_id.index + LocalDefIndex::from(def_id) }) ); for &def_id in associated_item_def_ids { @@ -1704,8 +1716,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { for (def_id, impls) in &tcx.crate_inherent_impls(()).0.inherent_impls { record_defaulted_array!(self.tables.inherent_impls[def_id.to_def_id()] <- impls.iter().map(|def_id| { - assert!(def_id.is_local()); - def_id.index + LocalDefIndex::from(*def_id) })); } @@ -1745,7 +1756,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { if adt_def.is_enum() { let module_children = tcx.module_children_local(local_def_id); record_array!(self.tables.module_children_non_reexports[def_id] <- - module_children.iter().map(|child| child.res.def_id().index)); + module_children.iter().map(|child| LocalDefIndex::from(child.res.def_id()))); } else { // For non-enum, there is only one variant, and its def_id is the adt's. debug_assert_eq!(adt_def.variants().len(), 1); @@ -1757,14 +1768,13 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { let data = VariantData { discr: variant.discr, idx, - ctor: variant.ctor.map(|(kind, def_id)| (kind, def_id.index)), + ctor: variant.ctor.map(|(kind, def_id)| (kind, LocalDefIndex::from(def_id))), is_non_exhaustive: variant.is_field_list_non_exhaustive(), }; record_some_lazy!(self.tables.variant_data[variant.def_id] <- data); record_array!(self.tables.associated_item_or_field_def_ids[variant.def_id] <- variant.fields.iter().map(|f| { - assert!(f.did.is_local()); - f.did.index + LocalDefIndex::from(f.did) })); for field in &variant.fields { @@ -1808,7 +1818,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { record_array!(self.tables.module_children_non_reexports[def_id] <- module_children.iter().filter(|child| child.reexport_chain.is_empty()) - .map(|child| child.res.def_id().index)); + .map(|child| LocalDefIndex::from(child.res.def_id()))); record_defaulted_array!(self.tables.module_children_reexports[def_id] <- module_children.iter().filter(|child| !child.reexport_chain.is_empty())); @@ -2052,7 +2062,9 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { let is_proc_macro = self.tcx.crate_types().contains(&CrateType::ProcMacro); if is_proc_macro { let tcx = self.tcx; - let proc_macro_decls_static = tcx.proc_macro_decls_static(()).unwrap().local_def_index; + let proc_macro_decls_static = tcx.proc_macro_decls_static(()).unwrap(); + let proc_macro_decls_static = LocalDefIndex::from(proc_macro_decls_static); + let stability = tcx.lookup_stability(CRATE_DEF_ID); record_some!(self.tables.def_kind[LOCAL_CRATE.as_def_id()] <- DefKind::Mod); @@ -2060,7 +2072,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { self.encode_attrs(LOCAL_CRATE.as_def_id().expect_local()); let vis = tcx .local_visibility(CRATE_DEF_ID) - .map_id(|mod_id| mod_id.to_local_def_id().local_def_index); + .map_id(|mod_id| LocalDefIndex::from(mod_id.to_local_def_id())); record_some_lazy!(self.tables.visibility[LOCAL_CRATE.as_def_id()] <- vis); if let Some(stability) = stability { record_some_lazy!(self.tables.lookup_stability[LOCAL_CRATE.as_def_id()] <- stability); @@ -2108,7 +2120,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { bug!("Unknown proc-macro type for item {:?}", id); }; - macros.push((id.local_def_index, self.lazy(kind))); + macros.push((id.into(), self.lazy(kind))); let mut def_key = self.tcx.hir_def_key(id); def_key.disambiguated_data.data = DefPathData::MacroNs(name); @@ -2222,32 +2234,36 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { self.lazy_array(sorted.into_iter().map(|(k, v)| (*k, *v))) } - fn encode_canonical_symbols(&mut self) -> LazyArray<(Symbol, DefIndex)> { + fn encode_canonical_symbols(&mut self) -> LazyArray<(Symbol, LocalDefIndex)> { empty_proc_macro!(self); let tcx = self.tcx; let canonical_symbols = &tcx.canonical_symbols(LOCAL_CRATE); - self.lazy_array(canonical_symbols.iter().map(|cs| (cs.symbol, cs.def_id.index))) + self.lazy_array( + canonical_symbols.iter().map(|cs| (cs.symbol, LocalDefIndex::from(cs.def_id))), + ) } - fn encode_diagnostic_items(&mut self) -> LazyArray<(Symbol, DefIndex)> { + fn encode_diagnostic_items(&mut self) -> LazyArray<(Symbol, LocalDefIndex)> { empty_proc_macro!(self); let tcx = self.tcx; let diagnostic_items = &tcx.diagnostic_items(LOCAL_CRATE).name_to_id; - self.lazy_array(diagnostic_items.iter().map(|(&name, def_id)| (name, def_id.index))) + self.lazy_array( + diagnostic_items.iter().map(|(&name, def_id)| (name, LocalDefIndex::from(*def_id))), + ) } - fn encode_fake_doc_items(&mut self) -> LazyArray { + fn encode_fake_doc_items(&mut self) -> LazyArray { empty_proc_macro!(self); let tcx = self.tcx; let fake_doc_items = &tcx.fake_doc_items(LOCAL_CRATE); - self.lazy_array(fake_doc_items.iter().map(|cs| cs.index)) + self.lazy_array(fake_doc_items.iter().map(|cs| LocalDefIndex::from(*cs))) } - fn encode_lang_items(&mut self) -> LazyArray<(DefIndex, LangItem)> { + fn encode_lang_items(&mut self) -> LazyArray<(LocalDefIndex, LangItem)> { empty_proc_macro!(self); let lang_items = self.tcx.lang_items().iter(); self.lazy_array(lang_items.filter_map(|(lang_item, def_id)| { - def_id.as_local().map(|id| (id.local_def_index, lang_item)) + def_id.as_local().map(|id| (LocalDefIndex::from(id), lang_item)) })) } @@ -2257,18 +2273,20 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { self.lazy_array(&tcx.lang_items().missing) } - fn encode_stripped_cfg_items(&mut self) -> LazyArray> { + fn encode_stripped_cfg_items(&mut self) -> LazyArray> { self.lazy_array( self.tcx .stripped_cfg_items(LOCAL_CRATE) .into_iter() - .map(|item| item.clone().map_scope_id(|def_id| def_id.index)), + .map(|item| item.clone().map_scope_id(|def_id| LocalDefIndex::from(def_id))), ) } - fn encode_traits(&mut self) -> LazyArray { + fn encode_traits(&mut self) -> LazyArray { empty_proc_macro!(self); - self.lazy_array(self.tcx.traits(LOCAL_CRATE).iter().map(|def_id| def_id.index)) + self.lazy_array( + self.tcx.traits(LOCAL_CRATE).iter().map(|def_id| LocalDefIndex::from(*def_id)), + ) } /// Encodes an index, mapping each trait to its (local) implementations. @@ -2276,7 +2294,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { fn encode_impls(&mut self) -> LazyArray { empty_proc_macro!(self); let tcx = self.tcx; - let mut trait_impls: FxIndexMap)>> = + let mut trait_impls: FxIndexMap)>> = FxIndexMap::default(); for id in tcx.hir_free_items() { @@ -2304,7 +2322,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { trait_impls .entry(trait_ref.def_id) .or_default() - .push((id.owner_id.def_id.local_def_index, simplified_self_ty)); + .push((LocalDefIndex::from(id.owner_id.def_id), simplified_self_ty)); let trait_def = tcx.trait_def(trait_ref.def_id); if let Ok(mut an) = trait_def.ancestors(tcx, def_id) @@ -2325,7 +2343,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { let trait_impls: Vec<_> = trait_impls .into_iter() .map(|(trait_def_id, impls)| TraitImpls { - trait_id: (trait_def_id.krate.as_u32(), trait_def_id.index), + trait_id: (trait_def_id.krate.as_u32(), trait_def_id.index.as_u32()), impls: self.lazy_array(&impls), }) .collect(); @@ -2345,24 +2363,31 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { .iter() .map(|(&simp, impls)| IncoherentImpls { self_ty: self.lazy(simp), - impls: self.lazy_array(impls.iter().map(|def_id| def_id.local_def_index)), + impls: self.lazy_array(impls.iter().map(|def_id| LocalDefIndex::from(*def_id))), }) .collect(); self.lazy_array(&all_impls) } - fn encode_exportable_items(&mut self) -> LazyArray { + fn encode_exportable_items(&mut self) -> LazyArray { empty_proc_macro!(self); - self.lazy_array(self.tcx.exportable_items(LOCAL_CRATE).iter().map(|def_id| def_id.index)) + self.lazy_array( + self.tcx + .exportable_items(LOCAL_CRATE) + .iter() + .map(|def_id| LocalDefIndex::from(*def_id)), + ) } - fn encode_stable_order_of_exportable_impls(&mut self) -> LazyArray<(DefIndex, usize)> { + fn encode_stable_order_of_exportable_impls(&mut self) -> LazyArray<(LocalDefIndex, usize)> { empty_proc_macro!(self); let stable_order_of_exportable_impls = self.tcx.stable_order_of_exportable_impls(LOCAL_CRATE); self.lazy_array( - stable_order_of_exportable_impls.iter().map(|(def_id, idx)| (def_id.index, *idx)), + stable_order_of_exportable_impls + .iter() + .map(|(def_id, idx)| (LocalDefIndex::from(*def_id), *idx)), ) } diff --git a/compiler/rustc_metadata/src/rmeta/mod.rs b/compiler/rustc_metadata/src/rmeta/mod.rs index 2b42f91f4ea05..536a4ddd6993f 100644 --- a/compiler/rustc_metadata/src/rmeta/mod.rs +++ b/compiler/rustc_metadata/src/rmeta/mod.rs @@ -11,7 +11,9 @@ pub(crate) use parameterized::ParameterizedOverTcx; use rustc_abi::{FieldIdx, ReprOptions, VariantIdx}; use rustc_ast as ast; use rustc_attr_ir::lang_items::LangItem; -use rustc_attr_ir::{Stability, StrippedCfgItem}; +use rustc_attr_ir::{ + Attribute, ConstStability, DefaultBodyStability, Deprecation, Stability, StrippedCfgItem, +}; use rustc_crate_store::{CrateDepKind, ForeignModule, LinkagePreference, NativeLib}; use rustc_data_structures::fingerprint::Fingerprint; use rustc_data_structures::fx::FxHashMap; @@ -19,7 +21,9 @@ use rustc_data_structures::svh::Svh; use rustc_hir as hir; use rustc_hir::PreciseCapturingArgKind; use rustc_hir::def::{CtorKind, DefKind, MacroKinds}; -use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, DefIndex, DefPathHash, StableCrateId}; +use rustc_hir::def_id::{ + CrateNum, DefId, DefIdMap, DefIndex, DefPathHash, LocalDefId, StableCrateId, +}; use rustc_hir::definitions::DefKey; use rustc_index::IndexVec; use rustc_index::bit_set::DenseBitSet; @@ -39,11 +43,12 @@ use rustc_middle::ty::fast_reject::SimplifiedType; use rustc_middle::ty::{self, Ty, TyCtxt}; use rustc_middle::util::Providers; use rustc_serialize::opaque::FileEncoder; +use rustc_serialize::{Decodable, Encodable}; use rustc_session::config::mitigation_coverage::DeniedPartialMitigation; use rustc_session::config::{SymbolManglingVersion, TargetModifier}; use rustc_span::edition::Edition; use rustc_span::hygiene::{ExpnIndex, MacroKind, SyntaxContextKey}; -use rustc_span::{self, ExpnData, ExpnHash, ExpnId, Ident, Span, Symbol}; +use rustc_span::{self, BlobDecoder, ExpnData, ExpnHash, ExpnId, Ident, Span, SpanEncoder, Symbol}; use rustc_target::spec::{PanicStrategy, TargetTuple}; use table::TableBuilder; @@ -205,9 +210,9 @@ type ExpnHashTable = LazyTable>>; #[derive(MetadataEncodable, LazyDecodable)] pub(crate) struct ProcMacroData { - proc_macro_decls_static: DefIndex, + proc_macro_decls_static: LocalDefIndex, stability: Option, - macros: LazyArray<(DefIndex, LazyValue)>, + macros: LazyArray<(LocalDefIndex, LazyValue)>, proc_macro_quoted_spans: LazyTable>>, } @@ -242,6 +247,68 @@ pub(crate) struct CrateHeader { pub(crate) is_stub: bool, } +rustc_index::newtype_index! { + #[orderable] + #[debug_format = "LocalDefIndex({})"] + pub struct LocalDefIndex { + const CRATE_LOCAL_DEF_INDEX = 0; + } +} + +impl LocalDefIndex { + #[inline] + pub fn from_def_index(index: DefIndex) -> LocalDefIndex { + LocalDefIndex::from_u32(index.as_u32()) + } + + #[inline] + pub fn into_def_index(self) -> DefIndex { + self.into() + } +} + +impl From for LocalDefIndex { + #[inline] + fn from(value: LocalDefId) -> LocalDefIndex { + LocalDefIndex::from_u32(value.local_def_index.as_u32()) + } +} + +impl Into for LocalDefIndex { + #[inline] + fn into(self) -> DefIndex { + DefIndex::from_u32(self.as_u32()) + } +} + +impl Into for DefIndex { + #[inline] + fn into(self) -> LocalDefIndex { + LocalDefIndex::from_u32(self.as_u32()) + } +} + +impl From for LocalDefIndex { + #[inline] + fn from(value: DefId) -> Self { + value.expect_local().into() + } +} + +impl Decodable for LocalDefIndex { + #[inline] + fn decode(d: &mut D) -> LocalDefIndex { + LocalDefIndex::from_u32(d.read_u32()) + } +} + +impl Encodable for LocalDefIndex { + #[inline] + fn encode(&self, e: &mut E) { + e.emit_u32(self.as_u32()); + } +} + /// Serialized `.rmeta` data for a crate. /// /// When compiling a proc-macro crate, we encode many of @@ -278,15 +345,15 @@ pub(crate) struct CrateRoot { dylib_dependency_formats: LazyArray>, lib_features: LazyArray<(Symbol, FeatureStability)>, stability_implications: LazyArray<(Symbol, Symbol)>, - lang_items: LazyArray<(DefIndex, LangItem)>, + lang_items: LazyArray<(LocalDefIndex, LangItem)>, lang_items_missing: LazyArray, - stripped_cfg_items: LazyArray>, - diagnostic_items: LazyArray<(Symbol, DefIndex)>, - canonical_symbols: LazyArray<(Symbol, DefIndex)>, - fake_doc_items: LazyArray, + stripped_cfg_items: LazyArray>, + diagnostic_items: LazyArray<(Symbol, LocalDefIndex)>, + canonical_symbols: LazyArray<(Symbol, LocalDefIndex)>, + fake_doc_items: LazyArray, native_libraries: LazyArray, foreign_modules: LazyArray, - traits: LazyArray, + traits: LazyArray, impls: LazyArray, incoherent_impls: LazyArray, interpret_alloc_index: LazyArray, @@ -295,8 +362,8 @@ pub(crate) struct CrateRoot { tables: LazyTables, debugger_visualizers: LazyArray, - exportable_items: LazyArray, - stable_order_of_exportable_impls: LazyArray<(DefIndex, usize)>, + exportable_items: LazyArray, + stable_order_of_exportable_impls: LazyArray<(LocalDefIndex, usize)>, exported_non_generic_symbols: LazyArray<(ExportedSymbol<'static>, SymbolExportInfo)>, exported_generic_symbols: LazyArray<(ExportedSymbol<'static>, SymbolExportInfo)>, @@ -372,14 +439,14 @@ pub(crate) struct CrateDep { #[derive(MetadataEncodable, LazyDecodable)] pub(crate) struct TraitImpls { - trait_id: (u32, DefIndex), - impls: LazyArray<(DefIndex, Option)>, + trait_id: (u32, u32), + impls: LazyArray<(LocalDefIndex, Option)>, } #[derive(MetadataEncodable, LazyDecodable)] pub(crate) struct IncoherentImpls { self_ty: LazyValue, - impls: LazyArray, + impls: LazyArray, } /// Define `LazyTables` and `TableBuilders` at the same time. @@ -413,106 +480,106 @@ macro_rules! define_tables { define_tables! { - defaulted: - intrinsic: Table>>, - is_macro_rules: Table, - type_alias_is_checked: Table, - attr_flags: Table, + intrinsic: Table>>, + is_macro_rules: Table, + type_alias_is_checked: Table, + attr_flags: Table, // The u64 is the crate-local part of the DefPathHash. All hashes in this crate have the same // StableCrateId, so we omit encoding those into the table. // // Note also that this table is fully populated (no gaps) as every DefIndex should have a // corresponding DefPathHash. - def_path_hashes: Table, - explicit_item_bounds: Table, Span)>>, - explicit_item_self_bounds: Table, Span)>>, - inferred_outlives_of: Table, Span)>>, - explicit_super_clauses_of: Table, Span)>>, - explicit_implied_clauses_of: Table, Span)>>, - explicit_implied_const_bounds: Table, Span)>>, - inherent_impls: Table>, - opt_rpitit_info: Table>>, + def_path_hashes: Table, + explicit_item_bounds: Table, Span)>>, + explicit_item_self_bounds: Table, Span)>>, + inferred_outlives_of: Table, Span)>>, + explicit_super_clauses_of: Table, Span)>>, + explicit_implied_clauses_of: Table, Span)>>, + explicit_implied_const_bounds: Table, Span)>>, + inherent_impls: Table>, + opt_rpitit_info: Table>>, // Reexported names are not associated with individual `DefId`s, // e.g. a glob import can introduce a lot of names, all with the same `DefId`. // That's why the encoded list needs to contain `ModChild` structures describing all the names // individually instead of `DefId`s. - module_children_reexports: Table>, - ambig_module_children: Table>, - cross_crate_inlinable: Table, - asyncness: Table, - constness: Table, - safety: Table, - defaultness: Table, - impl_is_fully_generic_for_reflection: Table, + module_children_reexports: Table>, + ambig_module_children: Table>, + cross_crate_inlinable: Table, + asyncness: Table, + constness: Table, + safety: Table, + defaultness: Table, + impl_is_fully_generic_for_reflection: Table, - optional: - attributes: Table>, + attributes: Table>, // For non-reexported names in a module every name is associated with a separate `DefId`, // so we can take their names, visibilities etc from other encoded tables. - module_children_non_reexports: Table>, - associated_item_or_field_def_ids: Table>, - def_kind: Table, - visibility: Table>>, - def_span: Table>, - def_ident_span: Table>, - lookup_stability: Table>, - lookup_const_stability: Table>, - lookup_default_body_stability: Table>, - lookup_deprecation_entry: Table>, - explicit_clauses_of: Table>>, - generics_of: Table>, - type_of: Table>>>, - variances_of: Table>, - fn_sig: Table>>>, - codegen_fn_attrs: Table>, - impl_trait_header: Table>>, - const_param_default: Table>>>, - object_lifetime_default: Table>, - optimized_mir: Table>>, - mir_for_ctfe: Table>>, - trivial_const: Table)>>, - closure_saved_names_of_captured_variables: Table>>, - mir_coroutine_witnesses: Table>>, - promoted_mir: Table>>>, - thir_abstract_const: Table>>>, - impl_parent: Table, - const_conditions: Table>>, + module_children_non_reexports: Table>, + associated_item_or_field_def_ids: Table>, + def_kind: Table, + visibility: Table>>, + def_span: Table>, + def_ident_span: Table>, + lookup_stability: Table>, + lookup_const_stability: Table>, + lookup_default_body_stability: Table>, + lookup_deprecation_entry: Table>, + explicit_clauses_of: Table>>, + generics_of: Table>, + type_of: Table>>>, + variances_of: Table>, + fn_sig: Table>>>, + codegen_fn_attrs: Table>, + impl_trait_header: Table>>, + const_param_default: Table>>>, + object_lifetime_default: Table>, + optimized_mir: Table>>, + mir_for_ctfe: Table>>, + trivial_const: Table)>>, + closure_saved_names_of_captured_variables: Table>>, + mir_coroutine_witnesses: Table>>, + promoted_mir: Table>>>, + thir_abstract_const: Table>>>, + impl_parent: Table, + const_conditions: Table>>, // FIXME(eddyb) perhaps compute this on the fly if cheap enough? - coerce_unsized_info: Table>, - mir_const_qualif: Table>, - rendered_const: Table>, - rendered_precise_capturing_args: Table>>, - fn_arg_idents: Table>>, - coroutine_kind: Table, - coroutine_for_closure: Table, - adt_destructor: Table>, - adt_async_destructor: Table>, - coroutine_by_move_body_def_id: Table, - eval_static_initializer: Table>>, - trait_def: Table>, - expn_that_defined: Table>, - default_fields: Table>, - params_in_repr: Table>>, - repr_options: Table>, + coerce_unsized_info: Table>, + mir_const_qualif: Table>, + rendered_const: Table>, + rendered_precise_capturing_args: Table>>, + fn_arg_idents: Table>>, + coroutine_kind: Table, + coroutine_for_closure: Table, + adt_destructor: Table>, + adt_async_destructor: Table>, + coroutine_by_move_body_def_id: Table, + eval_static_initializer: Table>>, + trait_def: Table>, + expn_that_defined: Table>, + default_fields: Table>, + params_in_repr: Table>>, + repr_options: Table>, // `def_keys` and `def_path_hashes` represent a lazy version of a // `DefPathTable`. This allows us to avoid deserializing an entire // `DefPathTable` up front, since we may only ever use a few // definitions from any given crate. - def_keys: Table>, - variant_data: Table>, - assoc_container: Table>, - macro_definition: Table>, - deduced_param_attrs: Table>, - collect_return_position_impl_trait_in_trait_tys: Table>>>>, - doc_link_resolutions: Table>, - doc_link_traits_in_scope: Table>, - assumed_wf_types_for_rpitit: Table, Span)>>, - opaque_ty_origin: Table>>, - anon_const_kind: Table>, - const_of_item: Table>>>>, - associated_types_for_impl_traits_in_trait_or_impl: Table>>>, - live_args_for_alias_from_outlives_bounds: Table>>, - args_known_to_outlive_alias_params: Table)>>>, - mut_restriction: Table>, + def_keys: Table>, + variant_data: Table>, + assoc_container: Table>, + macro_definition: Table>, + deduced_param_attrs: Table>, + collect_return_position_impl_trait_in_trait_tys: Table>>>>, + doc_link_resolutions: Table>, + doc_link_traits_in_scope: Table>, + assumed_wf_types_for_rpitit: Table, Span)>>, + opaque_ty_origin: Table>>, + anon_const_kind: Table>, + const_of_item: Table>>>>, + associated_types_for_impl_traits_in_trait_or_impl: Table>>>, + live_args_for_alias_from_outlives_bounds: Table>>, + args_known_to_outlive_alias_params: Table)>>>, + mut_restriction: Table>, } #[derive(TyEncodable, TyDecodable)] @@ -520,7 +587,7 @@ struct VariantData { idx: VariantIdx, discr: ty::VariantDiscr, /// If this is unit or tuple-variant/struct, then this is the index of the ctor id. - ctor: Option<(CtorKind, DefIndex)>, + ctor: Option<(CtorKind, LocalDefIndex)>, is_non_exhaustive: bool, } diff --git a/compiler/rustc_metadata/src/rmeta/parameterized.rs b/compiler/rustc_metadata/src/rmeta/parameterized.rs index 670d875f885c9..6db994faad758 100644 --- a/compiler/rustc_metadata/src/rmeta/parameterized.rs +++ b/compiler/rustc_metadata/src/rmeta/parameterized.rs @@ -1,12 +1,11 @@ use std::hash::Hash; use rustc_data_structures::unord::UnordMap; -use rustc_hir::def_id::DefIndex; use rustc_index::{Idx, IndexVec}; use rustc_middle::ty::{Binder, EarlyBinder, GenericArg, Region}; use rustc_span::Symbol; -use crate::rmeta::{LazyArray, LazyValue}; +use crate::rmeta::{LazyArray, LazyValue, LocalDefIndex}; pub(crate) trait ParameterizedOverTcx: 'static { type Value<'tcx>; @@ -80,6 +79,7 @@ trivially_parameterized_over_tcx! { crate::rmeta::CrateRoot, crate::rmeta::CrateRootUnhashed, crate::rmeta::IncoherentImpls, + crate::rmeta::LocalDefIndex, crate::rmeta::ProcMacroKind, crate::rmeta::RawDefId, crate::rmeta::TraitImpls, @@ -93,7 +93,7 @@ trivially_parameterized_over_tcx! { rustc_attr_ir::EiiDecl, rustc_attr_ir::EiiImpl, rustc_attr_ir::Stability, - rustc_attr_ir::StrippedCfgItem, + rustc_attr_ir::StrippedCfgItem, rustc_attr_ir::lang_items::LangItem, rustc_crate_store::ForeignModule, rustc_crate_store::LinkagePreference, @@ -131,7 +131,7 @@ trivially_parameterized_over_tcx! { rustc_middle::ty::RestrictionKind, rustc_middle::ty::TraitDef, rustc_middle::ty::Variance, - rustc_middle::ty::Visibility, + rustc_middle::ty::Visibility, rustc_middle::ty::adjustment::CoerceUnsizedInfo, rustc_middle::ty::fast_reject::SimplifiedType, rustc_session::config::TargetModifier, diff --git a/compiler/rustc_metadata/src/rmeta/table.rs b/compiler/rustc_metadata/src/rmeta/table.rs index 7b53ebba8adfc..39c239c673e9b 100644 --- a/compiler/rustc_metadata/src/rmeta/table.rs +++ b/compiler/rustc_metadata/src/rmeta/table.rs @@ -506,8 +506,14 @@ where for<'tcx> T::Value<'tcx>: FixedSizeEncoding, { /// Given the metadata, extract out the value at a particular index (if any). - pub(super) fn get<'a, 'tcx, M: MetaBlob<'a>>(&self, metadata: M, i: I) -> T::Value<'tcx> { + pub(super) fn get<'a, 'tcx, M: MetaBlob<'a>>( + &self, + metadata: M, + i: impl Into, + ) -> T::Value<'tcx> { // Access past the end of the table returns a Default + let i = i.into(); + if i.index() >= self.len { return Default::default(); } From 6f2c13eef67e402b7dad4fbc0f5d607dcb89d5ed Mon Sep 17 00:00:00 2001 From: aerooneqq Date: Mon, 28 Sep 2026 15:00:01 +0300 Subject: [PATCH 5/9] Introduce types for encoding and decoding indices --- compiler/rustc_metadata/src/rmeta/decoder.rs | 4 +- compiler/rustc_metadata/src/rmeta/encoder.rs | 12 +- compiler/rustc_metadata/src/rmeta/mod.rs | 204 +++++++++---------- compiler/rustc_metadata/src/rmeta/table.rs | 30 +-- 4 files changed, 129 insertions(+), 121 deletions(-) diff --git a/compiler/rustc_metadata/src/rmeta/decoder.rs b/compiler/rustc_metadata/src/rmeta/decoder.rs index ef4e88303a338..59a8536a2d2c5 100644 --- a/compiler/rustc_metadata/src/rmeta/decoder.rs +++ b/compiler/rustc_metadata/src/rmeta/decoder.rs @@ -189,7 +189,7 @@ pub(super) trait LazyDecoder: BlobDecoder { self.read_lazy_offset_then(|pos| LazyArray::from_position_and_num_elems(pos, len)) } - fn read_lazy_table(&mut self, width: usize, len: usize) -> LazyTable { + fn read_lazy_table(&mut self, width: usize, len: usize) -> LazyTable { self.read_lazy_offset_then(|pos| LazyTable::from_position_and_encoded_size(pos, width, len)) } @@ -667,7 +667,7 @@ impl Decodable for LazyArray { } } -impl Decodable for LazyTable { +impl Decodable for LazyTable { fn decode(decoder: &mut D) -> Self { let width = decoder.read_usize(); let len = decoder.read_usize(); diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs index efd48ee26c8e2..102b740cac4dc 100644 --- a/compiler/rustc_metadata/src/rmeta/encoder.rs +++ b/compiler/rustc_metadata/src/rmeta/encoder.rs @@ -133,7 +133,7 @@ impl<'a, 'tcx, T> Encodable> for LazyArray { } } -impl<'a, 'tcx, I, T> Encodable> for LazyTable { +impl<'a, 'tcx, Ie, Id, T> Encodable> for LazyTable { fn encode(&self, e: &mut EncodeContext<'a, 'tcx>) { e.emit_usize(self.width); e.emit_usize(self.len); @@ -577,7 +577,9 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { self.lazy(DefPathHashMapRef::BorrowedFromTcx(self.tcx.def_path_hash_to_def_index_map())) } - fn encode_source_map(&mut self) -> LazyTable>> { + fn encode_source_map( + &mut self, + ) -> LazyTable>> { let source_map = self.tcx.sess.source_map(); let all_source_files = source_map.files(); @@ -2031,9 +2033,9 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { } fn encode_hygiene(&mut self) -> (SyntaxContextTable, ExpnDataTable, ExpnHashTable) { - let mut syntax_contexts: TableBuilder<_, _> = Default::default(); - let mut expn_data_table: TableBuilder<_, _> = Default::default(); - let mut expn_hash_table: TableBuilder<_, _> = Default::default(); + let mut syntax_contexts: TableBuilder<_, _, _> = Default::default(); + let mut expn_data_table: TableBuilder<_, _, _> = Default::default(); + let mut expn_hash_table: TableBuilder<_, _, _> = Default::default(); HygieneEncodeContext::encode( &Rc::clone(&self.hygiene_ctxt), diff --git a/compiler/rustc_metadata/src/rmeta/mod.rs b/compiler/rustc_metadata/src/rmeta/mod.rs index 536a4ddd6993f..551a8b43a754d 100644 --- a/compiler/rustc_metadata/src/rmeta/mod.rs +++ b/compiler/rustc_metadata/src/rmeta/mod.rs @@ -148,22 +148,22 @@ impl LazyArray { /// Random-access table (i.e. offering constant-time `get`/`set`), similar to /// `LazyArray`, but without requiring encoding or decoding all the values /// eagerly and in-order. -struct LazyTable { +struct LazyTable { position: NonZero, /// The encoded size of the elements of a table is selected at runtime to drop /// trailing zeroes. This is the number of bytes used for each table element. width: usize, /// How many elements are in the table. len: usize, - _marker: PhantomData T>, + _marker: PhantomData T>, } -impl LazyTable { +impl LazyTable { fn from_position_and_encoded_size( position: NonZero, width: usize, len: usize, - ) -> LazyTable { + ) -> LazyTable { LazyTable { position, width, len, _marker: PhantomData } } } @@ -182,8 +182,8 @@ impl Clone for LazyArray { } } -impl Copy for LazyTable {} -impl Clone for LazyTable { +impl Copy for LazyTable {} +impl Clone for LazyTable { fn clone(&self) -> Self { *self } @@ -204,16 +204,16 @@ enum LazyState { Previous(NonZero), } -type SyntaxContextTable = LazyTable>>; -type ExpnDataTable = LazyTable>>; -type ExpnHashTable = LazyTable>>; +type SyntaxContextTable = LazyTable>>; +type ExpnDataTable = LazyTable>>; +type ExpnHashTable = LazyTable>>; #[derive(MetadataEncodable, LazyDecodable)] pub(crate) struct ProcMacroData { proc_macro_decls_static: LocalDefIndex, stability: Option, macros: LazyArray<(LocalDefIndex, LazyValue)>, - proc_macro_quoted_spans: LazyTable>>, + proc_macro_quoted_spans: LazyTable>>, } #[derive(MetadataEncodable, LazyDecodable)] @@ -250,19 +250,19 @@ pub(crate) struct CrateHeader { rustc_index::newtype_index! { #[orderable] #[debug_format = "LocalDefIndex({})"] - pub struct LocalDefIndex { + pub(crate) struct LocalDefIndex { const CRATE_LOCAL_DEF_INDEX = 0; } } impl LocalDefIndex { #[inline] - pub fn from_def_index(index: DefIndex) -> LocalDefIndex { + pub(crate) fn from_def_index(index: DefIndex) -> LocalDefIndex { LocalDefIndex::from_u32(index.as_u32()) } #[inline] - pub fn into_def_index(self) -> DefIndex { + pub(crate) fn into_def_index(self) -> DefIndex { self.into() } } @@ -373,7 +373,7 @@ pub(crate) struct CrateRoot { def_path_hash_map: LazyValue>, - source_map: LazyTable>>, + source_map: LazyTable>>, target_modifiers: LazyArray, denied_partial_mitigations: LazyArray, @@ -452,19 +452,19 @@ pub(crate) struct IncoherentImpls { /// Define `LazyTables` and `TableBuilders` at the same time. macro_rules! define_tables { ( - - defaulted: $($name1:ident: Table<$IDX1:ty, $T1:ty>,)+ - - optional: $($name2:ident: Table<$IDX2:ty, $T2:ty>,)+ + - defaulted: $($name1:ident: Table<$T1:ty>,)+ + - optional: $($name2:ident: Table<$T2:ty>,)+ ) => { #[derive(MetadataEncodable, LazyDecodable)] pub(crate) struct LazyTables { - $($name1: LazyTable<$IDX1, $T1>,)+ - $($name2: LazyTable<$IDX2, Option<$T2>>,)+ + $($name1: LazyTable,)+ + $($name2: LazyTable>,)+ } #[derive(Default)] struct TableBuilders { - $($name1: TableBuilder<$IDX1, $T1>,)+ - $($name2: TableBuilder<$IDX2, Option<$T2>>,)+ + $($name1: TableBuilder,)+ + $($name2: TableBuilder>,)+ } impl TableBuilders { @@ -480,106 +480,106 @@ macro_rules! define_tables { define_tables! { - defaulted: - intrinsic: Table>>, - is_macro_rules: Table, - type_alias_is_checked: Table, - attr_flags: Table, + intrinsic: Table>>, + is_macro_rules: Table, + type_alias_is_checked: Table, + attr_flags: Table, // The u64 is the crate-local part of the DefPathHash. All hashes in this crate have the same // StableCrateId, so we omit encoding those into the table. // // Note also that this table is fully populated (no gaps) as every DefIndex should have a // corresponding DefPathHash. - def_path_hashes: Table, - explicit_item_bounds: Table, Span)>>, - explicit_item_self_bounds: Table, Span)>>, - inferred_outlives_of: Table, Span)>>, - explicit_super_clauses_of: Table, Span)>>, - explicit_implied_clauses_of: Table, Span)>>, - explicit_implied_const_bounds: Table, Span)>>, - inherent_impls: Table>, - opt_rpitit_info: Table>>, + def_path_hashes: Table, + explicit_item_bounds: Table, Span)>>, + explicit_item_self_bounds: Table, Span)>>, + inferred_outlives_of: Table, Span)>>, + explicit_super_clauses_of: Table, Span)>>, + explicit_implied_clauses_of: Table, Span)>>, + explicit_implied_const_bounds: Table, Span)>>, + inherent_impls: Table>, + opt_rpitit_info: Table>>, // Reexported names are not associated with individual `DefId`s, // e.g. a glob import can introduce a lot of names, all with the same `DefId`. // That's why the encoded list needs to contain `ModChild` structures describing all the names // individually instead of `DefId`s. - module_children_reexports: Table>, - ambig_module_children: Table>, - cross_crate_inlinable: Table, - asyncness: Table, - constness: Table, - safety: Table, - defaultness: Table, - impl_is_fully_generic_for_reflection: Table, + module_children_reexports: Table>, + ambig_module_children: Table>, + cross_crate_inlinable: Table, + asyncness: Table, + constness: Table, + safety: Table, + defaultness: Table, + impl_is_fully_generic_for_reflection: Table, - optional: - attributes: Table>, + attributes: Table>, // For non-reexported names in a module every name is associated with a separate `DefId`, // so we can take their names, visibilities etc from other encoded tables. - module_children_non_reexports: Table>, - associated_item_or_field_def_ids: Table>, - def_kind: Table, - visibility: Table>>, - def_span: Table>, - def_ident_span: Table>, - lookup_stability: Table>, - lookup_const_stability: Table>, - lookup_default_body_stability: Table>, - lookup_deprecation_entry: Table>, - explicit_clauses_of: Table>>, - generics_of: Table>, - type_of: Table>>>, - variances_of: Table>, - fn_sig: Table>>>, - codegen_fn_attrs: Table>, - impl_trait_header: Table>>, - const_param_default: Table>>>, - object_lifetime_default: Table>, - optimized_mir: Table>>, - mir_for_ctfe: Table>>, - trivial_const: Table)>>, - closure_saved_names_of_captured_variables: Table>>, - mir_coroutine_witnesses: Table>>, - promoted_mir: Table>>>, - thir_abstract_const: Table>>>, - impl_parent: Table, - const_conditions: Table>>, + module_children_non_reexports: Table>, + associated_item_or_field_def_ids: Table>, + def_kind: Table, + visibility: Table>>, + def_span: Table>, + def_ident_span: Table>, + lookup_stability: Table>, + lookup_const_stability: Table>, + lookup_default_body_stability: Table>, + lookup_deprecation_entry: Table>, + explicit_clauses_of: Table>>, + generics_of: Table>, + type_of: Table>>>, + variances_of: Table>, + fn_sig: Table>>>, + codegen_fn_attrs: Table>, + impl_trait_header: Table>>, + const_param_default: Table>>>, + object_lifetime_default: Table>, + optimized_mir: Table>>, + mir_for_ctfe: Table>>, + trivial_const: Table)>>, + closure_saved_names_of_captured_variables: Table>>, + mir_coroutine_witnesses: Table>>, + promoted_mir: Table>>>, + thir_abstract_const: Table>>>, + impl_parent: Table, + const_conditions: Table>>, // FIXME(eddyb) perhaps compute this on the fly if cheap enough? - coerce_unsized_info: Table>, - mir_const_qualif: Table>, - rendered_const: Table>, - rendered_precise_capturing_args: Table>>, - fn_arg_idents: Table>>, - coroutine_kind: Table, - coroutine_for_closure: Table, - adt_destructor: Table>, - adt_async_destructor: Table>, - coroutine_by_move_body_def_id: Table, - eval_static_initializer: Table>>, - trait_def: Table>, - expn_that_defined: Table>, - default_fields: Table>, - params_in_repr: Table>>, - repr_options: Table>, + coerce_unsized_info: Table>, + mir_const_qualif: Table>, + rendered_const: Table>, + rendered_precise_capturing_args: Table>>, + fn_arg_idents: Table>>, + coroutine_kind: Table, + coroutine_for_closure: Table, + adt_destructor: Table>, + adt_async_destructor: Table>, + coroutine_by_move_body_def_id: Table, + eval_static_initializer: Table>>, + trait_def: Table>, + expn_that_defined: Table>, + default_fields: Table>, + params_in_repr: Table>>, + repr_options: Table>, // `def_keys` and `def_path_hashes` represent a lazy version of a // `DefPathTable`. This allows us to avoid deserializing an entire // `DefPathTable` up front, since we may only ever use a few // definitions from any given crate. - def_keys: Table>, - variant_data: Table>, - assoc_container: Table>, - macro_definition: Table>, - deduced_param_attrs: Table>, - collect_return_position_impl_trait_in_trait_tys: Table>>>>, - doc_link_resolutions: Table>, - doc_link_traits_in_scope: Table>, - assumed_wf_types_for_rpitit: Table, Span)>>, - opaque_ty_origin: Table>>, - anon_const_kind: Table>, - const_of_item: Table>>>>, - associated_types_for_impl_traits_in_trait_or_impl: Table>>>, - live_args_for_alias_from_outlives_bounds: Table>>, - args_known_to_outlive_alias_params: Table)>>>, - mut_restriction: Table>, + def_keys: Table>, + variant_data: Table>, + assoc_container: Table>, + macro_definition: Table>, + deduced_param_attrs: Table>, + collect_return_position_impl_trait_in_trait_tys: Table>>>>, + doc_link_resolutions: Table>, + doc_link_traits_in_scope: Table>, + assumed_wf_types_for_rpitit: Table, Span)>>, + opaque_ty_origin: Table>>, + anon_const_kind: Table>, + const_of_item: Table>>>>, + associated_types_for_impl_traits_in_trait_or_impl: Table>>>, + live_args_for_alias_from_outlives_bounds: Table>>, + args_known_to_outlive_alias_params: Table)>>>, + mut_restriction: Table>, } #[derive(TyEncodable, TyDecodable)] diff --git a/compiler/rustc_metadata/src/rmeta/table.rs b/compiler/rustc_metadata/src/rmeta/table.rs index 39c239c673e9b..af37933ded225 100644 --- a/compiler/rustc_metadata/src/rmeta/table.rs +++ b/compiler/rustc_metadata/src/rmeta/table.rs @@ -427,34 +427,36 @@ impl FixedSizeEncoding for Option> { } /// Helper for constructing a table's serialization (also see `Table`). -pub(super) struct TableBuilder { +pub(super) struct TableBuilder { width: usize, - blocks: IndexVec, - _marker: PhantomData, + blocks: IndexVec, + _marker: PhantomData ()>, } -impl Default for TableBuilder { +impl Default for TableBuilder { fn default() -> Self { TableBuilder { width: 0, blocks: Default::default(), _marker: PhantomData } } } -impl TableBuilder> +impl TableBuilder> where Option: FixedSizeEncoding, { - pub(crate) fn set_some(&mut self, i: I, value: T) { + pub(crate) fn set_some(&mut self, i: Ie, value: T) { self.set(i, Some(value)) } } -impl> TableBuilder { +impl> + TableBuilder +{ /// Sets the table value if it is not default. /// ATTENTION: For optimization default values are simply ignored by this function, because /// right now metadata tables never need to reset non-default values to default. If such need /// arises in the future then a new method (e.g. `clear` or `reset`) will need to be introduced /// for doing that explicitly. - pub(crate) fn set(&mut self, i: I, value: T) { + pub(crate) fn set(&mut self, i: Ie, value: T) { #[cfg(debug_assertions)] { debug_assert!( @@ -477,7 +479,7 @@ impl> TableBui } } - pub(crate) fn encode(&self, buf: &mut FileEncoder<'_>) -> LazyTable { + pub(crate) fn encode(&self, buf: &mut FileEncoder<'_>) -> LazyTable { let pos = buf.position(); let width = self.width; @@ -500,8 +502,12 @@ fn trailing_zeros(x: &[u8]) -> usize { x.iter().rev().take_while(|b| **b == 0).count() } -impl + ParameterizedOverTcx> - LazyTable +impl< + Ie: Idx, + Id: Idx, + const N: usize, + T: FixedSizeEncoding + ParameterizedOverTcx, +> LazyTable where for<'tcx> T::Value<'tcx>: FixedSizeEncoding, { @@ -509,7 +515,7 @@ where pub(super) fn get<'a, 'tcx, M: MetaBlob<'a>>( &self, metadata: M, - i: impl Into, + i: impl Into, ) -> T::Value<'tcx> { // Access past the end of the table returns a Default let i = i.into(); From e6d986b04022668350bf1fdf8d421d9ee9b848f5 Mon Sep 17 00:00:00 2001 From: aerooneqq Date: Mon, 28 Sep 2026 15:09:50 +0300 Subject: [PATCH 6/9] Remove impl Into for DefIndex --- compiler/rustc_metadata/src/rmeta/mod.rs | 7 ------- compiler/rustc_metadata/src/rmeta/table.rs | 8 +------- 2 files changed, 1 insertion(+), 14 deletions(-) diff --git a/compiler/rustc_metadata/src/rmeta/mod.rs b/compiler/rustc_metadata/src/rmeta/mod.rs index 551a8b43a754d..95b5a14ae7358 100644 --- a/compiler/rustc_metadata/src/rmeta/mod.rs +++ b/compiler/rustc_metadata/src/rmeta/mod.rs @@ -281,13 +281,6 @@ impl Into for LocalDefIndex { } } -impl Into for DefIndex { - #[inline] - fn into(self) -> LocalDefIndex { - LocalDefIndex::from_u32(self.as_u32()) - } -} - impl From for LocalDefIndex { #[inline] fn from(value: DefId) -> Self { diff --git a/compiler/rustc_metadata/src/rmeta/table.rs b/compiler/rustc_metadata/src/rmeta/table.rs index af37933ded225..c9217ff52bc36 100644 --- a/compiler/rustc_metadata/src/rmeta/table.rs +++ b/compiler/rustc_metadata/src/rmeta/table.rs @@ -512,14 +512,8 @@ where for<'tcx> T::Value<'tcx>: FixedSizeEncoding, { /// Given the metadata, extract out the value at a particular index (if any). - pub(super) fn get<'a, 'tcx, M: MetaBlob<'a>>( - &self, - metadata: M, - i: impl Into, - ) -> T::Value<'tcx> { + pub(super) fn get<'a, 'tcx, M: MetaBlob<'a>>(&self, metadata: M, i: Id) -> T::Value<'tcx> { // Access past the end of the table returns a Default - let i = i.into(); - if i.index() >= self.len { return Default::default(); } From f7eba0f9b4e80be68b3f5ca274f67096f45ab01e Mon Sep 17 00:00:00 2001 From: aerooneqq Date: Mon, 28 Sep 2026 15:44:28 +0300 Subject: [PATCH 7/9] WIP --- compiler/rustc_metadata/src/rmeta/decoder.rs | 22 +++++++++++++------- compiler/rustc_metadata/src/rmeta/mod.rs | 11 ++++++++-- 2 files changed, 23 insertions(+), 10 deletions(-) diff --git a/compiler/rustc_metadata/src/rmeta/decoder.rs b/compiler/rustc_metadata/src/rmeta/decoder.rs index 59a8536a2d2c5..5a8789920ec2e 100644 --- a/compiler/rustc_metadata/src/rmeta/decoder.rs +++ b/compiler/rustc_metadata/src/rmeta/decoder.rs @@ -869,11 +869,12 @@ impl MetadataBlob { fn print_item( blob: &MetadataBlob, out: &mut dyn io::Write, - item: DefIndex, + item: LocalDefIndex, indent: usize, ) -> io::Result<()> { let root = blob.get_root(); + let item = item.into(); let def_kind = root.tables.def_kind.get(blob, item).unwrap(); let def_key = root.tables.def_keys.get(blob, item).unwrap().decode(blob); #[allow(rustc::symbol_intern_string_literal)] @@ -915,7 +916,7 @@ impl MetadataBlob { { write!(out, "\n")?; for child in children.decode(blob) { - print_item(blob, out, child.into(), indent + 4)?; + print_item(blob, out, child, indent + 4)?; } writeln!(out, "{nil: , id: DefIndex) -> ModChild { + fn get_mod_child(&self, tcx: TyCtxt<'_>, id: LocalDefIndex) -> ModChild { + let id = id.into(); let ident = self.item_ident(tcx, id); let res = Res::Def(self.def_kind(id), self.local_def_id(id)); let vis = self.get_visibility(tcx, id); @@ -1344,7 +1346,7 @@ impl CrateMetadata { // the view of this crate as a proc macro crate. if id == CRATE_DEF_INDEX { for (child_index, _) in data.macros.decode((self, tcx)) { - yield self.get_mod_child(tcx, child_index.into()); + yield self.get_mod_child(tcx, child_index); } } } else { @@ -1353,7 +1355,7 @@ impl CrateMetadata { let non_reexports = non_reexports.expect("provided `DefIndex` must refer to a module-like item"); for child_index in non_reexports.decode((self, tcx)) { - yield self.get_mod_child(tcx, child_index.into()); + yield self.get_mod_child(tcx, child_index); } let reexports = self.root.tables.module_children_reexports.get(self, id); @@ -2111,7 +2113,7 @@ impl CrateMetadata { for def_id in data .macros .decode((self, tcx)) - .map(move |(index, _)| DefId { index: index.into(), krate }) + .map(move |(index, _)| Self::create_def_id(krate, index)) { yield def_id; } @@ -2139,6 +2141,10 @@ impl CrateMetadata { DefId { krate: self.cnum, index: index.into() } } + fn create_def_id(krate: CrateNum, index: LocalDefIndex) -> DefId { + DefId { krate, index: index.into() } + } + // Translate a DefId from the current compilation environment to a DefId // for an external crate. fn reverse_translate_def_id(&self, did: DefId) -> Option { diff --git a/compiler/rustc_metadata/src/rmeta/mod.rs b/compiler/rustc_metadata/src/rmeta/mod.rs index 95b5a14ae7358..422a51845e1ab 100644 --- a/compiler/rustc_metadata/src/rmeta/mod.rs +++ b/compiler/rustc_metadata/src/rmeta/mod.rs @@ -43,7 +43,7 @@ use rustc_middle::ty::fast_reject::SimplifiedType; use rustc_middle::ty::{self, Ty, TyCtxt}; use rustc_middle::util::Providers; use rustc_serialize::opaque::FileEncoder; -use rustc_serialize::{Decodable, Encodable}; +use rustc_serialize::{Decodable, Encodable, Encoder}; use rustc_session::config::mitigation_coverage::DeniedPartialMitigation; use rustc_session::config::{SymbolManglingVersion, TargetModifier}; use rustc_span::edition::Edition; @@ -297,7 +297,14 @@ impl Decodable for LocalDefIndex { impl Encodable for LocalDefIndex { #[inline] - fn encode(&self, e: &mut E) { + default fn encode(&self, e: &mut E) { + e.emit_u32(self.as_u32()); + } +} + +impl Encodable> for LocalDefIndex { + #[inline] + fn encode(&self, e: &mut EncodeContext<'_, '_>) { e.emit_u32(self.as_u32()); } } From 6197e26af809b01a96a85c999fdd111f4ed85725 Mon Sep 17 00:00:00 2001 From: aerooneqq Date: Mon, 28 Sep 2026 17:11:37 +0300 Subject: [PATCH 8/9] Remove not needed functions --- compiler/rustc_metadata/src/rmeta/decoder.rs | 2 +- compiler/rustc_metadata/src/rmeta/encoder.rs | 2 +- compiler/rustc_metadata/src/rmeta/mod.rs | 12 ------------ 3 files changed, 2 insertions(+), 14 deletions(-) diff --git a/compiler/rustc_metadata/src/rmeta/decoder.rs b/compiler/rustc_metadata/src/rmeta/decoder.rs index 5a8789920ec2e..decd0a74948be 100644 --- a/compiler/rustc_metadata/src/rmeta/decoder.rs +++ b/compiler/rustc_metadata/src/rmeta/decoder.rs @@ -1022,7 +1022,7 @@ impl CrateMetadata { .macros .decode((self, tcx)) .enumerate() - .find(|(_pos, (i, _))| i.into_def_index() == id) + .find(|(_pos, (i, _))| i.as_u32() == id.as_u32()) .unwrap(); (self.raw_proc_macros.unwrap()[pos], kind.decode((self, tcx))) } diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs index 102b740cac4dc..fa43d356ff532 100644 --- a/compiler/rustc_metadata/src/rmeta/encoder.rs +++ b/compiler/rustc_metadata/src/rmeta/encoder.rs @@ -383,7 +383,7 @@ impl<'a, 'tcx> Encodable> for [u8] { impl Encodable> for DefKey { fn encode(&self, e: &mut EncodeContext<'_, '_>) { - self.parent.as_ref().map(|p| LocalDefIndex::from_def_index(*p)).encode(e); + self.parent.as_ref().map(|p| LocalDefIndex::from_u32(p.as_u32())).encode(e); self.disambiguated_data.encode(e); } } diff --git a/compiler/rustc_metadata/src/rmeta/mod.rs b/compiler/rustc_metadata/src/rmeta/mod.rs index 422a51845e1ab..2b44ca85329a5 100644 --- a/compiler/rustc_metadata/src/rmeta/mod.rs +++ b/compiler/rustc_metadata/src/rmeta/mod.rs @@ -255,18 +255,6 @@ rustc_index::newtype_index! { } } -impl LocalDefIndex { - #[inline] - pub(crate) fn from_def_index(index: DefIndex) -> LocalDefIndex { - LocalDefIndex::from_u32(index.as_u32()) - } - - #[inline] - pub(crate) fn into_def_index(self) -> DefIndex { - self.into() - } -} - impl From for LocalDefIndex { #[inline] fn from(value: LocalDefId) -> LocalDefIndex { From 856a150aa4861b775ed30bde45346425bf14ef0f Mon Sep 17 00:00:00 2001 From: aerooneqq Date: Mon, 28 Sep 2026 18:07:06 +0300 Subject: [PATCH 9/9] Use specializations --- compiler/rustc_hir_id/src/definitions.rs | 10 +++++++++- compiler/rustc_hir_id/src/lib.rs | 1 + 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_hir_id/src/definitions.rs b/compiler/rustc_hir_id/src/definitions.rs index f7aa72597722a..c995f5097ccf6 100644 --- a/compiler/rustc_hir_id/src/definitions.rs +++ b/compiler/rustc_hir_id/src/definitions.rs @@ -12,11 +12,12 @@ use rustc_data_structures::stable_hash::StableHasher; use rustc_hashes::Hash64; use rustc_index::IndexVec; use rustc_macros::{BlobDecodable, Decodable, Encodable, extension}; +use rustc_serialize::Encodable; pub use rustc_span::def_id::DefPathHash; use rustc_span::def_id::{ CRATE_DEF_INDEX, CrateNum, DefIndex, LOCAL_CRATE, LocalDefId, LocalDefIdMap, StableCrateId, }; -use rustc_span::{Symbol, kw, sym}; +use rustc_span::{SpanEncoder, Symbol, kw, sym}; use tracing::{debug, instrument}; use crate::def_path_hash_map::DefPathHashMap; @@ -67,6 +68,13 @@ pub struct DefKey { pub disambiguated_data: DisambiguatedDefPathData, } +impl Encodable for DefKey { + default fn encode(&self, e: &mut E) { + self.parent.encode(e); + self.disambiguated_data.encode(e); + } +} + impl DefKey { pub(crate) fn compute_stable_hash(&self, parent: DefPathHash) -> DefPathHash { let mut hasher = StableHasher::new(); diff --git a/compiler/rustc_hir_id/src/lib.rs b/compiler/rustc_hir_id/src/lib.rs index 0e01600f9cb3d..cbdcb6cc30c03 100644 --- a/compiler/rustc_hir_id/src/lib.rs +++ b/compiler/rustc_hir_id/src/lib.rs @@ -2,6 +2,7 @@ //! on all of `rustc_hir` (which is large and depends on other large things like `rustc_target`). #![allow(internal_features)] #![feature(negative_impls)] +#![feature(min_specialization)] #![feature(rustc_attrs)] pub mod def_path_hash_map;