Conversation
Summary -- It's a bit late in the refactoring process, but I think there are still a couple of PRs left before getting rid of this type entirely, so I thought it would still be worth doing. This PR is just a quick rename with no other changes. Test Plan -- Existing tests
Summary -- This is the last main difference between the `OldDiagnostic` and `Message` types, so attaching a `SourceFile` to `OldDiagnostic` should make combining the two types almost trivial. Most of the `OldDiagnostic::new` calls in lint rules were already replaced in the `DiagnosticGuard`/`Checker::report_diagnostic` refactor, but there were still quite a few rules without access to a `Checker` that required passing a `&SourceFile` directly. Test Plan -- Existing tests
|
MichaReiser
left a comment
There was a problem hiding this comment.
This looks good. The only annoyance is that this introduces a new argument to so many functions. It may be worth checking if we can replace some Locator usages by using SourceFile instead (str implements Located which gives access to most methods on Locator))
crates/ruff_linter/src/rules/pycodestyle/rules/logical_lines/whitespace_before_parameters.rs
Outdated
Show resolved
Hide resolved
crates/ruff_linter/src/rules/flake8_pyi/rules/type_comment_in_stub.rs
Outdated
Show resolved
Hide resolved
|
I ran with your suggestion about the |
MichaReiser
left a comment
There was a problem hiding this comment.
I haven't done a full review but here some thoughts
| semantic_checker: SemanticSyntaxChecker, | ||
| /// Errors collected by the `semantic_checker`. | ||
| semantic_errors: RefCell<Vec<SemanticSyntaxError>>, | ||
| collector: &'a DiagnosticsCollector<'a>, |
There was a problem hiding this comment.
Nit. Maybe rename to diagnostics. It's the more important part of the name
There was a problem hiding this comment.
Ah okay, that makes sense. I replaced all of them!
Do you think diagnostics.report_diagnostic is too repetitive? And diagnostics.into_diagnostics, though that one is much less common.
There was a problem hiding this comment.
It's not ideal for sure :) I also thought about LintContext That would allow us to put more stuff on it that's needed by all lint rules and isn't directly tied to Checker.
There was a problem hiding this comment.
I like that. I can do one more rename to LintContext and update the variable names to context.
| if matches!(rule, Rule::BlanketNOQA) { | ||
| continue; | ||
| } | ||
| collector.with_diagnostics(|diagnostics| { |
There was a problem hiding this comment.
I think this api opens the door for multiple mutable borrows. First when calling with_diagnostics and then when calling report_diagnostics on the collector. I think I would instead add an as_mut_slice method that takes a mut self. The method here should then also require no changes
There was a problem hiding this comment.
Thanks, these all make sense. I saw RefCell and just made everything &self without thinking about this.
There was a problem hiding this comment.
Actually, I may be slightly misunderstanding in this case. What do you mean by the as_mut_slice method? I tried writing
pub(crate) fn as_mut_slice(&mut self) -> &mut [OldDiagnostic] {
self.diagnostics.borrow_mut().as_mut_slice()
}but the temporary value from borrow_mut is dropped in the function and can't be returned. This is actually the original problem I ran into. All I really wanted was to call self.diagnostics.borrow().iter(), but the borrow gets dropped. That's what led me to add with_diagnostics.
For now I've just updated with_diagnostics to take a &mut self like retain and swap_remove.
There was a problem hiding this comment.
You can use self.diagnostics.get_mut when you have a &self mut because the borrow checker than guarantees that no one else can be mutating diagnostic.
There was a problem hiding this comment.
Oh 🤦 Thank you!
I think I'll just replace all of these helper methods with an as_mut method. Some of them actually need the Vec, so I'm thinking either as_mut_vec or maybe as_diagnostics for the name.
I also added an iter method, also using get_mut, just to avoid having to call as_mut_vec().iter().
crates/ruff_linter/src/linter.rs
Outdated
| if let Some(line_index) = locator.line_index() { | ||
| builder.set_line_index(line_index.clone()); | ||
| } |
There was a problem hiding this comment.
We can probably just remove this. At this point, it's almost guaranteed that the line index is none (unless I"m mistaken)
* main: [ty] support callability of bound/constrained typevars (#18389) [ty] Minor tweaks to "list all members" docs and tests (#18388) [ty] Fix broken property tests for disjointness (#18384) [ty] List available members for a given type (#18251) [`airflow`] Add unsafe fix for module moved cases (`AIR312`) (#18363) Add a `SourceFile` to `OldDiagnostic` (#18356) Update salsa past generational id change (#18362) [`airflow`] Add unsafe fix for module moved cases (`AIR311`) (#18366) [`airflow`] Add unsafe fix for module moved cases (`AIR301`) (#18367) [ty] Improve tests for `site-packages` discovery (#18374) [ty] _typeshed.Self is not a special form (#18377) [ty] Callable types are disjoint from non-callable `@final` nominal instance types (#18368) [ty] Add diagnosis for function with no return statement but with return type annotation (#18359) [`airflow`] Add unsafe fix module moved cases (`AIR302`) (#18093) Rename `ruff_linter::Diagnostic` to `OldDiagnostic` (#18355) [`refurb`] Add coverage of `set` and `frozenset` calls (`FURB171`) (#18035)
Summary
This is the last main difference between the
OldDiagnosticandMessagetypes, so attaching a
SourceFiletoOldDiagnosticshould make combining thetwo types almost trivial.
Initially I updated the remaining rules without access to a
Checkerto take a&SourceFiledirectly, but after Micha's suggestion in #18356 (comment), I updated all of these calls to take aLintContextinstead. This new type is a thin wrapper around aRefCell<Vec<OldDiagnostic>>and a
SourceFileand now has thereport_diagnosticmethod returning aDiagnosticGuardinstead ofChecker.This allows the same
Drop-based implementation to be used in cases without aCheckerand also avoids a lot of intermediate allocations ofVec<OldDiagnostic>s.Checkernow also contains aLintContext, which it defers to for itsreport_diagnosticmethods, which I preserved for convenience.Test Plan
Existing tests