From 11f6cb70d39accba3e9f5de2473fdcd808d188aa Mon Sep 17 00:00:00 2001 From: Pavel Grigorenko Date: Mon, 23 Jun 2025 23:41:33 +0300 Subject: [PATCH 01/13] 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 2cbb727078577..bfef9d9715cfd 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 a6ae49d280873..360c65528810f 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, ExportName { .. } => Yes, 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 939f4a6fde705..f2a573e5ead70 100644 --- a/compiler/rustc_attr_parsing/src/context.rs +++ b/compiler/rustc_attr_parsing/src/context.rs @@ -39,7 +39,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}; @@ -145,6 +145,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 67b68e77d2b72..f058e71f11fee 100644 --- a/compiler/rustc_parse/src/validate_attr.rs +++ b/compiler/rustc_parse/src/validate_attr.rs @@ -279,6 +279,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 9e4e78c1db68e..f41220696ee85 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, .. }) => { @@ -291,7 +291,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 a9306772d1d621cc6a92428e28e5a2838e640eae Mon Sep 17 00:00:00 2001 From: Pavel Grigorenko Date: Tue, 24 Jun 2025 00:18:37 +0300 Subject: [PATCH 02/13] 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 bfef9d9715cfd..7072fa6ac6f60 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 360c65528810f..5197880aec994 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, ExportName { .. } => Yes, 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 f2a573e5ead70..55da11c3a5df1 100644 --- a/compiler/rustc_attr_parsing/src/context.rs +++ b/compiler/rustc_attr_parsing/src/context.rs @@ -39,7 +39,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}; @@ -146,6 +148,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 f058e71f11fee..2d63d3e796e42 100644 --- a/compiler/rustc_parse/src/validate_attr.rs +++ b/compiler/rustc_parse/src/validate_attr.rs @@ -279,6 +279,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 f41220696ee85..0a471cefa2f30 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); } @@ -289,7 +290,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 dba8b97932b6a347e73c1b9123a10c1c343f3f74 Mon Sep 17 00:00:00 2001 From: Pavel Grigorenko Date: Tue, 24 Jun 2025 00:22:09 +0300 Subject: [PATCH 03/13] 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 7072fa6ac6f60..28b3ccdc7c3a5 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 5197880aec994..a144e2921e0ba 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, ExportName { .. } => Yes, Ignore { .. } => No, 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 55da11c3a5df1..fee7a3b44219b 100644 --- a/compiler/rustc_attr_parsing/src/context.rs +++ b/compiler/rustc_attr_parsing/src/context.rs @@ -40,7 +40,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}; @@ -149,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 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 2d63d3e796e42..5623dfe170751 100644 --- a/compiler/rustc_parse/src/validate_attr.rs +++ b/compiler/rustc_parse/src/validate_attr.rs @@ -280,6 +280,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 0a471cefa2f30..2a8f228434cfe 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); } @@ -290,7 +291,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 808577a1a66ee4ae734e6e6809c1cc827e91509a Mon Sep 17 00:00:00 2001 From: Pavel Grigorenko Date: Tue, 24 Jun 2025 00:27:30 +0300 Subject: [PATCH 04/13] 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 28b3ccdc7c3a5..54090350b1ed0 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 a144e2921e0ba..cbcd807a294a0 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 fee7a3b44219b..699b36c0c1fe1 100644 --- a/compiler/rustc_attr_parsing/src/context.rs +++ b/compiler/rustc_attr_parsing/src/context.rs @@ -40,7 +40,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; @@ -145,6 +145,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 5623dfe170751..597a4fc331408 100644 --- a/compiler/rustc_parse/src/validate_attr.rs +++ b/compiler/rustc_parse/src/validate_attr.rs @@ -281,6 +281,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 2a8f228434cfe..9e8c0a1cd9620 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), @@ -289,9 +290,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 f55c37cbd1a1e8cf23057e2c73a7699fe58d47ce Mon Sep 17 00:00:00 2001 From: Pavel Grigorenko Date: Tue, 24 Jun 2025 00:51:16 +0300 Subject: [PATCH 05/13] 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 54090350b1ed0..6d39bab3f3fe9 100644 --- a/compiler/rustc_attr_data_structures/src/attributes.rs +++ b/compiler/rustc_attr_data_structures/src/attributes.rs @@ -344,6 +344,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 cbcd807a294a0..f0f18d397aadf 100644 --- a/compiler/rustc_attr_data_structures/src/encode_cross_crate.rs +++ b/compiler/rustc_attr_data_structures/src/encode_cross_crate.rs @@ -54,6 +54,7 @@ impl AttributeKind { Stability { .. } => Yes, 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 699b36c0c1fe1..356263b1fed2a 100644 --- a/compiler/rustc_attr_parsing/src/context.rs +++ b/compiler/rustc_attr_parsing/src/context.rs @@ -41,7 +41,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}; @@ -160,6 +160,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 597a4fc331408..57ec112a6a859 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_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 9e8c0a1cd9620..5231ce273c9f4 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); } @@ -330,9 +333,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 @@ -2508,7 +2508,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()) @@ -2518,7 +2518,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 2f7bf50ead5fd..b593527748b38 100644 --- a/tests/ui/attributes/malformed-attrs.stderr +++ b/tests/ui/attributes/malformed-attrs.stderr @@ -122,12 +122,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 | @@ -546,6 +540,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 a0d827905a54ece3a5a3d0f6eeddd4946b102db1 Mon Sep 17 00:00:00 2001 From: Pavel Grigorenko Date: Tue, 24 Jun 2025 01:29:44 +0300 Subject: [PATCH 06/13] 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 6d39bab3f3fe9..b8735a25a7ba4 100644 --- a/compiler/rustc_attr_data_structures/src/attributes.rs +++ b/compiler/rustc_attr_data_structures/src/attributes.rs @@ -331,6 +331,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 f0f18d397aadf..49a744ba49652 100644 --- a/compiler/rustc_attr_data_structures/src/encode_cross_crate.rs +++ b/compiler/rustc_attr_data_structures/src/encode_cross_crate.rs @@ -51,6 +51,7 @@ impl AttributeKind { RustcLayoutScalarValidRangeStart(..) => Yes, RustcObjectLifetimeDefault => No, SkipDuringMethodDispatch { .. } => No, + SpecializationTrait(..) => No, Stability { .. } => Yes, TargetFeature(..) => No, TrackCaller(..) => Yes, 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 356263b1fed2a..4457e6f1ab6e2 100644 --- a/compiler/rustc_attr_parsing/src/context.rs +++ b/compiler/rustc_attr_parsing/src/context.rs @@ -41,7 +41,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}; @@ -159,6 +159,7 @@ attribute_parsers!( Single>, Single>, 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 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 57ec112a6a859..3316cecf5c5d8 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_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 5231ce273c9f4..59b28375f2965 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 363f4623fda2f16ce669ae0a469a821a544723f0 Mon Sep 17 00:00:00 2001 From: Pavel Grigorenko Date: Tue, 24 Jun 2025 01:41:19 +0300 Subject: [PATCH 07/13] 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 b8735a25a7ba4..ce5d9868d9e64 100644 --- a/compiler/rustc_attr_data_structures/src/attributes.rs +++ b/compiler/rustc_attr_data_structures/src/attributes.rs @@ -350,6 +350,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 49a744ba49652..a24aa0c7a1dbf 100644 --- a/compiler/rustc_attr_data_structures/src/encode_cross_crate.rs +++ b/compiler/rustc_attr_data_structures/src/encode_cross_crate.rs @@ -56,6 +56,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 4457e6f1ab6e2..25292a691cee8 100644 --- a/compiler/rustc_attr_parsing/src/context.rs +++ b/compiler/rustc_attr_parsing/src/context.rs @@ -42,6 +42,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}; @@ -162,6 +163,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 3316cecf5c5d8..11067423367f1 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_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 59b28375f2965..6fcfdb22f67a0 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 c984bafc3f71e585e135cb1ca312b4c5b699ac60 Mon Sep 17 00:00:00 2001 From: Pavel Grigorenko Date: Tue, 24 Jun 2025 01:49:26 +0300 Subject: [PATCH 08/13] 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 ce5d9868d9e64..1af45a2bd11da 100644 --- a/compiler/rustc_attr_data_structures/src/attributes.rs +++ b/compiler/rustc_attr_data_structures/src/attributes.rs @@ -282,6 +282,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 a24aa0c7a1dbf..07752398fee1b 100644 --- a/compiler/rustc_attr_data_structures/src/encode_cross_crate.rs +++ b/compiler/rustc_attr_data_structures/src/encode_cross_crate.rs @@ -36,6 +36,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 25292a691cee8..db711ce838692 100644 --- a/compiler/rustc_attr_parsing/src/context.rs +++ b/compiler/rustc_attr_parsing/src/context.rs @@ -41,7 +41,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; @@ -154,6 +154,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 11067423367f1..0340734b8b2ab 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::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 6fcfdb22f67a0..c28a5ea6c7d7c 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); } @@ -259,7 +262,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, @@ -829,7 +831,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 @@ -837,13 +839,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 b593527748b38..9927497bb6050 100644 --- a/tests/ui/attributes/malformed-attrs.stderr +++ b/tests/ui/attributes/malformed-attrs.stderr @@ -122,12 +122,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 | @@ -531,6 +525,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 `non_exhaustive` attribute input --> $DIR/malformed-attrs.rs:197:1 | 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 2c158b3a2a884da084850def15fafa6c9fa7af1b Mon Sep 17 00:00:00 2001 From: Pavel Grigorenko Date: Tue, 24 Jun 2025 01:58:53 +0300 Subject: [PATCH 09/13] 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 1af45a2bd11da..37f92a1dec680 100644 --- a/compiler/rustc_attr_data_structures/src/attributes.rs +++ b/compiler/rustc_attr_data_structures/src/attributes.rs @@ -260,6 +260,9 @@ pub enum AttributeKind { span: 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 07752398fee1b..451299f5ae54d 100644 --- a/compiler/rustc_attr_data_structures/src/encode_cross_crate.rs +++ b/compiler/rustc_attr_data_structures/src/encode_cross_crate.rs @@ -30,6 +30,7 @@ impl AttributeKind { DoNotImplementViaObject(..) => No, DocComment { .. } => Yes, ExportName { .. } => Yes, + 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 db711ce838692..06dda337c5ee4 100644 --- a/compiler/rustc_attr_parsing/src/context.rs +++ b/compiler/rustc_attr_parsing/src/context.rs @@ -41,8 +41,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}; @@ -153,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 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 0340734b8b2ab..df43a972f0e59 100644 --- a/compiler/rustc_parse/src/validate_attr.rs +++ b/compiler/rustc_parse/src/validate_attr.rs @@ -286,6 +286,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 c28a5ea6c7d7c..7919fcc80734b 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); } @@ -367,7 +370,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 9927497bb6050..cd75a7a0fa3c3 100644 --- a/tests/ui/attributes/malformed-attrs.stderr +++ b/tests/ui/attributes/malformed-attrs.stderr @@ -122,12 +122,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 `ffi_pure` attribute input --> $DIR/malformed-attrs.rs:165:5 | @@ -534,6 +528,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 `non_exhaustive` attribute input --> $DIR/malformed-attrs.rs:197:1 | From 38d1efdb6873254885d34f2cab79b6aa619c0444 Mon Sep 17 00:00:00 2001 From: Pavel Grigorenko Date: Tue, 24 Jun 2025 02:06:57 +0300 Subject: [PATCH 10/13] 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 37f92a1dec680..ed1929ee230df 100644 --- a/compiler/rustc_attr_data_structures/src/attributes.rs +++ b/compiler/rustc_attr_data_structures/src/attributes.rs @@ -313,6 +313,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 451299f5ae54d..51123059c299a 100644 --- a/compiler/rustc_attr_data_structures/src/encode_cross_crate.rs +++ b/compiler/rustc_attr_data_structures/src/encode_cross_crate.rs @@ -45,6 +45,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 06dda337c5ee4..44fcdc6ea90e4 100644 --- a/compiler/rustc_attr_parsing/src/context.rs +++ b/compiler/rustc_attr_parsing/src/context.rs @@ -41,8 +41,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}; @@ -160,6 +160,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 df43a972f0e59..1c980289fc171 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_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 7919fcc80734b..9c71f97c661cd 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 7ecc5fbc53d7b0497f67684af909a57ce44e12da Mon Sep 17 00:00:00 2001 From: Pavel Grigorenko Date: Tue, 24 Jun 2025 23:41:07 +0300 Subject: [PATCH 11/13] 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 d22b4c715c9b3609b486650cb9fc6908c779b47c Mon Sep 17 00:00:00 2001 From: Pavel Grigorenko Date: Tue, 24 Jun 2025 23:53:39 +0300 Subject: [PATCH 12/13] 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 ed1929ee230df..49fa74115afa3 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 51123059c299a..61215c79bbea2 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 44fcdc6ea90e4..078f8b0ce8508 100644 --- a/compiler/rustc_attr_parsing/src/context.rs +++ b/compiler/rustc_attr_parsing/src/context.rs @@ -40,9 +40,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}; @@ -145,6 +146,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 1c980289fc171..84775d61647e7 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::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 9c71f97c661cd..de255cd94c043 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); } @@ -309,9 +312,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) } @@ -1491,11 +1491,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 da5ea0a19e25b6495e0920ac0b2a915c69af3fdb Mon Sep 17 00:00:00 2001 From: Pavel Grigorenko Date: Wed, 25 Jun 2025 00:24:14 +0300 Subject: [PATCH 13/13] 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 49fa74115afa3..e3894dfa430ba 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 61215c79bbea2..47fe09477cecf 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 078f8b0ce8508..f85e006488beb 100644 --- a/compiler/rustc_attr_parsing/src/context.rs +++ b/compiler/rustc_attr_parsing/src/context.rs @@ -40,9 +40,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; @@ -148,6 +148,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 84775d61647e7..37bd00d48a82a 100644 --- a/compiler/rustc_parse/src/validate_attr.rs +++ b/compiler/rustc_parse/src/validate_attr.rs @@ -286,6 +286,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 de255cd94c043..c6ba526a4c9b6 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)) => {