Upgrade to Rust 1.86 and bump MSRV to 1.84 (#17171)

<!--
Thank you for contributing to Ruff! To help us out with reviewing,
please consider the following:

- Does this pull request include a summary of the change? (See below.)
- Does this pull request include a descriptive title?
- Does this pull request include references to any relevant issues?
-->

## Summary

I decided to disable the new
[`needless_continue`](https://rust-lang.github.io/rust-clippy/master/index.html#needless_continue)
rule because I often found the explicit `continue` more readable over an
empty block or having to invert the condition of an other branch.


## Test Plan

`cargo test`

---------

Co-authored-by: Alex Waygood <Alex.Waygood@Gmail.com>
This commit is contained in:
Micha Reiser 2025-04-03 17:59:44 +02:00 committed by GitHub
parent fedd982fd5
commit 8a4158c5f8
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
135 changed files with 285 additions and 255 deletions

View File

@ -4,7 +4,7 @@ resolver = "2"
[workspace.package] [workspace.package]
edition = "2021" edition = "2021"
rust-version = "1.83" rust-version = "1.84"
homepage = "https://docs.astral.sh/ruff" homepage = "https://docs.astral.sh/ruff"
documentation = "https://docs.astral.sh/ruff" documentation = "https://docs.astral.sh/ruff"
repository = "https://github.com/astral-sh/ruff" repository = "https://github.com/astral-sh/ruff"
@ -209,6 +209,7 @@ must_use_candidate = "allow"
similar_names = "allow" similar_names = "allow"
single_match_else = "allow" single_match_else = "allow"
too_many_lines = "allow" too_many_lines = "allow"
needless_continue = "allow" # An explicit continue can be more readable, especially if the alternative is an empty block.
# Without the hashes we run into a `rustfmt` bug in some snapshot tests, see #13250 # Without the hashes we run into a `rustfmt` bug in some snapshot tests, see #13250
needless_raw_string_hashes = "allow" needless_raw_string_hashes = "allow"
# Disallowed restriction lints # Disallowed restriction lints
@ -227,6 +228,10 @@ redundant_clone = "warn"
debug_assert_with_mut_call = "warn" debug_assert_with_mut_call = "warn"
unused_peekable = "warn" unused_peekable = "warn"
# Has false positives
# https://github.com/rust-lang/rust-clippy/issues/14275
doc_overindented_list_items = "allow"
# Diagnostics are not actionable: Enable once https://github.com/rust-lang/rust-clippy/issues/13774 is resolved. # Diagnostics are not actionable: Enable once https://github.com/rust-lang/rust-clippy/issues/13774 is resolved.
large_stack_arrays = "allow" large_stack_arrays = "allow"

View File

@ -159,7 +159,7 @@ impl salsa::Database for ProjectDatabase {
} }
let event = event(); let event = event();
if matches!(event.kind, salsa::EventKind::WillCheckCancellation { .. }) { if matches!(event.kind, salsa::EventKind::WillCheckCancellation) {
return; return;
} }

View File

@ -187,7 +187,7 @@ impl ProjectDatabase {
let program = Program::get(self); let program = Program::get(self);
if let Err(error) = program.update_from_settings(self, program_settings) { if let Err(error) = program.update_from_settings(self, program_settings) {
tracing::error!("Failed to update the program settings, keeping the old program settings: {error}"); tracing::error!("Failed to update the program settings, keeping the old program settings: {error}");
}; }
if metadata.root() == project.root(self) { if metadata.root() == project.root(self) {
tracing::debug!("Reloading project after structural change"); tracing::debug!("Reloading project after structural change");

View File

@ -322,6 +322,7 @@ fn python_version_from_versions_file_string(
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use std::fmt::Write as _;
use std::num::{IntErrorKind, NonZeroU16}; use std::num::{IntErrorKind, NonZeroU16};
use std::path::Path; use std::path::Path;
@ -333,8 +334,7 @@ mod tests {
const TYPESHED_STDLIB_DIR: &str = "stdlib"; const TYPESHED_STDLIB_DIR: &str = "stdlib";
#[allow(unsafe_code)] const ONE: Option<NonZeroU16> = Some(NonZeroU16::new(1).unwrap());
const ONE: Option<NonZeroU16> = Some(unsafe { NonZeroU16::new_unchecked(1) });
impl TypeshedVersions { impl TypeshedVersions {
#[must_use] #[must_use]
@ -571,7 +571,7 @@ foo: 3.8- # trailing comment
let mut massive_versions_file = String::new(); let mut massive_versions_file = String::new();
for i in 0..too_many { for i in 0..too_many {
massive_versions_file.push_str(&format!("x{i}: 3.8-\n")); let _ = writeln!(&mut massive_versions_file, "x{i}: 3.8-");
} }
assert_eq!( assert_eq!(

View File

@ -1448,7 +1448,7 @@ where
self.visit_expr(subject); self.visit_expr(subject);
if cases.is_empty() { if cases.is_empty() {
return; return;
}; }
let after_subject = self.flow_snapshot(); let after_subject = self.flow_snapshot();
let mut vis_constraints = vec![]; let mut vis_constraints = vec![];

View File

@ -145,7 +145,7 @@ pub(crate) fn check_suppressions(db: &dyn Db, file: File, diagnostics: &mut Type
fn check_unknown_rule(context: &mut CheckSuppressionsContext) { fn check_unknown_rule(context: &mut CheckSuppressionsContext) {
if context.is_lint_disabled(&UNKNOWN_RULE) { if context.is_lint_disabled(&UNKNOWN_RULE) {
return; return;
}; }
for unknown in &context.suppressions.unknown { for unknown in &context.suppressions.unknown {
match &unknown.reason { match &unknown.reason {
@ -174,7 +174,7 @@ fn check_unknown_rule(context: &mut CheckSuppressionsContext) {
format_args!("Unknown rule `{prefixed}`. Did you mean `{suggestion}`?"), format_args!("Unknown rule `{prefixed}`. Did you mean `{suggestion}`?"),
); );
} }
}; }
} }
} }
@ -267,7 +267,7 @@ fn check_unused_suppressions(context: &mut CheckSuppressionsContext) {
suppression.range, suppression.range,
format_args!("Unused `{kind}` without a code", kind = suppression.kind), format_args!("Unused `{kind}` without a code", kind = suppression.kind),
), ),
}; }
} }
} }

View File

@ -657,7 +657,7 @@ fn symbol_from_bindings_impl<'db>(
binding, binding,
visibility_constraint, visibility_constraint,
narrowing_constraint: _, narrowing_constraint: _,
}) if binding.map_or(true, is_non_exported) => { }) if binding.is_none_or(is_non_exported) => {
visibility_constraints.evaluate(db, predicates, *visibility_constraint) visibility_constraints.evaluate(db, predicates, *visibility_constraint)
} }
_ => Truthiness::AlwaysFalse, _ => Truthiness::AlwaysFalse,
@ -794,7 +794,7 @@ fn symbol_from_declarations_impl<'db>(
Some(DeclarationWithConstraint { Some(DeclarationWithConstraint {
declaration, declaration,
visibility_constraint, visibility_constraint,
}) if declaration.map_or(true, is_non_exported) => { }) if declaration.is_none_or(is_non_exported) => {
visibility_constraints.evaluate(db, predicates, *visibility_constraint) visibility_constraints.evaluate(db, predicates, *visibility_constraint)
} }
_ => Truthiness::AlwaysFalse, _ => Truthiness::AlwaysFalse,

View File

