Upgrade to Rust 1.80 (#12586)

This commit is contained in:
Micha Reiser 2024-07-30 21:18:08 +02:00 committed by GitHub
parent ee103ffb25
commit 138e70bd5c
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
29 changed files with 57 additions and 48 deletions

View file

@ -156,6 +156,7 @@ zip = { version = "0.6.6", default-features = false, features = ["zstd"] }
[workspace.lints.rust] [workspace.lints.rust]
unsafe_code = "warn" unsafe_code = "warn"
unreachable_pub = "warn" unreachable_pub = "warn"
unexpected_cfgs = { level = "warn", check-cfg = ['cfg(fuzzing)'] }
[workspace.lints.clippy] [workspace.lints.clippy]
pedantic = { level = "warn", priority = -2 } pedantic = { level = "warn", priority = -2 }

View file

@ -11,3 +11,11 @@ doc-valid-idents = [
"SQLAlchemy", "SQLAlchemy",
"StackOverflow", "StackOverflow",
] ]
ignore-interior-mutability = [
# Interned is read-only. The wrapped `Rc` never gets updated.
"ruff_formatter::format_element::Interned",
# The expression is read-only.
"ruff_python_ast::hashable::HashableExpr",
]

View file

@ -330,7 +330,7 @@ where
function_def.type_params.as_deref(), function_def.type_params.as_deref(),
|builder| { |builder| {
builder.visit_parameters(&function_def.parameters); builder.visit_parameters(&function_def.parameters);
for expr in &function_def.returns { if let Some(expr) = &function_def.returns {
builder.visit_annotation(expr); builder.visit_annotation(expr);
} }

View file

@ -719,7 +719,7 @@ impl<'a> Visitor<'a> for Checker<'a> {
self.visit_expr(expr); self.visit_expr(expr);
} }
} }
for expr in returns { if let Some(expr) = returns {
match annotation { match annotation {
AnnotationContext::RuntimeRequired => { AnnotationContext::RuntimeRequired => {
self.visit_runtime_required_annotation(expr); self.visit_runtime_required_annotation(expr);
@ -1240,7 +1240,7 @@ impl<'a> Visitor<'a> for Checker<'a> {
for arg in args { for arg in args {
self.visit_type_definition(arg); self.visit_type_definition(arg);
} }
for keyword in arguments.keywords.iter() { for keyword in &*arguments.keywords {
let Keyword { let Keyword {
arg, arg,
value, value,
@ -1286,7 +1286,7 @@ impl<'a> Visitor<'a> for Checker<'a> {
} }
} }
for keyword in arguments.keywords.iter() { for keyword in &*arguments.keywords {
let Keyword { arg, value, .. } = keyword; let Keyword { arg, value, .. } = keyword;
match (arg.as_ref(), value) { match (arg.as_ref(), value) {
// Ex) NamedTuple("a", **{"a": int}) // Ex) NamedTuple("a", **{"a": int})
@ -1331,7 +1331,7 @@ impl<'a> Visitor<'a> for Checker<'a> {
} }
// Ex) TypedDict("a", a=int) // Ex) TypedDict("a", a=int)
for keyword in arguments.keywords.iter() { for keyword in &*arguments.keywords {
let Keyword { value, .. } = keyword; let Keyword { value, .. } = keyword;
self.visit_type_definition(value); self.visit_type_definition(value);
} }
@ -1345,13 +1345,13 @@ impl<'a> Visitor<'a> for Checker<'a> {
for arg in args { for arg in args {
self.visit_non_type_definition(arg); self.visit_non_type_definition(arg);
} }
for keyword in arguments.keywords.iter() { for keyword in &*arguments.keywords {
let Keyword { value, .. } = keyword; let Keyword { value, .. } = keyword;
self.visit_non_type_definition(value); self.visit_non_type_definition(value);
} }
} else { } else {
// Ex) DefaultNamedArg(type="bool", name="some_prop_name") // Ex) DefaultNamedArg(type="bool", name="some_prop_name")
for keyword in arguments.keywords.iter() { for keyword in &*arguments.keywords {
let Keyword { let Keyword {
value, value,
arg, arg,
@ -1369,10 +1369,10 @@ impl<'a> Visitor<'a> for Checker<'a> {
// If we're in a type definition, we need to treat the arguments to any // If we're in a type definition, we need to treat the arguments to any
// other callables as non-type definitions (i.e., we don't want to treat // other callables as non-type definitions (i.e., we don't want to treat
// any strings as deferred type definitions). // any strings as deferred type definitions).
for arg in arguments.args.iter() { for arg in &*arguments.args {
self.visit_non_type_definition(arg); self.visit_non_type_definition(arg);
} }
for keyword in arguments.keywords.iter() { for keyword in &*arguments.keywords {
let Keyword { value, .. } = keyword; let Keyword { value, .. } = keyword;
self.visit_non_type_definition(value); self.visit_non_type_definition(value);
} }

View file

@ -13,10 +13,9 @@ impl Emitter for JsonLinesEmitter {
messages: &[Message], messages: &[Message],
context: &EmitterContext, context: &EmitterContext,
) -> anyhow::Result<()> { ) -> anyhow::Result<()> {
let mut w = writer;
for message in messages { for message in messages {
serde_json::to_writer(&mut w, &message_to_json_value(message, context))?; serde_json::to_writer(&mut *writer, &message_to_json_value(message, context))?;
w.write_all(b"\n")?; writer.write_all(b"\n")?;
} }
Ok(()) Ok(())
} }

View file

@ -132,7 +132,7 @@ impl<'a> Visitor<'a> for SuspiciousVariablesVisitor<'a> {
match func.as_ref() { match func.as_ref() {
Expr::Name(ast::ExprName { id, .. }) => { Expr::Name(ast::ExprName { id, .. }) => {
if matches!(id.as_str(), "filter" | "reduce" | "map") { if matches!(id.as_str(), "filter" | "reduce" | "map") {
for arg in arguments.args.iter() { for arg in &*arguments.args {
if arg.is_lambda_expr() { if arg.is_lambda_expr() {
self.safe_functions.push(arg); self.safe_functions.push(arg);
} }
@ -143,7 +143,7 @@ impl<'a> Visitor<'a> for SuspiciousVariablesVisitor<'a> {
if attr == "reduce" { if attr == "reduce" {
if let Expr::Name(ast::ExprName { id, .. }) = value.as_ref() { if let Expr::Name(ast::ExprName { id, .. }) = value.as_ref() {
if id == "functools" { if id == "functools" {
for arg in arguments.args.iter() { for arg in &*arguments.args {
if arg.is_lambda_expr() { if arg.is_lambda_expr() {
self.safe_functions.push(arg); self.safe_functions.push(arg);
} }
@ -155,7 +155,7 @@ impl<'a> Visitor<'a> for SuspiciousVariablesVisitor<'a> {
_ => {} _ => {}
} }
for keyword in arguments.keywords.iter() { for keyword in &*arguments.keywords {
if keyword.arg.as_ref().is_some_and(|arg| arg == "key") if keyword.arg.as_ref().is_some_and(|arg| arg == "key")
&& keyword.value.is_lambda_expr() && keyword.value.is_lambda_expr()
{ {

View file

@ -116,7 +116,7 @@ fn is_infinite_iterator(arg: &Expr, semantic: &SemanticModel) -> bool {
} }
// Ex) `iterools.repeat(1, times=None)` // Ex) `iterools.repeat(1, times=None)`
for keyword in keywords.iter() { for keyword in &**keywords {
if keyword.arg.as_ref().is_some_and(|name| name == "times") { if keyword.arg.as_ref().is_some_and(|name| name == "times") {
if keyword.value.is_none_literal_expr() { if keyword.value.is_none_literal_expr() {
return true; return true;

View file

@ -88,7 +88,7 @@ fn is_nullable_field<'a>(value: &'a Expr, semantic: &'a SemanticModel) -> Option
let mut null_key = false; let mut null_key = false;
let mut blank_key = false; let mut blank_key = false;
let mut unique_key = false; let mut unique_key = false;
for keyword in call.arguments.keywords.iter() { for keyword in &*call.arguments.keywords {
let Some(argument) = &keyword.arg else { let Some(argument) = &keyword.arg else {
continue; continue;
}; };

View file

@ -110,7 +110,7 @@ fn check_log_record_attr_clash(checker: &mut Checker, extra: &Keyword) {
.. ..
}) => { }) => {
if checker.semantic().match_builtin_expr(func, "dict") { if checker.semantic().match_builtin_expr(func, "dict") {
for keyword in keywords.iter() { for keyword in &**keywords {
if let Some(attr) = &keyword.arg { if let Some(attr) = &keyword.arg {
if is_reserved_attr(attr) { if is_reserved_attr(attr) {
checker.diagnostics.push(Diagnostic::new( checker.diagnostics.push(Diagnostic::new(

View file

@ -58,7 +58,7 @@ impl Violation for UnnecessaryDictKwargs {
/// PIE804 /// PIE804
pub(crate) fn unnecessary_dict_kwargs(checker: &mut Checker, call: &ast::ExprCall) { pub(crate) fn unnecessary_dict_kwargs(checker: &mut Checker, call: &ast::ExprCall) {
let mut duplicate_keywords = None; let mut duplicate_keywords = None;
for keyword in call.arguments.keywords.iter() { for keyword in &*call.arguments.keywords {
// keyword is a spread operator (indicated by None). // keyword is a spread operator (indicated by None).
if keyword.arg.is_some() { if keyword.arg.is_some() {
continue; continue;
@ -152,7 +152,7 @@ fn duplicates(call: &ast::ExprCall) -> FxHashSet<&str> {
FxHashSet::with_capacity_and_hasher(call.arguments.keywords.len(), FxBuildHasher); FxHashSet::with_capacity_and_hasher(call.arguments.keywords.len(), FxBuildHasher);
let mut duplicates = let mut duplicates =
FxHashSet::with_capacity_and_hasher(call.arguments.keywords.len(), FxBuildHasher); FxHashSet::with_capacity_and_hasher(call.arguments.keywords.len(), FxBuildHasher);
for keyword in call.arguments.keywords.iter() { for keyword in &*call.arguments.keywords {
if let Some(name) = &keyword.arg { if let Some(name) = &keyword.arg {
if !seen.insert(name.as_str()) { if !seen.insert(name.as_str()) {
duplicates.insert(name.as_str()); duplicates.insert(name.as_str());

View file

@ -180,8 +180,8 @@ fn is_type(expr: &Expr, semantic: &SemanticModel) -> bool {
/// Returns `true` if the [`Expr`] appears to be a reference to a NumPy dtype, since: /// Returns `true` if the [`Expr`] appears to be a reference to a NumPy dtype, since:
/// > `dtype` are a bit of a strange beast, but definitely best thought of as instances, not /// > `dtype` are a bit of a strange beast, but definitely best thought of as instances, not
/// > classes, and they are meant to be comparable not just to their own class, but also to the /// > classes, and they are meant to be comparable not just to their own class, but also to the
/// corresponding scalar types (e.g., `x.dtype == np.float32`) and strings (e.g., /// > corresponding scalar types (e.g., `x.dtype == np.float32`) and strings (e.g.,
/// `x.dtype == ['i1,i4']`; basically, __eq__ always tries to do `dtype(other)`). /// > `x.dtype == ['i1,i4']`; basically, __eq__ always tries to do `dtype(other)`).
fn is_dtype(expr: &Expr, semantic: &SemanticModel) -> bool { fn is_dtype(expr: &Expr, semantic: &SemanticModel) -> bool {
match expr { match expr {
// Ex) `np.dtype(obj)` // Ex) `np.dtype(obj)`

View file

@ -64,7 +64,7 @@ pub(crate) fn duplicate_bases(checker: &mut Checker, name: &str, arguments: Opti
let bases = &arguments.args; let bases = &arguments.args;
let mut seen: FxHashSet<&str> = FxHashSet::with_capacity_and_hasher(bases.len(), FxBuildHasher); let mut seen: FxHashSet<&str> = FxHashSet::with_capacity_and_hasher(bases.len(), FxBuildHasher);
for base in bases.iter() { for base in &**bases {
if let Expr::Name(ast::ExprName { id, .. }) = base { if let Expr::Name(ast::ExprName { id, .. }) = base {
if !seen.insert(id) { if !seen.insert(id) {
let mut diagnostic = Diagnostic::new( let mut diagnostic = Diagnostic::new(

View file

@ -40,7 +40,7 @@ pub(crate) fn repeated_keyword_argument(checker: &mut Checker, call: &ExprCall)
let mut seen = FxHashSet::with_capacity_and_hasher(arguments.keywords.len(), FxBuildHasher); let mut seen = FxHashSet::with_capacity_and_hasher(arguments.keywords.len(), FxBuildHasher);
for keyword in arguments.keywords.iter() { for keyword in &*arguments.keywords {
if let Some(id) = &keyword.arg { if let Some(id) = &keyword.arg {
// Ex) `func(a=1, a=2)` // Ex) `func(a=1, a=2)`
if !seen.insert(id.as_str()) { if !seen.insert(id.as_str()) {

View file

@ -71,7 +71,7 @@ impl<'a> FormatSummaryValues<'a> {
let mut extracted_args: Vec<&Expr> = Vec::new(); let mut extracted_args: Vec<&Expr> = Vec::new();
let mut extracted_kwargs: FxHashMap<&str, &Expr> = FxHashMap::default(); let mut extracted_kwargs: FxHashMap<&str, &Expr> = FxHashMap::default();
for arg in call.arguments.args.iter() { for arg in &*call.arguments.args {
if matches!(arg, Expr::Starred(..)) if matches!(arg, Expr::Starred(..))
|| contains_quotes(locator.slice(arg)) || contains_quotes(locator.slice(arg))
|| locator.contains_line_break(arg.range()) || locator.contains_line_break(arg.range())
@ -80,7 +80,7 @@ impl<'a> FormatSummaryValues<'a> {
} }
extracted_args.push(arg); extracted_args.push(arg);
} }
for keyword in call.arguments.keywords.iter() { for keyword in &*call.arguments.keywords {
let Keyword { let Keyword {
arg, arg,
value, value,

View file

@ -108,7 +108,7 @@ pub(crate) fn replace_str_enum(checker: &mut Checker, class_def: &ast::StmtClass
// Determine whether the class inherits from both `str` and `enum.Enum`. // Determine whether the class inherits from both `str` and `enum.Enum`.
let mut inherits_str = false; let mut inherits_str = false;
let mut inherits_enum = false; let mut inherits_enum = false;
for base in arguments.args.iter() { for base in &*arguments.args {
if let Some(qualified_name) = checker.semantic().resolve_qualified_name(base) { if let Some(qualified_name) = checker.semantic().resolve_qualified_name(base) {
match qualified_name.segments() { match qualified_name.segments() {
["" | "builtins", "str"] => inherits_str = true, ["" | "builtins", "str"] => inherits_str = true,

View file

@ -50,7 +50,7 @@ pub(crate) fn useless_object_inheritance(checker: &mut Checker, class_def: &ast:
return; return;
}; };
for base in arguments.args.iter() { for base in &*arguments.args {
if !checker.semantic().match_builtin_expr(base, "object") { if !checker.semantic().match_builtin_expr(base, "object") {
continue; continue;
} }

View file

@ -138,7 +138,7 @@ pub(crate) fn sorted_min_max(checker: &mut Checker, subscript: &ast::ExprSubscri
let mut key_keyword_expr = None; let mut key_keyword_expr = None;
// Check if the call to `sorted()` has the `reverse` and `key` keywords. // Check if the call to `sorted()` has the `reverse` and `key` keywords.
for keyword in arguments.keywords.iter() { for keyword in &*arguments.keywords {
// If the call contains `**kwargs`, return. // If the call contains `**kwargs`, return.
let Some(arg) = keyword.arg.as_ref() else { let Some(arg) = keyword.arg.as_ref() else {
return; return;

View file

@ -174,12 +174,12 @@ fn should_be_fstring(
_ => {} _ => {}
} }
} }
for keyword in keywords.iter() { for keyword in &**keywords {
if let Some(ident) = keyword.arg.as_ref() { if let Some(ident) = keyword.arg.as_ref() {
arg_names.insert(ident.as_str()); arg_names.insert(ident.as_str());
} }
} }
for arg in args.iter() { for arg in &**args {
if let ast::Expr::Name(ast::ExprName { id, .. }) = arg { if let ast::Expr::Name(ast::ExprName { id, .. }) = arg {
arg_names.insert(id.as_str()); arg_names.insert(id.as_str());
} }

View file

@ -119,7 +119,7 @@ fn function_def_visit_preorder_except_body<'a, V>(
visitor.visit_parameters(parameters); visitor.visit_parameters(parameters);
for expr in returns { if let Some(expr) = returns {
visitor.visit_annotation(expr); visitor.visit_annotation(expr);
} }
} }

View file

@ -785,7 +785,7 @@ impl AstNode for ast::StmtFunctionDef {
visitor.visit_parameters(parameters); visitor.visit_parameters(parameters);
for expr in returns { if let Some(expr) = returns {
visitor.visit_annotation(expr); visitor.visit_annotation(expr);
} }

View file

@ -143,7 +143,7 @@ pub fn walk_stmt<'a, V: Visitor<'a> + ?Sized>(visitor: &mut V, stmt: &'a Stmt) {
visitor.visit_type_params(type_params); visitor.visit_type_params(type_params);
} }
visitor.visit_parameters(parameters); visitor.visit_parameters(parameters);
for expr in returns { if let Some(expr) = returns {
visitor.visit_annotation(expr); visitor.visit_annotation(expr);
} }
visitor.visit_body(body); visitor.visit_body(body);
@ -593,10 +593,10 @@ pub fn walk_arguments<'a, V: Visitor<'a> + ?Sized>(visitor: &mut V, arguments: &
// Note that the there might be keywords before the last arg, e.g. in // Note that the there might be keywords before the last arg, e.g. in
// f(*args, a=2, *args2, **kwargs)`, but we follow Python in evaluating first `args` and then // f(*args, a=2, *args2, **kwargs)`, but we follow Python in evaluating first `args` and then
// `keywords`. See also [Arguments::arguments_source_order`]. // `keywords`. See also [Arguments::arguments_source_order`].
for arg in arguments.args.iter() { for arg in &*arguments.args {
visitor.visit_expr(arg); visitor.visit_expr(arg);
} }
for keyword in arguments.keywords.iter() { for keyword in &*arguments.keywords {
visitor.visit_keyword(keyword); visitor.visit_keyword(keyword);
} }
} }

View file

@ -130,7 +130,7 @@ pub fn walk_stmt<V: Transformer + ?Sized>(visitor: &V, stmt: &mut Stmt) {
visitor.visit_type_params(type_params); visitor.visit_type_params(type_params);
} }
visitor.visit_parameters(parameters); visitor.visit_parameters(parameters);
for expr in returns { if let Some(expr) = returns {
visitor.visit_annotation(expr); visitor.visit_annotation(expr);
} }
visitor.visit_body(body); visitor.visit_body(body);
@ -579,10 +579,10 @@ pub fn walk_arguments<V: Transformer + ?Sized>(visitor: &V, arguments: &mut Argu
// Note that the there might be keywords before the last arg, e.g. in // Note that the there might be keywords before the last arg, e.g. in
// f(*args, a=2, *args2, **kwargs)`, but we follow Python in evaluating first `args` and then // f(*args, a=2, *args2, **kwargs)`, but we follow Python in evaluating first `args` and then
// `keywords`. See also [Arguments::arguments_source_order`]. // `keywords`. See also [Arguments::arguments_source_order`].
for arg in arguments.args.iter_mut() { for arg in &mut *arguments.args {
visitor.visit_expr(arg); visitor.visit_expr(arg);
} }
for keyword in arguments.keywords.iter_mut() { for keyword in &mut *arguments.keywords {
visitor.visit_keyword(keyword); visitor.visit_keyword(keyword);
} }
} }

View file

@ -17,6 +17,7 @@ use crate::{has_skip_comment, prelude::*};
/// > A compound statement consists of one or more clauses. A clause consists of a header and a suite. /// > A compound statement consists of one or more clauses. A clause consists of a header and a suite.
/// > The clause headers of a particular compound statement are all at the same indentation level. /// > The clause headers of a particular compound statement are all at the same indentation level.
/// > Each clause header begins with a uniquely identifying keyword and ends with a colon. /// > Each clause header begins with a uniquely identifying keyword and ends with a colon.
///
/// [source](https://docs.python.org/3/reference/compound_stmts.html#compound-statements) /// [source](https://docs.python.org/3/reference/compound_stmts.html#compound-statements)
#[derive(Copy, Clone)] #[derive(Copy, Clone)]
pub(crate) enum ClauseHeader<'a> { pub(crate) enum ClauseHeader<'a> {

View file

@ -2295,7 +2295,7 @@ impl<'src> Parser<'src> {
} }
if arguments.len() > 1 { if arguments.len() > 1 {
for arg in arguments.args.iter() { for arg in &*arguments.args {
if let Some(ast::ExprGenerator { if let Some(ast::ExprGenerator {
range, range,
parenthesized: false, parenthesized: false,

View file

@ -1,2 +1,2 @@
[toolchain] [toolchain]
channel = "1.79" channel = "1.80"