Skip to content

Re-port lint attributes to attribute parsers#155691

Open
Bryntet wants to merge 3 commits intorust-lang:mainfrom
Bryntet:lint_attrs_v2
Open

Re-port lint attributes to attribute parsers#155691
Bryntet wants to merge 3 commits intorust-lang:mainfrom
Bryntet:lint_attrs_v2

Conversation

@Bryntet
Copy link
Copy Markdown
Contributor

@Bryntet Bryntet commented Apr 23, 2026

View all comments

I managed to fix the related issues related to the lint attrs PR (one of which, with the help of @JonathanBrouwer ❤️ )

this is another attempt at #152369 and reverts #155056

r? @JonathanBrouwer
r? @jdonszelmann

follow up to this PR would be a cleaner way to do what I do in the commit c9e832c

probably by adding a new variant to ShouldEmit or changing the Nothing variant to have an option of whether to emit bugs or not

@rustbot
Copy link
Copy Markdown
Collaborator

rustbot commented Apr 23, 2026

Some changes occurred in compiler/rustc_attr_parsing

cc @jdonszelmann, @JonathanBrouwer

These commits modify the Cargo.lock file. Unintentional changes to Cargo.lock can be introduced when switching branches and rebasing PRs.

If this was unintentional then you should revert the changes before this PR is merged.
Otherwise, you can ignore this comment.

Some changes occurred in compiler/rustc_passes/src/check_attr.rs

cc @jdonszelmann, @JonathanBrouwer

Some changes occurred in compiler/rustc_hir/src/attrs

cc @jdonszelmann, @JonathanBrouwer

Some changes occurred in src/tools/clippy

cc @rust-lang/clippy

@rustbot rustbot added A-attributes Area: Attributes (`#[…]`, `#![…]`) S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-clippy Relevant to the Clippy team. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. T-rustdoc Relevant to the rustdoc team, which will review and decide on the PR/issue. labels Apr 23, 2026
@JonathanBrouwer
Copy link
Copy Markdown
Contributor

Just a sanity check
@bors try @rust-timer queue

@rust-timer

This comment has been minimized.

@rust-bors

This comment has been minimized.

@rustbot rustbot added the S-waiting-on-perf Status: Waiting on a perf run to be completed. label Apr 23, 2026
rust-bors Bot pushed a commit that referenced this pull request Apr 23, 2026
@petrochenkov petrochenkov self-assigned this Apr 23, 2026
@rust-bors
Copy link
Copy Markdown
Contributor

rust-bors Bot commented Apr 23, 2026

☀️ Try build successful (CI)
Build commit: a8bd7ef (a8bd7ef876125368f7f163a9b97cd468051ca908, parent: 827651f2200cefab42dac4c2ae7f80a7149340de)

@JonathanBrouwer
Copy link
Copy Markdown
Contributor

@rust-timer build a8bd7ef

@rust-timer

This comment has been minimized.

#![attr = Feature([fn_delegation#0])]
extern crate std;
#[attr = PreludeImport]
use std::prelude::rust_2021::*;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Why doesn't HIR pretty printing respect the comment ordering anymore?

Comment thread compiler/rustc_span/src/caching_source_map_view.rs Outdated
original_name: Option<Symbol>,
/// Index of this lint, used to keep track of lint groups
lint_index: usize,
kind: LintAttrTool,
Copy link
Copy Markdown
Contributor

@petrochenkov petrochenkov Apr 23, 2026

Choose a reason for hiding this comment

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

Any specific reason to make the fields here private and provide trivial accessor methods instead?
Most of the other data in this file is public.

View changes since the review

Copy link
Copy Markdown
Contributor Author

@Bryntet Bryntet Apr 23, 2026

Choose a reason for hiding this comment

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

I mainly just don't want other places constructing LintInstance without using LintInstance::new

I'm fine with making these public though if you think this would be preferable!

Comment thread compiler/rustc_hir/src/attrs/data_structures.rs Outdated
Comment thread compiler/rustc_hir/src/attrs/data_structures.rs
Comment thread compiler/rustc_hir/src/attrs/data_structures.rs Outdated
None => LintAttrTool::NoTool,
};

Self { original_name, span, lint_index, lint_name, kind }
Copy link
Copy Markdown
Contributor

@petrochenkov petrochenkov Apr 23, 2026

Choose a reason for hiding this comment

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

Could you avoid using Self in non-generic contexts? At least in constructors like this.

View changes since the review

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