@ -502,13 +502,13 @@ impl<'db> Bindings<'db> {
if let Some(len_ty) = first_arg.len(db) { if let Some(len_ty) = first_arg.len(db) {
overload.set_return_type(len_ty); overload.set_return_type(len_ty);
} }
}; }
} }
Some(KnownFunction::Repr) => { Some(KnownFunction::Repr) => {
if let [Some(first_arg)] = overload.parameter_types() { if let [Some(first_arg)] = overload.parameter_types() {
overload.set_return_type(first_arg.repr(db)); overload.set_return_type(first_arg.repr(db));
}; }
} }
Some(KnownFunction::Cast) => { Some(KnownFunction::Cast) => {

View File

@ -985,7 +985,7 @@ impl<'db> TypeInferenceBuilder<'db> {
Some(KnownClass::Float | KnownClass::Int | KnownClass::Bool) Some(KnownClass::Float | KnownClass::Int | KnownClass::Bool)
) => {} ) => {}
_ => return false, _ => return false,
}; }
let (op, by_zero) = match op { let (op, by_zero) = match op {
ast::Operator::Div => ("divide", "by zero"), ast::Operator::Div => ("divide", "by zero"),
@ -1036,7 +1036,7 @@ impl<'db> TypeInferenceBuilder<'db> {
report_invalid_assignment(&self.context, node, declared_ty, bound_ty); report_invalid_assignment(&self.context, node, declared_ty, bound_ty);
// allow declarations to override inference in case of invalid assignment // allow declarations to override inference in case of invalid assignment
bound_ty = declared_ty; bound_ty = declared_ty;
}; }
self.types.bindings.insert(binding, bound_ty); self.types.bindings.insert(binding, bound_ty);
} }
@ -2216,7 +2216,7 @@ impl<'db> TypeInferenceBuilder<'db> {
} }
} }
ast::Pattern::MatchStar(_) | ast::Pattern::MatchSingleton(_) => {} ast::Pattern::MatchStar(_) | ast::Pattern::MatchSingleton(_) => {}
}; }
} }
fn infer_assignment_statement(&mut self, assignment: &ast::StmtAssign) { fn infer_assignment_statement(&mut self, assignment: &ast::StmtAssign) {
@ -3242,7 +3242,7 @@ impl<'db> TypeInferenceBuilder<'db> {
&DeclaredAndInferredType::AreTheSame(ty), &DeclaredAndInferredType::AreTheSame(ty),
); );
return; return;
}; }
// If the module doesn't bind the symbol, check if it's a submodule. This won't get // If the module doesn't bind the symbol, check if it's a submodule. This won't get
// handled by the `Type::member` call because it relies on the semantic index's // handled by the `Type::member` call because it relies on the semantic index's
@ -4044,7 +4044,7 @@ impl<'db> TypeInferenceBuilder<'db> {
parameter_ty=parameter_ty.display(self.db()) parameter_ty=parameter_ty.display(self.db())
), ),
); );
}; }
} }
} }
} }
@ -4895,7 +4895,7 @@ impl<'db> TypeInferenceBuilder<'db> {
if done { if done {
return Type::Never; return Type::Never;
}; }
match (truthiness, op) { match (truthiness, op) {
(Truthiness::AlwaysTrue, ast::BoolOp::And) => Type::Never, (Truthiness::AlwaysTrue, ast::BoolOp::And) => Type::Never,
@ -5815,7 +5815,7 @@ impl<'db> TypeInferenceBuilder<'db> {
Err(CallDunderError::MethodNotAvailable) => { Err(CallDunderError::MethodNotAvailable) => {
// try `__class_getitem__` // try `__class_getitem__`
} }
}; }
// Otherwise, if the value is itself a class and defines `__class_getitem__`, // Otherwise, if the value is itself a class and defines `__class_getitem__`,
// return its return type. // return its return type.

View File

@ -30,7 +30,7 @@ impl SlotsKind {
if matches!(bound, Boundness::PossiblyUnbound) { if matches!(bound, Boundness::PossiblyUnbound) {
return Self::Dynamic; return Self::Dynamic;
}; }
match slots_ty { match slots_ty {
// __slots__ = ("a", "b") // __slots__ = ("a", "b")
@ -98,6 +98,6 @@ pub(super) fn check_class_slots(context: &InferContext, class: Class, node: &ast
if let Some(index) = first_with_solid_base { if let Some(index) = first_with_solid_base {
let base_node = &node.bases()[index]; let base_node = &node.bases()[index];
report_base_with_incompatible_slots(context, base_node); report_base_with_incompatible_slots(context, base_node);
}; }
} }
} }

View File

@ -116,8 +116,10 @@ impl<'db> Unpacker<'db> {
// it's worth it. // it's worth it.
TupleType::from_elements( TupleType::from_elements(
self.db(), self.db(),
std::iter::repeat(Type::LiteralString) std::iter::repeat_n(
.take(string_literal_ty.python_len(self.db())), Type::LiteralString,
string_literal_ty.python_len(self.db()),
),
) )
} }
_ => ty, _ => ty,

View File

@ -131,7 +131,7 @@ impl<'a> Iterator for AssertionWithRangeIterator<'a> {
let comment = &self.file_assertions.source[inner_next]; let comment = &self.file_assertions.source[inner_next];
if let Some(assertion) = UnparsedAssertion::from_comment(comment) { if let Some(assertion) = UnparsedAssertion::from_comment(comment) {
return Some(AssertionWithRange(assertion, inner_next)); return Some(AssertionWithRange(assertion, inner_next));
}; }
} }
} }
} }

View File

@ -265,13 +265,13 @@ fn run_test(
match info.location { match info.location {
Some(location) => messages.push(format!("panicked at {location}")), Some(location) => messages.push(format!("panicked at {location}")),
None => messages.push("panicked at unknown location".to_string()), None => messages.push("panicked at unknown location".to_string()),
}; }
match info.payload { match info.payload {
Some(payload) => messages.push(payload), Some(payload) => messages.push(payload),
// Mimic the default panic hook's rendering of the panic payload if it's // Mimic the default panic hook's rendering of the panic payload if it's
// not a string. // not a string.
None => messages.push("Box<dyn Any>".to_string()), None => messages.push("Box<dyn Any>".to_string()),
}; }
if let Some(backtrace) = info.backtrace { if let Some(backtrace) = info.backtrace {
if std::env::var("RUST_BACKTRACE").is_ok() { if std::env::var("RUST_BACKTRACE").is_ok() {
messages.extend(backtrace.to_string().split('\n').map(String::from)); messages.extend(backtrace.to_string().split('\n').map(String::from));

View File

@ -673,7 +673,7 @@ impl<'s> Parser<'s> {
"Test `{test_name}` has duplicate files named `{}`.", "Test `{test_name}` has duplicate files named `{}`.",
path.as_str(), path.as_str(),
); );
}; }
if has_explicit_file_paths { if has_explicit_file_paths {
bail!("Merged snippets in test `{test_name}` are not allowed in the presence of other files."); bail!("Merged snippets in test `{test_name}` are not allowed in the presence of other files.");

View File

@ -1,5 +1,5 @@
use std::cmp::Ordering; use std::cmp::Ordering;
use std::fmt::Formatter; use std::fmt::{Formatter, Write as _};
use std::ops::Deref; use std::ops::Deref;
use std::path::{Path, PathBuf}; use std::path::{Path, PathBuf};
use std::str::FromStr; use std::str::FromStr;
@ -974,12 +974,13 @@ A `--config` flag must either be a path to a `.toml` configuration file
.is_some_and(|ext| ext.eq_ignore_ascii_case("toml")) .is_some_and(|ext| ext.eq_ignore_ascii_case("toml"))
{ {
if !value.contains('=') { if !value.contains('=') {
tip.push_str(&format!( let _ = write!(
&mut tip,
" "
It looks like you were trying to pass a path to a configuration file. It looks like you were trying to pass a path to a configuration file.
The path `{value}` does not point to a configuration file" The path `{value}` does not point to a configuration file"
)); );
} }
} else if let Some((key, value)) = value.split_once('=') { } else if let Some((key, value)) = value.split_once('=') {
let key = key.trim_ascii(); let key = key.trim_ascii();
@ -993,7 +994,8 @@ The path `{value}` does not point to a configuration file"
.map(|(name, _)| format!("- `{key}.{name}`")) .map(|(name, _)| format!("- `{key}.{name}`"))
.join("\n"); .join("\n");
tip.push_str(&format!( let _ = write!(
&mut tip,
" "
`{key}` is a table of configuration options. `{key}` is a table of configuration options.
@ -1002,13 +1004,14 @@ Did you want to override one of the table's subkeys?
Possible choices: Possible choices:
{prefixed_subfields}" {prefixed_subfields}"
)); );
} }
_ => { _ => {
tip.push_str(&format!( let _ = write!(
&mut tip,
"\n\n{}:\n\n{underlying_error}", "\n\n{}:\n\n{underlying_error}",
config_parse_error.description() config_parse_error.description()
)); );
} }
} }
} }

View File

@ -1,3 +1,4 @@
use std::fmt::Write as _;
use std::io::{self, BufWriter, Write}; use std::io::{self, BufWriter, Write};
use anyhow::Result; use anyhow::Result;
@ -43,12 +44,16 @@ impl<'a> Explanation<'a> {
fn format_rule_text(rule: Rule) -> String { fn format_rule_text(rule: Rule) -> String {
let mut output = String::new(); let mut output = String::new();
output.push_str(&format!("# {} ({})", rule.as_ref(), rule.noqa_code())); let _ = write!(&mut output, "# {} ({})", rule.as_ref(), rule.noqa_code());
output.push('\n'); output.push('\n');
output.push('\n'); output.push('\n');
let (linter, _) = Linter::parse_code(&rule.noqa_code().to_string()).unwrap(); let (linter, _) = Linter::parse_code(&rule.noqa_code().to_string()).unwrap();
output.push_str(&format!("Derived from the **{}** linter.", linter.name())); let _ = write!(
&mut output,
"Derived from the **{}** linter.",
linter.name()
);
output.push('\n'); output.push('\n');
output.push('\n'); output.push('\n');
@ -76,7 +81,7 @@ fn format_rule_text(rule: Rule) -> String {
output.push_str("Message formats:"); output.push_str("Message formats:");
for format in rule.message_formats() { for format in rule.message_formats() {
output.push('\n'); output.push('\n');
output.push_str(&format!("* {format}")); let _ = write!(&mut output, "* {format}");
} }
} }
output output
@ -92,7 +97,7 @@ pub(crate) fn rule(rule: Rule, format: HelpFormat) -> Result<()> {
HelpFormat::Json => { HelpFormat::Json => {
serde_json::to_writer_pretty(stdout, &Explanation::from_rule(&rule))?; serde_json::to_writer_pretty(stdout, &Explanation::from_rule(&rule))?;
} }
}; }
Ok(()) Ok(())
} }

View File

