From 2dfd6c65a06ac2c0e8cc32edc0d674185c78244e Mon Sep 17 00:00:00 2001 From: Matyas Susits Date: Mon, 19 Oct 2026 17:04:12 +0200 Subject: [PATCH 1/8] 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 0410874c122a6..d7aba622e4b43 100644 --- a/compiler/rustc_metadata/src/rmeta/mod.rs +++ b/compiler/rustc_metadata/src/rmeta/mod.rs @@ -672,7 +672,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 c237c248352640f000ae1baf8d99022c0eab04e6 Mon Sep 17 00:00:00 2001 From: Matyas Susits Date: Tue, 20 Oct 2026 14:42:35 +0200 Subject: [PATCH 2/8] 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 d7aba622e4b43..655f10e771aba 100644 --- a/compiler/rustc_metadata/src/rmeta/mod.rs +++ b/compiler/rustc_metadata/src/rmeta/mod.rs @@ -592,7 +592,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 @@ -607,6 +606,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 9ab28d0b289ab192f267289dca1fa14b732ac759 Mon Sep 17 00:00:00 2001 From: Matyas Susits Date: Wed, 21 Oct 2026 08:34:25 +0200 Subject: [PATCH 3/8] 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 dc8a117704ca4..9eb4e3cf78a12 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 e84dee34ba98b341d3f2a2c2b3e2bf4540c304e5 Mon Sep 17 00:00:00 2001 From: Matyas Susits Date: Mon, 19 Oct 2026 14:47:59 +0200 Subject: [PATCH 4/8] 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 9eb4e3cf78a12..919fb07227041 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 655f10e771aba..63f84b6d24837 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; @@ -570,10 +571,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) + } +} From 23deb4573bb14151fa649caa6a2a08817f0a2592 Mon Sep 17 00:00:00 2001 From: Jamie Hill-Daniel Date: Thu, 22 Oct 2026 16:48:49 +0100 Subject: [PATCH 5/8] Update outdated/incorrect unstable tracking issue links --- .../src/deriving/generic/mod.rs | 2 +- compiler/rustc_feature/src/unstable.rs | 8 +-- compiler/rustc_span/src/symbol.rs | 2 +- .../alloc/src/collections/vec_deque/iter.rs | 2 +- .../src/collections/vec_deque/iter_mut.rs | 6 +- library/alloc/src/slice.rs | 18 +++--- library/alloc/src/str.rs | 4 +- library/core/src/intrinsics/gpu.rs | 2 +- library/core/src/intrinsics/mod.rs | 2 +- library/core/src/macros/mod.rs | 4 +- library/core/src/prelude/v1.rs | 4 +- library/core/src/slice/mod.rs | 2 +- library/std/src/ffi/os_str.rs | 2 +- library/std/src/prelude/v1.rs | 4 +- .../src/compiler-flags/control-flow-guard.md | 59 ------------------- .../direct-access-external-data.md | 2 +- .../src/compiler-flags/location-detail.md | 2 +- .../src/compiler-flags/remap-cwd-prefix.md | 2 +- .../half-open-range-patterns-in-slices.md | 5 +- .../native-link-modifiers-as-needed.md | 4 +- .../src/language-features/profiler-runtime.md | 5 -- tests/ui/feature-gates/doc-rust-logo.stderr | 1 - ...ve_link_modifiers_as_needed.in_attr.stderr | 2 +- .../feature-gate-rustdoc_internals.stderr | 7 --- .../feature-gate-type_ascription.stderr | 2 +- .../const_derives/derive-const-gate.stderr | 2 +- triagebot.toml | 4 -- 27 files changed, 40 insertions(+), 119 deletions(-) delete mode 100644 src/doc/unstable-book/src/compiler-flags/control-flow-guard.md delete mode 100644 src/doc/unstable-book/src/language-features/profiler-runtime.md diff --git a/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs b/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs index 880d387e7d72e..37e9c99d1acae 100644 --- a/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs +++ b/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs @@ -713,7 +713,7 @@ impl<'a> TraitDef<'a> { if self.is_const && cx.ecfg.features.staged_api() { let rustc_const_unstable = cx.path_name(self.span, sym::rustc_const_unstable); - // #[rustc_const_unstable(feature = "derive_const", issue = "118304")] + // #[rustc_const_unstable(feature = "derive_const", issue = "143874")] attrs.push( cx.attr_nested( rustc_ast::AttrItem { diff --git a/compiler/rustc_feature/src/unstable.rs b/compiler/rustc_feature/src/unstable.rs index 9541becfe324d..f6f1a5815a436 100644 --- a/compiler/rustc_feature/src/unstable.rs +++ b/compiler/rustc_feature/src/unstable.rs @@ -270,6 +270,8 @@ declare_features! ( (internal, profiler_runtime, "1.18.0", None), /// Allows using `rustc_*` attributes (RFC 572). (internal, rustc_attrs, "1.0.0", None), + /// Allows using internal rustdoc features like `doc(keyword)`. + (internal, rustdoc_internals, "1.58.0", None), /// Allows using the `#[stable]` and `#[unstable]` attributes. (internal, staged_api, "1.0.0", None), /// Perma-unstable, only used in the test suite for binders (`for<'a>`). @@ -322,8 +324,6 @@ declare_features! ( (internal, repr_simd, "1.4.0", Some(27731)), /// Allows using compiler's own crates. (unstable, rustc_private, "1.0.0", Some(27812)), - /// Allows using internal rustdoc features like `doc(keyword)`. - (internal, rustdoc_internals, "1.58.0", Some(90418)), /// Allows using the `rustdoc::missing_doc_code_examples` lint (unstable, rustdoc_missing_doc_code_examples, "1.31.0", Some(101730)), /// Introduces a hierarchy of `Sized` traits (RFC 3729). @@ -666,7 +666,7 @@ declare_features! ( /// Allows providing names to parameters of `impl Fn` etc (unstable, named_fn_trait_parameters, "1.99.0", Some(158499)), /// Allows specifying the as-needed link modifier - (unstable, native_link_modifiers_as_needed, "1.53.0", Some(81490)), + (unstable, native_link_modifiers_as_needed, "1.53.0", Some(99424)), /// Allow negative trait implementations. (unstable, negative_impls, "1.44.0", Some(68318)), /// Allows the `!` pattern. @@ -725,7 +725,7 @@ declare_features! ( /// Allows the use of the `sanitize` attribute. (unstable, sanitize, "1.91.0", Some(39699)), /// Allows the use of SIMD types in functions declared in `extern` blocks. - (unstable, simd_ffi, "1.0.0", Some(27731)), + (unstable, simd_ffi, "1.0.0", Some(63068)), /// Target features on sparc. (unstable, sparc_target_feature, "1.84.0", Some(132783)), /// Allows specialization of implementations (RFC 1210). diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 9f9e5fd6cba3d..cc340af0cdff1 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -839,7 +839,7 @@ symbols! { deref_target, derive, derive_const, - derive_const_issue: "118304", + derive_const_issue: "143874", derive_default_enum, derive_from, derive_smart_pointer, diff --git a/library/alloc/src/collections/vec_deque/iter.rs b/library/alloc/src/collections/vec_deque/iter.rs index 7794fb450d776..9e6a72e595a1e 100644 --- a/library/alloc/src/collections/vec_deque/iter.rs +++ b/library/alloc/src/collections/vec_deque/iter.rs @@ -49,7 +49,7 @@ impl<'a, T> Iter<'a, T> { /// /// assert_eq!(iter.as_slices(), (&[9, 10][..], &[0, 1][..])); /// ``` - #[unstable(feature = "vec_deque_iter_as_slices", issue = "123947")] + #[unstable(feature = "vec_deque_iter_as_slices", issue = "133253")] pub fn as_slices(&self) -> (&'a [T], &'a [T]) { (self.i1.as_slice(), self.i2.as_slice()) } diff --git a/library/alloc/src/collections/vec_deque/iter_mut.rs b/library/alloc/src/collections/vec_deque/iter_mut.rs index 9d7b99d765fac..cf3f96122b90f 100644 --- a/library/alloc/src/collections/vec_deque/iter_mut.rs +++ b/library/alloc/src/collections/vec_deque/iter_mut.rs @@ -52,7 +52,7 @@ impl<'a, T> IterMut<'a, T> { /// slices.1[0] = 24; /// assert_eq!(deque.as_slices(), (&[8, 42, 10][..], &[24, 1, 2][..])); /// ``` - #[unstable(feature = "vec_deque_iter_as_slices", issue = "123947")] + #[unstable(feature = "vec_deque_iter_as_slices", issue = "133253")] pub fn into_slices(self) -> (&'a mut [T], &'a mut [T]) { (self.i1.into_slice(), self.i2.into_slice()) } @@ -86,7 +86,7 @@ impl<'a, T> IterMut<'a, T> { /// /// assert_eq!(iter.as_slices(), (&[9, 10][..], &[0, 1][..])); /// ``` - #[unstable(feature = "vec_deque_iter_as_slices", issue = "123947")] + #[unstable(feature = "vec_deque_iter_as_slices", issue = "133253")] pub fn as_slices(&self) -> (&[T], &[T]) { (self.i1.as_slice(), self.i2.as_slice()) } @@ -122,7 +122,7 @@ impl<'a, T> IterMut<'a, T> { /// iter.as_mut_slices().1[0] = 24; /// assert_eq!(deque.as_slices(), (&[8, 42, 10][..], &[24, 1, 2][..])); /// ``` - #[unstable(feature = "vec_deque_iter_as_slices", issue = "123947")] + #[unstable(feature = "vec_deque_iter_as_slices", issue = "133253")] pub fn as_mut_slices(&mut self) -> (&mut [T], &mut [T]) { (self.i1.as_mut_slice(), self.i2.as_mut_slice()) } diff --git a/library/alloc/src/slice.rs b/library/alloc/src/slice.rs index 438549160a1c6..5583fce0b944d 100644 --- a/library/alloc/src/slice.rs +++ b/library/alloc/src/slice.rs @@ -713,31 +713,31 @@ impl [u8] { /// fn borrow(&self) -> &[String] { &self.1 } /// } /// ``` -#[unstable(feature = "slice_concat_trait", issue = "27747")] +#[unstable(feature = "slice_concat_trait", issue = "none", reason = "implementation detail")] pub trait Concat { - #[unstable(feature = "slice_concat_trait", issue = "27747")] + #[unstable(feature = "slice_concat_trait", issue = "none", reason = "implementation detail")] /// The resulting type after concatenation type Output; /// Implementation of [`[T]::concat`](slice::concat) - #[unstable(feature = "slice_concat_trait", issue = "27747")] + #[unstable(feature = "slice_concat_trait", issue = "none", reason = "implementation detail")] fn concat(slice: &Self) -> Self::Output; } /// Helper trait for [`[T]::join`](slice::join) -#[unstable(feature = "slice_concat_trait", issue = "27747")] +#[unstable(feature = "slice_concat_trait", issue = "none", reason = "implementation detail")] pub trait Join { - #[unstable(feature = "slice_concat_trait", issue = "27747")] + #[unstable(feature = "slice_concat_trait", issue = "none", reason = "implementation detail")] /// The resulting type after concatenation type Output; /// Implementation of [`[T]::join`](slice::join) - #[unstable(feature = "slice_concat_trait", issue = "27747")] + #[unstable(feature = "slice_concat_trait", issue = "none", reason = "implementation detail")] fn join(slice: &Self, sep: Separator) -> Self::Output; } #[cfg(not(no_global_oom_handling))] -#[unstable(feature = "slice_concat_ext", issue = "27747")] +#[unstable(feature = "slice_concat_ext", issue = "none", reason = "implementation detail")] impl> Concat for [V] { type Output = Vec; @@ -752,7 +752,7 @@ impl> Concat for [V] { } #[cfg(not(no_global_oom_handling))] -#[unstable(feature = "slice_concat_ext", issue = "27747")] +#[unstable(feature = "slice_concat_ext", issue = "none", reason = "implementation detail")] impl> Join<&T> for [V] { type Output = Vec; @@ -775,7 +775,7 @@ impl> Join<&T> for [V] { } #[cfg(not(no_global_oom_handling))] -#[unstable(feature = "slice_concat_ext", issue = "27747")] +#[unstable(feature = "slice_concat_ext", issue = "none", reason = "implementation detail")] impl> Join<&[T]> for [V] { type Output = Vec; diff --git a/library/alloc/src/str.rs b/library/alloc/src/str.rs index a736a25ccdeb8..7997e0c053dc9 100644 --- a/library/alloc/src/str.rs +++ b/library/alloc/src/str.rs @@ -58,7 +58,7 @@ use crate::vec::Vec; /// Note: `str` in `Concat` is not meaningful here. /// This type parameter of the trait only exists to enable another impl. #[cfg(not(no_global_oom_handling))] -#[unstable(feature = "slice_concat_ext", issue = "27747")] +#[unstable(feature = "slice_concat_ext", issue = "none", reason = "implementation detail")] impl> Concat for [S] { type Output = String; @@ -68,7 +68,7 @@ impl> Concat for [S] { } #[cfg(not(no_global_oom_handling))] -#[unstable(feature = "slice_concat_ext", issue = "27747")] +#[unstable(feature = "slice_concat_ext", issue = "none", reason = "implementation detail")] impl> Join<&str> for [S] { type Output = String; diff --git a/library/core/src/intrinsics/gpu.rs b/library/core/src/intrinsics/gpu.rs index 8ea894b3955d4..b5e993342b843 100644 --- a/library/core/src/intrinsics/gpu.rs +++ b/library/core/src/intrinsics/gpu.rs @@ -46,7 +46,7 @@ #[must_use = "returns a pointer that does nothing unless used"] #[rustc_intrinsic] #[rustc_nounwind] -#[unstable(feature = "gpu_launch_sized_workgroup_mem", issue = "135513")] +#[unstable(feature = "gpu_launch_sized_workgroup_mem", issue = "131513")] #[cfg(any(doc, target_arch = "amdgpu", target_arch = "nvptx64"))] pub fn gpu_launch_sized_workgroup_mem() -> *mut T; diff --git a/library/core/src/intrinsics/mod.rs b/library/core/src/intrinsics/mod.rs index 550e52480301c..e4eb66f4f97c8 100644 --- a/library/core/src/intrinsics/mod.rs +++ b/library/core/src/intrinsics/mod.rs @@ -2218,7 +2218,7 @@ pub const fn mul_with_overflow(x: T, y: T) -> (T, bool); /// This currently supports unsigned integers *only*, no signed ones. /// The stabilized versions of this intrinsic are available on integers. #[unstable(feature = "core_intrinsics", issue = "none")] -#[rustc_const_unstable(feature = "const_carrying_mul_add", issue = "85532")] +#[rustc_const_unstable(feature = "const_carrying_mul_add", issue = "152015")] #[rustc_nounwind] #[rustc_intrinsic] #[miri::intrinsic_fallback_is_spec] diff --git a/library/core/src/macros/mod.rs b/library/core/src/macros/mod.rs index ab8fc47009186..384213bbbe56d 100644 --- a/library/core/src/macros/mod.rs +++ b/library/core/src/macros/mod.rs @@ -1784,7 +1784,7 @@ pub(crate) mod builtin { /// See [the reference] for more info. /// /// [the reference]: ../../../reference/attributes/derive.html - #[unstable(feature = "derive_const", issue = "118304")] + #[unstable(feature = "derive_const", issue = "143874")] #[rustc_builtin_macro] pub macro derive_const($item:item) { /* compiler built-in */ @@ -1910,7 +1910,7 @@ pub(crate) mod builtin { #[allow_internal_unstable(builtin_syntax)] #[unstable( feature = "type_ascription", - issue = "23416", + issue = "101728", reason = "placeholder syntax for type ascription" )] #[diagnostic::opaque] diff --git a/library/core/src/prelude/v1.rs b/library/core/src/prelude/v1.rs index 6122ab12ec351..f68d3e614c53f 100644 --- a/library/core/src/prelude/v1.rs +++ b/library/core/src/prelude/v1.rs @@ -127,7 +127,7 @@ pub use crate::macros::builtin::{ #[doc(no_inline)] pub use crate::macros::builtin::derive; -#[unstable(feature = "derive_const", issue = "118304")] +#[unstable(feature = "derive_const", issue = "143874")] pub use crate::macros::builtin::derive_const; #[unstable( @@ -146,7 +146,7 @@ pub use crate::macros::builtin::cfg_eval; #[unstable( feature = "type_ascription", - issue = "23416", + issue = "101728", reason = "placeholder syntax for type ascription" )] pub use crate::macros::builtin::type_ascribe; diff --git a/library/core/src/slice/mod.rs b/library/core/src/slice/mod.rs index 35af6488895a1..0677bb8f5871a 100644 --- a/library/core/src/slice/mod.rs +++ b/library/core/src/slice/mod.rs @@ -5660,7 +5660,7 @@ const impl Default for &mut [T] { } } -#[unstable(feature = "slice_pattern", reason = "stopgap trait for slice patterns", issue = "56345")] +#[unstable(feature = "slice_pattern", issue = "none", reason = "stopgap trait for slice patterns")] /// Patterns in slices - currently, only used by `strip_prefix` and `strip_suffix`. At a future /// point, we hope to generalise `core::str::Pattern` (which at the time of writing is limited to /// `str`) to slices, and then this trait will be replaced or abolished. diff --git a/library/std/src/ffi/os_str.rs b/library/std/src/ffi/os_str.rs index b9d344284734b..770cc5f834a11 100644 --- a/library/std/src/ffi/os_str.rs +++ b/library/std/src/ffi/os_str.rs @@ -1711,7 +1711,7 @@ impl fmt::Display for Display<'_> { } } -#[unstable(feature = "slice_concat_ext", issue = "27747")] +#[unstable(feature = "slice_concat_ext", issue = "none", reason = "implementation detail")] impl> alloc::slice::Join<&OsStr> for [S] { type Output = OsString; diff --git a/library/std/src/prelude/v1.rs b/library/std/src/prelude/v1.rs index aeefec8b9e084..8f0a02119e007 100644 --- a/library/std/src/prelude/v1.rs +++ b/library/std/src/prelude/v1.rs @@ -122,7 +122,7 @@ pub use core::prelude::v1::{ #[doc(no_inline)] pub use core::prelude::v1::derive; -#[unstable(feature = "derive_const", issue = "118304")] +#[unstable(feature = "derive_const", issue = "143874")] pub use core::prelude::v1::derive_const; // Do not `doc(no_inline)` either. @@ -144,7 +144,7 @@ pub use core::prelude::v1::cfg_eval; // Do not `doc(no_inline)` either. #[unstable( feature = "type_ascription", - issue = "23416", + issue = "101728", reason = "placeholder syntax for type ascription" )] pub use core::prelude::v1::type_ascribe; diff --git a/src/doc/unstable-book/src/compiler-flags/control-flow-guard.md b/src/doc/unstable-book/src/compiler-flags/control-flow-guard.md deleted file mode 100644 index e7414aa9119de..0000000000000 --- a/src/doc/unstable-book/src/compiler-flags/control-flow-guard.md +++ /dev/null @@ -1,59 +0,0 @@ -# `control-flow-guard` - -The tracking issue for this feature is: [#68793](https://github.com/rust-lang/rust/issues/68793). - ------------------------- - -The rustc flag `-Z control-flow-guard` enables the Windows [Control Flow Guard](https://docs.microsoft.com/en-us/windows/win32/secbp/control-flow-guard) (CFG) platform security feature. - -CFG is an exploit mitigation designed to enforce control-flow integrity for software running on supported [Windows platforms (Windows 8.1 onwards)](https://docs.microsoft.com/en-us/windows/win32/secbp/control-flow-guard). Specifically, CFG uses runtime checks to validate the target address of every indirect call/jump before allowing the call to complete. - -During compilation, the compiler identifies all indirect calls/jumps and adds CFG checks. It also emits metadata containing the relative addresses of all address-taken functions. At runtime, if the binary is run on a CFG-aware operating system, the loader uses the CFG metadata to generate a bitmap of the address space and marks those addresses that contain valid targets. On each indirect call, the inserted check determines whether the target address is marked in this bitmap. If the target is not valid, the process is terminated. - -In terms of interoperability: -- Code compiled with CFG enabled can be linked with libraries and object files that are not compiled with CFG. In this case, a CFG-aware linker can identify address-taken functions in the non-CFG libraries. -- Libraries compiled with CFG can linked into non-CFG programs. In this case, the CFG runtime checks in the libraries are not used (i.e. the mitigation is completely disabled). - -CFG functionality is completely implemented in the LLVM backend and is supported for X86 (32-bit and 64-bit), ARM, and Aarch64 targets. The rustc flag adds the relevant LLVM module flags to enable the feature. This flag will be ignored for all non-Windows targets. - - -## When to use Control Flow Guard - -The primary motivation for enabling CFG in Rust is to enhance security when linking against non-Rust code, especially C/C++ code. To achieve full CFG protection, all indirect calls (including any from Rust code) must have the appropriate CFG checks, as added by this flag. CFG can also improve security for Rust code that uses the `unsafe` keyword. - -Another motivation behind CFG is to harden programs against [return-oriented programming (ROP)](https://en.wikipedia.org/wiki/Return-oriented_programming) attacks. CFG disallows an attacker from taking advantage of the program's own instructions while redirecting control flow in unexpected ways. - -## Overhead of Control Flow Guard - -The CFG checks and metadata can potentially increase binary size and runtime overhead. The magnitude of any increase depends on the number and frequency of indirect calls. For example, enabling CFG for the Rust standard library increases binary size by approximately 0.14%. Enabling CFG in the SPEC CPU 2017 Integer Speed benchmark suite (compiled with Clang/LLVM) incurs approximate runtime overheads of between 0% and 8%, with a geometric mean of 2.9%. - - -## Testing Control Flow Guard - -The rustc flag `-Z control-flow-guard=nochecks` instructs LLVM to emit the list of valid call targets without inserting runtime checks. This flag should only be used for testing purposes as it does not provide security enforcement. - - -## Control Flow Guard in libraries - -It is strongly recommended to also enable CFG checks for all linked libraries, including the standard library. - -To enable CFG in the standard library, use the [cargo `-Z build-std` functionality][build-std] to recompile the standard library with the same configuration options as the main program. - -[build-std]: ../../cargo/reference/unstable.html#build-std - -For example: -```cmd -rustup toolchain install --force nightly -rustup component add rust-src -SET RUSTFLAGS=-Z control-flow-guard -cargo +nightly build -Z build-std --target x86_64-pc-windows-msvc -``` - -```PowerShell -rustup toolchain install --force nightly -rustup component add rust-src -$Env:RUSTFLAGS = "-Z control-flow-guard" -cargo +nightly build -Z build-std --target x86_64-pc-windows-msvc -``` - -Alternatively, if you are building the standard library from source, you can set `control-flow-guard = true` in the bootstrap.toml file. diff --git a/src/doc/unstable-book/src/compiler-flags/direct-access-external-data.md b/src/doc/unstable-book/src/compiler-flags/direct-access-external-data.md index c72df43796038..dd6345bb55055 100644 --- a/src/doc/unstable-book/src/compiler-flags/direct-access-external-data.md +++ b/src/doc/unstable-book/src/compiler-flags/direct-access-external-data.md @@ -1,6 +1,6 @@ # `direct_access_external_data` -The tracking issue for this feature is: https://github.com/rust-lang/compiler-team/issues/707 +The tracking issue for this feature is: [#127488](https://github.com/rust-lang/rust/issues/127488). ------------------------ diff --git a/src/doc/unstable-book/src/compiler-flags/location-detail.md b/src/doc/unstable-book/src/compiler-flags/location-detail.md index db07061996964..64c5ac0dbb8be 100644 --- a/src/doc/unstable-book/src/compiler-flags/location-detail.md +++ b/src/doc/unstable-book/src/compiler-flags/location-detail.md @@ -1,6 +1,6 @@ # `location-detail` -The tracking issue for this feature is: [#70580](https://github.com/rust-lang/rust/issues/70580). +The tracking issue for this feature is: [cargo#14511](https://github.com/rust-lang/cargo/issues/14511). ------------------------ diff --git a/src/doc/unstable-book/src/compiler-flags/remap-cwd-prefix.md b/src/doc/unstable-book/src/compiler-flags/remap-cwd-prefix.md index bcf526694ad94..45aca930f60df 100644 --- a/src/doc/unstable-book/src/compiler-flags/remap-cwd-prefix.md +++ b/src/doc/unstable-book/src/compiler-flags/remap-cwd-prefix.md @@ -1,6 +1,6 @@ # `remap-cwd-prefix` -The tracking issue for this feature is: [#87325](https://github.com/rust-lang/rust/issues/87325). +The tracking issue for this feature is: [#89434](https://github.com/rust-lang/rust/issues/89434). ------------------------ diff --git a/src/doc/unstable-book/src/language-features/half-open-range-patterns-in-slices.md b/src/doc/unstable-book/src/language-features/half-open-range-patterns-in-slices.md index 93e9bc32ff064..e1384e22456d6 100644 --- a/src/doc/unstable-book/src/language-features/half-open-range-patterns-in-slices.md +++ b/src/doc/unstable-book/src/language-features/half-open-range-patterns-in-slices.md @@ -1,11 +1,8 @@ # `half_open_range_patterns_in_slices` -The tracking issue for this feature is: [#67264] -It is a future part of the `exclusive_range_pattern` feature, -tracked at [#37854]. +The tracking issue for this feature is: [#67264]. [#67264]: https://github.com/rust-lang/rust/issues/67264 -[#37854]: https://github.com/rust-lang/rust/issues/37854 ----- This feature allow using top-level half-open range patterns in slices. diff --git a/src/doc/unstable-book/src/language-features/native-link-modifiers-as-needed.md b/src/doc/unstable-book/src/language-features/native-link-modifiers-as-needed.md index 1757673612c48..ba995c7d47848 100644 --- a/src/doc/unstable-book/src/language-features/native-link-modifiers-as-needed.md +++ b/src/doc/unstable-book/src/language-features/native-link-modifiers-as-needed.md @@ -1,8 +1,8 @@ # `native_link_modifiers_as_needed` -The tracking issue for this feature is: [#81490] +The tracking issue for this feature is: [#99424] -[#81490]: https://github.com/rust-lang/rust/issues/81490 +[#99424]: https://github.com/rust-lang/rust/issues/99424 ------------------------ diff --git a/src/doc/unstable-book/src/language-features/profiler-runtime.md b/src/doc/unstable-book/src/language-features/profiler-runtime.md deleted file mode 100644 index aee86f63952a5..0000000000000 --- a/src/doc/unstable-book/src/language-features/profiler-runtime.md +++ /dev/null @@ -1,5 +0,0 @@ -# `profiler_runtime` - -The tracking issue for this feature is: [#42524](https://github.com/rust-lang/rust/issues/42524). - ------------------------- diff --git a/tests/ui/feature-gates/doc-rust-logo.stderr b/tests/ui/feature-gates/doc-rust-logo.stderr index f31837be284d1..802187e6a598c 100644 --- a/tests/ui/feature-gates/doc-rust-logo.stderr +++ b/tests/ui/feature-gates/doc-rust-logo.stderr @@ -4,7 +4,6 @@ error[E0658]: this subset of the `doc` attribute is meant for internal use only LL | #![doc(rust_logo)] | ^^^^^^^^^ | - = note: see issue #90418 for more information = help: add `#![feature(rustdoc_internals)]` to the crate attributes to enable = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date = note: the `#[doc(rust_logo)]` attribute is used for Rust branding diff --git a/tests/ui/feature-gates/feature-gate-native_link_modifiers_as_needed.in_attr.stderr b/tests/ui/feature-gates/feature-gate-native_link_modifiers_as_needed.in_attr.stderr index 11b7abc883e15..bbe1a0dc9ae5e 100644 --- a/tests/ui/feature-gates/feature-gate-native_link_modifiers_as_needed.in_attr.stderr +++ b/tests/ui/feature-gates/feature-gate-native_link_modifiers_as_needed.in_attr.stderr @@ -4,7 +4,7 @@ error[E0658]: linking modifier `as-needed` is unstable LL | #[link(name = "foo", kind = "dylib", modifiers = "+as-needed")] | ^^^^^^^^^^^^ | - = note: see issue #81490 for more information + = note: see issue #99424 for more information = help: add `#![feature(native_link_modifiers_as_needed)]` to the crate attributes to enable = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date diff --git a/tests/ui/feature-gates/feature-gate-rustdoc_internals.stderr b/tests/ui/feature-gates/feature-gate-rustdoc_internals.stderr index ab542eb85bacf..268c854285607 100644 --- a/tests/ui/feature-gates/feature-gate-rustdoc_internals.stderr +++ b/tests/ui/feature-gates/feature-gate-rustdoc_internals.stderr @@ -4,7 +4,6 @@ error[E0658]: this subset of the `doc` attribute is meant for internal use only LL | #[doc(search_unbox)] | ^^^^^^^^^^^^ | - = note: see issue #90418 for more information = help: add `#![feature(rustdoc_internals)]` to the crate attributes to enable = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date @@ -14,7 +13,6 @@ error[E0658]: this subset of the `doc` attribute is meant for internal use only LL | #[doc(fake_variadic)] | ^^^^^^^^^^^^^ | - = note: see issue #90418 for more information = help: add `#![feature(rustdoc_internals)]` to the crate attributes to enable = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date @@ -24,7 +22,6 @@ error[E0658]: this subset of the `doc` attribute is meant for internal use only LL | #[doc(attribute = "repr")] | ^^^^^^^^^ | - = note: see issue #90418 for more information = help: add `#![feature(rustdoc_internals)]` to the crate attributes to enable = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date @@ -34,7 +31,6 @@ error[E0658]: this subset of the `doc` attribute is meant for internal use only LL | #[doc(keyword = "match")] | ^^^^^^^ | - = note: see issue #90418 for more information = help: add `#![feature(rustdoc_internals)]` to the crate attributes to enable = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date @@ -44,7 +40,6 @@ error[E0658]: this subset of the `doc` attribute is meant for internal use only LL | #[doc(attribute = "repr")] | ^^^^^^^^^ | - = note: see issue #90418 for more information = help: add `#![feature(rustdoc_internals)]` to the crate attributes to enable = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date @@ -54,7 +49,6 @@ error[E0658]: this subset of the `doc` attribute is meant for internal use only LL | #[doc(fake_variadic)] | ^^^^^^^^^^^^^ | - = note: see issue #90418 for more information = help: add `#![feature(rustdoc_internals)]` to the crate attributes to enable = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date @@ -64,7 +58,6 @@ error[E0658]: this subset of the `doc` attribute is meant for internal use only LL | #[doc(search_unbox)] | ^^^^^^^^^^^^ | - = note: see issue #90418 for more information = help: add `#![feature(rustdoc_internals)]` to the crate attributes to enable = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date diff --git a/tests/ui/feature-gates/feature-gate-type_ascription.stderr b/tests/ui/feature-gates/feature-gate-type_ascription.stderr index f59e6435c8e89..1ed7604ebb448 100644 --- a/tests/ui/feature-gates/feature-gate-type_ascription.stderr +++ b/tests/ui/feature-gates/feature-gate-type_ascription.stderr @@ -4,7 +4,7 @@ error[E0658]: use of unstable library feature `type_ascription`: placeholder syn LL | let a = type_ascribe!(10, u8); | ^^^^^^^^^^^^ | - = note: see issue #23416 for more information + = note: see issue #101728 for more information = help: add `#![feature(type_ascription)]` to the crate attributes to enable = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date diff --git a/tests/ui/traits/const-traits/const_derives/derive-const-gate.stderr b/tests/ui/traits/const-traits/const_derives/derive-const-gate.stderr index cbc62d602a473..5820d1f353ef1 100644 --- a/tests/ui/traits/const-traits/const_derives/derive-const-gate.stderr +++ b/tests/ui/traits/const-traits/const_derives/derive-const-gate.stderr @@ -4,7 +4,7 @@ error[E0658]: use of unstable library feature `derive_const` LL | #[derive_const(Debug)] | ^^^^^^^^^^^^ | - = note: see issue #118304 for more information + = note: see issue #143874 for more information = help: add `#![feature(derive_const)]` to the crate attributes to enable = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date diff --git a/triagebot.toml b/triagebot.toml index 676ab4df6448a..dbb39058daac6 100644 --- a/triagebot.toml +++ b/triagebot.toml @@ -614,7 +614,6 @@ trigger_files = [ "src/doc/rustc/src/exploit-mitigations.md", "src/doc/unstable-book/src/compiler-flags/branch-protection.md", "src/doc/unstable-book/src/compiler-flags/cf-protection.md", - "src/doc/unstable-book/src/compiler-flags/control-flow-guard.md", "src/doc/unstable-book/src/compiler-flags/sanitizer.md", "src/doc/unstable-book/src/language-features/cfg-sanitize.md", "src/doc/unstable-book/src/language-features/cfi-encoding.md", @@ -1429,9 +1428,6 @@ cc = ["@rust-lang/project-exploit-mitigations", "@rcvalle"] [mentions."src/doc/unstable-book/src/compiler-flags/cf-protection.md"] cc = ["@rust-lang/project-exploit-mitigations", "@rcvalle"] -[mentions."src/doc/unstable-book/src/compiler-flags/control-flow-guard.md"] -cc = ["@rust-lang/project-exploit-mitigations", "@rcvalle"] - [mentions."src/doc/unstable-book/src/compiler-flags/sanitizer.md"] cc = ["@rust-lang/project-exploit-mitigations", "@rcvalle"] From c860e0d40d81bc3b3d48c2583edeae391338cd74 Mon Sep 17 00:00:00 2001 From: TechnoPorg Date: Wed, 21 Oct 2026 09:13:50 -0400 Subject: [PATCH 6/8] Use 64-bit time for futex syscalls on RV32 --- Cargo.lock | 4 ++-- library/std/src/sys/sync/futex/unix.rs | 18 +++++++++++++++--- 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 634e81eaf80b4..73c7c8ab97e1c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2273,9 +2273,9 @@ checksum = "803ec87c9cfb29b9d2633f20cba1f488db3fd53f2158b1024cbefb47ba05d413" [[package]] name = "libc" -version = "0.2.189" +version = "0.2.191" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3eaf3ede3fee6db1a4c2ee091bf8a8b4dccdc6d17f656fb07896ee72867612f2" +checksum = "65cd87c9a6d60536580b316ad985726104730a5151c99845f2490428ef91240a" [[package]] name = "libffi" diff --git a/library/std/src/sys/sync/futex/unix.rs b/library/std/src/sys/sync/futex/unix.rs index 004d8323060e5..82861c35e4c43 100644 --- a/library/std/src/sys/sync/futex/unix.rs +++ b/library/std/src/sys/sync/futex/unix.rs @@ -11,6 +11,18 @@ pub type SmallFutex = Atomic; /// Must be the underlying type of SmallFutex pub type SmallPrimitive = u32; +#[cfg(any(target_os = "linux", target_os = "android"))] +cfg_select! { + // riscv32 only exposes the `SYS_futex_time64` syscall, + // whereas other 32-bit targets also expose `SYS_futex`, which uses 32-bit time. + target_arch = "riscv32" => { + use libc::SYS_futex_time64 as SYS_futex; + } + _ => { + use libc::SYS_futex; + } +} + /// Waits for a `futex_wake` operation to wake us. /// /// Returns directly if the futex doesn't hold the expected value. @@ -61,7 +73,7 @@ pub fn futex_wait(futex: &Atomic, expected: u32, timeout: Option) // Use FUTEX_WAIT_BITSET rather than FUTEX_WAIT to be able to give an // absolute time rather than a relative time. libc::syscall( - libc::SYS_futex, + SYS_futex, futex as *const Atomic as *const u32, libc::FUTEX_WAIT_BITSET | libc::FUTEX_PRIVATE_FLAG, expected, @@ -94,7 +106,7 @@ pub fn futex_wait(futex: &Atomic, expected: u32, timeout: Option) pub fn futex_wake(futex: &Atomic) -> bool { let ptr = futex as *const Atomic as *const u32; let op = libc::FUTEX_WAKE | libc::FUTEX_PRIVATE_FLAG; - unsafe { libc::syscall(libc::SYS_futex, ptr, op, 1) > 0 } + unsafe { libc::syscall(SYS_futex, ptr, op, 1) > 0 } } /// Wakes up all threads that are waiting on `futex_wait` on this futex. @@ -103,7 +115,7 @@ pub fn futex_wake_all(futex: &Atomic) { let ptr = futex as *const Atomic as *const u32; let op = libc::FUTEX_WAKE | libc::FUTEX_PRIVATE_FLAG; unsafe { - libc::syscall(libc::SYS_futex, ptr, op, i32::MAX); + libc::syscall(SYS_futex, ptr, op, i32::MAX); } } From 8aed22cd809a4dbc1bbe7972afcf364ca609ef54 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Thu, 22 Oct 2026 18:22:42 +0000 Subject: [PATCH 7/8] Properly format return type in lifetime error with backticks ``` error: lifetime may not live long enough --> $DIR/issue-55394.rs:9:9 | LL | fn new(bar: &mut Bar) -> Self { | - ---- return type is `Foo<'2>` | | | let's call the lifetime of this reference `'1` LL | Foo { bar } | ^^^^^^^^^^^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` ``` --- compiler/rustc_borrowck/src/diagnostics/region_name.rs | 2 +- tests/ui/async-await/async-closures/not-lending.stderr | 2 +- .../issue-74072-lifetime-name-annotations.stderr | 8 ++++---- .../implementation-not-general-enough-ice-133252.stderr | 2 +- .../unmatched-arg-and-hir-arg-issue-126385.stderr | 2 +- tests/ui/closures/return-value-lifetime-error.stderr | 2 +- .../E0621-does-not-trigger-for-closures.stderr | 2 +- tests/ui/lifetimes/issue-79187-2.stderr | 2 +- tests/ui/nll/issue-48238.stderr | 2 +- tests/ui/nll/issue-55394.stderr | 2 +- tests/ui/nll/issue-58053.stderr | 2 +- tests/ui/regions/regions-escape-method.stderr | 2 +- tests/ui/regions/regions-escape-via-trait-or-not.stderr | 2 +- tests/ui/regions/regions-infer-call-3.stderr | 2 +- tests/ui/regions/regions-ret-borrowed-1.stderr | 2 +- tests/ui/regions/regions-ret-borrowed.stderr | 2 +- 16 files changed, 19 insertions(+), 19 deletions(-) diff --git a/compiler/rustc_borrowck/src/diagnostics/region_name.rs b/compiler/rustc_borrowck/src/diagnostics/region_name.rs index 871b974d28eea..1d1c9c0baef51 100644 --- a/compiler/rustc_borrowck/src/diagnostics/region_name.rs +++ b/compiler/rustc_borrowck/src/diagnostics/region_name.rs @@ -170,7 +170,7 @@ impl RegionName { RegionNameHighlight::CannotMatchHirTy(span, type_name), mir_description, ) => { - diag.span_label(*span, format!("return type{mir_description} is {type_name}")); + diag.span_label(*span, format!("return type{mir_description} is `{type_name}`")); } RegionNameSource::AnonRegionFromYieldTy(span, type_name) => { diag.span_label(*span, format!("yield type is {type_name}")); diff --git a/tests/ui/async-await/async-closures/not-lending.stderr b/tests/ui/async-await/async-closures/not-lending.stderr index 989b9ccb88a76..2b19516e99415 100644 --- a/tests/ui/async-await/async-closures/not-lending.stderr +++ b/tests/ui/async-await/async-closures/not-lending.stderr @@ -15,7 +15,7 @@ error: lifetime may not live long enough LL | let x = async move || { &s }; | ------------- ^^^^^^ returning this value requires that `'1` must outlive `'2` | | | - | | return type of async closure is &'2 String + | | return type of async closure is `&'2 String` | lifetime `'1` represents this closure's body | = note: closure implements `AsyncFn`, so references to captured variables can't escape the closure diff --git a/tests/ui/async-await/issue-74072-lifetime-name-annotations.stderr b/tests/ui/async-await/issue-74072-lifetime-name-annotations.stderr index b7f9a9ed24ecf..a76670f472225 100644 --- a/tests/ui/async-await/issue-74072-lifetime-name-annotations.stderr +++ b/tests/ui/async-await/issue-74072-lifetime-name-annotations.stderr @@ -34,7 +34,7 @@ error: lifetime may not live long enough LL | (async move || { | ______-------------_^ | | | | - | | | return type of async closure is &'2 i32 + | | | return type of async closure is `&'2 i32` | | lifetime `'1` represents this closure's body LL | | LL | | @@ -50,7 +50,7 @@ error[E0506]: cannot assign to `*x` because it is borrowed --> $DIR/issue-74072-lifetime-name-annotations.rs:17:9 | LL | (async move || { - | - return type of async closure is &'1 i32 + | - return type of async closure is `&'1 i32` ... LL | let y = &*x; | --- `*x` is borrowed here @@ -99,7 +99,7 @@ error[E0506]: cannot assign to `*x` because it is borrowed --> $DIR/issue-74072-lifetime-name-annotations.rs:27:9 | LL | (async move || -> &i32 { - | - return type of async closure is &'1 i32 + | - return type of async closure is `&'1 i32` ... LL | let y = &*x; | --- `*x` is borrowed here @@ -112,7 +112,7 @@ error[E0506]: cannot assign to `*x` because it is borrowed --> $DIR/issue-74072-lifetime-name-annotations.rs:35:9 | LL | async move { - | - return type of async block is &'1 i32 + | - return type of async block is `&'1 i32` LL | let y = &*x; | --- `*x` is borrowed here LL | *x += 1; diff --git a/tests/ui/borrowck/implementation-not-general-enough-ice-133252.stderr b/tests/ui/borrowck/implementation-not-general-enough-ice-133252.stderr index f1a561ef88049..1b441ba13bef2 100644 --- a/tests/ui/borrowck/implementation-not-general-enough-ice-133252.stderr +++ b/tests/ui/borrowck/implementation-not-general-enough-ice-133252.stderr @@ -15,7 +15,7 @@ error[E0597]: `not_static` does not live long enough --> $DIR/implementation-not-general-enough-ice-133252.rs:9:31 | LL | async { - | - return type of async block is &(dyn Owned + '1) + | - return type of async block is `&(dyn Owned + '1)` LL | let not_static = 0; | ---------- binding `not_static` declared here LL | force_send(async_load(¬_static)); diff --git a/tests/ui/borrowck/unmatched-arg-and-hir-arg-issue-126385.stderr b/tests/ui/borrowck/unmatched-arg-and-hir-arg-issue-126385.stderr index a18c4e7271949..dc19178732ba2 100644 --- a/tests/ui/borrowck/unmatched-arg-and-hir-arg-issue-126385.stderr +++ b/tests/ui/borrowck/unmatched-arg-and-hir-arg-issue-126385.stderr @@ -24,7 +24,7 @@ error: lifetime may not live long enough --> $DIR/unmatched-arg-and-hir-arg-issue-126385.rs:10:9 | LL | pub fn f(field: &[u32]) -> Self { - | - --------- return type is MyStruct<'2> + | - --------- return type is `MyStruct<'2>` | | | let's call the lifetime of this reference `'1` LL | Self { field } diff --git a/tests/ui/closures/return-value-lifetime-error.stderr b/tests/ui/closures/return-value-lifetime-error.stderr index a0ad127db2891..54d6be4cd16e2 100644 --- a/tests/ui/closures/return-value-lifetime-error.stderr +++ b/tests/ui/closures/return-value-lifetime-error.stderr @@ -4,7 +4,7 @@ error: lifetime may not live long enough LL | let _ = counts.iter().max_by_key(|(_, v)| v); | ------- ^ returning this value requires that `'1` must outlive `'2` | | | - | | return type of closure is &'2 &i32 + | | return type of closure is `&'2 &i32` | has type `&'1 (&i32, &i32)` | help: dereference the return value diff --git a/tests/ui/error-codes/E0621-does-not-trigger-for-closures.stderr b/tests/ui/error-codes/E0621-does-not-trigger-for-closures.stderr index 2d96926a230ff..d8a59850b3a19 100644 --- a/tests/ui/error-codes/E0621-does-not-trigger-for-closures.stderr +++ b/tests/ui/error-codes/E0621-does-not-trigger-for-closures.stderr @@ -4,7 +4,7 @@ error: lifetime may not live long enough LL | invoke(&x, |a, b| if a > b { a } else { b }); | -- ^ returning this value requires that `'1` must outlive `'2` | || - | |return type of closure is &'2 i32 + | |return type of closure is `&'2 i32` | has type `&'1 i32` error: aborting due to 1 previous error diff --git a/tests/ui/lifetimes/issue-79187-2.stderr b/tests/ui/lifetimes/issue-79187-2.stderr index adc64984a05e9..67bb7e8ba0e27 100644 --- a/tests/ui/lifetimes/issue-79187-2.stderr +++ b/tests/ui/lifetimes/issue-79187-2.stderr @@ -52,7 +52,7 @@ error: lifetime may not live long enough LL | take_foo(|a: &i32| a); | - - ^ returning this value requires that `'1` must outlive `'2` | | | - | | return type of closure is &'2 i32 + | | return type of closure is `&'2 i32` | let's call the lifetime of this reference `'1` error[E0308]: mismatched types diff --git a/tests/ui/nll/issue-48238.stderr b/tests/ui/nll/issue-48238.stderr index e15fbbdcdf21f..5c8505751bfad 100644 --- a/tests/ui/nll/issue-48238.stderr +++ b/tests/ui/nll/issue-48238.stderr @@ -4,7 +4,7 @@ error: lifetime may not live long enough LL | move || use_val(&orig); | ------- ^^^^^^^^^^^^^^ returning this value requires that `'1` must outlive `'2` | | | - | | return type of closure is &'2 u8 + | | return type of closure is `&'2 u8` | lifetime `'1` represents this closure's body | = note: closure implements `Fn`, so references to captured variables can't escape the closure diff --git a/tests/ui/nll/issue-55394.stderr b/tests/ui/nll/issue-55394.stderr index 69df901026436..03382b668aa53 100644 --- a/tests/ui/nll/issue-55394.stderr +++ b/tests/ui/nll/issue-55394.stderr @@ -2,7 +2,7 @@ error: lifetime may not live long enough --> $DIR/issue-55394.rs:9:9 | LL | fn new(bar: &mut Bar) -> Self { - | - ---- return type is Foo<'2> + | - ---- return type is `Foo<'2>` | | | let's call the lifetime of this reference `'1` LL | Foo { bar } diff --git a/tests/ui/nll/issue-58053.stderr b/tests/ui/nll/issue-58053.stderr index bf7416e1ab085..820da14c96dc7 100644 --- a/tests/ui/nll/issue-58053.stderr +++ b/tests/ui/nll/issue-58053.stderr @@ -13,7 +13,7 @@ error: lifetime may not live long enough LL | let g = |x: &i32| { x }; | - - ^ returning this value requires that `'1` must outlive `'2` | | | - | | return type of closure is &'2 i32 + | | return type of closure is `&'2 i32` | let's call the lifetime of this reference `'1` error: aborting due to 2 previous errors diff --git a/tests/ui/regions/regions-escape-method.stderr b/tests/ui/regions/regions-escape-method.stderr index 687b91bb7b47b..b3a51c2f09268 100644 --- a/tests/ui/regions/regions-escape-method.stderr +++ b/tests/ui/regions/regions-escape-method.stderr @@ -4,7 +4,7 @@ error: lifetime may not live long enough LL | s.f(|p| p) | -- ^ returning this value requires that `'1` must outlive `'2` | || - | |return type of closure is &'2 i32 + | |return type of closure is `&'2 i32` | has type `&'1 i32` | help: dereference the return value diff --git a/tests/ui/regions/regions-escape-via-trait-or-not.stderr b/tests/ui/regions/regions-escape-via-trait-or-not.stderr index 4d185e52d01be..668a27d3fdaef 100644 --- a/tests/ui/regions/regions-escape-via-trait-or-not.stderr +++ b/tests/ui/regions/regions-escape-via-trait-or-not.stderr @@ -4,7 +4,7 @@ error: lifetime may not live long enough LL | with(|o| o) | -- ^ returning this value requires that `'1` must outlive `'2` | || - | |return type of closure is &'2 isize + | |return type of closure is `&'2 isize` | has type `&'1 isize` error: aborting due to 1 previous error diff --git a/tests/ui/regions/regions-infer-call-3.stderr b/tests/ui/regions/regions-infer-call-3.stderr index 14d1ce7ae8b38..688bcce7bf30b 100644 --- a/tests/ui/regions/regions-infer-call-3.stderr +++ b/tests/ui/regions/regions-infer-call-3.stderr @@ -4,7 +4,7 @@ error: lifetime may not live long enough LL | let z = with(|y| { select(x, y) }); | -- ^^^^^^^^^^^^ returning this value requires that `'1` must outlive `'2` | || - | |return type of closure is &'2 isize + | |return type of closure is `&'2 isize` | has type `&'1 isize` error: aborting due to 1 previous error diff --git a/tests/ui/regions/regions-ret-borrowed-1.stderr b/tests/ui/regions/regions-ret-borrowed-1.stderr index 4ad526602df6b..dd48a761c2184 100644 --- a/tests/ui/regions/regions-ret-borrowed-1.stderr +++ b/tests/ui/regions/regions-ret-borrowed-1.stderr @@ -4,7 +4,7 @@ error: lifetime may not live long enough LL | with(|o| o) | -- ^ returning this value requires that `'1` must outlive `'2` | || - | |return type of closure is &'2 isize + | |return type of closure is `&'2 isize` | has type `&'1 isize` error: aborting due to 1 previous error diff --git a/tests/ui/regions/regions-ret-borrowed.stderr b/tests/ui/regions/regions-ret-borrowed.stderr index f16a4a2e8c154..7119eff0141f9 100644 --- a/tests/ui/regions/regions-ret-borrowed.stderr +++ b/tests/ui/regions/regions-ret-borrowed.stderr @@ -4,7 +4,7 @@ error: lifetime may not live long enough LL | with(|o| o) | -- ^ returning this value requires that `'1` must outlive `'2` | || - | |return type of closure is &'2 isize + | |return type of closure is `&'2 isize` | has type `&'1 isize` error: aborting due to 1 previous error From c4016d083927d81d73dc8aba7d38ff631afa1ee8 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Thu, 22 Oct 2026 10:44:47 +0200 Subject: [PATCH 8/8] Include `deprecated` attributes in `rustc_resolve` intra-doc link resolution --- compiler/rustc_resolve/src/late.rs | 7 ++++- .../intra-doc/link-in-deprecation-note-2.rs | 15 +++++++++ .../link-in-deprecation-note-2.stderr | 31 +++++++++++++++++++ 3 files changed, 52 insertions(+), 1 deletion(-) create mode 100644 tests/rustdoc-ui/intra-doc/link-in-deprecation-note-2.rs create mode 100644 tests/rustdoc-ui/intra-doc/link-in-deprecation-note-2.stderr diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index 315ace9c0d4cf..310211bffdeb6 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -2964,9 +2964,14 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { let mut mod_inner_attrs_start = None; match item.kind { ItemKind::Mod(..) => { - // We only handle outer doc comments for modules here. + // We only handle outer attributes which can contain intra-doc links (doc comments + // and `deprecated`) for modules here. let attrs = if let Some(pos) = item.attrs.iter().position(|a| { a.doc_resolution_scope().is_some_and(|style| style == AttrStyle::Inner) + || matches!( + a.kind, + AttrKind::Normal(ref n) + if n.item.name() == Some(sym::deprecated) && a.style == AttrStyle::Inner) }) { mod_inner_attrs_start = Some(pos); &item.attrs[..pos] diff --git a/tests/rustdoc-ui/intra-doc/link-in-deprecation-note-2.rs b/tests/rustdoc-ui/intra-doc/link-in-deprecation-note-2.rs new file mode 100644 index 0000000000000..e993b988b3fea --- /dev/null +++ b/tests/rustdoc-ui/intra-doc/link-in-deprecation-note-2.rs @@ -0,0 +1,15 @@ +// Because inner and outer attributes don't have the same scope for a module, we need +// to also apply the logic to the other module attributes which can contain intra-doc +// links. +// Regression test for . + +#![deny(rustdoc::broken_intra_doc_links)] + +pub mod a { + #![deprecated = "[](TypeAlias::x)"] + //~^ ERROR broken_intra_doc_links +} + +#[deprecated = "[](TypeAlias::x)"] +//~^ ERROR broken_intra_doc_links +pub mod b {} diff --git a/tests/rustdoc-ui/intra-doc/link-in-deprecation-note-2.stderr b/tests/rustdoc-ui/intra-doc/link-in-deprecation-note-2.stderr new file mode 100644 index 0000000000000..36c6ce48dd42a --- /dev/null +++ b/tests/rustdoc-ui/intra-doc/link-in-deprecation-note-2.stderr @@ -0,0 +1,31 @@ +error: unresolved link to `TypeAlias::x` + --> $DIR/link-in-deprecation-note-2.rs:9:21 + | +LL | #![deprecated = "[](TypeAlias::x)"] + | ^^^^^^^^^^^^^^^^^^ + | + = note: the link appears in this line: + + [](TypeAlias::x) + ^^^^^^^^^^^^ + = note: no item named `TypeAlias` in scope +note: the lint level is defined here + --> $DIR/link-in-deprecation-note-2.rs:6:9 + | +LL | #![deny(rustdoc::broken_intra_doc_links)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: unresolved link to `TypeAlias::x` + --> $DIR/link-in-deprecation-note-2.rs:13:16 + | +LL | #[deprecated = "[](TypeAlias::x)"] + | ^^^^^^^^^^^^^^^^^^ + | + = note: the link appears in this line: + + [](TypeAlias::x) + ^^^^^^^^^^^^ + = note: no item named `TypeAlias` in scope + +error: aborting due to 2 previous errors +