diff --git a/crates/ruff_linter/src/checkers/ast/mod.rs b/crates/ruff_linter/src/checkers/ast/mod.rs index 503bf71aaf6e1..d980831d3b159 100644 --- a/crates/ruff_linter/src/checkers/ast/mod.rs +++ b/crates/ruff_linter/src/checkers/ast/mod.rs @@ -31,8 +31,8 @@ use std::path::Path; use itertools::Itertools; use log::debug; use ruff_python_ast::{ - self as ast, Arguments, Comprehension, ElifElseClause, ExceptHandler, Expr, ExprContext, - Keyword, MatchCase, Parameter, ParameterWithDefault, Parameters, Pattern, Stmt, Suite, UnaryOp, + self as ast, Comprehension, ElifElseClause, ExceptHandler, Expr, ExprContext, Keyword, + MatchCase, Parameter, ParameterWithDefault, Parameters, Pattern, Stmt, Suite, UnaryOp, }; use ruff_text_size::{Ranged, TextRange, TextSize}; @@ -989,12 +989,7 @@ where } Expr::Call(ast::ExprCall { func, - arguments: - Arguments { - args, - keywords, - range: _, - }, + arguments, range: _, }) => { self.visit_expr(func); @@ -1037,7 +1032,7 @@ where }); match callable { Some(typing::Callable::Bool) => { - let mut args = args.iter(); + let mut args = arguments.args.iter(); if let Some(arg) = args.next() { self.visit_boolean_test(arg); } @@ -1046,7 +1041,7 @@ where } } Some(typing::Callable::Cast) => { - let mut args = args.iter(); + let mut args = arguments.args.iter(); if let Some(arg) = args.next() { self.visit_type_definition(arg); } @@ -1055,7 +1050,7 @@ where } } Some(typing::Callable::NewType) => { - let mut args = args.iter(); + let mut args = arguments.args.iter(); if let Some(arg) = args.next() { self.visit_non_type_definition(arg); } @@ -1064,21 +1059,21 @@ where } } Some(typing::Callable::TypeVar) => { - let mut args = args.iter(); + let mut args = arguments.args.iter(); if let Some(arg) = args.next() { self.visit_non_type_definition(arg); } for arg in args { self.visit_type_definition(arg); } - for keyword in keywords { + for keyword in arguments.keywords.iter() { let Keyword { arg, value, range: _, } = keyword; if let Some(id) = arg { - if id == "bound" { + if id.as_str() == "bound" { self.visit_type_definition(value); } else { self.visit_non_type_definition(value); @@ -1088,7 +1083,7 @@ where } Some(typing::Callable::NamedTuple) => { // Ex) NamedTuple("a", [("a", int)]) - let mut args = args.iter(); + let mut args = arguments.args.iter(); if let Some(arg) = args.next() { self.visit_non_type_definition(arg); } @@ -1117,7 +1112,7 @@ where } } - for keyword in keywords { + for keyword in arguments.keywords.iter() { let Keyword { arg, value, .. } = keyword; match (arg.as_ref(), value) { // Ex) NamedTuple("a", **{"a": int}) @@ -1144,7 +1139,7 @@ where } Some(typing::Callable::TypedDict) => { // Ex) TypedDict("a", {"a": int}) - let mut args = args.iter(); + let mut args = arguments.args.iter(); if let Some(arg) = args.next() { self.visit_non_type_definition(arg); } @@ -1167,13 +1162,13 @@ where } // Ex) TypedDict("a", a=int) - for keyword in keywords { + for keyword in arguments.keywords.iter() { let Keyword { value, .. } = keyword; self.visit_type_definition(value); } } Some(typing::Callable::MypyExtension) => { - let mut args = args.iter(); + let mut args = arguments.args.iter(); if let Some(arg) = args.next() { // Ex) DefaultNamedArg(bool | None, name="some_prop_name") self.visit_type_definition(arg); @@ -1181,13 +1176,13 @@ where for arg in args { self.visit_non_type_definition(arg); } - for keyword in keywords { + for keyword in arguments.keywords.iter() { let Keyword { value, .. } = keyword; self.visit_non_type_definition(value); } } else { // Ex) DefaultNamedArg(type="bool", name="some_prop_name") - for keyword in keywords { + for keyword in arguments.keywords.iter() { let Keyword { value, arg, @@ -1205,10 +1200,10 @@ where // 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 // any strings as deferred type definitions). - for arg in args { + for arg in arguments.args.iter() { self.visit_non_type_definition(arg); } - for keyword in keywords { + for keyword in arguments.keywords.iter() { let Keyword { value, .. } = keyword; self.visit_non_type_definition(value); } diff --git a/crates/ruff_linter/src/rules/flake8_bugbear/rules/assert_false.rs b/crates/ruff_linter/src/rules/flake8_bugbear/rules/assert_false.rs index 666e82eba5f29..e1d90e54be634 100644 --- a/crates/ruff_linter/src/rules/flake8_bugbear/rules/assert_false.rs +++ b/crates/ruff_linter/src/rules/flake8_bugbear/rules/assert_false.rs @@ -59,11 +59,11 @@ fn assertion_error(msg: Option<&Expr>) -> Stmt { })), arguments: Arguments { args: if let Some(msg) = msg { - vec![msg.clone()] + Box::from([msg.clone()]) } else { - vec![] + Box::from([]) }, - keywords: vec![], + keywords: Box::from([]), range: TextRange::default(), }, range: TextRange::default(), diff --git a/crates/ruff_linter/src/rules/flake8_bugbear/rules/assert_raises_exception.rs b/crates/ruff_linter/src/rules/flake8_bugbear/rules/assert_raises_exception.rs index f17ad3938dd3d..7dc21a544f49a 100644 --- a/crates/ruff_linter/src/rules/flake8_bugbear/rules/assert_raises_exception.rs +++ b/crates/ruff_linter/src/rules/flake8_bugbear/rules/assert_raises_exception.rs @@ -91,7 +91,7 @@ pub(crate) fn assert_raises_exception(checker: &mut Checker, items: &[WithItem]) return; } - let [arg] = arguments.args.as_slice() else { + let [arg] = &*arguments.args else { return; }; diff --git a/crates/ruff_linter/src/rules/flake8_bugbear/rules/function_uses_loop_variable.rs b/crates/ruff_linter/src/rules/flake8_bugbear/rules/function_uses_loop_variable.rs index daf0fe389e9d6..097be0fe2abf8 100644 --- a/crates/ruff_linter/src/rules/flake8_bugbear/rules/function_uses_loop_variable.rs +++ b/crates/ruff_linter/src/rules/flake8_bugbear/rules/function_uses_loop_variable.rs @@ -3,7 +3,7 @@ use ruff_macros::{derive_message_formats, violation}; use ruff_python_ast::types::Node; use ruff_python_ast::visitor; use ruff_python_ast::visitor::Visitor; -use ruff_python_ast::{self as ast, Arguments, Comprehension, Expr, ExprContext, Stmt}; +use ruff_python_ast::{self as ast, Comprehension, Expr, ExprContext, Stmt}; use ruff_text_size::Ranged; use crate::checkers::ast::Checker; @@ -126,18 +126,13 @@ impl<'a> Visitor<'a> for SuspiciousVariablesVisitor<'a> { match expr { Expr::Call(ast::ExprCall { func, - arguments: - Arguments { - args, - keywords, - range: _, - }, + arguments, range: _, }) => { match func.as_ref() { Expr::Name(ast::ExprName { id, .. }) => { if matches!(id.as_str(), "filter" | "reduce" | "map") { - for arg in args { + for arg in arguments.args.iter() { if arg.is_lambda_expr() { self.safe_functions.push(arg); } @@ -148,7 +143,7 @@ impl<'a> Visitor<'a> for SuspiciousVariablesVisitor<'a> { if attr == "reduce" { if let Expr::Name(ast::ExprName { id, .. }) = value.as_ref() { if id == "functools" { - for arg in args { + for arg in arguments.args.iter() { if arg.is_lambda_expr() { self.safe_functions.push(arg); } @@ -160,7 +155,7 @@ impl<'a> Visitor<'a> for SuspiciousVariablesVisitor<'a> { _ => {} } - for keyword in keywords { + for keyword in arguments.keywords.iter() { if keyword.arg.as_ref().is_some_and(|arg| arg == "key") && keyword.value.is_lambda_expr() { diff --git a/crates/ruff_linter/src/rules/flake8_bugbear/rules/zip_without_explicit_strict.rs b/crates/ruff_linter/src/rules/flake8_bugbear/rules/zip_without_explicit_strict.rs index 61b3fe246da45..6a58aa7e89a5f 100644 --- a/crates/ruff_linter/src/rules/flake8_bugbear/rules/zip_without_explicit_strict.rs +++ b/crates/ruff_linter/src/rules/flake8_bugbear/rules/zip_without_explicit_strict.rs @@ -114,7 +114,7 @@ fn is_infinite_iterator(arg: &Expr, semantic: &SemanticModel) -> bool { } // Ex) `iterools.repeat(1, times=None)` - for keyword in keywords { + for keyword in keywords.iter() { if keyword.arg.as_ref().is_some_and(|name| name == "times") { if keyword.value.is_none_literal_expr() { return true; diff --git a/crates/ruff_linter/src/rules/flake8_django/rules/nullable_model_string_field.rs b/crates/ruff_linter/src/rules/flake8_django/rules/nullable_model_string_field.rs index 8b24997b2c3fe..741e8e831f6ac 100644 --- a/crates/ruff_linter/src/rules/flake8_django/rules/nullable_model_string_field.rs +++ b/crates/ruff_linter/src/rules/flake8_django/rules/nullable_model_string_field.rs @@ -88,7 +88,7 @@ fn is_nullable_field<'a>(value: &'a Expr, semantic: &'a SemanticModel) -> Option let mut null_key = false; let mut blank_key = false; let mut unique_key = false; - for keyword in &call.arguments.keywords { + for keyword in call.arguments.keywords.iter() { let Some(argument) = &keyword.arg else { continue; }; diff --git a/crates/ruff_linter/src/rules/flake8_logging_format/rules/logging_call.rs b/crates/ruff_linter/src/rules/flake8_logging_format/rules/logging_call.rs index bd1e6399df596..12b3ad1ebbbda 100644 --- a/crates/ruff_linter/src/rules/flake8_logging_format/rules/logging_call.rs +++ b/crates/ruff_linter/src/rules/flake8_logging_format/rules/logging_call.rs @@ -113,7 +113,7 @@ fn check_log_record_attr_clash(checker: &mut Checker, extra: &Keyword) { .resolve_call_path(func) .is_some_and(|call_path| matches!(call_path.as_slice(), ["", "dict"])) { - for keyword in keywords { + for keyword in keywords.iter() { if let Some(attr) = &keyword.arg { if is_reserved_attr(attr) { checker.diagnostics.push(Diagnostic::new( diff --git a/crates/ruff_linter/src/rules/flake8_pie/rules/multiple_starts_ends_with.rs b/crates/ruff_linter/src/rules/flake8_pie/rules/multiple_starts_ends_with.rs index ea2e45230bea4..b3031ff97e617 100644 --- a/crates/ruff_linter/src/rules/flake8_pie/rules/multiple_starts_ends_with.rs +++ b/crates/ruff_linter/src/rules/flake8_pie/rules/multiple_starts_ends_with.rs @@ -97,7 +97,7 @@ pub(crate) fn multiple_starts_ends_with(checker: &mut Checker, expr: &Expr) { continue; } - let [arg] = args.as_slice() else { + let [arg] = &**args else { continue; }; @@ -188,8 +188,8 @@ pub(crate) fn multiple_starts_ends_with(checker: &mut Checker, expr: &Expr) { let node3 = Expr::Call(ast::ExprCall { func: Box::new(node2), arguments: Arguments { - args: vec![node], - keywords: vec![], + args: Box::from([node]), + keywords: Box::from([]), range: TextRange::default(), }, range: TextRange::default(), diff --git a/crates/ruff_linter/src/rules/flake8_pie/rules/unnecessary_dict_kwargs.rs b/crates/ruff_linter/src/rules/flake8_pie/rules/unnecessary_dict_kwargs.rs index 5f0bf0abb48d0..0d462c1748255 100644 --- a/crates/ruff_linter/src/rules/flake8_pie/rules/unnecessary_dict_kwargs.rs +++ b/crates/ruff_linter/src/rules/flake8_pie/rules/unnecessary_dict_kwargs.rs @@ -59,7 +59,7 @@ impl Violation for UnnecessaryDictKwargs { /// PIE804 pub(crate) fn unnecessary_dict_kwargs(checker: &mut Checker, call: &ast::ExprCall) { let mut duplicate_keywords = None; - for keyword in &call.arguments.keywords { + for keyword in call.arguments.keywords.iter() { // keyword is a spread operator (indicated by None). if keyword.arg.is_some() { continue; @@ -145,7 +145,7 @@ fn duplicates(call: &ast::ExprCall) -> FxHashSet<&str> { call.arguments.keywords.len(), BuildHasherDefault::default(), ); - for keyword in &call.arguments.keywords { + for keyword in call.arguments.keywords.iter() { if let Some(name) = &keyword.arg { if !seen.insert(name.as_str()) { duplicates.insert(name.as_str()); diff --git a/crates/ruff_linter/src/rules/flake8_pie/rules/unnecessary_range_start.rs b/crates/ruff_linter/src/rules/flake8_pie/rules/unnecessary_range_start.rs index 2ddcb313c9a69..e158b75ebe555 100644 --- a/crates/ruff_linter/src/rules/flake8_pie/rules/unnecessary_range_start.rs +++ b/crates/ruff_linter/src/rules/flake8_pie/rules/unnecessary_range_start.rs @@ -60,7 +60,7 @@ pub(crate) fn unnecessary_range_start(checker: &mut Checker, call: &ast::ExprCal } // Verify that the call has exactly two arguments (no `step`). - let [start, _] = call.arguments.args.as_slice() else { + let [start, _] = &*call.arguments.args else { return; }; diff --git a/crates/ruff_linter/src/rules/flake8_pyi/rules/bad_version_info_comparison.rs b/crates/ruff_linter/src/rules/flake8_pyi/rules/bad_version_info_comparison.rs index aac064960692c..0262770f81256 100644 --- a/crates/ruff_linter/src/rules/flake8_pyi/rules/bad_version_info_comparison.rs +++ b/crates/ruff_linter/src/rules/flake8_pyi/rules/bad_version_info_comparison.rs @@ -69,7 +69,7 @@ pub(crate) fn bad_version_info_comparison(checker: &mut Checker, test: &Expr) { return; }; - let ([op], [_right]) = (ops.as_slice(), comparators.as_slice()) else { + let ([op], [_right]) = (&**ops, &**comparators) else { return; }; diff --git a/crates/ruff_linter/src/rules/flake8_pyi/rules/unrecognized_platform.rs b/crates/ruff_linter/src/rules/flake8_pyi/rules/unrecognized_platform.rs index 17c82b398a635..5129d1366f760 100644 --- a/crates/ruff_linter/src/rules/flake8_pyi/rules/unrecognized_platform.rs +++ b/crates/ruff_linter/src/rules/flake8_pyi/rules/unrecognized_platform.rs @@ -101,7 +101,7 @@ pub(crate) fn unrecognized_platform(checker: &mut Checker, test: &Expr) { return; }; - let ([op], [right]) = (ops.as_slice(), comparators.as_slice()) else { + let ([op], [right]) = (&**ops, &**comparators) else { return; }; diff --git a/crates/ruff_linter/src/rules/flake8_pyi/rules/unrecognized_version_info.rs b/crates/ruff_linter/src/rules/flake8_pyi/rules/unrecognized_version_info.rs index 223575db971ae..ec4c5c5543eaf 100644 --- a/crates/ruff_linter/src/rules/flake8_pyi/rules/unrecognized_version_info.rs +++ b/crates/ruff_linter/src/rules/flake8_pyi/rules/unrecognized_version_info.rs @@ -129,7 +129,7 @@ pub(crate) fn unrecognized_version_info(checker: &mut Checker, test: &Expr) { return; }; - let ([op], [comparator]) = (ops.as_slice(), comparators.as_slice()) else { + let ([op], [comparator]) = (&**ops, &**comparators) else { return; }; diff --git a/crates/ruff_linter/src/rules/flake8_pytest_style/rules/assertion.rs b/crates/ruff_linter/src/rules/flake8_pytest_style/rules/assertion.rs index dde7f269280b3..9534c613968ef 100644 --- a/crates/ruff_linter/src/rules/flake8_pytest_style/rules/assertion.rs +++ b/crates/ruff_linter/src/rules/flake8_pytest_style/rules/assertion.rs @@ -411,7 +411,7 @@ fn to_pytest_raises_args<'a>( ) -> Option> { let args = match attr { "assertRaises" | "failUnlessRaises" => { - match (arguments.args.as_slice(), arguments.keywords.as_slice()) { + match (&*arguments.args, &*arguments.keywords) { // Ex) `assertRaises(Exception)` ([arg], []) => Cow::Borrowed(checker.locator().slice(arg)), // Ex) `assertRaises(expected_exception=Exception)` @@ -427,7 +427,7 @@ fn to_pytest_raises_args<'a>( } } "assertRaisesRegex" | "assertRaisesRegexp" => { - match (arguments.args.as_slice(), arguments.keywords.as_slice()) { + match (&*arguments.args, &*arguments.keywords) { // Ex) `assertRaisesRegex(Exception, regex)` ([arg1, arg2], []) => Cow::Owned(format!( "{}, match={}", diff --git a/crates/ruff_linter/src/rules/flake8_pytest_style/rules/parametrize.rs b/crates/ruff_linter/src/rules/flake8_pytest_style/rules/parametrize.rs index daf31d2e2b1f0..eb2608ff79792 100644 --- a/crates/ruff_linter/src/rules/flake8_pytest_style/rules/parametrize.rs +++ b/crates/ruff_linter/src/rules/flake8_pytest_style/rules/parametrize.rs @@ -638,17 +638,17 @@ pub(crate) fn parametrize(checker: &mut Checker, decorators: &[Decorator]) { }) = &decorator.expression { if checker.enabled(Rule::PytestParametrizeNamesWrongType) { - if let [names, ..] = args.as_slice() { + if let [names, ..] = &**args { check_names(checker, decorator, names); } } if checker.enabled(Rule::PytestParametrizeValuesWrongType) { - if let [names, values, ..] = args.as_slice() { + if let [names, values, ..] = &**args { check_values(checker, names, values); } } if checker.enabled(Rule::PytestDuplicateParametrizeTestCases) { - if let [_, values, ..] = args.as_slice() { + if let [_, values, ..] = &**args { check_duplicates(checker, values); } } diff --git a/crates/ruff_linter/src/rules/flake8_pytest_style/rules/unittest_assert.rs b/crates/ruff_linter/src/rules/flake8_pytest_style/rules/unittest_assert.rs index 92ac5389b5671..7dc0d23411319 100644 --- a/crates/ruff_linter/src/rules/flake8_pytest_style/rules/unittest_assert.rs +++ b/crates/ruff_linter/src/rules/flake8_pytest_style/rules/unittest_assert.rs @@ -173,8 +173,8 @@ fn assert(expr: &Expr, msg: Option<&Expr>) -> Stmt { fn compare(left: &Expr, cmp_op: CmpOp, right: &Expr) -> Expr { Expr::Compare(ast::ExprCompare { left: Box::new(left.clone()), - ops: vec![cmp_op], - comparators: vec![right.clone()], + ops: Box::from([cmp_op]), + comparators: Box::from([right.clone()]), range: TextRange::default(), }) } @@ -390,8 +390,8 @@ impl UnittestAssert { let node1 = ast::ExprCall { func: Box::new(node.into()), arguments: Arguments { - args: vec![(**obj).clone(), (**cls).clone()], - keywords: vec![], + args: Box::from([(**obj).clone(), (**cls).clone()]), + keywords: Box::from([]), range: TextRange::default(), }, range: TextRange::default(), @@ -434,8 +434,8 @@ impl UnittestAssert { let node2 = ast::ExprCall { func: Box::new(node1.into()), arguments: Arguments { - args: vec![(**regex).clone(), (**text).clone()], - keywords: vec![], + args: Box::from([(**regex).clone(), (**text).clone()]), + keywords: Box::from([]), range: TextRange::default(), }, range: TextRange::default(), diff --git a/crates/ruff_linter/src/rules/flake8_simplify/rules/ast_bool_op.rs b/crates/ruff_linter/src/rules/flake8_simplify/rules/ast_bool_op.rs index c3d4a86d1a026..5256d69e2f752 100644 --- a/crates/ruff_linter/src/rules/flake8_simplify/rules/ast_bool_op.rs +++ b/crates/ruff_linter/src/rules/flake8_simplify/rules/ast_bool_op.rs @@ -437,8 +437,8 @@ pub(crate) fn duplicate_isinstance_call(checker: &mut Checker, expr: &Expr) { let node2 = ast::ExprCall { func: Box::new(node1.into()), arguments: Arguments { - args: vec![target.clone(), node.into()], - keywords: vec![], + args: Box::from([target.clone(), node.into()]), + keywords: Box::from([]), range: TextRange::default(), }, range: TextRange::default(), @@ -480,13 +480,13 @@ fn match_eq_target(expr: &Expr) -> Option<(&str, &Expr)> { else { return None; }; - if ops != &[CmpOp::Eq] { + if **ops != [CmpOp::Eq] { return None; } let Expr::Name(ast::ExprName { id, .. }) = left.as_ref() else { return None; }; - let [comparator] = comparators.as_slice() else { + let [comparator] = &**comparators else { return None; }; if !comparator.is_name_expr() { @@ -551,8 +551,8 @@ pub(crate) fn compare_with_tuple(checker: &mut Checker, expr: &Expr) { }; let node2 = ast::ExprCompare { left: Box::new(node1.into()), - ops: vec![CmpOp::In], - comparators: vec![node.into()], + ops: Box::from([CmpOp::In]), + comparators: Box::from([node.into()]), range: TextRange::default(), }; let in_expr = node2.into(); diff --git a/crates/ruff_linter/src/rules/flake8_simplify/rules/ast_ifexp.rs b/crates/ruff_linter/src/rules/flake8_simplify/rules/ast_ifexp.rs index 764253fee05f1..50a3558fed252 100644 --- a/crates/ruff_linter/src/rules/flake8_simplify/rules/ast_ifexp.rs +++ b/crates/ruff_linter/src/rules/flake8_simplify/rules/ast_ifexp.rs @@ -185,8 +185,8 @@ pub(crate) fn if_expr_with_true_false( .into(), ), arguments: Arguments { - args: vec![test.clone()], - keywords: vec![], + args: Box::from([test.clone()]), + keywords: Box::from([]), range: TextRange::default(), }, range: TextRange::default(), diff --git a/crates/ruff_linter/src/rules/flake8_simplify/rules/ast_unary_op.rs b/crates/ruff_linter/src/rules/flake8_simplify/rules/ast_unary_op.rs index 8cc58ebda1a78..ee476f9d350a0 100644 --- a/crates/ruff_linter/src/rules/flake8_simplify/rules/ast_unary_op.rs +++ b/crates/ruff_linter/src/rules/flake8_simplify/rules/ast_unary_op.rs @@ -176,7 +176,7 @@ pub(crate) fn negation_with_equal_op( ); let node = ast::ExprCompare { left: left.clone(), - ops: vec![CmpOp::NotEq], + ops: Box::from([CmpOp::NotEq]), comparators: comparators.clone(), range: TextRange::default(), }; @@ -206,7 +206,7 @@ pub(crate) fn negation_with_not_equal_op( else { return; }; - if !matches!(&ops[..], [CmpOp::NotEq]) { + if !matches!(&**ops, [CmpOp::NotEq]) { return; } if is_exception_check(checker.semantic().current_statement()) { @@ -231,7 +231,7 @@ pub(crate) fn negation_with_not_equal_op( ); let node = ast::ExprCompare { left: left.clone(), - ops: vec![CmpOp::Eq], + ops: Box::from([CmpOp::Eq]), comparators: comparators.clone(), range: TextRange::default(), }; @@ -279,8 +279,8 @@ pub(crate) fn double_negation(checker: &mut Checker, expr: &Expr, op: UnaryOp, o let node1 = ast::ExprCall { func: Box::new(node.into()), arguments: Arguments { - args: vec![*operand.clone()], - keywords: vec![], + args: Box::from([*operand.clone()]), + keywords: Box::from([]), range: TextRange::default(), }, range: TextRange::default(), diff --git a/crates/ruff_linter/src/rules/flake8_simplify/rules/collapsible_if.rs b/crates/ruff_linter/src/rules/flake8_simplify/rules/collapsible_if.rs index f382996cbe2b8..8fb4f17fae23b 100644 --- a/crates/ruff_linter/src/rules/flake8_simplify/rules/collapsible_if.rs +++ b/crates/ruff_linter/src/rules/flake8_simplify/rules/collapsible_if.rs @@ -253,8 +253,7 @@ fn is_main_check(expr: &Expr) -> bool { { if let Expr::Name(ast::ExprName { id, .. }) = left.as_ref() { if id == "__name__" { - if let [Expr::StringLiteral(ast::ExprStringLiteral { value, .. })] = - comparators.as_slice() + if let [Expr::StringLiteral(ast::ExprStringLiteral { value, .. })] = &**comparators { if value == "__main__" { return true; diff --git a/crates/ruff_linter/src/rules/flake8_simplify/rules/if_else_block_instead_of_dict_get.rs b/crates/ruff_linter/src/rules/flake8_simplify/rules/if_else_block_instead_of_dict_get.rs index 1c710427fe077..04bc68cd20bce 100644 --- a/crates/ruff_linter/src/rules/flake8_simplify/rules/if_else_block_instead_of_dict_get.rs +++ b/crates/ruff_linter/src/rules/flake8_simplify/rules/if_else_block_instead_of_dict_get.rs @@ -122,7 +122,7 @@ pub(crate) fn if_else_block_instead_of_dict_get(checker: &mut Checker, stmt_if: else { return; }; - let [test_dict] = test_dict.as_slice() else { + let [test_dict] = &**test_dict else { return; }; let (expected_var, expected_value, default_var, default_value) = match ops[..] { @@ -176,8 +176,8 @@ pub(crate) fn if_else_block_instead_of_dict_get(checker: &mut Checker, stmt_if: let node3 = ast::ExprCall { func: Box::new(node2.into()), arguments: Arguments { - args: vec![node1, node], - keywords: vec![], + args: Box::from([node1, node]), + keywords: Box::from([]), range: TextRange::default(), }, range: TextRange::default(), @@ -233,11 +233,11 @@ pub(crate) fn if_exp_instead_of_dict_get( else { return; }; - let [test_dict] = test_dict.as_slice() else { + let [test_dict] = &**test_dict else { return; }; - let (body, default_value) = match ops.as_slice() { + let (body, default_value) = match &**ops { [CmpOp::In] => (body, orelse), [CmpOp::NotIn] => (orelse, body), _ => { @@ -276,8 +276,8 @@ pub(crate) fn if_exp_instead_of_dict_get( let fixed_node = ast::ExprCall { func: Box::new(dict_get_node.into()), arguments: Arguments { - args: vec![dict_key_node, default_value_node], - keywords: vec![], + args: Box::from([dict_key_node, default_value_node]), + keywords: Box::from([]), range: TextRange::default(), }, range: TextRange::default(), diff --git a/crates/ruff_linter/src/rules/flake8_simplify/rules/if_else_block_instead_of_dict_lookup.rs b/crates/ruff_linter/src/rules/flake8_simplify/rules/if_else_block_instead_of_dict_lookup.rs index f69c46639d707..cad99bf7cbb6b 100644 --- a/crates/ruff_linter/src/rules/flake8_simplify/rules/if_else_block_instead_of_dict_lookup.rs +++ b/crates/ruff_linter/src/rules/flake8_simplify/rules/if_else_block_instead_of_dict_lookup.rs @@ -64,10 +64,10 @@ pub(crate) fn if_else_block_instead_of_dict_lookup(checker: &mut Checker, stmt_i let Expr::Name(ast::ExprName { id: target, .. }) = left.as_ref() else { return; }; - if ops != &[CmpOp::Eq] { + if **ops != [CmpOp::Eq] { return; } - let [expr] = comparators.as_slice() else { + let [expr] = &**comparators else { return; }; let Some(literal_expr) = expr.as_literal_expr() else { @@ -127,10 +127,10 @@ pub(crate) fn if_else_block_instead_of_dict_lookup(checker: &mut Checker, stmt_i let Expr::Name(ast::ExprName { id, .. }) = left.as_ref() else { return; }; - if id != target || ops != &[CmpOp::Eq] { + if id != target || **ops != [CmpOp::Eq] { return; } - let [expr] = comparators.as_slice() else { + let [expr] = &**comparators else { return; }; let Some(literal_expr) = expr.as_literal_expr() else { diff --git a/crates/ruff_linter/src/rules/flake8_simplify/rules/key_in_dict.rs b/crates/ruff_linter/src/rules/flake8_simplify/rules/key_in_dict.rs index 2594722f34523..7ebcd9f9f30b5 100644 --- a/crates/ruff_linter/src/rules/flake8_simplify/rules/key_in_dict.rs +++ b/crates/ruff_linter/src/rules/flake8_simplify/rules/key_in_dict.rs @@ -194,7 +194,7 @@ pub(crate) fn key_in_dict_comprehension(checker: &mut Checker, comprehension: &C /// SIM118 in a comparison. pub(crate) fn key_in_dict_compare(checker: &mut Checker, compare: &ast::ExprCompare) { - let [op] = compare.ops.as_slice() else { + let [op] = &*compare.ops else { return; }; @@ -202,7 +202,7 @@ pub(crate) fn key_in_dict_compare(checker: &mut Checker, compare: &ast::ExprComp return; } - let [right] = compare.comparators.as_slice() else { + let [right] = &*compare.comparators else { return; }; diff --git a/crates/ruff_linter/src/rules/flake8_simplify/rules/needless_bool.rs b/crates/ruff_linter/src/rules/flake8_simplify/rules/needless_bool.rs index fc64997661751..656ed70059bd7 100644 --- a/crates/ruff_linter/src/rules/flake8_simplify/rules/needless_bool.rs +++ b/crates/ruff_linter/src/rules/flake8_simplify/rules/needless_bool.rs @@ -161,8 +161,8 @@ pub(crate) fn needless_bool(checker: &mut Checker, stmt_if: &ast::StmtIf) { let value_node = ast::ExprCall { func: Box::new(func_node.into()), arguments: Arguments { - args: vec![if_test.clone()], - keywords: vec![], + args: Box::from([if_test.clone()]), + keywords: Box::from([]), range: TextRange::default(), }, range: TextRange::default(), diff --git a/crates/ruff_linter/src/rules/flake8_simplify/rules/reimplemented_builtin.rs b/crates/ruff_linter/src/rules/flake8_simplify/rules/reimplemented_builtin.rs index 4362112ccfb71..09475ad8abd3b 100644 --- a/crates/ruff_linter/src/rules/flake8_simplify/rules/reimplemented_builtin.rs +++ b/crates/ruff_linter/src/rules/flake8_simplify/rules/reimplemented_builtin.rs @@ -140,7 +140,7 @@ pub(crate) fn convert_for_loop_to_any_all(checker: &mut Checker, stmt: &Stmt) { range: _, }) = &loop_.test { - if let ([op], [comparator]) = (ops.as_slice(), comparators.as_slice()) { + if let ([op], [comparator]) = (&**ops, &**comparators) { let op = match op { CmpOp::Eq => CmpOp::NotEq, CmpOp::NotEq => CmpOp::Eq, @@ -155,8 +155,8 @@ pub(crate) fn convert_for_loop_to_any_all(checker: &mut Checker, stmt: &Stmt) { }; let node = ast::ExprCompare { left: left.clone(), - ops: vec![op], - comparators: vec![comparator.clone()], + ops: Box::from([op]), + comparators: Box::from([comparator.clone()]), range: TextRange::default(), }; node.into() @@ -391,8 +391,8 @@ fn return_stmt(id: &str, test: &Expr, target: &Expr, iter: &Expr, generator: Gen let node2 = ast::ExprCall { func: Box::new(node1.into()), arguments: Arguments { - args: vec![node.into()], - keywords: vec![], + args: Box::from([node.into()]), + keywords: Box::from([]), range: TextRange::default(), }, range: TextRange::default(), diff --git a/crates/ruff_linter/src/rules/flake8_use_pathlib/rules/path_constructor_current_directory.rs b/crates/ruff_linter/src/rules/flake8_use_pathlib/rules/path_constructor_current_directory.rs index dc598dbb9f8ff..f5fbdb86817b0 100644 --- a/crates/ruff_linter/src/rules/flake8_use_pathlib/rules/path_constructor_current_directory.rs +++ b/crates/ruff_linter/src/rules/flake8_use_pathlib/rules/path_constructor_current_directory.rs @@ -1,7 +1,6 @@ -use ruff_python_ast::{self as ast, Arguments, Expr, ExprCall}; - use ruff_diagnostics::{AlwaysFixableViolation, Diagnostic, Edit, Fix}; use ruff_macros::{derive_message_formats, violation}; +use ruff_python_ast::{self as ast, Expr, ExprCall}; use crate::checkers::ast::Checker; @@ -53,19 +52,15 @@ pub(crate) fn path_constructor_current_directory(checker: &mut Checker, expr: &E return; } - let Expr::Call(ExprCall { - arguments: Arguments { args, keywords, .. }, - .. - }) = expr - else { + let Expr::Call(ExprCall { arguments, .. }) = expr else { return; }; - if !keywords.is_empty() { + if !arguments.keywords.is_empty() { return; } - let [Expr::StringLiteral(ast::ExprStringLiteral { value, range })] = args.as_slice() else { + let [Expr::StringLiteral(ast::ExprStringLiteral { value, range })] = &*arguments.args else { return; }; diff --git a/crates/ruff_linter/src/rules/flynt/rules/static_join_to_fstring.rs b/crates/ruff_linter/src/rules/flynt/rules/static_join_to_fstring.rs index bf0ca3d0565a1..67387373af495 100644 --- a/crates/ruff_linter/src/rules/flynt/rules/static_join_to_fstring.rs +++ b/crates/ruff_linter/src/rules/flynt/rules/static_join_to_fstring.rs @@ -116,7 +116,7 @@ pub(crate) fn static_join_to_fstring(checker: &mut Checker, expr: &Expr, joiner: if !keywords.is_empty() { return; } - let [arg] = args.as_slice() else { + let [arg] = &**args else { return; }; diff --git a/crates/ruff_linter/src/rules/perflint/rules/manual_list_comprehension.rs b/crates/ruff_linter/src/rules/perflint/rules/manual_list_comprehension.rs index b939f3671d3c3..5377003849640 100644 --- a/crates/ruff_linter/src/rules/perflint/rules/manual_list_comprehension.rs +++ b/crates/ruff_linter/src/rules/perflint/rules/manual_list_comprehension.rs @@ -109,7 +109,7 @@ pub(crate) fn manual_list_comprehension(checker: &mut Checker, target: &Expr, bo return; } - let [arg] = args.as_slice() else { + let [arg] = &**args else { return; }; diff --git a/crates/ruff_linter/src/rules/perflint/rules/manual_list_copy.rs b/crates/ruff_linter/src/rules/perflint/rules/manual_list_copy.rs index a1f0049588188..f3d1c25a07cfb 100644 --- a/crates/ruff_linter/src/rules/perflint/rules/manual_list_copy.rs +++ b/crates/ruff_linter/src/rules/perflint/rules/manual_list_copy.rs @@ -76,7 +76,7 @@ pub(crate) fn manual_list_copy(checker: &mut Checker, target: &Expr, body: &[Stm return; } - let [arg] = args.as_slice() else { + let [arg] = &**args else { return; }; diff --git a/crates/ruff_linter/src/rules/perflint/rules/unnecessary_list_cast.rs b/crates/ruff_linter/src/rules/perflint/rules/unnecessary_list_cast.rs index 4c73fd4800ecb..7ff1d544b392b 100644 --- a/crates/ruff_linter/src/rules/perflint/rules/unnecessary_list_cast.rs +++ b/crates/ruff_linter/src/rules/perflint/rules/unnecessary_list_cast.rs @@ -64,7 +64,7 @@ pub(crate) fn unnecessary_list_cast(checker: &mut Checker, iter: &Expr, body: &[ return; }; - let [arg] = args.as_slice() else { + let [arg] = &**args else { return; }; diff --git a/crates/ruff_linter/src/rules/pycodestyle/rules/literal_comparisons.rs b/crates/ruff_linter/src/rules/pycodestyle/rules/literal_comparisons.rs index 5abcbde90f896..b3841dd920d54 100644 --- a/crates/ruff_linter/src/rules/pycodestyle/rules/literal_comparisons.rs +++ b/crates/ruff_linter/src/rules/pycodestyle/rules/literal_comparisons.rs @@ -139,10 +139,10 @@ pub(crate) fn literal_comparisons(checker: &mut Checker, compare: &ast::ExprComp // Check `left`. let mut comparator = compare.left.as_ref(); - let [op, ..] = compare.ops.as_slice() else { + let [op, ..] = &*compare.ops else { return; }; - let [next, ..] = compare.comparators.as_slice() else { + let [next, ..] = &*compare.comparators else { return; }; diff --git a/crates/ruff_linter/src/rules/pycodestyle/rules/not_tests.rs b/crates/ruff_linter/src/rules/pycodestyle/rules/not_tests.rs index c870d2db25620..bcd0dc3a333f8 100644 --- a/crates/ruff_linter/src/rules/pycodestyle/rules/not_tests.rs +++ b/crates/ruff_linter/src/rules/pycodestyle/rules/not_tests.rs @@ -90,7 +90,7 @@ pub(crate) fn not_tests(checker: &mut Checker, unary_op: &ast::ExprUnaryOp) { return; }; - match ops.as_slice() { + match &**ops { [CmpOp::In] => { if checker.enabled(Rule::NotInTest) { let mut diagnostic = Diagnostic::new(NotInTest, unary_op.operand.range()); diff --git a/crates/ruff_linter/src/rules/pylint/rules/comparison_with_itself.rs b/crates/ruff_linter/src/rules/pylint/rules/comparison_with_itself.rs index 8aa58e70e8026..f93a884a9e5ce 100644 --- a/crates/ruff_linter/src/rules/pylint/rules/comparison_with_itself.rs +++ b/crates/ruff_linter/src/rules/pylint/rules/comparison_with_itself.rs @@ -84,10 +84,10 @@ pub(crate) fn comparison_with_itself( { continue; } - let [Expr::Name(left_arg)] = left_call.arguments.args.as_slice() else { + let [Expr::Name(left_arg)] = &*left_call.arguments.args else { continue; }; - let [Expr::Name(right_right)] = right_call.arguments.args.as_slice() else { + let [Expr::Name(right_right)] = &*right_call.arguments.args else { continue; }; if left_arg.id != right_right.id { diff --git a/crates/ruff_linter/src/rules/pylint/rules/duplicate_bases.rs b/crates/ruff_linter/src/rules/pylint/rules/duplicate_bases.rs index 85fdaa839022f..6a9863ccb1486 100644 --- a/crates/ruff_linter/src/rules/pylint/rules/duplicate_bases.rs +++ b/crates/ruff_linter/src/rules/pylint/rules/duplicate_bases.rs @@ -59,7 +59,7 @@ pub(crate) fn duplicate_bases(checker: &mut Checker, name: &str, arguments: Opti let mut seen: FxHashSet<&str> = FxHashSet::with_capacity_and_hasher(bases.len(), BuildHasherDefault::default()); - for base in bases { + for base in bases.iter() { if let Expr::Name(ast::ExprName { id, .. }) = base { if !seen.insert(id) { checker.diagnostics.push(Diagnostic::new( diff --git a/crates/ruff_linter/src/rules/pylint/rules/literal_membership.rs b/crates/ruff_linter/src/rules/pylint/rules/literal_membership.rs index 245de4e538c21..7441a228e80cd 100644 --- a/crates/ruff_linter/src/rules/pylint/rules/literal_membership.rs +++ b/crates/ruff_linter/src/rules/pylint/rules/literal_membership.rs @@ -45,7 +45,7 @@ impl AlwaysFixableViolation for LiteralMembership { /// PLR6201 pub(crate) fn literal_membership(checker: &mut Checker, compare: &ast::ExprCompare) { - let [op] = compare.ops.as_slice() else { + let [op] = &*compare.ops else { return; }; @@ -53,7 +53,7 @@ pub(crate) fn literal_membership(checker: &mut Checker, compare: &ast::ExprCompa return; } - let [right] = compare.comparators.as_slice() else { + let [right] = &*compare.comparators else { return; }; diff --git a/crates/ruff_linter/src/rules/pylint/rules/nested_min_max.rs b/crates/ruff_linter/src/rules/pylint/rules/nested_min_max.rs index 3911b55be2294..be336eadae5c9 100644 --- a/crates/ruff_linter/src/rules/pylint/rules/nested_min_max.rs +++ b/crates/ruff_linter/src/rules/pylint/rules/nested_min_max.rs @@ -106,7 +106,7 @@ fn collect_nested_args(min_max: MinMax, args: &[Expr], semantic: &SemanticModel) range: _, }) = arg { - if let [arg] = args.as_slice() { + if let [arg] = &**args { if arg.as_starred_expr().is_none() { let new_arg = Expr::Starred(ast::ExprStarred { value: Box::new(arg.clone()), @@ -164,8 +164,8 @@ pub(crate) fn nested_min_max( let flattened_expr = Expr::Call(ast::ExprCall { func: Box::new(func.clone()), arguments: Arguments { - args: collect_nested_args(min_max, args, checker.semantic()), - keywords: keywords.to_owned(), + args: collect_nested_args(min_max, args, checker.semantic()).into_boxed_slice(), + keywords: Box::from(keywords), range: TextRange::default(), }, range: TextRange::default(), diff --git a/crates/ruff_linter/src/rules/pylint/rules/repeated_equality_comparison.rs b/crates/ruff_linter/src/rules/pylint/rules/repeated_equality_comparison.rs index d3077539c8a34..b4c5a792256d0 100644 --- a/crates/ruff_linter/src/rules/pylint/rules/repeated_equality_comparison.rs +++ b/crates/ruff_linter/src/rules/pylint/rules/repeated_equality_comparison.rs @@ -96,7 +96,7 @@ pub(crate) fn repeated_equality_comparison(checker: &mut Checker, bool_op: &ast: }; // Enforced via `is_allowed_value`. - let [right] = comparators.as_slice() else { + let [right] = &**comparators else { return; }; @@ -136,14 +136,14 @@ pub(crate) fn repeated_equality_comparison(checker: &mut Checker, bool_op: &ast: checker.generator().expr(&Expr::Compare(ast::ExprCompare { left: Box::new(value.as_expr().clone()), ops: match bool_op.op { - BoolOp::Or => vec![CmpOp::In], - BoolOp::And => vec![CmpOp::NotIn], + BoolOp::Or => Box::from([CmpOp::In]), + BoolOp::And => Box::from([CmpOp::NotIn]), }, - comparators: vec![Expr::Tuple(ast::ExprTuple { + comparators: Box::from([Expr::Tuple(ast::ExprTuple { elts: comparators.iter().copied().cloned().collect(), range: TextRange::default(), ctx: ExprContext::Load, - })], + })]), range: bool_op.range(), })), bool_op.range(), @@ -169,7 +169,7 @@ fn is_allowed_value(bool_op: BoolOp, value: &Expr) -> bool { }; // Ignore, e.g., `foo == bar == baz`. - let [op] = ops.as_slice() else { + let [op] = &**ops else { return false; }; @@ -181,7 +181,7 @@ fn is_allowed_value(bool_op: BoolOp, value: &Expr) -> bool { } // Ignore self-comparisons, e.g., `foo == foo`. - let [right] = comparators.as_slice() else { + let [right] = &**comparators else { return false; }; if ComparableExpr::from(left) == ComparableExpr::from(right) { diff --git a/crates/ruff_linter/src/rules/pylint/rules/repeated_keyword_argument.rs b/crates/ruff_linter/src/rules/pylint/rules/repeated_keyword_argument.rs index b65f8fd6b4ac9..53099c879d782 100644 --- a/crates/ruff_linter/src/rules/pylint/rules/repeated_keyword_argument.rs +++ b/crates/ruff_linter/src/rules/pylint/rules/repeated_keyword_argument.rs @@ -1,10 +1,11 @@ use std::hash::BuildHasherDefault; +use rustc_hash::FxHashSet; + use ruff_diagnostics::{Diagnostic, Violation}; use ruff_macros::{derive_message_formats, violation}; -use ruff_python_ast::{Arguments, Expr, ExprCall, ExprDict, ExprStringLiteral}; +use ruff_python_ast::{Expr, ExprCall, ExprDict, ExprStringLiteral}; use ruff_text_size::Ranged; -use rustc_hash::FxHashSet; use crate::checkers::ast::Checker; @@ -37,15 +38,14 @@ impl Violation for RepeatedKeywordArgument { } pub(crate) fn repeated_keyword_argument(checker: &mut Checker, call: &ExprCall) { - let ExprCall { - arguments: Arguments { keywords, .. }, - .. - } = call; + let ExprCall { arguments, .. } = call; - let mut seen = - FxHashSet::with_capacity_and_hasher(keywords.len(), BuildHasherDefault::default()); + let mut seen = FxHashSet::with_capacity_and_hasher( + arguments.keywords.len(), + BuildHasherDefault::default(), + ); - for keyword in keywords { + for keyword in arguments.keywords.iter() { if let Some(id) = &keyword.arg { // Ex) `func(a=1, a=2)` if !seen.insert(id.as_str()) { diff --git a/crates/ruff_linter/src/rules/pylint/rules/unnecessary_dunder_call.rs b/crates/ruff_linter/src/rules/pylint/rules/unnecessary_dunder_call.rs index 6e2257d45e086..c1e10eef8cbe2 100644 --- a/crates/ruff_linter/src/rules/pylint/rules/unnecessary_dunder_call.rs +++ b/crates/ruff_linter/src/rules/pylint/rules/unnecessary_dunder_call.rs @@ -111,7 +111,7 @@ pub(crate) fn unnecessary_dunder_call(checker: &mut Checker, call: &ast::ExprCal let mut title: Option = None; if let Some(dunder) = DunderReplacement::from_method(attr) { - match (call.arguments.args.as_slice(), dunder) { + match (&*call.arguments.args, dunder) { ([], DunderReplacement::Builtin(replacement, message)) => { if !checker.semantic().is_builtin(replacement) { return; diff --git a/crates/ruff_linter/src/rules/pyupgrade/rules/convert_named_tuple_functional_to_class.rs b/crates/ruff_linter/src/rules/pyupgrade/rules/convert_named_tuple_functional_to_class.rs index dcc6a01ab64c8..20d29a698f891 100644 --- a/crates/ruff_linter/src/rules/pyupgrade/rules/convert_named_tuple_functional_to_class.rs +++ b/crates/ruff_linter/src/rules/pyupgrade/rules/convert_named_tuple_functional_to_class.rs @@ -216,8 +216,8 @@ fn create_class_def_stmt(typename: &str, body: Vec, base_class: &Expr) -> ast::StmtClassDef { name: Identifier::new(typename.to_string(), TextRange::default()), arguments: Some(Box::new(Arguments { - args: vec![base_class.clone()], - keywords: vec![], + args: Box::from([base_class.clone()]), + keywords: Box::from([]), range: TextRange::default(), })), body, diff --git a/crates/ruff_linter/src/rules/pyupgrade/rules/convert_typed_dict_functional_to_class.rs b/crates/ruff_linter/src/rules/pyupgrade/rules/convert_typed_dict_functional_to_class.rs index 4f98f6e5fa365..baf1b4c140228 100644 --- a/crates/ruff_linter/src/rules/pyupgrade/rules/convert_typed_dict_functional_to_class.rs +++ b/crates/ruff_linter/src/rules/pyupgrade/rules/convert_typed_dict_functional_to_class.rs @@ -148,10 +148,10 @@ fn create_class_def_stmt( ast::StmtClassDef { name: Identifier::new(class_name.to_string(), TextRange::default()), arguments: Some(Box::new(Arguments { - args: vec![base_class.clone()], + args: Box::from([base_class.clone()]), keywords: match total_keyword { - Some(keyword) => vec![keyword.clone()], - None => vec![], + Some(keyword) => Box::from([keyword.clone()]), + None => Box::from([]), }, range: TextRange::default(), })), @@ -226,7 +226,7 @@ fn fields_from_keywords(keywords: &[Keyword]) -> Option> { /// Match the fields and `total` keyword from a `TypedDict` call. fn match_fields_and_total(arguments: &Arguments) -> Option<(Vec, Option<&Keyword>)> { - match (arguments.args.as_slice(), arguments.keywords.as_slice()) { + match (&*arguments.args, &*arguments.keywords) { // Ex) `TypedDict("MyType", {"a": int, "b": str})` ([_typename, fields], [..]) => { let total = arguments.find_keyword("total"); diff --git a/crates/ruff_linter/src/rules/pyupgrade/rules/f_strings.rs b/crates/ruff_linter/src/rules/pyupgrade/rules/f_strings.rs index 2300c4b353eb2..8a3f633114dd8 100644 --- a/crates/ruff_linter/src/rules/pyupgrade/rules/f_strings.rs +++ b/crates/ruff_linter/src/rules/pyupgrade/rules/f_strings.rs @@ -71,7 +71,7 @@ impl<'a> FormatSummaryValues<'a> { let mut extracted_args: Vec<&Expr> = Vec::new(); let mut extracted_kwargs: FxHashMap<&str, &Expr> = FxHashMap::default(); - for arg in &call.arguments.args { + for arg in call.arguments.args.iter() { if matches!(arg, Expr::Starred(..)) || contains_quotes(locator.slice(arg)) || locator.contains_line_break(arg.range()) @@ -80,7 +80,7 @@ impl<'a> FormatSummaryValues<'a> { } extracted_args.push(arg); } - for keyword in &call.arguments.keywords { + for keyword in call.arguments.keywords.iter() { let Keyword { arg, value, diff --git a/crates/ruff_linter/src/rules/pyupgrade/rules/outdated_version_block.rs b/crates/ruff_linter/src/rules/pyupgrade/rules/outdated_version_block.rs index 97347e9027f78..af49f8a202c57 100644 --- a/crates/ruff_linter/src/rules/pyupgrade/rules/outdated_version_block.rs +++ b/crates/ruff_linter/src/rules/pyupgrade/rules/outdated_version_block.rs @@ -90,7 +90,7 @@ pub(crate) fn outdated_version_block(checker: &mut Checker, stmt_if: &StmtIf) { continue; }; - let ([op], [comparison]) = (ops.as_slice(), comparators.as_slice()) else { + let ([op], [comparison]) = (&**ops, &**comparators) else { continue; }; diff --git a/crates/ruff_linter/src/rules/pyupgrade/rules/super_call_with_parameters.rs b/crates/ruff_linter/src/rules/pyupgrade/rules/super_call_with_parameters.rs index c8af446f4adcf..a01934676b899 100644 --- a/crates/ruff_linter/src/rules/pyupgrade/rules/super_call_with_parameters.rs +++ b/crates/ruff_linter/src/rules/pyupgrade/rules/super_call_with_parameters.rs @@ -76,7 +76,7 @@ pub(crate) fn super_call_with_parameters(checker: &mut Checker, call: &ast::Expr // For a `super` invocation to be unnecessary, the first argument needs to match // the enclosing class, and the second argument needs to match the first // argument to the enclosing function. - let [first_arg, second_arg] = call.arguments.args.as_slice() else { + let [first_arg, second_arg] = &*call.arguments.args else { return; }; diff --git a/crates/ruff_linter/src/rules/pyupgrade/rules/unnecessary_encode_utf8.rs b/crates/ruff_linter/src/rules/pyupgrade/rules/unnecessary_encode_utf8.rs index 4bb5dd82fb041..db894ed688df3 100644 --- a/crates/ruff_linter/src/rules/pyupgrade/rules/unnecessary_encode_utf8.rs +++ b/crates/ruff_linter/src/rules/pyupgrade/rules/unnecessary_encode_utf8.rs @@ -93,7 +93,7 @@ enum EncodingArg<'a> { /// Return the encoding argument to an `encode` call, if it can be determined to be a /// UTF-8-equivalent encoding. fn match_encoding_arg(arguments: &Arguments) -> Option { - match (arguments.args.as_slice(), arguments.keywords.as_slice()) { + match (&*arguments.args, &*arguments.keywords) { // Ex `"".encode()` ([], []) => return Some(EncodingArg::Empty), // Ex `"".encode(encoding)` diff --git a/crates/ruff_linter/src/rules/pyupgrade/rules/useless_object_inheritance.rs b/crates/ruff_linter/src/rules/pyupgrade/rules/useless_object_inheritance.rs index 83f9a417e8c6c..470cdd911ed86 100644 --- a/crates/ruff_linter/src/rules/pyupgrade/rules/useless_object_inheritance.rs +++ b/crates/ruff_linter/src/rules/pyupgrade/rules/useless_object_inheritance.rs @@ -50,7 +50,7 @@ pub(crate) fn useless_object_inheritance(checker: &mut Checker, class_def: &ast: return; }; - for base in &arguments.args { + for base in arguments.args.iter() { let Expr::Name(ast::ExprName { id, .. }) = base else { continue; }; diff --git a/crates/ruff_linter/src/rules/refurb/helpers.rs b/crates/ruff_linter/src/rules/refurb/helpers.rs index 031a58c62a437..d429dd2d5d5b4 100644 --- a/crates/ruff_linter/src/rules/refurb/helpers.rs +++ b/crates/ruff_linter/src/rules/refurb/helpers.rs @@ -21,8 +21,8 @@ pub(super) fn generate_method_call(name: &str, method: &str, generator: Generato let call = ast::ExprCall { func: Box::new(attr.into()), arguments: ast::Arguments { - args: vec![], - keywords: vec![], + args: Box::from([]), + keywords: Box::from([]), range: TextRange::default(), }, range: TextRange::default(), @@ -55,8 +55,8 @@ pub(super) fn generate_none_identity_comparison( }; let compare = ast::ExprCompare { left: Box::new(var.into()), - ops: vec![op], - comparators: vec![ast::Expr::NoneLiteral(ast::ExprNoneLiteral::default())], + ops: Box::from([op]), + comparators: Box::from([ast::Expr::NoneLiteral(ast::ExprNoneLiteral::default())]), range: TextRange::default(), }; generator.expr(&compare.into()) diff --git a/crates/ruff_linter/src/rules/refurb/rules/bit_count.rs b/crates/ruff_linter/src/rules/refurb/rules/bit_count.rs index 6a1bbf3dddd9e..54405ff1730aa 100644 --- a/crates/ruff_linter/src/rules/refurb/rules/bit_count.rs +++ b/crates/ruff_linter/src/rules/refurb/rules/bit_count.rs @@ -74,7 +74,7 @@ pub(crate) fn bit_count(checker: &mut Checker, call: &ExprCall) { if !call.arguments.keywords.is_empty() { return; }; - let [arg] = call.arguments.args.as_slice() else { + let [arg] = &*call.arguments.args else { return; }; @@ -109,7 +109,7 @@ pub(crate) fn bit_count(checker: &mut Checker, call: &ExprCall) { if !arguments.keywords.is_empty() { return; }; - let [arg] = arguments.args.as_slice() else { + let [arg] = &*arguments.args else { return; }; diff --git a/crates/ruff_linter/src/rules/refurb/rules/check_and_remove_from_set.rs b/crates/ruff_linter/src/rules/refurb/rules/check_and_remove_from_set.rs index 93d1ac8357082..0c2f21125672c 100644 --- a/crates/ruff_linter/src/rules/refurb/rules/check_and_remove_from_set.rs +++ b/crates/ruff_linter/src/rules/refurb/rules/check_and_remove_from_set.rs @@ -132,11 +132,11 @@ fn match_check(if_stmt: &ast::StmtIf) -> Option<(&Expr, &ast::ExprName)> { .. } = if_stmt.test.as_compare_expr()?; - if ops.as_slice() != [CmpOp::In] { + if **ops != [CmpOp::In] { return None; } - let [Expr::Name(right @ ast::ExprName { .. })] = comparators.as_slice() else { + let [Expr::Name(right @ ast::ExprName { .. })] = &**comparators else { return None; }; @@ -165,7 +165,7 @@ fn match_remove(if_stmt: &ast::StmtIf) -> Option<(&Expr, &ast::ExprName)> { return None; }; - let [arg] = args.as_slice() else { + let [arg] = &**args else { return None; }; @@ -191,8 +191,8 @@ fn make_suggestion(set: &ast::ExprName, element: &Expr, generator: Generator) -> let call = ast::ExprCall { func: Box::new(attr.into()), arguments: ast::Arguments { - args: vec![element.clone()], - keywords: vec![], + args: Box::from([element.clone()]), + keywords: Box::from([]), range: TextRange::default(), }, range: TextRange::default(), diff --git a/crates/ruff_linter/src/rules/refurb/rules/if_expr_min_max.rs b/crates/ruff_linter/src/rules/refurb/rules/if_expr_min_max.rs index 05092785bdd9d..8cf5be9182e4a 100644 --- a/crates/ruff_linter/src/rules/refurb/rules/if_expr_min_max.rs +++ b/crates/ruff_linter/src/rules/refurb/rules/if_expr_min_max.rs @@ -88,7 +88,7 @@ pub(crate) fn if_expr_min_max(checker: &mut Checker, if_exp: &ast::ExprIfExp) { }; // Ignore, e.g., `foo < bar < baz`. - let [op] = ops.as_slice() else { + let [op] = &**ops else { return; }; @@ -102,7 +102,7 @@ pub(crate) fn if_expr_min_max(checker: &mut Checker, if_exp: &ast::ExprIfExp) { _ => return, }; - let [right] = comparators.as_slice() else { + let [right] = &**comparators else { return; }; diff --git a/crates/ruff_linter/src/rules/refurb/rules/implicit_cwd.rs b/crates/ruff_linter/src/rules/refurb/rules/implicit_cwd.rs index 8b24c361ab200..a9fb853ba645e 100644 --- a/crates/ruff_linter/src/rules/refurb/rules/implicit_cwd.rs +++ b/crates/ruff_linter/src/rules/refurb/rules/implicit_cwd.rs @@ -58,7 +58,7 @@ pub(crate) fn no_implicit_cwd(checker: &mut Checker, call: &ExprCall) { // Match on arguments, but ignore keyword arguments. `Path()` accepts keyword arguments, but // ignores them. See: https://github.com/python/cpython/issues/98094. - match arguments.args.as_slice() { + match &*arguments.args { // Ex) `Path().resolve()` [] => {} // Ex) `Path(".").resolve()` diff --git a/crates/ruff_linter/src/rules/refurb/rules/print_empty_string.rs b/crates/ruff_linter/src/rules/refurb/rules/print_empty_string.rs index ee6da013b5048..4789bf57a9361 100644 --- a/crates/ruff_linter/src/rules/refurb/rules/print_empty_string.rs +++ b/crates/ruff_linter/src/rules/refurb/rules/print_empty_string.rs @@ -79,7 +79,7 @@ pub(crate) fn print_empty_string(checker: &mut Checker, call: &ast::ExprCall) { return; } - match &call.arguments.args.as_slice() { + match &*call.arguments.args { // Ex) `print("")` or `print("", sep="\t")` [arg] if is_empty_string(arg) => { let reason = if call.arguments.find_keyword("sep").is_some() { @@ -211,16 +211,30 @@ fn generate_suggestion(call: &ast::ExprCall, separator: Separator, generator: Ge let mut call = call.clone(); // Remove all empty string positional arguments. - call.arguments.args.retain(|arg| !is_empty_string(arg)); + call.arguments.args = call + .arguments + .args + .iter() + .filter(|arg| !is_empty_string(arg)) + .cloned() + .collect::>() + .into_boxed_slice(); // Remove the `sep` keyword argument if it exists. if separator == Separator::Remove { - call.arguments.keywords.retain(|keyword| { - keyword - .arg - .as_ref() - .map_or(true, |arg| arg.as_str() != "sep") - }); + call.arguments.keywords = call + .arguments + .keywords + .iter() + .filter(|keyword| { + keyword + .arg + .as_ref() + .map_or(true, |arg| arg.as_str() != "sep") + }) + .cloned() + .collect::>() + .into_boxed_slice(); } generator.expr(&call.into()) diff --git a/crates/ruff_linter/src/rules/refurb/rules/read_whole_file.rs b/crates/ruff_linter/src/rules/refurb/rules/read_whole_file.rs index 8bf1e6b6bccfb..518d701c79038 100644 --- a/crates/ruff_linter/src/rules/refurb/rules/read_whole_file.rs +++ b/crates/ruff_linter/src/rules/refurb/rules/read_whole_file.rs @@ -322,7 +322,7 @@ fn make_suggestion(open: &FileOpen<'_>, generator: Generator) -> SourceCodeSnipp let call = ast::ExprCall { func: Box::new(name.into()), arguments: ast::Arguments { - args: vec![], + args: Box::from([]), keywords: open.keywords.iter().copied().cloned().collect(), range: TextRange::default(), }, diff --git a/crates/ruff_linter/src/rules/refurb/rules/redundant_log_base.rs b/crates/ruff_linter/src/rules/refurb/rules/redundant_log_base.rs index c7d6837d75699..3768bfc1301c5 100644 --- a/crates/ruff_linter/src/rules/refurb/rules/redundant_log_base.rs +++ b/crates/ruff_linter/src/rules/refurb/rules/redundant_log_base.rs @@ -70,7 +70,7 @@ pub(crate) fn redundant_log_base(checker: &mut Checker, call: &ast::ExprCall) { return; } - let [arg, base] = &call.arguments.args.as_slice() else { + let [arg, base] = &*call.arguments.args else { return; }; diff --git a/crates/ruff_linter/src/rules/refurb/rules/reimplemented_operator.rs b/crates/ruff_linter/src/rules/refurb/rules/reimplemented_operator.rs index 4fe969121fd0c..7f5f0ea75973f 100644 --- a/crates/ruff_linter/src/rules/refurb/rules/reimplemented_operator.rs +++ b/crates/ruff_linter/src/rules/refurb/rules/reimplemented_operator.rs @@ -232,10 +232,10 @@ fn cmp_op(expr: &ast::ExprCompare, params: &ast::Parameters) -> Option<&'static let [arg1, arg2] = params.args.as_slice() else { return None; }; - let [op] = expr.ops.as_slice() else { + let [op] = &*expr.ops else { return None; }; - let [right] = expr.comparators.as_slice() else { + let [right] = &*expr.comparators else { return None; }; diff --git a/crates/ruff_linter/src/rules/refurb/rules/reimplemented_starmap.rs b/crates/ruff_linter/src/rules/refurb/rules/reimplemented_starmap.rs index 8f380a187b952..143518339cfc7 100644 --- a/crates/ruff_linter/src/rules/refurb/rules/reimplemented_starmap.rs +++ b/crates/ruff_linter/src/rules/refurb/rules/reimplemented_starmap.rs @@ -304,8 +304,8 @@ fn construct_starmap_call(starmap_binding: String, iter: &Expr, func: &Expr) -> ast::ExprCall { func: Box::new(starmap.into()), arguments: ast::Arguments { - args: vec![func.clone(), iter.clone()], - keywords: vec![], + args: Box::from([func.clone(), iter.clone()]), + keywords: Box::from([]), range: TextRange::default(), }, range: TextRange::default(), @@ -322,8 +322,8 @@ fn wrap_with_call_to(call: ast::ExprCall, func_name: &str) -> ast::ExprCall { ast::ExprCall { func: Box::new(name.into()), arguments: ast::Arguments { - args: vec![call.into()], - keywords: vec![], + args: Box::from([call.into()]), + keywords: Box::from([]), range: TextRange::default(), }, range: TextRange::default(), diff --git a/crates/ruff_linter/src/rules/refurb/rules/repeated_append.rs b/crates/ruff_linter/src/rules/refurb/rules/repeated_append.rs index ba6db71e4a07f..d1fc37a7239fe 100644 --- a/crates/ruff_linter/src/rules/refurb/rules/repeated_append.rs +++ b/crates/ruff_linter/src/rules/refurb/rules/repeated_append.rs @@ -280,7 +280,7 @@ fn match_append<'a>(semantic: &'a SemanticModel, stmt: &'a Stmt) -> Option String { let call = ast::ExprCall { func: Box::new(attr.into()), arguments: ast::Arguments { - args: vec![tuple.into()], - keywords: vec![], + args: Box::from([tuple.into()]), + keywords: Box::from([]), range: TextRange::default(), }, range: TextRange::default(), diff --git a/crates/ruff_linter/src/rules/refurb/rules/type_none_comparison.rs b/crates/ruff_linter/src/rules/refurb/rules/type_none_comparison.rs index da1f3695a742b..d7617c8a56d5c 100644 --- a/crates/ruff_linter/src/rules/refurb/rules/type_none_comparison.rs +++ b/crates/ruff_linter/src/rules/refurb/rules/type_none_comparison.rs @@ -59,7 +59,7 @@ impl Violation for TypeNoneComparison { /// FURB169 pub(crate) fn type_none_comparison(checker: &mut Checker, compare: &ast::ExprCompare) { - let ([op], [right]) = (compare.ops.as_slice(), compare.comparators.as_slice()) else { + let ([op], [right]) = (&*compare.ops, &*compare.comparators) else { return; }; diff --git a/crates/ruff_linter/src/rules/refurb/rules/unnecessary_enumerate.rs b/crates/ruff_linter/src/rules/refurb/rules/unnecessary_enumerate.rs index 5d693dfc43894..15eb34b7c851f 100644 --- a/crates/ruff_linter/src/rules/refurb/rules/unnecessary_enumerate.rs +++ b/crates/ruff_linter/src/rules/refurb/rules/unnecessary_enumerate.rs @@ -251,8 +251,8 @@ fn generate_range_len_call(name: &str, generator: Generator) -> String { .into(), ), arguments: Arguments { - args: vec![var.into()], - keywords: vec![], + args: Box::from([var.into()]), + keywords: Box::from([]), range: TextRange::default(), }, range: TextRange::default(), @@ -268,8 +268,8 @@ fn generate_range_len_call(name: &str, generator: Generator) -> String { .into(), ), arguments: Arguments { - args: vec![len.into()], - keywords: vec![], + args: Box::from([len.into()]), + keywords: Box::from([]), range: TextRange::default(), }, range: TextRange::default(), diff --git a/crates/ruff_linter/src/rules/ruff/rules/explicit_f_string_type_conversion.rs b/crates/ruff_linter/src/rules/ruff/rules/explicit_f_string_type_conversion.rs index 7fe11923d2222..78213d76b2e67 100644 --- a/crates/ruff_linter/src/rules/ruff/rules/explicit_f_string_type_conversion.rs +++ b/crates/ruff_linter/src/rules/ruff/rules/explicit_f_string_type_conversion.rs @@ -88,7 +88,7 @@ pub(crate) fn explicit_f_string_type_conversion(checker: &mut Checker, f_string: } // Can't be a conversion otherwise. - let [arg] = args.as_slice() else { + let [arg] = &**args else { continue; }; diff --git a/crates/ruff_linter/src/rules/ruff/rules/missing_fstring_syntax.rs b/crates/ruff_linter/src/rules/ruff/rules/missing_fstring_syntax.rs index 4863bbe827bd4..7cfc2e7bf01b3 100644 --- a/crates/ruff_linter/src/rules/ruff/rules/missing_fstring_syntax.rs +++ b/crates/ruff_linter/src/rules/ruff/rules/missing_fstring_syntax.rs @@ -123,12 +123,12 @@ fn should_be_fstring( _ => {} } } - for keyword in keywords { + for keyword in keywords.iter() { if let Some(ident) = keyword.arg.as_ref() { arg_names.insert(ident.as_str()); } } - for arg in args { + for arg in args.iter() { if let ast::Expr::Name(ast::ExprName { id, .. }) = arg { arg_names.insert(id.as_str()); } diff --git a/crates/ruff_linter/src/rules/ruff/rules/mutable_fromkeys_value.rs b/crates/ruff_linter/src/rules/ruff/rules/mutable_fromkeys_value.rs index aecca48562480..6cac3d994e429 100644 --- a/crates/ruff_linter/src/rules/ruff/rules/mutable_fromkeys_value.rs +++ b/crates/ruff_linter/src/rules/ruff/rules/mutable_fromkeys_value.rs @@ -84,7 +84,7 @@ pub(crate) fn mutable_fromkeys_value(checker: &mut Checker, call: &ast::ExprCall } // Check that the value parameter is a mutable object. - let [keys, value] = call.arguments.args.as_slice() else { + let [keys, value] = &*call.arguments.args else { return; }; if !is_mutable_expr(value, checker.semantic()) { diff --git a/crates/ruff_linter/src/rules/ruff/rules/sort_dunder_all.rs b/crates/ruff_linter/src/rules/ruff/rules/sort_dunder_all.rs index 341bff19c5bdf..6df5646f6b002 100644 --- a/crates/ruff_linter/src/rules/ruff/rules/sort_dunder_all.rs +++ b/crates/ruff_linter/src/rules/ruff/rules/sort_dunder_all.rs @@ -107,7 +107,7 @@ pub(crate) fn sort_dunder_all_extend_call( .. }: &ast::ExprCall, ) { - let ([value_passed], []) = (args.as_slice(), keywords.as_slice()) else { + let ([value_passed], []) = (&**args, &**keywords) else { return; }; let ast::Expr::Attribute(ast::ExprAttribute { diff --git a/crates/ruff_linter/src/rules/ruff/rules/unnecessary_dict_comprehension_for_iterable.rs b/crates/ruff_linter/src/rules/ruff/rules/unnecessary_dict_comprehension_for_iterable.rs index 6adc4f69038c9..4336dbed308b3 100644 --- a/crates/ruff_linter/src/rules/ruff/rules/unnecessary_dict_comprehension_for_iterable.rs +++ b/crates/ruff_linter/src/rules/ruff/rules/unnecessary_dict_comprehension_for_iterable.rs @@ -160,11 +160,11 @@ fn fix_unnecessary_dict_comprehension(value: &Expr, generator: &Comprehension) - let iterable = generator.iter.clone(); let args = Arguments { args: if value.is_none_literal_expr() { - vec![iterable] + Box::from([iterable]) } else { - vec![iterable, value.clone()] + Box::from([iterable, value.clone()]) }, - keywords: vec![], + keywords: Box::from([]), range: TextRange::default(), }; Expr::Call(ExprCall { diff --git a/crates/ruff_linter/src/rules/ruff/rules/unnecessary_iterable_allocation_for_first_element.rs b/crates/ruff_linter/src/rules/ruff/rules/unnecessary_iterable_allocation_for_first_element.rs index ac5f37e04cdfb..9cac96d080794 100644 --- a/crates/ruff_linter/src/rules/ruff/rules/unnecessary_iterable_allocation_for_first_element.rs +++ b/crates/ruff_linter/src/rules/ruff/rules/unnecessary_iterable_allocation_for_first_element.rs @@ -146,7 +146,7 @@ fn match_iteration_target(expr: &Expr, semantic: &SemanticModel) -> Option { // Allow `tuple()`, `list()`, and their generic forms, like `list[int]()`. - if keywords.is_empty() && args.len() <= 1 { + if arguments.keywords.is_empty() && arguments.args.len() <= 1 { if let Expr::Name(ast::ExprName { id, .. }) = map_subscript(func) { let id = id.as_str(); if matches!(id, "tuple" | "list") && is_builtin(id) { - let [arg] = args.as_slice() else { + let [arg] = arguments.args.as_ref() else { return (None, DunderAllFlags::empty()); }; match arg { diff --git a/crates/ruff_python_ast/src/helpers.rs b/crates/ruff_python_ast/src/helpers.rs index 45e480372ee2d..579a29ffbc7dd 100644 --- a/crates/ruff_python_ast/src/helpers.rs +++ b/crates/ruff_python_ast/src/helpers.rs @@ -52,12 +52,12 @@ where // Accept empty initializers. if let Expr::Call(ast::ExprCall { func, - arguments: Arguments { args, keywords, .. }, + arguments, range: _, }) = expr { // Ex) `list()` - if args.is_empty() && keywords.is_empty() { + if arguments.is_empty() { if let Expr::Name(ast::ExprName { id, .. }) = func.as_ref() { if !is_iterable_initializer(id.as_str(), |id| is_builtin(id)) { return true; @@ -221,14 +221,14 @@ pub fn any_over_expr(expr: &Expr, func: &dyn Fn(&Expr) -> bool) -> bool { }) => any_over_expr(left, func) || comparators.iter().any(|expr| any_over_expr(expr, func)), Expr::Call(ast::ExprCall { func: call_func, - arguments: Arguments { args, keywords, .. }, + arguments, range: _, }) => { any_over_expr(call_func, func) // Note that this is the evaluation order but not necessarily the declaration order // (e.g. for `f(*args, a=2, *args2, **kwargs)` it's not) - || args.iter().any(|expr| any_over_expr(expr, func)) - || keywords + || arguments.args.iter().any(|expr| any_over_expr(expr, func)) + || arguments.keywords .iter() .any(|keyword| any_over_expr(&keyword.value, func)) } @@ -1227,18 +1227,16 @@ impl Truthiness { } } Expr::Call(ast::ExprCall { - func, - arguments: Arguments { args, keywords, .. }, - .. + func, arguments, .. }) => { if let Expr::Name(ast::ExprName { id, .. }) = func.as_ref() { if is_iterable_initializer(id.as_str(), |id| is_builtin(id)) { - if args.is_empty() && keywords.is_empty() { + if arguments.is_empty() { // Ex) `list()` Self::Falsey - } else if args.len() == 1 && keywords.is_empty() { + } else if arguments.args.len() == 1 && arguments.keywords.is_empty() { // Ex) `list([1, 2, 3])` - Self::from_expr(&args[0], is_builtin) + Self::from_expr(&arguments.args[0], is_builtin) } else { Self::Unknown } diff --git a/crates/ruff_python_ast/src/node.rs b/crates/ruff_python_ast/src/node.rs index 3d362691a26b6..54afd2e040b3e 100644 --- a/crates/ruff_python_ast/src/node.rs +++ b/crates/ruff_python_ast/src/node.rs @@ -2588,7 +2588,7 @@ impl AstNode for ast::ExprCompare { visitor.visit_expr(left); - for (op, comparator) in ops.iter().zip(comparators) { + for (op, comparator) in ops.iter().zip(&**comparators) { visitor.visit_cmp_op(op); visitor.visit_expr(comparator); } diff --git a/crates/ruff_python_ast/src/nodes.rs b/crates/ruff_python_ast/src/nodes.rs index 09f4bf8ddd410..cfb8355c69f05 100644 --- a/crates/ruff_python_ast/src/nodes.rs +++ b/crates/ruff_python_ast/src/nodes.rs @@ -894,8 +894,8 @@ impl From for Expr { pub struct ExprCompare { pub range: TextRange, pub left: Box, - pub ops: Vec, - pub comparators: Vec, + pub ops: Box<[CmpOp]>, + pub comparators: Box<[Expr]>, } impl From for Expr { @@ -2987,8 +2987,8 @@ pub struct ParameterWithDefault { #[derive(Clone, Debug, PartialEq)] pub struct Arguments { pub range: TextRange, - pub args: Vec, - pub keywords: Vec, + pub args: Box<[Expr]>, + pub keywords: Box<[Keyword]>, } /// An entry in the argument list of a function call. @@ -3894,10 +3894,42 @@ mod tests { assert!(std::mem::size_of::() <= 144); assert!(std::mem::size_of::() <= 104); assert!(std::mem::size_of::() <= 112); - // 80 for Rustc < 1.76 - assert!(matches!(std::mem::size_of::(), 72 | 80)); + assert!(std::mem::size_of::() <= 32); // 96 for Rustc < 1.76 assert!(matches!(std::mem::size_of::(), 88 | 96)); - assert!(std::mem::size_of::() <= 32); + + assert_eq!(std::mem::size_of::(), 64); + assert_eq!(std::mem::size_of::(), 56); + assert_eq!(std::mem::size_of::(), 16); + assert_eq!(std::mem::size_of::(), 32); + assert_eq!(std::mem::size_of::(), 40); + assert_eq!(std::mem::size_of::(), 12); + assert_eq!(std::mem::size_of::(), 40); + assert_eq!(std::mem::size_of::(), 56); + assert_eq!(std::mem::size_of::(), 48); + assert_eq!(std::mem::size_of::(), 56); + assert_eq!(std::mem::size_of::(), 48); + assert_eq!(std::mem::size_of::(), 8); + assert_eq!(std::mem::size_of::(), 48); + assert_eq!(std::mem::size_of::(), 40); + assert_eq!(std::mem::size_of::(), 32); + assert_eq!(std::mem::size_of::(), 32); + assert_eq!(std::mem::size_of::(), 24); + assert_eq!(std::mem::size_of::(), 40); + assert_eq!(std::mem::size_of::(), 40); + assert_eq!(std::mem::size_of::(), 40); + assert_eq!(std::mem::size_of::(), 24); + assert_eq!(std::mem::size_of::(), 8); + assert_eq!(std::mem::size_of::(), 32); + assert_eq!(std::mem::size_of::(), 32); + assert_eq!(std::mem::size_of::(), 40); + assert_eq!(std::mem::size_of::(), 32); + assert_eq!(std::mem::size_of::(), 24); + assert_eq!(std::mem::size_of::(), 48); + assert_eq!(std::mem::size_of::(), 32); + assert_eq!(std::mem::size_of::(), 40); + assert_eq!(std::mem::size_of::(), 24); + assert_eq!(std::mem::size_of::(), 16); + assert_eq!(std::mem::size_of::(), 16); } } diff --git a/crates/ruff_python_ast/src/visitor.rs b/crates/ruff_python_ast/src/visitor.rs index 2d8773fcfdcb0..cd93b4927fd66 100644 --- a/crates/ruff_python_ast/src/visitor.rs +++ b/crates/ruff_python_ast/src/visitor.rs @@ -461,10 +461,10 @@ pub fn walk_expr<'a, V: Visitor<'a> + ?Sized>(visitor: &mut V, expr: &'a Expr) { range: _, }) => { visitor.visit_expr(left); - for cmp_op in ops { + for cmp_op in &**ops { visitor.visit_cmp_op(cmp_op); } - for expr in comparators { + for expr in &**comparators { visitor.visit_expr(expr); } } @@ -594,10 +594,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 // f(*args, a=2, *args2, **kwargs)`, but we follow Python in evaluating first `args` and then // `keywords`. See also [Arguments::arguments_source_order`]. - for arg in &arguments.args { + for arg in arguments.args.iter() { visitor.visit_expr(arg); } - for keyword in &arguments.keywords { + for keyword in arguments.keywords.iter() { visitor.visit_keyword(keyword); } } diff --git a/crates/ruff_python_ast/src/visitor/transformer.rs b/crates/ruff_python_ast/src/visitor/transformer.rs index caa111c43f95b..a8e1f8950880f 100644 --- a/crates/ruff_python_ast/src/visitor/transformer.rs +++ b/crates/ruff_python_ast/src/visitor/transformer.rs @@ -448,10 +448,10 @@ pub fn walk_expr(visitor: &V, expr: &mut Expr) { range: _, }) => { visitor.visit_expr(left); - for cmp_op in ops { + for cmp_op in &mut **ops { visitor.visit_cmp_op(cmp_op); } - for expr in comparators { + for expr in &mut **comparators { visitor.visit_expr(expr); } } @@ -580,10 +580,10 @@ pub fn walk_arguments(visitor: &V, arguments: &mut Argu // 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 // `keywords`. See also [Arguments::arguments_source_order`]. - for arg in &mut arguments.args { + for arg in arguments.args.iter_mut() { visitor.visit_expr(arg); } - for keyword in &mut arguments.keywords { + for keyword in arguments.keywords.iter_mut() { visitor.visit_keyword(keyword); } } diff --git a/crates/ruff_python_codegen/src/generator.rs b/crates/ruff_python_codegen/src/generator.rs index 77cdcd3252e44..c3d7a60ffb3e6 100644 --- a/crates/ruff_python_codegen/src/generator.rs +++ b/crates/ruff_python_codegen/src/generator.rs @@ -1007,7 +1007,7 @@ impl<'a> Generator<'a> { group_if!(precedence::CMP, { let new_lvl = precedence::CMP + 1; self.unparse_expr(left, new_lvl); - for (op, cmp) in ops.iter().zip(comparators) { + for (op, cmp) in ops.iter().zip(&**comparators) { let op = match op { CmpOp::Eq => " == ", CmpOp::NotEq => " != ", @@ -1039,7 +1039,7 @@ impl<'a> Generator<'a> { range: _, })], [], - ) = (arguments.args.as_slice(), arguments.keywords.as_slice()) + ) = (arguments.args.as_ref(), arguments.keywords.as_ref()) { // Ensure that a single generator doesn't get double-parenthesized. self.unparse_expr(elt, precedence::COMMA); diff --git a/crates/ruff_python_formatter/src/other/arguments.rs b/crates/ruff_python_formatter/src/other/arguments.rs index 8e7462d204a37..7328c39eeccc2 100644 --- a/crates/ruff_python_formatter/src/other/arguments.rs +++ b/crates/ruff_python_formatter/src/other/arguments.rs @@ -38,7 +38,7 @@ impl FormatNodeRule for FormatArguments { let all_arguments = format_with(|f: &mut PyFormatter| { let source = f.context().source(); let mut joiner = f.join_comma_separated(range.end()); - match args.as_slice() { + match args.as_ref() { [arg] if keywords.is_empty() => { match arg { Expr::GeneratorExp(generator_exp) => joiner.entry( @@ -180,7 +180,7 @@ fn is_single_argument_parenthesized(argument: &Expr, call_end: TextSize, source: /// of those collections. fn is_arguments_huggable(arguments: &Arguments, context: &PyFormatContext) -> bool { // Find the lone argument or `**kwargs` keyword. - let arg = match (arguments.args.as_slice(), arguments.keywords.as_slice()) { + let arg = match (arguments.args.as_ref(), arguments.keywords.as_ref()) { ([arg], []) => arg, ([], [keyword]) if keyword.arg.is_none() && !context.comments().has(keyword) => { &keyword.value diff --git a/crates/ruff_python_parser/src/function.rs b/crates/ruff_python_parser/src/function.rs index 1700066165e4b..38045cb028a60 100644 --- a/crates/ruff_python_parser/src/function.rs +++ b/crates/ruff_python_parser/src/function.rs @@ -81,16 +81,16 @@ type FunctionArgument = ( pub(crate) fn parse_arguments( function_arguments: Vec, ) -> Result { - let mut args = vec![]; - let mut keywords = vec![]; - + // First, run through the comments to determine the number of positional and keyword arguments. let mut keyword_names = FxHashSet::with_capacity_and_hasher( function_arguments.len(), BuildHasherDefault::default(), ); let mut double_starred = false; - for (name, value) in function_arguments { - if let Some((start, end, name)) = name { + let mut num_args = 0; + let mut num_keywords = 0; + for (name, value) in &function_arguments { + if let Some((start, _end, name)) = name { // Check for duplicate keyword arguments in the call. if let Some(keyword_name) = &name { if !keyword_names.insert(keyword_name.to_string()) { @@ -98,21 +98,17 @@ pub(crate) fn parse_arguments( LexicalErrorType::DuplicateKeywordArgumentError( keyword_name.to_string().into_boxed_str(), ), - start, + *start, )); } } else { double_starred = true; } - keywords.push(ast::Keyword { - arg: name, - value, - range: TextRange::new(start, end), - }); + num_keywords += 1; } else { // Positional arguments mustn't follow keyword arguments. - if !keywords.is_empty() && !is_starred(&value) { + if num_keywords > 0 && !is_starred(value) { return Err(LexicalError::new( LexicalErrorType::PositionalArgumentError, value.start(), @@ -126,9 +122,26 @@ pub(crate) fn parse_arguments( )); } + num_args += 1; + } + } + + // Second, push the arguments into vectors of exact capacity. This avoids a vector resize later + // on when these vectors are boxed into slices. + let mut args = Vec::with_capacity(num_args); + let mut keywords = Vec::with_capacity(num_keywords); + for (name, value) in function_arguments { + if let Some((start, end, name)) = name { + keywords.push(ast::Keyword { + arg: name, + value, + range: TextRange::new(start, end), + }); + } else { args.push(value); } } + Ok(ArgumentList { args, keywords }) } diff --git a/crates/ruff_python_parser/src/parser.rs b/crates/ruff_python_parser/src/parser.rs index a73b6d12e16b8..46fef053bdb16 100644 --- a/crates/ruff_python_parser/src/parser.rs +++ b/crates/ruff_python_parser/src/parser.rs @@ -569,8 +569,7 @@ mod tests { #[cfg(target_pointer_width = "64")] #[test] fn size_assertions() { - // 80 with Rustc >= 1.76, 88 with Rustc < 1.76 - assert!(matches!(std::mem::size_of::(), 80 | 88)); + assert_eq!(std::mem::size_of::(), 72); } #[test] diff --git a/crates/ruff_python_parser/src/python.lalrpop b/crates/ruff_python_parser/src/python.lalrpop index 386574b0001b7..2d628ae74a805 100644 --- a/crates/ruff_python_parser/src/python.lalrpop +++ b/crates/ruff_python_parser/src/python.lalrpop @@ -1406,8 +1406,18 @@ NotTest: crate::parser::ParenthesizedExpr = { Comparison: crate::parser::ParenthesizedExpr = { > )+> => { - let (ops, comparators) = comparisons.into_iter().map(|(op, comparator)| (op, ast::Expr::from(comparator))).unzip(); - ast::ExprCompare { left: Box::new(left.into()), ops, comparators, range: (location..end_location).into() }.into() + let mut ops = Vec::with_capacity(comparisons.len()); + let mut comparators = Vec::with_capacity(comparisons.len()); + for (op, comparator) in comparisons { + ops.push(op); + comparators.push(comparator.into()); + } + ast::ExprCompare { + left: Box::new(left.into()), + ops: ops.into_boxed_slice(), + comparators: comparators.into_boxed_slice(), + range: (location..end_location).into(), + }.into() }, Expression, }; @@ -1880,8 +1890,8 @@ Arguments: ast::Arguments = { "(" > ")" =>? { let ArgumentList { args, keywords } = parse_arguments(e)?; Ok(ast::Arguments { - args, - keywords, + args: args.into_boxed_slice(), + keywords: keywords.into_boxed_slice(), range: (location..end_location).into() }) } diff --git a/crates/ruff_python_parser/src/python.rs b/crates/ruff_python_parser/src/python.rs index abe55991b201a..1372b6e4fb260 100644 --- a/crates/ruff_python_parser/src/python.rs +++ b/crates/ruff_python_parser/src/python.rs @@ -1,5 +1,5 @@ // auto-generated: "lalrpop 0.20.0" -// sha3: fd05d84d3b654796ff740a7f905ec0ae8915f43f952428717735481947ab55e1 +// sha3: 02c60b5c591440061dda68775005d87a203b5448c205120bda1566a62fc2147c use ruff_text_size::{Ranged, TextLen, TextRange, TextSize}; use ruff_python_ast::{self as ast, Int, IpyEscapeKind}; use crate::{ @@ -36771,8 +36771,8 @@ fn __action241< { let ArgumentList { args, keywords } = parse_arguments(e)?; Ok(ast::Arguments { - args, - keywords, + args: args.into_boxed_slice(), + keywords: keywords.into_boxed_slice(), range: (location..end_location).into() }) } @@ -40651,8 +40651,18 @@ fn __action515< ) -> crate::parser::ParenthesizedExpr { { - let (ops, comparators) = comparisons.into_iter().map(|(op, comparator)| (op, ast::Expr::from(comparator))).unzip(); - ast::ExprCompare { left: Box::new(left.into()), ops, comparators, range: (location..end_location).into() }.into() + let mut ops = Vec::with_capacity(comparisons.len()); + let mut comparators = Vec::with_capacity(comparisons.len()); + for (op, comparator) in comparisons { + ops.push(op); + comparators.push(comparator.into()); + } + ast::ExprCompare { + left: Box::new(left.into()), + ops: ops.into_boxed_slice(), + comparators: comparators.into_boxed_slice(), + range: (location..end_location).into(), + }.into() } } @@ -40816,8 +40826,18 @@ fn __action526< ) -> crate::parser::ParenthesizedExpr { { - let (ops, comparators) = comparisons.into_iter().map(|(op, comparator)| (op, ast::Expr::from(comparator))).unzip(); - ast::ExprCompare { left: Box::new(left.into()), ops, comparators, range: (location..end_location).into() }.into() + let mut ops = Vec::with_capacity(comparisons.len()); + let mut comparators = Vec::with_capacity(comparisons.len()); + for (op, comparator) in comparisons { + ops.push(op); + comparators.push(comparator.into()); + } + ast::ExprCompare { + left: Box::new(left.into()), + ops: ops.into_boxed_slice(), + comparators: comparators.into_boxed_slice(), + range: (location..end_location).into(), + }.into() } }