From b2299e20b2c2a25254fb554ccc59a8b60fdc25e0 Mon Sep 17 00:00:00 2001 From: Dillon Amburgey Date: Tue, 8 Jul 2025 06:18:18 -0500 Subject: [PATCH 01/25] 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 02/25] 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 03/25] 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 04/25] 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 05/25] 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 06/25] 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 07/25] 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 08/25] 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 09/25] 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 10/25] 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 11/25] 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 12/25] 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 13/25] 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 14/25] 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 15/25] 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 16/25] 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 17/25] 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 18/25] =?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 19/25] 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 20/25] 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 21/25] 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 22/25] 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 23/25] 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 24/25] 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 25/25] 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) }