From 37adec22c5852eef96c4e590041221a33b39a857 Mon Sep 17 00:00:00 2001 From: Matyas Susits Date: Mon, 19 Oct 2026 17:04:12 +0200 Subject: [PATCH 1/4] remove unused live_args_for_alias_from_outlives_bounds from metadata --- compiler/rustc_metadata/src/rmeta/mod.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/compiler/rustc_metadata/src/rmeta/mod.rs b/compiler/rustc_metadata/src/rmeta/mod.rs index 4d3c49497a6c2..69db5006b6270 100644 --- a/compiler/rustc_metadata/src/rmeta/mod.rs +++ b/compiler/rustc_metadata/src/rmeta/mod.rs @@ -684,7 +684,6 @@ define_tables! { 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>, } From 77d8722f0dcf8356d58c7f536771b8826c61489b Mon Sep 17 00:00:00 2001 From: Matyas Susits Date: Tue, 20 Oct 2026 14:42:35 +0200 Subject: [PATCH 2/4] rmeta: move opt_rpitit_info from defaulted to optional --- compiler/rustc_metadata/src/rmeta/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_metadata/src/rmeta/mod.rs b/compiler/rustc_metadata/src/rmeta/mod.rs index 69db5006b6270..e4eef92f9e400 100644 --- a/compiler/rustc_metadata/src/rmeta/mod.rs +++ b/compiler/rustc_metadata/src/rmeta/mod.rs @@ -604,7 +604,6 @@ define_tables! { 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 @@ -619,6 +618,7 @@ define_tables! { impl_is_fully_generic_for_reflection: Table, - optional: + opt_rpitit_info: 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. From 2e73b1db34505a4ed1ddf1c5e353abbeb9b195c1 Mon Sep 17 00:00:00 2001 From: Matyas Susits Date: Wed, 21 Oct 2026 08:34:25 +0200 Subject: [PATCH 3/4] use tcx instead of self.tcx when available --- compiler/rustc_metadata/src/rmeta/encoder.rs | 95 ++++++++++---------- 1 file changed, 47 insertions(+), 48 deletions(-) diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs index cbc6851d8d719..a14004eda185f 100644 --- a/compiler/rustc_metadata/src/rmeta/encoder.rs +++ b/compiler/rustc_metadata/src/rmeta/encoder.rs @@ -889,14 +889,14 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { // Slot 0 (`LOCAL_CRATE`) is filler; this crate's own value is `extra_filename`. let mut dep_extra_filenames = IndexVec::from_elem_n(String::new(), 1); if !self.is_proc_macro { - for &cnum in self.tcx.crates(()).iter() { - let idx = dep_extra_filenames.push(self.tcx.extra_filename(cnum).to_owned()); + for &cnum in tcx.crates(()).iter() { + let idx = dep_extra_filenames.push(tcx.extra_filename(cnum).to_owned()); assert_eq!(idx, cnum, "dep_extra_filenames must be indexed by CrateNum"); } } self.lazy(CrateRootUnhashed { - extra_filename: self.tcx.sess.opts.cg.extra_filename.clone(), + extra_filename: tcx.sess.opts.cg.extra_filename.clone(), dep_extra_filenames, }) }); @@ -1565,7 +1565,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { self.encode_attrs(local_id); } if should_encode_expn_that_defined(def_kind) { - record_some_lazy!(self.tables.expn_that_defined[local_id] <- self.tcx.expn_that_defined(def_id)); + record_some_lazy!(self.tables.expn_that_defined[local_id] <- tcx.expn_that_defined(def_id)); } if should_encode_span(def_kind) && let Some(ident_span) = tcx.def_ident_span(def_id) @@ -1573,11 +1573,10 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { record_some_lazy!(self.tables.def_ident_span[local_id] <- ident_span); } if def_kind.has_codegen_attrs() { - record_some_lazy!(self.tables.codegen_fn_attrs[local_id] <- self.tcx.codegen_fn_attrs(def_id)); + record_some_lazy!(self.tables.codegen_fn_attrs[local_id] <- 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()); + let vis = tcx.local_visibility(local_id).map_id(|mod_id| mod_id.to_local_def_id()); record_some_lazy!(self.tables.visibility[local_id] <- vis); } if should_encode_stability(def_kind) { @@ -1587,7 +1586,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { self.encode_deprecation(local_id); } if should_encode_variances(tcx, def_id, def_kind) { - let v = self.tcx.variances_of(def_id); + let v = tcx.variances_of(def_id); record_array!(self.tables.variances_of[local_id] <- v); } if should_encode_fn_sig(def_kind) { @@ -1596,25 +1595,25 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { if should_encode_generics(def_kind) { let g = tcx.generics_of(def_id); record_some_lazy!(self.tables.generics_of[local_id] <- g); - record_some_lazy!(self.tables.explicit_clauses_of[local_id] <- self.tcx.explicit_clauses_of(def_id)); - let inferred_outlives = self.tcx.inferred_outlives_of(def_id); + record_some_lazy!(self.tables.explicit_clauses_of[local_id] <- tcx.explicit_clauses_of(def_id)); + let inferred_outlives = tcx.inferred_outlives_of(def_id); record_defaulted_array!(self.tables.inferred_outlives_of[local_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); + let default = tcx.const_param_default(param.def_id); record_some_lazy!(self.tables.const_param_default[param.def_id.expect_local()] <- default); } } } if tcx.is_conditionally_const(def_id) { - record_some_lazy!(self.tables.const_conditions[local_id] <- self.tcx.const_conditions(def_id)); + record_some_lazy!(self.tables.const_conditions[local_id] <- tcx.const_conditions(def_id)); } if should_encode_type(tcx, local_id, def_kind) { - record_some_lazy!(self.tables.type_of[local_id] <- self.tcx.type_of(def_id)); + record_some_lazy!(self.tables.type_of[local_id] <- tcx.type_of(def_id)); } if should_encode_constness(def_kind) { - let constness = self.tcx.constness(def_id); + let constness = tcx.constness(def_id); record_value!(self.tables.constness[local_id] <- constness) } if let DefKind::Fn | DefKind::AssocFn = def_kind { @@ -1626,32 +1625,32 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { record_some_lazy!(self.tables.intrinsic[local_id] <- name); } if let DefKind::TyParam | DefKind::Trait = def_kind { - let default = self.tcx.object_lifetime_default(def_id); + let default = tcx.object_lifetime_default(def_id); record_some_lazy!(self.tables.object_lifetime_default[local_id] <- default); } if let DefKind::Trait = def_kind { - record_some_lazy!(self.tables.trait_def[local_id] <- self.tcx.trait_def(def_id)); + record_some_lazy!(self.tables.trait_def[local_id] <- tcx.trait_def(def_id)); record_defaulted_array!(self.tables.explicit_super_clauses_of[local_id] <- - self.tcx.explicit_super_clauses_of(def_id).skip_binder()); + tcx.explicit_super_clauses_of(def_id).skip_binder()); record_defaulted_array!(self.tables.explicit_implied_clauses_of[local_id] <- - self.tcx.explicit_implied_clauses_of(def_id).skip_binder()); - let module_children = self.tcx.module_children_local(local_id); + tcx.explicit_implied_clauses_of(def_id).skip_binder()); + let module_children = tcx.module_children_local(local_id); record_array!(self.tables.module_children_non_reexports[local_id] <- module_children.iter().map(|child| child.res.def_id().expect_local())); - if self.tcx.is_const_trait(def_id) { + if tcx.is_const_trait(def_id) { record_defaulted_array!(self.tables.explicit_implied_const_bounds[local_id] - <- self.tcx.explicit_implied_const_bounds(def_id).skip_binder()); + <- tcx.explicit_implied_const_bounds(def_id).skip_binder()); } } if let DefKind::TraitAlias = def_kind { - record_some_lazy!(self.tables.trait_def[local_id] <- self.tcx.trait_def(def_id)); + record_some_lazy!(self.tables.trait_def[local_id] <- tcx.trait_def(def_id)); record_defaulted_array!(self.tables.explicit_super_clauses_of[local_id] <- - self.tcx.explicit_super_clauses_of(def_id).skip_binder()); + tcx.explicit_super_clauses_of(def_id).skip_binder()); record_defaulted_array!(self.tables.explicit_implied_clauses_of[local_id] <- - self.tcx.explicit_implied_clauses_of(def_id).skip_binder()); + tcx.explicit_implied_clauses_of(def_id).skip_binder()); } if let DefKind::Trait | DefKind::Impl { .. } = def_kind { - let associated_item_def_ids = self.tcx.associated_item_def_ids(def_id); + let associated_item_def_ids = tcx.associated_item_def_ids(def_id); record_array!(self.tables.associated_item_or_field_def_ids[local_id] <- associated_item_def_ids.iter().map(|&def_id| { def_id.expect_local() @@ -1662,14 +1661,14 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { } } if let DefKind::Closure | DefKind::SyntheticCoroutineBody = def_kind - && let Some(coroutine_kind) = self.tcx.coroutine_kind(def_id) + && let Some(coroutine_kind) = tcx.coroutine_kind(def_id) { record_value!(self.tables.coroutine_kind[local_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); + let coroutine_for_closure = tcx.coroutine_for_closure(def_id); let remapped_id = RemappedRawDefId::create(coroutine_for_closure, &self.local_defs_remapping); @@ -1677,7 +1676,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { // 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); + let id = tcx.coroutine_by_move_body_def_id(coroutine_for_closure); let id = RemappedRawDefId::create(id, &self.local_defs_remapping); record_some!( @@ -1686,14 +1685,14 @@ 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) { + if !tcx.is_foreign_item(def_id) { + match tcx.eval_static_initializer(def_id) { Ok(data) => { record_some_lazy!(self.tables.eval_static_initializer[local_id] <- data) } Err(err) => match err { interpret::ErrorHandled::Reported(_, _) => { - self.tcx.dcx().delayed_bug(format!( + tcx.dcx().delayed_bug(format!( "eval_static_initializer returned an error in metadata emission" )); } @@ -1714,16 +1713,16 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { self.encode_info_for_macro(local_id); } if let DefKind::TyAlias = def_kind { - record_value!(self.tables.type_alias_is_checked[local_id] <- self.tcx.type_alias_is_checked(def_id)); + record_value!(self.tables.type_alias_is_checked[local_id] <- tcx.type_alias_is_checked(def_id)); - if self.tcx.type_alias_is_checked(def_id) { + if tcx.type_alias_is_checked(def_id) { record_some_lazy!(self.tables.args_known_to_outlive_alias_params[local_id] <- tcx.args_known_to_outlive_alias_params(def_id)); } } if let DefKind::OpaqueTy = def_kind { self.encode_explicit_item_bounds(local_id); self.encode_explicit_item_self_bounds(local_id); - record_some_lazy!(self.tables.opaque_ty_origin[local_id] <- self.tcx.opaque_ty_origin(def_id)); + record_some_lazy!(self.tables.opaque_ty_origin[local_id] <- tcx.opaque_ty_origin(def_id)); self.encode_precise_capturing_args(local_id); if tcx.is_conditionally_const(def_id) { record_defaulted_array!(self.tables.explicit_implied_const_bounds[local_id] @@ -1744,13 +1743,13 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { } } if let DefKind::AnonConst = def_kind { - record_some_lazy!(self.tables.anon_const_kind[local_id] <- self.tcx.anon_const_kind(def_id)); + record_some_lazy!(self.tables.anon_const_kind[local_id] <- tcx.anon_const_kind(def_id)); } if let DefKind::Const | DefKind::AssocConst = def_kind { - record_some_lazy!(self.tables.const_of_item[local_id] <- self.tcx.const_of_item(def_id)); + record_some_lazy!(self.tables.const_of_item[local_id] <- 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) + && let Ok(table) = tcx.collect_return_position_impl_trait_in_trait_tys(def_id) { record_some_lazy!(self.tables.collect_return_position_impl_trait_in_trait_tys[local_id] <- table); } @@ -1796,7 +1795,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { let adt_def = tcx.adt_def(def_id); record_some_lazy!(self.tables.repr_options[local_def_id] <- adt_def.repr()); - let params_in_repr = self.tcx.params_in_repr(def_id); + let params_in_repr = tcx.params_in_repr(def_id); record_some_lazy!(self.tables.params_in_repr[local_def_id] <- params_in_repr); if adt_def.is_enum() { @@ -1911,7 +1910,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { self.encode_explicit_item_self_bounds(def_id); if tcx.is_conditionally_const(def_id) { record_defaulted_array!(self.tables.explicit_implied_const_bounds[def_id] - <- self.tcx.explicit_implied_const_bounds(def_id).skip_binder()); + <- tcx.explicit_implied_const_bounds(def_id).skip_binder()); } } if let ty::AssocKind::Type { data: ty::AssocTypeData::Rpitit(rpitit_info) } = item.kind { @@ -1919,7 +1918,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { if matches!(rpitit_info, ty::ImplTraitInTraitData::Trait { .. }) { record_array!( self.tables.assumed_wf_types_for_rpitit[def_id] - <- self.tcx.assumed_wf_types_for_rpitit(def_id) + <- tcx.assumed_wf_types_for_rpitit(def_id) ); self.encode_precise_capturing_args(def_id); } @@ -1953,12 +1952,12 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { if encode_opt { record_some_lazy!(self.tables.optimized_mir[def_id] <- tcx.optimized_mir(def_id)); - record_value!(self.tables.cross_crate_inlinable[def_id] <- self.tcx.cross_crate_inlinable(def_id)); + record_value!(self.tables.cross_crate_inlinable[def_id] <- tcx.cross_crate_inlinable(def_id)); record_some_lazy!(self.tables.closure_saved_names_of_captured_variables[def_id] <- tcx.closure_saved_names_of_captured_variables(def_id)); - if self.tcx.is_coroutine(def_id.to_def_id()) + if tcx.is_coroutine(def_id.to_def_id()) && let Some(witnesses) = tcx.mir_coroutine_witnesses(def_id) { record_some_lazy!(self.tables.mir_coroutine_witnesses[def_id] <- witnesses); @@ -1985,7 +1984,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { record_some_lazy!(self.tables.mir_const_qualif[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); + let const_data = rendered_const(tcx, &body, def_id); record_some_lazy!(self.tables.rendered_const[def_id] <- const_data); } } @@ -1994,7 +1993,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { record_some_lazy!(self.tables.promoted_mir[def_id] <- tcx.promoted_mir(def_id)); } - if self.tcx.is_coroutine(def_id.to_def_id()) + if tcx.is_coroutine(def_id.to_def_id()) && let Some(witnesses) = tcx.mir_coroutine_witnesses(def_id) { record_some_lazy!(self.tables.mir_coroutine_witnesses[def_id] <- witnesses); @@ -2011,7 +2010,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { for &local_def_id in tcx.mir_keys(()) { if let DefKind::AssocFn | DefKind::Fn = tcx.def_kind(local_def_id) { record_array!(self.tables.deduced_param_attrs[local_def_id] <- - self.tcx.deduced_param_attrs(local_def_id.to_def_id())); + tcx.deduced_param_attrs(local_def_id.to_def_id())); } } } @@ -2169,7 +2168,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { macros.push((id, self.lazy(kind))); - let mut def_key = self.tcx.hir_def_key(id); + let mut def_key = tcx.hir_def_key(id); def_key.disambiguated_data.data = DefPathData::MacroNs(name); record_some!(self.tables.def_kind[id] <- DefKind::Macro(macro_kind.into())); @@ -2187,7 +2186,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { let macros = self.lazy_array(macros); let mut proc_macro_quoted_spans = TableBuilder::default(); - for (i, span) in self.tcx.sess.proc_macro_quoted_spans() { + for (i, span) in tcx.sess.proc_macro_quoted_spans() { proc_macro_quoted_spans.set_some(i, self.lazy(span)); } @@ -2358,7 +2357,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { let trait_ref = header.trait_ref.instantiate_identity().skip_norm_wip(); let simplified_self_ty = fast_reject::simplify_type( - self.tcx, + tcx, trait_ref.self_ty(), TreatParams::InstantiateWithInfer, ); From 10dcc9b183dfeb476665ce6c547c1bf3486762c0 Mon Sep 17 00:00:00 2001 From: Matyas Susits Date: Mon, 19 Oct 2026 14:47:59 +0200 Subject: [PATCH 4/4] Replace `record_*` macros in the metadata encoder with setter functions using the `EncodeFrom` trait --- compiler/rustc_metadata/src/rmeta/encoder.rs | 392 +++++++++--------- compiler/rustc_metadata/src/rmeta/mod.rs | 36 ++ .../rustc_metadata/src/rmeta/parameterized.rs | 140 ++++++- 3 files changed, 376 insertions(+), 192 deletions(-) diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs index a14004eda185f..2ed2156c2ba6e 100644 --- a/compiler/rustc_metadata/src/rmeta/encoder.rs +++ b/compiler/rustc_metadata/src/rmeta/encoder.rs @@ -58,7 +58,7 @@ pub(super) struct EncodeContext<'a, 'tcx> { metadata_hasher: Arc>, tcx: TyCtxt<'tcx>, feat: &'tcx rustc_feature::Features, - tables: TableBuilders, + pub(super) tables: TableBuilders, lazy_state: LazyState, span_shorthands: FxHashMap, @@ -82,7 +82,7 @@ pub(super) struct EncodeContext<'a, 'tcx> { hygiene_ctxt: Rc>, // Used for both `Symbol`s and `ByteSymbol`s. symbol_index_table: FxHashMap, - local_defs_remapping: LocalDefsRemapping, + pub(super) local_defs_remapping: LocalDefsRemapping, syntax_context_remapping: HygieneRemappingResults, local_expn_id_remapping: HygieneRemappingResults, } @@ -448,52 +448,6 @@ 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_some_lazy { - ($self:ident.$tables:ident.$table:ident[$def_id:expr] <- $value:expr) => {{ - let value = $value; - let lazy = $self.lazy(value); - let def_id = $self.local_defs_remapping.map_local_def_id($def_id); - $self.$tables.$table.set_some(def_id, lazy); - }}; -} - -macro_rules! record_some { - ($self:ident.$tables:ident.$table:ident[$def_id:expr] <- $value:expr) => {{ - let def_id = $self.local_defs_remapping.map_local_def_id($def_id); - $self.$tables.$table.set_some(def_id, $value) - }}; -} - -macro_rules! record_value { - ($self:ident.$tables:ident.$table:ident[$def_id:expr] <- $value:expr) => {{ - let def_id = $self.local_defs_remapping.map_local_def_id($def_id); - $self.$tables.$table.set(def_id, $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 { - ($self:ident.$tables:ident.$table:ident[$def_id:expr] <- $value:expr) => {{ - let value = $value; - let lazy = $self.lazy_array(value); - let def_id = $self.local_defs_remapping.map_local_def_id($def_id); - $self.$tables.$table.set_some(def_id, lazy); - }}; -} - -macro_rules! record_defaulted_array { - ($self:ident.$tables:ident.$table:ident[$def_id:expr] <- $value:expr) => {{ - let value = $value; - let lazy = $self.lazy_array(value); - let def_id = $self.local_defs_remapping.map_local_def_id($def_id); - $self.$tables.$table.set(def_id, lazy); - }}; -} - impl<'a, 'tcx> EncodeContext<'a, 'tcx> { fn emit_lazy_distance(&mut self, position: NonZero) { let pos = position.get(); @@ -517,7 +471,10 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { self.emit_usize(distance); } - fn lazy>>(&mut self, value: B) -> LazyValue + pub(super) fn lazy>>( + &mut self, + value: B, + ) -> LazyValue where T::Value<'tcx>: Encodable>, { @@ -533,7 +490,11 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { LazyValue::from_position(pos) } - fn lazy_array, B: Borrow>>( + pub(super) fn lazy_array< + T: ParameterizedOverTcx, + I: IntoIterator, + B: Borrow>, + >( &mut self, values: I, ) -> LazyArray @@ -588,16 +549,16 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { let def_key = defs.def_key(def_id); let def_path_hash = defs.def_path_hash(def_id); - 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()) + self.table_writer().def_keys(def_id, def_key); + self.table_writer().def_path_hashes(def_id, def_path_hash.local_hash().as_u64()); } } else { for def_id in self.local_defs_remapping.iter_sorted_local_ids() { let def_key = defs.def_key(def_id); let hash = defs.def_path_hash(def_id).local_hash().as_u64(); - record_some_lazy!(self.tables.def_keys[def_id] <- def_key); - record_value!(self.tables.def_path_hashes[def_id] <- hash); + self.table_writer().def_keys(def_id, def_key); + self.table_writer().def_path_hashes(def_id, hash); } } } @@ -1510,14 +1471,23 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { .iter() .filter(|attr| analyze_attr(*attr, &mut state)); - record_array!(self.tables.attributes[def_id] <- attr_iter); + self.table_writer().attributes(def_id, attr_iter); let mut attr_flags = AttrFlags::empty(); if state.is_doc_hidden { attr_flags |= AttrFlags::IS_DOC_HIDDEN; } - record_value!(self.tables.attr_flags[def_id] <- attr_flags) + self.table_writer().attr_flags(def_id, attr_flags); + } + + /// Helper struct simplifying writing to tables in the `tables` field. + /// + /// Writing to a field of `tables` should be as simple as + /// `self.table_writer().field(index, tcx.get_field_value(index))`, even for complex structs + /// that require encoding as `LazyValue`/`LazyArray` first. + fn table_writer(&mut self) -> super::TableWriter<'a, 'tcx, '_> { + super::TableWriter { encoder: self } } fn encode_def_ids(&mut self) { @@ -1533,7 +1503,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { for local_id in self.local_defs_remapping.iter_sorted_local_ids() { let def_id = local_id.to_def_id(); let def_kind = tcx.def_kind(local_id); - record_some!(self.tables.def_kind[local_id] <- def_kind); + self.table_writer().def_kind(local_id, def_kind); // The `DefCollector` will sometimes create unnecessary `DefId`s // for trivial const arguments which are directly lowered to @@ -1554,30 +1524,30 @@ 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_some_lazy!(self.tables.default_fields[local_id] <- anon.def_id.to_def_id()); + self.table_writer().default_fields(local_id, anon.def_id.to_def_id()); } if should_encode_span(def_kind) { let def_span = tcx.def_span(local_id); - record_some_lazy!(self.tables.def_span[local_id] <- def_span); + self.table_writer().def_span(local_id, def_span); } if should_encode_attrs(def_kind) { self.encode_attrs(local_id); } if should_encode_expn_that_defined(def_kind) { - record_some_lazy!(self.tables.expn_that_defined[local_id] <- tcx.expn_that_defined(def_id)); + self.table_writer().expn_that_defined(local_id, tcx.expn_that_defined(def_id)); } if should_encode_span(def_kind) && let Some(ident_span) = tcx.def_ident_span(def_id) { - record_some_lazy!(self.tables.def_ident_span[local_id] <- ident_span); + self.table_writer().def_ident_span(local_id, ident_span); } if def_kind.has_codegen_attrs() { - record_some_lazy!(self.tables.codegen_fn_attrs[local_id] <- tcx.codegen_fn_attrs(def_id)); + self.table_writer().codegen_fn_attrs(local_id, tcx.codegen_fn_attrs(def_id)); } if should_encode_visibility(def_kind) { let vis = tcx.local_visibility(local_id).map_id(|mod_id| mod_id.to_local_def_id()); - record_some_lazy!(self.tables.visibility[local_id] <- vis); + self.table_writer().visibility(local_id, vis); } if should_encode_stability(def_kind) { self.encode_stability(local_id); @@ -1587,74 +1557,84 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { } if should_encode_variances(tcx, def_id, def_kind) { let v = tcx.variances_of(def_id); - record_array!(self.tables.variances_of[local_id] <- v); + self.table_writer().variances_of(local_id, v); } if should_encode_fn_sig(def_kind) { - record_some_lazy!(self.tables.fn_sig[local_id] <- tcx.fn_sig(def_id)); + self.table_writer().fn_sig(local_id, tcx.fn_sig(def_id)); } if should_encode_generics(def_kind) { let g = tcx.generics_of(def_id); - record_some_lazy!(self.tables.generics_of[local_id] <- g); - record_some_lazy!(self.tables.explicit_clauses_of[local_id] <- tcx.explicit_clauses_of(def_id)); + self.table_writer().generics_of(local_id, g); + self.table_writer().explicit_clauses_of(local_id, tcx.explicit_clauses_of(def_id)); let inferred_outlives = tcx.inferred_outlives_of(def_id); - record_defaulted_array!(self.tables.inferred_outlives_of[local_id] <- inferred_outlives); + self.table_writer().inferred_outlives_of(local_id, inferred_outlives); for param in &g.own_params { if let ty::GenericParamDefKind::Const { has_default: true, .. } = param.kind { let default = tcx.const_param_default(param.def_id); - record_some_lazy!(self.tables.const_param_default[param.def_id.expect_local()] <- default); + self.table_writer() + .const_param_default(param.def_id.expect_local(), default); } } } if tcx.is_conditionally_const(def_id) { - record_some_lazy!(self.tables.const_conditions[local_id] <- tcx.const_conditions(def_id)); + self.table_writer().const_conditions(local_id, tcx.const_conditions(def_id)); } if should_encode_type(tcx, local_id, def_kind) { - record_some_lazy!(self.tables.type_of[local_id] <- tcx.type_of(def_id)); + self.table_writer().type_of(local_id, tcx.type_of(def_id)); } if should_encode_constness(def_kind) { let constness = tcx.constness(def_id); - record_value!(self.tables.constness[local_id] <- constness) + self.table_writer().constness(local_id, constness); } if let DefKind::Fn | DefKind::AssocFn = def_kind { let asyncness = tcx.asyncness(def_id); - record_value!(self.tables.asyncness[local_id] <- asyncness); - record_array!(self.tables.fn_arg_idents[local_id] <- tcx.fn_arg_idents(def_id)); - } - if let Some(name) = tcx.intrinsic(def_id) { - record_some_lazy!(self.tables.intrinsic[local_id] <- name); + self.table_writer().asyncness(local_id, asyncness); + self.table_writer().fn_arg_idents(local_id, tcx.fn_arg_idents(def_id)); } + self.table_writer().intrinsic(local_id, tcx.intrinsic(def_id)); if let DefKind::TyParam | DefKind::Trait = def_kind { let default = tcx.object_lifetime_default(def_id); - record_some_lazy!(self.tables.object_lifetime_default[local_id] <- default); + self.table_writer().object_lifetime_default(local_id, default); } if let DefKind::Trait = def_kind { - record_some_lazy!(self.tables.trait_def[local_id] <- tcx.trait_def(def_id)); - record_defaulted_array!(self.tables.explicit_super_clauses_of[local_id] <- - tcx.explicit_super_clauses_of(def_id).skip_binder()); - record_defaulted_array!(self.tables.explicit_implied_clauses_of[local_id] <- - tcx.explicit_implied_clauses_of(def_id).skip_binder()); + self.table_writer().trait_def(local_id, tcx.trait_def(def_id)); + self.table_writer().explicit_super_clauses_of( + local_id, + tcx.explicit_super_clauses_of(def_id).skip_binder(), + ); + self.table_writer().explicit_implied_clauses_of( + local_id, + tcx.explicit_implied_clauses_of(def_id).skip_binder(), + ); let module_children = tcx.module_children_local(local_id); - record_array!(self.tables.module_children_non_reexports[local_id] <- - module_children.iter().map(|child| child.res.def_id().expect_local())); + self.table_writer().module_children_non_reexports( + local_id, + module_children.iter().map(|child| child.res.def_id().expect_local()), + ); if tcx.is_const_trait(def_id) { - record_defaulted_array!(self.tables.explicit_implied_const_bounds[local_id] - <- tcx.explicit_implied_const_bounds(def_id).skip_binder()); + self.table_writer().explicit_implied_const_bounds( + local_id, + tcx.explicit_implied_const_bounds(def_id).skip_binder(), + ); } } if let DefKind::TraitAlias = def_kind { - record_some_lazy!(self.tables.trait_def[local_id] <- tcx.trait_def(def_id)); - record_defaulted_array!(self.tables.explicit_super_clauses_of[local_id] <- - tcx.explicit_super_clauses_of(def_id).skip_binder()); - record_defaulted_array!(self.tables.explicit_implied_clauses_of[local_id] <- - tcx.explicit_implied_clauses_of(def_id).skip_binder()); + self.table_writer().trait_def(local_id, tcx.trait_def(def_id)); + self.table_writer().explicit_super_clauses_of( + local_id, + tcx.explicit_super_clauses_of(def_id).skip_binder(), + ); + self.table_writer().explicit_implied_clauses_of( + local_id, + tcx.explicit_implied_clauses_of(def_id).skip_binder(), + ); } if let DefKind::Trait | DefKind::Impl { .. } = def_kind { let associated_item_def_ids = tcx.associated_item_def_ids(def_id); - record_array!(self.tables.associated_item_or_field_def_ids[local_id] <- - associated_item_def_ids.iter().map(|&def_id| { - def_id.expect_local() - }) + self.table_writer().associated_item_or_field_def_ids( + local_id, + associated_item_def_ids.iter().map(|&def_id| def_id.expect_local()), ); for &def_id in associated_item_def_ids { self.encode_info_for_assoc_item(def_id.expect_local()); @@ -1663,7 +1643,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { if let DefKind::Closure | DefKind::SyntheticCoroutineBody = def_kind && let Some(coroutine_kind) = tcx.coroutine_kind(def_id) { - record_value!(self.tables.coroutine_kind[local_id] <- Some(coroutine_kind)) + self.table_writer().coroutine_kind(local_id, coroutine_kind); } if def_kind == DefKind::Closure && tcx.type_of(def_id).skip_binder().is_coroutine_closure() @@ -1672,23 +1652,22 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { let remapped_id = RemappedRawDefId::create(coroutine_for_closure, &self.local_defs_remapping); - record_some!(self.tables.coroutine_for_closure[local_id] <- remapped_id); + self.table_writer().coroutine_for_closure(local_id, remapped_id); // 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 = tcx.coroutine_by_move_body_def_id(coroutine_for_closure); let id = RemappedRawDefId::create(id, &self.local_defs_remapping); - record_some!( - self.tables.coroutine_by_move_body_def_id[coroutine_for_closure.expect_local()] <- id - ) + self.table_writer() + .coroutine_by_move_body_def_id(coroutine_for_closure.expect_local(), id); } } if let DefKind::Static { .. } = def_kind { if !tcx.is_foreign_item(def_id) { match tcx.eval_static_initializer(def_id) { Ok(data) => { - record_some_lazy!(self.tables.eval_static_initializer[local_id] <- data) + self.table_writer().eval_static_initializer(local_id, data); } Err(err) => match err { interpret::ErrorHandled::Reported(_, _) => { @@ -1713,64 +1692,80 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { self.encode_info_for_macro(local_id); } if let DefKind::TyAlias = def_kind { - record_value!(self.tables.type_alias_is_checked[local_id] <- tcx.type_alias_is_checked(def_id)); + self.table_writer() + .type_alias_is_checked(local_id, tcx.type_alias_is_checked(def_id)); if tcx.type_alias_is_checked(def_id) { - record_some_lazy!(self.tables.args_known_to_outlive_alias_params[local_id] <- tcx.args_known_to_outlive_alias_params(def_id)); + self.table_writer().args_known_to_outlive_alias_params( + local_id, + tcx.args_known_to_outlive_alias_params(def_id), + ); } } if let DefKind::OpaqueTy = def_kind { self.encode_explicit_item_bounds(local_id); self.encode_explicit_item_self_bounds(local_id); - record_some_lazy!(self.tables.opaque_ty_origin[local_id] <- tcx.opaque_ty_origin(def_id)); + self.table_writer().opaque_ty_origin(local_id, tcx.opaque_ty_origin(def_id)); self.encode_precise_capturing_args(local_id); if tcx.is_conditionally_const(def_id) { - record_defaulted_array!(self.tables.explicit_implied_const_bounds[local_id] - <- tcx.explicit_implied_const_bounds(def_id).skip_binder()); + self.table_writer().explicit_implied_const_bounds( + local_id, + tcx.explicit_implied_const_bounds(def_id).skip_binder(), + ); } - record_some_lazy!(self.tables.args_known_to_outlive_alias_params[local_id] <- tcx.args_known_to_outlive_alias_params(def_id)); + self.table_writer().args_known_to_outlive_alias_params( + local_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_some_lazy!(self.tables.args_known_to_outlive_alias_params[local_id] <- tcx.args_known_to_outlive_alias_params(def_id)); + self.table_writer().args_known_to_outlive_alias_params( + local_id, + tcx.args_known_to_outlive_alias_params(def_id), + ); } ty::AssocContainer::InherentImpl => { - record_some_lazy!(self.tables.args_known_to_outlive_alias_params[local_id] <- tcx.args_known_to_outlive_alias_params(def_id)); + self.table_writer().args_known_to_outlive_alias_params( + local_id, + tcx.args_known_to_outlive_alias_params(def_id), + ); } ty::AssocContainer::TraitImpl(_) => {} } } if let DefKind::AnonConst = def_kind { - record_some_lazy!(self.tables.anon_const_kind[local_id] <- tcx.anon_const_kind(def_id)); + self.table_writer().anon_const_kind(local_id, tcx.anon_const_kind(def_id)); } if let DefKind::Const | DefKind::AssocConst = def_kind { - record_some_lazy!(self.tables.const_of_item[local_id] <- tcx.const_of_item(def_id)); + self.table_writer().const_of_item(local_id, tcx.const_of_item(def_id)); } if tcx.impl_method_has_trait_impl_trait_tys(def_id) && let Ok(table) = tcx.collect_return_position_impl_trait_in_trait_tys(def_id) { - record_some_lazy!(self.tables.collect_return_position_impl_trait_in_trait_tys[local_id] <- table); + self.table_writer() + .collect_return_position_impl_trait_in_trait_tys(local_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_some_lazy!(self.tables.associated_types_for_impl_traits_in_trait_or_impl[local_id] <- table); + self.table_writer() + .associated_types_for_impl_traits_in_trait_or_impl(local_id, table); } } for (def_id, impls) in &tcx.crate_inherent_impls(()).0.inherent_impls { - record_defaulted_array!(self.tables.inherent_impls[*def_id] <- impls.iter().map(|def_id| { - def_id.expect_local() - })); + self.table_writer() + .inherent_impls(*def_id, impls.iter().map(|def_id| def_id.expect_local())); } for (def_id, res_map) in &tcx.resolutions(()).doc_link_resolutions { - record_some_lazy!(self.tables.doc_link_resolutions[def_id.to_local_def_id()] <- res_map); + self.table_writer().doc_link_resolutions(def_id.to_local_def_id(), res_map); } for (def_id, traits) in &tcx.resolutions(()).doc_link_traits_in_scope { - record_array!(self.tables.doc_link_traits_in_scope[def_id.to_local_def_id()] <- traits); + self.table_writer().doc_link_traits_in_scope(def_id.to_local_def_id(), traits); } } @@ -1793,15 +1788,17 @@ 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_some_lazy!(self.tables.repr_options[local_def_id] <- adt_def.repr()); + self.table_writer().repr_options(local_def_id, adt_def.repr()); let params_in_repr = tcx.params_in_repr(def_id); - record_some_lazy!(self.tables.params_in_repr[local_def_id] <- params_in_repr); + self.table_writer().params_in_repr(local_def_id, params_in_repr); if adt_def.is_enum() { let module_children = tcx.module_children_local(local_def_id); - record_array!(self.tables.module_children_non_reexports[local_def_id] <- - module_children.iter().map(|child| child.res.def_id().expect_local())); + self.table_writer().module_children_non_reexports( + local_def_id, + module_children.iter().map(|child| child.res.def_id().expect_local()), + ); } 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); @@ -1818,33 +1815,32 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { ctor: variant.ctor.map(|(kind, def_id)| (kind, def_id.expect_local())), is_non_exhaustive: variant.is_field_list_non_exhaustive(), }; - record_some_lazy!(self.tables.variant_data[variant_id] <- data); + self.table_writer().variant_data(variant_id, data); - record_array!(self.tables.associated_item_or_field_def_ids[variant_id] <- variant.fields.iter().map(|f| { - f.did.expect_local() - })); + self.table_writer().associated_item_or_field_def_ids( + variant_id, + variant.fields.iter().map(|f| f.did.expect_local()), + ); for field in &variant.fields { let field_id = field.did.expect_local(); - record_value!(self.tables.safety[field_id] <- field.safety); - record_some_lazy!( - self.tables.mut_restriction[field_id] <- field.mut_restriction - ); + self.table_writer().safety(field_id, field.safety); + self.table_writer().mut_restriction(field_id, field.mut_restriction); } 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_some_lazy!(self.tables.fn_sig[variant_id] <- fn_sig); + self.table_writer().fn_sig(variant_id, fn_sig); } } if let Some(destructor) = tcx.adt_destructor(local_def_id) { - record_some_lazy!(self.tables.adt_destructor[local_def_id] <- destructor); + self.table_writer().adt_destructor(local_def_id, destructor); } if let Some(destructor) = tcx.adt_async_destructor(local_def_id) { - record_some_lazy!(self.tables.adt_async_destructor[local_def_id] <- destructor); + self.table_writer().adt_async_destructor(local_def_id, destructor); } } @@ -1859,37 +1855,43 @@ 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_some_lazy!(self.tables.expn_that_defined[local_def_id] <- tcx.expn_that_defined(local_def_id)); + self.table_writer() + .expn_that_defined(local_def_id, tcx.expn_that_defined(local_def_id)); } else { let module_children = tcx.module_children_local(local_def_id); - record_array!(self.tables.module_children_non_reexports[local_def_id] <- - module_children.iter().filter(|child| child.reexport_chain.is_empty()) - .map(|child| child.res.def_id().expect_local())); + self.table_writer().module_children_non_reexports( + local_def_id, + module_children + .iter() + .filter(|child| child.reexport_chain.is_empty()) + .map(|child| child.res.def_id().expect_local()), + ); - record_defaulted_array!(self.tables.module_children_reexports[local_def_id] <- - module_children.iter().filter(|child| !child.reexport_chain.is_empty())); + self.table_writer().module_children_reexports( + local_def_id, + module_children.iter().filter(|child| !child.reexport_chain.is_empty()), + ); let ambig_module_children = tcx .resolutions(()) .ambig_module_children .get(&local_def_id) .map_or_default(|v| &v[..]); - record_defaulted_array!(self.tables.ambig_module_children[local_def_id] <- - ambig_module_children); + self.table_writer().ambig_module_children(local_def_id, ambig_module_children); } } fn encode_explicit_item_bounds(&mut self, def_id: LocalDefId) { debug!("EncodeContext::encode_explicit_item_bounds({:?})", def_id); let bounds = self.tcx.explicit_item_bounds(def_id).skip_binder(); - record_defaulted_array!(self.tables.explicit_item_bounds[def_id] <- bounds); + self.table_writer().explicit_item_bounds(def_id, bounds); } fn encode_explicit_item_self_bounds(&mut self, def_id: LocalDefId) { debug!("EncodeContext::encode_explicit_item_self_bounds({:?})", def_id); let bounds = self.tcx.explicit_item_self_bounds(def_id).skip_binder(); - record_defaulted_array!(self.tables.explicit_item_self_bounds[def_id] <- bounds); + self.table_writer().explicit_item_self_bounds(def_id, bounds); } #[instrument(level = "debug", skip(self))] @@ -1898,10 +1900,10 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { let item = tcx.associated_item(def_id); if matches!(item.container, AssocContainer::Trait | AssocContainer::TraitImpl(_)) { - record_value!(self.tables.defaultness[def_id] <- item.defaultness(tcx)); + self.table_writer().defaultness(def_id, item.defaultness(tcx)); } - record_some_lazy!(self.tables.assoc_container[def_id] <- item.container); + self.table_writer().assoc_container(def_id, item.container); if let AssocContainer::Trait = item.container && item.is_type() @@ -1909,17 +1911,17 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { self.encode_explicit_item_bounds(def_id); self.encode_explicit_item_self_bounds(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()); + self.table_writer().explicit_implied_const_bounds( + def_id, + tcx.explicit_implied_const_bounds(def_id).skip_binder(), + ); } } if let ty::AssocKind::Type { data: ty::AssocTypeData::Rpitit(rpitit_info) } = item.kind { - record_some_lazy!(self.tables.opt_rpitit_info[def_id] <- rpitit_info); + self.table_writer().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] - <- tcx.assumed_wf_types_for_rpitit(def_id) - ); + self.table_writer() + .assumed_wf_types_for_rpitit(def_id, tcx.assumed_wf_types_for_rpitit(def_id)); self.encode_precise_capturing_args(def_id); } } @@ -1930,7 +1932,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { return; }; - record_array!(self.tables.rendered_precise_capturing_args[def_id] <- precise_capturing_args); + self.table_writer().rendered_precise_capturing_args(def_id, precise_capturing_args); } fn encode_mir(&mut self) { @@ -1950,53 +1952,56 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { debug!("EntryBuilder::encode_mir({:?})", def_id); if encode_opt { - record_some_lazy!(self.tables.optimized_mir[def_id] <- tcx.optimized_mir(def_id)); + self.table_writer().optimized_mir(def_id, tcx.optimized_mir(def_id)); - record_value!(self.tables.cross_crate_inlinable[def_id] <- tcx.cross_crate_inlinable(def_id)); + self.table_writer() + .cross_crate_inlinable(def_id, tcx.cross_crate_inlinable(def_id)); - record_some_lazy!(self.tables.closure_saved_names_of_captured_variables[def_id] - <- tcx.closure_saved_names_of_captured_variables(def_id)); + self.table_writer().closure_saved_names_of_captured_variables( + def_id, + tcx.closure_saved_names_of_captured_variables(def_id), + ); if tcx.is_coroutine(def_id.to_def_id()) && let Some(witnesses) = tcx.mir_coroutine_witnesses(def_id) { - record_some_lazy!(self.tables.mir_coroutine_witnesses[def_id] <- witnesses); + self.table_writer().mir_coroutine_witnesses(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_some_lazy!(self.tables.trivial_const[def_id] <- (val, ty)); + self.table_writer().trivial_const(def_id, (val, ty)); } else { is_trivial = false; - record_some_lazy!(self.tables.mir_for_ctfe[def_id] <- tcx.mir_for_ctfe(def_id)); + self.table_writer().mir_for_ctfe(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_some_lazy!(self.tables.thir_abstract_const[def_id] <- abstract_const); + self.table_writer().thir_abstract_const(def_id, abstract_const); } if should_encode_const(tcx.def_kind(def_id)) { let qualifs = tcx.mir_const_qualif(def_id); - record_some_lazy!(self.tables.mir_const_qualif[def_id] <- qualifs); + self.table_writer().mir_const_qualif(def_id, qualifs); let body = tcx.hir_maybe_body_owned_by(def_id); if let Some(body) = body { let const_data = rendered_const(tcx, &body, def_id); - record_some_lazy!(self.tables.rendered_const[def_id] <- const_data); + self.table_writer().rendered_const(def_id, const_data); } } } if !is_trivial { - record_some_lazy!(self.tables.promoted_mir[def_id] <- tcx.promoted_mir(def_id)); + self.table_writer().promoted_mir(def_id, tcx.promoted_mir(def_id)); } if tcx.is_coroutine(def_id.to_def_id()) && let Some(witnesses) = tcx.mir_coroutine_witnesses(def_id) { - record_some_lazy!(self.tables.mir_coroutine_witnesses[def_id] <- witnesses); + self.table_writer().mir_coroutine_witnesses(def_id, witnesses); } } @@ -2009,8 +2014,10 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { { for &local_def_id in tcx.mir_keys(()) { if let DefKind::AssocFn | DefKind::Fn = tcx.def_kind(local_def_id) { - record_array!(self.tables.deduced_param_attrs[local_def_id] <- - tcx.deduced_param_attrs(local_def_id.to_def_id())); + self.table_writer().deduced_param_attrs( + local_def_id, + tcx.deduced_param_attrs(local_def_id.to_def_id()), + ); } } } @@ -2022,7 +2029,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_some_lazy!(self.tables.lookup_stability[def_id] <- stab) + self.table_writer().lookup_stability(def_id, stab); } } } @@ -2033,7 +2040,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_some_lazy!(self.tables.lookup_const_stability[def_id] <- stab) + self.table_writer().lookup_const_stability(def_id, stab); } } } @@ -2044,7 +2051,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_some_lazy!(self.tables.lookup_default_body_stability[def_id] <- stab) + self.table_writer().lookup_default_body_stability(def_id, stab); } } } @@ -2052,7 +2059,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { #[instrument(level = "debug", skip(self))] fn encode_deprecation(&mut self, def_id: LocalDefId) { if let Some(depr) = self.tcx.lookup_deprecation(def_id.to_def_id()) { - record_some_lazy!(self.tables.lookup_deprecation_entry[def_id] <- depr); + self.table_writer().lookup_deprecation_entry(def_id, depr); } } @@ -2061,8 +2068,8 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { let tcx = self.tcx; let (_, macro_def, _) = tcx.hir_expect_item(def_id).expect_macro(); - record_value!(self.tables.is_macro_rules[def_id] <- macro_def.macro_rules); - record_some_lazy!(self.tables.macro_definition[def_id] <- &*macro_def.body); + self.table_writer().is_macro_rules(def_id, macro_def.macro_rules); + self.table_writer().macro_definition(def_id, &*macro_def.body); } fn encode_native_libraries(&mut self) -> LazyArray { @@ -2115,20 +2122,20 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { let stability = tcx.lookup_stability(CRATE_DEF_ID); - record_some!(self.tables.def_kind[CRATE_DEF_ID] <- DefKind::Mod); - record_some_lazy!(self.tables.def_span[CRATE_DEF_ID] <- tcx.def_span(CRATE_DEF_ID.to_def_id())); + self.table_writer().def_kind(CRATE_DEF_ID, DefKind::Mod); + self.table_writer().def_span(CRATE_DEF_ID, tcx.def_span(CRATE_DEF_ID.to_def_id())); self.encode_attrs(CRATE_DEF_ID); let vis = tcx.local_visibility(CRATE_DEF_ID).map_id(|mod_id| mod_id.to_local_def_id()); - record_some_lazy!(self.tables.visibility[CRATE_DEF_ID] <- vis); + self.table_writer().visibility(CRATE_DEF_ID, vis); if let Some(stability) = stability { - record_some_lazy!(self.tables.lookup_stability[CRATE_DEF_ID] <- stability); + self.table_writer().lookup_stability(CRATE_DEF_ID, stability); } self.encode_deprecation(CRATE_DEF_ID); if let Some(res_map) = tcx.resolutions(()).doc_link_resolutions.get(&CRATE_MOD_ID) { - record_some_lazy!(self.tables.doc_link_resolutions[CRATE_DEF_ID] <- res_map); + self.table_writer().doc_link_resolutions(CRATE_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[CRATE_DEF_ID] <- traits); + self.table_writer().doc_link_traits_in_scope(CRATE_DEF_ID, traits); } let mut macros = vec![]; @@ -2171,15 +2178,15 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { let mut def_key = tcx.hir_def_key(id); def_key.disambiguated_data.data = DefPathData::MacroNs(name); - record_some!(self.tables.def_kind[id] <- DefKind::Macro(macro_kind.into())); + self.table_writer().def_kind(id, DefKind::Macro(macro_kind.into())); self.encode_attrs(id); - record_some_lazy!(self.tables.def_keys[id] <- def_key); - record_some_lazy!(self.tables.def_ident_span[id] <- span); - record_some_lazy!(self.tables.def_span[id] <- span); - record_some_lazy!(self.tables.visibility[id] <- ty::Visibility::Public); + self.table_writer().def_keys(id, def_key); + self.table_writer().def_ident_span(id, span); + self.table_writer().def_span(id, span); + self.table_writer().visibility(id, ty::Visibility::Public); if let Some(stability) = stability { - record_some_lazy!(self.tables.lookup_stability[id] <- stability); + self.table_writer().lookup_stability(id, stability); } } @@ -2347,13 +2354,16 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { if of_trait { let header = tcx.impl_trait_header(local_id); - record_some_lazy!(self.tables.impl_trait_header[local_id] <- header); + self.table_writer().impl_trait_header(local_id, header); let impl_is_fully_generic_for_reflection = tcx.impl_is_fully_generic_for_reflection(local_id); - record_value!(self.tables.impl_is_fully_generic_for_reflection[local_id] <- impl_is_fully_generic_for_reflection); - record_value!(self.tables.defaultness[local_id] <- tcx.defaultness(local_id)); + self.table_writer().impl_is_fully_generic_for_reflection( + local_id, + impl_is_fully_generic_for_reflection, + ); + self.table_writer().defaultness(local_id, tcx.defaultness(local_id)); let trait_ref = header.trait_ref.instantiate_identity().skip_norm_wip(); let simplified_self_ty = fast_reject::simplify_type( @@ -2371,14 +2381,14 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { && let Some(specialization_graph::Node::Impl(parent)) = an.nth(1) { let parent = RemappedRawDefId::create(parent, &self.local_defs_remapping); - record_some!(self.tables.impl_parent[local_id] <- parent); + self.table_writer().impl_parent(local_id, parent); } // 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(local_id).unwrap(); - record_some_lazy!(self.tables.coerce_unsized_info[local_id] <- coerce_unsized_info); + self.table_writer().coerce_unsized_info(local_id, coerce_unsized_info); } } } diff --git a/compiler/rustc_metadata/src/rmeta/mod.rs b/compiler/rustc_metadata/src/rmeta/mod.rs index e4eef92f9e400..c389a5ea6afcf 100644 --- a/compiler/rustc_metadata/src/rmeta/mod.rs +++ b/compiler/rustc_metadata/src/rmeta/mod.rs @@ -54,6 +54,7 @@ use rustc_target::spec::{PanicStrategy, TargetTuple}; use table::TableBuilder; use crate::eii::EiiMapEncodedKeyValue; +use crate::rmeta::parameterized::EncodeFrom; use crate::rmeta::remapped_def_id::RemappedRawDefId; mod decoder; @@ -582,10 +583,45 @@ macro_rules! define_tables { } } } + + impl<'a, 'tcx, 'b> TableWriter<'a, 'tcx, 'b> { + $( + /// Records a value into the corresponding `TableBuilders` field, encoding it in + /// the process when necessary + fn $name1(&mut self, i: LocalDefId, v: T) + where + $T1: EncodeFrom<'tcx, T> + { + let encoded = <$T1 as EncodeFrom<'tcx, T>>::encode_from(self.encoder, v); + let idx = self.encoder.local_defs_remapping.map_local_def_id(i); + self.encoder.tables.$name1.set(idx, encoded); + } + )+ + $( + /// Records a value into the corresponding `TableBuilders` field, encoding it in + /// the process when necessary + fn $name2(&mut self, i: LocalDefId, v: T) + where + $T2: EncodeFrom<'tcx, T> + { + let encoded = <$T2 as EncodeFrom<'tcx, T>>::encode_from(self.encoder, v); + let idx = self.encoder.local_defs_remapping.map_local_def_id(i); + self.encoder.tables.$name2.set(idx, Some(encoded)); + } + )+ + } } } +/// Helper struct for writing values into [`TableBuilders`]. +#[must_use] +struct TableWriter<'a, 'tcx, 'b> { + encoder: &'b mut EncodeContext<'a, 'tcx>, +} + define_tables! { +// If the compiler complains about `EncodeFrom` or `ParameterizedOverTcx` bounds when calling a +// function generated in this macro, add them to parameterized.rs - defaulted: intrinsic: Table>>, is_macro_rules: Table, diff --git a/compiler/rustc_metadata/src/rmeta/parameterized.rs b/compiler/rustc_metadata/src/rmeta/parameterized.rs index 299a5ca906ea1..f7a4661430916 100644 --- a/compiler/rustc_metadata/src/rmeta/parameterized.rs +++ b/compiler/rustc_metadata/src/rmeta/parameterized.rs @@ -2,9 +2,11 @@ use std::hash::Hash; use rustc_data_structures::unord::UnordMap; use rustc_index::{Idx, IndexVec}; -use rustc_middle::ty::{Binder, EarlyBinder, GenericArg, Region}; +use rustc_middle::ty::{Binder, EarlyBinder, GenericArg, Region, Ty}; +use rustc_serialize::Encodable; use rustc_span::Symbol; +use crate::rmeta::encoder::EncodeContext; use crate::rmeta::{LazyArray, LazyValue, LocalDefId}; pub(crate) trait ParameterizedOverTcx: 'static { @@ -176,3 +178,139 @@ parameterized_over_tcx! { rustc_middle::ty::Ty, // tidy-alphabetical-end } + +/// Converts values from `TyCtxt` stored form into metadata table stored form +pub(super) trait EncodeFrom<'tcx, T> { + /// When a `T` is trivial to encode, it has a fixed size, no pointers inside, this can be + /// just a no-op. For more complex types this usually creates a `LazyValue` or `LazyArray` + /// encoding `value` with `encoder` in the process + fn encode_from<'a>(encoder: &mut EncodeContext<'a, 'tcx>, value: T) -> Self; +} + +macro_rules! trivial_encode_from { + ( + $($ty:ty,)+ + ) => { + $( + impl<'tcx> EncodeFrom<'tcx, $ty> for $ty { + fn encode_from<'a>( + _encoder: &mut EncodeContext<'a, 'tcx>, + value: $ty, + ) -> $ty { + value + } + } + )+ + }; +} + +macro_rules! lazy_encode_from { + ( + $($ty:ty,)+ + ) => { + $( + impl<'tcx, B> EncodeFrom<'tcx, B> for LazyValue<$ty> + where + B: std::borrow::Borrow<<$ty as ParameterizedOverTcx>::Value<'tcx>> + { + fn encode_from<'a>( + encoder: &mut EncodeContext<'a, 'tcx>, + value: B, + ) -> LazyValue<$ty> { + encoder.lazy(value) + } + } + )+ + }; +} + +trivial_encode_from! { + bool, + u64, + // tidy-alphabetical-start + crate::rmeta::AttrFlags, + crate::rmeta::remapped_def_id::RemappedRawDefId, + rustc_hir::Constness, + rustc_hir::CoroutineKind, + rustc_hir::Defaultness, + rustc_hir::Safety, + rustc_hir::def::DefKind, + rustc_middle::ty::Asyncness, + // tidy-alphabetical-end +} + +lazy_encode_from! { + // tidy-alphabetical-start + (rustc_middle::mir::ConstValue, Ty<'static>), + crate::rmeta::VariantData, + rustc_abi::ReprOptions, + rustc_ast::DelimArgs, + rustc_attr_ir::ConstStability, + rustc_attr_ir::DefaultBodyStability, + rustc_attr_ir::Deprecation, + rustc_attr_ir::Stability, + rustc_hir::OpaqueTyOrigin, + rustc_hir::def_id::DefId, + rustc_hir::def_id::DefIdMap>>, + rustc_hir::def_id::DefIdMap>, + rustc_hir::definitions::DefKey, + rustc_index::IndexVec, + rustc_index::IndexVec>, + rustc_index::bit_set::DenseBitSet, + rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrs, + rustc_middle::middle::resolve::DocLinkResMap, + rustc_middle::middle::resolve_bound_vars::ObjectLifetimeDefault, + rustc_middle::mir::Body<'static>, + rustc_middle::mir::ConstQualifs, + rustc_middle::mir::CoroutineLayout<'static>, + rustc_middle::mir::interpret::ConstAllocation<'static>, + rustc_middle::ty::AnonConstKind, + rustc_middle::ty::AssocContainer, + rustc_middle::ty::AsyncDestructor, + rustc_middle::ty::ConstConditions<'static>, + rustc_middle::ty::Destructor, + rustc_middle::ty::EarlyBinder<'static, Ty<'static>>, + rustc_middle::ty::EarlyBinder<'static, rustc_middle::ty::Const<'static>>, + rustc_middle::ty::EarlyBinder<'static, rustc_middle::ty::PolyFnSig<'static>>, + rustc_middle::ty::GenericClauses<'static>, + rustc_middle::ty::Generics, + rustc_middle::ty::ImplTraitHeader<'static>, + rustc_middle::ty::ImplTraitInTraitData, + rustc_middle::ty::IntrinsicDef, + rustc_middle::ty::RestrictionKind, + rustc_middle::ty::Visibility, + rustc_middle::ty::adjustment::CoerceUnsizedInfo, + rustc_middle::ty::trait_def::TraitDef, + rustc_span::ExpnId, + rustc_span::Span, + std::option::Option>>, + std::string::String, + std::vec::Vec<(usize, rustc_index::bit_set::DenseBitSet)>, + // tidy-alphabetical-end +} + +impl<'tcx, T, B> EncodeFrom<'tcx, Option> for Option> +where + T: ParameterizedOverTcx, + T::Value<'tcx>: for<'b> Encodable>, + B: std::borrow::Borrow>, +{ + fn encode_from<'a>( + encoder: &mut EncodeContext<'a, 'tcx>, + value: Option, + ) -> Option> { + value.map(|v| encoder.lazy(v)) + } +} + +impl<'tcx, T, I, B> EncodeFrom<'tcx, I> for LazyArray +where + T: ParameterizedOverTcx, + I: IntoIterator, + B: std::borrow::Borrow>, + T::Value<'tcx>: for<'a> Encodable>, +{ + fn encode_from<'a>(encoder: &mut EncodeContext<'a, 'tcx>, values: I) -> Self { + encoder.lazy_array(values) + } +}