Skip to content

Rewrite the new attribute argument parser #144689

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 5 commits into
base: master
Choose a base branch
from

Conversation

JonathanBrouwer
Copy link
Contributor

@JonathanBrouwer JonathanBrouwer commented Jul 30, 2025

Fixes #143940

This rewrites the parser, should improve performance and maintainability.
This can be reviewed commit by commit

@rustbot rustbot added A-attributes Area: Attributes (`#[…]`, `#![…]`) S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Jul 30, 2025
@jdonszelmann
Copy link
Contributor

@bors try @rust-timer queue

@rust-timer

This comment has been minimized.

@rust-bors
Copy link

rust-bors bot commented Jul 30, 2025

⌛ Trying commit 7b3bb12 with merge acc46aa

To cancel the try build, run the command @bors try cancel.

rust-bors bot added a commit that referenced this pull request Jul 30, 2025
@rustbot rustbot added the S-waiting-on-perf Status: Waiting on a perf run to be completed. label Jul 30, 2025
@@ -51,12 +37,26 @@ error[E0589]: invalid alignment value: not a power of two
LL | #[rustc_align(0)]
| ^

error: expected unsuffixed literal, found `-`
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it would be pretty cool if we could explain here what an unsuffixed literal is. Maybe give an example of one with a short explanation. It's not required, but does teach the language better through diagnostics which is always cool

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I improved the error a lot :)

error: expected a literal (`1u8`, `1.0f32`, `"string"`, etc.) here, found `-`
  --> $DIR/malformed-fn-align.rs:29:15
   |
LL | #[rustc_align(-1)]
   |               ^
   |
help: negative numbers are not literals, try removing the `-` sign
   |
LL - #[rustc_align(-1)]
LL + #[rustc_align(1)]
   |

@rust-bors
Copy link

rust-bors bot commented Jul 30, 2025

☀️ Try build successful (CI)
Build commit: acc46aa (acc46aa5d053362bb20ae7f352cba2635ef61120, parent: e5e79f8bd428d0b8d26e8240d718b134ef297459)

@rust-timer

This comment has been minimized.

@rust-timer
Copy link
Collaborator

Finished benchmarking commit (acc46aa): comparison URL.

Overall result: ❌✅ regressions and improvements - please read the text below

Benchmarking this pull request means it may be perf-sensitive – we'll automatically label it not fit for rolling up. You can override this, but we strongly advise not to, due to possible changes in compiler perf.

Next Steps: If you can justify the regressions found in this try perf run, please do so in sufficient writing along with @rustbot label: +perf-regression-triaged. If not, please fix the regressions and do another perf run. If its results are neutral or positive, the label will be automatically removed.

@bors rollup=never
@rustbot label: -S-waiting-on-perf +perf-regression

Instruction count

Our most reliable metric. Used to determine the overall result above. However, even this metric can be noisy.

mean range count
Regressions ❌
(primary)
0.2% [0.2%, 0.2%] 1
Regressions ❌
(secondary)
0.8% [0.0%, 1.0%] 7
Improvements ✅
(primary)
-0.3% [-0.5%, -0.1%] 12
Improvements ✅
(secondary)
-0.2% [-0.2%, -0.1%] 12
All ❌✅ (primary) -0.2% [-0.5%, 0.2%] 13

Max RSS (memory usage)

Results (secondary -1.3%)

A less reliable metric. May be of interest, but not used to determine the overall result above.

mean range count
Regressions ❌
(primary)
- - 0
Regressions ❌
(secondary)
2.0% [2.0%, 2.0%] 1
Improvements ✅
(primary)
- - 0
Improvements ✅
(secondary)
-2.4% [-2.9%, -2.0%] 3
All ❌✅ (primary) - - 0

Cycles

Results (secondary -0.5%)

A less reliable metric. May be of interest, but not used to determine the overall result above.