@ -16,6 +16,6 @@ pub(crate) fn version(output_format: HelpFormat) -> Result<()> {
HelpFormat::Json => { HelpFormat::Json => {
serde_json::to_writer_pretty(stdout, &version_info)?; serde_json::to_writer_pretty(stdout, &version_info)?;
} }
}; }
Ok(()) Ok(())
} }

View File

@ -31,7 +31,7 @@ pub fn main() -> ExitCode {
// support FORCE_COLOR env var // support FORCE_COLOR env var
if let Some(force_color) = std::env::var_os("FORCE_COLOR") { if let Some(force_color) = std::env::var_os("FORCE_COLOR") {
if force_color.len() > 0 { if !force_color.is_empty() {
colored::control::set_override(true); colored::control::set_override(true);
} }
} }

View File

@ -315,7 +315,7 @@ impl DisplaySet<'_> {
None => { None => {
buffer.putc(line_offset, lineno_width + 1, '|', *lineno_color); buffer.putc(line_offset, lineno_width + 1, '|', *lineno_color);
} }
}; }
} }
if let DisplaySourceLine::Content { text, .. } = line { if let DisplaySourceLine::Content { text, .. } = line {
// The width of the line number, a space, pipe, and a space // The width of the line number, a space, pipe, and a space
@ -1753,7 +1753,7 @@ fn format_inline_marks(
DisplayMarkType::AnnotationThrough(depth) => { DisplayMarkType::AnnotationThrough(depth) => {
buf.putc(line, 3 + lineno_width + depth, '|', *annotation_style); buf.putc(line, 3 + lineno_width + depth, '|', *annotation_style);
} }
}; }
} }
Ok(()) Ok(())
} }

View File

@ -2,6 +2,7 @@
#![allow(clippy::print_stdout, clippy::print_stderr)] #![allow(clippy::print_stdout, clippy::print_stderr)]
use std::collections::HashSet; use std::collections::HashSet;
use std::fmt::Write as _;
use std::fs; use std::fs;
use std::path::PathBuf; use std::path::PathBuf;
@ -29,8 +30,7 @@ pub(crate) fn main(args: &Args) -> Result<()> {
if let Some(explanation) = rule.explanation() { if let Some(explanation) = rule.explanation() {
let mut output = String::new(); let mut output = String::new();
output.push_str(&format!("# {} ({})", rule.as_ref(), rule.noqa_code())); let _ = writeln!(&mut output, "# {} ({})", rule.as_ref(), rule.noqa_code());
output.push('\n');
let (linter, _) = Linter::parse_code(&rule.noqa_code().to_string()).unwrap(); let (linter, _) = Linter::parse_code(&rule.noqa_code().to_string()).unwrap();
if linter.url().is_some() { if linter.url().is_some() {
@ -49,11 +49,12 @@ pub(crate) fn main(args: &Args) -> Result<()> {
common_prefix.to_lowercase() common_prefix.to_lowercase()
); );
output.push_str(&format!( let _ = write!(
output,
"Derived from the **[{}](../rules.md#{})** linter.", "Derived from the **[{}](../rules.md#{})** linter.",
linter.name(), linter.name(),
anchor anchor,
)); );
output.push('\n'); output.push('\n');
output.push('\n'); output.push('\n');
} }
@ -155,8 +156,8 @@ fn process_documentation(documentation: &str, out: &mut String, rule_name: &str)
} }
let anchor = option.replace('.', "_"); let anchor = option.replace('.', "_");
out.push_str(&format!("- [`{option}`][{option}]\n")); let _ = writeln!(out, "- [`{option}`][{option}]");
after.push_str(&format!("[{option}]: ../settings.md#{anchor}\n")); let _ = writeln!(&mut after, "[{option}]: ../settings.md#{anchor}");
referenced_options.insert(option); referenced_options.insert(option);
continue; continue;
@ -171,7 +172,7 @@ fn process_documentation(documentation: &str, out: &mut String, rule_name: &str)
if let Some(OptionEntry::Field(field)) = Options::metadata().find(option) { if let Some(OptionEntry::Field(field)) = Options::metadata().find(option) {
if referenced_options.insert(option) { if referenced_options.insert(option) {
let anchor = option.replace('.', "_"); let anchor = option.replace('.', "_");
after.push_str(&format!("[{option}]: ../settings.md#{anchor}\n")); let _ = writeln!(&mut after, "[{option}]: ../settings.md#{anchor}");
} }
if field.deprecated.is_some() { if field.deprecated.is_some() {
eprintln!("Rule {rule_name} references deprecated option {option}."); eprintln!("Rule {rule_name} references deprecated option {option}.");

View File

@ -98,17 +98,16 @@ fn emit_field(output: &mut String, name: &str, field: &OptionField, parents: &[S
let parents_anchor = parents.iter().filter_map(|parent| parent.name()).join("_"); let parents_anchor = parents.iter().filter_map(|parent| parent.name()).join("_");
if parents_anchor.is_empty() { if parents_anchor.is_empty() {
output.push_str(&format!( let _ = writeln!(output, "{header_level} [`{name}`](#{name}) {{: #{name} }}");
"{header_level} [`{name}`](#{name}) {{: #{name} }}\n"
));
} else { } else {
output.push_str(&format!( let _ =
"{header_level} [`{name}`](#{parents_anchor}_{name}) {{: #{parents_anchor}_{name} }}\n" writeln!(output,
)); "{header_level} [`{name}`](#{parents_anchor}_{name}) {{: #{parents_anchor}_{name} }}"
);
// the anchor used to just be the name, but now it's the group name // the anchor used to just be the name, but now it's the group name
// for backwards compatibility, we need to keep the old anchor // for backwards compatibility, we need to keep the old anchor
output.push_str(&format!("<span id=\"{name}\"></span>\n")); let _ = writeln!(output, "<span id=\"{name}\"></span>");
} }
output.push('\n'); output.push('\n');
@ -132,9 +131,9 @@ fn emit_field(output: &mut String, name: &str, field: &OptionField, parents: &[S
output.push_str(field.doc); output.push_str(field.doc);
output.push_str("\n\n"); output.push_str("\n\n");
output.push_str(&format!("**Default value**: `{}`\n", field.default)); let _ = writeln!(output, "**Default value**: `{}`", field.default);
output.push('\n'); output.push('\n');
output.push_str(&format!("**Type**: `{}`\n", field.value_type)); let _ = writeln!(output, "**Type**: `{}`", field.value_type);
output.push('\n'); output.push('\n');
output.push_str("**Example usage**:\n\n"); output.push_str("**Example usage**:\n\n");
output.push_str(&format_tab( output.push_str(&format_tab(

View File

@ -5,6 +5,7 @@
use itertools::Itertools; use itertools::Itertools;
use ruff_linter::codes::RuleGroup; use ruff_linter::codes::RuleGroup;
use std::borrow::Cow; use std::borrow::Cow;
use std::fmt::Write;
use strum::IntoEnumIterator; use strum::IntoEnumIterator;
use ruff_diagnostics::FixAvailability; use ruff_diagnostics::FixAvailability;
@ -78,7 +79,8 @@ fn generate_table(table_out: &mut String, rules: impl IntoIterator<Item = Rule>,
} }
#[allow(clippy::or_fun_call)] #[allow(clippy::or_fun_call)]
table_out.push_str(&format!( let _ = write!(
table_out,
"| {ss}{0}{1}{se} {{ #{0}{1} }} | {ss}{2}{se} | {ss}{3}{se} | {ss}{4}{se} |", "| {ss}{0}{1}{se} {{ #{0}{1} }} | {ss}{2}{se} | {ss}{3}{se} | {ss}{4}{se} |",
linter.common_prefix(), linter.common_prefix(),
linter.code_for_rule(rule).unwrap(), linter.code_for_rule(rule).unwrap(),
@ -88,7 +90,7 @@ fn generate_table(table_out: &mut String, rules: impl IntoIterator<Item = Rule>,
.unwrap_or(format_args!("{rule_name}")), .unwrap_or(format_args!("{rule_name}")),
message, message,
tokens, tokens,
)); );
table_out.push('\n'); table_out.push('\n');
} }
table_out.push('\n'); table_out.push('\n');
@ -101,29 +103,30 @@ pub(crate) fn generate() -> String {
table_out.push_str("### Legend"); table_out.push_str("### Legend");
table_out.push('\n'); table_out.push('\n');
table_out.push_str(&format!( let _ = write!(
&mut table_out,
"{SPACER}{STABLE_SYMBOL}{SPACER} The rule is stable." "{SPACER}{STABLE_SYMBOL}{SPACER} The rule is stable."
)); );
table_out.push_str("<br />"); table_out.push_str("<br />");
table_out.push_str(&format!( let _ = write!(&mut table_out,
"{SPACER}{PREVIEW_SYMBOL}{SPACER} The rule is unstable and is in [\"preview\"](faq.md#what-is-preview)." "{SPACER}{PREVIEW_SYMBOL}{SPACER} The rule is unstable and is in [\"preview\"](faq.md#what-is-preview)."
)); );
table_out.push_str("<br />"); table_out.push_str("<br />");
table_out.push_str(&format!( let _ = write!(&mut table_out,
"{SPACER}{WARNING_SYMBOL}{SPACER} The rule has been deprecated and will be removed in a future release." "{SPACER}{WARNING_SYMBOL}{SPACER} The rule has been deprecated and will be removed in a future release."
)); );
table_out.push_str("<br />"); table_out.push_str("<br />");
table_out.push_str(&format!( let _ = write!(&mut table_out,
"{SPACER}{REMOVED_SYMBOL}{SPACER} The rule has been removed only the documentation is available." "{SPACER}{REMOVED_SYMBOL}{SPACER} The rule has been removed only the documentation is available."
)); );
table_out.push_str("<br />"); table_out.push_str("<br />");
table_out.push_str(&format!( let _ = write!(&mut table_out,
"{SPACER}{FIX_SYMBOL}{SPACER} The rule is automatically fixable by the `--fix` command-line option." "{SPACER}{FIX_SYMBOL}{SPACER} The rule is automatically fixable by the `--fix` command-line option."
)); );
table_out.push_str("<br />"); table_out.push_str("<br />");
table_out.push('\n'); table_out.push('\n');
@ -137,7 +140,7 @@ pub(crate) fn generate() -> String {
.join(", "), .join(", "),
prefix => prefix.to_string(), prefix => prefix.to_string(),
}; };
table_out.push_str(&format!("### {} ({codes_csv})", linter.name())); let _ = write!(&mut table_out, "### {} ({codes_csv})", linter.name());
table_out.push('\n'); table_out.push('\n');
table_out.push('\n'); table_out.push('\n');
@ -147,7 +150,8 @@ pub(crate) fn generate() -> String {
.split('/') .split('/')
.next() .next()
.unwrap(); .unwrap();
table_out.push_str(&format!( let _ = write!(
table_out,
"For more, see [{}]({}) on {}.", "For more, see [{}]({}) on {}.",
linter.name(), linter.name(),
url, url,
@ -160,17 +164,18 @@ pub(crate) fn generate() -> String {
linter.name() linter.name()
), ),
} }
)); );
table_out.push('\n'); table_out.push('\n');
table_out.push('\n'); table_out.push('\n');
} }
if Options::metadata().has(&format!("lint.{}", linter.name())) { if Options::metadata().has(&format!("lint.{}", linter.name())) {
table_out.push_str(&format!( let _ = write!(
table_out,
"For related settings, see [{}](settings.md#lint{}).", "For related settings, see [{}](settings.md#lint{}).",
linter.name(), linter.name(),
linter.name(), linter.name(),
)); );
table_out.push('\n'); table_out.push('\n');
table_out.push('\n'); table_out.push('\n');
} }
@ -200,10 +205,10 @@ pub(crate) fn generate() -> String {
let UpstreamCategoryAndPrefix { category, prefix } = opt.unwrap(); let UpstreamCategoryAndPrefix { category, prefix } = opt.unwrap();
match codes_csv.as_str() { match codes_csv.as_str() {
"PL" => { "PL" => {
table_out.push_str(&format!("#### {category} ({codes_csv}{prefix})")); let _ = write!(table_out, "#### {category} ({codes_csv}{prefix})");
} }
_ => { _ => {
table_out.push_str(&format!("#### {category} ({prefix})")); let _ = write!(table_out, "#### {category} ({prefix})");
} }
} }
} }

View File

@ -610,7 +610,7 @@ impl Format<IrFormatContext<'_>> for &[FormatElement] {
} }
} }
StartEntry | StartBestFittingEntry { .. } => { StartEntry | StartBestFittingEntry => {
// handled after the match for all start tags // handled after the match for all start tags
} }
EndEntry | EndBestFittingEntry => write!(f, [ContentArrayEnd])?, EndEntry | EndBestFittingEntry => write!(f, [ContentArrayEnd])?,
@ -630,7 +630,7 @@ impl Format<IrFormatContext<'_>> for &[FormatElement] {
| EndVerbatim => { | EndVerbatim => {
write!(f, [ContentArrayEnd, token(")")])?; write!(f, [ContentArrayEnd, token(")")])?;
} }
}; }
if tag.is_start() { if tag.is_start() {
write!(f, [ContentArrayStart])?; write!(f, [ContentArrayStart])?;

View File

@ -144,7 +144,7 @@ impl Tag {
StartVerbatim(_) | EndVerbatim => TagKind::Verbatim, StartVerbatim(_) | EndVerbatim => TagKind::Verbatim,
StartLabelled(_) | EndLabelled => TagKind::Labelled, StartLabelled(_) | EndLabelled => TagKind::Labelled,
StartFitsExpanded { .. } | EndFitsExpanded => TagKind::FitsExpanded, StartFitsExpanded { .. } | EndFitsExpanded => TagKind::FitsExpanded,
StartBestFittingEntry { .. } | EndBestFittingEntry => TagKind::BestFittingEntry, StartBestFittingEntry | EndBestFittingEntry => TagKind::BestFittingEntry,
StartBestFitParenthesize { .. } | EndBestFitParenthesize => { StartBestFitParenthesize { .. } | EndBestFitParenthesize => {
TagKind::BestFitParenthesize TagKind::BestFitParenthesize
} }

View File

@ -7,10 +7,10 @@
//! //!
//! * [`Format`]: Implemented by objects that can be formatted. //! * [`Format`]: Implemented by objects that can be formatted.
//! * [`FormatRule`]: Rule that knows how to format an object of another type. Useful in the situation where //! * [`FormatRule`]: Rule that knows how to format an object of another type. Useful in the situation where
//! it's necessary to implement [Format] on an object from another crate. This module defines the //! it's necessary to implement [Format] on an object from another crate. This module defines the
//! [`FormatRefWithRule`] and [`FormatOwnedWithRule`] structs to pass an item with its corresponding rule. //! [`FormatRefWithRule`] and [`FormatOwnedWithRule`] structs to pass an item with its corresponding rule.
//! * [`FormatWithRule`] implemented by objects that know how to format another type. Useful for implementing //! * [`FormatWithRule`] implemented by objects that know how to format another type. Useful for implementing
//! some reusable formatting logic inside of this module if the type itself doesn't implement [Format] //! some reusable formatting logic inside of this module if the type itself doesn't implement [Format]
//! //!
//! ## Formatting Macros //! ## Formatting Macros
//! //!

View File

@ -362,9 +362,7 @@ impl<'a> Printer<'a> {
stack.push(TagKind::FitsExpanded, args); stack.push(TagKind::FitsExpanded, args);
} }
FormatElement::Tag( FormatElement::Tag(tag @ (StartLabelled(_) | StartEntry | StartBestFittingEntry)) => {
tag @ (StartLabelled(_) | StartEntry | StartBestFittingEntry { .. }),
) => {
stack.push(tag.kind(), args); stack.push(tag.kind(), args);
} }
@ -386,7 +384,7 @@ impl<'a> Printer<'a> {
) => { ) => {
stack.pop(tag.kind())?; stack.pop(tag.kind())?;
} }
}; }
Ok(()) Ok(())
} }
@ -1416,7 +1414,7 @@ impl<'a, 'print> FitsMeasurer<'a, 'print> {
| StartVerbatim(_) | StartVerbatim(_)
| StartLabelled(_) | StartLabelled(_)
| StartEntry | StartEntry
| StartBestFittingEntry { .. }), | StartBestFittingEntry),
) => { ) => {
self.stack.push(tag.kind(), args); self.stack.push(tag.kind(), args);
} }