would you prefer this in the function signature as well?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Up to you, I think having LintInstance { and LintInstance::new constructors searchable is particularly important, but I personally usually avoid Self in other cases too.

Comment thread compiler/rustc_hir/src/attrs/data_structures.rs Outdated
Comment thread compiler/rustc_hir/src/attrs/data_structures.rs Outdated
@petrochenkov
Copy link
Copy Markdown
Contributor

I'd like to review this PR before it is merged.
I started today and will continue tomorrow.

The PR is huge and contains both various refactorings (registered_tools, early.rs, string -> symbol, etc) and the core change (migrating lint attributes), and perhaps some post-migration cleanups too.
It would be good to split it into at least 2 PRs, one for refactorings (with explanation/motivation for each change) and then another for the core change.

Also cjgilllot left some comments in #152369, didn't check if they were addressed yet.

@JonathanBrouwer JonathanBrouwer changed the title Re-add lint attributes Re-port lint attributes to attribute parsers Apr 23, 2026
@rust-timer
Copy link
Copy Markdown
Collaborator

Finished benchmarking commit (a8bd7ef): comparison URL.

Overall result: ❌✅ regressions and improvements - please read:

Benchmarking means the PR may be perf-sensitive. It's automatically marked not fit for rolling up. Overriding is possible but disadvised: it risks changing compiler perf.

Next, please: If you can, justify the regressions found in this try perf run in writing along with @rustbot label: +perf-regression-triaged. If not, fix the regressions and do another perf run. Neutral or positive results will clear the label automatically.

@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
Regressions ❌
(secondary)
0.3% [0.2%, 0.6%] 8
Improvements ✅
(primary)
-0.3% [-0.6%, -0.2%] 16
Improvements ✅
(secondary)
-0.4% [-0.5%, -0.2%] 26
All ❌✅ (primary) -0.3% [-0.6%, -0.2%] 16

Max RSS (memory usage)

Results (primary -0.0%, secondary 1.0%)

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

mean range count
Regressions ❌
(primary)
3.2% [3.2%, 3.2%] 1
Regressions ❌
(secondary)
4.6% [2.0%, 6.5%] 7
Improvements ✅
(primary)
-0.8% [-1.3%, -0.6%] 4
Improvements ✅
(secondary)
-2.5% [-6.9%, -1.1%] 7
All ❌✅ (primary) -0.0% [-1.3%, 3.2%] 5

Cycles

Results (primary 2.9%, secondary 4.3%)

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

mean range count
Regressions ❌
(primary)
2.9% [2.0%, 4.0%] 7
Regressions ❌
(secondary)
4.3% [2.4%, 6.1%] 13
Improvements ✅
(primary)
- - 0
Improvements ✅
(secondary)
- - 0
All ❌✅ (primary) 2.9% [2.0%, 4.0%] 7

Binary size

This perf run didn't have relevant results for this metric.

Bootstrap: 490.734s -> 492.119s (0.28%)
Artifact size: 394.28 MiB -> 394.31 MiB (0.01%)

@rustbot rustbot added perf-regression Performance regression. and removed S-waiting-on-perf Status: Waiting on a perf run to be completed. labels Apr 23, 2026
Copy link
Copy Markdown
Contributor

@JonathanBrouwer JonathanBrouwer left a comment

Choose a reason for hiding this comment

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

Will do some more review later, some initial comments

View changes since this review

Comment thread tests/ui/parser/issues/issue-104620.rs Outdated
Comment thread tests/ui/lint/rfc-2383-lint-reason/multiple_expect_attrs.rs
Comment thread src/tools/clippy/clippy_lints/src/returns/needless_return.rs
@rustbot rustbot removed the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Apr 24, 2026
@rustbot
Copy link
Copy Markdown
Collaborator

rustbot commented Apr 24, 2026

Reminder, once the PR becomes ready for a review, use @rustbot ready.

@rustbot rustbot added the S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. label Apr 24, 2026
@Bryntet Bryntet force-pushed the lint_attrs_v2 branch 2 times, most recently from 803cb3c to 1a81a4b Compare April 24, 2026 09:48
fn check_unused_attribute(&self, hir_id: HirId, attr: &Attribute) {
// Warn on useless empty attributes.
// FIXME(jdonszelmann): this lint should be moved to attribute parsing, see `AcceptContext::warn_empty_attribute`
let note = if attr.has_any_name(&[sym::feature])
Copy link
Copy Markdown
Contributor

@JonathanBrouwer JonathanBrouwer Apr 24, 2026

Choose a reason for hiding this comment

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

Why is this unused check for feature added here?

View changes since the review

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

diff looks weird, but it's because I refactored the check_lint_attr logic out of the already existing function check_unused_attribute

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I can't find this check anywhere in the old code tho, could you point me to where this check was moved from?

Comment thread compiler/rustc_passes/src/check_attr.rs
Comment thread compiler/rustc_mir_build/src/builder/scope.rs Outdated
Comment thread compiler/rustc_lint_defs/src/lib.rs Outdated
Comment thread compiler/rustc_attr_parsing/src/attributes/lint.rs
/// context, through which all attributes can be lowered.
pub struct AttributeParser<'sess, S: Stage = Late> {
pub(crate) tools: Vec<Symbol>,
pub(crate) tools: Option<&'sess FxIndexSet<Ident>>,
Copy link
Copy Markdown
Contributor

@JonathanBrouwer JonathanBrouwer Apr 24, 2026

Choose a reason for hiding this comment

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

Could you make this change to tools a separate PR that is merged before this one, to reduce the size of this one a bit?

View changes since the review

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I'd rather move all the other refactorings too #155691 (comment), so the core change becomes as minimal as possible.

}
}
false
self.tcx.hir_attrs(id).iter().any(Attribute::has_span_without_desugaring_kind)
Copy link
Copy Markdown
Contributor