mean range count
Regressions ❌
(primary)
- - 0
Regressions ❌
(secondary)
4.7% [4.7%, 4.7%] 1
Improvements ✅
(primary)
- - 0
Improvements ✅
(secondary)
-3.1% [-3.7%, -2.5%] 2
All ❌✅ (primary) - - 0

Binary size

This benchmark run did not return any relevant results for this metric.

Bootstrap: 469.342s -> 468.873s (-0.10%)
Artifact size: 376.86 MiB -> 376.85 MiB (-0.00%)

@rustbot rustbot added perf-regression Performance regression. and removed S-waiting-on-perf Status: Waiting on a perf run to be completed. labels Jul 30, 2025
@lqd
Copy link
Member

lqd commented Jul 31, 2025

(match-stress looks currently noisy to me)

@jdonszelmann
Copy link
Contributor

Mhm, we came to the same conclusion (@JonathanBrouwer )

@JonathanBrouwer JonathanBrouwer force-pushed the share_parse_path branch 2 times, most recently from 4c9a573 to 244cefa Compare July 31, 2025 13:39
@@ -4,7 +4,7 @@ macro_rules! bar (

macro_rules! foo (
() => (
#[allow_internal_unstable] //~ ERROR allow_internal_unstable side-steps
#[allow_internal_unstable()] //~ ERROR allow_internal_unstable side-steps
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

BREAKING CHANGE:
Previously, attributes on macro calls were partially checked for correct syntax (only what check_builtin_meta_item can check).
After this PR, the attributes are fully parsed.

In any case, these attributes are always completely ignored, except for #[cfg], which was always completely parsed and still is and is not affected by this breaking change.

@@ -1095,7 +1095,7 @@ impl<'a> Parser<'a> {
/// Parses a comma-separated sequence delimited by parentheses (e.g. `(x, y)`).
/// The function `f` must consume tokens until reaching the next separator or
/// closing bracket.
fn parse_paren_comma_seq<T>(
pub fn parse_paren_comma_seq<T>(
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've had to make quite a few of these functions public, how problematic is that?
I don't think it matters right, or at least it's better than the alternative of copying them over

@JonathanBrouwer
Copy link
Contributor Author

@rustbot ready
r? @jdonszelmann

@JonathanBrouwer JonathanBrouwer marked this pull request as ready for review July 31, 2025 13:47
@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. and removed S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. labels Jul 31, 2025
@rustbot
Copy link
Collaborator

rustbot commented Jul 31, 2025

r? @SparrowLii

rustbot has assigned @SparrowLii.
They will have a look at your PR within the next two weeks and either review your PR or reassign to another reviewer.

Use r? to explicitly pick a reviewer

@rustbot
Copy link
Collaborator

rustbot commented Jul 31, 2025

jdonszelmann is currently at their maximum review capacity.
They may take a while to respond.

@craterbot craterbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. and removed S-waiting-on-crater Status: Waiting on a crater run to be completed. labels Jul 31, 2025
@jdonszelmann
Copy link
Contributor

@rust-lang/lang

@rust-bors
Copy link

rust-bors bot commented Jul 31, 2025

☀️ Try build successful (CI)
Build commit: c228194 (c2281943234ec635f9ee34a268a0011c3e897826, parent: 3fb1b53a9dbfcdf37a4b67d35cde373316829930)

@jdonszelmann
Copy link
Contributor

@craterbot check

@craterbot
Copy link
Collaborator

👌 Experiment pr-144689 created and queued.
🤖 Automatically detected try build c228194
🔍 You can check out the queue and this experiment's details.

ℹ️ Crater is a tool to run experiments across parts of the Rust ecosystem. Learn more

@craterbot craterbot added S-waiting-on-crater Status: Waiting on a crater run to be completed. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Jul 31, 2025
@bors
Copy link
Collaborator

bors commented Jul 31, 2025

☔ The latest upstream changes (presumably #144740) made this pull request unmergeable. Please resolve the merge conflicts.

@traviscross traviscross added P-lang-drag-1 Lang team prioritization drag level 1. https://rust-lang.zulipchat.com/#narrow/channel/410516-t-lang T-lang Relevant to the language team needs-fcp This change is insta-stable, or significant enough to need a team FCP to proceed. labels Jul 31, 2025
@craterbot
Copy link
Collaborator

🚧 Experiment pr-144689 is now running

ℹ️ Crater is a tool to run experiments across parts of the Rust ecosystem. Learn more

@craterbot
Copy link
Collaborator

🎉 Experiment pr-144689 is completed!
📊 4 regressed and 7 fixed (674726 total)
📰 Open the summary report.

⚠️ If you notice any spurious failure please add them to the denylist!
ℹ️ Crater is a tool to run experiments across parts of the Rust ecosystem. Learn more

@craterbot craterbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. and removed S-waiting-on-crater Status: Waiting on a crater run to be completed. labels Aug 2, 2025
@JonathanBrouwer
Copy link
Contributor Author

JonathanBrouwer commented Aug 2, 2025

All regressions are spurious.

The crater run did find a bug in my new implementation (in the "fixed" results), which is easy to fix. Apparently my new parser accepts #[cfg(target-os = "windows")] (with a dash instead of an underscore) even though it shouldn't, and the current implementation doesn't.

@JonathanBrouwer
Copy link
Contributor Author

JonathanBrouwer commented Aug 2, 2025

^ Fixed the bug and added a regression test

@rust-log-analyzer

This comment has been minimized.

@jdonszelmann
Copy link
Contributor

Well, that's nice, that should make the decision for lang easier. Still would like their opinion though. This is a by far superior way to handle errors in attribute parsing, and we emit more errors when things are wrong. That's good, as long as it doesn't break anyone and it seems the impact will be small.

@traviscross
Copy link
Contributor

Previously, attributes on macro calls were partially checked for correct syntax (only what check_builtin_meta_item can check). After this PR, the attributes are fully parsed.

If you could please describe further what it meant for the calls to be partially checked, that would help. I.e., what were we catching and what were the limits of that?

@bors
Copy link
Collaborator

bors commented Aug 3, 2025

☔ The latest upstream changes (presumably #144814) made this pull request unmergeable. Please resolve the merge conflicts.

@JonathanBrouwer
Copy link
Contributor Author

JonathanBrouwer commented Aug 3, 2025

@traviscross

Previously for attributes on macro calls we were doing the following:

  1. Parsing the attribute arguments to a MetaItem, as per the spec here: https://doc.rust-lang.org/reference/attributes.html#r-attributes.meta . This would report errors for any attributes that are not valid meta items, such as:
#[inline(1 2 3)]
#[inline(1=2)]
  1. Checking that the attribute arguments match the template provided here
    ungated!(inline, Normal, template!(Word, List: "always|never"), FutureWarnFollowing, EncodeCrossCrate::No),

    So inline must have Word or List arguments (so not NameValue), so this is invalid
#[inline = "string"]
#[inline = 5]

Note that this only looks at the Word and List parts, the "always|never" is only provided as a hint to the user and is not something that we check against.

What this PR introduces, is fully validating that the arguments to the attribute actually make sense, using the attributes' individual parsers.
So this is rejected, while it is previously accepted:

#[inline(this, is, not, valid)]
#[inline(this(is="not", valid="either"))]

As a reminder, these attributes on macro calls already have a warning that they are unused and will continue to have that warning.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-attributes Area: Attributes (`#[…]`, `#![…]`) I-lang-nominated Nominated for discussion during a lang team meeting. needs-fcp This change is insta-stable, or significant enough to need a team FCP to proceed. P-lang-drag-1 Lang team prioritization drag level 1. https://rust-lang.zulipchat.com/#narrow/channel/410516-t-lang perf-regression Performance regression. S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. T-lang Relevant to the language team
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Attributes are parsed twice
10 participants