View File

@ -1749,5 +1749,5 @@ pub(crate) fn expression(expr: &Expr, checker: &Checker) {
} }
} }
_ => {} _ => {}
}; }
} }

View File

@ -645,7 +645,7 @@ pub(crate) fn statement(stmt: &Stmt, checker: &mut Checker) {
} }
} }
if let Some(asname) = &alias.asname { if let Some(asname) = &alias.asname {
let name = alias.name.split('.').last().unwrap(); let name = alias.name.split('.').next_back().unwrap();
if checker.enabled(Rule::ConstantImportedAsNonConstant) { if checker.enabled(Rule::ConstantImportedAsNonConstant) {
if let Some(diagnostic) = if let Some(diagnostic) =
pep8_naming::rules::constant_imported_as_non_constant( pep8_naming::rules::constant_imported_as_non_constant(

View File

@ -1164,7 +1164,7 @@ impl<'a> Visitor<'a> for Checker<'a> {
} }
} }
_ => visitor::walk_stmt(self, stmt), _ => visitor::walk_stmt(self, stmt),
}; }
if self.semantic().at_top_level() || self.semantic().current_scope().kind.is_class() { if self.semantic().at_top_level() || self.semantic().current_scope().kind.is_class() {
match stmt { match stmt {
@ -1726,7 +1726,7 @@ impl<'a> Visitor<'a> for Checker<'a> {
self.semantic.pop_scope(); self.semantic.pop_scope();
} }
_ => {} _ => {}
}; }
// Step 4: Analysis // Step 4: Analysis
match expr { match expr {

View File

@ -320,7 +320,7 @@ impl<'a> TodoDirective<'a> {
subset = &comment[relative_offset.to_usize()..]; subset = &comment[relative_offset.to_usize()..];
} else { } else {
break; break;
}; }
} }
None None

View File

@ -288,7 +288,7 @@ pub(crate) fn add_parameter(parameter: &str, parameters: &Parameters, source: &s
.args .args
.iter() .iter()
.filter(|arg| arg.default.is_none()) .filter(|arg| arg.default.is_none())
.last() .next_back()
{ {
// Case 1: at least one regular parameter, so append after the last one. // Case 1: at least one regular parameter, so append after the last one.
Edit::insertion(format!(", {parameter}"), last.end()) Edit::insertion(format!(", {parameter}"), last.end())

View File

@ -162,7 +162,7 @@ impl Display for RuleCodeAndBody<'_> {
); );
} }
} }
}; }
if let Some(rule) = self.message.rule() { if let Some(rule) = self.message.rule() {
write!( write!(

View File

@ -291,7 +291,7 @@ impl<'a> FileNoqaDirectives<'a> {
warn!("Invalid `# ruff: noqa` directive at {path_display}:{line}: {err}"); warn!("Invalid `# ruff: noqa` directive at {path_display}:{line}: {err}");
} }
Ok(None) => {} Ok(None) => {}
}; }
} }
Self(lines) Self(lines)
} }
@ -990,7 +990,7 @@ fn generate_noqa_edit<'a>(
codes = Some(existing_codes); codes = Some(existing_codes);
} }
Some(Directive::All(_)) => return None, Some(Directive::All(_)) => return None,
}; }
Some(NoqaEdit { Some(NoqaEdit {
edit_range, edit_range,

View File

@ -216,8 +216,7 @@ impl RuleSelector {
} }
// Deprecated rules are excluded in preview mode and with 'All' option unless explicitly selected // Deprecated rules are excluded in preview mode and with 'All' option unless explicitly selected
RuleGroup::Deprecated => { RuleGroup::Deprecated => {
(!preview_enabled || self.is_exact()) (!preview_enabled || self.is_exact()) && !matches!(self, RuleSelector::All)
&& !matches!(self, RuleSelector::All { .. })
} }
// Removed rules are included if explicitly selected but will error downstream // Removed rules are included if explicitly selected but will error downstream
RuleGroup::Removed => self.is_exact(), RuleGroup::Removed => self.is_exact(),

View File

@ -91,7 +91,7 @@ pub(crate) fn airflow_3_removal_expr(checker: &Checker, expr: &Expr) {
) => { ) => {
if let Some(qualified_name) = checker.semantic().resolve_qualified_name(func) { if let Some(qualified_name) = checker.semantic().resolve_qualified_name(func) {
check_call_arguments(checker, &qualified_name, arguments); check_call_arguments(checker, &qualified_name, arguments);
}; }
check_method(checker, call_expr); check_method(checker, call_expr);
check_context_key_usage_in_call(checker, call_expr); check_context_key_usage_in_call(checker, call_expr);
} }
@ -256,7 +256,7 @@ fn check_call_arguments(checker: &Checker, qualified_name: &QualifiedName, argum
} }
} }
} }
}; }
} }
/// Check whether a removed Airflow class attribute (include property) is called. /// Check whether a removed Airflow class attribute (include property) is called.
@ -930,7 +930,7 @@ fn check_name(checker: &Checker, expr: &Expr, range: TextRange) {
let replacement_edit = Edit::range_replacement(binding, range); let replacement_edit = Edit::range_replacement(binding, range);
Ok(Fix::safe_edits(import_edit, [replacement_edit])) Ok(Fix::safe_edits(import_edit, [replacement_edit]))
}); });
}; }
checker.report_diagnostic(diagnostic); checker.report_diagnostic(diagnostic);
} }

View File

@ -72,7 +72,7 @@ pub(crate) fn cancel_scope_no_checkpoint(
None None
} }
}) })
.last() .next_back()
else { else {
return; return;
}; };

View File

@ -78,7 +78,7 @@ pub(crate) fn sync_call(checker: &Checker, call: &ExprCall) {
.is_some_and(Expr::is_await_expr) .is_some_and(Expr::is_await_expr)
{ {
return; return;
}; }
let mut diagnostic = Diagnostic::new(TrioSyncCall { method_name }, call.range); let mut diagnostic = Diagnostic::new(TrioSyncCall { method_name }, call.range);
if checker.semantic().in_async_context() { if checker.semantic().in_async_context() {

View File

@ -70,5 +70,5 @@ pub(crate) fn hardcoded_bind_all_interfaces(checker: &Checker, string: StringLik
} }
} }
StringLike::Bytes(_) => (), StringLike::Bytes(_) => (),
}; }
} }

View File

@ -599,7 +599,7 @@ pub(crate) fn suspicious_imports(checker: &Checker, stmt: &Stmt) {
} }
} }
_ => panic!("Expected Stmt::Import | Stmt::ImportFrom"), _ => panic!("Expected Stmt::Import | Stmt::ImportFrom"),
}; }
} }
fn check_and_push_diagnostic(checker: &Checker, diagnostic_kind: DiagnosticKind, range: TextRange) { fn check_and_push_diagnostic(checker: &Checker, diagnostic_kind: DiagnosticKind, range: TextRange) {

View File

@ -97,7 +97,7 @@ pub(crate) fn assert_raises_exception(checker: &Checker, items: &[WithItem]) {
&& arguments.find_keyword("match").is_none()) && arguments.find_keyword("match").is_none())
{ {
continue; continue;
}; }
checker.report_diagnostic(Diagnostic::new( checker.report_diagnostic(Diagnostic::new(
AssertRaisesException { exception }, AssertRaisesException { exception },

View File

@ -74,7 +74,7 @@ pub(crate) fn duplicate_value(checker: &Checker, set: &ast::ExprSet) {
checker.report_diagnostic(diagnostic); checker.report_diagnostic(diagnostic);
} }
}; }
} }
} }

View File

@ -1,3 +1,5 @@
use std::fmt::Write;
use ruff_diagnostics::{Diagnostic, Edit, Fix, FixAvailability, Violation}; use ruff_diagnostics::{Diagnostic, Edit, Fix, FixAvailability, Violation};
use ruff_macros::{derive_message_formats, ViolationMetadata}; use ruff_macros::{derive_message_formats, ViolationMetadata};
use ruff_python_ast::helpers::is_docstring_stmt; use ruff_python_ast::helpers::is_docstring_stmt;
@ -160,14 +162,15 @@ fn move_initialization(
// Add an `if`, to set the argument to its original value if still `None`. // Add an `if`, to set the argument to its original value if still `None`.
let mut content = String::new(); let mut content = String::new();
content.push_str(&format!("if {} is None:", parameter.name())); let _ = write!(&mut content, "if {} is None:", parameter.name());
content.push_str(stylist.line_ending().as_str()); content.push_str(stylist.line_ending().as_str());
content.push_str(stylist.indentation()); content.push_str(stylist.indentation());
content.push_str(&format!( let _ = write!(
&mut content,
"{} = {}", "{} = {}",
parameter.name(), parameter.name(),
generator.expr(default) generator.expr(default)
)); );
content.push_str(stylist.line_ending().as_str()); content.push_str(stylist.line_ending().as_str());
// Determine the indentation depth of the function body. // Determine the indentation depth of the function body.
@ -204,7 +207,7 @@ fn move_initialization(
} }
} else { } else {
break; break;
}; }
} }
let initialization_edit = Edit::insertion(content, pos); let initialization_edit = Edit::insertion(content, pos);

View File

@ -61,5 +61,5 @@ pub(crate) fn unintentional_type_annotation(
} }
} }
_ => {} _ => {}
}; }
} }

View File

@ -426,7 +426,7 @@ pub(crate) fn fix_unnecessary_call_around_sorted(
tree = Expression::Call(Box::new((*inner_call).clone())); tree = Expression::Call(Box::new((*inner_call).clone()));
if inner_needs_parens { if inner_needs_parens {
tree = tree.with_parens(LeftParen::default(), RightParen::default()); tree = tree.with_parens(LeftParen::default(), RightParen::default());
}; }
} else { } else {
// If the `reverse` argument is used... // If the `reverse` argument is used...
let args = if inner_call.args.iter().any(|arg| { let args = if inner_call.args.iter().any(|arg| {

View File

@ -79,7 +79,7 @@ pub(crate) fn unnecessary_subscript_reversal(checker: &Checker, call: &ast::Expr
}; };
if *val != 1 { if *val != 1 {
return; return;
}; }
let Some(function_name) = checker.semantic().resolve_builtin_symbol(&call.func) else { let Some(function_name) = checker.semantic().resolve_builtin_symbol(&call.func) else {
return; return;
}; };

View File

@ -132,7 +132,7 @@ pub(crate) fn call_datetime_strptime_without_zone(checker: &Checker, call: &ast:
} }
_ => {} _ => {}
} }
}; }
let semantic = checker.semantic(); let semantic = checker.semantic();
if let Some(antipattern) = find_antipattern( if let Some(antipattern) = find_antipattern(

View File

@ -95,7 +95,7 @@ pub(crate) fn all_with_model_form(checker: &Checker, class_def: &ast::StmtClassD
} }
} }
_ => (), _ => (),
}; }
} }
} }
} }

View File

@ -54,7 +54,7 @@ impl Violation for PrintfInGetTextFuncCall {
pub(crate) fn printf_in_gettext_func_call(checker: &Checker, args: &[Expr]) { pub(crate) fn printf_in_gettext_func_call(checker: &Checker, args: &[Expr]) {
if let Some(first) = args.first() { if let Some(first) = args.first() {
if let Expr::BinOp(ast::ExprBinOp { if let Expr::BinOp(ast::ExprBinOp {
op: Operator::Mod { .. }, op: Operator::Mod,
left, left,
.. ..
}) = &first }) = &first

View File

@ -160,7 +160,7 @@ pub(crate) fn implicit(
} }
diagnostics.push(diagnostic); diagnostics.push(diagnostic);
}; }
} }
} }

View File

@ -63,12 +63,12 @@ pub(crate) fn unnecessary_range_start(checker: &Checker, call: &ast::ExprCall) {
}; };
if *value != 0 { if *value != 0 {
return; return;
}; }
// Verify that the call is to the `range` builtin. // Verify that the call is to the `range` builtin.
if !checker.semantic().match_builtin_expr(&call.func, "range") { if !checker.semantic().match_builtin_expr(&call.func, "range") {
return; return;
}; }
let mut diagnostic = Diagnostic::new(UnnecessaryRangeStart, start.range()); let mut diagnostic = Diagnostic::new(UnnecessaryRangeStart, start.range());
diagnostic.try_set_fix(|| { diagnostic.try_set_fix(|| {

View File

@ -209,7 +209,7 @@ pub(crate) fn bad_generator_return_type(function_def: &ast::StmtFunctionDef, che
_ => return, _ => return,
} }
} }
}; }
let mut diagnostic = Diagnostic::new( let mut diagnostic = Diagnostic::new(
GeneratorReturnFromIterMethod { GeneratorReturnFromIterMethod {
return_type: member.to_iter(), return_type: member.to_iter(),

View File

@ -149,6 +149,6 @@ pub(crate) fn bad_version_info_comparison(checker: &Checker, test: &Expr, has_el
} else { } else {
if checker.enabled(Rule::BadVersionInfoComparison) { if checker.enabled(Rule::BadVersionInfoComparison) {
checker.report_diagnostic(Diagnostic::new(BadVersionInfoComparison, test.range())); checker.report_diagnostic(Diagnostic::new(BadVersionInfoComparison, test.range()));
}; }
} }
} }

View File

@ -107,7 +107,7 @@ pub(crate) fn duplicate_literal_member<'a>(checker: &Checker, expr: &'a Expr) {
for diagnostic in &mut diagnostics { for diagnostic in &mut diagnostics {
diagnostic.set_fix(fix.clone()); diagnostic.set_fix(fix.clone());
} }
}; }
checker.report_diagnostics(diagnostics); checker.report_diagnostics(diagnostics);
} }

View File

@ -47,7 +47,7 @@ pub(crate) fn from_future_import(checker: &Checker, target: &StmtImportFrom) {
if module_name != "__future__" { if module_name != "__future__" {
return; return;
}; }
if names.iter().all(|alias| &*alias.name != "annotations") { if names.iter().all(|alias| &*alias.name != "annotations") {
return; return;

View File

@ -73,7 +73,7 @@ pub(crate) fn prefix_type_params(checker: &Checker, value: &Expr, targets: &[Exp
if id.starts_with('_') { if id.starts_with('_') {
return; return;
} }
}; }
let Expr::Call(ast::ExprCall { func, .. }) = value else { let Expr::Call(ast::ExprCall { func, .. }) = value else {
return; return;

View File

@ -646,7 +646,7 @@ impl<'a> Visitor<'a> for SkipFunctionsVisitor<'a> {
.is_some_and(|name| matches!(name.segments(), ["request", "addfinalizer"])) .is_some_and(|name| matches!(name.segments(), ["request", "addfinalizer"]))
{ {
self.addfinalizer_call = Some(expr); self.addfinalizer_call = Some(expr);
}; }
visitor::walk_expr(self, expr); visitor::walk_expr(self, expr);
} }
_ => {} _ => {}

View File

@ -59,7 +59,7 @@ pub(crate) fn import_from(
// If level is not zero or module is none, return // If level is not zero or module is none, return
if level != 0 { if level != 0 {
return None; return None;
}; }
if let Some(module) = module { if let Some(module) = module {
if is_pytest_or_subpackage(module) { if is_pytest_or_subpackage(module) {
@ -68,7 +68,7 @@ pub(crate) fn import_from(
import_from.range(), import_from.range(),
)); ));
} }
}; }
None None
} }

View File

@ -458,7 +458,7 @@ fn check_names(checker: &Checker, call: &ExprCall, expr: &Expr, argvalues: &Expr
checker.report_diagnostic(diagnostic); checker.report_diagnostic(diagnostic);
} }
} }
}; }
} }
Expr::List(ast::ExprList { elts, .. }) => { Expr::List(ast::ExprList { elts, .. }) => {
if elts.len() == 1 { if elts.len() == 1 {
@ -505,7 +505,7 @@ fn check_names(checker: &Checker, call: &ExprCall, expr: &Expr, argvalues: &Expr
checker.report_diagnostic(diagnostic); checker.report_diagnostic(diagnostic);
} }
} }
}; }
} }
_ => {} _ => {}
} }

View File

@ -195,7 +195,7 @@ pub(crate) fn if_expr_with_true_false(
), ),
expr.range(), expr.range(),
))); )));
}; }
checker.report_diagnostic(diagnostic); checker.report_diagnostic(diagnostic);
} }

View File

@ -295,6 +295,6 @@ pub(crate) fn double_negation(checker: &Checker, expr: &Expr, op: UnaryOp, opera
checker.generator().expr(&node1.into()), checker.generator().expr(&node1.into()),
expr.range(), expr.range(),
))); )));
}; }
checker.report_diagnostic(diagnostic); checker.report_diagnostic(diagnostic);
} }

View File

@ -114,7 +114,7 @@ pub(crate) fn if_else_block_instead_of_dict_lookup(checker: &Checker, stmt_if: &
contains_effect(value, |id| checker.semantic().has_builtin_binding(id)) contains_effect(value, |id| checker.semantic().has_builtin_binding(id))
}) { }) {
return; return;
}; }
} }
// `elif` // `elif`
Some(Expr::Compare(ast::ExprCompare { Some(Expr::Compare(ast::ExprCompare {
@ -140,7 +140,7 @@ pub(crate) fn if_else_block_instead_of_dict_lookup(checker: &Checker, stmt_if: &
contains_effect(value, |id| checker.semantic().has_builtin_binding(id)) contains_effect(value, |id| checker.semantic().has_builtin_binding(id))
}) { }) {
return; return;
}; }
// The `expr` was checked to be a literal above, so this is safe. // The `expr` was checked to be a literal above, so this is safe.
literals.insert(literal_expr.into()); literals.insert(literal_expr.into());

View File

@ -71,7 +71,7 @@ pub(crate) fn zip_dict_keys_and_values(checker: &Checker, expr: &ast::ExprCall)
arg: Some(name), .. arg: Some(name), ..
}] if name.as_str() == "strict" => {} }] if name.as_str() == "strict" => {}
_ => return, _ => return,
}; }
let [arg1, arg2] = &args[..] else { let [arg1, arg2] = &args[..] else {
return; return;
}; };

View File

@ -128,7 +128,7 @@ pub(crate) fn banned_relative_import(
fix_banned_relative_import(stmt, level, module, module_path, checker.generator()) fix_banned_relative_import(stmt, level, module, module_path, checker.generator())
{ {
diagnostic.set_fix(fix); diagnostic.set_fix(fix);
}; }
Some(diagnostic) Some(diagnostic)
} else { } else {
None None

View File

@ -216,7 +216,7 @@ pub(crate) fn is_singledispatch_implementation(
if attribute.attr.as_str() != "register" { if attribute.attr.as_str() != "register" {
return false; return false;
}; }
let Some(id) = semantic.lookup_attribute(attribute.value.as_ref()) else { let Some(id) = semantic.lookup_attribute(attribute.value.as_ref()) else {
return false; return false;

View File

@ -74,7 +74,7 @@ pub(crate) fn os_sep_split(checker: &Checker, call: &ast::ExprCall) {
if attr.as_str() != "split" { if attr.as_str() != "split" {
return; return;
}; }
// Match `.split(os.sep)` or `.split(sep=os.sep)`, but avoid cases in which a `maxsplit` is // Match `.split(os.sep)` or `.split(sep=os.sep)`, but avoid cases in which a `maxsplit` is
// specified. // specified.

View File

@ -110,7 +110,7 @@ pub(crate) fn path_constructor_current_directory(checker: &Checker, call: &ExprC
let edit = remove_argument(arg, arguments, Parentheses::Preserve, checker.source())?; let edit = remove_argument(arg, arguments, Parentheses::Preserve, checker.source())?;
Ok(Fix::applicable_edit(edit, applicability(call.range()))) Ok(Fix::applicable_edit(edit, applicability(call.range())))
}), }),
}; }
checker.report_diagnostic(diagnostic); checker.report_diagnostic(diagnostic);
} }

View File

@ -178,7 +178,7 @@ fn is_file_descriptor(expr: &Expr, semantic: &SemanticModel) -> bool {
}) })
) { ) {
return true; return true;
}; }
let Some(name) = expr.as_name_expr() else { let Some(name) = expr.as_name_expr() else {
return false; return false;

View File

@ -706,7 +706,7 @@ pub(crate) fn numpy_2_0_deprecation(checker: &Checker, expr: &Expr) {
Edit::range_replacement(python_expr.to_string(), expr.range()), Edit::range_replacement(python_expr.to_string(), expr.range()),
)), )),
Details::Manual { guideline: _ } => {} Details::Manual { guideline: _ } => {}
}; }
checker.report_diagnostic(diagnostic); checker.report_diagnostic(diagnostic);
} }

View File

@ -307,7 +307,7 @@ pub(crate) fn compound_statements(
match_ = Some(token.range()); match_ = Some(token.range());
} }
_ => {} _ => {}
}; }
} }
} }

View File

@ -175,7 +175,7 @@ pub(crate) fn missing_whitespace_around_operator(
TokenKind::Lpar | TokenKind::Lambda => parens += 1, TokenKind::Lpar | TokenKind::Lambda => parens += 1,
TokenKind::Rpar => parens = parens.saturating_sub(1), TokenKind::Rpar => parens = parens.saturating_sub(1),
_ => {} _ => {}
}; }
let needs_space = if kind == TokenKind::Equal let needs_space = if kind == TokenKind::Equal
&& (parens > 0 || fstrings > 0 || definition_state.in_type_params()) && (parens > 0 || fstrings > 0 || definition_state.in_type_params())

View File

@ -68,7 +68,7 @@ pub(crate) fn too_many_newlines_at_end_of_file(
diagnostics.extend(notebook_newline_diagnostics(tokens_iter, cell_offsets)); diagnostics.extend(notebook_newline_diagnostics(tokens_iter, cell_offsets));
} else if let Some(diagnostic) = newline_diagnostic(&mut tokens_iter, false) { } else if let Some(diagnostic) = newline_diagnostic(&mut tokens_iter, false) {
diagnostics.push(diagnostic); diagnostics.push(diagnostic);
}; }
} }
/// Collects trailing newline diagnostics for each cell /// Collects trailing newline diagnostics for each cell
@ -127,7 +127,7 @@ fn newline_diagnostic<'a>(
if num_trailing_newlines == 0 || num_trailing_newlines == 1 { if num_trailing_newlines == 0 || num_trailing_newlines == 1 {
return None; return None;
}; }
let (start, end) = (match (newline_range_start, newline_range_end) { let (start, end) = (match (newline_range_start, newline_range_end) {
(Some(s), Some(e)) => Some((s, e)), (Some(s), Some(e)) => Some((s, e)),

View File

@ -119,7 +119,7 @@ pub(crate) fn get_section_contexts<'a>(
Ordering::Greater => return google_sections, Ordering::Greater => return google_sections,
Ordering::Less => return numpy_sections, Ordering::Less => return numpy_sections,
Ordering::Equal => {} Ordering::Equal => {}
}; }
// 0 sections of either convention? Default to numpy // 0 sections of either convention? Default to numpy
if google_sections.len() == 0 { if google_sections.len() == 0 {

View File

@ -115,6 +115,6 @@ pub(crate) fn ends_with_period(checker: &Checker, docstring: &Docstring) {
))); )));
} }
checker.report_diagnostic(diagnostic); checker.report_diagnostic(diagnostic);
}; }
} }
} }

View File

@ -114,6 +114,6 @@ pub(crate) fn ends_with_punctuation(checker: &Checker, docstring: &Docstring) {
))); )));
} }
checker.report_diagnostic(diagnostic); checker.report_diagnostic(diagnostic);
}; }
} }
} }

View File

@ -146,7 +146,7 @@ pub(crate) fn multi_line_summary_start(checker: &Checker, docstring: &Docstring)
.is_none() .is_none()
{ {
return; return;
}; }
let mut content_lines = let mut content_lines =
UniversalNewlineIterator::with_offset(docstring.contents(), docstring.start()); UniversalNewlineIterator::with_offset(docstring.contents(), docstring.start());
@ -201,7 +201,7 @@ pub(crate) fn multi_line_summary_start(checker: &Checker, docstring: &Docstring)
indentation.push_str(checker.stylist().indentation()); indentation.push_str(checker.stylist().indentation());
fixable = true; fixable = true;
} }
}; }
} }
if fixable { if fixable {

View File

@ -36,7 +36,7 @@ impl From<&CFormatString> for CFormatSummary {
None => { None => {
num_positional += 1; num_positional += 1;
} }
}; }
if min_field_width == &Some(CFormatQuantity::FromValuesTuple) { if min_field_width == &Some(CFormatQuantity::FromValuesTuple) {
num_positional += 1; num_positional += 1;
starred = true; starred = true;

View File

@ -55,7 +55,7 @@ impl TryFrom<&str> for FormatSummary {
FieldType::Auto => autos.push(autos.len()), FieldType::Auto => autos.push(autos.len()),
FieldType::Index(i) => indices.push(i), FieldType::Index(i) => indices.push(i),
FieldType::Keyword(k) => keywords.push(Name::from(k)), FieldType::Keyword(k) => keywords.push(Name::from(k)),
}; }
let nested = FormatString::from_str(format_spec)?; let nested = FormatString::from_str(format_spec)?;
for nested_part in nested.format_parts { for nested_part in nested.format_parts {
@ -67,7 +67,7 @@ impl TryFrom<&str> for FormatSummary {
FieldType::Auto => autos.push(autos.len()), FieldType::Auto => autos.push(autos.len()),
FieldType::Index(i) => indices.push(i), FieldType::Index(i) => indices.push(i),
FieldType::Keyword(k) => keywords.push(Name::from(k)), FieldType::Keyword(k) => keywords.push(Name::from(k)),
}; }
has_nested_parts = true; has_nested_parts = true;
} }
} }

View File

@ -80,7 +80,7 @@ pub(crate) fn bad_staticmethod_argument(checker: &Checker, scope: &Scope) {
FunctionType::Function | FunctionType::Method | FunctionType::ClassMethod => { FunctionType::Function | FunctionType::Method | FunctionType::ClassMethod => {
return; return;
} }
}; }
let Some(ParameterWithDefault { let Some(ParameterWithDefault {
parameter: self_or_cls, parameter: self_or_cls,

View File

@ -108,6 +108,6 @@ pub(crate) fn percent(checker: &Checker, expr: &Expr, format_string: &ExprString
expr.range(), expr.range(),
)); ));
} }
}; }
} }
} }

View File

@ -230,7 +230,7 @@ pub(crate) fn bad_string_format_type(
// Parse the format string (e.g. `"%s"`) into a list of `PercentFormat`. // Parse the format string (e.g. `"%s"`) into a list of `PercentFormat`.
if let Ok(format_string) = CFormatString::from_str(string) { if let Ok(format_string) = CFormatString::from_str(string) {
format_strings.push(format_string); format_strings.push(format_string);
}; }
} }
// Parse the parameters. // Parse the parameters.

View File

@ -72,6 +72,6 @@ pub(crate) fn comparison_of_constant(
); );
checker.report_diagnostic(diagnostic); checker.report_diagnostic(diagnostic);
}; }
} }
} }

View File

@ -72,7 +72,7 @@ pub(crate) fn dict_iter_missing_items(checker: &Checker, target: &Expr, iter: &E
if tuple.len() != 2 { if tuple.len() != 2 {
return; return;
}; }
let Expr::Name(name) = iter else { let Expr::Name(name) = iter else {
return; return;

View File

@ -105,7 +105,7 @@ pub(crate) fn logging_call(checker: &Checker, call: &ast::ExprCall) {
Expr::Attribute(ast::ExprAttribute { attr, .. }) => { Expr::Attribute(ast::ExprAttribute { attr, .. }) => {
if LoggingLevel::from_attribute(attr).is_none() { if LoggingLevel::from_attribute(attr).is_none() {
return; return;
}; }
if !logging::is_logger_candidate( if !logging::is_logger_candidate(
&call.func, &call.func,
checker.semantic(), checker.semantic(),
@ -126,10 +126,10 @@ pub(crate) fn logging_call(checker: &Checker, call: &ast::ExprCall) {
}; };
if LoggingLevel::from_attribute(attribute).is_none() { if LoggingLevel::from_attribute(attribute).is_none() {
return; return;
}; }
} }
_ => return, _ => return,
}; }
let Some(Expr::StringLiteral(ast::ExprStringLiteral { value, .. })) = let Some(Expr::StringLiteral(ast::ExprStringLiteral { value, .. })) =
call.arguments.find_positional(0) call.arguments.find_positional(0)

View File

@ -135,16 +135,16 @@ fn get_undecorated_methods(checker: &Checker, class_stmt: &Stmt, method_type: &M
if target_name == *id { if target_name == *id {
explicit_decorator_calls.insert(id.clone(), stmt); explicit_decorator_calls.insert(id.clone(), stmt);
} }
}; }
} }
} }
} }
}; }
} }
if explicit_decorator_calls.is_empty() { if explicit_decorator_calls.is_empty() {
return; return;
}; }
for stmt in &class_def.body { for stmt in &class_def.body {
if let Stmt::FunctionDef(ast::StmtFunctionDef { if let Stmt::FunctionDef(ast::StmtFunctionDef {
@ -196,7 +196,7 @@ fn get_undecorated_methods(checker: &Checker, class_stmt: &Stmt, method_type: &M
None => { None => {
continue; continue;
} }
}; }
}; }
} }
} }

View File

