Skip to content

Commit

Permalink
bump MSRV to 1.83 (#16294)
Browse files Browse the repository at this point in the history
According to our new MSRV policy (see
#16370 ), bump our MSRV to 1.83
(N - 2), and autofix some new clippy lints.
  • Loading branch information
carljm authored Feb 26, 2025
1 parent bf2c9a4 commit dd6f623
Show file tree
Hide file tree
Showing 47 changed files with 85 additions and 93 deletions.
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ resolver = "2"

[workspace.package]
edition = "2021"
rust-version = "1.80"
rust-version = "1.83"
homepage = "https://docs.astral.sh/ruff"
documentation = "https://docs.astral.sh/ruff"
repository = "https://github.com/astral-sh/ruff"
Expand Down
4 changes: 2 additions & 2 deletions crates/red_knot_project/src/metadata.rs
Original file line number Diff line number Diff line change
Expand Up @@ -77,10 +77,10 @@ impl ProjectMetadata {
// If the `options` don't specify a python version but the `project.requires-python` field is set,
// use that as a lower bound instead.
if let Some(project) = project {
if !options
if options
.environment
.as_ref()
.is_some_and(|env| env.python_version.is_some())
.is_none_or(|env| env.python_version.is_none())
{
if let Some(requires_python) = project.resolve_requires_python_lower_bound()? {
let mut environment = options.environment.unwrap_or_default();
Expand Down
8 changes: 4 additions & 4 deletions crates/red_knot_test/src/matcher.rs
Original file line number Diff line number Diff line change
Expand Up @@ -283,12 +283,12 @@ impl Matcher {
let position = unmatched.iter().position(|diagnostic| {
!error.rule.is_some_and(|rule| {
!(diagnostic.id().is_lint_named(rule) || diagnostic.id().matches(rule))
}) && !error
}) && error
.column
.is_some_and(|col| col != self.column(*diagnostic))
&& !error
.is_none_or(|col| col == self.column(*diagnostic))
&& error
.message_contains
.is_some_and(|needle| !diagnostic.message().contains(needle))
.is_none_or(|needle| diagnostic.message().contains(needle))
});
if let Some(position) = position {
unmatched.swap_remove(position);
Expand Down
4 changes: 2 additions & 2 deletions crates/ruff_formatter/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -470,13 +470,13 @@ impl Printed {
for marker in self.sourcemap {
// Take the closest start marker, but skip over start_markers that have the same start.
if marker.source <= source_range.start()
&& !start_marker.is_some_and(|existing| existing.source >= marker.source)
&& start_marker.is_none_or(|existing| existing.source < marker.source)
{
start_marker = Some(marker);
}

if marker.source >= source_range.end()
&& !end_marker.is_some_and(|existing| existing.source <= marker.source)
&& end_marker.is_none_or(|existing| existing.source > marker.source)
{
end_marker = Some(marker);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -177,10 +177,10 @@ pub(crate) fn deferred_scopes(checker: &Checker) {
}

// If the bindings are in different forks, abort.
if shadowed.source.map_or(true, |left| {
if shadowed.source.is_none_or(|left| {
binding
.source
.map_or(true, |right| !checker.semantic.same_branch(left, right))
.is_none_or(|right| !checker.semantic.same_branch(left, right))
}) {
continue;
}
Expand Down Expand Up @@ -269,10 +269,10 @@ pub(crate) fn deferred_scopes(checker: &Checker) {
}

// If the bindings are in different forks, abort.
if shadowed.source.map_or(true, |left| {
if shadowed.source.is_none_or(|left| {
binding
.source
.map_or(true, |right| !checker.semantic.same_branch(left, right))
.is_none_or(|right| !checker.semantic.same_branch(left, right))
}) {
continue;
}
Expand Down
2 changes: 1 addition & 1 deletion crates/ruff_linter/src/docstrings/sections.rs
Original file line number Diff line number Diff line change
Expand Up @@ -453,7 +453,7 @@ fn is_docstring_section(
}

// Determine whether the previous line looks like the end of a paragraph.
let previous_line_looks_like_end_of_paragraph = previous_line.map_or(true, |previous_line| {
let previous_line_looks_like_end_of_paragraph = previous_line.is_none_or(|previous_line| {
let previous_line = previous_line.trim();
let previous_line_ends_with_punctuation = [',', ';', '.', '-', '\\', '/', ']', '}', ')']
.into_iter()
Expand Down
2 changes: 1 addition & 1 deletion crates/ruff_linter/src/rules/flake8_bandit/helpers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ pub(super) fn matches_password_name(string: &str) -> bool {
}

pub(super) fn is_untyped_exception(type_: Option<&Expr>, semantic: &SemanticModel) -> bool {
type_.map_or(true, |type_| {
type_.is_none_or(|type_| {
if let Expr::Tuple(ast::ExprTuple { elts, .. }) = &type_ {
elts.iter().any(|type_| {
semantic
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,10 +62,10 @@ pub(crate) fn hardcoded_sql_expression(checker: &Checker, expr: &Expr) {
op: Operator::Add, ..
}) => {
// Only evaluate the full BinOp, not the nested components.
if !checker
if checker
.semantic()
.current_expression_parent()
.map_or(true, |parent| !parent.is_bin_op_expr())
.is_some_and(ruff_python_ast::Expr::is_bin_op_expr)
{
return;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,7 @@ fn detect_insecure_crypt_calls(checker: &Checker, call: &ast::ExprCall) {
fn is_used_for_security(arguments: &Arguments) -> bool {
arguments
.find_keyword("usedforsecurity")
.map_or(true, |keyword| !is_const_false(&keyword.value))
.is_none_or(|keyword| !is_const_false(&keyword.value))
}

#[derive(Debug, Copy, Clone)]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,10 +53,10 @@ pub(crate) fn tarfile_unsafe_members(checker: &Checker, call: &ast::ExprCall) {
return;
}

if !call
if call
.func
.as_attribute_expr()
.is_some_and(|attr| attr.attr.as_str() == "extractall")
.is_none_or(|attr| attr.attr.as_str() != "extractall")
{
return;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,17 +66,17 @@ pub(crate) fn implicit_namespace_package(
// Ignore non-`.py` files, which don't require an `__init__.py`.
&& PySourceType::try_from_path(path).is_some_and(PySourceType::is_py_file)
// Ignore any files that are direct children of the project root.
&& !path
&& path
.parent()
.is_some_and( |parent| parent == project_root)
.is_none_or( |parent| parent != project_root)
// Ignore any files that are direct children of a source directory (e.g., `src/manage.py`).
&& !path
.parent()
.is_some_and( |parent| src.iter().any(|src| src == parent))
// Ignore files that contain a shebang.
&& !comment_ranges
&& comment_ranges
.first().filter(|range| range.start() == TextSize::from(0))
.is_some_and(|range| ShebangDirective::try_extract(locator.slice(*range)).is_some())
.is_none_or(|range| ShebangDirective::try_extract(locator.slice(*range)).is_none())
// Ignore PEP 723 scripts.
&& ScriptTag::parse(locator.contents().as_bytes()).is_none()
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -109,8 +109,7 @@ pub(crate) fn print_call(checker: &Checker, call: &ast::ExprCall) {
// or `"sys.stderr"`), don't trigger T201.
if let Some(keyword) = call.arguments.find_keyword("file") {
if !keyword.value.is_none_literal_expr() {
if semantic.resolve_qualified_name(&keyword.value).map_or(
true,
if semantic.resolve_qualified_name(&keyword.value).is_none_or(
|qualified_name| {
!matches!(qualified_name.segments(), ["sys", "stdout" | "stderr"])
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -294,7 +294,7 @@ fn check_positional_args_for_overloaded_method(
predicate: impl FnOnce(&Expr) -> bool,
semantic: &SemanticModel,
) -> bool {
parameter.annotation().map_or(true, |annotation| {
parameter.annotation().is_none_or(|annotation| {
predicate(annotation) || is_object_or_unused(annotation, semantic)
})
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ pub(crate) fn fail_call(checker: &Checker, call: &ast::ExprCall) {
.arguments
.find_argument_value("reason", 0)
.or_else(|| call.arguments.find_argument_value("msg", 0))
.map_or(true, is_empty_or_null_string)
.is_none_or(is_empty_or_null_string)
{
checker.report_diagnostic(Diagnostic::new(PytestFailWithoutMessage, call.func.range()));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,7 @@ pub(crate) fn raises_call(checker: &Checker, call: &ast::ExprCall) {
if call
.arguments
.find_keyword("match")
.map_or(true, |k| is_empty_or_null_string(&k.value))
.is_none_or(|k| is_empty_or_null_string(&k.value))
{
exception_needs_match(checker, exception);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,7 @@ pub(crate) fn warns_call(checker: &Checker, call: &ast::ExprCall) {
if call
.arguments
.find_keyword("match")
.map_or(true, |k| is_empty_or_null_string(&k.value))
.is_none_or(|k| is_empty_or_null_string(&k.value))
{
warning_needs_match(checker, warning);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -817,7 +817,7 @@ pub(crate) fn function(checker: &Checker, function_def: &ast::StmtFunctionDef) {
} else {
if checker.enabled(Rule::UnnecessaryReturnNone) {
// Skip functions that have a return annotation that is not `None`.
if returns.as_deref().map_or(true, Expr::is_none_literal_expr) {
if returns.as_deref().is_none_or(Expr::is_none_literal_expr) {
unnecessary_return_none(checker, decorator_list, &stack);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,7 @@ pub(crate) fn multiple_with_statements(
with_stmt,
) {
Ok(edit) => {
if edit.content().map_or(true, |content| {
if edit.content().is_none_or(|content| {
fits(
content,
with_stmt.into(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ pub(crate) fn nested_if_statements(
diagnostic.try_set_optional_fix(|| {
match collapse_nested_if(checker.locator(), checker.stylist(), nested_if) {
Ok(edit) => {
if edit.content().map_or(true, |content| {
if edit.content().is_none_or(|content| {
fits(
content,
(&nested_if).into(),
Expand Down
7 changes: 3 additions & 4 deletions crates/ruff_linter/src/rules/isort/normalize.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,10 +53,9 @@ pub(crate) fn normalize_imports<'a>(
} => {
// Whether to track each member of the import as a separate entry.
let isolate_aliases = settings.force_single_line
&& module.map_or(true, |module| {
!settings.single_line_exclusions.contains(module)
})
&& !names.first().is_some_and(|alias| alias.name == "*");
&& module
.is_none_or(|module| !settings.single_line_exclusions.contains(module))
&& names.first().is_none_or(|alias| alias.name != "*");

// Insert comments on the statement itself.
if isolate_aliases {
Expand Down
2 changes: 1 addition & 1 deletion crates/ruff_linter/src/rules/pep8_naming/settings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ impl IgnoreNames {
) -> Result<Self, SettingsError> {
// If the user is not customizing the set of ignored names, use the default matcher,
// which is hard-coded to avoid expensive regex matching.
if ignore_names.is_none() && extend_ignore_names.as_ref().map_or(true, Vec::is_empty) {
if ignore_names.is_none() && extend_ignore_names.as_ref().is_none_or(Vec::is_empty) {
return Ok(IgnoreNames::Default);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ pub(crate) fn manual_list_copy(checker: &Checker, for_stmt: &ast::StmtFor) {
}

// Only flag direct list copies (e.g., `for x in y: filtered.append(x)`).
if !arg.as_name_expr().is_some_and(|arg| arg.id == *id) {
if arg.as_name_expr().is_none_or(|arg| arg.id != *id) {
return;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -245,9 +245,9 @@ pub(crate) fn missing_whitespace_around_operator(
let has_leading_trivia =
prev_token.end() < token.start() || is_non_logical_token(prev_token.kind());

let has_trailing_trivia = tokens.peek().map_or(true, |next| {
token.end() < next.start() || is_non_logical_token(next.kind())
});
let has_trailing_trivia = tokens
.peek()
.is_none_or(|next| token.end() < next.start() || is_non_logical_token(next.kind()));

match (has_leading_trivia, has_trailing_trivia) {
// Operator with trailing but no leading space, enforce consistent spacing.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -794,7 +794,7 @@ impl<'a> GeneratorOrIteratorArguments<'a> {
match self {
Self::Unparameterized => true,
Self::Single(_) => true,
Self::Several(elements) => elements.get(2).map_or(true, Expr::is_none_literal_expr),
Self::Several(elements) => elements.get(2).is_none_or(Expr::is_none_literal_expr),
}
}
}
Expand Down Expand Up @@ -947,7 +947,7 @@ pub(crate) fn check_docstring(
match function_def.returns.as_deref() {
Some(returns)
if !generator_annotation_arguments(returns, semantic).is_some_and(
|arguments| arguments.first().map_or(true, Expr::is_none_literal_expr),
|arguments| arguments.first().is_none_or(Expr::is_none_literal_expr),
) =>
{
diagnostics
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ pub(crate) fn no_signature(checker: &Checker, docstring: &Docstring) {
let preceded_by_word_boundary = first_line[..index]
.chars()
.next_back()
.map_or(true, |c| matches!(c, ' ' | '\t' | ';' | ','));
.is_none_or(|c| matches!(c, ' ' | '\t' | ';' | ','));
if !preceded_by_word_boundary {
return false;
}
Expand Down
2 changes: 1 addition & 1 deletion crates/ruff_linter/src/rules/pydocstyle/rules/sections.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1871,7 +1871,7 @@ fn args_section(context: &SectionContext) -> FxHashSet<String> {
// Reformat each section.
let mut args_sections: Vec<String> = vec![];
for line in args_content.trim().lines() {
if line.chars().next().map_or(true, char::is_whitespace) {
if line.chars().next().is_none_or(char::is_whitespace) {
// This is a continuation of the documentation for the previous parameter,
// because it starts with whitespace.
if let Some(last) = args_sections.last_mut() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ pub(crate) fn potential_index_error(checker: &Checker, value: &Expr, slice: &Exp

// Emit a diagnostic if the index is out of bounds. If the index can't be represented as an
// `i64`, but the length _can_, then the index is definitely out of bounds.
if index.map_or(true, |index| index >= length || index < -length) {
if index.is_none_or(|index| index >= length || index < -length) {
checker.report_diagnostic(Diagnostic::new(PotentialIndexError, slice.range()));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -140,9 +140,9 @@ pub(crate) fn type_name_incorrect_variance(checker: &Checker, value: &Expr) {
/// Returns `true` if the parameter name does not match its type variance.
fn mismatch(param_name: &str, covariant: Option<&Expr>, contravariant: Option<&Expr>) -> bool {
if param_name.ends_with("_co") {
covariant.map_or(true, |covariant| !is_const_true(covariant))
covariant.is_none_or(|covariant| !is_const_true(covariant))
} else if param_name.ends_with("_contra") {
contravariant.map_or(true, |contravariant| !is_const_true(contravariant))
contravariant.is_none_or(|contravariant| !is_const_true(contravariant))
} else {
covariant.is_some_and(is_const_true) || contravariant.is_some_and(is_const_true)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@ fn enumerate_items<'a>(
// If the `enumerate` call has a non-zero `start`, don't omit.
if !arguments
.find_argument_value("start", 1)
.map_or(true, |expr| {
.is_none_or(|expr| {
matches!(
expr,
Expr::NumberLiteral(ast::ExprNumberLiteral {
Expand Down
4 changes: 2 additions & 2 deletions crates/ruff_linter/src/rules/pylint/rules/useless_return.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ pub(crate) fn useless_return(
returns: Option<&Expr>,
) {
// Skip functions that have a return annotation that is not `None`.
if !returns.map_or(true, Expr::is_none_literal_expr) {
if !returns.is_none_or(Expr::is_none_literal_expr) {
return;
}

Expand Down Expand Up @@ -82,7 +82,7 @@ pub(crate) fn useless_return(
// Verify that the return statement is either bare or returns `None`.
if !value
.as_ref()
.map_or(true, |expr| expr.is_none_literal_expr())
.is_none_or(|expr| expr.is_none_literal_expr())
{
return;
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -106,12 +106,12 @@ pub(crate) fn int_on_sliced_str(checker: &Checker, call: &ExprCall) {
if expr_slice.upper.is_some() || expr_slice.step.is_some() {
return;
}
if !expr_slice
if expr_slice
.lower
.as_ref()
.and_then(|expr| expr.as_number_literal_expr())
.and_then(|expr| expr.value.as_int())
.is_some_and(|expr| expr.as_u8() == Some(2))
.is_none_or(|expr| expr.as_u8() != Some(2))
{
return;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ fn peel_lists(expr: &Expr) -> &Expr {
return expr;
}

if !func.as_name_expr().is_some_and(|name| name.id == "list") {
if func.as_name_expr().is_none_or(|name| name.id != "list") {
return expr;
}

Expand Down Expand Up @@ -175,11 +175,11 @@ fn extract_name_from_sliced_reversed(expr: &Expr) -> Option<&ExprName> {
else {
return None;
};
if !operand
if operand
.as_number_literal_expr()
.and_then(|num| num.value.as_int())
.and_then(Int::as_u8)
.is_some_and(|value| value == 1)
.is_none_or(|value| value != 1)
{
return None;
};
Expand Down
Loading

0 comments on commit dd6f623

Please sign in to comment.