diff options
| author | Jonathan Brouwer <jonathantbrouwer@gmail.com> | 2025-07-11 12:01:11 +0200 |
|---|---|---|
| committer | Jonathan Brouwer <jonathantbrouwer@gmail.com> | 2025-07-12 17:48:50 +0200 |
| commit | ef82007ed7b7833e3efdec0d80712849048c5c1f (patch) | |
| tree | 76a8c855164384dd5daa3c36a99fff02aacc00c3 | |
| parent | 915e5352448afb3c24f89117468935283bc7d2cf (diff) | |
| download | rust-ef82007ed7b7833e3efdec0d80712849048c5c1f.tar.gz rust-ef82007ed7b7833e3efdec0d80712849048c5c1f.zip | |
Port `#[automatically_derived]` to the new attribute parsing infrastructure
Signed-off-by: Jonathan Brouwer <jonathantbrouwer@gmail.com>
| -rw-r--r-- | compiler/rustc_ast/src/attr/mod.rs | 5 | ||||
| -rw-r--r-- | compiler/rustc_attr_data_structures/src/attributes.rs | 3 | ||||
| -rw-r--r-- | compiler/rustc_attr_data_structures/src/encode_cross_crate.rs | 1 | ||||
| -rw-r--r-- | compiler/rustc_attr_parsing/src/attributes/lint_helpers.rs | 7 | ||||
| -rw-r--r-- | compiler/rustc_attr_parsing/src/context.rs | 5 | ||||
| -rw-r--r-- | compiler/rustc_hir/src/hir.rs | 6 | ||||
| -rw-r--r-- | compiler/rustc_lint/src/default_could_be_derived.rs | 3 | ||||
| -rw-r--r-- | compiler/rustc_lint/src/levels.rs | 2 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/ty/mod.rs | 4 | ||||
| -rw-r--r-- | compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs | 6 | ||||
| -rw-r--r-- | compiler/rustc_parse/src/validate_attr.rs | 1 | ||||
| -rw-r--r-- | compiler/rustc_passes/src/check_attr.rs | 14 | ||||
| -rw-r--r-- | compiler/rustc_passes/src/liveness.rs | 4 |
13 files changed, 48 insertions, 13 deletions
diff --git a/compiler/rustc_ast/src/attr/mod.rs b/compiler/rustc_ast/src/attr/mod.rs index 44865c493b3..4348a4bb120 100644 --- a/compiler/rustc_ast/src/attr/mod.rs +++ b/compiler/rustc_ast/src/attr/mod.rs @@ -217,6 +217,10 @@ impl AttributeExt for Attribute { _ => None, } } + + fn is_automatically_derived_attr(&self) -> bool { + self.has_name(sym::automatically_derived) + } } impl Attribute { @@ -810,6 +814,7 @@ pub trait AttributeExt: Debug { .iter() .any(|kind| self.has_name(*kind)) } + fn is_automatically_derived_attr(&self) -> bool; /// Returns the documentation and its kind if this is a doc comment or a sugared doc comment. /// * `///doc` returns `Some(("doc", CommentKind::Line))`. diff --git a/compiler/rustc_attr_data_structures/src/attributes.rs b/compiler/rustc_attr_data_structures/src/attributes.rs index f61efcf2388..41a9e8feaaf 100644 --- a/compiler/rustc_attr_data_structures/src/attributes.rs +++ b/compiler/rustc_attr_data_structures/src/attributes.rs @@ -207,6 +207,9 @@ pub enum AttributeKind { /// Represents `#[rustc_as_ptr]` (used by the `dangling_pointers_from_temporaries` lint). AsPtr(Span), + /// Represents `#[automatically_derived]` + AutomaticallyDerived(Span), + /// Represents `#[rustc_default_body_unstable]`. BodyStability { stability: DefaultBodyStability, 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 ad587523e03..b92f0ade3d3 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 { AllowIncoherentImpl(..) => No, AllowInternalUnstable(..) => Yes, AsPtr(..) => Yes, + AutomaticallyDerived(..) => Yes, BodyStability { .. } => No, CoherenceIsCore => No, Coinductive(..) => No, diff --git a/compiler/rustc_attr_parsing/src/attributes/lint_helpers.rs b/compiler/rustc_attr_parsing/src/attributes/lint_helpers.rs index 8ad98c8d1d4..0eceff53e8b 100644 --- a/compiler/rustc_attr_parsing/src/attributes/lint_helpers.rs +++ b/compiler/rustc_attr_parsing/src/attributes/lint_helpers.rs @@ -24,3 +24,10 @@ impl<S: Stage> NoArgsAttributeParser<S> for PassByValueParser { const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error; const CREATE: fn(Span) -> AttributeKind = AttributeKind::PassByValue; } + +pub(crate) struct AutomaticallyDerivedParser; +impl<S: Stage> NoArgsAttributeParser<S> for AutomaticallyDerivedParser { + const PATH: &[Symbol] = &[sym::automatically_derived]; + const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Warn; + const CREATE: fn(Span) -> AttributeKind = AttributeKind::AutomaticallyDerived; +} diff --git a/compiler/rustc_attr_parsing/src/context.rs b/compiler/rustc_attr_parsing/src/context.rs index cc10bb3098a..0b34fe0a592 100644 --- a/compiler/rustc_attr_parsing/src/context.rs +++ b/compiler/rustc_attr_parsing/src/context.rs @@ -27,7 +27,9 @@ use crate::attributes::link_attrs::{ ExportStableParser, FfiConstParser, FfiPureParser, LinkNameParser, LinkSectionParser, StdInternalSymbolParser, }; -use crate::attributes::lint_helpers::{AsPtrParser, PassByValueParser, PubTransparentParser}; +use crate::attributes::lint_helpers::{ + AsPtrParser, AutomaticallyDerivedParser, PassByValueParser, PubTransparentParser, +}; use crate::attributes::loop_match::{ConstContinueParser, LoopMatchParser}; use crate::attributes::must_use::MustUseParser; use crate::attributes::no_implicit_prelude::NoImplicitPreludeParser; @@ -153,6 +155,7 @@ attribute_parsers!( Single<TransparencyParser>, Single<WithoutArgs<AllowIncoherentImplParser>>, Single<WithoutArgs<AsPtrParser>>, + Single<WithoutArgs<AutomaticallyDerivedParser>>, Single<WithoutArgs<CoherenceIsCoreParser>>, Single<WithoutArgs<CoinductiveParser>>, Single<WithoutArgs<ColdParser>>, diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index 0f6f81d7964..f655a7e11f0 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -1304,6 +1304,7 @@ impl AttributeExt for Attribute { Attribute::Parsed(AttributeKind::DocComment { span, .. }) => *span, Attribute::Parsed(AttributeKind::MayDangle(span)) => *span, Attribute::Parsed(AttributeKind::Ignore { span, .. }) => *span, + Attribute::Parsed(AttributeKind::AutomaticallyDerived(span)) => *span, a => panic!("can't get the span of an arbitrary parsed attribute: {a:?}"), } } @@ -1334,6 +1335,11 @@ impl AttributeExt for Attribute { _ => None, } } + + fn is_automatically_derived_attr(&self) -> bool { + matches!(self, Attribute::Parsed(AttributeKind::AutomaticallyDerived(..))) + } + #[inline] fn doc_str_and_comment_kind(&self) -> Option<(Symbol, CommentKind)> { match &self { diff --git a/compiler/rustc_lint/src/default_could_be_derived.rs b/compiler/rustc_lint/src/default_could_be_derived.rs index 0bc772d081f..b5fc083a095 100644 --- a/compiler/rustc_lint/src/default_could_be_derived.rs +++ b/compiler/rustc_lint/src/default_could_be_derived.rs @@ -1,3 +1,4 @@ +use rustc_attr_data_structures::{AttributeKind, find_attr}; use rustc_data_structures::fx::FxHashMap; use rustc_errors::{Applicability, Diag}; use rustc_hir as hir; @@ -62,7 +63,7 @@ impl<'tcx> LateLintPass<'tcx> for DefaultCouldBeDerived { let hir::ImplItemKind::Fn(_sig, body_id) = impl_item.kind else { return }; let assoc = cx.tcx.associated_item(impl_item.owner_id); let parent = assoc.container_id(cx.tcx); - if cx.tcx.has_attr(parent, sym::automatically_derived) { + if find_attr!(cx.tcx.get_all_attrs(parent), AttributeKind::AutomaticallyDerived(..)) { // We don't care about what `#[derive(Default)]` produces in this lint. return; } diff --git a/compiler/rustc_lint/src/levels.rs b/compiler/rustc_lint/src/levels.rs index c72f8571153..16eeb89207b 100644 --- a/compiler/rustc_lint/src/levels.rs +++ b/compiler/rustc_lint/src/levels.rs @@ -644,7 +644,7 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> { ) { let sess = self.sess; for (attr_index, attr) in attrs.iter().enumerate() { - if attr.has_name(sym::automatically_derived) { + if attr.is_automatically_derived_attr() { self.insert( LintId::of(SINGLE_USE_LIFETIMES), LevelAndSource { diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index 0177a95498b..5dbdff76bee 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -28,7 +28,7 @@ use rustc_abi::{Align, FieldIdx, Integer, IntegerType, ReprFlags, ReprOptions, V use rustc_ast::expand::StrippedCfgItem; use rustc_ast::node_id::NodeMap; pub use rustc_ast_ir::{Movability, Mutability, try_visit}; -use rustc_attr_data_structures::AttributeKind; +use rustc_attr_data_structures::{AttributeKind, find_attr}; use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap, FxIndexSet}; use rustc_data_structures::intern::Interned; use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; @@ -2031,7 +2031,7 @@ impl<'tcx> TyCtxt<'tcx> { /// Check if the given `DefId` is `#\[automatically_derived\]`. pub fn is_automatically_derived(self, def_id: DefId) -> bool { - self.has_attr(def_id, sym::automatically_derived) + find_attr!(self.get_all_attrs(def_id), AttributeKind::AutomaticallyDerived(..)) } /// Looks up the span of `impl_did` if the impl is local; otherwise returns `Err` diff --git a/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs b/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs index 6d617d43c2a..91fcbb9390f 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs @@ -2,6 +2,7 @@ use core::ops::ControlFlow; use rustc_abi::{FieldIdx, VariantIdx}; use rustc_apfloat::Float; +use rustc_attr_data_structures::{AttributeKind, find_attr}; use rustc_data_structures::fx::FxHashSet; use rustc_errors::Diag; use rustc_hir as hir; @@ -15,7 +16,7 @@ use rustc_middle::ty::{ }; use rustc_middle::{mir, span_bug}; use rustc_span::def_id::DefId; -use rustc_span::{DUMMY_SP, Span, sym}; +use rustc_span::{DUMMY_SP, Span}; use rustc_trait_selection::traits::ObligationCause; use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt; use tracing::{debug, instrument, trace}; @@ -495,7 +496,8 @@ fn type_has_partial_eq_impl<'tcx>( let mut structural_peq = false; let mut impl_def_id = None; for def_id in tcx.non_blanket_impls_for_ty(partial_eq_trait_id, ty) { - automatically_derived = tcx.has_attr(def_id, sym::automatically_derived); + automatically_derived = + find_attr!(tcx.get_all_attrs(def_id), AttributeKind::AutomaticallyDerived(..)); impl_def_id = Some(def_id); } for _ in tcx.non_blanket_impls_for_ty(structural_partial_eq_trait_id, ty) { diff --git a/compiler/rustc_parse/src/validate_attr.rs b/compiler/rustc_parse/src/validate_attr.rs index bb5c1e0e653..3e80af82bef 100644 --- a/compiler/rustc_parse/src/validate_attr.rs +++ b/compiler/rustc_parse/src/validate_attr.rs @@ -316,6 +316,7 @@ pub fn check_builtin_meta_item( | sym::rustc_layout_scalar_valid_range_start | sym::rustc_layout_scalar_valid_range_end | sym::no_implicit_prelude + | sym::automatically_derived ) { return; } diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index 2c95fead9e8..0924d877263 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -152,6 +152,14 @@ impl<'tcx> CheckAttrVisitor<'tcx> { Attribute::Parsed(AttributeKind::Confusables { first_span, .. }) => { self.check_confusables(*first_span, target); } + Attribute::Parsed(AttributeKind::AutomaticallyDerived(attr_span)) => self + .check_generic_attr( + hir_id, + sym::automatically_derived, + *attr_span, + target, + Target::Impl, + ), Attribute::Parsed( AttributeKind::Stability { span, .. } | AttributeKind::ConstStability { span, .. }, @@ -335,9 +343,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> { [sym::should_panic, ..] => { self.check_generic_attr_unparsed(hir_id, attr, target, Target::Fn) } - [sym::automatically_derived, ..] => { - self.check_generic_attr_unparsed(hir_id, attr, target, Target::Impl) - } [sym::proc_macro, ..] => { self.check_proc_macro(hir_id, target, ProcMacroKind::FunctionLike) } @@ -2814,7 +2819,6 @@ fn check_invalid_crate_level_attr(tcx: TyCtxt<'_>, attrs: &[Attribute]) { // resolution for the attribute macro error. const ATTRS_TO_CHECK: &[Symbol] = &[ sym::macro_export, - sym::automatically_derived, sym::rustc_main, sym::derive, sym::test, @@ -2837,6 +2841,8 @@ fn check_invalid_crate_level_attr(tcx: TyCtxt<'_>, attrs: &[Attribute]) { (*first_attr_span, sym::repr) } else if let Attribute::Parsed(AttributeKind::Path(.., span)) = attr { (*span, sym::path) + } else if let Attribute::Parsed(AttributeKind::AutomaticallyDerived(span)) = attr { + (*span, sym::automatically_derived) } else { continue; }; diff --git a/compiler/rustc_passes/src/liveness.rs b/compiler/rustc_passes/src/liveness.rs index 3088e189c20..7350c6a5a82 100644 --- a/compiler/rustc_passes/src/liveness.rs +++ b/compiler/rustc_passes/src/liveness.rs @@ -97,7 +97,7 @@ use rustc_middle::query::Providers; use rustc_middle::span_bug; use rustc_middle::ty::{self, RootVariableMinCaptureList, Ty, TyCtxt}; use rustc_session::lint; -use rustc_span::{BytePos, Span, Symbol, sym}; +use rustc_span::{BytePos, Span, Symbol}; use tracing::{debug, instrument}; use self::LiveNodeKind::*; @@ -140,7 +140,7 @@ fn check_liveness(tcx: TyCtxt<'_>, def_id: LocalDefId) { // Don't run unused pass for #[derive()] let parent = tcx.local_parent(def_id); if let DefKind::Impl { .. } = tcx.def_kind(parent) - && tcx.has_attr(parent, sym::automatically_derived) + && find_attr!(tcx.get_all_attrs(parent), AttributeKind::AutomaticallyDerived(..)) { return; } |
