Rollup merge of #150198 - Bryntet:parse_thread_local, r=JonathanBrouwer

Port `#[thread_local]` to attribute parser

Simple port, only thing that might be an issue is the `help: #[thread_local] can be applied to foreign statics and statics` it probably would be that if an attribute is applicable to both statics and foreign statics that we don't alphabetically sort them next to each other, because now it kinda reads like `#[thread_local]` is something that you primarily use on foreign statics

r? `@JonathanBrouwer`
This commit is contained in:
Jonathan Brouwer
2025-12-20 16:24:06 +01:00
committed by GitHub
11 changed files with 48 additions and 58 deletions
@@ -690,6 +690,16 @@ fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser) -> Option<Attrib
}
}
pub(crate) struct ThreadLocalParser;
impl<S: Stage> NoArgsAttributeParser<S> for ThreadLocalParser {
const PATH: &[Symbol] = &[sym::thread_local];
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::WarnButFutureError;
const ALLOWED_TARGETS: AllowedTargets =
AllowedTargets::AllowList(&[Allow(Target::Static), Allow(Target::ForeignStatic)]);
const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::ThreadLocal;
}
pub(crate) struct RustcPassIndirectlyInNonRusticAbisParser;
impl<S: Stage> NoArgsAttributeParser<S> for RustcPassIndirectlyInNonRusticAbisParser {
+2 -1
View File
@@ -23,7 +23,7 @@
ColdParser, CoverageParser, EiiExternItemParser, ExportNameParser, ForceTargetFeatureParser,
NakedParser, NoMangleParser, ObjcClassParser, ObjcSelectorParser, OptimizeParser,
RustcPassIndirectlyInNonRusticAbisParser, SanitizeParser, TargetFeatureParser,
TrackCallerParser, UsedParser,
ThreadLocalParser, TrackCallerParser, UsedParser,
};
use crate::attributes::confusables::ConfusablesParser;
use crate::attributes::crate_level::{
@@ -269,6 +269,7 @@ mod late {
Single<WithoutArgs<RustcShouldNotBeCalledOnConstItems>>,
Single<WithoutArgs<SpecializationTraitParser>>,
Single<WithoutArgs<StdInternalSymbolParser>>,
Single<WithoutArgs<ThreadLocalParser>>,
Single<WithoutArgs<TrackCallerParser>>,
Single<WithoutArgs<TypeConstParser>>,
Single<WithoutArgs<UnsafeSpecializationMarkerParser>>,
@@ -350,6 +350,9 @@ fn process_builtin_attrs(
codegen_fn_attrs.flags |= CodegenFnAttrFlags::EXTERNALLY_IMPLEMENTABLE_ITEM;
}
}
AttributeKind::ThreadLocal => {
codegen_fn_attrs.flags |= CodegenFnAttrFlags::THREAD_LOCAL
}
_ => {}
}
}
@@ -366,7 +369,6 @@ fn process_builtin_attrs(
sym::rustc_allocator_zeroed => {
codegen_fn_attrs.flags |= CodegenFnAttrFlags::ALLOCATOR_ZEROED
}
sym::thread_local => codegen_fn_attrs.flags |= CodegenFnAttrFlags::THREAD_LOCAL,
sym::instruction_set => {
codegen_fn_attrs.instruction_set = parse_instruction_set_attr(tcx, attr)
}
@@ -1010,6 +1010,9 @@ pub enum AttributeKind {
/// `#[unsafe(force_target_feature(enable = "...")]`.
TargetFeature { features: ThinVec<(Symbol, Span)>, attr_span: Span, was_forced: bool },
/// Represents `#[thread_local]`
ThreadLocal,
/// Represents `#[track_caller]`
TrackCaller(Span),
@@ -114,6 +114,7 @@ pub fn encode_cross_crate(&self) -> EncodeCrossCrate {
Stability { .. } => Yes,
StdInternalSymbol(..) => No,
TargetFeature { .. } => No,
ThreadLocal => No,
TrackCaller(..) => Yes,
TypeConst(..) => Yes,
TypeLengthLimit { .. } => No,
-4
View File
@@ -484,10 +484,6 @@ passes_sanitize_attribute_not_allowed =
.no_body = function has no body
.help = sanitize attribute can be applied to a function (with body), impl block, or module
passes_should_be_applied_to_static =
attribute should be applied to a static
.label = not a static
passes_should_be_applied_to_trait =
attribute should be applied to a trait
.label = not a trait
+1 -14
View File
@@ -297,6 +297,7 @@ fn check_attributes(
| AttributeKind::RustcPassIndirectlyInNonRusticAbis(..)
| AttributeKind::PinV2(..)
| AttributeKind::WindowsSubsystem(..)
| AttributeKind::ThreadLocal
) => { /* do nothing */ }
Attribute::Unparsed(attr_item) => {
style = Some(attr_item.style);
@@ -310,7 +311,6 @@ fn check_attributes(
[sym::diagnostic, sym::on_const, ..] => {
self.check_diagnostic_on_const(attr.span(), hir_id, target, item)
}
[sym::thread_local, ..] => self.check_thread_local(attr, span, target),
[sym::rustc_clean, ..]
| [sym::rustc_dirty, ..]
| [sym::rustc_if_this_changed, ..]
@@ -768,19 +768,6 @@ fn check_target_feature(
}
}
/// Checks if the `#[thread_local]` attribute on `item` is valid.
fn check_thread_local(&self, attr: &Attribute, span: Span, target: Target) {
match target {
Target::ForeignStatic | Target::Static => {}
_ => {
self.dcx().emit_err(errors::AttrShouldBeAppliedToStatic {
attr_span: attr.span(),
defn_span: span,
});
}
}
}
fn check_doc_alias_value(&self, span: Span, hir_id: HirId, target: Target, alias: Symbol) {
if let Some(location) = match target {
Target::AssocTy => {
-9
View File
@@ -98,15 +98,6 @@ pub(crate) struct AttrShouldBeAppliedToTrait {
pub defn_span: Span,
}
#[derive(Diagnostic)]
#[diag(passes_should_be_applied_to_static)]
pub(crate) struct AttrShouldBeAppliedToStatic {
#[primary_span]
pub attr_span: Span,
#[label]
pub defn_span: Span,
}
#[derive(Diagnostic)]
#[diag(passes_doc_alias_bad_location)]
pub(crate) struct DocAliasBadLocation<'a> {
+9 -6
View File
@@ -141,12 +141,6 @@ LL | #[forbid(lint1, lint2, ...)]
LL | #[forbid(lint1, lint2, lint3, reason = "...")]
| +++++++++++++++++++++++++++++++++++++
error: malformed `thread_local` attribute input
--> $DIR/malformed-attrs.rs:210:1
|
LL | #[thread_local()]
| ^^^^^^^^^^^^^^^^^ help: must be of the form: `#[thread_local]`
error: the `#[proc_macro]` attribute is only usable with crates of the `proc-macro` crate type
--> $DIR/malformed-attrs.rs:105:1
|
@@ -618,6 +612,15 @@ LL | #[non_exhaustive = 1]
| | didn't expect any arguments here
| help: must be of the form: `#[non_exhaustive]`
error[E0565]: malformed `thread_local` attribute input
--> $DIR/malformed-attrs.rs:210:1
|
LL | #[thread_local()]
| ^^^^^^^^^^^^^^--^
| | |
| | didn't expect any arguments here
| help: must be of the form: `#[thread_local]`
error[E0565]: malformed `no_link` attribute input
--> $DIR/malformed-attrs.rs:214:1
|
+4 -4
View File
@@ -2,19 +2,19 @@
#![feature(thread_local)]
#[thread_local]
//~^ ERROR attribute should be applied to a static
//~^ ERROR `#[thread_local]` attribute cannot be used on constants
const A: u32 = 0;
#[thread_local]
//~^ ERROR attribute should be applied to a static
//~^ ERROR `#[thread_local]` attribute cannot be used on functions
fn main() {
#[thread_local] || {};
//~^ ERROR attribute should be applied to a static
//~^ ERROR `#[thread_local]` attribute cannot be used on closures
}
struct S {
#[thread_local]
//~^ ERROR attribute should be applied to a static
//~^ ERROR `#[thread_local]` attribute cannot be used on struct fields
a: String,
b: String,
}
+15 -19
View File
@@ -1,38 +1,34 @@
error: attribute should be applied to a static
error: `#[thread_local]` attribute cannot be used on constants
--> $DIR/non-static.rs:4:1
|
LL | #[thread_local]
| ^^^^^^^^^^^^^^^
LL |
LL | const A: u32 = 0;
| ----------------- not a static
|
= help: `#[thread_local]` can be applied to foreign statics and statics
error: attribute should be applied to a static
error: `#[thread_local]` attribute cannot be used on functions
--> $DIR/non-static.rs:8:1
|
LL | #[thread_local]
| ^^^^^^^^^^^^^^^
LL |
LL | / fn main() {
LL | | #[thread_local] || {};
LL | |
LL | | }
| |_- not a static
LL | #[thread_local]
| ^^^^^^^^^^^^^^^
|
= help: `#[thread_local]` can be applied to foreign statics and statics
error: attribute should be applied to a static
error: `#[thread_local]` attribute cannot be used on closures
--> $DIR/non-static.rs:11:5
|
LL | #[thread_local] || {};
| ^^^^^^^^^^^^^^^ ----- not a static
| ^^^^^^^^^^^^^^^
|
= help: `#[thread_local]` can be applied to foreign statics and statics
error: attribute should be applied to a static
error: `#[thread_local]` attribute cannot be used on struct fields
--> $DIR/non-static.rs:16:5
|
LL | #[thread_local]
| ^^^^^^^^^^^^^^^
LL |
LL | a: String,
| --------- not a static
|
= help: `#[thread_local]` can be applied to foreign statics and statics
error: aborting due to 4 previous errors