@JonathanBrouwer JonathanBrouwer Apr 24, 2026

Choose a reason for hiding this comment

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

This looks like it might partially fix #143094 (for the attrs that has_span_without_desugaring_kind supports)

  • Does it?
  • Why does this change need to be in this PR?

View changes since the review

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I created the helper function has_span_without_desugaring_kind because if you don't do this check in a specific way, you'll get ICE, and the same check was done in multiple places, and it would become a big mess if we don't have a helper function

I think that issue could possibly be fixed by expanding on this helper function, it does not fix that specific issue right now, no.

}
}
false
self.tcx.hir_attrs(id).iter().any(hir::Attribute::has_span_without_desugaring_kind)
Copy link
Copy Markdown
Contributor

@JonathanBrouwer JonathanBrouwer Apr 24, 2026

Choose a reason for hiding this comment

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

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

see my response to the comment above

@rustbot

This comment has been minimized.

@rustbot
Copy link
Copy Markdown
Collaborator

rustbot commented Apr 24, 2026

This PR was rebased onto a different main commit. Here's a range-diff highlighting what actually changed.

Rebasing is a normal part of keeping PRs up to date, so no action is needed—this note is just to help reviewers.

&mut emit_lint,
);
}
let attr_id = sess.psess.attr_id_generator.mk_attr_id();
Copy link
Copy Markdown
Contributor

@petrochenkov petrochenkov Apr 24, 2026

Choose a reason for hiding this comment

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

This is not good, I'd rather make the attr_id in the context optional.
When processing lint attributes it is always set, so it can be unwrapped there.

View changes since the review


/// This method provides the same functionality as [`parse_limited_all`](Self::parse_limited_all) except filtered,
/// making sure that only allow-listed symbols are parsed
pub fn parse_limited_all_filtered<'a>(
Copy link
Copy Markdown
Contributor

@petrochenkov petrochenkov Apr 24, 2026

Choose a reason for hiding this comment

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

Calling this function is not much simpler than calling the underlying parse_limited_all with an iterator.
If levels.rs calls it multiple times, then it could have a more specialized private helper, but otherwise it would probably be better to reduce the API surface.

View changes since the review

| [sym::deny]
| [sym::expect]
| [sym::forbid]
| [sym::warn]
Copy link
Copy Markdown
Contributor

@petrochenkov petrochenkov Apr 24, 2026

Choose a reason for hiding this comment

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

What is the special relation between lint attributes and incorrect delimiters?
Why shouldn't the delimiters be reported for lint attributes specifically?

View changes since the review


pub(crate) trait Lint {
const KIND: LintAttributeKind;
const ATTR_SYMBOL: Symbol = Self::KIND.symbol();
Copy link
Copy Markdown
Contributor

@petrochenkov petrochenkov Apr 24, 2026

Choose a reason for hiding this comment

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

Is ATTR_SYMBOl ever overridden to something other than Self::KIND.symbol()?
If not, then it shouldn't be a trait item.

I'm not actually sure why lint attribute kinds need to exist at type level (as opposed to value level LintAttributeKind enum).

View changes since the review


fn finalize(mut self, _cx: &FinalizeContext<'_, '_, S>) -> Option<AttributeKind> {
if !self.lint_attrs.is_empty() {
// Sort to ensure correct order operations later
Copy link
Copy Markdown
Contributor

@petrochenkov petrochenkov Apr 24, 2026

Choose a reason for hiding this comment

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

Span ordering shouldn't generally be relied upon for anything besides displaying diagnostics.

View changes since the review

&[]
}
fn check<'ecx, 'tcx, T: EarlyLintPass>(self, cx: &mut EarlyContextAndPass<'ecx, 'tcx, T>) {
walk_list!(cx, visit_attribute, self.1);
Copy link
Copy Markdown
Contributor

@petrochenkov petrochenkov Apr 24, 2026

Choose a reason for hiding this comment

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

I'm not sure what this change achieves.
Pre-expansion lints never want to check node attributes?

View changes since the review

}

pub fn set_lint_index(&mut self, new_lint_index: Option<u16>) {
pub fn set_lint_index(&mut self, new_lint_index: u16) {
Copy link
Copy Markdown
Contributor

@petrochenkov petrochenkov Apr 24, 2026

Choose a reason for hiding this comment

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

This method is never used now.
get_lint_index isn't used either.

View changes since the review

@rust-bors
Copy link
Copy Markdown
Contributor

rust-bors Bot commented Apr 25, 2026

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

A-attributes Area: Attributes (`#[…]`, `#![…]`) perf-regression Performance regression. S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. T-clippy Relevant to the Clippy team. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. T-rustdoc Relevant to the rustdoc team, which will review and decide on the PR/issue.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants