diff options
| author | bors <bors@rust-lang.org> | 2025-06-20 23:09:48 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2025-06-20 23:09:48 +0000 |
| commit | 15c701fbc995eb6c5b3a86021c18185f8eee020d (patch) | |
| tree | 0d4b164e407ebce78c37e09f104e5371e9aa149c /compiler/rustc_attr_parsing/src | |
| parent | 5526a2f47cd676ceeedc08cf71ae75ce2e9284ae (diff) | |
| parent | 61f491872a01b0906fcedc3862d0e11cb3f6de01 (diff) | |
| download | rust-15c701fbc995eb6c5b3a86021c18185f8eee020d.tar.gz rust-15c701fbc995eb6c5b3a86021c18185f8eee020d.zip | |
Auto merge of #142794 - tgross35:rollup-iae7okj, r=tgross35
Rollup of 9 pull requests Successful merges: - rust-lang/rust#142331 (Add `trim_prefix` and `trim_suffix` methods for both `slice` and `str` types.) - rust-lang/rust#142491 (Rework #[cold] attribute parser) - rust-lang/rust#142494 (Fix missing docs in `rustc_attr_parsing`) - rust-lang/rust#142495 (Better template for `#[repr]` attributes) - rust-lang/rust#142497 (Fix random failure when JS code is executed when the whole file was not read yet) - rust-lang/rust#142575 (Ensure copy* intrinsics also perform the static self-init checks) - rust-lang/rust#142650 (Refactor Translator) - rust-lang/rust#142713 (mbe: Refactor transcription) - rust-lang/rust#142755 (rustdoc: Remove `FormatRenderer::cache`) r? `@ghost` `@rustbot` modify labels: rollup
Diffstat (limited to 'compiler/rustc_attr_parsing/src')
5 files changed, 56 insertions, 2 deletions
diff --git a/compiler/rustc_attr_parsing/src/attributes/codegen_attrs.rs b/compiler/rustc_attr_parsing/src/attributes/codegen_attrs.rs index ddcf82cbf7c..1b03525a5ce 100644 --- a/compiler/rustc_attr_parsing/src/attributes/codegen_attrs.rs +++ b/compiler/rustc_attr_parsing/src/attributes/codegen_attrs.rs @@ -38,3 +38,21 @@ impl<S: Stage> SingleAttributeParser<S> for OptimizeParser { Some(AttributeKind::Optimize(res, cx.attr_span)) } } + +pub(crate) struct ColdParser; + +impl<S: Stage> SingleAttributeParser<S> for ColdParser { + const PATH: &[rustc_span::Symbol] = &[sym::cold]; + const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepLast; + const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Warn; + const TEMPLATE: AttributeTemplate = template!(Word); + + fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser<'_>) -> Option<AttributeKind> { + if !args.no_args() { + cx.expected_no_args(args.span().unwrap_or(cx.attr_span)); + return None; + }; + + Some(AttributeKind::Cold(cx.attr_span)) + } +} diff --git a/compiler/rustc_attr_parsing/src/attributes/mod.rs b/compiler/rustc_attr_parsing/src/attributes/mod.rs index 3bb4c163d32..78a696afa27 100644 --- a/compiler/rustc_attr_parsing/src/attributes/mod.rs +++ b/compiler/rustc_attr_parsing/src/attributes/mod.rs @@ -87,8 +87,19 @@ pub(crate) trait AttributeParser<S: Stage>: Default + 'static { /// [`SingleAttributeParser`] can only convert attributes one-to-one, and cannot combine multiple /// attributes together like is necessary for `#[stable()]` and `#[unstable()]` for example. pub(crate) trait SingleAttributeParser<S: Stage>: 'static { + /// The single path of the attribute this parser accepts. + /// + /// If you need the parser to accept more than one path, use [`AttributeParser`] instead const PATH: &[Symbol]; + + /// Configures the precedence of attributes with the same `PATH` on a syntax node. const ATTRIBUTE_ORDER: AttributeOrder; + + /// Configures what to do when when the same attribute is + /// applied more than once on the same syntax node. + /// + /// [`ATTRIBUTE_ORDER`](Self::ATTRIBUTE_ORDER) specified which one is assumed to be correct, + /// and this specified whether to, for example, warn or error on the other one. const ON_DUPLICATE: OnDuplicate<S>; /// The template this attribute parser should implement. Used for diagnostics. @@ -98,6 +109,8 @@ pub(crate) trait SingleAttributeParser<S: Stage>: 'static { fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser<'_>) -> Option<AttributeKind>; } +/// Use in combination with [`SingleAttributeParser`]. +/// `Single<T: SingleAttributeParser>` implements [`AttributeParser`]. pub(crate) struct Single<T: SingleAttributeParser<S>, S: Stage>( PhantomData<(S, T)>, Option<(AttributeKind, Span)>, @@ -230,6 +243,10 @@ pub(crate) trait CombineAttributeParser<S: Stage>: 'static { const PATH: &[rustc_span::Symbol]; type Item; + /// A function that converts individual items (of type [`Item`](Self::Item)) into the final attribute. + /// + /// For example, individual representations fomr `#[repr(...)]` attributes into an `AttributeKind::Repr(x)`, + /// where `x` is a vec of these individual reprs. const CONVERT: ConvertFn<Self::Item>; /// The template this attribute parser should implement. Used for diagnostics. @@ -242,6 +259,8 @@ pub(crate) trait CombineAttributeParser<S: Stage>: 'static { ) -> impl IntoIterator<Item = Self::Item> + 'c; } +/// Use in combination with [`CombineAttributeParser`]. +/// `Combine<T: CombineAttributeParser>` implements [`AttributeParser`]. pub(crate) struct Combine<T: CombineAttributeParser<S>, S: Stage>( PhantomData<(S, T)>, ThinVec<<T as CombineAttributeParser<S>>::Item>, diff --git a/compiler/rustc_attr_parsing/src/attributes/repr.rs b/compiler/rustc_attr_parsing/src/attributes/repr.rs index eb16c3f95f0..4aa27043e98 100644 --- a/compiler/rustc_attr_parsing/src/attributes/repr.rs +++ b/compiler/rustc_attr_parsing/src/attributes/repr.rs @@ -25,7 +25,8 @@ impl<S: Stage> CombineAttributeParser<S> for ReprParser { const PATH: &[Symbol] = &[sym::repr]; const CONVERT: ConvertFn<Self::Item> = AttributeKind::Repr; // FIXME(jdonszelmann): never used - const TEMPLATE: AttributeTemplate = template!(List: "C"); + const TEMPLATE: AttributeTemplate = + template!(List: "C | Rust | align(...) | packed(...) | <integer type> | transparent"); fn extend<'c>( cx: &'c mut AcceptContext<'_, '_, S>, diff --git a/compiler/rustc_attr_parsing/src/context.rs b/compiler/rustc_attr_parsing/src/context.rs index 7925c43d62f..8311fccacd8 100644 --- a/compiler/rustc_attr_parsing/src/context.rs +++ b/compiler/rustc_attr_parsing/src/context.rs @@ -15,7 +15,7 @@ use rustc_session::Session; use rustc_span::{DUMMY_SP, ErrorGuaranteed, Span, Symbol, sym}; use crate::attributes::allow_unstable::{AllowConstFnUnstableParser, AllowInternalUnstableParser}; -use crate::attributes::codegen_attrs::OptimizeParser; +use crate::attributes::codegen_attrs::{ColdParser, OptimizeParser}; use crate::attributes::confusables::ConfusablesParser; use crate::attributes::deprecation::DeprecationParser; use crate::attributes::inline::{InlineParser, RustcForceInlineParser}; @@ -106,6 +106,7 @@ attribute_parsers!( // tidy-alphabetical-start Single<AsPtrParser>, + Single<ColdParser>, Single<ConstStabilityIndirectParser>, Single<DeprecationParser>, Single<InlineParser>, @@ -234,6 +235,16 @@ impl<'f, 'sess: 'f, S: Stage> AcceptContext<'f, 'sess, S> { }) } + pub(crate) fn expected_no_args(&self, args_span: Span) -> ErrorGuaranteed { + self.emit_err(AttributeParseError { + span: args_span, + attr_span: self.attr_span, + template: self.template.clone(), + attribute: self.attr_path.clone(), + reason: AttributeParseErrorReason::ExpectedNoArgs, + }) + } + /// emit an error that a `name = value` pair was expected at this span. The symbol can be given for /// a nicer error message talking about the specific name that was found lacking a value. pub(crate) fn expected_name_value(&self, span: Span, name: Option<Symbol>) -> ErrorGuaranteed { diff --git a/compiler/rustc_attr_parsing/src/session_diagnostics.rs b/compiler/rustc_attr_parsing/src/session_diagnostics.rs index 337921a318c..29f2e44a98a 100644 --- a/compiler/rustc_attr_parsing/src/session_diagnostics.rs +++ b/compiler/rustc_attr_parsing/src/session_diagnostics.rs @@ -474,6 +474,7 @@ pub(crate) struct UnrecognizedReprHint { } pub(crate) enum AttributeParseErrorReason { + ExpectedNoArgs, ExpectedStringLiteral { byte_string: Option<Span> }, ExpectedSingleArgument, ExpectedList, @@ -529,6 +530,10 @@ impl<'a, G: EmissionGuarantee> Diagnostic<'a, G> for AttributeParseError { diag.span_label(self.span, format!("didn't expect a literal here")); diag.code(E0565); } + AttributeParseErrorReason::ExpectedNoArgs => { + diag.span_label(self.span, format!("didn't expect any arguments here")); + diag.code(E0565); + } AttributeParseErrorReason::ExpectedNameValue(None) => { diag.span_label( self.span, |
