diff options
| author | Pavel Grigorenko <GrigorenkoPV@ya.ru> | 2025-06-15 16:59:11 +0300 |
|---|---|---|
| committer | Pavel Grigorenko <GrigorenkoPV@ya.ru> | 2025-07-04 00:07:56 +0300 |
| commit | ef4dece2cb52dd14dc4f37a8484fa440a447da14 (patch) | |
| tree | 510696ebfe3f236b74452512a430b2ed083e0911 | |
| parent | 35453a854c4e7eabbfcc4ac4f0095b26ee890dc1 (diff) | |
| download | rust-ef4dece2cb52dd14dc4f37a8484fa440a447da14.tar.gz rust-ef4dece2cb52dd14dc4f37a8484fa440a447da14.zip | |
Port `#[rustc_pass_by_value]` to the new attribute system
7 files changed, 24 insertions, 7 deletions
diff --git a/compiler/rustc_attr_data_structures/src/attributes.rs b/compiler/rustc_attr_data_structures/src/attributes.rs index 61ef31b8f9f..1744d394b90 100644 --- a/compiler/rustc_attr_data_structures/src/attributes.rs +++ b/compiler/rustc_attr_data_structures/src/attributes.rs @@ -284,6 +284,9 @@ pub enum AttributeKind { /// Represents `#[optimize(size|speed)]` Optimize(OptimizeAttr, Span), + /// Represents `#[rustc_pass_by_value]` (used by the `rustc_pass_by_value` lint). + PassByValue(Span), + /// Represents `#[rustc_pub_transparent]` (used by the `repr_transparent_external_private_fields` lint). PubTransparent(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 34638ff5540..af085bfc8ee 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 { Naked(..) => No, NoMangle(..) => No, Optimize(..) => No, + PassByValue(..) => Yes, PubTransparent(..) => Yes, Repr(..) => No, RustcLayoutScalarValidRangeEnd(..) => Yes, diff --git a/compiler/rustc_attr_parsing/src/attributes/lint_helpers.rs b/compiler/rustc_attr_parsing/src/attributes/lint_helpers.rs index 5437803d781..8ad98c8d1d4 100644 --- a/compiler/rustc_attr_parsing/src/attributes/lint_helpers.rs +++ b/compiler/rustc_attr_parsing/src/attributes/lint_helpers.rs @@ -17,3 +17,10 @@ impl<S: Stage> NoArgsAttributeParser<S> for PubTransparentParser { const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error; const CREATE: fn(Span) -> AttributeKind = AttributeKind::PubTransparent; } + +pub(crate) struct PassByValueParser; +impl<S: Stage> NoArgsAttributeParser<S> for PassByValueParser { + const PATH: &[Symbol] = &[sym::rustc_pass_by_value]; + const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error; + const CREATE: fn(Span) -> AttributeKind = AttributeKind::PassByValue; +} diff --git a/compiler/rustc_attr_parsing/src/context.rs b/compiler/rustc_attr_parsing/src/context.rs index bf8b1438df7..f060bef0ec5 100644 --- a/compiler/rustc_attr_parsing/src/context.rs +++ b/compiler/rustc_attr_parsing/src/context.rs @@ -23,7 +23,7 @@ use crate::attributes::confusables::ConfusablesParser; use crate::attributes::deprecation::DeprecationParser; use crate::attributes::inline::{InlineParser, RustcForceInlineParser}; use crate::attributes::link_attrs::{LinkNameParser, LinkSectionParser}; -use crate::attributes::lint_helpers::{AsPtrParser, PubTransparentParser}; +use crate::attributes::lint_helpers::{AsPtrParser, PassByValueParser, PubTransparentParser}; use crate::attributes::loop_match::{ConstContinueParser, LoopMatchParser}; use crate::attributes::must_use::MustUseParser; use crate::attributes::repr::{AlignParser, ReprParser}; @@ -142,6 +142,7 @@ attribute_parsers!( Single<WithoutArgs<LoopMatchParser>>, Single<WithoutArgs<MayDangleParser>>, Single<WithoutArgs<NoMangleParser>>, + Single<WithoutArgs<PassByValueParser>>, Single<WithoutArgs<PubTransparentParser>>, Single<WithoutArgs<TrackCallerParser>>, // tidy-alphabetical-end diff --git a/compiler/rustc_lint/src/pass_by_value.rs b/compiler/rustc_lint/src/pass_by_value.rs index d85618f664d..d3b3b55dd4c 100644 --- a/compiler/rustc_lint/src/pass_by_value.rs +++ b/compiler/rustc_lint/src/pass_by_value.rs @@ -1,8 +1,8 @@ +use rustc_attr_data_structures::{AttributeKind, find_attr}; use rustc_hir::def::Res; use rustc_hir::{self as hir, AmbigArg, GenericArg, PathSegment, QPath, TyKind}; use rustc_middle::ty; use rustc_session::{declare_lint_pass, declare_tool_lint}; -use rustc_span::sym; use crate::lints::PassByValueDiag; use crate::{LateContext, LateLintPass, LintContext}; @@ -45,14 +45,16 @@ impl<'tcx> LateLintPass<'tcx> for PassByValue { fn path_for_pass_by_value(cx: &LateContext<'_>, ty: &hir::Ty<'_>) -> Option<String> { if let TyKind::Path(QPath::Resolved(_, path)) = &ty.kind { match path.res { - Res::Def(_, def_id) if cx.tcx.has_attr(def_id, sym::rustc_pass_by_value) => { + Res::Def(_, def_id) + if find_attr!(cx.tcx.get_all_attrs(def_id), AttributeKind::PassByValue(_)) => + { let name = cx.tcx.item_ident(def_id); let path_segment = path.segments.last().unwrap(); return Some(format!("{}{}", name, gen_args(cx, path_segment))); } Res::SelfTyAlias { alias_to: did, is_trait_impl: false, .. } => { if let ty::Adt(adt, args) = cx.tcx.type_of(did).instantiate_identity().kind() { - if cx.tcx.has_attr(adt.did(), sym::rustc_pass_by_value) { + if find_attr!(cx.tcx.get_all_attrs(adt.did()), AttributeKind::PassByValue(_)) { return Some(cx.tcx.def_path_str_with_args(adt.did(), args)); } } diff --git a/compiler/rustc_parse/src/validate_attr.rs b/compiler/rustc_parse/src/validate_attr.rs index 4d64cdeb69a..1ca9ca84285 100644 --- a/compiler/rustc_parse/src/validate_attr.rs +++ b/compiler/rustc_parse/src/validate_attr.rs @@ -293,6 +293,7 @@ fn emit_malformed_attribute( | sym::rustc_force_inline | sym::rustc_confusables | sym::rustc_skip_during_method_dispatch + | sym::rustc_pass_by_value | 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 87d46e3e506..7bcd893969e 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -213,6 +213,9 @@ impl<'tcx> CheckAttrVisitor<'tcx> { Attribute::Parsed(AttributeKind::Used { span: attr_span, .. }) => { self.check_used(*attr_span, target, span); } + &Attribute::Parsed(AttributeKind::PassByValue(attr_span)) => { + self.check_pass_by_value(attr_span, span, target) + } Attribute::Unparsed(attr_item) => { style = Some(attr_item.style); match attr.path().as_slice() { @@ -275,7 +278,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> { | [sym::const_trait, ..] => 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_pass_by_value, ..] => self.check_pass_by_value(attr, span, target), [sym::rustc_allow_incoherent_impl, ..] => { self.check_allow_incoherent_impl(attr, span, target) } @@ -1438,11 +1440,11 @@ impl<'tcx> CheckAttrVisitor<'tcx> { } /// Warns against some misuses of `#[pass_by_value]` - fn check_pass_by_value(&self, attr: &Attribute, span: Span, target: Target) { + fn check_pass_by_value(&self, attr_span: Span, span: Span, target: Target) { match target { Target::Struct | Target::Enum | Target::TyAlias => {} _ => { - self.dcx().emit_err(errors::PassByValue { attr_span: attr.span(), span }); + self.dcx().emit_err(errors::PassByValue { attr_span, span }); } } } |
