From d7cf3cbce8748136e232ad44f9ff3f935eca9223 Mon Sep 17 00:00:00 2001 From: sjwang05 <63834813+sjwang05@users.noreply.github.com> Date: Sat, 15 Aug 2026 21:35:05 -0700 Subject: [PATCH 01/17] only rerun const eval if the const actually references opaques --- .../rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs index 3a4875c1d0951..f52408b3401f7 100644 --- a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs +++ b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs @@ -1411,7 +1411,12 @@ where alias_const: ty::AliasConst, ) -> Result, NoSolutionOrRerunNonErased> { if self.typing_mode().is_erased_not_coherence() { - match self.opaque_accesses.rerun_always(RerunReason::EvaluateConst)? {} + let resolved = self.deeply_resolve_ignoring_regions(alias_const); + // FIXME: get rid of this once GCE is removed + let is_gce = self.cx().features().generic_const_exprs(); + if resolved.has_opaque_types() || is_gce { + match self.opaque_accesses.rerun_always(RerunReason::EvaluateConst)? {} + } } self.delegate.evaluate_const(param_env, alias_const, |ty| { From e9a87d0f7bcc2e6fc2ab2f687e2e6e2c1697fa49 Mon Sep 17 00:00:00 2001 From: Lucas Sunsi Abreu Date: Thu, 17 Sep 2026 11:03:37 -0300 Subject: [PATCH 02/17] Add regression test for ambiguous trait with mixed import ids Co-authored-by: Philip Sampaio --- ...ambiguous-trait-with-mixed-import-paths.rs | 27 +++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 tests/ui/imports/ambiguous-trait-with-mixed-import-paths.rs diff --git a/tests/ui/imports/ambiguous-trait-with-mixed-import-paths.rs b/tests/ui/imports/ambiguous-trait-with-mixed-import-paths.rs new file mode 100644 index 0000000000000..acc97a2491f8e --- /dev/null +++ b/tests/ui/imports/ambiguous-trait-with-mixed-import-paths.rs @@ -0,0 +1,27 @@ +//! Regression test for . +//@ check-pass + +mod vis1 { + pub trait Visitor { + fn visit_b(&self); + fn visit_c(&self); + } +} + +mod vis2 { + pub trait Visitor {} +} + +use crate::{vis1::*, vis2::*}; + +pub struct Impl; + +impl vis1::Visitor for Impl { + fn visit_b(&self) {} + + fn visit_c(&self) { + self.visit_b(); + } +} + +fn main() {} From 8aa21475d1b01e6f780b5dcb268dd6bbf32a2d63 Mon Sep 17 00:00:00 2001 From: Bee Date: Thu, 24 Sep 2026 18:16:57 +0100 Subject: [PATCH 03/17] Add `f16` inline ASM support to `spirv.rs` --- compiler/rustc_target/src/asm/spirv.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_target/src/asm/spirv.rs b/compiler/rustc_target/src/asm/spirv.rs index c050c4e36b70e..19b1c37b3bfdb 100644 --- a/compiler/rustc_target/src/asm/spirv.rs +++ b/compiler/rustc_target/src/asm/spirv.rs @@ -35,7 +35,7 @@ impl SpirVInlineAsmRegClass { ) -> &'static [(InlineAsmType, Option)] { match self { Self::reg => { - types! { _: I8, I16, I32, I64, F32, F64; } + types! { _: I8, I16, I32, I64, F16, F32, F64; } } } } From 1161c07cf9e0d542c00426ec18eb706a73e317fb Mon Sep 17 00:00:00 2001 From: aerooneqq Date: Wed, 30 Sep 2026 13:39:14 +0000 Subject: [PATCH 04/17] Some refactorings around metadata encoding --- compiler/rustc_metadata/src/rmeta/decoder.rs | 6 +- compiler/rustc_metadata/src/rmeta/encoder.rs | 254 ++++++++++--------- compiler/rustc_metadata/src/rmeta/mod.rs | 2 +- 3 files changed, 139 insertions(+), 123 deletions(-) diff --git a/compiler/rustc_metadata/src/rmeta/decoder.rs b/compiler/rustc_metadata/src/rmeta/decoder.rs index 7dd920c7e39bd..5348ee0ccaac1 100644 --- a/compiler/rustc_metadata/src/rmeta/decoder.rs +++ b/compiler/rustc_metadata/src/rmeta/decoder.rs @@ -1544,10 +1544,12 @@ impl CrateMetadata { fn get_proc_macro_quoted_span(&self, tcx: TyCtxt<'_>, index: usize) -> Span { self.root - .tables + .proc_macro_data + .as_ref() + .expect("missing proc macro data") .proc_macro_quoted_spans .get(self, index) - .unwrap_or_else(|| panic!("Missing proc macro quoted span: {index:?}")) + .unwrap_or_else(|| panic!("missing proc macro quoted span: {index:?}")) .decode((self, tcx)) } diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs index 40b61a52d2310..03493d0e1b6a9 100644 --- a/compiler/rustc_metadata/src/rmeta/encoder.rs +++ b/compiler/rustc_metadata/src/rmeta/encoder.rs @@ -404,35 +404,42 @@ 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. -macro_rules! record { +// 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); - $self.$tables.$table.set_some($def_id.index, lazy); - } + let value = $value; + let lazy = $self.lazy(value); + $self.$tables.$table.set_some($def_id.index, lazy); }}; } +macro_rules! record_some { + ($self:ident.$tables:ident.$table:ident[$def_id:expr] <- $value:expr) => { + $self.$tables.$table.set_some($def_id.index, $value) + }; +} + +macro_rules! record_value { + ($self:ident.$tables:ident.$table:ident[$def_id:expr] <- $value:expr) => { + $self.$tables.$table.set($def_id.index, $value) + }; +} + // Shorthand for `$self.$tables.$table.set_some($def_id.index, $self.lazy_array($value))`, which would // normally need extra variables to avoid errors about multiple mutable borrows. macro_rules! record_array { ($self:ident.$tables:ident.$table:ident[$def_id:expr] <- $value:expr) => {{ - { - let value = $value; - let lazy = $self.lazy_array(value); - $self.$tables.$table.set_some($def_id.index, lazy); - } + let value = $value; + let lazy = $self.lazy_array(value); + $self.$tables.$table.set_some($def_id.index, 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); - $self.$tables.$table.set($def_id.index, lazy); - } + let value = $value; + let lazy = $self.lazy_array(value); + $self.$tables.$table.set($def_id.index, lazy); }}; } @@ -527,18 +534,18 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { for def_id in std::iter::once(CRATE_DEF_ID) .chain(self.tcx.resolutions(()).proc_macros.iter().copied()) { - let def_key = self.lazy(defs.def_key(def_id)); + let def_key = defs.def_key(def_id); let def_path_hash = defs.def_path_hash(def_id); - self.tables.def_keys.set_some(def_id.local_def_index, def_key); - self.tables - .def_path_hashes - .set(def_id.local_def_index, def_path_hash.local_hash().as_u64()); + let def_id = def_id.to_def_id(); + + record_some_lazy!(self.tables.def_keys[def_id] <- def_key); + record_value!(self.tables.def_path_hashes[def_id] <- def_path_hash.local_hash().as_u64()) } } else { for (def_index, def_key, def_path_hash) in defs.enumerated_keys_and_path_hashes() { - let def_key = self.lazy(def_key); - self.tables.def_keys.set_some(def_index, def_key); - self.tables.def_path_hashes.set(def_index, def_path_hash.local_hash().as_u64()); + let def_id = LocalDefId { local_def_index: def_index }.to_def_id(); + record_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()) } } } @@ -1444,7 +1451,8 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { if state.is_doc_hidden { attr_flags |= AttrFlags::IS_DOC_HIDDEN; } - self.tables.attr_flags.set(def_id.local_def_index, attr_flags); + + record_value!(self.tables.attr_flags[def_id.to_def_id()] <- attr_flags) } fn encode_def_ids(&mut self) { @@ -1461,7 +1469,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { for local_id in tcx.iter_local_def_id() { let def_id = local_id.to_def_id(); let def_kind = tcx.def_kind(local_id); - self.tables.def_kind.set_some(def_id.index, def_kind); + record_some!(self.tables.def_kind[def_id] <- def_kind); // The `DefCollector` will sometimes create unnecessary `DefId`s // for trivial const arguments which are directly lowered to @@ -1482,33 +1490,33 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { && let hir::Node::Field(field) = tcx.hir_node_by_def_id(local_id) && let Some(anon) = field.default { - record!(self.tables.default_fields[def_id] <- anon.def_id.to_def_id()); + record_some_lazy!(self.tables.default_fields[def_id] <- anon.def_id.to_def_id()); } if should_encode_span(def_kind) { let def_span = tcx.def_span(local_id); - record!(self.tables.def_span[def_id] <- def_span); + record_some_lazy!(self.tables.def_span[def_id] <- def_span); } if should_encode_attrs(def_kind) { self.encode_attrs(local_id); } if should_encode_expn_that_defined(def_kind) { - record!(self.tables.expn_that_defined[def_id] <- self.tcx.expn_that_defined(def_id)); + record_some_lazy!(self.tables.expn_that_defined[def_id] <- self.tcx.expn_that_defined(def_id)); } if should_encode_span(def_kind) && let Some(ident_span) = tcx.def_ident_span(def_id) { - record!(self.tables.def_ident_span[def_id] <- ident_span); + record_some_lazy!(self.tables.def_ident_span[def_id] <- ident_span); } if def_kind.has_codegen_attrs() { - record!(self.tables.codegen_fn_attrs[def_id] <- self.tcx.codegen_fn_attrs(def_id)); + record_some_lazy!(self.tables.codegen_fn_attrs[def_id] <- self.tcx.codegen_fn_attrs(def_id)); } if should_encode_visibility(def_kind) { let vis = self .tcx .local_visibility(local_id) .map_id(|mod_id| mod_id.to_local_def_id().local_def_index); - record!(self.tables.visibility[def_id] <- vis); + record_some_lazy!(self.tables.visibility[def_id] <- vis); } if should_encode_stability(def_kind) { self.encode_stability(def_id); @@ -1521,46 +1529,46 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { record_array!(self.tables.variances_of[def_id] <- v); } if should_encode_fn_sig(def_kind) { - record!(self.tables.fn_sig[def_id] <- tcx.fn_sig(def_id)); + record_some_lazy!(self.tables.fn_sig[def_id] <- tcx.fn_sig(def_id)); } if should_encode_generics(def_kind) { let g = tcx.generics_of(def_id); - record!(self.tables.generics_of[def_id] <- g); - record!(self.tables.explicit_clauses_of[def_id] <- self.tcx.explicit_clauses_of(def_id)); + record_some_lazy!(self.tables.generics_of[def_id] <- g); + record_some_lazy!(self.tables.explicit_clauses_of[def_id] <- self.tcx.explicit_clauses_of(def_id)); let inferred_outlives = self.tcx.inferred_outlives_of(def_id); record_defaulted_array!(self.tables.inferred_outlives_of[def_id] <- inferred_outlives); for param in &g.own_params { if let ty::GenericParamDefKind::Const { has_default: true, .. } = param.kind { let default = self.tcx.const_param_default(param.def_id); - record!(self.tables.const_param_default[param.def_id] <- default); + record_some_lazy!(self.tables.const_param_default[param.def_id] <- default); } } } if tcx.is_conditionally_const(def_id) { - record!(self.tables.const_conditions[def_id] <- self.tcx.const_conditions(def_id)); + record_some_lazy!(self.tables.const_conditions[def_id] <- self.tcx.const_conditions(def_id)); } if should_encode_type(tcx, local_id, def_kind) { - record!(self.tables.type_of[def_id] <- self.tcx.type_of(def_id)); + record_some_lazy!(self.tables.type_of[def_id] <- self.tcx.type_of(def_id)); } if should_encode_constness(def_kind) { let constness = self.tcx.constness(def_id); - self.tables.constness.set(def_id.index, constness); + record_value!(self.tables.constness[def_id] <- constness) } if let DefKind::Fn | DefKind::AssocFn = def_kind { let asyncness = tcx.asyncness(def_id); - self.tables.asyncness.set(def_id.index, asyncness); + record_value!(self.tables.asyncness[def_id] <- asyncness); record_array!(self.tables.fn_arg_idents[def_id] <- tcx.fn_arg_idents(def_id)); } if let Some(name) = tcx.intrinsic(def_id) { - record!(self.tables.intrinsic[def_id] <- name); + record_some_lazy!(self.tables.intrinsic[def_id] <- name); } if let DefKind::TyParam | DefKind::Trait = def_kind { let default = self.tcx.object_lifetime_default(def_id); - record!(self.tables.object_lifetime_default[def_id] <- default); + record_some_lazy!(self.tables.object_lifetime_default[def_id] <- default); } if let DefKind::Trait = def_kind { - record!(self.tables.trait_def[def_id] <- self.tcx.trait_def(def_id)); + record_some_lazy!(self.tables.trait_def[def_id] <- self.tcx.trait_def(def_id)); record_defaulted_array!(self.tables.explicit_super_clauses_of[def_id] <- self.tcx.explicit_super_clauses_of(def_id).skip_binder()); record_defaulted_array!(self.tables.explicit_implied_clauses_of[def_id] <- @@ -1574,7 +1582,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { } } if let DefKind::TraitAlias = def_kind { - record!(self.tables.trait_def[def_id] <- self.tcx.trait_def(def_id)); + record_some_lazy!(self.tables.trait_def[def_id] <- self.tcx.trait_def(def_id)); record_defaulted_array!(self.tables.explicit_super_clauses_of[def_id] <- self.tcx.explicit_super_clauses_of(def_id).skip_binder()); record_defaulted_array!(self.tables.explicit_implied_clauses_of[def_id] <- @@ -1595,28 +1603,28 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { if let DefKind::Closure | DefKind::SyntheticCoroutineBody = def_kind && let Some(coroutine_kind) = self.tcx.coroutine_kind(def_id) { - self.tables.coroutine_kind.set(def_id.index, Some(coroutine_kind)) + record_value!(self.tables.coroutine_kind[def_id] <- Some(coroutine_kind)) } if def_kind == DefKind::Closure && tcx.type_of(def_id).skip_binder().is_coroutine_closure() { let coroutine_for_closure = self.tcx.coroutine_for_closure(def_id); - self.tables - .coroutine_for_closure - .set_some(def_id.index, coroutine_for_closure.into()); + record_some!(self.tables.coroutine_for_closure[def_id] <- coroutine_for_closure.into()); // If this async closure has a by-move body, record it too. if tcx.needs_coroutine_by_move_body_def_id(coroutine_for_closure) { - self.tables.coroutine_by_move_body_def_id.set_some( - coroutine_for_closure.index, - self.tcx.coroutine_by_move_body_def_id(coroutine_for_closure).into(), - ); + let id = self.tcx.coroutine_by_move_body_def_id(coroutine_for_closure); + record_some!( + self.tables.coroutine_by_move_body_def_id[coroutine_for_closure] <- id.into() + ) } } if let DefKind::Static { .. } = def_kind { if !self.tcx.is_foreign_item(def_id) { match self.tcx.eval_static_initializer(def_id) { - Ok(data) => record!(self.tables.eval_static_initializer[def_id] <- data), + Ok(data) => { + record_some_lazy!(self.tables.eval_static_initializer[def_id] <- data) + } Err(err) => match err { interpret::ErrorHandled::Reported(_, _) => { self.tcx.dcx().delayed_bug(format!( @@ -1640,50 +1648,49 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { self.encode_info_for_macro(local_id); } if let DefKind::TyAlias = def_kind { - self.tables - .type_alias_is_checked - .set(def_id.index, self.tcx.type_alias_is_checked(def_id)); + record_value!(self.tables.type_alias_is_checked[def_id] <- self.tcx.type_alias_is_checked(def_id)); + if self.tcx.type_alias_is_checked(def_id) { - record!(self.tables.args_known_to_outlive_alias_params[def_id] <- tcx.args_known_to_outlive_alias_params(def_id)); + record_some_lazy!(self.tables.args_known_to_outlive_alias_params[def_id] <- tcx.args_known_to_outlive_alias_params(def_id)); } } if let DefKind::OpaqueTy = def_kind { self.encode_explicit_item_bounds(def_id); self.encode_explicit_item_self_bounds(def_id); - record!(self.tables.opaque_ty_origin[def_id] <- self.tcx.opaque_ty_origin(def_id)); + record_some_lazy!(self.tables.opaque_ty_origin[def_id] <- self.tcx.opaque_ty_origin(def_id)); self.encode_precise_capturing_args(def_id); if tcx.is_conditionally_const(def_id) { record_defaulted_array!(self.tables.explicit_implied_const_bounds[def_id] <- tcx.explicit_implied_const_bounds(def_id).skip_binder()); } - record!(self.tables.args_known_to_outlive_alias_params[def_id] <- tcx.args_known_to_outlive_alias_params(def_id)); + record_some_lazy!(self.tables.args_known_to_outlive_alias_params[def_id] <- tcx.args_known_to_outlive_alias_params(def_id)); } if let DefKind::AssocTy = def_kind { let assoc_item = tcx.associated_item(def_id); match assoc_item.container { ty::AssocContainer::Trait => { - record!(self.tables.args_known_to_outlive_alias_params[def_id] <- tcx.args_known_to_outlive_alias_params(def_id)); + record_some_lazy!(self.tables.args_known_to_outlive_alias_params[def_id] <- tcx.args_known_to_outlive_alias_params(def_id)); } ty::AssocContainer::InherentImpl => { - record!(self.tables.args_known_to_outlive_alias_params[def_id] <- tcx.args_known_to_outlive_alias_params(def_id)); + record_some_lazy!(self.tables.args_known_to_outlive_alias_params[def_id] <- tcx.args_known_to_outlive_alias_params(def_id)); } ty::AssocContainer::TraitImpl(_) => {} } } if let DefKind::AnonConst = def_kind { - record!(self.tables.anon_const_kind[def_id] <- self.tcx.anon_const_kind(def_id)); + record_some_lazy!(self.tables.anon_const_kind[def_id] <- self.tcx.anon_const_kind(def_id)); } if let DefKind::Const | DefKind::AssocConst = def_kind { - record!(self.tables.const_of_item[def_id] <- self.tcx.const_of_item(def_id)); + record_some_lazy!(self.tables.const_of_item[def_id] <- self.tcx.const_of_item(def_id)); } if tcx.impl_method_has_trait_impl_trait_tys(def_id) && let Ok(table) = self.tcx.collect_return_position_impl_trait_in_trait_tys(def_id) { - record!(self.tables.collect_return_position_impl_trait_in_trait_tys[def_id] <- table); + record_some_lazy!(self.tables.collect_return_position_impl_trait_in_trait_tys[def_id] <- table); } if let DefKind::Impl { .. } | DefKind::Trait = def_kind { let table = tcx.associated_types_for_impl_traits_in_trait_or_impl(def_id); - record!(self.tables.associated_types_for_impl_traits_in_trait_or_impl[def_id] <- table); + record_some_lazy!(self.tables.associated_types_for_impl_traits_in_trait_or_impl[def_id] <- table); } } @@ -1695,7 +1702,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { } for (def_id, res_map) in &tcx.resolutions(()).doc_link_resolutions { - record!(self.tables.doc_link_resolutions[def_id.to_def_id()] <- res_map); + record_some_lazy!(self.tables.doc_link_resolutions[def_id.to_def_id()] <- res_map); } for (def_id, traits) in &tcx.resolutions(()).doc_link_traits_in_scope { @@ -1722,10 +1729,10 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { let def_id = local_def_id.to_def_id(); let tcx = self.tcx; let adt_def = tcx.adt_def(def_id); - record!(self.tables.repr_options[def_id] <- adt_def.repr()); + record_some_lazy!(self.tables.repr_options[def_id] <- adt_def.repr()); let params_in_repr = self.tcx.params_in_repr(def_id); - record!(self.tables.params_in_repr[def_id] <- params_in_repr); + record_some_lazy!(self.tables.params_in_repr[def_id] <- params_in_repr); if adt_def.is_enum() { let module_children = tcx.module_children_local(local_def_id); @@ -1745,7 +1752,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { ctor: variant.ctor.map(|(kind, def_id)| (kind, def_id.index)), is_non_exhaustive: variant.is_field_list_non_exhaustive(), }; - record!(self.tables.variant_data[variant.def_id] <- data); + record_some_lazy!(self.tables.variant_data[variant.def_id] <- data); record_array!(self.tables.associated_item_or_field_def_ids[variant.def_id] <- variant.fields.iter().map(|f| { assert!(f.did.is_local()); @@ -1753,8 +1760,8 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { })); for field in &variant.fields { - self.tables.safety.set(field.did.index, field.safety); - record!( + record_value!(self.tables.safety[field.did] <- field.safety); + record_some_lazy!( self.tables.mut_restriction[field.did] <- field.mut_restriction ); } @@ -1762,16 +1769,16 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { if let Some((CtorKind::Fn, ctor_def_id)) = variant.ctor { let fn_sig = tcx.fn_sig(ctor_def_id); // FIXME only encode signature for ctor_def_id - record!(self.tables.fn_sig[variant.def_id] <- fn_sig); + record_some_lazy!(self.tables.fn_sig[variant.def_id] <- fn_sig); } } if let Some(destructor) = tcx.adt_destructor(local_def_id) { - record!(self.tables.adt_destructor[def_id] <- destructor); + record_some_lazy!(self.tables.adt_destructor[def_id] <- destructor); } if let Some(destructor) = tcx.adt_async_destructor(local_def_id) { - record!(self.tables.adt_async_destructor[def_id] <- destructor); + record_some_lazy!(self.tables.adt_async_destructor[def_id] <- destructor); } } @@ -1787,7 +1794,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { // items - we encode information about proc-macros later on. if self.is_proc_macro { // Encode this here because we don't do it in encode_def_ids. - record!(self.tables.expn_that_defined[def_id] <- tcx.expn_that_defined(local_def_id)); + record_some_lazy!(self.tables.expn_that_defined[def_id] <- tcx.expn_that_defined(local_def_id)); } else { let module_children = tcx.module_children_local(local_def_id); @@ -1826,10 +1833,10 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { let item = tcx.associated_item(def_id); if matches!(item.container, AssocContainer::Trait | AssocContainer::TraitImpl(_)) { - self.tables.defaultness.set(def_id.index, item.defaultness(tcx)); + record_value!(self.tables.defaultness[def_id] <- item.defaultness(tcx)); } - record!(self.tables.assoc_container[def_id] <- item.container); + record_some_lazy!(self.tables.assoc_container[def_id] <- item.container); if let AssocContainer::Trait = item.container && item.is_type() @@ -1842,7 +1849,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { } } if let ty::AssocKind::Type { data: ty::AssocTypeData::Rpitit(rpitit_info) } = item.kind { - record!(self.tables.opt_rpitit_info[def_id] <- rpitit_info); + record_some_lazy!(self.tables.opt_rpitit_info[def_id] <- rpitit_info); if matches!(rpitit_info, ty::ImplTraitInTraitData::Trait { .. }) { record_array!( self.tables.assumed_wf_types_for_rpitit[def_id] @@ -1878,53 +1885,53 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { debug!("EntryBuilder::encode_mir({:?})", def_id); if encode_opt { - record!(self.tables.optimized_mir[def_id.to_def_id()] <- tcx.optimized_mir(def_id)); - self.tables - .cross_crate_inlinable - .set(def_id.to_def_id().index, self.tcx.cross_crate_inlinable(def_id)); - record!(self.tables.closure_saved_names_of_captured_variables[def_id.to_def_id()] + record_some_lazy!(self.tables.optimized_mir[def_id.to_def_id()] <- tcx.optimized_mir(def_id)); + + record_value!(self.tables.cross_crate_inlinable[def_id.to_def_id()] <- self.tcx.cross_crate_inlinable(def_id)); + + record_some_lazy!(self.tables.closure_saved_names_of_captured_variables[def_id.to_def_id()] <- tcx.closure_saved_names_of_captured_variables(def_id)); if self.tcx.is_coroutine(def_id.to_def_id()) && let Some(witnesses) = tcx.mir_coroutine_witnesses(def_id) { - record!(self.tables.mir_coroutine_witnesses[def_id.to_def_id()] <- witnesses); + record_some_lazy!(self.tables.mir_coroutine_witnesses[def_id.to_def_id()] <- witnesses); } } let mut is_trivial = false; if encode_const { if let Some((val, ty)) = tcx.trivial_const(def_id) { is_trivial = true; - record!(self.tables.trivial_const[def_id.to_def_id()] <- (val, ty)); + record_some_lazy!(self.tables.trivial_const[def_id.to_def_id()] <- (val, ty)); } else { is_trivial = false; - record!(self.tables.mir_for_ctfe[def_id.to_def_id()] <- tcx.mir_for_ctfe(def_id)); + record_some_lazy!(self.tables.mir_for_ctfe[def_id.to_def_id()] <- tcx.mir_for_ctfe(def_id)); } // FIXME(generic_const_exprs): this feels wrong to have in `encode_mir` let abstract_const = tcx.thir_abstract_const(def_id); if let Ok(Some(abstract_const)) = abstract_const { - record!(self.tables.thir_abstract_const[def_id.to_def_id()] <- abstract_const); + record_some_lazy!(self.tables.thir_abstract_const[def_id.to_def_id()] <- abstract_const); } if should_encode_const(tcx.def_kind(def_id)) { let qualifs = tcx.mir_const_qualif(def_id); - record!(self.tables.mir_const_qualif[def_id.to_def_id()] <- qualifs); + record_some_lazy!(self.tables.mir_const_qualif[def_id.to_def_id()] <- qualifs); let body = tcx.hir_maybe_body_owned_by(def_id); if let Some(body) = body { let const_data = rendered_const(self.tcx, &body, def_id); - record!(self.tables.rendered_const[def_id.to_def_id()] <- const_data); + record_some_lazy!(self.tables.rendered_const[def_id.to_def_id()] <- const_data); } } } if !is_trivial { - record!(self.tables.promoted_mir[def_id.to_def_id()] <- tcx.promoted_mir(def_id)); + record_some_lazy!(self.tables.promoted_mir[def_id.to_def_id()] <- tcx.promoted_mir(def_id)); } if self.tcx.is_coroutine(def_id.to_def_id()) && let Some(witnesses) = tcx.mir_coroutine_witnesses(def_id) { - record!(self.tables.mir_coroutine_witnesses[def_id.to_def_id()] <- witnesses); + record_some_lazy!(self.tables.mir_coroutine_witnesses[def_id.to_def_id()] <- witnesses); } } @@ -1950,7 +1957,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { // the stability attributes are even enabled before using their queries. if self.feat.staged_api() || self.tcx.sess.opts.unstable_opts.force_unstable_if_unmarked { if let Some(stab) = self.tcx.lookup_stability(def_id) { - record!(self.tables.lookup_stability[def_id] <- stab) + record_some_lazy!(self.tables.lookup_stability[def_id] <- stab) } } } @@ -1961,7 +1968,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { // the stability attributes are even enabled before using their queries. if self.feat.staged_api() || self.tcx.sess.opts.unstable_opts.force_unstable_if_unmarked { if let Some(stab) = self.tcx.lookup_const_stability(def_id) { - record!(self.tables.lookup_const_stability[def_id] <- stab) + record_some_lazy!(self.tables.lookup_const_stability[def_id] <- stab) } } } @@ -1972,7 +1979,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { // the stability attributes are even enabled before using their queries. if self.feat.staged_api() || self.tcx.sess.opts.unstable_opts.force_unstable_if_unmarked { if let Some(stab) = self.tcx.lookup_default_body_stability(def_id) { - record!(self.tables.lookup_default_body_stability[def_id] <- stab) + record_some_lazy!(self.tables.lookup_default_body_stability[def_id] <- stab) } } } @@ -1980,7 +1987,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { #[instrument(level = "debug", skip(self))] fn encode_deprecation(&mut self, def_id: DefId) { if let Some(depr) = self.tcx.lookup_deprecation(def_id) { - record!(self.tables.lookup_deprecation_entry[def_id] <- depr); + record_some_lazy!(self.tables.lookup_deprecation_entry[def_id] <- depr); } } @@ -1989,8 +1996,8 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { let tcx = self.tcx; let (_, macro_def, _) = tcx.hir_expect_item(def_id).expect_macro(); - self.tables.is_macro_rules.set(def_id.local_def_index, macro_def.macro_rules); - record!(self.tables.macro_definition[def_id.to_def_id()] <- &*macro_def.body); + record_value!(self.tables.is_macro_rules[def_id.to_def_id()] <- macro_def.macro_rules); + record_some_lazy!(self.tables.macro_definition[def_id.to_def_id()] <- &*macro_def.body); } fn encode_native_libraries(&mut self) -> LazyArray { @@ -2039,24 +2046,20 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { let tcx = self.tcx; let proc_macro_decls_static = tcx.proc_macro_decls_static(()).unwrap().local_def_index; let stability = tcx.lookup_stability(CRATE_DEF_ID); - for (i, span) in self.tcx.sess.proc_macro_quoted_spans() { - let span = self.lazy(span); - self.tables.proc_macro_quoted_spans.set_some(i, span); - } - self.tables.def_kind.set_some(LOCAL_CRATE.as_def_id().index, DefKind::Mod); - record!(self.tables.def_span[LOCAL_CRATE.as_def_id()] <- tcx.def_span(LOCAL_CRATE.as_def_id())); + record_some!(self.tables.def_kind[LOCAL_CRATE.as_def_id()] <- DefKind::Mod); + record_some_lazy!(self.tables.def_span[LOCAL_CRATE.as_def_id()] <- tcx.def_span(LOCAL_CRATE.as_def_id())); self.encode_attrs(LOCAL_CRATE.as_def_id().expect_local()); let vis = tcx .local_visibility(CRATE_DEF_ID) .map_id(|mod_id| mod_id.to_local_def_id().local_def_index); - record!(self.tables.visibility[LOCAL_CRATE.as_def_id()] <- vis); + record_some_lazy!(self.tables.visibility[LOCAL_CRATE.as_def_id()] <- vis); if let Some(stability) = stability { - record!(self.tables.lookup_stability[LOCAL_CRATE.as_def_id()] <- stability); + record_some_lazy!(self.tables.lookup_stability[LOCAL_CRATE.as_def_id()] <- stability); } self.encode_deprecation(LOCAL_CRATE.as_def_id()); if let Some(res_map) = tcx.resolutions(()).doc_link_resolutions.get(&CRATE_MOD_ID) { - record!(self.tables.doc_link_resolutions[LOCAL_CRATE.as_def_id()] <- res_map); + record_some_lazy!(self.tables.doc_link_resolutions[LOCAL_CRATE.as_def_id()] <- res_map); } if let Some(traits) = tcx.resolutions(()).doc_link_traits_in_scope.get(&CRATE_MOD_ID) { record_array!(self.tables.doc_link_traits_in_scope[LOCAL_CRATE.as_def_id()] <- traits); @@ -2103,20 +2106,33 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { def_key.disambiguated_data.data = DefPathData::MacroNs(name); let def_id = id.to_def_id(); - self.tables.def_kind.set_some(def_id.index, DefKind::Macro(macro_kind.into())); + record_some!(self.tables.def_kind[def_id] <- DefKind::Macro(macro_kind.into())); + self.encode_attrs(id); - record!(self.tables.def_keys[def_id] <- def_key); - record!(self.tables.def_ident_span[def_id] <- span); - record!(self.tables.def_span[def_id] <- span); - record!(self.tables.visibility[def_id] <- ty::Visibility::Public); + record_some_lazy!(self.tables.def_keys[def_id] <- def_key); + record_some_lazy!(self.tables.def_ident_span[def_id] <- span); + record_some_lazy!(self.tables.def_span[def_id] <- span); + record_some_lazy!(self.tables.visibility[def_id] <- ty::Visibility::Public); if let Some(stability) = stability { - record!(self.tables.lookup_stability[def_id] <- stability); + record_some_lazy!(self.tables.lookup_stability[def_id] <- stability); } } let macros = self.lazy_array(macros); - Some(ProcMacroData { proc_macro_decls_static, stability, macros }) + let mut proc_macro_quoted_spans = TableBuilder::default(); + for (i, span) in self.tcx.sess.proc_macro_quoted_spans() { + proc_macro_quoted_spans.set_some(i, self.lazy(span)); + } + + let proc_macro_quoted_spans = proc_macro_quoted_spans.encode(&mut self.opaque); + + Some(ProcMacroData { + proc_macro_decls_static, + stability, + macros, + proc_macro_quoted_spans, + }) } else { None } @@ -2263,15 +2279,13 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { if of_trait { let header = tcx.impl_trait_header(def_id); - record!(self.tables.impl_trait_header[def_id] <- header); + record_some_lazy!(self.tables.impl_trait_header[def_id] <- header); let impl_is_fully_generic_for_reflection = tcx.impl_is_fully_generic_for_reflection(def_id); - self.tables - .impl_is_fully_generic_for_reflection - .set(def_id.index, impl_is_fully_generic_for_reflection); - self.tables.defaultness.set(def_id.index, tcx.defaultness(def_id)); + record_value!(self.tables.impl_is_fully_generic_for_reflection[def_id] <- impl_is_fully_generic_for_reflection); + record_value!(self.tables.defaultness[def_id] <- tcx.defaultness(def_id)); let trait_ref = header.trait_ref.instantiate_identity().skip_norm_wip(); let simplified_self_ty = fast_reject::simplify_type( @@ -2288,14 +2302,14 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { if let Ok(mut an) = trait_def.ancestors(tcx, def_id) && let Some(specialization_graph::Node::Impl(parent)) = an.nth(1) { - self.tables.impl_parent.set_some(def_id.index, parent.into()); + record_some!(self.tables.impl_parent[def_id] <- parent.into()); } // if this is an impl of `CoerceUnsized`, create its // "unsized info", else just store None if tcx.is_lang_item(trait_ref.def_id, LangItem::CoerceUnsized) { let coerce_unsized_info = tcx.coerce_unsized_info(def_id).unwrap(); - record!(self.tables.coerce_unsized_info[def_id] <- coerce_unsized_info); + record_some_lazy!(self.tables.coerce_unsized_info[def_id] <- coerce_unsized_info); } } } diff --git a/compiler/rustc_metadata/src/rmeta/mod.rs b/compiler/rustc_metadata/src/rmeta/mod.rs index b70151604f679..f7a437043dade 100644 --- a/compiler/rustc_metadata/src/rmeta/mod.rs +++ b/compiler/rustc_metadata/src/rmeta/mod.rs @@ -214,6 +214,7 @@ pub(crate) struct ProcMacroData { proc_macro_decls_static: DefIndex, stability: Option, macros: LazyArray<(DefIndex, LazyValue)>, + proc_macro_quoted_spans: LazyTableSingleIdx>>, } #[derive(MetadataEncodable, LazyDecodable)] @@ -503,7 +504,6 @@ define_tables! { // `DefPathTable` up front, since we may only ever use a few // definitions from any given crate. def_keys: Table>, - proc_macro_quoted_spans: Table>, variant_data: Table>, assoc_container: Table>, macro_definition: Table>, From 7c35df5fd9c557cd4036a8d174027eb808547a21 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Sun, 27 Sep 2026 16:05:10 +0200 Subject: [PATCH 05/17] Remove #[linkage = "internal"] Rustc already defaults to this for regular items whenever possible. Overriding it would only lead to linker errors. And for depending on the exact codegen unit partitioning rustc uses, so there it is a bad idea to use it too. --- .../rustc_attr_parsing/src/attributes/link_attrs.rs | 3 --- compiler/rustc_codegen_gcc/tests/c/import_linkage.c | 1 - compiler/rustc_codegen_gcc/tests/c/static_linkage.c | 8 +------- .../rustc_codegen_gcc/tests/run/import_linkage.rs | 8 -------- .../rustc_codegen_gcc/tests/run/static_linkage.rs | 11 +---------- compiler/rustc_span/src/symbol.rs | 1 - .../linkage-attr-does-not-panic-llvm-issue-33992.rs | 3 --- tests/ui/linkage-attr/linkage3.stderr | 2 +- tests/ui/lint/inline-exported.rs | 4 ---- 9 files changed, 3 insertions(+), 38 deletions(-) diff --git a/compiler/rustc_attr_parsing/src/attributes/link_attrs.rs b/compiler/rustc_attr_parsing/src/attributes/link_attrs.rs index f4d0fa35e3f47..bb5160db76ee8 100644 --- a/compiler/rustc_attr_parsing/src/attributes/link_attrs.rs +++ b/compiler/rustc_attr_parsing/src/attributes/link_attrs.rs @@ -688,7 +688,6 @@ impl SingleAttributeParser for LinkageParser { "common", "extern_weak", "external", - "internal", "linkonce", "linkonce_odr", "weak", @@ -714,7 +713,6 @@ impl SingleAttributeParser for LinkageParser { sym::common => Linkage::Common, sym::extern_weak => Linkage::ExternalWeak, sym::external => Linkage::External, - sym::internal => Linkage::Internal, sym::linkonce => Linkage::LinkOnceAny, sym::linkonce_odr => Linkage::LinkOnceODR, sym::weak => Linkage::WeakAny, @@ -728,7 +726,6 @@ impl SingleAttributeParser for LinkageParser { sym::common, sym::extern_weak, sym::external, - sym::internal, sym::linkonce, sym::linkonce_odr, sym::weak, diff --git a/compiler/rustc_codegen_gcc/tests/c/import_linkage.c b/compiler/rustc_codegen_gcc/tests/c/import_linkage.c index f2beb9603d08b..d725b86c6c14b 100644 --- a/compiler/rustc_codegen_gcc/tests/c/import_linkage.c +++ b/compiler/rustc_codegen_gcc/tests/c/import_linkage.c @@ -14,4 +14,3 @@ int32_t weak_value = 5; int32_t weak_odr_value = 6; int32_t common_value = 7; int32_t extern_weak_value = 8; -int32_t internal_value = 9; diff --git a/compiler/rustc_codegen_gcc/tests/c/static_linkage.c b/compiler/rustc_codegen_gcc/tests/c/static_linkage.c index 787e61f9cf105..66c77bd418b94 100644 --- a/compiler/rustc_codegen_gcc/tests/c/static_linkage.c +++ b/compiler/rustc_codegen_gcc/tests/c/static_linkage.c @@ -1,9 +1,6 @@ /* Strong definitions of the statics that `tests/run/static_linkage.rs` also defines, but weakly. * The linker has to keep these and drop the Rust ones; a backend that emits the Rust definitions - * as ordinary global symbols fails the link with a duplicate definition instead. - * - * `internal_static` is the opposite case: the Rust side keeps its own, and the two definitions - * coexist because the Rust one is local. */ + * as ordinary global symbols fails the link with a duplicate definition instead. */ #include @@ -12,7 +9,6 @@ int32_t weak_odr_static = 2; int32_t linkonce_static = 3; int32_t linkonce_odr_static = 4; int32_t common_static = 5; -int32_t internal_static = 200; /* `available_externally` promises the real definition lives elsewhere: a backend may read this one * or emit an equivalent copy of the Rust initializer, so the two have to hold the same value. */ @@ -31,7 +27,5 @@ int32_t c_read_all(void) return 14; if (common_static != 5) return 15; - if (internal_static != 200) - return 16; return 0; } diff --git a/compiler/rustc_codegen_gcc/tests/run/import_linkage.rs b/compiler/rustc_codegen_gcc/tests/run/import_linkage.rs index bf5cb9e532799..33c9ef57e9599 100644 --- a/compiler/rustc_codegen_gcc/tests/run/import_linkage.rs +++ b/compiler/rustc_codegen_gcc/tests/run/import_linkage.rs @@ -35,11 +35,6 @@ extern "C" { static common_value: *const i32; #[linkage = "extern_weak"] static extern_weak_value: *const i32; - // An import is an undefined reference whatever the flavour says. Upstream bug: rustc lowers - // this one to an internal declaration, which LLVM's verifier rejects ("Global is external, but - // doesn't have external or weak linkage!") and which crashes cg_llvm at -O3. - #[linkage = "internal"] - static internal_value: *const i32; // Nothing defines this one, so it stays null instead of breaking the link. #[linkage = "extern_weak"] @@ -73,9 +68,6 @@ extern "C" fn main(_argc: i32, _argv: *const *const u8) -> i32 { if *extern_weak_value != 8 { return 8; } - if *internal_value != 9 { - return 9; - } if undefined_value as usize != 0 { return 10; } diff --git a/compiler/rustc_codegen_gcc/tests/run/static_linkage.rs b/compiler/rustc_codegen_gcc/tests/run/static_linkage.rs index 7b911c064d797..ba9e1fe4d2645 100644 --- a/compiler/rustc_codegen_gcc/tests/run/static_linkage.rs +++ b/compiler/rustc_codegen_gcc/tests/run/static_linkage.rs @@ -7,8 +7,7 @@ // `tests/c/static_linkage.c`, which defines the overridable ones strongly. // // If `predefine_static` were to ignore its `linkage` argument outright, every static would come out as -// an ordinary global symbol: the overridable ones would clash with the C definitions at link time, and -// `internal` would export a symbol it should have kept private. +// an ordinary global symbol: the overridable ones would clash with the C definitions at link time. #![feature(linkage, no_core)] #![no_std] @@ -39,11 +38,6 @@ pub static linkonce_odr_static: i32 = 0; #[no_mangle] pub static mut common_static: i32 = 0; -// Private to this crate, so the C definition of the same name is a different object. -#[linkage = "internal"] -#[no_mangle] -pub static internal_static: i32 = 100; - // Not overridden by the C side: the definition here is the one that survives. #[linkage = "weak"] #[no_mangle] @@ -66,9 +60,6 @@ extern "C" fn main(_argc: i32, _argv: *const *const u8) -> i32 { return result; } - if internal_static != 100 { - return 1; - } if only_weak_static != 6 { return 2; } diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 3debf3248ff80..a7dbf7dc5e035 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -1176,7 +1176,6 @@ symbols! { integer_max, integer_min, integral, - internal, internal_eq_trait_method_impls, internal_features, interrupt, diff --git a/tests/ui/linkage-attr/linkage-attr-does-not-panic-llvm-issue-33992.rs b/tests/ui/linkage-attr/linkage-attr-does-not-panic-llvm-issue-33992.rs index 0717a2d5a6c9e..d80236cae7c6d 100644 --- a/tests/ui/linkage-attr/linkage-attr-does-not-panic-llvm-issue-33992.rs +++ b/tests/ui/linkage-attr/linkage-attr-does-not-panic-llvm-issue-33992.rs @@ -7,9 +7,6 @@ #[linkage = "external"] pub static TEST2: bool = true; -#[linkage = "internal"] -pub static TEST3: bool = true; - #[cfg(not(target_env = "msvc"))] #[linkage = "linkonce"] pub static TEST4: bool = true; diff --git a/tests/ui/linkage-attr/linkage3.stderr b/tests/ui/linkage-attr/linkage3.stderr index aa25cd39ba291..45555eef3d120 100644 --- a/tests/ui/linkage-attr/linkage3.stderr +++ b/tests/ui/linkage-attr/linkage3.stderr @@ -4,7 +4,7 @@ error[E0539]: malformed `linkage` attribute input LL | #[linkage = "foo"] | ^^^^^^^^^^----- | | - | valid arguments are `available_externally`, `common`, `extern_weak`, `external`, `internal`, `linkonce`, `linkonce_odr`, `weak` or `weak_odr` + | valid arguments are `available_externally`, `common`, `extern_weak`, `external`, `linkonce`, `linkonce_odr`, `weak` or `weak_odr` error: aborting due to 1 previous error diff --git a/tests/ui/lint/inline-exported.rs b/tests/ui/lint/inline-exported.rs index 6a23cd58236ff..bacbd128cd632 100644 --- a/tests/ui/lint/inline-exported.rs +++ b/tests/ui/lint/inline-exported.rs @@ -22,7 +22,3 @@ fn external_linkage() {} #[inline] fn normal() {} - -#[inline] -#[linkage = "internal"] // not exported -fn internal_linkage() {} From 6d02b772e3930c415cf7990ffb5fbfb277bde796 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Sun, 27 Sep 2026 16:08:18 +0200 Subject: [PATCH 06/17] Remove #[linkage = "external"] Rustc already defaults to this for #[no_mangle]/#[export_name] items. There is no reason to explicitly use it. --- .../rustc_attr_parsing/src/attributes/link_attrs.rs | 3 --- compiler/rustc_codegen_gcc/tests/c/import_linkage.c | 1 - .../rustc_codegen_gcc/tests/run/import_linkage.rs | 5 ----- tests/codegen-llvm/direct-access-external-data.rs | 10 ---------- .../loongarch/direct-access-external-data.rs | 10 ---------- tests/run-make/linkage-attr-on-static/bar.rs | 2 +- tests/run-make/linkage-attr-on-static/rmake.rs | 2 ++ .../run-make/naked-symbol-visibility/a_rust_dylib.rs | 11 ----------- tests/run-make/naked-symbol-visibility/rmake.rs | 3 --- tests/ui/asm/naked-functions/naked-functions.rs | 2 +- tests/ui/linkage-attr/auxiliary/def_external.rs | 5 ----- tests/ui/linkage-attr/auxiliary/def_weak.rs | 5 +++++ .../linkage-attr-does-not-panic-llvm-issue-33992.rs | 3 --- tests/ui/linkage-attr/linkage-import.rs | 8 +++++--- tests/ui/linkage-attr/linkage3.stderr | 2 +- tests/ui/linkage-attr/linkage4.rs | 2 +- tests/ui/linkage-attr/linkage4.stderr | 2 +- tests/ui/lint/inline-exported.rs | 4 ++-- 18 files changed, 19 insertions(+), 61 deletions(-) delete mode 100644 tests/ui/linkage-attr/auxiliary/def_external.rs create mode 100644 tests/ui/linkage-attr/auxiliary/def_weak.rs diff --git a/compiler/rustc_attr_parsing/src/attributes/link_attrs.rs b/compiler/rustc_attr_parsing/src/attributes/link_attrs.rs index bb5160db76ee8..4796556819b4a 100644 --- a/compiler/rustc_attr_parsing/src/attributes/link_attrs.rs +++ b/compiler/rustc_attr_parsing/src/attributes/link_attrs.rs @@ -687,7 +687,6 @@ impl SingleAttributeParser for LinkageParser { "available_externally", "common", "extern_weak", - "external", "linkonce", "linkonce_odr", "weak", @@ -712,7 +711,6 @@ impl SingleAttributeParser for LinkageParser { sym::available_externally => Linkage::AvailableExternally, sym::common => Linkage::Common, sym::extern_weak => Linkage::ExternalWeak, - sym::external => Linkage::External, sym::linkonce => Linkage::LinkOnceAny, sym::linkonce_odr => Linkage::LinkOnceODR, sym::weak => Linkage::WeakAny, @@ -725,7 +723,6 @@ impl SingleAttributeParser for LinkageParser { sym::available_externally, sym::common, sym::extern_weak, - sym::external, sym::linkonce, sym::linkonce_odr, sym::weak, diff --git a/compiler/rustc_codegen_gcc/tests/c/import_linkage.c b/compiler/rustc_codegen_gcc/tests/c/import_linkage.c index d725b86c6c14b..48ab31d4c6ee2 100644 --- a/compiler/rustc_codegen_gcc/tests/c/import_linkage.c +++ b/compiler/rustc_codegen_gcc/tests/c/import_linkage.c @@ -6,7 +6,6 @@ #include -int32_t external_value = 1; int32_t available_externally_value = 2; int32_t linkonce_value = 3; int32_t linkonce_odr_value = 4; diff --git a/compiler/rustc_codegen_gcc/tests/run/import_linkage.rs b/compiler/rustc_codegen_gcc/tests/run/import_linkage.rs index 33c9ef57e9599..ed9123a433973 100644 --- a/compiler/rustc_codegen_gcc/tests/run/import_linkage.rs +++ b/compiler/rustc_codegen_gcc/tests/run/import_linkage.rs @@ -19,8 +19,6 @@ extern crate mini_core; use mini_core::*; extern "C" { - #[linkage = "external"] - static external_value: *const i32; #[linkage = "available_externally"] static available_externally_value: *const i32; #[linkage = "linkonce"] @@ -44,9 +42,6 @@ extern "C" { #[no_mangle] extern "C" fn main(_argc: i32, _argv: *const *const u8) -> i32 { unsafe { - if *external_value != 1 { - return 1; - } if *available_externally_value != 2 { return 2; } diff --git a/tests/codegen-llvm/direct-access-external-data.rs b/tests/codegen-llvm/direct-access-external-data.rs index a151bb6012e1e..43ee290d3a058 100644 --- a/tests/codegen-llvm/direct-access-external-data.rs +++ b/tests/codegen-llvm/direct-access-external-data.rs @@ -22,15 +22,6 @@ unsafe extern "C" { // When "linkage" is used, we generate an indirection global. // Check dso_local is still applied to the actual global. - // CHECK: @EXTERNAL = external - // DEFAULT-SAME: dso_local - // PIE-NOT: dso_local - // DIRECT-SAME: dso_local - // INDIRECT-NOT: dso_local - // CHECK-SAME: global i8 - #[linkage = "external"] - safe static EXTERNAL: *const u32; - // CHECK: @WEAK = extern_weak // DEFAULT-SAME: dso_local // PIE-NOT: dso_local @@ -44,6 +35,5 @@ unsafe extern "C" { #[no_mangle] pub fn refer() { core::hint::black_box(VAR); - core::hint::black_box(EXTERNAL); core::hint::black_box(WEAK); } diff --git a/tests/codegen-llvm/loongarch/direct-access-external-data.rs b/tests/codegen-llvm/loongarch/direct-access-external-data.rs index de495d7fe9a72..e5b7124a722e2 100644 --- a/tests/codegen-llvm/loongarch/direct-access-external-data.rs +++ b/tests/codegen-llvm/loongarch/direct-access-external-data.rs @@ -20,15 +20,6 @@ unsafe extern "C" { // When "linkage" is used, we generate an indirection global. // Check dso_local is still applied to the actual global. - // CHECK: @EXTERNAL = external - // DEFAULT-NOT: dso_local - // PIE-NOT: dso_local - // DIRECT-SAME: dso_local - // INDIRECT-NOT: dso_local - // CHECK-SAME: global i8 - #[linkage = "external"] - safe static EXTERNAL: *const u32; - // CHECK: @WEAK = extern_weak // DEFAULT-NOT: dso_local // PIE-NOT: dso_local @@ -42,6 +33,5 @@ unsafe extern "C" { #[no_mangle] pub fn refer() { core::hint::black_box(VAR); - core::hint::black_box(EXTERNAL); core::hint::black_box(WEAK); } diff --git a/tests/run-make/linkage-attr-on-static/bar.rs b/tests/run-make/linkage-attr-on-static/bar.rs index 68607cbb65721..cbab76ba6f403 100644 --- a/tests/run-make/linkage-attr-on-static/bar.rs +++ b/tests/run-make/linkage-attr-on-static/bar.rs @@ -1,7 +1,7 @@ #![feature(linkage)] #[no_mangle] -#[linkage = "external"] +#[linkage = "weak"] static BAZ: i32 = 21; #[link(name = "foo", kind = "static")] diff --git a/tests/run-make/linkage-attr-on-static/rmake.rs b/tests/run-make/linkage-attr-on-static/rmake.rs index cd85542e9587d..f1cf80a2b0c5a 100644 --- a/tests/run-make/linkage-attr-on-static/rmake.rs +++ b/tests/run-make/linkage-attr-on-static/rmake.rs @@ -5,6 +5,8 @@ //@ ignore-cross-compile // Reason: the compiled binary is executed +//@ ignore-i686-pc-windows-gnu weak symbols broken with MinGW linker +//@ ignore-x86_64-pc-windows-gnu weak symbols broken with MinGW linker use run_make_support::{build_native_static_lib, run, rustc}; diff --git a/tests/run-make/naked-symbol-visibility/a_rust_dylib.rs b/tests/run-make/naked-symbol-visibility/a_rust_dylib.rs index ce787f83ade6d..8d699a665ae24 100644 --- a/tests/run-make/naked-symbol-visibility/a_rust_dylib.rs +++ b/tests/run-make/naked-symbol-visibility/a_rust_dylib.rs @@ -51,17 +51,6 @@ pub extern "C" fn public_naked_generic() -> u32 { naked_asm!("mov rax, {}", "ret", const T::COUNT) } -#[linkage = "external"] -extern "C" fn vanilla_external_linkage() -> u32 { - 42 -} - -#[unsafe(naked)] -#[linkage = "external"] -extern "C" fn naked_external_linkage() -> u32 { - naked_asm!("mov rax, 42", "ret") -} - #[cfg(not(windows))] #[linkage = "weak"] extern "C" fn vanilla_weak_linkage() -> u32 { diff --git a/tests/run-make/naked-symbol-visibility/rmake.rs b/tests/run-make/naked-symbol-visibility/rmake.rs index 69317c872f895..1acbe11dc4ae4 100644 --- a/tests/run-make/naked-symbol-visibility/rmake.rs +++ b/tests/run-make/naked-symbol-visibility/rmake.rs @@ -29,9 +29,6 @@ fn main() { // -Zshare-generics. global_function(&rdylib, "public_naked_generic"); - global_function(&rdylib, "vanilla_external_linkage"); - global_function(&rdylib, "naked_external_linkage"); - // FIXME: make this work on windows (gnu and msvc). See the PR // https://github.com/rust-lang/rust/pull/128362 for some approaches // that don't work diff --git a/tests/ui/asm/naked-functions/naked-functions.rs b/tests/ui/asm/naked-functions/naked-functions.rs index d994b1151514a..e7da65a169074 100644 --- a/tests/ui/asm/naked-functions/naked-functions.rs +++ b/tests/ui/asm/naked-functions/naked-functions.rs @@ -224,7 +224,7 @@ pub extern "C" fn compatible_doc_attributes() { naked_asm!("", options(raw)); } -#[linkage = "external"] +#[linkage = "weak"] #[unsafe(naked)] pub extern "C" fn compatible_linkage() { naked_asm!("", options(raw)); diff --git a/tests/ui/linkage-attr/auxiliary/def_external.rs b/tests/ui/linkage-attr/auxiliary/def_external.rs deleted file mode 100644 index 2300930e513af..0000000000000 --- a/tests/ui/linkage-attr/auxiliary/def_external.rs +++ /dev/null @@ -1,5 +0,0 @@ -#![feature(linkage)] -#![crate_type = "lib"] - -#[linkage="external"] -pub static EXTERN: u32 = 0; diff --git a/tests/ui/linkage-attr/auxiliary/def_weak.rs b/tests/ui/linkage-attr/auxiliary/def_weak.rs new file mode 100644 index 0000000000000..a8940f73c5536 --- /dev/null +++ b/tests/ui/linkage-attr/auxiliary/def_weak.rs @@ -0,0 +1,5 @@ +#![feature(linkage)] +#![crate_type = "lib"] + +#[linkage = "weak"] +pub static WEAK: u32 = 0; diff --git a/tests/ui/linkage-attr/linkage-attr-does-not-panic-llvm-issue-33992.rs b/tests/ui/linkage-attr/linkage-attr-does-not-panic-llvm-issue-33992.rs index d80236cae7c6d..a7209b71c7809 100644 --- a/tests/ui/linkage-attr/linkage-attr-does-not-panic-llvm-issue-33992.rs +++ b/tests/ui/linkage-attr/linkage-attr-does-not-panic-llvm-issue-33992.rs @@ -4,9 +4,6 @@ #![feature(linkage)] -#[linkage = "external"] -pub static TEST2: bool = true; - #[cfg(not(target_env = "msvc"))] #[linkage = "linkonce"] pub static TEST4: bool = true; diff --git a/tests/ui/linkage-attr/linkage-import.rs b/tests/ui/linkage-attr/linkage-import.rs index 838d1fc29a238..427a487ef1905 100644 --- a/tests/ui/linkage-attr/linkage-import.rs +++ b/tests/ui/linkage-attr/linkage-import.rs @@ -1,8 +1,10 @@ //@ build-pass -//@ aux-build:def_external.rs +//@ aux-build:def_weak.rs +//@ ignore-i686-pc-windows-gnu weak symbols broken with MinGW linker +//@ ignore-x86_64-pc-windows-gnu weak symbols broken with MinGW linker -extern crate def_external as dep; +extern crate def_weak as dep; fn main() { - println!("{:p}", &dep::EXTERN); + println!("{:p}", &dep::WEAK); } diff --git a/tests/ui/linkage-attr/linkage3.stderr b/tests/ui/linkage-attr/linkage3.stderr index 45555eef3d120..4a85c39009517 100644 --- a/tests/ui/linkage-attr/linkage3.stderr +++ b/tests/ui/linkage-attr/linkage3.stderr @@ -4,7 +4,7 @@ error[E0539]: malformed `linkage` attribute input LL | #[linkage = "foo"] | ^^^^^^^^^^----- | | - | valid arguments are `available_externally`, `common`, `extern_weak`, `external`, `linkonce`, `linkonce_odr`, `weak` or `weak_odr` + | valid arguments are `available_externally`, `common`, `extern_weak`, `linkonce`, `linkonce_odr`, `weak` or `weak_odr` error: aborting due to 1 previous error diff --git a/tests/ui/linkage-attr/linkage4.rs b/tests/ui/linkage-attr/linkage4.rs index 3b935f9723dc1..25df81189d8f5 100644 --- a/tests/ui/linkage-attr/linkage4.rs +++ b/tests/ui/linkage-attr/linkage4.rs @@ -1,4 +1,4 @@ -#[linkage = "external"] +#[linkage = "weak"] static foo: isize = 0; //~^^ ERROR: the `linkage` attribute is experimental and not portable diff --git a/tests/ui/linkage-attr/linkage4.stderr b/tests/ui/linkage-attr/linkage4.stderr index a5970d100581a..2f04ceee5199d 100644 --- a/tests/ui/linkage-attr/linkage4.stderr +++ b/tests/ui/linkage-attr/linkage4.stderr @@ -1,7 +1,7 @@ error[E0658]: the `linkage` attribute is experimental and not portable across platforms --> $DIR/linkage4.rs:1:3 | -LL | #[linkage = "external"] +LL | #[linkage = "weak"] | ^^^^^^^ | = note: see issue #29603 for more information diff --git a/tests/ui/lint/inline-exported.rs b/tests/ui/lint/inline-exported.rs index bacbd128cd632..25ca5f0633079 100644 --- a/tests/ui/lint/inline-exported.rs +++ b/tests/ui/lint/inline-exported.rs @@ -17,8 +17,8 @@ fn export_name() {} #[inline] //~^ ERROR: `#[inline]` is ignored on externally exported functions -#[linkage = "external"] -fn external_linkage() {} +#[linkage = "weak"] +fn weak_linkage() {} #[inline] fn normal() {} From d731edabc063472a52ae5fea422aca122989e921 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Sun, 27 Sep 2026 16:20:51 +0200 Subject: [PATCH 07/17] Remove #[linkage = "common"] A common definition is like a weak definition except that it must be a zero-initialized static and when merging two common symbols with the same name, the size and alignment are set to the higher of both symbols. This is used for tentative definitions in C and doesn't have any reason to exist outside of that. This behavior doesn't work across dylibs and common symbols have inconsistent behavior across linkers [1]. It is also fragile to rely on getting the largest size of all common symbol definitions as a (possibly smaller) global definition can override it. Link: https://maskray.me/blog/all-about-common-symbols [1] --- compiler/rustc_attr_ir/src/data_structures.rs | 1 - .../rustc_attr_ir/src/encode_cross_crate.rs | 1 - .../src/attributes/link_attrs.rs | 3 --- compiler/rustc_codegen_gcc/src/base.rs | 19 ++++------------- compiler/rustc_codegen_gcc/src/consts.rs | 21 ++----------------- .../tests/c/import_linkage.c | 1 - .../tests/c/static_linkage.c | 3 --- .../tests/run/import_linkage.rs | 5 ----- .../tests/run/static_linkage.rs | 5 ----- .../tests/run/weak_function_linkage.rs | 3 --- compiler/rustc_codegen_llvm/src/base.rs | 1 - .../rustc_codegen_ssa/src/mir/naked_asm.rs | 1 - .../rustc_monomorphize/src/partitioning.rs | 1 - compiler/rustc_span/src/symbol.rs | 1 - .../codegen_attr_on_required_trait_method.rs | 2 +- ...degen_attr_on_required_trait_method.stderr | 2 +- .../common-linkage-non-zero-init.rs | 17 --------------- .../common-linkage-non-zero-init.stderr | 3 --- ...ge-attr-does-not-panic-llvm-issue-33992.rs | 2 +- tests/ui/linkage-attr/linkage3.stderr | 2 +- 20 files changed, 10 insertions(+), 84 deletions(-) delete mode 100644 tests/ui/linkage-attr/common-linkage-non-zero-init.rs delete mode 100644 tests/ui/linkage-attr/common-linkage-non-zero-init.stderr diff --git a/compiler/rustc_attr_ir/src/data_structures.rs b/compiler/rustc_attr_ir/src/data_structures.rs index 712ed41ae7759..55c0bedb9c39c 100644 --- a/compiler/rustc_attr_ir/src/data_structures.rs +++ b/compiler/rustc_attr_ir/src/data_structures.rs @@ -283,7 +283,6 @@ impl StrippedCfgItem { #[derive(StableHash, PrintAttribute)] pub enum Linkage { AvailableExternally, - Common, ExternalWeak, External, Internal, diff --git a/compiler/rustc_attr_ir/src/encode_cross_crate.rs b/compiler/rustc_attr_ir/src/encode_cross_crate.rs index 66fbbc1e3cbf7..b6733e8c1db54 100644 --- a/compiler/rustc_attr_ir/src/encode_cross_crate.rs +++ b/compiler/rustc_attr_ir/src/encode_cross_crate.rs @@ -265,7 +265,6 @@ impl AttributeKind { Linkage(linkage, _) => match *linkage { crate::Linkage::Internal => false, crate::Linkage::AvailableExternally - | crate::Linkage::Common | crate::Linkage::External | crate::Linkage::ExternalWeak | crate::Linkage::LinkOnceAny diff --git a/compiler/rustc_attr_parsing/src/attributes/link_attrs.rs b/compiler/rustc_attr_parsing/src/attributes/link_attrs.rs index 4796556819b4a..ed911a63eb7fe 100644 --- a/compiler/rustc_attr_parsing/src/attributes/link_attrs.rs +++ b/compiler/rustc_attr_parsing/src/attributes/link_attrs.rs @@ -685,7 +685,6 @@ impl SingleAttributeParser for LinkageParser { ]); const TEMPLATE: AttributeTemplate = template!(NameValueStr: [ "available_externally", - "common", "extern_weak", "linkonce", "linkonce_odr", @@ -709,7 +708,6 @@ impl SingleAttributeParser for LinkageParser { // and don't have to be, LLVM treats them as no-ops. let linkage = match value { sym::available_externally => Linkage::AvailableExternally, - sym::common => Linkage::Common, sym::extern_weak => Linkage::ExternalWeak, sym::linkonce => Linkage::LinkOnceAny, sym::linkonce_odr => Linkage::LinkOnceODR, @@ -721,7 +719,6 @@ impl SingleAttributeParser for LinkageParser { name_value.value_span, &[ sym::available_externally, - sym::common, sym::extern_weak, sym::linkonce, sym::linkonce_odr, diff --git a/compiler/rustc_codegen_gcc/src/base.rs b/compiler/rustc_codegen_gcc/src/base.rs index 07214096b3e49..acf5c75e4d8cd 100644 --- a/compiler/rustc_codegen_gcc/src/base.rs +++ b/compiler/rustc_codegen_gcc/src/base.rs @@ -55,19 +55,14 @@ pub fn global_linkage_to_gcc(linkage: Linkage) -> GlobalKind { | Linkage::LinkOnceODR | Linkage::WeakAny | Linkage::WeakODR - | Linkage::ExternalWeak - | Linkage::Common => GlobalKind::Exported, + | Linkage::ExternalWeak => GlobalKind::Exported, } } /// The attribute a global *definition* needs on top of its [`GlobalKind`] to get this linkage. #[cfg(feature = "master")] pub fn global_linkage_attribute<'gcc>(linkage: Linkage) -> Option> { - match linkage { - Linkage::Common => Some(VarAttribute::Common), - _ if linkage_needs_weak_attribute(linkage) => Some(VarAttribute::Weak), - _ => None, - } + if linkage_needs_weak_attribute(linkage) { Some(VarAttribute::Weak) } else { None } } /// The type of a function *definition* with an explicit `#[linkage]`. @@ -85,17 +80,12 @@ pub fn linkage_to_gcc(linkage: Linkage) -> FunctionType { | Linkage::LinkOnceODR | Linkage::WeakAny | Linkage::WeakODR - | Linkage::ExternalWeak - | Linkage::Common => FunctionType::Exported, + | Linkage::ExternalWeak => FunctionType::Exported, } } /// Whether a definition with this linkage must carry the `weak` attribute, so that a strong /// definition in another object file wins over it instead of clashing with it. -/// -/// `common` is in here for functions only: GCC honours that attribute on a variable, but drops it -/// on a function, so a common function falls back to weak. Globals go through -/// `global_linkage_attribute` instead. #[cfg(feature = "master")] pub fn linkage_needs_weak_attribute(linkage: Linkage) -> bool { match linkage { @@ -103,8 +93,7 @@ pub fn linkage_needs_weak_attribute(linkage: Linkage) -> bool { | Linkage::LinkOnceODR | Linkage::WeakAny | Linkage::WeakODR - | Linkage::ExternalWeak - | Linkage::Common => true, + | Linkage::ExternalWeak => true, Linkage::External | Linkage::AvailableExternally | Linkage::Internal => false, } } diff --git a/compiler/rustc_codegen_gcc/src/consts.rs b/compiler/rustc_codegen_gcc/src/consts.rs index c58ab6d2a9bef..0784064547e0f 100644 --- a/compiler/rustc_codegen_gcc/src/consts.rs +++ b/compiler/rustc_codegen_gcc/src/consts.rs @@ -13,8 +13,7 @@ use rustc_hir::def_id::LOCAL_CRATE; use rustc_log::tracing::trace; use rustc_middle::middle::codegen_fn_attrs::{CodegenFnAttrFlags, CodegenFnAttrs}; use rustc_middle::mir::interpret::{ - self, Allocation, ConstAllocation, CtfeProvenance, ErrorHandled, Scalar as InterpScalar, - read_target_uint, + self, ConstAllocation, CtfeProvenance, ErrorHandled, Scalar as InterpScalar, read_target_uint, }; use rustc_middle::mono::MonoItem; use rustc_middle::ty::layout::LayoutOf; @@ -113,12 +112,7 @@ impl<'gcc, 'tcx> StaticCodegenMethods for CodegenCx<'gcc, 'tcx> { // NOTE: Alignment from attributes has already been applied to the allocation. set_global_alignment(self, global, alloc.align); - // A common symbol is storage the linker allocates and zero-fills, so giving the definition - // an initializer — even an all-zero one — takes it back out of `.comm`. A non-zero one is - // kept: the symbol is then an ordinary definition, which is what GCC does with it too. - if attrs.linkage != Some(Linkage::Common) || !is_zero_initializer(alloc) { - global.global_set_initializer_rvalue(value); - } + global.global_set_initializer_rvalue(value); // As an optimization, all shared statics which do not have interior // mutability are placed into read-only memory. @@ -458,17 +452,6 @@ pub(crate) fn const_alloc_to_gcc_uncached<'gcc>( cx.const_struct(&llvals, true) } -/// Whether this allocation is all zeroes, and so needs no initializer to be spelled out. -fn is_zero_initializer(alloc: &Allocation) -> bool { - alloc.provenance().ptrs().is_empty() - // This `inspect` is okay: it is within the bounds of the allocation, there is no provenance - // to misread, and it does not affect interpreter execution. - && alloc - .inspect_with_uninit_and_ptr_outside_interpreter(0..alloc.size().bytes_usize()) - .iter() - .all(|&byte| byte == 0) -} - fn codegen_static_initializer<'gcc, 'tcx>( cx: &CodegenCx<'gcc, 'tcx>, def_id: DefId, diff --git a/compiler/rustc_codegen_gcc/tests/c/import_linkage.c b/compiler/rustc_codegen_gcc/tests/c/import_linkage.c index 48ab31d4c6ee2..227fa1c848ddf 100644 --- a/compiler/rustc_codegen_gcc/tests/c/import_linkage.c +++ b/compiler/rustc_codegen_gcc/tests/c/import_linkage.c @@ -11,5 +11,4 @@ int32_t linkonce_value = 3; int32_t linkonce_odr_value = 4; int32_t weak_value = 5; int32_t weak_odr_value = 6; -int32_t common_value = 7; int32_t extern_weak_value = 8; diff --git a/compiler/rustc_codegen_gcc/tests/c/static_linkage.c b/compiler/rustc_codegen_gcc/tests/c/static_linkage.c index 66c77bd418b94..00360d8633e68 100644 --- a/compiler/rustc_codegen_gcc/tests/c/static_linkage.c +++ b/compiler/rustc_codegen_gcc/tests/c/static_linkage.c @@ -8,7 +8,6 @@ int32_t weak_static = 1; int32_t weak_odr_static = 2; int32_t linkonce_static = 3; int32_t linkonce_odr_static = 4; -int32_t common_static = 5; /* `available_externally` promises the real definition lives elsewhere: a backend may read this one * or emit an equivalent copy of the Rust initializer, so the two have to hold the same value. */ @@ -25,7 +24,5 @@ int32_t c_read_all(void) return 13; if (linkonce_odr_static != 4) return 14; - if (common_static != 5) - return 15; return 0; } diff --git a/compiler/rustc_codegen_gcc/tests/run/import_linkage.rs b/compiler/rustc_codegen_gcc/tests/run/import_linkage.rs index ed9123a433973..58008ecbc9746 100644 --- a/compiler/rustc_codegen_gcc/tests/run/import_linkage.rs +++ b/compiler/rustc_codegen_gcc/tests/run/import_linkage.rs @@ -29,8 +29,6 @@ extern "C" { static weak_value: *const i32; #[linkage = "weak_odr"] static weak_odr_value: *const i32; - #[linkage = "common"] - static common_value: *const i32; #[linkage = "extern_weak"] static extern_weak_value: *const i32; @@ -57,9 +55,6 @@ extern "C" fn main(_argc: i32, _argv: *const *const u8) -> i32 { if *weak_odr_value != 6 { return 6; } - if *common_value != 7 { - return 7; - } if *extern_weak_value != 8 { return 8; } diff --git a/compiler/rustc_codegen_gcc/tests/run/static_linkage.rs b/compiler/rustc_codegen_gcc/tests/run/static_linkage.rs index ba9e1fe4d2645..3c9303fa8cf16 100644 --- a/compiler/rustc_codegen_gcc/tests/run/static_linkage.rs +++ b/compiler/rustc_codegen_gcc/tests/run/static_linkage.rs @@ -33,11 +33,6 @@ pub static linkonce_static: i32 = 0; #[no_mangle] pub static linkonce_odr_static: i32 = 0; -// `common` is only valid on a mutable global: LLVM rejects a constant one. -#[linkage = "common"] -#[no_mangle] -pub static mut common_static: i32 = 0; - // Not overridden by the C side: the definition here is the one that survives. #[linkage = "weak"] #[no_mangle] diff --git a/compiler/rustc_codegen_gcc/tests/run/weak_function_linkage.rs b/compiler/rustc_codegen_gcc/tests/run/weak_function_linkage.rs index 677f01353401a..406b85df10b02 100644 --- a/compiler/rustc_codegen_gcc/tests/run/weak_function_linkage.rs +++ b/compiler/rustc_codegen_gcc/tests/run/weak_function_linkage.rs @@ -41,9 +41,6 @@ extern "C" fn linkonce_odr_function() -> i32 { 4 } -// `#[linkage = "common"]` is absent on purpose: a common symbol is `SHN_COMMON`, which the object -// format only allows for objects, so no backend can give a function that linkage. - // Not overridden by the C side: the definition here is the one that runs. #[linkage = "weak"] #[no_mangle] diff --git a/compiler/rustc_codegen_llvm/src/base.rs b/compiler/rustc_codegen_llvm/src/base.rs index cf278694399f3..77cb37edec770 100644 --- a/compiler/rustc_codegen_llvm/src/base.rs +++ b/compiler/rustc_codegen_llvm/src/base.rs @@ -237,7 +237,6 @@ pub(crate) fn linkage_to_llvm(linkage: Linkage) -> llvm::Linkage { Linkage::WeakODR => llvm::Linkage::WeakODRLinkage, Linkage::Internal => llvm::Linkage::InternalLinkage, Linkage::ExternalWeak => llvm::Linkage::ExternalWeakLinkage, - Linkage::Common => llvm::Linkage::CommonLinkage, } } diff --git a/compiler/rustc_codegen_ssa/src/mir/naked_asm.rs b/compiler/rustc_codegen_ssa/src/mir/naked_asm.rs index 2fa6f3fc06550..5433b9da6f2b6 100644 --- a/compiler/rustc_codegen_ssa/src/mir/naked_asm.rs +++ b/compiler/rustc_codegen_ssa/src/mir/naked_asm.rs @@ -228,7 +228,6 @@ fn prefix_and_suffix<'tcx>( // LTO can fail when internal linkage is used. emit_fatal("naked functions may not have internal linkage") } - Linkage::Common => emit_fatal("Functions may not have common linkage"), Linkage::AvailableExternally => { // this would make the function equal an extern definition emit_fatal("Functions may not have available_externally linkage") diff --git a/compiler/rustc_monomorphize/src/partitioning.rs b/compiler/rustc_monomorphize/src/partitioning.rs index 43ce9634cc203..16df895b0f728 100644 --- a/compiler/rustc_monomorphize/src/partitioning.rs +++ b/compiler/rustc_monomorphize/src/partitioning.rs @@ -1252,7 +1252,6 @@ fn collect_and_partition_mono_items(tcx: TyCtxt<'_>, (): ()) -> MonoItemPartitio Linkage::WeakODR => "WeakODR", Linkage::Internal => "Internal", Linkage::ExternalWeak => "ExternalWeak", - Linkage::Common => "Common", }; output.push('['); diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index a7dbf7dc5e035..a003f20e3512d 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -671,7 +671,6 @@ symbols! { cold_path, collapse_debuginfo, column, - common, compare_bytes, compare_exchange, compare_exchange_weak, diff --git a/tests/ui/attributes/codegen_attr_on_required_trait_method.rs b/tests/ui/attributes/codegen_attr_on_required_trait_method.rs index 737ebf7f2b144..2ea4e0b5a395c 100644 --- a/tests/ui/attributes/codegen_attr_on_required_trait_method.rs +++ b/tests/ui/attributes/codegen_attr_on_required_trait_method.rs @@ -11,7 +11,7 @@ trait Test { //~^ ERROR cannot be used on required trait methods [unused_attributes] //~| WARN previously accepted fn method2(&self); - #[linkage = "common"] + #[linkage = "weak"] //~^ ERROR `linkage` attribute cannot be used on required trait methods fn method3(&self); #[track_caller] diff --git a/tests/ui/attributes/codegen_attr_on_required_trait_method.stderr b/tests/ui/attributes/codegen_attr_on_required_trait_method.stderr index b5452ba2882c0..729231956337d 100644 --- a/tests/ui/attributes/codegen_attr_on_required_trait_method.stderr +++ b/tests/ui/attributes/codegen_attr_on_required_trait_method.stderr @@ -1,7 +1,7 @@ error: the `linkage` attribute cannot be used on required trait methods --> $DIR/codegen_attr_on_required_trait_method.rs:14:7 | -LL | #[linkage = "common"] +LL | #[linkage = "weak"] | ^^^^^^^ | = help: the `linkage` attribute can be applied to foreign functions, foreign statics, functions with a body, and statics diff --git a/tests/ui/linkage-attr/common-linkage-non-zero-init.rs b/tests/ui/linkage-attr/common-linkage-non-zero-init.rs deleted file mode 100644 index 512616251c2f7..0000000000000 --- a/tests/ui/linkage-attr/common-linkage-non-zero-init.rs +++ /dev/null @@ -1,17 +0,0 @@ -//@ build-fail -//@ failure-status: 101 -//@ known-bug: #109681 -//@ ignore-wasm32 this appears to SIGABRT on wasm, not fail cleanly -//@ compile-flags: -Z verify-llvm-ir -//@ ignore-backends: gcc - -// This test verifies that we continue to hit the LLVM error for common linkage with non-zero -// initializers, since it generates invalid LLVM IR. -// Linkages are internal features marked as perma-unstable, so we don't need to fix the issue -// for now. -#![crate_type="lib"] -#![feature(linkage)] - -#[linkage = "common"] -#[no_mangle] -pub static TEST: bool = true; diff --git a/tests/ui/linkage-attr/common-linkage-non-zero-init.stderr b/tests/ui/linkage-attr/common-linkage-non-zero-init.stderr deleted file mode 100644 index 93015bb2bac12..0000000000000 --- a/tests/ui/linkage-attr/common-linkage-non-zero-init.stderr +++ /dev/null @@ -1,3 +0,0 @@ -'common' global must have a zero initializer! -ptr @TEST -rustc-LLVM ERROR: Broken module found, compilation aborted! diff --git a/tests/ui/linkage-attr/linkage-attr-does-not-panic-llvm-issue-33992.rs b/tests/ui/linkage-attr/linkage-attr-does-not-panic-llvm-issue-33992.rs index a7209b71c7809..e1ad2405b1df8 100644 --- a/tests/ui/linkage-attr/linkage-attr-does-not-panic-llvm-issue-33992.rs +++ b/tests/ui/linkage-attr/linkage-attr-does-not-panic-llvm-issue-33992.rs @@ -1,6 +1,6 @@ //@ run-pass //@ ignore-apple -//@ ignore-wasm32 common linkage not implemented right now +//@ ignore-wasm32 linkonce linkage not working right now #![feature(linkage)] diff --git a/tests/ui/linkage-attr/linkage3.stderr b/tests/ui/linkage-attr/linkage3.stderr index 4a85c39009517..616f80df09c8b 100644 --- a/tests/ui/linkage-attr/linkage3.stderr +++ b/tests/ui/linkage-attr/linkage3.stderr @@ -4,7 +4,7 @@ error[E0539]: malformed `linkage` attribute input LL | #[linkage = "foo"] | ^^^^^^^^^^----- | | - | valid arguments are `available_externally`, `common`, `extern_weak`, `linkonce`, `linkonce_odr`, `weak` or `weak_odr` + | valid arguments are `available_externally`, `extern_weak`, `linkonce`, `linkonce_odr`, `weak` or `weak_odr` error: aborting due to 1 previous error From 3c67da6404f8269505e8953c7db8fef04a5534ef Mon Sep 17 00:00:00 2001 From: darkraider01 <95766741+darkraider01@users.noreply.github.com> Date: Wed, 30 Sep 2026 21:33:32 +0530 Subject: [PATCH 08/17] Cover macro export on macro_rules definitions --- tests/ui/attributes/macro_export_on_decl_macro.rs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/tests/ui/attributes/macro_export_on_decl_macro.rs b/tests/ui/attributes/macro_export_on_decl_macro.rs index e6fe66ac6c30e..413b844cc1b83 100644 --- a/tests/ui/attributes/macro_export_on_decl_macro.rs +++ b/tests/ui/attributes/macro_export_on_decl_macro.rs @@ -6,4 +6,10 @@ #[macro_export] //~ ERROR `#[macro_export]` has no effect on declarative macro definitions pub macro foo() {} +// `#[macro_export]` on `macro_rules!` is valid and should not emit unused_attributes +#[macro_export] +macro_rules! bar { + () => {}; +} + fn main() {} From 7f542b6a12648df131e1dc9406d3c763a5dc2d0e Mon Sep 17 00:00:00 2001 From: darkraider01 <95766741+darkraider01@users.noreply.github.com> Date: Wed, 30 Sep 2026 21:33:33 +0530 Subject: [PATCH 09/17] Check declarative macro exports during attribute finalization --- .../src/attributes/macro_attrs.rs | 18 +++++++++++++-- .../rustc_attr_parsing/src/diagnostics.rs | 7 ++++++ compiler/rustc_passes/src/check_attr.rs | 23 +------------------ compiler/rustc_passes/src/diagnostics.rs | 7 ------ 4 files changed, 24 insertions(+), 31 deletions(-) diff --git a/compiler/rustc_attr_parsing/src/attributes/macro_attrs.rs b/compiler/rustc_attr_parsing/src/attributes/macro_attrs.rs index dde10225e652f..968a613209248 100644 --- a/compiler/rustc_attr_parsing/src/attributes/macro_attrs.rs +++ b/compiler/rustc_attr_parsing/src/attributes/macro_attrs.rs @@ -1,10 +1,12 @@ +use rustc_ast::ItemKind; use rustc_attr_ir::{MacroUseArgs, find_attr}; use rustc_feature::AttributeStability; -use rustc_lint_defs::builtin::INVALID_MACRO_EXPORT_ARGUMENTS; +use rustc_lint_defs::builtin::{INVALID_MACRO_EXPORT_ARGUMENTS, UNUSED_ATTRIBUTES}; use rustc_structures::CollapseMacroDebuginfo; use super::prelude::*; -use crate::diagnostics::MacroOnlyAttribute; +use crate::context::ShouldEmit; +use crate::diagnostics::{MacroExport, MacroOnlyAttribute}; pub(crate) struct MacroEscapeParser; impl NoArgsAttributeParser for MacroEscapeParser { @@ -175,8 +177,20 @@ impl SingleAttributeParser for MacroExportParser { return None; } }; + Some(AttributeKind::MacroExport { span: cx.attr_span, local_inner_macros }) } + + fn finalize_check(cx: &mut FinalizeCheckContext<'_, '_>, attr_span: Span) { + if cx.target != Target::MacroDef || matches!(cx.should_emit, ShouldEmit::Nothing) { + return; + } + + let item = cx.target_item.unwrap(); + if let ItemKind::MacroDef(_, macro_def) = &item.kind && !macro_def.macro_rules { + cx.emit_lint(UNUSED_ATTRIBUTES, MacroExport::OnDeclMacro, attr_span); + } + } } pub(crate) struct CollapseDebugInfoParser; diff --git a/compiler/rustc_attr_parsing/src/diagnostics.rs b/compiler/rustc_attr_parsing/src/diagnostics.rs index bf630c6bf91a0..879f8da67ae15 100644 --- a/compiler/rustc_attr_parsing/src/diagnostics.rs +++ b/compiler/rustc_attr_parsing/src/diagnostics.rs @@ -2063,3 +2063,10 @@ pub(crate) struct UnusedDuplicate { )] pub warning: bool, } + +#[derive(Diagnostic)] +pub(crate) enum MacroExport { + #[diag("`#[macro_export]` has no effect on declarative macro definitions")] + #[note("declarative macros follow the same exporting rules as regular items")] + OnDeclMacro, +} diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index 3c920d14006bb..d6501ee672bff 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -207,9 +207,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> { } AttributeKind::Naked(..) => self.check_naked(hir_id, target), AttributeKind::MayDangle(attr_span) => self.check_may_dangle(hir_id, *attr_span), - AttributeKind::MacroExport { span, .. } => { - self.check_macro_export(hir_id, *span, target) - } AttributeKind::RustcLegacyConstGenerics { attr_span, fn_indexes } => { self.check_rustc_legacy_const_generics(item, *attr_span, fn_indexes) } @@ -275,6 +272,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { AttributeKind::LinkSection { .. } => (), AttributeKind::LoopMatch(..) => (), AttributeKind::MacroEscape => (), + AttributeKind::MacroExport { .. } => (), AttributeKind::MacroUse { .. } => (), AttributeKind::Marker => (), AttributeKind::MoveSizeLimit { .. } => (), @@ -1281,25 +1279,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> { } } - fn check_macro_export(&self, hir_id: HirId, attr_span: Span, target: Target) { - if target != Target::MacroDef { - return; - } - - // special case when `#[macro_export]` is applied to a macro 2.0 - let (_, macro_definition, _) = self.tcx.hir_node(hir_id).expect_item().expect_macro(); - let is_decl_macro = !macro_definition.macro_rules; - - if is_decl_macro { - self.tcx.emit_node_span_lint( - UNUSED_ATTRIBUTES, - hir_id, - attr_span, - diagnostics::MacroExport::OnDeclMacro, - ); - } - } - fn check_unused_attribute(&self, hir_id: HirId, attr: &Attribute) { // Warn on useless empty attributes. // FIXME(jdonszelmann): this lint should be moved to attribute parsing, see `AcceptContext::warn_empty_attribute` diff --git a/compiler/rustc_passes/src/diagnostics.rs b/compiler/rustc_passes/src/diagnostics.rs index 7c82811f99276..76b00864c35fe 100644 --- a/compiler/rustc_passes/src/diagnostics.rs +++ b/compiler/rustc_passes/src/diagnostics.rs @@ -199,13 +199,6 @@ pub(crate) struct RustcForceInlineCoro { pub span: Span, } -#[derive(Diagnostic)] -pub(crate) enum MacroExport { - #[diag("`#[macro_export]` has no effect on declarative macro definitions")] - #[note("declarative macros follow the same exporting rules as regular items")] - OnDeclMacro, -} - #[derive(Subdiagnostic)] pub(crate) enum UnusedNote { #[note("attribute `{$name}` with an empty list has no effect")] From bf2b89cb1946c20726136606062caf1f79d2214f Mon Sep 17 00:00:00 2001 From: darkraider01 <95766741+darkraider01@users.noreply.github.com> Date: Wed, 30 Sep 2026 21:53:05 +0530 Subject: [PATCH 10/17] Format macro export finalization check --- compiler/rustc_attr_parsing/src/attributes/macro_attrs.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_attr_parsing/src/attributes/macro_attrs.rs b/compiler/rustc_attr_parsing/src/attributes/macro_attrs.rs index 968a613209248..8bca20cda67aa 100644 --- a/compiler/rustc_attr_parsing/src/attributes/macro_attrs.rs +++ b/compiler/rustc_attr_parsing/src/attributes/macro_attrs.rs @@ -187,7 +187,9 @@ impl SingleAttributeParser for MacroExportParser { } let item = cx.target_item.unwrap(); - if let ItemKind::MacroDef(_, macro_def) = &item.kind && !macro_def.macro_rules { + if let ItemKind::MacroDef(_, macro_def) = &item.kind + && !macro_def.macro_rules + { cx.emit_lint(UNUSED_ATTRIBUTES, MacroExport::OnDeclMacro, attr_span); } } From 109c9176424c1b03e00db6ee5a1b6cc2100c061c Mon Sep 17 00:00:00 2001 From: Lucas Sunsi Abreu Date: Thu, 17 Sep 2026 10:55:08 -0300 Subject: [PATCH 11/17] Fix ICE for ambiguous candidates on method probing The ICE was caused because the code assumed the import_ids would always be the same for all candidates, but it's not true. Sometimes the candidate is ambiguous with import_ids to be logged and sometimes the candidate is not ambigous and does not have the ids. Mixing the two (flag = true, without import_ids) ICEs. Co-authored-by: Philip Sampaio --- compiler/rustc_hir_typeck/src/method/probe.rs | 16 ++++++++++------ .../ambiguous-trait-with-mixed-import-paths.rs | 2 ++ ...mbiguous-trait-with-mixed-import-paths.stderr | 16 ++++++++++++++++ 3 files changed, 28 insertions(+), 6 deletions(-) create mode 100644 tests/ui/imports/ambiguous-trait-with-mixed-import-paths.stderr diff --git a/compiler/rustc_hir_typeck/src/method/probe.rs b/compiler/rustc_hir_typeck/src/method/probe.rs index 02b3255e795ac..edfda911a0b98 100644 --- a/compiler/rustc_hir_typeck/src/method/probe.rs +++ b/compiler/rustc_hir_typeck/src/method/probe.rs @@ -2383,18 +2383,22 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { } } - // They are all the same, so if any of them is ambiguous, we report the pick as ambiguous. - let is_ambiguously_imported = probes.iter().any(|(p, _)| match p.kind { - TraitCandidate { is_ambiguously_imported, .. } => is_ambiguously_imported, - _ => false, + // We try and find the ambiguous candidate in order to report the pick as ambiguous. + let ambiguous_candidate = probes.iter().find_map(|(p, _)| match p.kind { + TraitCandidate { is_ambiguously_imported: true, .. } => Some(p), + _ => None, }); + // If there isn't any, then we just use the first probe. + let (is_ambiguously_imported, candidate) = + ambiguous_candidate.map(|c| (true, *c)).unwrap_or_else(|| (false, probes[0].0)); + // FIXME: check the return type here somehow. // If so, just use this trait and call it a day. Some(Pick { - item: probes[0].0.item, + item: candidate.item, kind: TraitPick { is_ambiguously_imported }, - import_ids: probes[0].0.import_ids, + import_ids: candidate.import_ids, autoderefs: 0, autoref_or_ptr_adjustment: None, self_ty, diff --git a/tests/ui/imports/ambiguous-trait-with-mixed-import-paths.rs b/tests/ui/imports/ambiguous-trait-with-mixed-import-paths.rs index acc97a2491f8e..08f57d7feb7a3 100644 --- a/tests/ui/imports/ambiguous-trait-with-mixed-import-paths.rs +++ b/tests/ui/imports/ambiguous-trait-with-mixed-import-paths.rs @@ -21,6 +21,8 @@ impl vis1::Visitor for Impl { fn visit_c(&self) { self.visit_b(); + //~^ WARN: use of ambiguously glob imported trait `Visitor` [ambiguous_glob_imported_traits] + //~| WARN: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! } } diff --git a/tests/ui/imports/ambiguous-trait-with-mixed-import-paths.stderr b/tests/ui/imports/ambiguous-trait-with-mixed-import-paths.stderr new file mode 100644 index 0000000000000..d65f941f03671 --- /dev/null +++ b/tests/ui/imports/ambiguous-trait-with-mixed-import-paths.stderr @@ -0,0 +1,16 @@ +warning: use of ambiguously glob imported trait `Visitor` + --> $DIR/ambiguous-trait-with-mixed-import-paths.rs:23:14 + | +LL | use crate::{vis1::*, vis2::*}; + | ---- `Visitor` imported ambiguously here +... +LL | self.visit_b(); + | ^^^^^^^ + | + = help: import `Visitor` explicitly + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #152822 + = note: `#[warn(ambiguous_glob_imported_traits)]` (part of `#[warn(future_incompatible)]`) on by default + +warning: 1 warning emitted + From 1ea0af2b635db880e64e9c1083d3f89c5d757fb5 Mon Sep 17 00:00:00 2001 From: darkraider01 <95766741+darkraider01@users.noreply.github.com> Date: Thu, 1 Oct 2026 05:02:05 +0530 Subject: [PATCH 12/17] Skip deferred attribute checks when not emitting --- .../src/attributes/macro_attrs.rs | 3 +- compiler/rustc_attr_parsing/src/interface.rs | 34 ++++++++++--------- 2 files changed, 19 insertions(+), 18 deletions(-) diff --git a/compiler/rustc_attr_parsing/src/attributes/macro_attrs.rs b/compiler/rustc_attr_parsing/src/attributes/macro_attrs.rs index 8bca20cda67aa..8bb5e6b7fc270 100644 --- a/compiler/rustc_attr_parsing/src/attributes/macro_attrs.rs +++ b/compiler/rustc_attr_parsing/src/attributes/macro_attrs.rs @@ -5,7 +5,6 @@ use rustc_lint_defs::builtin::{INVALID_MACRO_EXPORT_ARGUMENTS, UNUSED_ATTRIBUTES use rustc_structures::CollapseMacroDebuginfo; use super::prelude::*; -use crate::context::ShouldEmit; use crate::diagnostics::{MacroExport, MacroOnlyAttribute}; pub(crate) struct MacroEscapeParser; @@ -182,7 +181,7 @@ impl SingleAttributeParser for MacroExportParser { } fn finalize_check(cx: &mut FinalizeCheckContext<'_, '_>, attr_span: Span) { - if cx.target != Target::MacroDef || matches!(cx.should_emit, ShouldEmit::Nothing) { + if cx.target != Target::MacroDef { return; } diff --git a/compiler/rustc_attr_parsing/src/interface.rs b/compiler/rustc_attr_parsing/src/interface.rs index df89ffe57b9a0..95412c34be371 100644 --- a/compiler/rustc_attr_parsing/src/interface.rs +++ b/compiler/rustc_attr_parsing/src/interface.rs @@ -510,23 +510,25 @@ impl<'sess> AttributeParser<'sess> { // Now that all attributes have been parsed, run the deferred checks. These can // inspect the fully parsed attributes via `FinalizeCheckContext::parsed_attrs`. - for (check, attr_span) in deferred_checks { - check( - &mut FinalizeCheckContext { - shared: SharedContext { - cx: self, - target_span, - target, - emit_lint: &mut emit_lint, - #[cfg(debug_assertions)] - has_lint_been_emitted: AtomicBool::new(false), + if !matches!(self.should_emit, ShouldEmit::Nothing) { + for (check, attr_span) in deferred_checks { + check( + &mut FinalizeCheckContext { + shared: SharedContext { + cx: self, + target_span, + target, + emit_lint: &mut emit_lint, + #[cfg(debug_assertions)] + has_lint_been_emitted: AtomicBool::new(false), + }, + all_attrs: &attr_paths, + parsed_attrs: &attributes, + target_item, }, - all_attrs: &attr_paths, - parsed_attrs: &attributes, - target_item, - }, - attr_span, - ); + attr_span, + ); + } } if !matches!(self.should_emit, ShouldEmit::Nothing) && target == Target::WherePredicate { From 82366d5fada2e3fcabc7361964e795f5710745c3 Mon Sep 17 00:00:00 2001 From: Mahdi Ali-Raihan Date: Wed, 30 Sep 2026 23:43:12 -0400 Subject: [PATCH 13/17] Provide better doc code example for UnixDatagram::bind_addr and UnixListener::bind_addr --- library/std/src/os/unix/net/datagram.rs | 7 +++---- library/std/src/os/unix/net/listener.rs | 7 +++---- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/library/std/src/os/unix/net/datagram.rs b/library/std/src/os/unix/net/datagram.rs index e03ecd7eed9ea..0543de4b837f4 100644 --- a/library/std/src/os/unix/net/datagram.rs +++ b/library/std/src/os/unix/net/datagram.rs @@ -112,13 +112,12 @@ impl UnixDatagram { /// #[cfg_attr(target_family = "unix", doc = "```no_run")] #[cfg_attr(not(target_family = "unix"), doc = "```ignore (needs unix)")] - /// use std::os::unix::net::{UnixDatagram}; + /// use std::os::unix::net::{SocketAddr, UnixDatagram}; /// /// fn main() -> std::io::Result<()> { - /// let sock1 = UnixDatagram::bind("path/to/socket")?; - /// let addr = sock1.local_addr()?; + /// let addr = SocketAddr::from_pathname("path/to/socket")?; /// - /// let sock2 = match UnixDatagram::bind_addr(&addr) { + /// let sock = match UnixDatagram::bind_addr(&addr) { /// Ok(sock) => sock, /// Err(err) => { /// println!("Couldn't bind: {err:?}"); diff --git a/library/std/src/os/unix/net/listener.rs b/library/std/src/os/unix/net/listener.rs index b7f8d25a85ae5..b51b61fc11cfe 100644 --- a/library/std/src/os/unix/net/listener.rs +++ b/library/std/src/os/unix/net/listener.rs @@ -119,13 +119,12 @@ impl UnixListener { /// #[cfg_attr(target_family = "unix", doc = "```no_run")] #[cfg_attr(not(target_family = "unix"), doc = "```ignore (needs unix)")] - /// use std::os::unix::net::{UnixListener}; + /// use std::os::unix::net::{SocketAddr, UnixListener}; /// /// fn main() -> std::io::Result<()> { - /// let listener1 = UnixListener::bind("path/to/socket")?; - /// let addr = listener1.local_addr()?; + /// let addr = SocketAddr::from_pathname("path/to/socket")?; /// - /// let listener2 = match UnixListener::bind_addr(&addr) { + /// let listener = match UnixListener::bind_addr(&addr) { /// Ok(sock) => sock, /// Err(err) => { /// println!("Couldn't bind: {err:?}"); From 0e70786bbaea859c5304a31daf557b8ab8e4b402 Mon Sep 17 00:00:00 2001 From: Walnut <39544927+Walnut356@users.noreply.github.com> Date: Wed, 30 Sep 2026 23:59:05 -0500 Subject: [PATCH 14/17] ping me for debugger visualizer changes --- triagebot.toml | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/triagebot.toml b/triagebot.toml index 611f7724f5cae..d214fafab04e1 100644 --- a/triagebot.toml +++ b/triagebot.toml @@ -1554,6 +1554,21 @@ cc = ["@mejrs"] message = "Some changes occurred to diagnostic attributes." cc = ["@mejrs"] +[mentions."compiler/rustc_codegen_llvm/src/debuginfo"] +cc = ["@Walnut356"] +[mentions."src/etc/debugger_tester"] +cc = ["@Walnut356"] +[mentions."src/etc/natvis"] +cc = ["@Walnut356"] +[mentions."src/etc/gdb_lookup.py"] +cc = ["@Walnut356"] +[mentions."src/etc/gdb_providers.py"] +cc = ["@Walnut356"] +[mentions."src/etc/lldb_lookup.py"] +cc = ["@Walnut356"] +[mentions."src/etc/lldb_providers.py"] +cc = ["@Walnut356"] + [mentions."RELEASES.md"] message = """ `RELEASES.md` was changed. Upon merging, each section will be automatically synced with its \ From 1dae79f67e60770891da10ed8b9d702a551e3467 Mon Sep 17 00:00:00 2001 From: albab-hasan Date: Thu, 1 Oct 2026 09:57:22 +0600 Subject: [PATCH 15/17] add test for overcapture suggestion inside attribute macro expansion the test records what the compiler emits today: impl_trait_overcapture_suggestion anchors its suggestion on the opaque def span, which for an opaque inside an attribute macro expansion is the attribute itself, not a type position. the suggestion is machine-applicable, so edition migration applies it and produces error: expected item after attributes --- .../auxiliary/overcapture-attr-pm.rs | 7 ++ ...apture-suggestion-in-macro-issue-139567.rs | 36 +++++++ ...re-suggestion-in-macro-issue-139567.stderr | 97 +++++++++++++++++++ 3 files changed, 140 insertions(+) create mode 100644 tests/ui/impl-trait/precise-capturing/auxiliary/overcapture-attr-pm.rs create mode 100644 tests/ui/impl-trait/precise-capturing/overcapture-suggestion-in-macro-issue-139567.rs create mode 100644 tests/ui/impl-trait/precise-capturing/overcapture-suggestion-in-macro-issue-139567.stderr diff --git a/tests/ui/impl-trait/precise-capturing/auxiliary/overcapture-attr-pm.rs b/tests/ui/impl-trait/precise-capturing/auxiliary/overcapture-attr-pm.rs new file mode 100644 index 0000000000000..1c2e196ccc619 --- /dev/null +++ b/tests/ui/impl-trait/precise-capturing/auxiliary/overcapture-attr-pm.rs @@ -0,0 +1,7 @@ +extern crate proc_macro; +use proc_macro::TokenStream; + +#[proc_macro_attribute] +pub fn rpc(_attr: TokenStream, _item: TokenStream) -> TokenStream { + "pub fn generated(x: &u8) -> impl Sized { *x }".parse().unwrap() +} diff --git a/tests/ui/impl-trait/precise-capturing/overcapture-suggestion-in-macro-issue-139567.rs b/tests/ui/impl-trait/precise-capturing/overcapture-suggestion-in-macro-issue-139567.rs new file mode 100644 index 0000000000000..761678281598a --- /dev/null +++ b/tests/ui/impl-trait/precise-capturing/overcapture-suggestion-in-macro-issue-139567.rs @@ -0,0 +1,36 @@ +//@ edition: 2018 +//@ proc-macro: overcapture-attr-pm.rs + +#![allow(unused)] +#![deny(impl_trait_overcaptures)] + +#[overcapture_attr_pm::rpc] +pub fn from_attr_macro() {} +//~^^ ERROR `impl Sized` will capture more lifetimes than possibly intended in edition 2024 +//~| WARN this changes meaning in Rust 2024 + +pub fn plain(x: &u8) -> impl Sized { *x } +//~^ ERROR `impl Sized` will capture more lifetimes than possibly intended in edition 2024 +//~| WARN this changes meaning in Rust 2024 + +macro_rules! mk { + ($ret:ty) => { + pub fn from_macro_rules(x: &u8) -> $ret { *x } + }; +} + +mk!(impl Sized); +//~^ ERROR `impl Sized` will capture more lifetimes than possibly intended in edition 2024 +//~| WARN this changes meaning in Rust 2024 + +macro_rules! mk_body { + () => { + pub fn from_macro_body(x: &u8) -> impl Sized { *x } + //~^ ERROR `impl Sized` will capture more lifetimes than possibly intended in edition 2024 + //~| WARN this changes meaning in Rust 2024 + }; +} + +mk_body!(); + +fn main() {} diff --git a/tests/ui/impl-trait/precise-capturing/overcapture-suggestion-in-macro-issue-139567.stderr b/tests/ui/impl-trait/precise-capturing/overcapture-suggestion-in-macro-issue-139567.stderr new file mode 100644 index 0000000000000..ab6bd9c11733f --- /dev/null +++ b/tests/ui/impl-trait/precise-capturing/overcapture-suggestion-in-macro-issue-139567.stderr @@ -0,0 +1,97 @@ +error: `impl Sized` will capture more lifetimes than possibly intended in edition 2024 + --> $DIR/overcapture-suggestion-in-macro-issue-139567.rs:7:1 + | +LL | #[overcapture_attr_pm::rpc] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +note: specifically, this lifetime is in scope but not mentioned in the type's bounds + --> $DIR/overcapture-suggestion-in-macro-issue-139567.rs:7:1 + | +LL | #[overcapture_attr_pm::rpc] + | ^ + = note: all lifetimes in scope will be captured by `impl Trait`s in edition 2024 + = warning: this changes meaning in Rust 2024 + = note: for more information, see +note: the lint level is defined here + --> $DIR/overcapture-suggestion-in-macro-issue-139567.rs:5:9 + | +LL | #![deny(impl_trait_overcaptures)] + | ^^^^^^^^^^^^^^^^^^^^^^^ + = note: this error originates in the attribute macro `overcapture_attr_pm::rpc` (in Nightly builds, run with -Z macro-backtrace for more info) +help: use the precise capturing `use<...>` syntax to make the captures explicit + | +LL | #[overcapture_attr_pm::rpc] + use<> + | +++++++ + +error: `impl Sized` will capture more lifetimes than possibly intended in edition 2024 + --> $DIR/overcapture-suggestion-in-macro-issue-139567.rs:12:25 + | +LL | pub fn plain(x: &u8) -> impl Sized { *x } + | ^^^^^^^^^^ + | +note: specifically, this lifetime is in scope but not mentioned in the type's bounds + --> $DIR/overcapture-suggestion-in-macro-issue-139567.rs:12:17 + | +LL | pub fn plain(x: &u8) -> impl Sized { *x } + | ^ + = note: all lifetimes in scope will be captured by `impl Trait`s in edition 2024 + = warning: this changes meaning in Rust 2024 + = note: for more information, see +help: use the precise capturing `use<...>` syntax to make the captures explicit + | +LL | pub fn plain(x: &u8) -> impl Sized + use<> { *x } + | +++++++ + +error: `impl Sized` will capture more lifetimes than possibly intended in edition 2024 + --> $DIR/overcapture-suggestion-in-macro-issue-139567.rs:22:5 + | +LL | macro_rules! mk { +... +LL | mk!(impl Sized); + | ^^^^^^^^^^ + | +note: specifically, this lifetime is in scope but not mentioned in the type's bounds + --> $DIR/overcapture-suggestion-in-macro-issue-139567.rs:18:36 + | +LL | pub fn from_macro_rules(x: &u8) -> $ret { *x } + | ^ +... +LL | mk!(impl Sized); + | --------------- in this macro invocation + = note: all lifetimes in scope will be captured by `impl Trait`s in edition 2024 + = warning: this changes meaning in Rust 2024 + = note: for more information, see +help: use the precise capturing `use<...>` syntax to make the captures explicit + | +LL | mk!(impl Sized + use<>); + | +++++++ + +error: `impl Sized` will capture more lifetimes than possibly intended in edition 2024 + --> $DIR/overcapture-suggestion-in-macro-issue-139567.rs:28:43 + | +LL | macro_rules! mk_body { +LL | () => { +LL | pub fn from_macro_body(x: &u8) -> impl Sized { *x } + | ^^^^^^^^^^ +... +LL | mk_body!(); + | ---------- in this macro invocation + | +note: specifically, this lifetime is in scope but not mentioned in the type's bounds + --> $DIR/overcapture-suggestion-in-macro-issue-139567.rs:28:35 + | +LL | pub fn from_macro_body(x: &u8) -> impl Sized { *x } + | ^ +... +LL | mk_body!(); + | ---------- in this macro invocation + = note: all lifetimes in scope will be captured by `impl Trait`s in edition 2024 + = warning: this changes meaning in Rust 2024 + = note: for more information, see +help: use the precise capturing `use<...>` syntax to make the captures explicit + | +LL | pub fn from_macro_body(x: &u8) -> impl Sized + use<> { *x } + | +++++++ + +error: aborting due to 4 previous errors + From 057e810a4e93f4bde88e1cc5cf4ea185d7dd2b92 Mon Sep 17 00:00:00 2001 From: albab-hasan Date: Thu, 1 Oct 2026 09:58:45 +0600 Subject: [PATCH 16/17] do not suggest precise capturing when the opaque span is inside a macro expansion impl_trait_overcapture_suggestion anchored every suggestion on tcx.def_span(opaque_def_id) with no expansion check. for an opaque created inside an attribute macro expansion that span is the attribute, which is not a type position, so applying the machine-applicable suggestion breaks the file the obvious patch of calling can_be_used_for_suggestions() on that span directly suppresses all suggestions including for ordinary code, because ast lowering stamps DesugaringKind::OpaqueTy onto the opaque span at compiler/rustc_ast_lowering/src/lib.rs:1825, making from_expansion() unconditionally true. the fix calls parent_callsite() to peel that single desugaring layer and asks can_be_used_for_suggestions() about the span underneath the guard sits at function entry rather than beside the rpit_span push because the apit rename and the generics-list insertion are anchored on the same span, so one check covers all three fixes https://github.com/rust-lang/rust/issues/139567 --- compiler/rustc_trait_selection/src/diagnostics.rs | 12 +++++++++++- ...ercapture-suggestion-in-macro-issue-139567.stderr | 8 -------- 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/compiler/rustc_trait_selection/src/diagnostics.rs b/compiler/rustc_trait_selection/src/diagnostics.rs index 90f6faaad1dc1..112cbf68f8375 100644 --- a/compiler/rustc_trait_selection/src/diagnostics.rs +++ b/compiler/rustc_trait_selection/src/diagnostics.rs @@ -1935,6 +1935,17 @@ pub fn impl_trait_overcapture_suggestion<'tcx>( fn_def_id: LocalDefId, captured_args: FxIndexSet, ) -> Option { + let rpit_span = tcx.def_span(opaque_def_id); + + // Every suggestion below is anchored on the opaque's span, so bail if that span is not one + // the user can edit. AST lowering marks it with the `impl Trait` desugaring, hence the + // question is about the span it desugared from: for an opaque created inside a macro + // expansion that span is the expansion site, which for an attribute macro is the attribute + // itself, where `+ use<..>` does not even parse. + if rpit_span.parent_callsite().is_some_and(|span| !span.can_be_used_for_suggestions()) { + return None; + } + let generics = tcx.generics_of(fn_def_id); let mut captured_lifetimes = FxIndexSet::default(); @@ -2036,7 +2047,6 @@ pub fn impl_trait_overcapture_suggestion<'tcx>( _ => ("", ""), }; - let rpit_span = tcx.def_span(opaque_def_id); if !lparen.is_empty() { suggs.push((rpit_span.shrink_to_lo(), lparen.to_string())); } diff --git a/tests/ui/impl-trait/precise-capturing/overcapture-suggestion-in-macro-issue-139567.stderr b/tests/ui/impl-trait/precise-capturing/overcapture-suggestion-in-macro-issue-139567.stderr index ab6bd9c11733f..9f70c2f075942 100644 --- a/tests/ui/impl-trait/precise-capturing/overcapture-suggestion-in-macro-issue-139567.stderr +++ b/tests/ui/impl-trait/precise-capturing/overcapture-suggestion-in-macro-issue-139567.stderr @@ -18,10 +18,6 @@ note: the lint level is defined here LL | #![deny(impl_trait_overcaptures)] | ^^^^^^^^^^^^^^^^^^^^^^^ = note: this error originates in the attribute macro `overcapture_attr_pm::rpc` (in Nightly builds, run with -Z macro-backtrace for more info) -help: use the precise capturing `use<...>` syntax to make the captures explicit - | -LL | #[overcapture_attr_pm::rpc] + use<> - | +++++++ error: `impl Sized` will capture more lifetimes than possibly intended in edition 2024 --> $DIR/overcapture-suggestion-in-macro-issue-139567.rs:12:25 @@ -88,10 +84,6 @@ LL | mk_body!(); = note: all lifetimes in scope will be captured by `impl Trait`s in edition 2024 = warning: this changes meaning in Rust 2024 = note: for more information, see -help: use the precise capturing `use<...>` syntax to make the captures explicit - | -LL | pub fn from_macro_body(x: &u8) -> impl Sized + use<> { *x } - | +++++++ error: aborting due to 4 previous errors From 576456671dd90827023a65ac63d44a1d7fda8f98 Mon Sep 17 00:00:00 2001 From: James Barford-Evans Date: Wed, 30 Sep 2026 10:32:18 +0100 Subject: [PATCH 17/17] `const impl PartialEq` for `f16b` --- library/core/src/num/bfloat.rs | 3 ++- tests/ui/float/f16b.rs | 17 ++++++++++++++++- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/library/core/src/num/bfloat.rs b/library/core/src/num/bfloat.rs index 4937dd8448c60..203ededeb2c0a 100644 --- a/library/core/src/num/bfloat.rs +++ b/library/core/src/num/bfloat.rs @@ -133,7 +133,8 @@ impl Default for f16b { } #[unstable(feature = "f16b", issue = "160630")] -impl PartialEq for f16b { +#[rustc_const_unstable(feature = "const_cmp", issue = "143800")] +const impl PartialEq for f16b { #[inline] fn eq(&self, other: &Self) -> bool { widen(*self).eq(&widen(*other)) diff --git a/tests/ui/float/f16b.rs b/tests/ui/float/f16b.rs index ed143c2c2b2fa..0be9f07de5e05 100644 --- a/tests/ui/float/f16b.rs +++ b/tests/ui/float/f16b.rs @@ -8,7 +8,8 @@ //@ compile-flags: --check-cfg=cfg(target_has_reliable_f16b) -Copt-level=3 //@ run-pass -#![feature(f16b, cfg_target_has_reliable_f16b)] +#![feature(f16b, const_trait_impl, cfg_target_has_reliable_f16b)] +#![cfg_attr(target_has_reliable_f16b, feature(const_cmp))] extern crate core; @@ -22,6 +23,20 @@ const ONE: f16b = f16b::from_bits(0x3f80); #[cfg(target_has_reliable_f16b)] const ONE_BITS: u16 = ONE.to_bits(); +#[cfg(target_has_reliable_f16b)] +const _: () = { + let one = f16b::from_bits(0x3f80); + let two = f16b::from_bits(0x4000); + let positive_zero = f16b::from_bits(0x0000); + let negative_zero = f16b::from_bits(0x8000); + let nan = f16b::from_bits(0x7fc0); + + assert!(one == one); + assert!(one != two); + assert!(positive_zero == negative_zero); + assert!(nan != nan); +}; + #[cfg(target_has_reliable_f16b)] fn assert_traits() where