From 2988b2c775a3be17bd8b651a3ca5da3df9ff4ce9 Mon Sep 17 00:00:00 2001 From: Jens Reidel Date: Tue, 10 Jun 2025 18:36:22 +0200 Subject: [PATCH 01/27] tests: Fix duplicated-path-in-error fail with musl musl's dlopen returns a different error than glibc, which contains the name of the file. This would cause the test to fail, since the filename would appear twice in the output (once in the error from rustc, once in the error message from musl). Split the expected test outputs for the different libc implementations. Signed-off-by: Jens Reidel --- src/tools/compiletest/src/directive-list.rs | 1 + ...ath-in-error.stderr => duplicated-path-in-error.gnu.stderr} | 0 tests/ui/codegen/duplicated-path-in-error.musl.stderr | 2 ++ tests/ui/codegen/duplicated-path-in-error.rs | 3 +++ 4 files changed, 6 insertions(+) rename tests/ui/codegen/{duplicated-path-in-error.stderr => duplicated-path-in-error.gnu.stderr} (100%) create mode 100644 tests/ui/codegen/duplicated-path-in-error.musl.stderr diff --git a/src/tools/compiletest/src/directive-list.rs b/src/tools/compiletest/src/directive-list.rs index 1406553c9ea7b..d19a159e31459 100644 --- a/src/tools/compiletest/src/directive-list.rs +++ b/src/tools/compiletest/src/directive-list.rs @@ -205,6 +205,7 @@ const KNOWN_DIRECTIVE_NAMES: &[&str] = &[ "only-mips64", "only-msp430", "only-msvc", + "only-musl", "only-nightly", "only-nvptx64", "only-powerpc", diff --git a/tests/ui/codegen/duplicated-path-in-error.stderr b/tests/ui/codegen/duplicated-path-in-error.gnu.stderr similarity index 100% rename from tests/ui/codegen/duplicated-path-in-error.stderr rename to tests/ui/codegen/duplicated-path-in-error.gnu.stderr diff --git a/tests/ui/codegen/duplicated-path-in-error.musl.stderr b/tests/ui/codegen/duplicated-path-in-error.musl.stderr new file mode 100644 index 0000000000000..2892ebffdde6a --- /dev/null +++ b/tests/ui/codegen/duplicated-path-in-error.musl.stderr @@ -0,0 +1,2 @@ +error: couldn't load codegen backend /non-existing-one.so: Error loading shared library /non-existing-one.so: No such file or directory + diff --git a/tests/ui/codegen/duplicated-path-in-error.rs b/tests/ui/codegen/duplicated-path-in-error.rs index a446395de208f..1852a6301b55f 100644 --- a/tests/ui/codegen/duplicated-path-in-error.rs +++ b/tests/ui/codegen/duplicated-path-in-error.rs @@ -1,5 +1,8 @@ +//@ revisions: musl gnu //@ only-linux //@ compile-flags: -Zcodegen-backend=/non-existing-one.so +//@[gnu] only-gnu +//@[musl] only-musl // This test ensures that the error of the "not found dylib" doesn't duplicate // the path of the dylib. From b2299e20b2c2a25254fb554ccc59a8b60fdc25e0 Mon Sep 17 00:00:00 2001 From: Dillon Amburgey Date: Tue, 8 Jul 2025 06:18:18 -0500 Subject: [PATCH 02/27] fix: correct assertion to check for 'noinline' attribute presence before removal --- compiler/rustc_codegen_llvm/src/back/lto.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_codegen_llvm/src/back/lto.rs b/compiler/rustc_codegen_llvm/src/back/lto.rs index 9c62244f3c9ff..74418adc43c1d 100644 --- a/compiler/rustc_codegen_llvm/src/back/lto.rs +++ b/compiler/rustc_codegen_llvm/src/back/lto.rs @@ -680,7 +680,7 @@ pub(crate) fn run_pass_manager( if attributes::has_string_attr(function, enzyme_marker) { // Sanity check: Ensure 'noinline' is present before replacing it. assert!( - !attributes::has_attr(function, Function, llvm::AttributeKind::NoInline), + attributes::has_attr(function, Function, llvm::AttributeKind::NoInline), "Expected __enzyme function to have 'noinline' before adding 'alwaysinline'" ); From 62f58dbb2d4b9cc0f2a20cb836eb48d869358416 Mon Sep 17 00:00:00 2001 From: Pavel Grigorenko Date: Mon, 23 Jun 2025 23:41:33 +0300 Subject: [PATCH 03/27] Port `#[const_trait]` to the new attribute system --- .../src/attributes.rs | 3 ++ .../src/encode_cross_crate.rs | 1 + .../src/attributes/traits.rs | 13 +++++- compiler/rustc_attr_parsing/src/context.rs | 3 +- compiler/rustc_hir_analysis/src/collect.rs | 40 ++++++++++--------- compiler/rustc_middle/src/ty/mod.rs | 11 ++--- compiler/rustc_parse/src/validate_attr.rs | 1 + compiler/rustc_passes/src/check_attr.rs | 10 ++--- 8 files changed, 49 insertions(+), 33 deletions(-) diff --git a/compiler/rustc_attr_data_structures/src/attributes.rs b/compiler/rustc_attr_data_structures/src/attributes.rs index b656db3252823..6ea98f6640575 100644 --- a/compiler/rustc_attr_data_structures/src/attributes.rs +++ b/compiler/rustc_attr_data_structures/src/attributes.rs @@ -234,6 +234,9 @@ pub enum AttributeKind { /// Represents `#[rustc_const_stable_indirect]`. ConstStabilityIndirect, + /// Represents `#[const_trait]`. + ConstTrait(Span), + /// Represents [`#[deprecated]`](https://doc.rust-lang.org/stable/reference/attributes/diagnostics.html#the-deprecated-attribute). Deprecation { deprecation: Deprecation, span: Span }, diff --git a/compiler/rustc_attr_data_structures/src/encode_cross_crate.rs b/compiler/rustc_attr_data_structures/src/encode_cross_crate.rs index 5414c7b103bcb..f22a64b2fd075 100644 --- a/compiler/rustc_attr_data_structures/src/encode_cross_crate.rs +++ b/compiler/rustc_attr_data_structures/src/encode_cross_crate.rs @@ -23,6 +23,7 @@ impl AttributeKind { ConstContinue(..) => No, ConstStability { .. } => Yes, ConstStabilityIndirect => No, + ConstTrait(..) => No, Deprecation { .. } => Yes, DocComment { .. } => Yes, Dummy => No, diff --git a/compiler/rustc_attr_parsing/src/attributes/traits.rs b/compiler/rustc_attr_parsing/src/attributes/traits.rs index 83a98c53c7f74..e897fc76ad73e 100644 --- a/compiler/rustc_attr_parsing/src/attributes/traits.rs +++ b/compiler/rustc_attr_parsing/src/attributes/traits.rs @@ -2,9 +2,11 @@ use core::mem; use rustc_attr_data_structures::AttributeKind; use rustc_feature::{AttributeTemplate, template}; -use rustc_span::{Symbol, sym}; +use rustc_span::{Span, Symbol, sym}; -use crate::attributes::{AttributeOrder, OnDuplicate, SingleAttributeParser}; +use crate::attributes::{ + AttributeOrder, NoArgsAttributeParser, OnDuplicate, SingleAttributeParser, +}; use crate::context::{AcceptContext, Stage}; use crate::parser::ArgParser; @@ -52,3 +54,10 @@ impl SingleAttributeParser for SkipDuringMethodDispatchParser { Some(AttributeKind::SkipDuringMethodDispatch { array, boxed_slice, span: cx.attr_span }) } } + +pub(crate) struct ConstTraitParser; +impl NoArgsAttributeParser for ConstTraitParser { + const PATH: &[Symbol] = &[sym::const_trait]; + const ON_DUPLICATE: OnDuplicate = OnDuplicate::Warn; + const CREATE: fn(Span) -> AttributeKind = AttributeKind::ConstTrait; +} diff --git a/compiler/rustc_attr_parsing/src/context.rs b/compiler/rustc_attr_parsing/src/context.rs index dbe1a5b2ad03d..9d294b0528d7c 100644 --- a/compiler/rustc_attr_parsing/src/context.rs +++ b/compiler/rustc_attr_parsing/src/context.rs @@ -43,7 +43,7 @@ use crate::attributes::stability::{ BodyStabilityParser, ConstStabilityIndirectParser, ConstStabilityParser, StabilityParser, }; use crate::attributes::test_attrs::IgnoreParser; -use crate::attributes::traits::SkipDuringMethodDispatchParser; +use crate::attributes::traits::{ConstTraitParser, SkipDuringMethodDispatchParser}; use crate::attributes::transparency::TransparencyParser; use crate::attributes::{AttributeParser as _, Combine, Single, WithoutArgs}; use crate::parser::{ArgParser, MetaItemParser, PathParser}; @@ -150,6 +150,7 @@ attribute_parsers!( Single>, Single>, Single>, + Single>, Single>, Single>, Single>, diff --git a/compiler/rustc_hir_analysis/src/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs index a185291887dc7..75e732ff46104 100644 --- a/compiler/rustc_hir_analysis/src/collect.rs +++ b/compiler/rustc_hir_analysis/src/collect.rs @@ -852,39 +852,42 @@ fn trait_def(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::TraitDef { _ => span_bug!(item.span, "trait_def_of_item invoked on non-trait"), }; + let attrs = tcx.get_all_attrs(def_id); // Only regular traits can be const. - let constness = if !is_alias && tcx.has_attr(def_id, sym::const_trait) { + let constness = if !is_alias && find_attr!(attrs, AttributeKind::ConstTrait(_)) { hir::Constness::Const } else { hir::Constness::NotConst }; - let paren_sugar = tcx.has_attr(def_id, sym::rustc_paren_sugar); + let paren_sugar = attrs.iter().any(|attr| attr.has_name(sym::rustc_paren_sugar)); if paren_sugar && !tcx.features().unboxed_closures() { tcx.dcx().emit_err(errors::ParenSugarAttribute { span: item.span }); } // Only regular traits can be marker. - let is_marker = !is_alias && tcx.has_attr(def_id, sym::marker); + let is_marker = !is_alias && attrs.iter().any(|attr| attr.has_name(sym::marker)); - let rustc_coinductive = tcx.has_attr(def_id, sym::rustc_coinductive); - let is_fundamental = tcx.has_attr(def_id, sym::fundamental); + let rustc_coinductive = attrs.iter().any(|attr| attr.has_name(sym::rustc_coinductive)); + let is_fundamental = attrs.iter().any(|attr| attr.has_name(sym::fundamental)); let [skip_array_during_method_dispatch, skip_boxed_slice_during_method_dispatch] = find_attr!( - tcx.get_all_attrs(def_id), - AttributeKind::SkipDuringMethodDispatch { array, boxed_slice, span:_ } => [*array, *boxed_slice] + attrs, + AttributeKind::SkipDuringMethodDispatch { array, boxed_slice, span: _ } => [*array, *boxed_slice] ) .unwrap_or([false; 2]); - let specialization_kind = if tcx.has_attr(def_id, sym::rustc_unsafe_specialization_marker) { - ty::trait_def::TraitSpecializationKind::Marker - } else if tcx.has_attr(def_id, sym::rustc_specialization_trait) { - ty::trait_def::TraitSpecializationKind::AlwaysApplicable - } else { - ty::trait_def::TraitSpecializationKind::None - }; - let must_implement_one_of = tcx - .get_attr(def_id, sym::rustc_must_implement_one_of) + let specialization_kind = + if attrs.iter().any(|attr| attr.has_name(sym::rustc_unsafe_specialization_marker)) { + ty::trait_def::TraitSpecializationKind::Marker + } else if attrs.iter().any(|attr| attr.has_name(sym::rustc_specialization_trait)) { + ty::trait_def::TraitSpecializationKind::AlwaysApplicable + } else { + ty::trait_def::TraitSpecializationKind::None + }; + let must_implement_one_of = attrs + .iter() + .find(|attr| attr.has_name(sym::rustc_must_implement_one_of)) // Check that there are at least 2 arguments of `#[rustc_must_implement_one_of]` // and that they are all identifiers .and_then(|attr| match attr.meta_item_list() { @@ -958,8 +961,9 @@ fn trait_def(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::TraitDef { no_dups.then_some(list) }); - let deny_explicit_impl = tcx.has_attr(def_id, sym::rustc_deny_explicit_impl); - let implement_via_object = !tcx.has_attr(def_id, sym::rustc_do_not_implement_via_object); + let deny_explicit_impl = attrs.iter().any(|attr| attr.has_name(sym::rustc_deny_explicit_impl)); + let implement_via_object = + !attrs.iter().any(|attr| attr.has_name(sym::rustc_do_not_implement_via_object)); ty::TraitDef { def_id: def_id.to_def_id(), diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index b780b1c5776bc..0177a95498bcd 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -1782,21 +1782,18 @@ impl<'tcx> TyCtxt<'tcx> { did: impl Into, attr: Symbol, ) -> impl Iterator { - self.get_all_attrs(did).filter(move |a: &&hir::Attribute| a.has_name(attr)) + self.get_all_attrs(did).iter().filter(move |a: &&hir::Attribute| a.has_name(attr)) } /// Gets all attributes. /// /// To see if an item has a specific attribute, you should use [`rustc_attr_data_structures::find_attr!`] so you can use matching. - pub fn get_all_attrs( - self, - did: impl Into, - ) -> impl Iterator { + pub fn get_all_attrs(self, did: impl Into) -> &'tcx [hir::Attribute] { let did: DefId = did.into(); if let Some(did) = did.as_local() { - self.hir_attrs(self.local_def_id_to_hir_id(did)).iter() + self.hir_attrs(self.local_def_id_to_hir_id(did)) } else { - self.attrs_for_def(did).iter() + self.attrs_for_def(did) } } diff --git a/compiler/rustc_parse/src/validate_attr.rs b/compiler/rustc_parse/src/validate_attr.rs index 11424ec3724bf..53346b40e2b4d 100644 --- a/compiler/rustc_parse/src/validate_attr.rs +++ b/compiler/rustc_parse/src/validate_attr.rs @@ -283,6 +283,7 @@ pub fn check_builtin_meta_item( | sym::rustc_confusables | sym::rustc_skip_during_method_dispatch | sym::rustc_pass_by_value + | sym::const_trait | sym::repr | sym::align | sym::deprecated diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index 0aa6a2b41cfb6..744f93506fee9 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -120,10 +120,10 @@ impl<'tcx> CheckAttrVisitor<'tcx> { for attr in attrs { let mut style = None; match attr { - Attribute::Parsed(AttributeKind::SkipDuringMethodDispatch { - span: attr_span, - .. - }) => { + Attribute::Parsed( + AttributeKind::SkipDuringMethodDispatch { span: attr_span, .. } + | AttributeKind::ConstTrait(attr_span), + ) => { self.check_must_be_applied_to_trait(*attr_span, span, target); } Attribute::Parsed(AttributeKind::Confusables { first_span, .. }) => { @@ -301,7 +301,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { | [sym::rustc_must_implement_one_of, ..] | [sym::rustc_deny_explicit_impl, ..] | [sym::rustc_do_not_implement_via_object, ..] - | [sym::const_trait, ..] => self.check_must_be_applied_to_trait(attr.span(), span, target), + => self.check_must_be_applied_to_trait(attr.span(), span, target), [sym::collapse_debuginfo, ..] => self.check_collapse_debuginfo(attr, span, target), [sym::must_not_suspend, ..] => self.check_must_not_suspend(attr, span, target), [sym::rustc_allow_incoherent_impl, ..] => { From 938916d220f2b8f7a5c5de26e7c43a826382d27f Mon Sep 17 00:00:00 2001 From: Pavel Grigorenko Date: Tue, 24 Jun 2025 00:18:37 +0300 Subject: [PATCH 04/27] Port `#[rustc_deny_explicit_impl]` to the new attribute system --- compiler/rustc_attr_data_structures/src/attributes.rs | 3 +++ .../rustc_attr_data_structures/src/encode_cross_crate.rs | 1 + compiler/rustc_attr_parsing/src/attributes/traits.rs | 7 +++++++ compiler/rustc_attr_parsing/src/context.rs | 5 ++++- compiler/rustc_hir_analysis/src/collect.rs | 2 +- compiler/rustc_parse/src/validate_attr.rs | 1 + compiler/rustc_passes/src/check_attr.rs | 4 ++-- 7 files changed, 19 insertions(+), 4 deletions(-) diff --git a/compiler/rustc_attr_data_structures/src/attributes.rs b/compiler/rustc_attr_data_structures/src/attributes.rs index 6ea98f6640575..f554b7a258ad3 100644 --- a/compiler/rustc_attr_data_structures/src/attributes.rs +++ b/compiler/rustc_attr_data_structures/src/attributes.rs @@ -237,6 +237,9 @@ pub enum AttributeKind { /// Represents `#[const_trait]`. ConstTrait(Span), + ///Represents `#[rustc_deny_explicit_impl]`. + DenyExplicitImpl(Span), + /// Represents [`#[deprecated]`](https://doc.rust-lang.org/stable/reference/attributes/diagnostics.html#the-deprecated-attribute). Deprecation { deprecation: Deprecation, span: Span }, diff --git a/compiler/rustc_attr_data_structures/src/encode_cross_crate.rs b/compiler/rustc_attr_data_structures/src/encode_cross_crate.rs index f22a64b2fd075..183a789f63672 100644 --- a/compiler/rustc_attr_data_structures/src/encode_cross_crate.rs +++ b/compiler/rustc_attr_data_structures/src/encode_cross_crate.rs @@ -24,6 +24,7 @@ impl AttributeKind { ConstStability { .. } => Yes, ConstStabilityIndirect => No, ConstTrait(..) => No, + DenyExplicitImpl(..) => No, Deprecation { .. } => Yes, DocComment { .. } => Yes, Dummy => No, diff --git a/compiler/rustc_attr_parsing/src/attributes/traits.rs b/compiler/rustc_attr_parsing/src/attributes/traits.rs index e897fc76ad73e..a7c9a77ca8c0c 100644 --- a/compiler/rustc_attr_parsing/src/attributes/traits.rs +++ b/compiler/rustc_attr_parsing/src/attributes/traits.rs @@ -61,3 +61,10 @@ impl NoArgsAttributeParser for ConstTraitParser { const ON_DUPLICATE: OnDuplicate = OnDuplicate::Warn; const CREATE: fn(Span) -> AttributeKind = AttributeKind::ConstTrait; } + +pub(crate) struct DenyExplicitImplParser; +impl NoArgsAttributeParser for DenyExplicitImplParser { + const PATH: &[Symbol] = &[sym::rustc_deny_explicit_impl]; + const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error; + const CREATE: fn(Span) -> AttributeKind = AttributeKind::DenyExplicitImpl; +} diff --git a/compiler/rustc_attr_parsing/src/context.rs b/compiler/rustc_attr_parsing/src/context.rs index 9d294b0528d7c..a6d41de36b6b7 100644 --- a/compiler/rustc_attr_parsing/src/context.rs +++ b/compiler/rustc_attr_parsing/src/context.rs @@ -43,7 +43,9 @@ use crate::attributes::stability::{ BodyStabilityParser, ConstStabilityIndirectParser, ConstStabilityParser, StabilityParser, }; use crate::attributes::test_attrs::IgnoreParser; -use crate::attributes::traits::{ConstTraitParser, SkipDuringMethodDispatchParser}; +use crate::attributes::traits::{ + ConstTraitParser, DenyExplicitImplParser, SkipDuringMethodDispatchParser, +}; use crate::attributes::transparency::TransparencyParser; use crate::attributes::{AttributeParser as _, Combine, Single, WithoutArgs}; use crate::parser::{ArgParser, MetaItemParser, PathParser}; @@ -151,6 +153,7 @@ attribute_parsers!( Single>, Single>, Single>, + Single>, Single>, Single>, Single>, diff --git a/compiler/rustc_hir_analysis/src/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs index 75e732ff46104..0c997c8ee18e0 100644 --- a/compiler/rustc_hir_analysis/src/collect.rs +++ b/compiler/rustc_hir_analysis/src/collect.rs @@ -961,7 +961,7 @@ fn trait_def(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::TraitDef { no_dups.then_some(list) }); - let deny_explicit_impl = attrs.iter().any(|attr| attr.has_name(sym::rustc_deny_explicit_impl)); + let deny_explicit_impl = find_attr!(attrs, AttributeKind::DenyExplicitImpl(_)); let implement_via_object = !attrs.iter().any(|attr| attr.has_name(sym::rustc_do_not_implement_via_object)); diff --git a/compiler/rustc_parse/src/validate_attr.rs b/compiler/rustc_parse/src/validate_attr.rs index 53346b40e2b4d..3fc10e31fc63f 100644 --- a/compiler/rustc_parse/src/validate_attr.rs +++ b/compiler/rustc_parse/src/validate_attr.rs @@ -283,6 +283,7 @@ pub fn check_builtin_meta_item( | sym::rustc_confusables | sym::rustc_skip_during_method_dispatch | sym::rustc_pass_by_value + | sym::rustc_deny_explicit_impl | sym::const_trait | sym::repr | sym::align diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index 744f93506fee9..470b41d9cc7f1 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -122,7 +122,8 @@ impl<'tcx> CheckAttrVisitor<'tcx> { match attr { Attribute::Parsed( AttributeKind::SkipDuringMethodDispatch { span: attr_span, .. } - | AttributeKind::ConstTrait(attr_span), + | AttributeKind::ConstTrait(attr_span) + | AttributeKind::DenyExplicitImpl(attr_span), ) => { self.check_must_be_applied_to_trait(*attr_span, span, target); } @@ -299,7 +300,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> { | [sym::rustc_then_this_would_need, ..] => self.check_rustc_dirty_clean(attr), [sym::rustc_coinductive, ..] | [sym::rustc_must_implement_one_of, ..] - | [sym::rustc_deny_explicit_impl, ..] | [sym::rustc_do_not_implement_via_object, ..] => self.check_must_be_applied_to_trait(attr.span(), span, target), [sym::collapse_debuginfo, ..] => self.check_collapse_debuginfo(attr, span, target), From adb325fc163bcb3b4248804309245a6a482dabe2 Mon Sep 17 00:00:00 2001 From: Pavel Grigorenko Date: Tue, 24 Jun 2025 00:22:09 +0300 Subject: [PATCH 05/27] Port `#[rustc_do_not_implement_via_object]` to the new attribute system --- compiler/rustc_attr_data_structures/src/attributes.rs | 3 +++ .../rustc_attr_data_structures/src/encode_cross_crate.rs | 1 + compiler/rustc_attr_parsing/src/attributes/traits.rs | 7 +++++++ compiler/rustc_attr_parsing/src/context.rs | 4 +++- compiler/rustc_hir_analysis/src/collect.rs | 3 +-- compiler/rustc_parse/src/validate_attr.rs | 1 + compiler/rustc_passes/src/check_attr.rs | 4 ++-- 7 files changed, 18 insertions(+), 5 deletions(-) diff --git a/compiler/rustc_attr_data_structures/src/attributes.rs b/compiler/rustc_attr_data_structures/src/attributes.rs index f554b7a258ad3..0127cea650599 100644 --- a/compiler/rustc_attr_data_structures/src/attributes.rs +++ b/compiler/rustc_attr_data_structures/src/attributes.rs @@ -243,6 +243,9 @@ pub enum AttributeKind { /// Represents [`#[deprecated]`](https://doc.rust-lang.org/stable/reference/attributes/diagnostics.html#the-deprecated-attribute). Deprecation { deprecation: Deprecation, span: Span }, + /// Represents `#[rustc_do_not_implement_via_object]`. + DoNotImplementViaObject(Span), + /// Represents [`#[doc]`](https://doc.rust-lang.org/stable/rustdoc/write-documentation/the-doc-attribute.html). DocComment { style: AttrStyle, kind: CommentKind, span: Span, comment: Symbol }, diff --git a/compiler/rustc_attr_data_structures/src/encode_cross_crate.rs b/compiler/rustc_attr_data_structures/src/encode_cross_crate.rs index 183a789f63672..d2b1edda1a485 100644 --- a/compiler/rustc_attr_data_structures/src/encode_cross_crate.rs +++ b/compiler/rustc_attr_data_structures/src/encode_cross_crate.rs @@ -26,6 +26,7 @@ impl AttributeKind { ConstTrait(..) => No, DenyExplicitImpl(..) => No, Deprecation { .. } => Yes, + DoNotImplementViaObject(..) => No, DocComment { .. } => Yes, Dummy => No, ExportName { .. } => Yes, diff --git a/compiler/rustc_attr_parsing/src/attributes/traits.rs b/compiler/rustc_attr_parsing/src/attributes/traits.rs index a7c9a77ca8c0c..3aa7389d1f2ba 100644 --- a/compiler/rustc_attr_parsing/src/attributes/traits.rs +++ b/compiler/rustc_attr_parsing/src/attributes/traits.rs @@ -68,3 +68,10 @@ impl NoArgsAttributeParser for DenyExplicitImplParser { const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error; const CREATE: fn(Span) -> AttributeKind = AttributeKind::DenyExplicitImpl; } + +pub(crate) struct DoNotImplementViaObjectParser; +impl NoArgsAttributeParser for DoNotImplementViaObjectParser { + const PATH: &[Symbol] = &[sym::rustc_do_not_implement_via_object]; + const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error; + const CREATE: fn(Span) -> AttributeKind = AttributeKind::DoNotImplementViaObject; +} diff --git a/compiler/rustc_attr_parsing/src/context.rs b/compiler/rustc_attr_parsing/src/context.rs index a6d41de36b6b7..baa944b840506 100644 --- a/compiler/rustc_attr_parsing/src/context.rs +++ b/compiler/rustc_attr_parsing/src/context.rs @@ -44,7 +44,8 @@ use crate::attributes::stability::{ }; use crate::attributes::test_attrs::IgnoreParser; use crate::attributes::traits::{ - ConstTraitParser, DenyExplicitImplParser, SkipDuringMethodDispatchParser, + ConstTraitParser, DenyExplicitImplParser, DoNotImplementViaObjectParser, + SkipDuringMethodDispatchParser, }; use crate::attributes::transparency::TransparencyParser; use crate::attributes::{AttributeParser as _, Combine, Single, WithoutArgs}; @@ -154,6 +155,7 @@ attribute_parsers!( Single>, Single>, Single>, + Single>, Single>, Single>, Single>, diff --git a/compiler/rustc_hir_analysis/src/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs index 0c997c8ee18e0..6bc339735418c 100644 --- a/compiler/rustc_hir_analysis/src/collect.rs +++ b/compiler/rustc_hir_analysis/src/collect.rs @@ -962,8 +962,7 @@ fn trait_def(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::TraitDef { }); let deny_explicit_impl = find_attr!(attrs, AttributeKind::DenyExplicitImpl(_)); - let implement_via_object = - !attrs.iter().any(|attr| attr.has_name(sym::rustc_do_not_implement_via_object)); + let implement_via_object = !find_attr!(attrs, AttributeKind::DoNotImplementViaObject(_)); ty::TraitDef { def_id: def_id.to_def_id(), diff --git a/compiler/rustc_parse/src/validate_attr.rs b/compiler/rustc_parse/src/validate_attr.rs index 3fc10e31fc63f..0290f60533795 100644 --- a/compiler/rustc_parse/src/validate_attr.rs +++ b/compiler/rustc_parse/src/validate_attr.rs @@ -284,6 +284,7 @@ pub fn check_builtin_meta_item( | sym::rustc_skip_during_method_dispatch | sym::rustc_pass_by_value | sym::rustc_deny_explicit_impl + | sym::rustc_do_not_implement_via_object | sym::const_trait | sym::repr | sym::align diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index 470b41d9cc7f1..4aaf3b34b718e 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -123,7 +123,8 @@ impl<'tcx> CheckAttrVisitor<'tcx> { Attribute::Parsed( AttributeKind::SkipDuringMethodDispatch { span: attr_span, .. } | AttributeKind::ConstTrait(attr_span) - | AttributeKind::DenyExplicitImpl(attr_span), + | AttributeKind::DenyExplicitImpl(attr_span) + | AttributeKind::DoNotImplementViaObject(attr_span), ) => { self.check_must_be_applied_to_trait(*attr_span, span, target); } @@ -300,7 +301,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> { | [sym::rustc_then_this_would_need, ..] => self.check_rustc_dirty_clean(attr), [sym::rustc_coinductive, ..] | [sym::rustc_must_implement_one_of, ..] - | [sym::rustc_do_not_implement_via_object, ..] => self.check_must_be_applied_to_trait(attr.span(), span, target), [sym::collapse_debuginfo, ..] => self.check_collapse_debuginfo(attr, span, target), [sym::must_not_suspend, ..] => self.check_must_not_suspend(attr, span, target), From 6f8e92d5aaa717773e38c1be547a0c4556ed9145 Mon Sep 17 00:00:00 2001 From: Pavel Grigorenko Date: Tue, 24 Jun 2025 00:27:30 +0300 Subject: [PATCH 06/27] Port `#[rustc_coinductive]` to the new attribute system --- compiler/rustc_attr_data_structures/src/attributes.rs | 3 +++ .../rustc_attr_data_structures/src/encode_cross_crate.rs | 1 + compiler/rustc_attr_parsing/src/attributes/traits.rs | 7 +++++++ compiler/rustc_attr_parsing/src/context.rs | 3 ++- compiler/rustc_hir_analysis/src/collect.rs | 2 +- compiler/rustc_parse/src/validate_attr.rs | 1 + compiler/rustc_passes/src/check_attr.rs | 5 ++--- 7 files changed, 17 insertions(+), 5 deletions(-) diff --git a/compiler/rustc_attr_data_structures/src/attributes.rs b/compiler/rustc_attr_data_structures/src/attributes.rs index 0127cea650599..f8a3ba093f79b 100644 --- a/compiler/rustc_attr_data_structures/src/attributes.rs +++ b/compiler/rustc_attr_data_structures/src/attributes.rs @@ -211,6 +211,9 @@ pub enum AttributeKind { span: Span, }, + /// Represents `#[rustc_coinductive]`. + Coinductive(Span), + /// Represents `#[cold]`. Cold(Span), diff --git a/compiler/rustc_attr_data_structures/src/encode_cross_crate.rs b/compiler/rustc_attr_data_structures/src/encode_cross_crate.rs index d2b1edda1a485..d78483b7c0912 100644 --- a/compiler/rustc_attr_data_structures/src/encode_cross_crate.rs +++ b/compiler/rustc_attr_data_structures/src/encode_cross_crate.rs @@ -18,6 +18,7 @@ impl AttributeKind { AllowInternalUnstable(..) => Yes, AsPtr(..) => Yes, BodyStability { .. } => No, + Coinductive(..) => No, Cold(..) => No, Confusables { .. } => Yes, ConstContinue(..) => No, diff --git a/compiler/rustc_attr_parsing/src/attributes/traits.rs b/compiler/rustc_attr_parsing/src/attributes/traits.rs index 3aa7389d1f2ba..e6f50761caaa9 100644 --- a/compiler/rustc_attr_parsing/src/attributes/traits.rs +++ b/compiler/rustc_attr_parsing/src/attributes/traits.rs @@ -75,3 +75,10 @@ impl NoArgsAttributeParser for DoNotImplementViaObjectParser { const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error; const CREATE: fn(Span) -> AttributeKind = AttributeKind::DoNotImplementViaObject; } + +pub(crate) struct CoinductiveParser; +impl NoArgsAttributeParser for CoinductiveParser { + const PATH: &[Symbol] = &[sym::rustc_coinductive]; + const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error; + const CREATE: fn(Span) -> AttributeKind = AttributeKind::Coinductive; +} diff --git a/compiler/rustc_attr_parsing/src/context.rs b/compiler/rustc_attr_parsing/src/context.rs index baa944b840506..c1584cd878f84 100644 --- a/compiler/rustc_attr_parsing/src/context.rs +++ b/compiler/rustc_attr_parsing/src/context.rs @@ -44,7 +44,7 @@ use crate::attributes::stability::{ }; use crate::attributes::test_attrs::IgnoreParser; use crate::attributes::traits::{ - ConstTraitParser, DenyExplicitImplParser, DoNotImplementViaObjectParser, + CoinductiveParser, ConstTraitParser, DenyExplicitImplParser, DoNotImplementViaObjectParser, SkipDuringMethodDispatchParser, }; use crate::attributes::transparency::TransparencyParser; @@ -150,6 +150,7 @@ attribute_parsers!( Single, Single, Single>, + Single>, Single>, Single>, Single>, diff --git a/compiler/rustc_hir_analysis/src/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs index 6bc339735418c..e6d6c3fad26e9 100644 --- a/compiler/rustc_hir_analysis/src/collect.rs +++ b/compiler/rustc_hir_analysis/src/collect.rs @@ -868,7 +868,7 @@ fn trait_def(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::TraitDef { // Only regular traits can be marker. let is_marker = !is_alias && attrs.iter().any(|attr| attr.has_name(sym::marker)); - let rustc_coinductive = attrs.iter().any(|attr| attr.has_name(sym::rustc_coinductive)); + let rustc_coinductive = find_attr!(attrs, AttributeKind::Coinductive(_)); let is_fundamental = attrs.iter().any(|attr| attr.has_name(sym::fundamental)); let [skip_array_during_method_dispatch, skip_boxed_slice_during_method_dispatch] = find_attr!( diff --git a/compiler/rustc_parse/src/validate_attr.rs b/compiler/rustc_parse/src/validate_attr.rs index 0290f60533795..700f5e788845c 100644 --- a/compiler/rustc_parse/src/validate_attr.rs +++ b/compiler/rustc_parse/src/validate_attr.rs @@ -285,6 +285,7 @@ pub fn check_builtin_meta_item( | sym::rustc_pass_by_value | sym::rustc_deny_explicit_impl | sym::rustc_do_not_implement_via_object + | sym::rustc_coinductive | sym::const_trait | sym::repr | sym::align diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index 4aaf3b34b718e..2aa3f0f4e007d 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -122,6 +122,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { match attr { Attribute::Parsed( AttributeKind::SkipDuringMethodDispatch { span: attr_span, .. } + | AttributeKind::Coinductive(attr_span) | AttributeKind::ConstTrait(attr_span) | AttributeKind::DenyExplicitImpl(attr_span) | AttributeKind::DoNotImplementViaObject(attr_span), @@ -299,9 +300,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { | [sym::rustc_dirty, ..] | [sym::rustc_if_this_changed, ..] | [sym::rustc_then_this_would_need, ..] => self.check_rustc_dirty_clean(attr), - [sym::rustc_coinductive, ..] - | [sym::rustc_must_implement_one_of, ..] - => self.check_must_be_applied_to_trait(attr.span(), span, target), + [sym::rustc_must_implement_one_of, ..] => self.check_must_be_applied_to_trait(attr.span(), span, target), [sym::collapse_debuginfo, ..] => self.check_collapse_debuginfo(attr, span, target), [sym::must_not_suspend, ..] => self.check_must_not_suspend(attr, span, target), [sym::rustc_allow_incoherent_impl, ..] => { From 813ec60744a4cc85740b73fb5bc2aba14bce41da Mon Sep 17 00:00:00 2001 From: Pavel Grigorenko Date: Tue, 24 Jun 2025 00:51:16 +0300 Subject: [PATCH 07/27] Port `#[type_const]` to the new attribute system --- .../src/attributes.rs | 3 +++ .../src/encode_cross_crate.rs | 1 + .../src/attributes/traits.rs | 7 +++++++ compiler/rustc_attr_parsing/src/context.rs | 3 ++- compiler/rustc_middle/src/ty/assoc.rs | 5 +++-- compiler/rustc_parse/src/validate_attr.rs | 1 + compiler/rustc_passes/src/check_attr.rs | 10 +++++----- tests/ui/attributes/malformed-attrs.stderr | 15 +++++++++------ .../mgca/bad-type_const-syntax.stderr | 18 +++++++++++------- 9 files changed, 42 insertions(+), 21 deletions(-) diff --git a/compiler/rustc_attr_data_structures/src/attributes.rs b/compiler/rustc_attr_data_structures/src/attributes.rs index f8a3ba093f79b..dd301fdfb12ad 100644 --- a/compiler/rustc_attr_data_structures/src/attributes.rs +++ b/compiler/rustc_attr_data_structures/src/attributes.rs @@ -359,6 +359,9 @@ pub enum AttributeKind { /// Represents `#[track_caller]` TrackCaller(Span), + /// Represents `#[type_const]`. + TypeConst(Span), + /// Represents `#[used]` Used { used_by: UsedBy, span: Span }, // tidy-alphabetical-end diff --git a/compiler/rustc_attr_data_structures/src/encode_cross_crate.rs b/compiler/rustc_attr_data_structures/src/encode_cross_crate.rs index d78483b7c0912..08e5e971a7d36 100644 --- a/compiler/rustc_attr_data_structures/src/encode_cross_crate.rs +++ b/compiler/rustc_attr_data_structures/src/encode_cross_crate.rs @@ -59,6 +59,7 @@ impl AttributeKind { StdInternalSymbol(..) => No, TargetFeature(..) => No, TrackCaller(..) => Yes, + TypeConst(..) => Yes, Used { .. } => No, // tidy-alphabetical-end } diff --git a/compiler/rustc_attr_parsing/src/attributes/traits.rs b/compiler/rustc_attr_parsing/src/attributes/traits.rs index e6f50761caaa9..5f9d182b00f84 100644 --- a/compiler/rustc_attr_parsing/src/attributes/traits.rs +++ b/compiler/rustc_attr_parsing/src/attributes/traits.rs @@ -82,3 +82,10 @@ impl NoArgsAttributeParser for CoinductiveParser { const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error; const CREATE: fn(Span) -> AttributeKind = AttributeKind::Coinductive; } + +pub(crate) struct TypeConstParser; +impl NoArgsAttributeParser for TypeConstParser { + const PATH: &[Symbol] = &[sym::type_const]; + const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error; + const CREATE: fn(Span) -> AttributeKind = AttributeKind::TypeConst; +} diff --git a/compiler/rustc_attr_parsing/src/context.rs b/compiler/rustc_attr_parsing/src/context.rs index c1584cd878f84..f86f5c7a1f444 100644 --- a/compiler/rustc_attr_parsing/src/context.rs +++ b/compiler/rustc_attr_parsing/src/context.rs @@ -45,7 +45,7 @@ use crate::attributes::stability::{ use crate::attributes::test_attrs::IgnoreParser; use crate::attributes::traits::{ CoinductiveParser, ConstTraitParser, DenyExplicitImplParser, DoNotImplementViaObjectParser, - SkipDuringMethodDispatchParser, + SkipDuringMethodDispatchParser, TypeConstParser, }; use crate::attributes::transparency::TransparencyParser; use crate::attributes::{AttributeParser as _, Combine, Single, WithoutArgs}; @@ -169,6 +169,7 @@ attribute_parsers!( Single>, Single>, Single>, + Single>, // tidy-alphabetical-end ]; ); diff --git a/compiler/rustc_middle/src/ty/assoc.rs b/compiler/rustc_middle/src/ty/assoc.rs index 78b2e265b488c..344a81f5e24d1 100644 --- a/compiler/rustc_middle/src/ty/assoc.rs +++ b/compiler/rustc_middle/src/ty/assoc.rs @@ -1,9 +1,10 @@ +use rustc_attr_data_structures::{AttributeKind, find_attr}; use rustc_data_structures::sorted_map::SortedIndexMultiMap; use rustc_hir as hir; use rustc_hir::def::{DefKind, Namespace}; use rustc_hir::def_id::DefId; use rustc_macros::{Decodable, Encodable, HashStable}; -use rustc_span::{Ident, Symbol, sym}; +use rustc_span::{Ident, Symbol}; use super::{TyCtxt, Visibility}; use crate::ty; @@ -160,7 +161,7 @@ impl AssocItem { // Inherent impl but this attr is only applied to trait assoc items. (AssocItemContainer::Impl, None) => return true, }; - tcx.has_attr(def_id, sym::type_const) + find_attr!(tcx.get_all_attrs(def_id), AttributeKind::TypeConst(_)) } } diff --git a/compiler/rustc_parse/src/validate_attr.rs b/compiler/rustc_parse/src/validate_attr.rs index 700f5e788845c..50a0366d9fe30 100644 --- a/compiler/rustc_parse/src/validate_attr.rs +++ b/compiler/rustc_parse/src/validate_attr.rs @@ -287,6 +287,7 @@ pub fn check_builtin_meta_item( | sym::rustc_do_not_implement_via_object | sym::rustc_coinductive | sym::const_trait + | sym::type_const | sym::repr | sym::align | sym::deprecated diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index 2aa3f0f4e007d..0951c49de11fe 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -129,6 +129,9 @@ impl<'tcx> CheckAttrVisitor<'tcx> { ) => { self.check_must_be_applied_to_trait(*attr_span, span, target); } + &Attribute::Parsed(AttributeKind::TypeConst(attr_span)) => { + self.check_type_const(hir_id, attr_span, target) + } Attribute::Parsed(AttributeKind::Confusables { first_span, .. }) => { self.check_confusables(*first_span, target); } @@ -338,9 +341,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> { [sym::coroutine, ..] => { self.check_coroutine(attr, target); } - [sym::type_const, ..] => { - self.check_type_const(hir_id,attr, target); - } [sym::linkage, ..] => self.check_linkage(attr, span, target), [ // ok @@ -2513,7 +2513,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { } } - fn check_type_const(&self, hir_id: HirId, attr: &Attribute, target: Target) { + fn check_type_const(&self, hir_id: HirId, attr_span: Span, target: Target) { let tcx = self.tcx; if target == Target::AssocConst && let parent = tcx.parent(hir_id.expect_owner().to_def_id()) @@ -2523,7 +2523,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { } else { self.dcx() .struct_span_err( - attr.span(), + attr_span, "`#[type_const]` must only be applied to trait associated constants", ) .emit(); diff --git a/tests/ui/attributes/malformed-attrs.stderr b/tests/ui/attributes/malformed-attrs.stderr index 5bcb0c4dc0a4c..ef5dcf7b2a0bf 100644 --- a/tests/ui/attributes/malformed-attrs.stderr +++ b/tests/ui/attributes/malformed-attrs.stderr @@ -116,12 +116,6 @@ error: malformed `cfi_encoding` attribute input LL | #[cfi_encoding] | ^^^^^^^^^^^^^^^ help: must be of the form: `#[cfi_encoding = "encoding"]` -error: malformed `type_const` attribute input - --> $DIR/malformed-attrs.rs:143:5 - | -LL | #[type_const = 1] - | ^^^^^^^^^^^^^^^^^ help: must be of the form: `#[type_const]` - error: malformed `marker` attribute input --> $DIR/malformed-attrs.rs:155:1 | @@ -555,6 +549,15 @@ LL | #[non_exhaustive = 1] | | didn't expect any arguments here | help: must be of the form: `#[non_exhaustive]` +error[E0565]: malformed `type_const` attribute input + --> $DIR/malformed-attrs.rs:143:5 + | +LL | #[type_const = 1] + | ^^^^^^^^^^^^^---^ + | | | + | | didn't expect any arguments here + | help: must be of the form: `#[type_const]` + error: attribute should be applied to `const fn` --> $DIR/malformed-attrs.rs:34:1 | diff --git a/tests/ui/const-generics/mgca/bad-type_const-syntax.stderr b/tests/ui/const-generics/mgca/bad-type_const-syntax.stderr index 579aff849d6e6..125c778ef1cd3 100644 --- a/tests/ui/const-generics/mgca/bad-type_const-syntax.stderr +++ b/tests/ui/const-generics/mgca/bad-type_const-syntax.stderr @@ -1,9 +1,3 @@ -error: malformed `type_const` attribute input - --> $DIR/bad-type_const-syntax.rs:2:5 - | -LL | #[type_const()] - | ^^^^^^^^^^^^^^^ help: must be of the form: `#[type_const]` - error[E0658]: the `#[type_const]` attribute is an experimental feature --> $DIR/bad-type_const-syntax.rs:2:5 | @@ -24,6 +18,15 @@ LL | #[type_const] = help: add `#![feature(min_generic_const_args)]` to the crate attributes to enable = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date +error[E0565]: malformed `type_const` attribute input + --> $DIR/bad-type_const-syntax.rs:2:5 + | +LL | #[type_const()] + | ^^^^^^^^^^^^--^ + | | | + | | didn't expect any arguments here + | help: must be of the form: `#[type_const]` + error: `#[type_const]` must only be applied to trait associated constants --> $DIR/bad-type_const-syntax.rs:11:5 | @@ -32,4 +35,5 @@ LL | #[type_const] error: aborting due to 4 previous errors -For more information about this error, try `rustc --explain E0658`. +Some errors have detailed explanations: E0565, E0658. +For more information about an error, try `rustc --explain E0565`. From 61937839616b89838afe77a0a9d14c70d51a3f09 Mon Sep 17 00:00:00 2001 From: Pavel Grigorenko Date: Tue, 24 Jun 2025 01:29:44 +0300 Subject: [PATCH 08/27] Port `#[rustc_specialization_trait]` to the new attribute system --- compiler/rustc_attr_data_structures/src/attributes.rs | 3 +++ .../rustc_attr_data_structures/src/encode_cross_crate.rs | 1 + compiler/rustc_attr_parsing/src/attributes/traits.rs | 7 +++++++ compiler/rustc_attr_parsing/src/context.rs | 3 ++- compiler/rustc_hir_analysis/src/collect.rs | 2 +- compiler/rustc_parse/src/validate_attr.rs | 1 + compiler/rustc_passes/src/check_attr.rs | 3 ++- 7 files changed, 17 insertions(+), 3 deletions(-) diff --git a/compiler/rustc_attr_data_structures/src/attributes.rs b/compiler/rustc_attr_data_structures/src/attributes.rs index dd301fdfb12ad..fe947c778b5ff 100644 --- a/compiler/rustc_attr_data_structures/src/attributes.rs +++ b/compiler/rustc_attr_data_structures/src/attributes.rs @@ -343,6 +343,9 @@ pub enum AttributeKind { /// Represents `#[rustc_skip_during_method_dispatch]`. SkipDuringMethodDispatch { array: bool, boxed_slice: bool, span: Span }, + /// Represents `#[rustc_specialization_trait]`. + SpecializationTrait(Span), + /// Represents `#[stable]`, `#[unstable]` and `#[rustc_allowed_through_unstable_modules]`. Stability { stability: Stability, diff --git a/compiler/rustc_attr_data_structures/src/encode_cross_crate.rs b/compiler/rustc_attr_data_structures/src/encode_cross_crate.rs index 08e5e971a7d36..8833f6102dbec 100644 --- a/compiler/rustc_attr_data_structures/src/encode_cross_crate.rs +++ b/compiler/rustc_attr_data_structures/src/encode_cross_crate.rs @@ -55,6 +55,7 @@ impl AttributeKind { RustcLayoutScalarValidRangeStart(..) => Yes, RustcObjectLifetimeDefault => No, SkipDuringMethodDispatch { .. } => No, + SpecializationTrait(..) => No, Stability { .. } => Yes, StdInternalSymbol(..) => No, TargetFeature(..) => No, diff --git a/compiler/rustc_attr_parsing/src/attributes/traits.rs b/compiler/rustc_attr_parsing/src/attributes/traits.rs index 5f9d182b00f84..d5aabea6823cd 100644 --- a/compiler/rustc_attr_parsing/src/attributes/traits.rs +++ b/compiler/rustc_attr_parsing/src/attributes/traits.rs @@ -89,3 +89,10 @@ impl NoArgsAttributeParser for TypeConstParser { const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error; const CREATE: fn(Span) -> AttributeKind = AttributeKind::TypeConst; } + +pub(crate) struct SpecializationTraitParser; +impl NoArgsAttributeParser for SpecializationTraitParser { + const PATH: &[Symbol] = &[sym::rustc_specialization_trait]; + const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error; + const CREATE: fn(Span) -> AttributeKind = AttributeKind::SpecializationTrait; +} diff --git a/compiler/rustc_attr_parsing/src/context.rs b/compiler/rustc_attr_parsing/src/context.rs index f86f5c7a1f444..f9a4b3e9a26cf 100644 --- a/compiler/rustc_attr_parsing/src/context.rs +++ b/compiler/rustc_attr_parsing/src/context.rs @@ -45,7 +45,7 @@ use crate::attributes::stability::{ use crate::attributes::test_attrs::IgnoreParser; use crate::attributes::traits::{ CoinductiveParser, ConstTraitParser, DenyExplicitImplParser, DoNotImplementViaObjectParser, - SkipDuringMethodDispatchParser, TypeConstParser, + SkipDuringMethodDispatchParser, SpecializationTraitParser, TypeConstParser, }; use crate::attributes::transparency::TransparencyParser; use crate::attributes::{AttributeParser as _, Combine, Single, WithoutArgs}; @@ -167,6 +167,7 @@ attribute_parsers!( Single>, Single>, Single>, + Single>, Single>, Single>, Single>, diff --git a/compiler/rustc_hir_analysis/src/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs index e6d6c3fad26e9..7f3900e72be45 100644 --- a/compiler/rustc_hir_analysis/src/collect.rs +++ b/compiler/rustc_hir_analysis/src/collect.rs @@ -880,7 +880,7 @@ fn trait_def(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::TraitDef { let specialization_kind = if attrs.iter().any(|attr| attr.has_name(sym::rustc_unsafe_specialization_marker)) { ty::trait_def::TraitSpecializationKind::Marker - } else if attrs.iter().any(|attr| attr.has_name(sym::rustc_specialization_trait)) { + } else if find_attr!(attrs, AttributeKind::SpecializationTrait(_)) { ty::trait_def::TraitSpecializationKind::AlwaysApplicable } else { ty::trait_def::TraitSpecializationKind::None diff --git a/compiler/rustc_parse/src/validate_attr.rs b/compiler/rustc_parse/src/validate_attr.rs index 50a0366d9fe30..7dbf323821598 100644 --- a/compiler/rustc_parse/src/validate_attr.rs +++ b/compiler/rustc_parse/src/validate_attr.rs @@ -287,6 +287,7 @@ pub fn check_builtin_meta_item( | sym::rustc_do_not_implement_via_object | sym::rustc_coinductive | sym::const_trait + | sym::rustc_specialization_trait | sym::type_const | sym::repr | sym::align diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index 0951c49de11fe..6e3ec5584d462 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -125,7 +125,8 @@ impl<'tcx> CheckAttrVisitor<'tcx> { | AttributeKind::Coinductive(attr_span) | AttributeKind::ConstTrait(attr_span) | AttributeKind::DenyExplicitImpl(attr_span) - | AttributeKind::DoNotImplementViaObject(attr_span), + | AttributeKind::DoNotImplementViaObject(attr_span) + | AttributeKind::SpecializationTrait(attr_span), ) => { self.check_must_be_applied_to_trait(*attr_span, span, target); } From a57a885abc342cf0fec0521da21b295f8694f75e Mon Sep 17 00:00:00 2001 From: Pavel Grigorenko Date: Tue, 24 Jun 2025 01:41:19 +0300 Subject: [PATCH 09/27] Port `#[rustc_unsafe_specialization_marker]` to the new attribute system --- .../rustc_attr_data_structures/src/attributes.rs | 3 +++ .../src/encode_cross_crate.rs | 1 + .../rustc_attr_parsing/src/attributes/traits.rs | 7 +++++++ compiler/rustc_attr_parsing/src/context.rs | 2 ++ compiler/rustc_hir_analysis/src/collect.rs | 15 +++++++-------- compiler/rustc_parse/src/validate_attr.rs | 1 + compiler/rustc_passes/src/check_attr.rs | 10 ++++++++-- 7 files changed, 29 insertions(+), 10 deletions(-) diff --git a/compiler/rustc_attr_data_structures/src/attributes.rs b/compiler/rustc_attr_data_structures/src/attributes.rs index fe947c778b5ff..9d924023e72ee 100644 --- a/compiler/rustc_attr_data_structures/src/attributes.rs +++ b/compiler/rustc_attr_data_structures/src/attributes.rs @@ -365,6 +365,9 @@ pub enum AttributeKind { /// Represents `#[type_const]`. TypeConst(Span), + /// Represents `#[rustc_unsafe_specialization_marker]`. + UnsafeSpecializationMarker(Span), + /// Represents `#[used]` Used { used_by: UsedBy, span: Span }, // tidy-alphabetical-end diff --git a/compiler/rustc_attr_data_structures/src/encode_cross_crate.rs b/compiler/rustc_attr_data_structures/src/encode_cross_crate.rs index 8833f6102dbec..5811cfa60c166 100644 --- a/compiler/rustc_attr_data_structures/src/encode_cross_crate.rs +++ b/compiler/rustc_attr_data_structures/src/encode_cross_crate.rs @@ -61,6 +61,7 @@ impl AttributeKind { TargetFeature(..) => No, TrackCaller(..) => Yes, TypeConst(..) => Yes, + UnsafeSpecializationMarker(..) => No, Used { .. } => No, // tidy-alphabetical-end } diff --git a/compiler/rustc_attr_parsing/src/attributes/traits.rs b/compiler/rustc_attr_parsing/src/attributes/traits.rs index d5aabea6823cd..a9e6f1f3a33d6 100644 --- a/compiler/rustc_attr_parsing/src/attributes/traits.rs +++ b/compiler/rustc_attr_parsing/src/attributes/traits.rs @@ -96,3 +96,10 @@ impl NoArgsAttributeParser for SpecializationTraitParser { const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error; const CREATE: fn(Span) -> AttributeKind = AttributeKind::SpecializationTrait; } + +pub(crate) struct UnsafeSpecializationMarkerParser; +impl NoArgsAttributeParser for UnsafeSpecializationMarkerParser { + const PATH: &[Symbol] = &[sym::rustc_unsafe_specialization_marker]; + const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error; + const CREATE: fn(Span) -> AttributeKind = AttributeKind::UnsafeSpecializationMarker; +} diff --git a/compiler/rustc_attr_parsing/src/context.rs b/compiler/rustc_attr_parsing/src/context.rs index f9a4b3e9a26cf..fe8ac2c532a3c 100644 --- a/compiler/rustc_attr_parsing/src/context.rs +++ b/compiler/rustc_attr_parsing/src/context.rs @@ -46,6 +46,7 @@ use crate::attributes::test_attrs::IgnoreParser; use crate::attributes::traits::{ CoinductiveParser, ConstTraitParser, DenyExplicitImplParser, DoNotImplementViaObjectParser, SkipDuringMethodDispatchParser, SpecializationTraitParser, TypeConstParser, + UnsafeSpecializationMarkerParser, }; use crate::attributes::transparency::TransparencyParser; use crate::attributes::{AttributeParser as _, Combine, Single, WithoutArgs}; @@ -171,6 +172,7 @@ attribute_parsers!( Single>, Single>, Single>, + Single>, // tidy-alphabetical-end ]; ); diff --git a/compiler/rustc_hir_analysis/src/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs index 7f3900e72be45..f0db98832d905 100644 --- a/compiler/rustc_hir_analysis/src/collect.rs +++ b/compiler/rustc_hir_analysis/src/collect.rs @@ -877,14 +877,13 @@ fn trait_def(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::TraitDef { ) .unwrap_or([false; 2]); - let specialization_kind = - if attrs.iter().any(|attr| attr.has_name(sym::rustc_unsafe_specialization_marker)) { - ty::trait_def::TraitSpecializationKind::Marker - } else if find_attr!(attrs, AttributeKind::SpecializationTrait(_)) { - ty::trait_def::TraitSpecializationKind::AlwaysApplicable - } else { - ty::trait_def::TraitSpecializationKind::None - }; + let specialization_kind = if find_attr!(attrs, AttributeKind::UnsafeSpecializationMarker(_)) { + ty::trait_def::TraitSpecializationKind::Marker + } else if find_attr!(attrs, AttributeKind::SpecializationTrait(_)) { + ty::trait_def::TraitSpecializationKind::AlwaysApplicable + } else { + ty::trait_def::TraitSpecializationKind::None + }; let must_implement_one_of = attrs .iter() .find(|attr| attr.has_name(sym::rustc_must_implement_one_of)) diff --git a/compiler/rustc_parse/src/validate_attr.rs b/compiler/rustc_parse/src/validate_attr.rs index 7dbf323821598..6efa9edfa079c 100644 --- a/compiler/rustc_parse/src/validate_attr.rs +++ b/compiler/rustc_parse/src/validate_attr.rs @@ -288,6 +288,7 @@ pub fn check_builtin_meta_item( | sym::rustc_coinductive | sym::const_trait | sym::rustc_specialization_trait + | sym::rustc_unsafe_specialization_marker | sym::type_const | sym::repr | sym::align diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index 6e3ec5584d462..7d30c36b463d0 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -125,11 +125,17 @@ impl<'tcx> CheckAttrVisitor<'tcx> { | AttributeKind::Coinductive(attr_span) | AttributeKind::ConstTrait(attr_span) | AttributeKind::DenyExplicitImpl(attr_span) - | AttributeKind::DoNotImplementViaObject(attr_span) - | AttributeKind::SpecializationTrait(attr_span), + | AttributeKind::DoNotImplementViaObject(attr_span), ) => { self.check_must_be_applied_to_trait(*attr_span, span, target); } + &Attribute::Parsed( + AttributeKind::SpecializationTrait(attr_span) + | AttributeKind::UnsafeSpecializationMarker(attr_span), + ) => { + // FIXME(specialization): more validation is needed + self.check_must_be_applied_to_trait(attr_span, span, target); + } &Attribute::Parsed(AttributeKind::TypeConst(attr_span)) => { self.check_type_const(hir_id, attr_span, target) } From 12f6487d79199c660edfba58cfcdc34e717b9abc Mon Sep 17 00:00:00 2001 From: Pavel Grigorenko Date: Tue, 24 Jun 2025 01:49:26 +0300 Subject: [PATCH 10/27] Port `#[marker]` to the new attribute system --- .../src/attributes.rs | 3 +++ .../src/encode_cross_crate.rs | 1 + .../src/attributes/traits.rs | 7 ++++++ compiler/rustc_attr_parsing/src/context.rs | 3 ++- compiler/rustc_hir_analysis/src/collect.rs | 2 +- compiler/rustc_parse/src/validate_attr.rs | 1 + compiler/rustc_passes/src/check_attr.rs | 14 ++++++------ tests/ui/attributes/malformed-attrs.stderr | 15 ++++++++----- .../marker-attribute-with-values.stderr | 22 ++++++++++++++----- 9 files changed, 47 insertions(+), 21 deletions(-) diff --git a/compiler/rustc_attr_data_structures/src/attributes.rs b/compiler/rustc_attr_data_structures/src/attributes.rs index 9d924023e72ee..91eee14b8ea2d 100644 --- a/compiler/rustc_attr_data_structures/src/attributes.rs +++ b/compiler/rustc_attr_data_structures/src/attributes.rs @@ -294,6 +294,9 @@ pub enum AttributeKind { /// Represents `#[rustc_macro_transparency]`. MacroTransparency(Transparency), + /// Represents `#[marker]`. + Marker(Span), + /// Represents [`#[may_dangle]`](https://std-dev-guide.rust-lang.org/tricky/may-dangle.html). MayDangle(Span), diff --git a/compiler/rustc_attr_data_structures/src/encode_cross_crate.rs b/compiler/rustc_attr_data_structures/src/encode_cross_crate.rs index 5811cfa60c166..f326bbf41f20b 100644 --- a/compiler/rustc_attr_data_structures/src/encode_cross_crate.rs +++ b/compiler/rustc_attr_data_structures/src/encode_cross_crate.rs @@ -40,6 +40,7 @@ impl AttributeKind { LinkSection { .. } => No, LoopMatch(..) => No, MacroTransparency(..) => Yes, + Marker(..) => No, MayDangle(..) => No, MustUse { .. } => Yes, Naked(..) => No, diff --git a/compiler/rustc_attr_parsing/src/attributes/traits.rs b/compiler/rustc_attr_parsing/src/attributes/traits.rs index a9e6f1f3a33d6..44b916b4cb3d7 100644 --- a/compiler/rustc_attr_parsing/src/attributes/traits.rs +++ b/compiler/rustc_attr_parsing/src/attributes/traits.rs @@ -103,3 +103,10 @@ impl NoArgsAttributeParser for UnsafeSpecializationMarkerParser { const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error; const CREATE: fn(Span) -> AttributeKind = AttributeKind::UnsafeSpecializationMarker; } + +pub(crate) struct MarkerParser; +impl NoArgsAttributeParser for MarkerParser { + const PATH: &[Symbol] = &[sym::marker]; + const ON_DUPLICATE: OnDuplicate = OnDuplicate::Warn; + const CREATE: fn(Span) -> AttributeKind = AttributeKind::Marker; +} diff --git a/compiler/rustc_attr_parsing/src/context.rs b/compiler/rustc_attr_parsing/src/context.rs index fe8ac2c532a3c..edfb013fe0cfe 100644 --- a/compiler/rustc_attr_parsing/src/context.rs +++ b/compiler/rustc_attr_parsing/src/context.rs @@ -45,7 +45,7 @@ use crate::attributes::stability::{ use crate::attributes::test_attrs::IgnoreParser; use crate::attributes::traits::{ CoinductiveParser, ConstTraitParser, DenyExplicitImplParser, DoNotImplementViaObjectParser, - SkipDuringMethodDispatchParser, SpecializationTraitParser, TypeConstParser, + MarkerParser, SkipDuringMethodDispatchParser, SpecializationTraitParser, TypeConstParser, UnsafeSpecializationMarkerParser, }; use crate::attributes::transparency::TransparencyParser; @@ -162,6 +162,7 @@ attribute_parsers!( Single>, Single>, Single>, + Single>, Single>, Single>, Single>, diff --git a/compiler/rustc_hir_analysis/src/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs index f0db98832d905..b5c7bfeed9bb8 100644 --- a/compiler/rustc_hir_analysis/src/collect.rs +++ b/compiler/rustc_hir_analysis/src/collect.rs @@ -866,7 +866,7 @@ fn trait_def(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::TraitDef { } // Only regular traits can be marker. - let is_marker = !is_alias && attrs.iter().any(|attr| attr.has_name(sym::marker)); + let is_marker = !is_alias && find_attr!(attrs, AttributeKind::Marker(_)); let rustc_coinductive = find_attr!(attrs, AttributeKind::Coinductive(_)); let is_fundamental = attrs.iter().any(|attr| attr.has_name(sym::fundamental)); diff --git a/compiler/rustc_parse/src/validate_attr.rs b/compiler/rustc_parse/src/validate_attr.rs index 6efa9edfa079c..89670674042c1 100644 --- a/compiler/rustc_parse/src/validate_attr.rs +++ b/compiler/rustc_parse/src/validate_attr.rs @@ -289,6 +289,7 @@ pub fn check_builtin_meta_item( | sym::const_trait | sym::rustc_specialization_trait | sym::rustc_unsafe_specialization_marker + | sym::marker | sym::type_const | sym::repr | sym::align diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index 7d30c36b463d0..7eedc748bd6ab 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -139,6 +139,9 @@ impl<'tcx> CheckAttrVisitor<'tcx> { &Attribute::Parsed(AttributeKind::TypeConst(attr_span)) => { self.check_type_const(hir_id, attr_span, target) } + &Attribute::Parsed(AttributeKind::Marker(attr_span)) => { + self.check_marker(hir_id, attr_span, span, target) + } Attribute::Parsed(AttributeKind::Confusables { first_span, .. }) => { self.check_confusables(*first_span, target); } @@ -272,7 +275,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> { [sym::no_sanitize, ..] => { self.check_no_sanitize(attr, span, target) } - [sym::marker, ..] => self.check_marker(hir_id, attr, span, target), [sym::thread_local, ..] => self.check_thread_local(attr, span, target), [sym::doc, ..] => self.check_doc_attrs( attr, @@ -836,7 +838,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { } /// Checks if the `#[marker]` attribute on an `item` is valid. - fn check_marker(&self, hir_id: HirId, attr: &Attribute, span: Span, target: Target) { + fn check_marker(&self, hir_id: HirId, attr_span: Span, span: Span, target: Target) { match target { Target::Trait => {} // FIXME(#80564): We permit struct fields, match arms and macro defs to have an @@ -844,13 +846,11 @@ impl<'tcx> CheckAttrVisitor<'tcx> { // erroneously allowed it and some crates used it accidentally, to be compatible // with crates depending on them, we can't throw an error here. Target::Field | Target::Arm | Target::MacroDef => { - self.inline_attr_str_error_with_macro_def(hir_id, attr.span(), "marker"); + self.inline_attr_str_error_with_macro_def(hir_id, attr_span, "marker"); } _ => { - self.dcx().emit_err(errors::AttrShouldBeAppliedToTrait { - attr_span: attr.span(), - defn_span: span, - }); + self.dcx() + .emit_err(errors::AttrShouldBeAppliedToTrait { attr_span, defn_span: span }); } } } diff --git a/tests/ui/attributes/malformed-attrs.stderr b/tests/ui/attributes/malformed-attrs.stderr index ef5dcf7b2a0bf..aef54248bb6c4 100644 --- a/tests/ui/attributes/malformed-attrs.stderr +++ b/tests/ui/attributes/malformed-attrs.stderr @@ -116,12 +116,6 @@ error: malformed `cfi_encoding` attribute input LL | #[cfi_encoding] | ^^^^^^^^^^^^^^^ help: must be of the form: `#[cfi_encoding = "encoding"]` -error: malformed `marker` attribute input - --> $DIR/malformed-attrs.rs:155:1 - | -LL | #[marker = 3] - | ^^^^^^^^^^^^^ help: must be of the form: `#[marker]` - error: malformed `fundamental` attribute input --> $DIR/malformed-attrs.rs:157:1 | @@ -522,6 +516,15 @@ LL | #[rustc_layout_scalar_valid_range_end] | expected this to be a list | help: must be of the form: `#[rustc_layout_scalar_valid_range_end(end)]` +error[E0565]: malformed `marker` attribute input + --> $DIR/malformed-attrs.rs:155:1 + | +LL | #[marker = 3] + | ^^^^^^^^^---^ + | | | + | | didn't expect any arguments here + | help: must be of the form: `#[marker]` + error[E0565]: malformed `ffi_pure` attribute input --> $DIR/malformed-attrs.rs:165:5 | diff --git a/tests/ui/marker_trait_attr/marker-attribute-with-values.stderr b/tests/ui/marker_trait_attr/marker-attribute-with-values.stderr index 6f9c9508e7e55..9a2e5add37b35 100644 --- a/tests/ui/marker_trait_attr/marker-attribute-with-values.stderr +++ b/tests/ui/marker_trait_attr/marker-attribute-with-values.stderr @@ -1,20 +1,30 @@ -error: malformed `marker` attribute input +error[E0565]: malformed `marker` attribute input --> $DIR/marker-attribute-with-values.rs:3:1 | LL | #[marker(always)] - | ^^^^^^^^^^^^^^^^^ help: must be of the form: `#[marker]` + | ^^^^^^^^--------^ + | | | + | | didn't expect any arguments here + | help: must be of the form: `#[marker]` -error: malformed `marker` attribute input +error[E0565]: malformed `marker` attribute input --> $DIR/marker-attribute-with-values.rs:6:1 | LL | #[marker("never")] - | ^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[marker]` + | ^^^^^^^^---------^ + | | | + | | didn't expect any arguments here + | help: must be of the form: `#[marker]` -error: malformed `marker` attribute input +error[E0565]: malformed `marker` attribute input --> $DIR/marker-attribute-with-values.rs:9:1 | LL | #[marker(key = "value")] - | ^^^^^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[marker]` + | ^^^^^^^^---------------^ + | | | + | | didn't expect any arguments here + | help: must be of the form: `#[marker]` error: aborting due to 3 previous errors +For more information about this error, try `rustc --explain E0565`. From 507ebced1693e4671db3f059caf24d7a4a9c6d28 Mon Sep 17 00:00:00 2001 From: Pavel Grigorenko Date: Tue, 24 Jun 2025 01:58:53 +0300 Subject: [PATCH 11/27] Port `#[fundamental]` to the new attribute system --- .../rustc_attr_data_structures/src/attributes.rs | 3 +++ .../src/encode_cross_crate.rs | 1 + .../rustc_attr_parsing/src/attributes/traits.rs | 7 +++++++ compiler/rustc_attr_parsing/src/context.rs | 5 +++-- compiler/rustc_hir_analysis/src/collect.rs | 2 +- compiler/rustc_middle/src/ty/adt.rs | 3 +-- compiler/rustc_parse/src/validate_attr.rs | 1 + compiler/rustc_passes/src/check_attr.rs | 4 +++- tests/ui/attributes/malformed-attrs.stderr | 15 +++++++++------ 9 files changed, 29 insertions(+), 12 deletions(-) diff --git a/compiler/rustc_attr_data_structures/src/attributes.rs b/compiler/rustc_attr_data_structures/src/attributes.rs index 91eee14b8ea2d..36a8bf87eeed6 100644 --- a/compiler/rustc_attr_data_structures/src/attributes.rs +++ b/compiler/rustc_attr_data_structures/src/attributes.rs @@ -272,6 +272,9 @@ pub enum AttributeKind { /// Represents `#[ffi_pure]`. FfiPure(Span), + /// Represents `#[fundamental]`. + Fundamental, + /// Represents `#[ignore]` Ignore { span: Span, diff --git a/compiler/rustc_attr_data_structures/src/encode_cross_crate.rs b/compiler/rustc_attr_data_structures/src/encode_cross_crate.rs index f326bbf41f20b..9747f85c128a7 100644 --- a/compiler/rustc_attr_data_structures/src/encode_cross_crate.rs +++ b/compiler/rustc_attr_data_structures/src/encode_cross_crate.rs @@ -34,6 +34,7 @@ impl AttributeKind { ExportStable => No, FfiConst(..) => No, FfiPure(..) => No, + Fundamental { .. } => Yes, Ignore { .. } => No, Inline(..) => No, LinkName { .. } => Yes, diff --git a/compiler/rustc_attr_parsing/src/attributes/traits.rs b/compiler/rustc_attr_parsing/src/attributes/traits.rs index 44b916b4cb3d7..0059698f4ad0d 100644 --- a/compiler/rustc_attr_parsing/src/attributes/traits.rs +++ b/compiler/rustc_attr_parsing/src/attributes/traits.rs @@ -110,3 +110,10 @@ impl NoArgsAttributeParser for MarkerParser { const ON_DUPLICATE: OnDuplicate = OnDuplicate::Warn; const CREATE: fn(Span) -> AttributeKind = AttributeKind::Marker; } + +pub(crate) struct FundamentalParser; +impl NoArgsAttributeParser for FundamentalParser { + const PATH: &[Symbol] = &[sym::fundamental]; + const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error; + const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::Fundamental; +} diff --git a/compiler/rustc_attr_parsing/src/context.rs b/compiler/rustc_attr_parsing/src/context.rs index edfb013fe0cfe..cf7dfa8157b71 100644 --- a/compiler/rustc_attr_parsing/src/context.rs +++ b/compiler/rustc_attr_parsing/src/context.rs @@ -45,8 +45,8 @@ use crate::attributes::stability::{ use crate::attributes::test_attrs::IgnoreParser; use crate::attributes::traits::{ CoinductiveParser, ConstTraitParser, DenyExplicitImplParser, DoNotImplementViaObjectParser, - MarkerParser, SkipDuringMethodDispatchParser, SpecializationTraitParser, TypeConstParser, - UnsafeSpecializationMarkerParser, + FundamentalParser, MarkerParser, SkipDuringMethodDispatchParser, SpecializationTraitParser, + TypeConstParser, UnsafeSpecializationMarkerParser, }; use crate::attributes::transparency::TransparencyParser; use crate::attributes::{AttributeParser as _, Combine, Single, WithoutArgs}; @@ -161,6 +161,7 @@ attribute_parsers!( Single>, Single>, Single>, + Single>, Single>, Single>, Single>, diff --git a/compiler/rustc_hir_analysis/src/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs index b5c7bfeed9bb8..415ff2d26bbe5 100644 --- a/compiler/rustc_hir_analysis/src/collect.rs +++ b/compiler/rustc_hir_analysis/src/collect.rs @@ -869,7 +869,7 @@ fn trait_def(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::TraitDef { let is_marker = !is_alias && find_attr!(attrs, AttributeKind::Marker(_)); let rustc_coinductive = find_attr!(attrs, AttributeKind::Coinductive(_)); - let is_fundamental = attrs.iter().any(|attr| attr.has_name(sym::fundamental)); + let is_fundamental = find_attr!(attrs, AttributeKind::Fundamental); let [skip_array_during_method_dispatch, skip_boxed_slice_during_method_dispatch] = find_attr!( attrs, diff --git a/compiler/rustc_middle/src/ty/adt.rs b/compiler/rustc_middle/src/ty/adt.rs index 44165b06f1c33..275458fc85f8d 100644 --- a/compiler/rustc_middle/src/ty/adt.rs +++ b/compiler/rustc_middle/src/ty/adt.rs @@ -17,7 +17,6 @@ use rustc_index::{IndexSlice, IndexVec}; use rustc_macros::{HashStable, TyDecodable, TyEncodable}; use rustc_query_system::ich::StableHashingContext; use rustc_session::DataTypeKind; -use rustc_span::sym; use rustc_type_ir::solve::AdtDestructorKind; use tracing::{debug, info, trace}; @@ -296,7 +295,7 @@ impl AdtDefData { flags |= AdtFlags::HAS_CTOR; } - if tcx.has_attr(did, sym::fundamental) { + if find_attr!(tcx.get_all_attrs(did), AttributeKind::Fundamental) { flags |= AdtFlags::IS_FUNDAMENTAL; } if tcx.is_lang_item(did, LangItem::PhantomData) { diff --git a/compiler/rustc_parse/src/validate_attr.rs b/compiler/rustc_parse/src/validate_attr.rs index 89670674042c1..d415b3241c928 100644 --- a/compiler/rustc_parse/src/validate_attr.rs +++ b/compiler/rustc_parse/src/validate_attr.rs @@ -290,6 +290,7 @@ pub fn check_builtin_meta_item( | sym::rustc_specialization_trait | sym::rustc_unsafe_specialization_marker | sym::marker + | sym::fundamental | sym::type_const | sym::repr | sym::align diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index 7eedc748bd6ab..776939e6886b9 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -142,6 +142,9 @@ impl<'tcx> CheckAttrVisitor<'tcx> { &Attribute::Parsed(AttributeKind::Marker(attr_span)) => { self.check_marker(hir_id, attr_span, span, target) } + Attribute::Parsed(AttributeKind::Fundamental) => { + // FIXME: add validation + } Attribute::Parsed(AttributeKind::Confusables { first_span, .. }) => { self.check_confusables(*first_span, target); } @@ -374,7 +377,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> { | sym::prelude_import | sym::panic_handler | sym::allow_internal_unsafe - | sym::fundamental | sym::lang | sym::needs_allocator | sym::default_lib_allocator diff --git a/tests/ui/attributes/malformed-attrs.stderr b/tests/ui/attributes/malformed-attrs.stderr index aef54248bb6c4..be529df3a4953 100644 --- a/tests/ui/attributes/malformed-attrs.stderr +++ b/tests/ui/attributes/malformed-attrs.stderr @@ -116,12 +116,6 @@ error: malformed `cfi_encoding` attribute input LL | #[cfi_encoding] | ^^^^^^^^^^^^^^^ help: must be of the form: `#[cfi_encoding = "encoding"]` -error: malformed `fundamental` attribute input - --> $DIR/malformed-attrs.rs:157:1 - | -LL | #[fundamental()] - | ^^^^^^^^^^^^^^^^ help: must be of the form: `#[fundamental]` - error: malformed `link_ordinal` attribute input --> $DIR/malformed-attrs.rs:167:5 | @@ -525,6 +519,15 @@ LL | #[marker = 3] | | didn't expect any arguments here | help: must be of the form: `#[marker]` +error[E0565]: malformed `fundamental` attribute input + --> $DIR/malformed-attrs.rs:157:1 + | +LL | #[fundamental()] + | ^^^^^^^^^^^^^--^ + | | | + | | didn't expect any arguments here + | help: must be of the form: `#[fundamental]` + error[E0565]: malformed `ffi_pure` attribute input --> $DIR/malformed-attrs.rs:165:5 | From 1bdf70317165de715fd320042d6502aa25f5aabf Mon Sep 17 00:00:00 2001 From: Pavel Grigorenko Date: Tue, 24 Jun 2025 02:06:57 +0300 Subject: [PATCH 12/27] Port `#[rustc_paren_sugar]` to the new attribute system --- compiler/rustc_attr_data_structures/src/attributes.rs | 3 +++ .../rustc_attr_data_structures/src/encode_cross_crate.rs | 1 + compiler/rustc_attr_parsing/src/attributes/traits.rs | 7 +++++++ compiler/rustc_attr_parsing/src/context.rs | 5 +++-- compiler/rustc_hir_analysis/src/collect.rs | 2 +- compiler/rustc_parse/src/validate_attr.rs | 1 + compiler/rustc_passes/src/check_attr.rs | 5 +++-- 7 files changed, 19 insertions(+), 5 deletions(-) diff --git a/compiler/rustc_attr_data_structures/src/attributes.rs b/compiler/rustc_attr_data_structures/src/attributes.rs index 36a8bf87eeed6..de2bbcceac48c 100644 --- a/compiler/rustc_attr_data_structures/src/attributes.rs +++ b/compiler/rustc_attr_data_structures/src/attributes.rs @@ -325,6 +325,9 @@ pub enum AttributeKind { /// Represents `#[optimize(size|speed)]` Optimize(OptimizeAttr, Span), + /// Represents `#[rustc_paren_sugar]`. + ParenSugar(Span), + /// Represents `#[rustc_pass_by_value]` (used by the `rustc_pass_by_value` lint). PassByValue(Span), diff --git a/compiler/rustc_attr_data_structures/src/encode_cross_crate.rs b/compiler/rustc_attr_data_structures/src/encode_cross_crate.rs index 9747f85c128a7..99b3ae9b9cdb7 100644 --- a/compiler/rustc_attr_data_structures/src/encode_cross_crate.rs +++ b/compiler/rustc_attr_data_structures/src/encode_cross_crate.rs @@ -49,6 +49,7 @@ impl AttributeKind { NoMangle(..) => No, NonExhaustive(..) => Yes, Optimize(..) => No, + ParenSugar(..) => No, PassByValue(..) => Yes, Path(..) => No, PubTransparent(..) => Yes, diff --git a/compiler/rustc_attr_parsing/src/attributes/traits.rs b/compiler/rustc_attr_parsing/src/attributes/traits.rs index 0059698f4ad0d..362625abe7dbf 100644 --- a/compiler/rustc_attr_parsing/src/attributes/traits.rs +++ b/compiler/rustc_attr_parsing/src/attributes/traits.rs @@ -117,3 +117,10 @@ impl NoArgsAttributeParser for FundamentalParser { const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error; const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::Fundamental; } + +pub(crate) struct ParenSugarParser; +impl NoArgsAttributeParser for ParenSugarParser { + const PATH: &[Symbol] = &[sym::rustc_paren_sugar]; + const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error; + const CREATE: fn(Span) -> AttributeKind = AttributeKind::ParenSugar; +} diff --git a/compiler/rustc_attr_parsing/src/context.rs b/compiler/rustc_attr_parsing/src/context.rs index cf7dfa8157b71..4d618c171c8fb 100644 --- a/compiler/rustc_attr_parsing/src/context.rs +++ b/compiler/rustc_attr_parsing/src/context.rs @@ -45,8 +45,8 @@ use crate::attributes::stability::{ use crate::attributes::test_attrs::IgnoreParser; use crate::attributes::traits::{ CoinductiveParser, ConstTraitParser, DenyExplicitImplParser, DoNotImplementViaObjectParser, - FundamentalParser, MarkerParser, SkipDuringMethodDispatchParser, SpecializationTraitParser, - TypeConstParser, UnsafeSpecializationMarkerParser, + FundamentalParser, MarkerParser, ParenSugarParser, SkipDuringMethodDispatchParser, + SpecializationTraitParser, TypeConstParser, UnsafeSpecializationMarkerParser, }; use crate::attributes::transparency::TransparencyParser; use crate::attributes::{AttributeParser as _, Combine, Single, WithoutArgs}; @@ -168,6 +168,7 @@ attribute_parsers!( Single>, Single>, Single>, + Single>, Single>, Single>, Single>, diff --git a/compiler/rustc_hir_analysis/src/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs index 415ff2d26bbe5..431d99a572d26 100644 --- a/compiler/rustc_hir_analysis/src/collect.rs +++ b/compiler/rustc_hir_analysis/src/collect.rs @@ -860,7 +860,7 @@ fn trait_def(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::TraitDef { hir::Constness::NotConst }; - let paren_sugar = attrs.iter().any(|attr| attr.has_name(sym::rustc_paren_sugar)); + let paren_sugar = find_attr!(attrs, AttributeKind::ParenSugar(_)); if paren_sugar && !tcx.features().unboxed_closures() { tcx.dcx().emit_err(errors::ParenSugarAttribute { span: item.span }); } diff --git a/compiler/rustc_parse/src/validate_attr.rs b/compiler/rustc_parse/src/validate_attr.rs index d415b3241c928..ce7a7cd0a93e8 100644 --- a/compiler/rustc_parse/src/validate_attr.rs +++ b/compiler/rustc_parse/src/validate_attr.rs @@ -291,6 +291,7 @@ pub fn check_builtin_meta_item( | sym::rustc_unsafe_specialization_marker | sym::marker | sym::fundamental + | sym::rustc_paren_sugar | sym::type_const | sym::repr | sym::align diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index 776939e6886b9..567b0423d52e9 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -131,9 +131,10 @@ impl<'tcx> CheckAttrVisitor<'tcx> { } &Attribute::Parsed( AttributeKind::SpecializationTrait(attr_span) - | AttributeKind::UnsafeSpecializationMarker(attr_span), + | AttributeKind::UnsafeSpecializationMarker(attr_span) + | AttributeKind::ParenSugar(attr_span), ) => { - // FIXME(specialization): more validation is needed + // FIXME: more validation is needed self.check_must_be_applied_to_trait(attr_span, span, target); } &Attribute::Parsed(AttributeKind::TypeConst(attr_span)) => { From a6bc8160d64df15ddf08fd9bdcc13d2c5f1028e0 Mon Sep 17 00:00:00 2001 From: Pavel Grigorenko Date: Tue, 24 Jun 2025 23:41:07 +0300 Subject: [PATCH 13/27] Reorder attribute parsers in `traits.rs` --- .../src/attributes/traits.rs | 63 ++++++++++--------- 1 file changed, 35 insertions(+), 28 deletions(-) diff --git a/compiler/rustc_attr_parsing/src/attributes/traits.rs b/compiler/rustc_attr_parsing/src/attributes/traits.rs index 362625abe7dbf..a0c2509639b7c 100644 --- a/compiler/rustc_attr_parsing/src/attributes/traits.rs +++ b/compiler/rustc_attr_parsing/src/attributes/traits.rs @@ -11,7 +11,6 @@ use crate::context::{AcceptContext, Stage}; use crate::parser::ArgParser; pub(crate) struct SkipDuringMethodDispatchParser; - impl SingleAttributeParser for SkipDuringMethodDispatchParser { const PATH: &[Symbol] = &[sym::rustc_skip_during_method_dispatch]; const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepFirst; @@ -55,11 +54,27 @@ impl SingleAttributeParser for SkipDuringMethodDispatchParser { } } -pub(crate) struct ConstTraitParser; -impl NoArgsAttributeParser for ConstTraitParser { - const PATH: &[Symbol] = &[sym::const_trait]; +pub(crate) struct ParenSugarParser; +impl NoArgsAttributeParser for ParenSugarParser { + const PATH: &[Symbol] = &[sym::rustc_paren_sugar]; + const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error; + const CREATE: fn(Span) -> AttributeKind = AttributeKind::ParenSugar; +} + +pub(crate) struct TypeConstParser; +impl NoArgsAttributeParser for TypeConstParser { + const PATH: &[Symbol] = &[sym::type_const]; + const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error; + const CREATE: fn(Span) -> AttributeKind = AttributeKind::TypeConst; +} + +// Markers + +pub(crate) struct MarkerParser; +impl NoArgsAttributeParser for MarkerParser { + const PATH: &[Symbol] = &[sym::marker]; const ON_DUPLICATE: OnDuplicate = OnDuplicate::Warn; - const CREATE: fn(Span) -> AttributeKind = AttributeKind::ConstTrait; + const CREATE: fn(Span) -> AttributeKind = AttributeKind::Marker; } pub(crate) struct DenyExplicitImplParser; @@ -76,20 +91,17 @@ impl NoArgsAttributeParser for DoNotImplementViaObjectParser { const CREATE: fn(Span) -> AttributeKind = AttributeKind::DoNotImplementViaObject; } -pub(crate) struct CoinductiveParser; -impl NoArgsAttributeParser for CoinductiveParser { - const PATH: &[Symbol] = &[sym::rustc_coinductive]; - const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error; - const CREATE: fn(Span) -> AttributeKind = AttributeKind::Coinductive; -} +// Const traits -pub(crate) struct TypeConstParser; -impl NoArgsAttributeParser for TypeConstParser { - const PATH: &[Symbol] = &[sym::type_const]; - const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error; - const CREATE: fn(Span) -> AttributeKind = AttributeKind::TypeConst; +pub(crate) struct ConstTraitParser; +impl NoArgsAttributeParser for ConstTraitParser { + const PATH: &[Symbol] = &[sym::const_trait]; + const ON_DUPLICATE: OnDuplicate = OnDuplicate::Warn; + const CREATE: fn(Span) -> AttributeKind = AttributeKind::ConstTrait; } +// Specialization + pub(crate) struct SpecializationTraitParser; impl NoArgsAttributeParser for SpecializationTraitParser { const PATH: &[Symbol] = &[sym::rustc_specialization_trait]; @@ -104,11 +116,13 @@ impl NoArgsAttributeParser for UnsafeSpecializationMarkerParser { const CREATE: fn(Span) -> AttributeKind = AttributeKind::UnsafeSpecializationMarker; } -pub(crate) struct MarkerParser; -impl NoArgsAttributeParser for MarkerParser { - const PATH: &[Symbol] = &[sym::marker]; - const ON_DUPLICATE: OnDuplicate = OnDuplicate::Warn; - const CREATE: fn(Span) -> AttributeKind = AttributeKind::Marker; +// Coherence + +pub(crate) struct CoinductiveParser; +impl NoArgsAttributeParser for CoinductiveParser { + const PATH: &[Symbol] = &[sym::rustc_coinductive]; + const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error; + const CREATE: fn(Span) -> AttributeKind = AttributeKind::Coinductive; } pub(crate) struct FundamentalParser; @@ -117,10 +131,3 @@ impl NoArgsAttributeParser for FundamentalParser { const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error; const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::Fundamental; } - -pub(crate) struct ParenSugarParser; -impl NoArgsAttributeParser for ParenSugarParser { - const PATH: &[Symbol] = &[sym::rustc_paren_sugar]; - const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error; - const CREATE: fn(Span) -> AttributeKind = AttributeKind::ParenSugar; -} From e9e64954e60ab92c839a98da16952a58196c3430 Mon Sep 17 00:00:00 2001 From: Pavel Grigorenko Date: Tue, 24 Jun 2025 23:53:39 +0300 Subject: [PATCH 14/27] Port `#[rustc_allow_incoherent_impl]` to the new attribute system --- compiler/rustc_attr_data_structures/src/attributes.rs | 3 +++ .../src/encode_cross_crate.rs | 1 + compiler/rustc_attr_parsing/src/attributes/traits.rs | 7 +++++++ compiler/rustc_attr_parsing/src/context.rs | 8 +++++--- .../src/coherence/inherent_impls.rs | 11 +++++++++-- compiler/rustc_parse/src/validate_attr.rs | 1 + compiler/rustc_passes/src/check_attr.rs | 10 +++++----- 7 files changed, 31 insertions(+), 10 deletions(-) diff --git a/compiler/rustc_attr_data_structures/src/attributes.rs b/compiler/rustc_attr_data_structures/src/attributes.rs index de2bbcceac48c..860a1ce593f13 100644 --- a/compiler/rustc_attr_data_structures/src/attributes.rs +++ b/compiler/rustc_attr_data_structures/src/attributes.rs @@ -198,6 +198,9 @@ pub enum AttributeKind { /// Represents `#[rustc_allow_const_fn_unstable]`. AllowConstFnUnstable(ThinVec, Span), + /// Represents `#[rustc_allow_incoherent_impl]`. + AllowIncoherentImpl(Span), + /// Represents `#[allow_internal_unstable]`. AllowInternalUnstable(ThinVec<(Symbol, Span)>, Span), diff --git a/compiler/rustc_attr_data_structures/src/encode_cross_crate.rs b/compiler/rustc_attr_data_structures/src/encode_cross_crate.rs index 99b3ae9b9cdb7..36abbb171a5af 100644 --- a/compiler/rustc_attr_data_structures/src/encode_cross_crate.rs +++ b/compiler/rustc_attr_data_structures/src/encode_cross_crate.rs @@ -15,6 +15,7 @@ impl AttributeKind { // tidy-alphabetical-start Align { .. } => No, AllowConstFnUnstable(..) => No, + AllowIncoherentImpl(..) => No, AllowInternalUnstable(..) => Yes, AsPtr(..) => Yes, BodyStability { .. } => No, diff --git a/compiler/rustc_attr_parsing/src/attributes/traits.rs b/compiler/rustc_attr_parsing/src/attributes/traits.rs index a0c2509639b7c..74673fdd3fb70 100644 --- a/compiler/rustc_attr_parsing/src/attributes/traits.rs +++ b/compiler/rustc_attr_parsing/src/attributes/traits.rs @@ -125,6 +125,13 @@ impl NoArgsAttributeParser for CoinductiveParser { const CREATE: fn(Span) -> AttributeKind = AttributeKind::Coinductive; } +pub(crate) struct AllowIncoherentImplParser; +impl NoArgsAttributeParser for AllowIncoherentImplParser { + const PATH: &[Symbol] = &[sym::rustc_allow_incoherent_impl]; + const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error; + const CREATE: fn(Span) -> AttributeKind = AttributeKind::AllowIncoherentImpl; +} + pub(crate) struct FundamentalParser; impl NoArgsAttributeParser for FundamentalParser { const PATH: &[Symbol] = &[sym::fundamental]; diff --git a/compiler/rustc_attr_parsing/src/context.rs b/compiler/rustc_attr_parsing/src/context.rs index 4d618c171c8fb..db5ed13bc7d1b 100644 --- a/compiler/rustc_attr_parsing/src/context.rs +++ b/compiler/rustc_attr_parsing/src/context.rs @@ -44,9 +44,10 @@ use crate::attributes::stability::{ }; use crate::attributes::test_attrs::IgnoreParser; use crate::attributes::traits::{ - CoinductiveParser, ConstTraitParser, DenyExplicitImplParser, DoNotImplementViaObjectParser, - FundamentalParser, MarkerParser, ParenSugarParser, SkipDuringMethodDispatchParser, - SpecializationTraitParser, TypeConstParser, UnsafeSpecializationMarkerParser, + AllowIncoherentImplParser, CoinductiveParser, ConstTraitParser, DenyExplicitImplParser, + DoNotImplementViaObjectParser, FundamentalParser, MarkerParser, ParenSugarParser, + SkipDuringMethodDispatchParser, SpecializationTraitParser, TypeConstParser, + UnsafeSpecializationMarkerParser, }; use crate::attributes::transparency::TransparencyParser; use crate::attributes::{AttributeParser as _, Combine, Single, WithoutArgs}; @@ -150,6 +151,7 @@ attribute_parsers!( Single, Single, Single, + Single>, Single>, Single>, Single>, diff --git a/compiler/rustc_hir_analysis/src/coherence/inherent_impls.rs b/compiler/rustc_hir_analysis/src/coherence/inherent_impls.rs index bd25b4a326086..80bf13dc4b7a3 100644 --- a/compiler/rustc_hir_analysis/src/coherence/inherent_impls.rs +++ b/compiler/rustc_hir_analysis/src/coherence/inherent_impls.rs @@ -7,6 +7,7 @@ //! `tcx.inherent_impls(def_id)`). That value, however, //! is computed by selecting an idea from this table. +use rustc_attr_data_structures::{AttributeKind, find_attr}; use rustc_hir as hir; use rustc_hir::def::DefKind; use rustc_hir::def_id::{DefId, LocalDefId}; @@ -85,7 +86,10 @@ impl<'tcx> InherentCollect<'tcx> { } for &impl_item in items { - if !self.tcx.has_attr(impl_item, sym::rustc_allow_incoherent_impl) { + if !find_attr!( + self.tcx.get_all_attrs(impl_item), + AttributeKind::AllowIncoherentImpl(_) + ) { let impl_span = self.tcx.def_span(impl_def_id); return Err(self.tcx.dcx().emit_err(errors::InherentTyOutsideRelevant { span: impl_span, @@ -116,7 +120,10 @@ impl<'tcx> InherentCollect<'tcx> { if !self.tcx.hir_rustc_coherence_is_core() { if self.tcx.features().rustc_attrs() { for &impl_item in items { - if !self.tcx.has_attr(impl_item, sym::rustc_allow_incoherent_impl) { + if !find_attr!( + self.tcx.get_all_attrs(impl_item), + AttributeKind::AllowIncoherentImpl(_) + ) { let span = self.tcx.def_span(impl_def_id); return Err(self.tcx.dcx().emit_err(errors::InherentTyOutsidePrimitive { span, diff --git a/compiler/rustc_parse/src/validate_attr.rs b/compiler/rustc_parse/src/validate_attr.rs index ce7a7cd0a93e8..c500c9b406311 100644 --- a/compiler/rustc_parse/src/validate_attr.rs +++ b/compiler/rustc_parse/src/validate_attr.rs @@ -289,6 +289,7 @@ pub fn check_builtin_meta_item( | sym::const_trait | sym::rustc_specialization_trait | sym::rustc_unsafe_specialization_marker + | sym::rustc_allow_incoherent_impl | sym::marker | sym::fundamental | sym::rustc_paren_sugar diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index 567b0423d52e9..5d2b6d3de39f6 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -146,6 +146,9 @@ impl<'tcx> CheckAttrVisitor<'tcx> { Attribute::Parsed(AttributeKind::Fundamental) => { // FIXME: add validation } + &Attribute::Parsed(AttributeKind::AllowIncoherentImpl(attr_span)) => { + self.check_allow_incoherent_impl(attr_span, span, target) + } Attribute::Parsed(AttributeKind::Confusables { first_span, .. }) => { self.check_confusables(*first_span, target); } @@ -319,9 +322,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> { [sym::rustc_must_implement_one_of, ..] => self.check_must_be_applied_to_trait(attr.span(), span, target), [sym::collapse_debuginfo, ..] => self.check_collapse_debuginfo(attr, span, target), [sym::must_not_suspend, ..] => self.check_must_not_suspend(attr, span, target), - [sym::rustc_allow_incoherent_impl, ..] => { - self.check_allow_incoherent_impl(attr, span, target) - } [sym::rustc_has_incoherent_inherent_impls, ..] => { self.check_has_incoherent_inherent_impls(attr, span, target) } @@ -1498,11 +1498,11 @@ impl<'tcx> CheckAttrVisitor<'tcx> { } } - fn check_allow_incoherent_impl(&self, attr: &Attribute, span: Span, target: Target) { + fn check_allow_incoherent_impl(&self, attr_span: Span, span: Span, target: Target) { match target { Target::Method(MethodKind::Inherent) => {} _ => { - self.dcx().emit_err(errors::AllowIncoherentImpl { attr_span: attr.span(), span }); + self.dcx().emit_err(errors::AllowIncoherentImpl { attr_span, span }); } } } From e584ed0de2150ad11b24ed75e954825fd5b273f9 Mon Sep 17 00:00:00 2001 From: Pavel Grigorenko Date: Wed, 25 Jun 2025 00:24:14 +0300 Subject: [PATCH 15/27] Port `#[rustc_coherence_is_core]` to the new attribute system --- compiler/rustc_attr_data_structures/src/attributes.rs | 3 +++ .../rustc_attr_data_structures/src/encode_cross_crate.rs | 1 + compiler/rustc_attr_parsing/src/attributes/traits.rs | 7 +++++++ compiler/rustc_attr_parsing/src/context.rs | 7 ++++--- compiler/rustc_middle/src/hir/map.rs | 5 +++-- compiler/rustc_parse/src/validate_attr.rs | 1 + compiler/rustc_passes/src/check_attr.rs | 2 +- 7 files changed, 20 insertions(+), 6 deletions(-) diff --git a/compiler/rustc_attr_data_structures/src/attributes.rs b/compiler/rustc_attr_data_structures/src/attributes.rs index 860a1ce593f13..f61efcf238852 100644 --- a/compiler/rustc_attr_data_structures/src/attributes.rs +++ b/compiler/rustc_attr_data_structures/src/attributes.rs @@ -214,6 +214,9 @@ pub enum AttributeKind { span: Span, }, + /// Represents `#[rustc_coherence_is_core]`. + CoherenceIsCore, + /// Represents `#[rustc_coinductive]`. Coinductive(Span), diff --git a/compiler/rustc_attr_data_structures/src/encode_cross_crate.rs b/compiler/rustc_attr_data_structures/src/encode_cross_crate.rs index 36abbb171a5af..ad587523e0373 100644 --- a/compiler/rustc_attr_data_structures/src/encode_cross_crate.rs +++ b/compiler/rustc_attr_data_structures/src/encode_cross_crate.rs @@ -19,6 +19,7 @@ impl AttributeKind { AllowInternalUnstable(..) => Yes, AsPtr(..) => Yes, BodyStability { .. } => No, + CoherenceIsCore => No, Coinductive(..) => No, Cold(..) => No, Confusables { .. } => Yes, diff --git a/compiler/rustc_attr_parsing/src/attributes/traits.rs b/compiler/rustc_attr_parsing/src/attributes/traits.rs index 74673fdd3fb70..c202a0315a09c 100644 --- a/compiler/rustc_attr_parsing/src/attributes/traits.rs +++ b/compiler/rustc_attr_parsing/src/attributes/traits.rs @@ -132,6 +132,13 @@ impl NoArgsAttributeParser for AllowIncoherentImplParser { const CREATE: fn(Span) -> AttributeKind = AttributeKind::AllowIncoherentImpl; } +pub(crate) struct CoherenceIsCoreParser; +impl NoArgsAttributeParser for CoherenceIsCoreParser { + const PATH: &[Symbol] = &[sym::rustc_coherence_is_core]; + const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error; + const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::CoherenceIsCore; +} + pub(crate) struct FundamentalParser; impl NoArgsAttributeParser for FundamentalParser { const PATH: &[Symbol] = &[sym::fundamental]; diff --git a/compiler/rustc_attr_parsing/src/context.rs b/compiler/rustc_attr_parsing/src/context.rs index db5ed13bc7d1b..cc10bb3098a61 100644 --- a/compiler/rustc_attr_parsing/src/context.rs +++ b/compiler/rustc_attr_parsing/src/context.rs @@ -44,9 +44,9 @@ use crate::attributes::stability::{ }; use crate::attributes::test_attrs::IgnoreParser; use crate::attributes::traits::{ - AllowIncoherentImplParser, CoinductiveParser, ConstTraitParser, DenyExplicitImplParser, - DoNotImplementViaObjectParser, FundamentalParser, MarkerParser, ParenSugarParser, - SkipDuringMethodDispatchParser, SpecializationTraitParser, TypeConstParser, + AllowIncoherentImplParser, CoherenceIsCoreParser, CoinductiveParser, ConstTraitParser, + DenyExplicitImplParser, DoNotImplementViaObjectParser, FundamentalParser, MarkerParser, + ParenSugarParser, SkipDuringMethodDispatchParser, SpecializationTraitParser, TypeConstParser, UnsafeSpecializationMarkerParser, }; use crate::attributes::transparency::TransparencyParser; @@ -153,6 +153,7 @@ attribute_parsers!( Single, Single>, Single>, + Single>, Single>, Single>, Single>, diff --git a/compiler/rustc_middle/src/hir/map.rs b/compiler/rustc_middle/src/hir/map.rs index 291707878a342..84710e5e636e0 100644 --- a/compiler/rustc_middle/src/hir/map.rs +++ b/compiler/rustc_middle/src/hir/map.rs @@ -4,6 +4,7 @@ use rustc_abi::ExternAbi; use rustc_ast::visit::{VisitorResult, walk_list}; +use rustc_attr_data_structures::{AttributeKind, find_attr}; use rustc_data_structures::fingerprint::Fingerprint; use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; use rustc_data_structures::svh::Svh; @@ -15,7 +16,7 @@ use rustc_hir::intravisit::Visitor; use rustc_hir::*; use rustc_hir_pretty as pprust_hir; use rustc_span::def_id::StableCrateId; -use rustc_span::{ErrorGuaranteed, Ident, Span, Symbol, kw, sym, with_metavar_spans}; +use rustc_span::{ErrorGuaranteed, Ident, Span, Symbol, kw, with_metavar_spans}; use crate::hir::{ModuleItems, nested_filter}; use crate::middle::debugger_visualizer::DebuggerVisualizerFile; @@ -369,7 +370,7 @@ impl<'tcx> TyCtxt<'tcx> { } pub fn hir_rustc_coherence_is_core(self) -> bool { - self.hir_krate_attrs().iter().any(|attr| attr.has_name(sym::rustc_coherence_is_core)) + find_attr!(self.hir_krate_attrs(), AttributeKind::CoherenceIsCore) } pub fn hir_get_module(self, module: LocalModDefId) -> (&'tcx Mod<'tcx>, Span, HirId) { diff --git a/compiler/rustc_parse/src/validate_attr.rs b/compiler/rustc_parse/src/validate_attr.rs index c500c9b406311..bb5c1e0e653a7 100644 --- a/compiler/rustc_parse/src/validate_attr.rs +++ b/compiler/rustc_parse/src/validate_attr.rs @@ -290,6 +290,7 @@ pub fn check_builtin_meta_item( | sym::rustc_specialization_trait | sym::rustc_unsafe_specialization_marker | sym::rustc_allow_incoherent_impl + | sym::rustc_coherence_is_core | sym::marker | sym::fundamental | sym::rustc_paren_sugar diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index 5d2b6d3de39f6..2c95fead9e801 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -143,7 +143,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { &Attribute::Parsed(AttributeKind::Marker(attr_span)) => { self.check_marker(hir_id, attr_span, span, target) } - Attribute::Parsed(AttributeKind::Fundamental) => { + Attribute::Parsed(AttributeKind::Fundamental | AttributeKind::CoherenceIsCore) => { // FIXME: add validation } &Attribute::Parsed(AttributeKind::AllowIncoherentImpl(attr_span)) => { From 04bb68ac869bc4d55bcb260398470b0c5eea4a40 Mon Sep 17 00:00:00 2001 From: Jubilee Young Date: Wed, 9 Jul 2025 20:50:17 -0700 Subject: [PATCH 16/27] compiler: recomment `needs_fn_once_adapter_shim` This requires digging up ffee9566bbd7728e6411e6094105d6905373255d and reading the comments there to understand that the callee in resolve_closure previously directly handled a function pointer value. --- compiler/rustc_middle/src/ty/instance.rs | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/compiler/rustc_middle/src/ty/instance.rs b/compiler/rustc_middle/src/ty/instance.rs index 21b7500e46fe0..d5767ca3786e8 100644 --- a/compiler/rustc_middle/src/ty/instance.rs +++ b/compiler/rustc_middle/src/ty/instance.rs @@ -991,18 +991,16 @@ fn needs_fn_once_adapter_shim( Ok(false) } (ty::ClosureKind::Fn, ty::ClosureKind::FnMut) => { - // The closure fn `llfn` is a `fn(&self, ...)`. We want a - // `fn(&mut self, ...)`. In fact, at codegen time, these are - // basically the same thing, so we can just return llfn. + // The closure fn is a `fn(&self, ...)`, but we want a `fn(&mut self, ...)`. + // At codegen time, these are basically the same, so we can just return the closure. Ok(false) } (ty::ClosureKind::Fn | ty::ClosureKind::FnMut, ty::ClosureKind::FnOnce) => { - // The closure fn `llfn` is a `fn(&self, ...)` or `fn(&mut - // self, ...)`. We want a `fn(self, ...)`. We can produce - // this by doing something like: + // The closure fn is a `fn(&self, ...)` or `fn(&mut self, ...)`, but + // we want a `fn(self, ...)`. We can produce this by doing something like: // - // fn call_once(self, ...) { call_mut(&self, ...) } - // fn call_once(mut self, ...) { call_mut(&mut self, ...) } + // fn call_once(self, ...) { Fn::call(&self, ...) } + // fn call_once(mut self, ...) { FnMut::call_mut(&mut self, ...) } // // These are both the same at codegen time. Ok(true) From a8663770c96c3be6d3a42bb84f2e377921628c1e Mon Sep 17 00:00:00 2001 From: Jens Reidel Date: Thu, 10 Jul 2025 21:04:40 +0200 Subject: [PATCH 17/27] Add target maintainer information for aarch64-unknown-linux-musl Signed-off-by: Jens Reidel --- src/doc/rustc/src/SUMMARY.md | 1 + src/doc/rustc/src/platform-support.md | 2 +- .../aarch64-unknown-linux-musl.md | 49 +++++++++++++++++++ 3 files changed, 51 insertions(+), 1 deletion(-) create mode 100644 src/doc/rustc/src/platform-support/aarch64-unknown-linux-musl.md diff --git a/src/doc/rustc/src/SUMMARY.md b/src/doc/rustc/src/SUMMARY.md index e1742631f63cc..7c688e32bc0dd 100644 --- a/src/doc/rustc/src/SUMMARY.md +++ b/src/doc/rustc/src/SUMMARY.md @@ -46,6 +46,7 @@ - [\*-apple-watchos](platform-support/apple-watchos.md) - [\*-apple-visionos](platform-support/apple-visionos.md) - [aarch64-nintendo-switch-freestanding](platform-support/aarch64-nintendo-switch-freestanding.md) + - [aarch64-unknown-linux-musl](platform-support/aarch64-unknown-linux-musl.md) - [amdgcn-amd-amdhsa](platform-support/amdgcn-amd-amdhsa.md) - [armeb-unknown-linux-gnueabi](platform-support/armeb-unknown-linux-gnueabi.md) - [arm-none-eabi](platform-support/arm-none-eabi.md) diff --git a/src/doc/rustc/src/platform-support.md b/src/doc/rustc/src/platform-support.md index ed01de4c1c300..65b7063015388 100644 --- a/src/doc/rustc/src/platform-support.md +++ b/src/doc/rustc/src/platform-support.md @@ -90,7 +90,7 @@ target | notes -------|------- [`aarch64-pc-windows-gnullvm`](platform-support/windows-gnullvm.md) | ARM64 MinGW (Windows 10+), LLVM ABI [`aarch64-pc-windows-msvc`](platform-support/windows-msvc.md) | ARM64 Windows MSVC -`aarch64-unknown-linux-musl` | ARM64 Linux with musl 1.2.3 +[`aarch64-unknown-linux-musl`](platform-support/aarch64-unknown-linux-musl.md) | ARM64 Linux with musl 1.2.3 [`aarch64-unknown-linux-ohos`](platform-support/openharmony.md) | ARM64 OpenHarmony `arm-unknown-linux-gnueabi` | Armv6 Linux (kernel 3.2+, glibc 2.17) `arm-unknown-linux-gnueabihf` | Armv6 Linux, hardfloat (kernel 3.2+, glibc 2.17) diff --git a/src/doc/rustc/src/platform-support/aarch64-unknown-linux-musl.md b/src/doc/rustc/src/platform-support/aarch64-unknown-linux-musl.md new file mode 100644 index 0000000000000..5d9a552e4603f --- /dev/null +++ b/src/doc/rustc/src/platform-support/aarch64-unknown-linux-musl.md @@ -0,0 +1,49 @@ +# aarch64-unknown-linux-musl + +**Tier: 2** + +Target for 64-bit little endian ARMv8-A Linux programs using musl libc. + +## Target maintainers + +[@Gelbpunkt](https://github.com/Gelbpunkt) +[@famfo](https://github.com/famfo) + +## Requirements + +Building the target itself requires a 64-bit little endian ARMv8-A compiler +that is supported by `cc-rs`. + +## Building the target + +The target can be built by enabling it for a `rustc` build. + +```toml +[build] +target = ["aarch64-unknown-linux-musl"] +``` + +Make sure your C compiler is included in `$PATH`, then add it to the +`bootstrap.toml`: + +```toml +[target.aarch64-unknown-linux-musl] +cc = "aarch64-linux-musl-gcc" +cxx = "aarch64-linux-musl-g++" +ar = "aarch64-linux-musl-ar" +linker = "aarch64-linux-musl-gcc" +``` + +## Building Rust programs + +This target is distributed through `rustup`, and otherwise requires no +special configuration. + +## Cross-compilation + +This target can be cross-compiled from any host. + +## Testing + +This target can be tested as normal with `x.py` on a 64-bit little endian +ARMv8-A host or via QEMU emulation. From ed96f00682c8c170c7fd680eef9bd6c2021669f9 Mon Sep 17 00:00:00 2001 From: Fluid <90795031+fluiderson@users.noreply.github.com> Date: Fri, 11 Jul 2025 02:27:39 +0300 Subject: [PATCH 18/27] fix typos in function names in the `target_feature` test --- tests/rustdoc-json/attrs/target_feature.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/rustdoc-json/attrs/target_feature.rs b/tests/rustdoc-json/attrs/target_feature.rs index 80262d8e33257..5c8aeb84ee3cc 100644 --- a/tests/rustdoc-json/attrs/target_feature.rs +++ b/tests/rustdoc-json/attrs/target_feature.rs @@ -6,17 +6,17 @@ pub fn test1() {} //@ is "$.index[?(@.name=='test2')].attrs" '["#[target_feature(enable=\"avx\", enable=\"avx2\")]"]' -//@ is "$.index[?(@.name=='test1')].inner.function.header.is_unsafe" false +//@ is "$.index[?(@.name=='test2')].inner.function.header.is_unsafe" false #[target_feature(enable = "avx,avx2")] pub fn test2() {} //@ is "$.index[?(@.name=='test3')].attrs" '["#[target_feature(enable=\"avx\", enable=\"avx2\")]"]' -//@ is "$.index[?(@.name=='test1')].inner.function.header.is_unsafe" false +//@ is "$.index[?(@.name=='test3')].inner.function.header.is_unsafe" false #[target_feature(enable = "avx", enable = "avx2")] pub fn test3() {} //@ is "$.index[?(@.name=='test4')].attrs" '["#[target_feature(enable=\"avx\", enable=\"avx2\", enable=\"avx512f\")]"]' -//@ is "$.index[?(@.name=='test1')].inner.function.header.is_unsafe" false +//@ is "$.index[?(@.name=='test4')].inner.function.header.is_unsafe" false #[target_feature(enable = "avx", enable = "avx2,avx512f")] pub fn test4() {} From 3c11029acef45da169dd6713c48e9fdd98d606b5 Mon Sep 17 00:00:00 2001 From: Colten <70793703+ColtenOuO@users.noreply.github.com> Date: Wed, 9 Jul 2025 01:59:03 +0800 Subject: [PATCH 19/27] =?UTF-8?q?docs:=20clarify=20=E2=80=9Cdag=E2=80=9D?= =?UTF-8?q?=20in=20std::sys=5Fcommon=20doc=20comment?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- library/std/src/sys_common/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/std/src/sys_common/mod.rs b/library/std/src/sys_common/mod.rs index b7f4656fa3701..cce88d936b71b 100644 --- a/library/std/src/sys_common/mod.rs +++ b/library/std/src/sys_common/mod.rs @@ -11,7 +11,7 @@ //! This is because `sys_common` not only contains platform-independent code, //! but also code that is shared between the different platforms in `sys`. //! Ideally all that shared code should be moved to `sys::common`, -//! and the dependencies between `std`, `sys_common` and `sys` all would form a dag. +//! and the dependencies between `std`, `sys_common` and `sys` all would form a DAG. //! Progress on this is tracked in #84187. #![allow(missing_docs)] From 28612748f61767c20c93da45156fc4ebde604dc1 Mon Sep 17 00:00:00 2001 From: Marijn Schouten Date: Fri, 11 Jul 2025 05:03:22 +0000 Subject: [PATCH 20/27] x: clippy fixes --- src/tools/x/src/main.rs | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/src/tools/x/src/main.rs b/src/tools/x/src/main.rs index b288cfcd5be9c..8c5735014df7e 100644 --- a/src/tools/x/src/main.rs +++ b/src/tools/x/src/main.rs @@ -89,7 +89,7 @@ fn exec_or_status(command: &mut Command) -> io::Result { fn handle_result(result: io::Result, cmd: Command) { match result { Err(error) => { - eprintln!("Failed to invoke `{:?}`: {}", cmd, error); + eprintln!("Failed to invoke `{cmd:?}`: {error}"); } Ok(status) => { process::exit(status.code().unwrap_or(1)); @@ -98,13 +98,10 @@ fn handle_result(result: io::Result, cmd: Command) { } fn main() { - match env::args().skip(1).next().as_deref() { - Some("--wrapper-version") => { - let version = env!("CARGO_PKG_VERSION"); - println!("{}", version); - return; - } - _ => {} + if env::args().nth(1).is_some_and(|s| s == "--wrapper-version") { + let version = env!("CARGO_PKG_VERSION"); + println!("{version}"); + return; } let current = match env::current_dir() { Ok(dir) => dir, From b87a1b1297c2786e49133e274c2e9f7b793320e0 Mon Sep 17 00:00:00 2001 From: Marijn Schouten Date: Fri, 11 Jul 2025 05:14:24 +0000 Subject: [PATCH 21/27] x: move to edition 2024 --- src/tools/x/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/x/Cargo.toml b/src/tools/x/Cargo.toml index 84a42ca36ef1c..c59f5ff52a0f5 100644 --- a/src/tools/x/Cargo.toml +++ b/src/tools/x/Cargo.toml @@ -2,5 +2,5 @@ name = "x" version = "0.1.1" description = "Run x.py slightly more conveniently" -edition = "2021" +edition = "2024" publish = false From dcf965d65271c76b3cb73e53b91147905f811f34 Mon Sep 17 00:00:00 2001 From: Marijn Schouten Date: Fri, 11 Jul 2025 05:29:05 +0000 Subject: [PATCH 22/27] x: use let-else --- src/tools/x/src/main.rs | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/tools/x/src/main.rs b/src/tools/x/src/main.rs index 8c5735014df7e..93167141d34dd 100644 --- a/src/tools/x/src/main.rs +++ b/src/tools/x/src/main.rs @@ -19,15 +19,14 @@ const PYTHON2: &str = "python2"; const PYTHON3: &str = "python3"; fn python() -> &'static str { - let val = match env::var_os("PATH") { - Some(val) => val, - None => return PYTHON, + let Some(path) = env::var_os("PATH") else { + return PYTHON; }; let mut python2 = false; let mut python3 = false; - for dir in env::split_paths(&val) { + for dir in env::split_paths(&path) { // `python` should always take precedence over python2 / python3 if it exists if dir.join(PYTHON).with_extension(EXE_EXTENSION).exists() { return PYTHON; @@ -103,6 +102,7 @@ fn main() { println!("{version}"); return; } + let current = match env::current_dir() { Ok(dir) => dir, Err(err) => { @@ -110,7 +110,6 @@ fn main() { process::exit(1); } }; - for dir in current.ancestors() { let candidate = dir.join("x.py"); if candidate.exists() { From 011d4aa81f1d20b4923a01c7162caa5f0042b8ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Mi=C4=85sko?= Date: Fri, 11 Jul 2025 08:10:16 +0200 Subject: [PATCH 23/27] Call `get_switch_int_data` on a block with SwitchInt terminator Fix a mix-up of a block with its predecessors in handling of SwitchInt edge effects for backward analysis. Note that this functionality is currently unused, so change has no practical impact. --- compiler/rustc_mir_dataflow/src/framework/direction.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_mir_dataflow/src/framework/direction.rs b/compiler/rustc_mir_dataflow/src/framework/direction.rs index cb647476db8f3..bba652656dd2f 100644 --- a/compiler/rustc_mir_dataflow/src/framework/direction.rs +++ b/compiler/rustc_mir_dataflow/src/framework/direction.rs @@ -113,7 +113,7 @@ impl Direction for Backward { } mir::TerminatorKind::SwitchInt { ref targets, ref discr } => { - if let Some(mut data) = analysis.get_switch_int_data(block, discr) { + if let Some(mut data) = analysis.get_switch_int_data(pred, discr) { let mut tmp = analysis.bottom_value(body); for &value in &body.basic_blocks.switch_sources()[&(block, pred)] { tmp.clone_from(exit_state); From ba3b7a7d9c5908633c26145e78166b0d97e518ad Mon Sep 17 00:00:00 2001 From: Marijn Schouten Date: Fri, 11 Jul 2025 07:15:20 +0000 Subject: [PATCH 24/27] build-helper: clippy fixes --- src/build_helper/src/ci.rs | 2 +- src/build_helper/src/git.rs | 32 ++++++++++++++++---------------- src/build_helper/src/metrics.rs | 2 +- src/build_helper/src/util.rs | 15 +++++++-------- 4 files changed, 25 insertions(+), 26 deletions(-) diff --git a/src/build_helper/src/ci.rs b/src/build_helper/src/ci.rs index 9d114c70a671b..b5e70eb84cc6c 100644 --- a/src/build_helper/src/ci.rs +++ b/src/build_helper/src/ci.rs @@ -9,7 +9,7 @@ pub enum CiEnv { impl CiEnv { /// Obtains the current CI environment. pub fn current() -> CiEnv { - if std::env::var("GITHUB_ACTIONS").map_or(false, |e| e == "true") { + if std::env::var("GITHUB_ACTIONS").is_ok_and(|e| e == "true") { CiEnv::GitHubActions } else { CiEnv::None diff --git a/src/build_helper/src/git.rs b/src/build_helper/src/git.rs index 9d1195aadf848..cbefb836c0044 100644 --- a/src/build_helper/src/git.rs +++ b/src/build_helper/src/git.rs @@ -13,7 +13,7 @@ pub struct GitConfig<'a> { pub fn output_result(cmd: &mut Command) -> Result { let output = match cmd.stderr(Stdio::inherit()).output() { Ok(status) => status, - Err(e) => return Err(format!("failed to run command: {:?}: {}", cmd, e)), + Err(e) => return Err(format!("failed to run command: {cmd:?}: {e}")), }; if !output.status.success() { return Err(format!( @@ -62,22 +62,22 @@ pub enum PathFreshness { /// The function behaves differently in CI and outside CI. /// /// - Outside CI, we want to find out if `target_paths` were modified in some local commit on -/// top of the latest upstream commit that is available in local git history. -/// If not, we try to find the most recent upstream commit (which we assume are commits -/// made by bors) that modified `target_paths`. -/// We don't want to simply take the latest master commit to avoid changing the output of -/// this function frequently after rebasing on the latest master branch even if `target_paths` -/// were not modified upstream in the meantime. In that case we would be redownloading CI -/// artifacts unnecessarily. +/// top of the latest upstream commit that is available in local git history. +/// If not, we try to find the most recent upstream commit (which we assume are commits +/// made by bors) that modified `target_paths`. +/// We don't want to simply take the latest master commit to avoid changing the output of +/// this function frequently after rebasing on the latest master branch even if `target_paths` +/// were not modified upstream in the meantime. In that case we would be redownloading CI +/// artifacts unnecessarily. /// /// - In CI, we use a shallow clone of depth 2, i.e., we fetch only a single parent commit -/// (which will be the most recent bors merge commit) and do not have access -/// to the full git history. Luckily, we only need to distinguish between two situations: -/// 1) The current PR made modifications to `target_paths`. -/// In that case, a build is typically necessary. -/// 2) The current PR did not make modifications to `target_paths`. -/// In that case we simply take the latest upstream commit, because on CI there is no need to avoid -/// redownloading. +/// (which will be the most recent bors merge commit) and do not have access +/// to the full git history. Luckily, we only need to distinguish between two situations: +/// 1) The current PR made modifications to `target_paths`. +/// In that case, a build is typically necessary. +/// 2) The current PR did not make modifications to `target_paths`. +/// In that case we simply take the latest upstream commit, because on CI there is no need to avoid +/// redownloading. pub fn check_path_modifications( git_dir: &Path, config: &GitConfig<'_>, @@ -232,7 +232,7 @@ pub fn get_closest_upstream_commit( "--author-date-order", &format!("--author={}", config.git_merge_commit_email), "-n1", - &base, + base, ]); let output = output_result(&mut git)?.trim().to_owned(); diff --git a/src/build_helper/src/metrics.rs b/src/build_helper/src/metrics.rs index 8b82e62a32770..07157e364158d 100644 --- a/src/build_helper/src/metrics.rs +++ b/src/build_helper/src/metrics.rs @@ -141,7 +141,7 @@ impl BuildStep { } => { let full_name = format!("{parent_name}-{kind}"); let children: Vec<_> = - children.into_iter().filter_map(|s| parse(s, &full_name)).collect(); + children.iter().filter_map(|s| parse(s, &full_name)).collect(); let children_duration = children.iter().map(|c| c.duration).sum::(); Some(BuildStep { r#type: kind.to_string(), diff --git a/src/build_helper/src/util.rs b/src/build_helper/src/util.rs index 80dd6813d136e..a8355f774e9d1 100644 --- a/src/build_helper/src/util.rs +++ b/src/build_helper/src/util.rs @@ -18,29 +18,28 @@ macro_rules! exit { pub fn detail_exit(code: i32, is_test: bool) -> ! { // if in test and code is an error code, panic with status code provided if is_test { - panic!("status code: {}", code); + panic!("status code: {code}"); } else { - // otherwise,exit with provided status code + // otherwise, exit with provided status code std::process::exit(code); } } pub fn fail(s: &str) -> ! { - eprintln!("\n\n{}\n\n", s); + eprintln!("\n\n{s}\n\n"); detail_exit(1, cfg!(test)); } pub fn try_run(cmd: &mut Command, print_cmd_on_fail: bool) -> Result<(), ()> { let status = match cmd.status() { Ok(status) => status, - Err(e) => fail(&format!("failed to execute command: {:?}\nerror: {}", cmd, e)), + Err(e) => fail(&format!("failed to execute command: {cmd:?}\nerror: {e}")), }; if !status.success() { if print_cmd_on_fail { println!( - "\n\ncommand did not execute successfully: {:?}\n\ - expected success, got: {}\n\n", - cmd, status + "\n\ncommand did not execute successfully: {cmd:?}\n\ + expected success, got: {status}\n\n" ); } Err(()) @@ -60,7 +59,7 @@ pub fn parse_gitmodules(target_dir: &Path) -> Vec { for line in BufReader::new(file).lines().map_while(Result::ok) { let line = line.trim(); if line.starts_with("path") { - let actual_path = line.split(' ').last().expect("Couldn't get value of path"); + let actual_path = line.split(' ').next_back().expect("Couldn't get value of path"); submodules_paths.push(actual_path.to_owned()); } } From 39f7707feac629defbd5a0cc9e2a1f7c18e843ea Mon Sep 17 00:00:00 2001 From: Jubilee Young Date: Wed, 9 Jul 2025 20:53:13 -0700 Subject: [PATCH 25/27] compiler: comment on some call-related codegen fn in cg_ssa Partially documents the situation due to LLVM CFI. --- .../rustc_codegen_ssa/src/traits/builder.rs | 23 ++++++++++++++++++- .../rustc_codegen_ssa/src/traits/intrinsic.rs | 8 ++++++- 2 files changed, 29 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_codegen_ssa/src/traits/builder.rs b/compiler/rustc_codegen_ssa/src/traits/builder.rs index 9d367748c2a8a..829b8899398ab 100644 --- a/compiler/rustc_codegen_ssa/src/traits/builder.rs +++ b/compiler/rustc_codegen_ssa/src/traits/builder.rs @@ -555,12 +555,33 @@ pub trait BuilderMethods<'a, 'tcx>: /// Called for `StorageDead` fn lifetime_end(&mut self, ptr: Self::Value, size: Size); + /// "Finally codegen the call" + /// + /// ## Arguments + /// + /// The `fn_attrs`, `fn_abi`, and `instance` arguments are Options because they are advisory. + /// They relate to optional codegen enhancements like LLVM CFI, and do not affect ABI per se. + /// Any ABI-related transformations should be handled by different, earlier stages of codegen. + /// For instance, in the caller of `BuilderMethods::call`. + /// + /// This means that a codegen backend which disregards `fn_attrs`, `fn_abi`, and `instance` + /// should still do correct codegen, and code should not be miscompiled if they are omitted. + /// It is not a miscompilation in this sense if it fails to run under CFI, other sanitizers, or + /// in the context of other compiler-enhanced security features. + /// + /// The typical case that they are None is during the codegen of intrinsics and lang-items, + /// as those are "fake functions" with only a trivial ABI if any, et cetera. + /// + /// ## Return + /// + /// Must return the value the function will return so it can be written to the destination, + /// assuming the function does not explicitly pass the destination as a pointer in `args`. fn call( &mut self, llty: Self::Type, fn_attrs: Option<&CodegenFnAttrs>, fn_abi: Option<&FnAbi<'tcx, Ty<'tcx>>>, - llfn: Self::Value, + fn_val: Self::Value, args: &[Self::Value], funclet: Option<&Self::Funclet>, instance: Option>, diff --git a/compiler/rustc_codegen_ssa/src/traits/intrinsic.rs b/compiler/rustc_codegen_ssa/src/traits/intrinsic.rs index 7d0c6be4c650d..c5ecf43046c74 100644 --- a/compiler/rustc_codegen_ssa/src/traits/intrinsic.rs +++ b/compiler/rustc_codegen_ssa/src/traits/intrinsic.rs @@ -6,16 +6,22 @@ use crate::mir::operand::OperandRef; use crate::mir::place::PlaceRef; pub trait IntrinsicCallBuilderMethods<'tcx>: BackendTypes { + /// Higher-level interface to emitting calls to intrinsics + /// /// Remember to add all intrinsics here, in `compiler/rustc_hir_analysis/src/check/mod.rs`, /// and in `library/core/src/intrinsics.rs`; if you need access to any LLVM intrinsics, /// add them to `compiler/rustc_codegen_llvm/src/context.rs`. /// Returns `Err` if another instance should be called instead. This is used to invoke /// intrinsic default bodies in case an intrinsic is not implemented by the backend. + /// + /// NOTE: allowed to call [`BuilderMethods::call`] + /// + /// [`BuilderMethods::call`]: super::builder::BuilderMethods::call fn codegen_intrinsic_call( &mut self, instance: ty::Instance<'tcx>, args: &[OperandRef<'tcx, Self::Value>], - result: PlaceRef<'tcx, Self::Value>, + result_dest: PlaceRef<'tcx, Self::Value>, span: Span, ) -> Result<(), ty::Instance<'tcx>>; From 5b6d661039116ea573652393938061a9a2a2c586 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Mi=C4=85sko?= Date: Fri, 11 Jul 2025 08:43:16 +0200 Subject: [PATCH 26/27] Remove support for SwitchInt edge effects in backward dataflow analyses Those effects are untested and unused. Remove them along with the implementation of `BasicBlocks::switch_sources`. --- compiler/rustc_middle/src/mir/basic_blocks.rs | 40 +------------------ .../src/framework/direction.rs | 15 +++---- 2 files changed, 7 insertions(+), 48 deletions(-) diff --git a/compiler/rustc_middle/src/mir/basic_blocks.rs b/compiler/rustc_middle/src/mir/basic_blocks.rs index d0dbf64dc5959..0d2e23609ce35 100644 --- a/compiler/rustc_middle/src/mir/basic_blocks.rs +++ b/compiler/rustc_middle/src/mir/basic_blocks.rs @@ -1,6 +1,5 @@ use std::sync::OnceLock; -use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::graph; use rustc_data_structures::graph::dominators::{Dominators, dominators}; use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; @@ -10,7 +9,7 @@ use rustc_serialize::{Decodable, Decoder, Encodable, Encoder}; use smallvec::SmallVec; use crate::mir::traversal::Postorder; -use crate::mir::{BasicBlock, BasicBlockData, START_BLOCK, Terminator, TerminatorKind}; +use crate::mir::{BasicBlock, BasicBlockData, START_BLOCK}; #[derive(Clone, TyEncodable, TyDecodable, Debug, HashStable, TypeFoldable, TypeVisitable)] pub struct BasicBlocks<'tcx> { @@ -21,15 +20,6 @@ pub struct BasicBlocks<'tcx> { // Typically 95%+ of basic blocks have 4 or fewer predecessors. type Predecessors = IndexVec>; -/// Each `(target, switch)` entry in the map contains a list of switch values -/// that lead to a `target` block from a `switch` block. -/// -/// Note: this type is currently never instantiated, because it's only used for -/// `BasicBlocks::switch_sources`, which is only called by backwards analyses -/// that do `SwitchInt` handling, and we don't have any of those, not even in -/// tests. See #95120 and #94576. -type SwitchSources = FxHashMap<(BasicBlock, BasicBlock), SmallVec<[SwitchTargetValue; 1]>>; - #[derive(Debug, Clone, Copy)] pub enum SwitchTargetValue { // A normal switch value. @@ -41,7 +31,6 @@ pub enum SwitchTargetValue { #[derive(Clone, Default, Debug)] struct Cache { predecessors: OnceLock, - switch_sources: OnceLock, reverse_postorder: OnceLock>, dominators: OnceLock>, } @@ -86,33 +75,6 @@ impl<'tcx> BasicBlocks<'tcx> { }) } - /// Returns info about switch values that lead from one block to another - /// block. See `SwitchSources`. - #[inline] - pub fn switch_sources(&self) -> &SwitchSources { - self.cache.switch_sources.get_or_init(|| { - let mut switch_sources: SwitchSources = FxHashMap::default(); - for (bb, data) in self.basic_blocks.iter_enumerated() { - if let Some(Terminator { - kind: TerminatorKind::SwitchInt { targets, .. }, .. - }) = &data.terminator - { - for (value, target) in targets.iter() { - switch_sources - .entry((target, bb)) - .or_default() - .push(SwitchTargetValue::Normal(value)); - } - switch_sources - .entry((targets.otherwise(), bb)) - .or_default() - .push(SwitchTargetValue::Otherwise); - } - } - switch_sources - }) - } - /// Returns mutable reference to basic blocks. Invalidates CFG cache. #[inline] pub fn as_mut(&mut self) -> &mut IndexVec> { diff --git a/compiler/rustc_mir_dataflow/src/framework/direction.rs b/compiler/rustc_mir_dataflow/src/framework/direction.rs index bba652656dd2f..79c0db7d72831 100644 --- a/compiler/rustc_mir_dataflow/src/framework/direction.rs +++ b/compiler/rustc_mir_dataflow/src/framework/direction.rs @@ -1,5 +1,6 @@ use std::ops::RangeInclusive; +use rustc_middle::bug; use rustc_middle::mir::{ self, BasicBlock, CallReturnPlaces, Location, SwitchTargetValue, TerminatorEdges, }; @@ -112,15 +113,11 @@ impl Direction for Backward { propagate(pred, &tmp); } - mir::TerminatorKind::SwitchInt { ref targets, ref discr } => { - if let Some(mut data) = analysis.get_switch_int_data(pred, discr) { - let mut tmp = analysis.bottom_value(body); - for &value in &body.basic_blocks.switch_sources()[&(block, pred)] { - tmp.clone_from(exit_state); - analysis - .apply_switch_int_edge_effect(&mut data, &mut tmp, value, targets); - propagate(pred, &tmp); - } + mir::TerminatorKind::SwitchInt { ref discr, .. } => { + if let Some(_data) = analysis.get_switch_int_data(pred, discr) { + bug!( + "SwitchInt edge effects are unsupported in backward dataflow analyses" + ); } else { propagate(pred, exit_state) } From 3ffd47d1aa0376cf86b8ddd965a2a7cfb39e220a Mon Sep 17 00:00:00 2001 From: Jens Reidel Date: Fri, 11 Jul 2025 14:56:01 +0200 Subject: [PATCH 27/27] Add a comment explaining the split Signed-off-by: Jens Reidel --- tests/ui/codegen/duplicated-path-in-error.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/ui/codegen/duplicated-path-in-error.rs b/tests/ui/codegen/duplicated-path-in-error.rs index 1852a6301b55f..0005ed09800d8 100644 --- a/tests/ui/codegen/duplicated-path-in-error.rs +++ b/tests/ui/codegen/duplicated-path-in-error.rs @@ -6,6 +6,9 @@ // This test ensures that the error of the "not found dylib" doesn't duplicate // the path of the dylib. +// +// glibc and musl have different dlopen error messages, so the expected error +// message differs between the two. fn main() {}