@ -103,8 +103,8 @@ pub(crate) fn self_or_cls_assignment(checker: &Checker, target: &Expr) {
); );
let method_type = match (function_type, self_or_cls.name().as_str()) { let method_type = match (function_type, self_or_cls.name().as_str()) {
(FunctionType::Method { .. }, "self") => MethodType::Instance, (FunctionType::Method, "self") => MethodType::Instance,
(FunctionType::ClassMethod { .. }, "cls") => MethodType::Class, (FunctionType::ClassMethod, "cls") => MethodType::Class,
(FunctionType::NewMethod, "cls") => MethodType::New, (FunctionType::NewMethod, "cls") => MethodType::New,
_ => return, _ => return,
}; };

View File

@ -101,9 +101,9 @@ pub(crate) fn super_without_brackets(checker: &Checker, func: &Expr) {
); );
if !matches!( if !matches!(
classification, classification,
function_type::FunctionType::Method { .. } function_type::FunctionType::Method
| function_type::FunctionType::ClassMethod { .. } | function_type::FunctionType::ClassMethod
| function_type::FunctionType::StaticMethod { .. } | function_type::FunctionType::StaticMethod
) { ) {
return; return;
} }

View File

@ -79,7 +79,7 @@ pub(crate) fn sys_exit_alias(checker: &Checker, call: &ExprCall) {
if call.arguments.len() > 1 || has_star_kwargs { if call.arguments.len() > 1 || has_star_kwargs {
checker.report_diagnostic(diagnostic); checker.report_diagnostic(diagnostic);
return; return;
}; }
diagnostic.try_set_fix(|| { diagnostic.try_set_fix(|| {
let (import_edit, binding) = checker.importer().get_or_import_symbol( let (import_edit, binding) = checker.importer().get_or_import_symbol(
@ -94,7 +94,7 @@ pub(crate) fn sys_exit_alias(checker: &Checker, call: &ExprCall) {
checker.source()[kwarg.value.range()].to_string(), checker.source()[kwarg.value.range()].to_string(),
kwarg.range, kwarg.range,
)); ));
}; }
Ok(Fix::unsafe_edits(import_edit, edits)) Ok(Fix::unsafe_edits(import_edit, edits))
}); });
checker.report_diagnostic(diagnostic); checker.report_diagnostic(diagnostic);

View File

@ -54,6 +54,6 @@ pub(crate) fn too_many_locals(checker: &Checker, scope: &Scope) {
}, },
func.identifier(), func.identifier(),
)); ));
}; }
} }
} }

View File

@ -208,7 +208,7 @@ pub(crate) fn unnecessary_dunder_call(checker: &Checker, call: &ast::ExprCall) {
fixed, fixed,
call.range(), call.range(),
))); )));
}; }
checker.report_diagnostic(diagnostic); checker.report_diagnostic(diagnostic);
} }

View File

@ -85,7 +85,7 @@ pub(crate) fn useless_return(
.is_none_or(|expr| expr.is_none_literal_expr()) .is_none_or(|expr| expr.is_none_literal_expr())
{ {
return; return;
}; }
// Finally: verify that there are no _other_ return statements in the function. // Finally: verify that there are no _other_ return statements in the function.
let mut visitor = ReturnStatementVisitor::default(); let mut visitor = ReturnStatementVisitor::default();

View File

@ -527,6 +527,6 @@ pub(crate) fn f_strings(checker: &Checker, call: &ast::ExprCall, summary: &Forma
call.range(), call.range(),
))); )));
} }
}; }
checker.report_diagnostic(diagnostic); checker.report_diagnostic(diagnostic);
} }

View File

@ -1,4 +1,5 @@
use std::borrow::Cow; use std::borrow::Cow;
use std::fmt::Write;
use std::str::FromStr; use std::str::FromStr;
use ruff_diagnostics::{Diagnostic, Edit, Fix, FixAvailability, Violation}; use ruff_diagnostics::{Diagnostic, Edit, Fix, FixAvailability, Violation};
@ -501,7 +502,7 @@ pub(crate) fn printf_string_formatting(
} }
// Add the `.format` call. // Add the `.format` call.
contents.push_str(&format!(".format{params_string}")); let _ = write!(&mut contents, ".format{params_string}");
let mut diagnostic = Diagnostic::new(PrintfStringFormatting, bin_op.range()); let mut diagnostic = Diagnostic::new(PrintfStringFormatting, bin_op.range());
diagnostic.set_fix(Fix::unsafe_edit(Edit::range_replacement( diagnostic.set_fix(Fix::unsafe_edit(Edit::range_replacement(

View File

@ -124,7 +124,7 @@ pub(crate) fn replace_str_enum(checker: &Checker, class_def: &ast::StmtClassDef)
// If the class does not inherit both `str` and `enum.Enum`, exit early. // If the class does not inherit both `str` and `enum.Enum`, exit early.
if !inherits_str || !inherits_enum { if !inherits_str || !inherits_enum {
return; return;
}; }
let mut diagnostic = Diagnostic::new( let mut diagnostic = Diagnostic::new(
ReplaceStrEnum { ReplaceStrEnum {

View File

@ -1,3 +1,5 @@
use std::fmt::Write as _;
use ruff_diagnostics::{AlwaysFixableViolation, Diagnostic, Edit, Fix}; use ruff_diagnostics::{AlwaysFixableViolation, Diagnostic, Edit, Fix};
use ruff_macros::{derive_message_formats, ViolationMetadata}; use ruff_macros::{derive_message_formats, ViolationMetadata};
use ruff_python_ast::{self as ast, Arguments, Expr, Keyword}; use ruff_python_ast::{self as ast, Arguments, Expr, Keyword};
@ -129,10 +131,11 @@ fn replace_with_bytes_literal(locator: &Locator, call: &ast::ExprCall, tokens: &
TokenKind::String => { TokenKind::String => {
replacement.push_str(locator.slice(TextRange::new(prev, token.start()))); replacement.push_str(locator.slice(TextRange::new(prev, token.start())));
let string = locator.slice(token); let string = locator.slice(token);
replacement.push_str(&format!( let _ = write!(
&mut replacement,
"b{}", "b{}",
&string.trim_start_matches('u').trim_start_matches('U') &string.trim_start_matches('u').trim_start_matches('U')
)); );
} }
_ => { _ => {
replacement.push_str(locator.slice(TextRange::new(prev, token.end()))); replacement.push_str(locator.slice(TextRange::new(prev, token.end())));

View File

@ -283,7 +283,7 @@ fn match_open_keywords(
// All other keywords cannot be directly forwarded. // All other keywords cannot be directly forwarded.
_ => return None, _ => return None,
}; }
} }
Some((result, mode)) Some((result, mode))
} }

View File

@ -74,7 +74,7 @@ pub(crate) fn bit_count(checker: &Checker, call: &ExprCall) {
if !call.arguments.keywords.is_empty() { if !call.arguments.keywords.is_empty() {
return; return;
}; }
let [arg] = &*call.arguments.args else { let [arg] = &*call.arguments.args else {
return; return;
}; };
@ -100,7 +100,7 @@ pub(crate) fn bit_count(checker: &Checker, call: &ExprCall) {
if !arguments.keywords.is_empty() { if !arguments.keywords.is_empty() {
return; return;
}; }
let [arg] = &*arguments.args else { let [arg] = &*arguments.args else {
return; return;
}; };

View File

@ -102,7 +102,7 @@ pub(crate) fn check_and_remove_from_set(checker: &Checker, if_stmt: &ast::StmtIf
.is_some_and(|binding| is_set(binding, checker.semantic())) .is_some_and(|binding| is_set(binding, checker.semantic()))
{ {
return; return;
}; }
let mut diagnostic = Diagnostic::new( let mut diagnostic = Diagnostic::new(
CheckAndRemoveFromSet { CheckAndRemoveFromSet {

View File

@ -160,7 +160,7 @@ impl<'a> ReplaceTimeZone<'a> {
if !arguments.keywords.is_empty() { if !arguments.keywords.is_empty() {
return None; return None;
}; }
let ExprAttribute { value, attr, .. } = call.func.as_attribute_expr()?; let ExprAttribute { value, attr, .. } = call.func.as_attribute_expr()?;

View File

@ -182,7 +182,7 @@ fn extract_name_from_sliced_reversed(expr: &Expr) -> Option<&ExprName> {
.is_none_or(|value| value != 1) .is_none_or(|value| value != 1)
{ {
return None; return None;
}; }
value.as_name_expr() value.as_name_expr()
} }

View File

@ -273,7 +273,7 @@ fn itemgetter_op(expr: &ExprSubscript, params: &Parameters, locator: &Locator) -
// The argument to the lambda must match the subscripted value, as in: `lambda x: x[1]`. // The argument to the lambda must match the subscripted value, as in: `lambda x: x[1]`.
if !is_same_expression(arg, &expr.value) { if !is_same_expression(arg, &expr.value) {
return None; return None;
}; }
// The subscripted expression can't contain references to the argument, as in: `lambda x: x[x]`. // The subscripted expression can't contain references to the argument, as in: `lambda x: x[x]`.
if any_over_expr(expr.slice.as_ref(), &|expr| is_same_expression(arg, expr)) { if any_over_expr(expr.slice.as_ref(), &|expr| is_same_expression(arg, expr)) {

Some files were not shown because too many files have changed in this diff Show More