diff options
| author | Jonathan Brouwer <jonathantbrouwer@gmail.com> | 2025-06-25 09:36:26 +0200 | 
|---|---|---|
| committer | Jonathan Brouwer <jonathantbrouwer@gmail.com> | 2025-06-27 08:58:26 +0200 | 
| commit | 9e3568407234ba4b8fa772cb4acf8d18b12baa7c (patch) | |
| tree | 9640b7781f40da7d4392dbca5a9d9cc370a300c0 /compiler/rustc_attr_parsing/src | |
| parent | e61dd437f33b5a640e67dc3628397689c664c17f (diff) | |
| download | rust-9e3568407234ba4b8fa772cb4acf8d18b12baa7c.tar.gz rust-9e3568407234ba4b8fa772cb4acf8d18b12baa7c.zip | |
Port `#[used]` to new attribute parsing infrastructure
Signed-off-by: Jonathan Brouwer <jonathantbrouwer@gmail.com>
Diffstat (limited to 'compiler/rustc_attr_parsing/src')
| -rw-r--r-- | compiler/rustc_attr_parsing/src/attributes/codegen_attrs.rs | 83 | ||||
| -rw-r--r-- | compiler/rustc_attr_parsing/src/context.rs | 2 | 
2 files changed, 84 insertions, 1 deletions
| diff --git a/compiler/rustc_attr_parsing/src/attributes/codegen_attrs.rs b/compiler/rustc_attr_parsing/src/attributes/codegen_attrs.rs index 5a849e79cc3..7c412d4fa89 100644 --- a/compiler/rustc_attr_parsing/src/attributes/codegen_attrs.rs +++ b/compiler/rustc_attr_parsing/src/attributes/codegen_attrs.rs @@ -1,4 +1,4 @@ -use rustc_attr_data_structures::{AttributeKind, OptimizeAttr}; +use rustc_attr_data_structures::{AttributeKind, OptimizeAttr, UsedBy}; use rustc_feature::{AttributeTemplate, template}; use rustc_session::parse::feature_err; use rustc_span::{Span, Symbol, sym}; @@ -228,3 +228,84 @@ impl<S: Stage> SingleAttributeParser<S> for NoMangleParser { Some(AttributeKind::NoMangle(cx.attr_span)) } } + +#[derive(Default)] +pub(crate) struct UsedParser { + first_compiler: Option<Span>, + first_linker: Option<Span>, +} + +// A custom `AttributeParser` is used rather than a Simple attribute parser because +// - Specifying two `#[used]` attributes is a warning (but will be an error in the future) +// - But specifying two conflicting attributes: `#[used(compiler)]` and `#[used(linker)]` is already an error today +// We can change this to a Simple parser once the warning becomes an error +impl<S: Stage> AttributeParser<S> for UsedParser { + const ATTRIBUTES: AcceptMapping<Self, S> = &[( + &[sym::used], + template!(Word, List: "compiler|linker"), + |group: &mut Self, cx, args| { + let used_by = match args { + ArgParser::NoArgs => UsedBy::Linker, + ArgParser::List(list) => { + let Some(l) = list.single() else { + cx.expected_single_argument(list.span); + return; + }; + + match l.meta_item().and_then(|i| i.path().word_sym()) { + Some(sym::compiler) => { + if !cx.features().used_with_arg() { + feature_err( + &cx.sess(), + sym::used_with_arg, + cx.attr_span, + "`#[used(compiler)]` is currently unstable", + ) + .emit(); + } + UsedBy::Compiler + } + Some(sym::linker) => { + if !cx.features().used_with_arg() { + feature_err( + &cx.sess(), + sym::used_with_arg, + cx.attr_span, + "`#[used(linker)]` is currently unstable", + ) + .emit(); + } + UsedBy::Linker + } + _ => { + cx.expected_specific_argument(l.span(), vec!["compiler", "linker"]); + return; + } + } + } + ArgParser::NameValue(_) => return, + }; + + let target = match used_by { + UsedBy::Compiler => &mut group.first_compiler, + UsedBy::Linker => &mut group.first_linker, + }; + + let attr_span = cx.attr_span; + if let Some(prev) = *target { + cx.warn_unused_duplicate(prev, attr_span); + } else { + *target = Some(attr_span); + } + }, + )]; + + fn finalize(self, _cx: &FinalizeContext<'_, '_, S>) -> Option<AttributeKind> { + // Ratcheting behaviour, if both `linker` and `compiler` are specified, use `linker` + Some(match (self.first_compiler, self.first_linker) { + (_, Some(span)) => AttributeKind::Used { used_by: UsedBy::Linker, span }, + (Some(span), _) => AttributeKind::Used { used_by: UsedBy::Compiler, span }, + (None, None) => return None, + }) + } +} diff --git a/compiler/rustc_attr_parsing/src/context.rs b/compiler/rustc_attr_parsing/src/context.rs index 83e3c75dedb..71bb86ca3d3 100644 --- a/compiler/rustc_attr_parsing/src/context.rs +++ b/compiler/rustc_attr_parsing/src/context.rs @@ -17,6 +17,7 @@ use rustc_span::{DUMMY_SP, ErrorGuaranteed, Span, Symbol, sym}; use crate::attributes::allow_unstable::{AllowConstFnUnstableParser, AllowInternalUnstableParser}; use crate::attributes::codegen_attrs::{ ColdParser, ExportNameParser, NakedParser, NoMangleParser, OptimizeParser, TrackCallerParser, + UsedParser, }; use crate::attributes::confusables::ConfusablesParser; use crate::attributes::deprecation::DeprecationParser; @@ -103,6 +104,7 @@ attribute_parsers!( ConstStabilityParser, NakedParser, StabilityParser, + UsedParser, // tidy-alphabetical-end // tidy-alphabetical-start | 
