Apply fix availability and applicability when adding to DiagnosticGuard and remove NoqaCode::rule (#18834)

## Summary

This PR removes the last two places we were using `NoqaCode::rule` in
`linter.rs` (see
https://github.com/astral-sh/ruff/pull/18391#discussion_r2154637329 and
https://github.com/astral-sh/ruff/pull/18391#discussion_r2154649726) by
checking whether fixes are actually desired before adding them to a
`DiagnosticGuard`. I implemented this by storing a `Violation`'s `Rule`
on the `DiagnosticGuard` so that we could check if it was enabled in the
embedded `LinterSettings` when trying to set a fix.

All of the corresponding `set_fix` methods on `OldDiagnostic` were now
unused (except in tests where I just set `.fix` directly), so I moved
these to the guard instead of keeping both sets.

The very last place where we were using `NoqaCode::rule` was in the
cache. I just reverted this to parsing the `Rule` from the name. I had
forgotten to update the comment there anyway. Hopefully this doesn't
cause too much of a perf hit.

In terms of binary size, we're back down almost to where `main` was two
days ago
(https://github.com/astral-sh/ruff/pull/18391#discussion_r2155034320):

```
41,559,344 bytes for main 2 days ago
41,669,840 bytes for #18391
41,653,760 bytes for main now (after #18391 merged)
41,602,224 bytes for this branch
```

Only 43 kb up, but that shouldn't all be me this time :)

## Test Plan

Existing tests and benchmarks on this PR
This commit is contained in:
Brent Westbrook 2025-06-24 10:08:36 -04:00 committed by GitHub
parent 0edbd6c390
commit 02ae8e1210
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
11 changed files with 73 additions and 102 deletions

View file

@ -254,11 +254,9 @@ fn generate_rule_to_code(linter_to_rules: &BTreeMap<Ident, BTreeMap<String, Rule
}
let mut rule_noqa_code_match_arms = quote!();
let mut noqa_code_rule_match_arms = quote!();
let mut rule_group_match_arms = quote!();
let mut noqa_code_consts = quote!();
for (i, (rule, codes)) in rule_to_codes.into_iter().enumerate() {
for (rule, codes) in rule_to_codes {
let rule_name = rule.segments.last().unwrap();
assert_eq!(
codes.len(),
@ -294,14 +292,6 @@ See also https://github.com/astral-sh/ruff/issues/2186.
#(#attrs)* Rule::#rule_name => NoqaCode(crate::registry::Linter::#linter.common_prefix(), #code),
});
let const_ident = quote::format_ident!("NOQA_PREFIX_{}", i);
noqa_code_consts.extend(quote! {
const #const_ident: &str = crate::registry::Linter::#linter.common_prefix();
});
noqa_code_rule_match_arms.extend(quote! {
#(#attrs)* NoqaCode(#const_ident, #code) => Some(Rule::#rule_name),
});
rule_group_match_arms.extend(quote! {
#(#attrs)* Rule::#rule_name => #group,
});
@ -350,16 +340,6 @@ See also https://github.com/astral-sh/ruff/issues/2186.
}
}
}
impl NoqaCode {
pub fn rule(&self) -> Option<Rule> {
#noqa_code_consts
match self {
#noqa_code_rule_match_arms
_ => None
}
}
}
};
rule_to_code
}

View file

@ -118,6 +118,10 @@ pub(crate) fn derive_impl(input: DeriveInput) -> syn::Result<proc_macro2::TokenS
None
}
fn common_prefix(&self) -> &'static str {
match self { #common_prefix_match_arms }
}
fn name(&self) -> &'static str {
match self { #name_match_arms }
}
@ -126,16 +130,6 @@ pub(crate) fn derive_impl(input: DeriveInput) -> syn::Result<proc_macro2::TokenS
match self { #url_match_arms }
}
}
impl #ident {
/// Returns the prefix that every single code that ruff uses to identify
/// rules from this linter starts with. In the case that multiple
/// `#[prefix]`es are configured for the variant in the `Linter` enum
/// definition this is the empty string.
pub const fn common_prefix(&self) -> &'static str {
match self { #common_prefix_match_arms }
}
}
})
}