diff --git a/Cargo.lock b/Cargo.lock index b5daeb5aba9b5c..b549bfc93bb3f5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -246,6 +246,15 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5" +[[package]] +name = "castaway" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a17ed5635fc8536268e5d4de1e22e81ac34419e5f052d4d51f4e01dcc263fcc" +dependencies = [ + "rustversion", +] + [[package]] name = "cc" version = "1.0.83" @@ -444,6 +453,19 @@ dependencies = [ "windows-sys 0.48.0", ] +[[package]] +name = "compact_str" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f86b9c4c00838774a6d902ef931eff7470720c51d90c2e32cfe15dc304737b3f" +dependencies = [ + "castaway", + "cfg-if", + "itoa", + "ryu", + "static_assertions", +] + [[package]] name = "configparser" version = "3.0.2" @@ -2197,6 +2219,7 @@ dependencies = [ "chrono", "clap", "colored", + "compact_str", "fern", "glob", "globset", @@ -2286,6 +2309,7 @@ name = "ruff_python_ast" version = "0.0.0" dependencies = [ "bitflags 2.4.0", + "compact_str", "insta", "is-macro", "itertools 0.11.0", @@ -2376,6 +2400,7 @@ version = "0.0.0" dependencies = [ "anyhow", "bitflags 2.4.0", + "compact_str", "insta", "is-macro", "itertools 0.11.0", diff --git a/Cargo.toml b/Cargo.toml index 80630fc0452f5e..dbefd7c4f6217f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -17,6 +17,7 @@ bitflags = { version = "2.3.1" } chrono = { version = "0.4.31", default-features = false, features = ["clock"] } clap = { version = "4.4.6", features = ["derive"] } colored = { version = "2.0.0" } +compact_str = { version = "0.7.1" } filetime = { version = "0.2.20" } glob = { version = "0.3.1" } globset = { version = "0.4.10" } @@ -52,7 +53,12 @@ tracing-subscriber = { version = "0.3.17", features = ["env-filter"] } unicode-ident = { version = "1.0.12" } unicode_names2 = { version = "1.2.0" } unicode-width = { version = "0.1.11" } -uuid = { version = "1.4.1", features = ["v4", "fast-rng", "macro-diagnostics", "js"] } +uuid = { version = "1.4.1", features = [ + "v4", + "fast-rng", + "macro-diagnostics", + "js", +] } wsl = { version = "0.1.0" } [profile.release] diff --git a/crates/ruff_linter/Cargo.toml b/crates/ruff_linter/Cargo.toml index a68c72ff5d3608..42d43d7fd32f47 100644 --- a/crates/ruff_linter/Cargo.toml +++ b/crates/ruff_linter/Cargo.toml @@ -36,6 +36,7 @@ bitflags = { workspace = true } chrono = { workspace = true } clap = { workspace = true, features = ["derive", "string"], optional = true } colored = { workspace = true } +compact_str = { workspace = true } fern = { version = "0.6.1" } glob = { workspace = true } globset = { workspace = true } diff --git a/crates/ruff_linter/src/checkers/ast/mod.rs b/crates/ruff_linter/src/checkers/ast/mod.rs index 2905820fa65900..ecb204857de51d 100644 --- a/crates/ruff_linter/src/checkers/ast/mod.rs +++ b/crates/ruff_linter/src/checkers/ast/mod.rs @@ -832,7 +832,7 @@ where range: _, }) => { if let Expr::Name(ast::ExprName { id, ctx, range: _ }) = func.as_ref() { - if id == "locals" && ctx.is_load() { + if id.as_str() == "locals" && ctx.is_load() { let scope = self.semantic.current_scope_mut(); scope.set_uses_locals(); } @@ -1005,7 +1005,7 @@ where 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); @@ -1664,21 +1664,21 @@ impl<'a> Checker<'a> { && match parent { Stmt::Assign(ast::StmtAssign { targets, .. }) => { if let Some(Expr::Name(ast::ExprName { id, .. })) = targets.first() { - id == "__all__" + id.as_str() == "__all__" } else { false } } Stmt::AugAssign(ast::StmtAugAssign { target, .. }) => { if let Expr::Name(ast::ExprName { id, .. }) = target.as_ref() { - id == "__all__" + id.as_str() == "__all__" } else { false } } Stmt::AnnAssign(ast::StmtAnnAssign { target, .. }) => { if let Expr::Name(ast::ExprName { id, .. }) = target.as_ref() { - id == "__all__" + id.as_str() == "__all__" } else { false } diff --git a/crates/ruff_linter/src/checkers/imports.rs b/crates/ruff_linter/src/checkers/imports.rs index 22cbe662f5c8bc..543528de55d173 100644 --- a/crates/ruff_linter/src/checkers/imports.rs +++ b/crates/ruff_linter/src/checkers/imports.rs @@ -2,6 +2,7 @@ use std::borrow::Cow; use std::path::Path; +use compact_str::CompactString; use ruff_diagnostics::Diagnostic; use ruff_python_ast::helpers::to_module_path; use ruff_python_ast::imports::{ImportMap, ModuleImport}; @@ -46,9 +47,9 @@ fn extract_import_map(path: &Path, package: Option<&Path>, blocks: &[&Block]) -> }) => { let level = level.unwrap_or_default() as usize; let module = if let Some(module) = module { - let module: &String = module.as_ref(); + let module: &CompactString = module.as_ref(); if level == 0 { - Cow::Borrowed(module) + Cow::Borrowed(module.as_str()) } else { if module_path.len() <= level { continue; diff --git a/crates/ruff_linter/src/rules/airflow/rules/task_variable_name.rs b/crates/ruff_linter/src/rules/airflow/rules/task_variable_name.rs index fccf1a79aade10..a1a7c35c1de02d 100644 --- a/crates/ruff_linter/src/rules/airflow/rules/task_variable_name.rs +++ b/crates/ruff_linter/src/rules/airflow/rules/task_variable_name.rs @@ -88,7 +88,7 @@ pub(crate) fn variable_name_task_id( }; // If the target name is the same as the task_id, no violation. - if id == task_id { + if id.as_str() == task_id.as_str() { return None; } diff --git a/crates/ruff_linter/src/rules/flake8_bandit/rules/jinja2_autoescape_false.rs b/crates/ruff_linter/src/rules/flake8_bandit/rules/jinja2_autoescape_false.rs index 9d7093b35a1b81..48dbb874599a26 100644 --- a/crates/ruff_linter/src/rules/flake8_bandit/rules/jinja2_autoescape_false.rs +++ b/crates/ruff_linter/src/rules/flake8_bandit/rules/jinja2_autoescape_false.rs @@ -72,7 +72,7 @@ pub(crate) fn jinja2_autoescape_false(checker: &mut Checker, call: &ast::ExprCal }) => (), Expr::Call(ast::ExprCall { func, .. }) => { if let Expr::Name(ast::ExprName { id, .. }) = func.as_ref() { - if id != "select_autoescape" { + if id.as_str() != "select_autoescape" { checker.diagnostics.push(Diagnostic::new( Jinja2AutoescapeFalse { value: true }, keyword.range(), diff --git a/crates/ruff_linter/src/rules/flake8_blind_except/rules/blind_except.rs b/crates/ruff_linter/src/rules/flake8_blind_except/rules/blind_except.rs index 102f40be9913e8..7f475cbbb10acf 100644 --- a/crates/ruff_linter/src/rules/flake8_blind_except/rules/blind_except.rs +++ b/crates/ruff_linter/src/rules/flake8_blind_except/rules/blind_except.rs @@ -77,7 +77,7 @@ pub(crate) fn blind_except( if let Stmt::Raise(ast::StmtRaise { exc, .. }) = stmt { if let Some(exc) = exc { if let Expr::Name(ast::ExprName { id, .. }) = exc.as_ref() { - name.is_some_and(|name| id == name) + name.is_some_and(|name| id.as_str() == name) } else { false } diff --git a/crates/ruff_linter/src/rules/flake8_boolean_trap/rules/boolean_type_hint_positional_argument.rs b/crates/ruff_linter/src/rules/flake8_boolean_trap/rules/boolean_type_hint_positional_argument.rs index f6178b7cf13d24..6b330e7722b518 100644 --- a/crates/ruff_linter/src/rules/flake8_boolean_trap/rules/boolean_type_hint_positional_argument.rs +++ b/crates/ruff_linter/src/rules/flake8_boolean_trap/rules/boolean_type_hint_positional_argument.rs @@ -125,11 +125,11 @@ pub(crate) fn boolean_type_hint_positional_argument( // check for both bool (python class) and 'bool' (string annotation) let hint = match annotation.as_ref() { - Expr::Name(name) => &name.id == "bool", + Expr::Name(name) => name.id.as_str() == "bool", Expr::Constant(ast::ExprConstant { value: Constant::Str(ast::StringConstant { value, .. }), .. - }) => value == "bool", + }) => value.as_str() == "bool", _ => false, }; if !hint || !checker.semantic().is_builtin("bool") { diff --git a/crates/ruff_linter/src/rules/flake8_bugbear/rules/assignment_to_os_environ.rs b/crates/ruff_linter/src/rules/flake8_bugbear/rules/assignment_to_os_environ.rs index 9f0fef6c38be35..021f709c4a4c8d 100644 --- a/crates/ruff_linter/src/rules/flake8_bugbear/rules/assignment_to_os_environ.rs +++ b/crates/ruff_linter/src/rules/flake8_bugbear/rules/assignment_to_os_environ.rs @@ -63,7 +63,7 @@ pub(crate) fn assignment_to_os_environ(checker: &mut Checker, targets: &[Expr]) let Expr::Name(ast::ExprName { id, .. }) = value.as_ref() else { return; }; - if id != "os" { + if id.as_str() != "os" { return; } checker diff --git a/crates/ruff_linter/src/rules/flake8_bugbear/rules/cached_instance_method.rs b/crates/ruff_linter/src/rules/flake8_bugbear/rules/cached_instance_method.rs index 083954116a68b2..f006d0728ed0e1 100644 --- a/crates/ruff_linter/src/rules/flake8_bugbear/rules/cached_instance_method.rs +++ b/crates/ruff_linter/src/rules/flake8_bugbear/rules/cached_instance_method.rs @@ -85,7 +85,7 @@ pub(crate) fn cached_instance_method(checker: &mut Checker, decorator_list: &[De // TODO(charlie): This should take into account `classmethod-decorators` and // `staticmethod-decorators`. if let Expr::Name(ast::ExprName { id, .. }) = &decorator.expression { - if id == "classmethod" || id == "staticmethod" { + if id.as_str() == "classmethod" || id.as_str() == "staticmethod" { 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 daf0fe389e9d6c..84bcbfc021e4df 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 @@ -95,7 +95,11 @@ impl<'a> Visitor<'a> for SuspiciousVariablesVisitor<'a> { // Treat any non-arguments as "suspicious". self.names .extend(visitor.loaded.into_iter().filter(|loaded| { - if visitor.stored.iter().any(|stored| stored.id == loaded.id) { + if visitor + .stored + .iter() + .any(|stored| stored.id.as_str() == loaded.id) + { return false; } @@ -147,7 +151,7 @@ impl<'a> Visitor<'a> for SuspiciousVariablesVisitor<'a> { Expr::Attribute(ast::ExprAttribute { value, attr, .. }) => { if attr == "reduce" { if let Expr::Name(ast::ExprName { id, .. }) = value.as_ref() { - if id == "functools" { + if id.as_str() == "functools" { for arg in args { if arg.is_lambda_expr() { self.safe_functions.push(arg); @@ -181,7 +185,11 @@ impl<'a> Visitor<'a> for SuspiciousVariablesVisitor<'a> { // Treat any non-arguments as "suspicious". self.names .extend(visitor.loaded.into_iter().filter(|loaded| { - if visitor.stored.iter().any(|stored| stored.id == loaded.id) { + if visitor + .stored + .iter() + .any(|stored| stored.id.as_str() == loaded.id) + { return false; } diff --git a/crates/ruff_linter/src/rules/flake8_bugbear/rules/getattr_with_constant.rs b/crates/ruff_linter/src/rules/flake8_bugbear/rules/getattr_with_constant.rs index b9b26249501239..c289ec10f38525 100644 --- a/crates/ruff_linter/src/rules/flake8_bugbear/rules/getattr_with_constant.rs +++ b/crates/ruff_linter/src/rules/flake8_bugbear/rules/getattr_with_constant.rs @@ -57,7 +57,7 @@ pub(crate) fn getattr_with_constant( let Expr::Name(ast::ExprName { id, .. }) = func else { return; }; - if id != "getattr" { + if id.as_str() != "getattr" { return; } let [obj, arg] = args else { diff --git a/crates/ruff_linter/src/rules/flake8_bugbear/rules/raise_without_from_inside_except.rs b/crates/ruff_linter/src/rules/flake8_bugbear/rules/raise_without_from_inside_except.rs index 7af198e177e4cc..f935a38a24d8b6 100644 --- a/crates/ruff_linter/src/rules/flake8_bugbear/rules/raise_without_from_inside_except.rs +++ b/crates/ruff_linter/src/rules/flake8_bugbear/rules/raise_without_from_inside_except.rs @@ -87,7 +87,7 @@ pub(crate) fn raise_without_from_inside_except( if let Some(name) = name { if exc .as_name_expr() - .is_some_and(|ast::ExprName { id, .. }| name == id) + .is_some_and(|ast::ExprName { id, .. }| name == id.as_str()) { continue; } diff --git a/crates/ruff_linter/src/rules/flake8_bugbear/rules/reuse_of_groupby_generator.rs b/crates/ruff_linter/src/rules/flake8_bugbear/rules/reuse_of_groupby_generator.rs index 3bc93c22eb882f..3f8fb7785864b6 100644 --- a/crates/ruff_linter/src/rules/flake8_bugbear/rules/reuse_of_groupby_generator.rs +++ b/crates/ruff_linter/src/rules/flake8_bugbear/rules/reuse_of_groupby_generator.rs @@ -83,7 +83,7 @@ impl<'a> GroupNameFinder<'a> { fn name_matches(&self, expr: &Expr) -> bool { if let Expr::Name(ast::ExprName { id, .. }) = expr { - id == self.group_name + id.as_str() == self.group_name } else { false } diff --git a/crates/ruff_linter/src/rules/flake8_bugbear/rules/setattr_with_constant.rs b/crates/ruff_linter/src/rules/flake8_bugbear/rules/setattr_with_constant.rs index 290f3ebc87197d..33abf262e1a5d3 100644 --- a/crates/ruff_linter/src/rules/flake8_bugbear/rules/setattr_with_constant.rs +++ b/crates/ruff_linter/src/rules/flake8_bugbear/rules/setattr_with_constant.rs @@ -71,7 +71,7 @@ pub(crate) fn setattr_with_constant( let Expr::Name(ast::ExprName { id, .. }) = func else { return; }; - if id != "setattr" { + if id.as_str() != "setattr" { return; } let [obj, name, value] = args else { diff --git a/crates/ruff_linter/src/rules/flake8_bugbear/rules/unintentional_type_annotation.rs b/crates/ruff_linter/src/rules/flake8_bugbear/rules/unintentional_type_annotation.rs index 69f8c5505d4e63..c019eb5bd749ca 100644 --- a/crates/ruff_linter/src/rules/flake8_bugbear/rules/unintentional_type_annotation.rs +++ b/crates/ruff_linter/src/rules/flake8_bugbear/rules/unintentional_type_annotation.rs @@ -54,7 +54,7 @@ pub(crate) fn unintentional_type_annotation( } Expr::Attribute(ast::ExprAttribute { value, .. }) => { if let Expr::Name(ast::ExprName { id, .. }) = value.as_ref() { - if id != "self" { + if id.as_str() != "self" { checker .diagnostics .push(Diagnostic::new(UnintentionalTypeAnnotation, stmt.range())); diff --git a/crates/ruff_linter/src/rules/flake8_bugbear/rules/unreliable_callable_check.rs b/crates/ruff_linter/src/rules/flake8_bugbear/rules/unreliable_callable_check.rs index 400f5d31c13966..207f696afd32c2 100644 --- a/crates/ruff_linter/src/rules/flake8_bugbear/rules/unreliable_callable_check.rs +++ b/crates/ruff_linter/src/rules/flake8_bugbear/rules/unreliable_callable_check.rs @@ -74,12 +74,12 @@ pub(crate) fn unreliable_callable_check( else { return; }; - if value != "__call__" { + if value.as_str() != "__call__" { return; } let mut diagnostic = Diagnostic::new(UnreliableCallableCheck, expr.range()); - if id == "hasattr" { + if id.as_str() == "hasattr" { if checker.semantic().is_builtin("callable") { diagnostic.set_fix(Fix::safe_edit(Edit::range_replacement( format!("callable({})", checker.locator().slice(obj)), 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 c7a807a50c16c1..562c878f4fbf99 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 @@ -43,7 +43,7 @@ impl Violation for ZipWithoutExplicitStrict { /// B905 pub(crate) fn zip_without_explicit_strict(checker: &mut Checker, call: &ast::ExprCall) { if let Expr::Name(ast::ExprName { id, .. }) = call.func.as_ref() { - if id == "zip" + if id.as_str() == "zip" && checker.semantic().is_builtin("zip") && call.arguments.find_keyword("strict").is_none() && !call diff --git a/crates/ruff_linter/src/rules/flake8_comprehensions/rules/helpers.rs b/crates/ruff_linter/src/rules/flake8_comprehensions/rules/helpers.rs index f22a8dd9085095..3f00de5775fdaf 100644 --- a/crates/ruff_linter/src/rules/flake8_comprehensions/rules/helpers.rs +++ b/crates/ruff_linter/src/rules/flake8_comprehensions/rules/helpers.rs @@ -13,7 +13,7 @@ pub(super) fn exactly_one_argument_with_matching_function<'a>( return None; } let func = func.as_name_expr()?; - if func.id != name { + if func.id.as_str() != name { return None; } Some(arg) @@ -24,7 +24,10 @@ pub(super) fn first_argument_with_matching_function<'a>( func: &Expr, args: &'a [Expr], ) -> Option<&'a Expr> { - if func.as_name_expr().is_some_and(|func| func.id == name) { + if func + .as_name_expr() + .is_some_and(|func| func.id.as_str() == name) + { args.first() } else { None diff --git a/crates/ruff_linter/src/rules/flake8_comprehensions/rules/unnecessary_call_around_sorted.rs b/crates/ruff_linter/src/rules/flake8_comprehensions/rules/unnecessary_call_around_sorted.rs index 7117d099916870..ca6b92c9653716 100644 --- a/crates/ruff_linter/src/rules/flake8_comprehensions/rules/unnecessary_call_around_sorted.rs +++ b/crates/ruff_linter/src/rules/flake8_comprehensions/rules/unnecessary_call_around_sorted.rs @@ -70,7 +70,7 @@ pub(crate) fn unnecessary_call_around_sorted( let Some(inner) = func.as_name_expr() else { return; }; - if inner.id != "sorted" { + if inner.id.as_str() != "sorted" { return; } if !checker.semantic().is_builtin(&inner.id) || !checker.semantic().is_builtin(&outer.id) { @@ -85,7 +85,7 @@ pub(crate) fn unnecessary_call_around_sorted( diagnostic.try_set_fix(|| { let edit = fixes::fix_unnecessary_call_around_sorted(expr, checker.locator(), checker.stylist())?; - if outer.id == "reversed" { + if outer.id.as_str() == "reversed" { Ok(Fix::unsafe_edit(edit)) } else { Ok(Fix::safe_edit(edit)) diff --git a/crates/ruff_linter/src/rules/flake8_comprehensions/rules/unnecessary_double_cast_or_process.rs b/crates/ruff_linter/src/rules/flake8_comprehensions/rules/unnecessary_double_cast_or_process.rs index 5bdeca9a5725be..f110ca48910a4f 100644 --- a/crates/ruff_linter/src/rules/flake8_comprehensions/rules/unnecessary_double_cast_or_process.rs +++ b/crates/ruff_linter/src/rules/flake8_comprehensions/rules/unnecessary_double_cast_or_process.rs @@ -101,7 +101,7 @@ pub(crate) fn unnecessary_double_cast_or_process( // Avoid collapsing nested `sorted` calls with non-identical keyword arguments // (i.e., `key`, `reverse`). - if inner.id == "sorted" && outer.id == "sorted" { + if inner.id.as_str() == "sorted" && outer.id.as_str() == "sorted" { if inner_kw.len() != outer_kw.len() { return; } diff --git a/crates/ruff_linter/src/rules/flake8_django/rules/all_with_model_form.rs b/crates/ruff_linter/src/rules/flake8_django/rules/all_with_model_form.rs index 50a7f98c55a447..208833447543dc 100644 --- a/crates/ruff_linter/src/rules/flake8_django/rules/all_with_model_form.rs +++ b/crates/ruff_linter/src/rules/flake8_django/rules/all_with_model_form.rs @@ -77,7 +77,7 @@ pub(crate) fn all_with_model_form( let Expr::Name(ast::ExprName { id, .. }) = target else { continue; }; - if id != "fields" { + if id.as_str() != "fields" { continue; } let Expr::Constant(ast::ExprConstant { value, .. }) = value.as_ref() else { @@ -85,7 +85,7 @@ pub(crate) fn all_with_model_form( }; match value { Constant::Str(ast::StringConstant { value, .. }) => { - if value == "__all__" { + if value.as_str() == "__all__" { return Some(Diagnostic::new(DjangoAllWithModelForm, element.range())); } } diff --git a/crates/ruff_linter/src/rules/flake8_django/rules/exclude_with_model_form.rs b/crates/ruff_linter/src/rules/flake8_django/rules/exclude_with_model_form.rs index 41661892bb9d6c..4a0c8e1073c999 100644 --- a/crates/ruff_linter/src/rules/flake8_django/rules/exclude_with_model_form.rs +++ b/crates/ruff_linter/src/rules/flake8_django/rules/exclude_with_model_form.rs @@ -75,7 +75,7 @@ pub(crate) fn exclude_with_model_form( let Expr::Name(ast::ExprName { id, .. }) = target else { continue; }; - if id == "exclude" { + if id.as_str() == "exclude" { return Some(Diagnostic::new(DjangoExcludeWithModelForm, target.range())); } } diff --git a/crates/ruff_linter/src/rules/flake8_django/rules/model_without_dunder_str.rs b/crates/ruff_linter/src/rules/flake8_django/rules/model_without_dunder_str.rs index 9228d04753e4e9..5ecaf9534670fe 100644 --- a/crates/ruff_linter/src/rules/flake8_django/rules/model_without_dunder_str.rs +++ b/crates/ruff_linter/src/rules/flake8_django/rules/model_without_dunder_str.rs @@ -117,7 +117,7 @@ fn is_model_abstract(body: &[Stmt]) -> bool { let Expr::Name(ast::ExprName { id, .. }) = target else { continue; }; - if id != "abstract" { + if id.as_str() != "abstract" { continue; } if !is_const_true(value) { diff --git a/crates/ruff_linter/src/rules/flake8_django/rules/unordered_body_content_in_model.rs b/crates/ruff_linter/src/rules/flake8_django/rules/unordered_body_content_in_model.rs index 01a63d4e342f9a..d061d1a5a55cbe 100644 --- a/crates/ruff_linter/src/rules/flake8_django/rules/unordered_body_content_in_model.rs +++ b/crates/ruff_linter/src/rules/flake8_django/rules/unordered_body_content_in_model.rs @@ -118,7 +118,7 @@ fn get_element_type(element: &Stmt, semantic: &SemanticModel) -> Option bool { if let Expr::Name(ast::ExprName { id, .. }) = func { - functions_names.contains(id) + functions_names.contains(&id.to_string()) } else { false } 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 1bc2bd1cf79239..ebb5946b55b655 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 @@ -47,7 +47,7 @@ pub(crate) fn unnecessary_range_start(checker: &mut Checker, call: &ast::ExprCal let Expr::Name(ast::ExprName { id, .. }) = call.func.as_ref() else { return; }; - if id != "range" { + if id.as_str() != "range" { return; }; if !checker.semantic().is_builtin("range") { diff --git a/crates/ruff_linter/src/rules/flake8_pyi/rules/custom_type_var_return_type.rs b/crates/ruff_linter/src/rules/flake8_pyi/rules/custom_type_var_return_type.rs index da360b76dd715c..7fde6d971c805a 100644 --- a/crates/ruff_linter/src/rules/flake8_pyi/rules/custom_type_var_return_type.rs +++ b/crates/ruff_linter/src/rules/flake8_pyi/rules/custom_type_var_return_type.rs @@ -139,7 +139,7 @@ fn class_method( // Don't error if the first argument is annotated with typing.Type[T]. // These are edge cases, and it's hard to give good error messages for them. - if value.id != "type" { + if value.id.as_str() != "type" { return false; }; @@ -151,7 +151,7 @@ fn class_method( return false; }; - if slice.id != return_annotation.id { + if slice.id.as_str() != return_annotation.id { return false; } diff --git a/crates/ruff_linter/src/rules/flake8_pyi/rules/unnecessary_type_union.rs b/crates/ruff_linter/src/rules/flake8_pyi/rules/unnecessary_type_union.rs index 75ba6ab9bc59fc..6f26b107541b31 100644 --- a/crates/ruff_linter/src/rules/flake8_pyi/rules/unnecessary_type_union.rs +++ b/crates/ruff_linter/src/rules/flake8_pyi/rules/unnecessary_type_union.rs @@ -128,7 +128,7 @@ pub(crate) fn unnecessary_type_union<'a>(checker: &mut Checker, union: &'a Expr) .into_iter() .map(|type_member| { Expr::Name(ast::ExprName { - id: type_member, + id: type_member.into(), ctx: ExprContext::Load, range: TextRange::default(), }) 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 5793c24ae498bc..622a64ce9a5f12 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 @@ -134,7 +134,7 @@ pub(crate) fn unrecognized_platform(checker: &mut Checker, test: &Expr) { if !matches!(value.as_str(), "linux" | "win32" | "cygwin" | "darwin") { checker.diagnostics.push(Diagnostic::new( UnrecognizedPlatformName { - platform: value.clone(), + platform: value.to_string(), }, right.range(), )); diff --git a/crates/ruff_linter/src/rules/flake8_pytest_style/rules/helpers.rs b/crates/ruff_linter/src/rules/flake8_pytest_style/rules/helpers.rs index 43c066ff65e00d..5a726aaa17b936 100644 --- a/crates/ruff_linter/src/rules/flake8_pytest_style/rules/helpers.rs +++ b/crates/ruff_linter/src/rules/flake8_pytest_style/rules/helpers.rs @@ -49,7 +49,7 @@ pub(super) fn keyword_is_literal(keyword: &Keyword, literal: &str) -> bool { .. }) = &keyword.value { - value == literal + value.as_str() == literal } else { false } 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 4ab938ffef5cc1..e5c83fabd9a1d6 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 @@ -1,5 +1,6 @@ use std::hash::BuildHasherDefault; +use compact_str::CompactString; use rustc_hash::FxHashMap; use ruff_diagnostics::{Diagnostic, Edit, Fix, FixAvailability, Violation}; @@ -265,7 +266,7 @@ fn elts_to_csv(elts: &[Expr], generator: Generator) -> Option { let node = Expr::Constant(ast::ExprConstant { value: elts .iter() - .fold(String::new(), |mut acc, elt| { + .fold(CompactString::new(""), |mut acc, elt| { if let Expr::Constant(ast::ExprConstant { value: Constant::Str(ast::StringConstant { value, .. }), .. @@ -341,9 +342,9 @@ fn check_names(checker: &mut Checker, decorator: &Decorator, expr: &Expr) { let node = Expr::Tuple(ast::ExprTuple { elts: names .iter() - .map(|name| { + .map(|&name| { Expr::Constant(ast::ExprConstant { - value: (*name).to_string().into(), + value: name.into(), range: TextRange::default(), }) }) @@ -374,9 +375,9 @@ fn check_names(checker: &mut Checker, decorator: &Decorator, expr: &Expr) { let node = Expr::List(ast::ExprList { elts: names .iter() - .map(|name| { + .map(|&name| { Expr::Constant(ast::ExprConstant { - value: (*name).to_string().into(), + value: name.into(), range: TextRange::default(), }) }) diff --git a/crates/ruff_linter/src/rules/flake8_self/rules/private_member_access.rs b/crates/ruff_linter/src/rules/flake8_self/rules/private_member_access.rs index 543c4d36d73486..22715af6988a6c 100644 --- a/crates/ruff_linter/src/rules/flake8_self/rules/private_member_access.rs +++ b/crates/ruff_linter/src/rules/flake8_self/rules/private_member_access.rs @@ -73,7 +73,7 @@ pub(crate) fn private_member_access(checker: &mut Checker, expr: &Expr) { .settings .flake8_self .ignore_names - .contains(attr.as_ref()) + .contains(&attr.to_string()) { return; } 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 7694dd021cb339..1bfbf6397f6737 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 @@ -323,7 +323,7 @@ fn isinstance_target<'a>(call: &'a Expr, semantic: &'a SemanticModel) -> Option< let Expr::Name(ast::ExprName { id: func_name, .. }) = func.as_ref() else { return None; }; - if func_name != "isinstance" { + if func_name.as_str() != "isinstance" { return None; } if !semantic.is_builtin("isinstance") { diff --git a/crates/ruff_linter/src/rules/flake8_simplify/rules/ast_expr.rs b/crates/ruff_linter/src/rules/flake8_simplify/rules/ast_expr.rs index 511a0e373b9a3f..deef9f7ad9cbc7 100644 --- a/crates/ruff_linter/src/rules/flake8_simplify/rules/ast_expr.rs +++ b/crates/ruff_linter/src/rules/flake8_simplify/rules/ast_expr.rs @@ -171,7 +171,7 @@ pub(crate) fn use_capital_environment_variables(checker: &mut Checker, expr: &Ex checker.diagnostics.push(Diagnostic::new( UncapitalizedEnvironmentVariables { expected: SourceCodeSnippet::new(capital_env_var), - actual: SourceCodeSnippet::new(env_var.clone()), + actual: SourceCodeSnippet::new(env_var.to_string()), }, arg.range(), )); @@ -192,7 +192,7 @@ fn check_os_environ_subscript(checker: &mut Checker, expr: &Expr) { let Expr::Name(ast::ExprName { id, .. }) = attr_value.as_ref() else { return; }; - if id != "os" || attr != "environ" { + if id.as_str() != "os" || attr != "environ" { return; } let Expr::Constant(ast::ExprConstant { @@ -220,13 +220,13 @@ fn check_os_environ_subscript(checker: &mut Checker, expr: &Expr) { let mut diagnostic = Diagnostic::new( UncapitalizedEnvironmentVariables { expected: SourceCodeSnippet::new(capital_env_var.clone()), - actual: SourceCodeSnippet::new(env_var.clone()), + actual: SourceCodeSnippet::new(env_var.to_string()), }, slice.range(), ); let node = ast::ExprConstant { value: ast::Constant::Str(ast::StringConstant { - value: capital_env_var, + value: capital_env_var.into(), unicode: *unicode, implicit_concatenated: false, }), 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 584c8c4182a2ca..1e07adb83ee0a5 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 @@ -258,13 +258,13 @@ fn is_main_check(expr: &Expr) -> bool { }) = expr { if let Expr::Name(ast::ExprName { id, .. }) = left.as_ref() { - if id == "__name__" { + if id.as_str() == "__name__" { if let [Expr::Constant(ast::ExprConstant { value: Constant::Str(ast::StringConstant { value, .. }), .. })] = comparators.as_slice() { - if value == "__main__" { + if value.as_str() == "__main__" { return true; } } 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 f5fc09c2c0d663..16546f9e28c2da 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 @@ -126,7 +126,7 @@ 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.as_str() != target.as_str() || ops != &[CmpOp::Eq] { return; } let [Expr::Constant(ast::ExprConstant { diff --git a/crates/ruff_linter/src/rules/flake8_unused_arguments/helpers.rs b/crates/ruff_linter/src/rules/flake8_unused_arguments/helpers.rs index 5b90db881d8e64..e2d07f7e3ac992 100644 --- a/crates/ruff_linter/src/rules/flake8_unused_arguments/helpers.rs +++ b/crates/ruff_linter/src/rules/flake8_unused_arguments/helpers.rs @@ -21,11 +21,13 @@ fn is_empty_stmt(stmt: &Stmt) -> bool { if let Some(exc) = exc { match exc.as_ref() { Expr::Name(ast::ExprName { id, .. }) => { - return id == "NotImplementedError" || id == "NotImplemented"; + return id.as_str() == "NotImplementedError" + || id.as_str() == "NotImplemented"; } Expr::Call(ast::ExprCall { func, .. }) => { if let Expr::Name(ast::ExprName { id, .. }) = func.as_ref() { - return id == "NotImplementedError" || id == "NotImplemented"; + return id.as_str() == "NotImplementedError" + || id.as_str() == "NotImplemented"; } } _ => {} diff --git a/crates/ruff_linter/src/rules/flynt/helpers.rs b/crates/ruff_linter/src/rules/flynt/helpers.rs index bc2e18197a0a29..7a22f4fd1d73c5 100644 --- a/crates/ruff_linter/src/rules/flynt/helpers.rs +++ b/crates/ruff_linter/src/rules/flynt/helpers.rs @@ -1,3 +1,4 @@ +use compact_str::ToCompactString; use ruff_python_ast::{self as ast, Arguments, Constant, ConversionFlag, Expr}; use ruff_text_size::TextRange; @@ -16,7 +17,7 @@ fn to_formatted_value_expr(inner: &Expr) -> Expr { /// Convert a string to a constant string expression. pub(super) fn to_constant_string(s: &str) -> Expr { let node = ast::ExprConstant { - value: s.to_owned().into(), + value: Constant::Str(s.to_compact_string().into()), range: TextRange::default(), }; node.into() 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 4f4c68c5e7975b..a41df6be0d2b50 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 @@ -1,3 +1,4 @@ +use compact_str::ToCompactString; use itertools::Itertools; use crate::fix::edits::pad; @@ -85,6 +86,7 @@ fn build_fstring(joiner: &str, joinees: &[Expr]) -> Option { } }) .join(joiner) + .to_compact_string() .into(), range: TextRange::default(), }; diff --git a/crates/ruff_linter/src/rules/pandas_vet/rules/assignment_to_df.rs b/crates/ruff_linter/src/rules/pandas_vet/rules/assignment_to_df.rs index bdca4d20317d77..501ba13622ffef 100644 --- a/crates/ruff_linter/src/rules/pandas_vet/rules/assignment_to_df.rs +++ b/crates/ruff_linter/src/rules/pandas_vet/rules/assignment_to_df.rs @@ -45,7 +45,7 @@ pub(crate) fn assignment_to_df(targets: &[Expr]) -> Option { let Expr::Name(ast::ExprName { id, .. }) = target else { return None; }; - if id != "df" { + if id.as_str() != "df" { return None; } Some(Diagnostic::new(PandasDfVariableName, target.range())) diff --git a/crates/ruff_linter/src/rules/pandas_vet/rules/pd_merge.rs b/crates/ruff_linter/src/rules/pandas_vet/rules/pd_merge.rs index 3c2c0eb381aef4..f7ea8b311ab836 100644 --- a/crates/ruff_linter/src/rules/pandas_vet/rules/pd_merge.rs +++ b/crates/ruff_linter/src/rules/pandas_vet/rules/pd_merge.rs @@ -58,7 +58,7 @@ impl Violation for PandasUseOfPdMerge { pub(crate) fn use_of_pd_merge(checker: &mut Checker, func: &Expr) { if let Expr::Attribute(ast::ExprAttribute { attr, value, .. }) = func { if let Expr::Name(ast::ExprName { id, .. }) = value.as_ref() { - if id == "pd" && attr == "merge" { + if id.as_str() == "pd" && attr == "merge" { checker .diagnostics .push(Diagnostic::new(PandasUseOfPdMerge, func.range())); diff --git a/crates/ruff_linter/src/rules/pandas_vet/rules/read_table.rs b/crates/ruff_linter/src/rules/pandas_vet/rules/read_table.rs index 4d4aafb9ee2759..33e77234cee4c3 100644 --- a/crates/ruff_linter/src/rules/pandas_vet/rules/read_table.rs +++ b/crates/ruff_linter/src/rules/pandas_vet/rules/read_table.rs @@ -59,7 +59,7 @@ pub(crate) fn use_of_read_table(checker: &mut Checker, call: &ast::ExprCall) { .find_keyword("sep") .map(|keyword| &keyword.value) { - if value == "," { + if value.as_str() == "," { checker .diagnostics .push(Diagnostic::new(PandasUseOfDotReadTable, call.func.range())); diff --git a/crates/ruff_linter/src/rules/pep8_naming/rules/error_suffix_on_exception_name.rs b/crates/ruff_linter/src/rules/pep8_naming/rules/error_suffix_on_exception_name.rs index 74bb9de5311082..f5f0a1ed9bac04 100644 --- a/crates/ruff_linter/src/rules/pep8_naming/rules/error_suffix_on_exception_name.rs +++ b/crates/ruff_linter/src/rules/pep8_naming/rules/error_suffix_on_exception_name.rs @@ -56,7 +56,7 @@ pub(crate) fn error_suffix_on_exception_name( if !arguments.is_some_and(|arguments| { arguments.args.iter().any(|base| { if let Expr::Name(ast::ExprName { id, .. }) = &base { - id == "Exception" || id.ends_with("Error") + id.as_str() == "Exception" || id.ends_with("Error") } else { false } diff --git a/crates/ruff_linter/src/rules/perflint/rules/manual_dict_comprehension.rs b/crates/ruff_linter/src/rules/perflint/rules/manual_dict_comprehension.rs index 559ba86e1e6e06..ef4104378788d8 100644 --- a/crates/ruff_linter/src/rules/perflint/rules/manual_dict_comprehension.rs +++ b/crates/ruff_linter/src/rules/perflint/rules/manual_dict_comprehension.rs @@ -166,7 +166,7 @@ pub(crate) fn manual_dict_comprehension(checker: &mut Checker, target: &Expr, bo if if_test.is_some_and(|test| { any_over_expr(test, &|expr| { expr.as_name_expr() - .is_some_and(|expr| expr.id == *subscript_name) + .is_some_and(|expr| expr.id.as_str() == *subscript_name) }) }) { 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 bf04777f7934ef..95713b3bf3c31f 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 @@ -124,14 +124,15 @@ pub(crate) fn manual_list_comprehension(checker: &mut Checker, target: &Expr, bo // Ignore direct list copies (e.g., `for x in y: filtered.append(x)`). if if_test.is_none() { - if arg.as_name_expr().is_some_and(|arg| arg.id == *id) { + if arg.as_name_expr().is_some_and(|arg| arg.id.as_str() == *id) { return; } } // Avoid, e.g., `for x in y: filtered[x].append(x * x)`. if any_over_expr(value, &|expr| { - expr.as_name_expr().is_some_and(|expr| expr.id == *id) + expr.as_name_expr() + .is_some_and(|expr| expr.id.as_str() == *id) }) { return; } @@ -180,7 +181,7 @@ pub(crate) fn manual_list_comprehension(checker: &mut Checker, target: &Expr, bo if if_test.is_some_and(|test| { any_over_expr(test, &|expr| { expr.as_name_expr() - .is_some_and(|expr| expr.id == value_name.id) + .is_some_and(|expr| expr.id.as_str() == value_name.id) }) }) { 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 39ad7dc0592f67..07661412037a72 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 @@ -90,13 +90,14 @@ pub(crate) fn manual_list_copy(checker: &mut Checker, target: &Expr, body: &[Stm } // Only flag direct list copies (e.g., `for x in y: filtered.append(x)`). - if !arg.as_name_expr().is_some_and(|arg| arg.id == *id) { + if !arg.as_name_expr().is_some_and(|arg| arg.id.as_str() == *id) { return; } // Avoid, e.g., `for x in y: filtered[x].append(x)`. if any_over_expr(value, &|expr| { - expr.as_name_expr().is_some_and(|expr| expr.id == *id) + expr.as_name_expr() + .is_some_and(|expr| expr.id.as_str() == *id) }) { 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 9769eed8d71e3e..41a17cf41f2f0f 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 @@ -72,7 +72,7 @@ pub(crate) fn unnecessary_list_cast(checker: &mut Checker, iter: &Expr) { return; }; - if !(id == "list" && checker.semantic().is_builtin("list")) { + if !(id.as_str() == "list" && checker.semantic().is_builtin("list")) { return; } diff --git a/crates/ruff_linter/src/rules/pycodestyle/rules/type_comparison.rs b/crates/ruff_linter/src/rules/pycodestyle/rules/type_comparison.rs index 1a7c3a67c7d5c4..4d0265d4fbec15 100644 --- a/crates/ruff_linter/src/rules/pycodestyle/rules/type_comparison.rs +++ b/crates/ruff_linter/src/rules/pycodestyle/rules/type_comparison.rs @@ -80,7 +80,7 @@ fn deprecated_type_comparison(checker: &mut Checker, compare: &ast::ExprCompare) continue; }; - if !(id == "type" && checker.semantic().is_builtin("type")) { + if !(id.as_str() == "type" && checker.semantic().is_builtin("type")) { continue; } @@ -94,7 +94,7 @@ fn deprecated_type_comparison(checker: &mut Checker, compare: &ast::ExprCompare) continue; }; - if id == "type" && checker.semantic().is_builtin("type") { + if id.as_str() == "type" && checker.semantic().is_builtin("type") { // Allow comparison for types which are not obvious. if arguments .args @@ -183,7 +183,7 @@ fn is_type(expr: &Expr, semantic: &SemanticModel) -> bool { return false; }; - if !(id == "type" && semantic.is_builtin("type")) { + if !(id.as_str() == "type" && semantic.is_builtin("type")) { return false; }; diff --git a/crates/ruff_linter/src/rules/pyflakes/cformat.rs b/crates/ruff_linter/src/rules/pyflakes/cformat.rs index 9fccc4788484a4..3f49a92034de20 100644 --- a/crates/ruff_linter/src/rules/pyflakes/cformat.rs +++ b/crates/ruff_linter/src/rules/pyflakes/cformat.rs @@ -73,7 +73,10 @@ mod tests { let literal = "%(foo)s %s %d %(bar)x"; let expected_positional = 2; - let expected_keywords = ["foo", "bar"].into_iter().map(String::from).collect(); + let expected_keywords = ["foo", "bar"] + .into_iter() + .map(ToString::to_string) + .collect(); let format_summary = CFormatSummary::try_from(literal).unwrap(); assert!(!format_summary.starred); diff --git a/crates/ruff_linter/src/rules/pyflakes/rules/invalid_print_syntax.rs b/crates/ruff_linter/src/rules/pyflakes/rules/invalid_print_syntax.rs index 74acdca4031677..8e505ff8a2b92c 100644 --- a/crates/ruff_linter/src/rules/pyflakes/rules/invalid_print_syntax.rs +++ b/crates/ruff_linter/src/rules/pyflakes/rules/invalid_print_syntax.rs @@ -61,7 +61,7 @@ pub(crate) fn invalid_print_syntax(checker: &mut Checker, left: &Expr) { let Expr::Name(ast::ExprName { id, .. }) = &left else { return; }; - if id != "print" { + if id.as_str() != "print" { return; } if !checker.semantic().is_builtin("print") { diff --git a/crates/ruff_linter/src/rules/pyflakes/rules/raise_not_implemented.rs b/crates/ruff_linter/src/rules/pyflakes/rules/raise_not_implemented.rs index 3a48fe902f77c6..3affe9b4deecb0 100644 --- a/crates/ruff_linter/src/rules/pyflakes/rules/raise_not_implemented.rs +++ b/crates/ruff_linter/src/rules/pyflakes/rules/raise_not_implemented.rs @@ -54,13 +54,13 @@ fn match_not_implemented(expr: &Expr) -> Option<&Expr> { match expr { Expr::Call(ast::ExprCall { func, .. }) => { if let Expr::Name(ast::ExprName { id, .. }) = func.as_ref() { - if id == "NotImplemented" { + if id.as_str() == "NotImplemented" { return Some(func); } } } Expr::Name(ast::ExprName { id, .. }) => { - if id == "NotImplemented" { + if id.as_str() == "NotImplemented" { return Some(expr); } } diff --git a/crates/ruff_linter/src/rules/pyflakes/rules/strings.rs b/crates/ruff_linter/src/rules/pyflakes/rules/strings.rs index 317c5692ea289b..4cad2ec0c993fd 100644 --- a/crates/ruff_linter/src/rules/pyflakes/rules/strings.rs +++ b/crates/ruff_linter/src/rules/pyflakes/rules/strings.rs @@ -647,7 +647,7 @@ pub(crate) fn percent_format_missing_arguments( value: Constant::Str(ast::StringConstant { value, .. }), .. }) => { - keywords.insert(value); + keywords.insert(value.to_string()); } _ => { return; // Dynamic keys present @@ -658,7 +658,7 @@ pub(crate) fn percent_format_missing_arguments( let missing: Vec<&String> = summary .keywords .iter() - .filter(|k| !keywords.contains(k)) + .filter(|k| !keywords.contains(k.as_str())) .collect(); if !missing.is_empty() { @@ -753,7 +753,7 @@ pub(crate) fn string_dot_format_extra_named_arguments( let missing: Vec<(usize, &str)> = keywords .enumerate() .filter_map(|(index, keyword)| { - if summary.keywords.contains(keyword.as_ref()) { + if summary.keywords.contains(&keyword.to_string()) { None } else { Some((index, keyword.as_str())) diff --git a/crates/ruff_linter/src/rules/pygrep_hooks/rules/no_eval.rs b/crates/ruff_linter/src/rules/pygrep_hooks/rules/no_eval.rs index a9d49f7689fcc9..54b375387dd371 100644 --- a/crates/ruff_linter/src/rules/pygrep_hooks/rules/no_eval.rs +++ b/crates/ruff_linter/src/rules/pygrep_hooks/rules/no_eval.rs @@ -44,7 +44,7 @@ pub(crate) fn no_eval(checker: &mut Checker, func: &Expr) { let Expr::Name(ast::ExprName { id, .. }) = func else { return; }; - if id != "eval" { + if id.as_str() != "eval" { return; } if !checker.semantic().is_builtin("eval") { 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 ce02b12fff4331..c5790d5370ffc6 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 @@ -54,7 +54,9 @@ pub(crate) fn comparison_with_itself( { match (left, right) { // Ex) `foo == foo` - (Expr::Name(left_name), Expr::Name(right_name)) if left_name.id == right_name.id => { + (Expr::Name(left_name), Expr::Name(right_name)) + if left_name.id.as_str() == right_name.id => + { let actual = format!( "{} {} {}", checker.locator().slice(left), @@ -82,7 +84,7 @@ pub(crate) fn comparison_with_itself( let [Expr::Name(right_right)] = right_call.arguments.args.as_slice() else { continue; }; - if left_arg.id != right_right.id { + if left_arg.id.as_str() != right_right.id { continue; } @@ -93,7 +95,7 @@ pub(crate) fn comparison_with_itself( let Expr::Name(right_func) = right_call.func.as_ref() else { continue; }; - if left_func.id != right_func.id { + if left_func.id.as_str() != right_func.id { continue; } diff --git a/crates/ruff_linter/src/rules/pylint/rules/eq_without_hash.rs b/crates/ruff_linter/src/rules/pylint/rules/eq_without_hash.rs index 8add44f2c2f37d..c5d29df2bbe153 100644 --- a/crates/ruff_linter/src/rules/pylint/rules/eq_without_hash.rs +++ b/crates/ruff_linter/src/rules/pylint/rules/eq_without_hash.rs @@ -80,7 +80,7 @@ fn has_eq_without_hash(body: &[Stmt]) -> bool { // // __hash__ = None // ``` - if id == "__hash__" && is_const_none(value) { + if id.as_str() == "__hash__" && is_const_none(value) { has_hash = true; } } diff --git a/crates/ruff_linter/src/rules/pylint/rules/property_with_parameters.rs b/crates/ruff_linter/src/rules/pylint/rules/property_with_parameters.rs index 42a7db35d28b97..6fa4555ebf4ff3 100644 --- a/crates/ruff_linter/src/rules/pylint/rules/property_with_parameters.rs +++ b/crates/ruff_linter/src/rules/pylint/rules/property_with_parameters.rs @@ -55,7 +55,7 @@ pub(crate) fn property_with_parameters( ) { if !decorator_list .iter() - .any(|decorator| matches!(&decorator.expression, Expr::Name(ast::ExprName { id, .. }) if id == "property")) + .any(|decorator| matches!(&decorator.expression, Expr::Name(ast::ExprName { id, .. }) if id.as_str() == "property")) { return; } diff --git a/crates/ruff_linter/src/rules/pylint/rules/repeated_isinstance_calls.rs b/crates/ruff_linter/src/rules/pylint/rules/repeated_isinstance_calls.rs index 4ede23df5ca3d4..8b96b60863118a 100644 --- a/crates/ruff_linter/src/rules/pylint/rules/repeated_isinstance_calls.rs +++ b/crates/ruff_linter/src/rules/pylint/rules/repeated_isinstance_calls.rs @@ -92,7 +92,8 @@ pub(crate) fn repeated_isinstance_calls( else { continue; }; - if !matches!(func.as_ref(), Expr::Name(ast::ExprName { id, .. }) if id == "isinstance") { + if !matches!(func.as_ref(), Expr::Name(ast::ExprName { id, .. }) if id.as_str() == "isinstance") + { continue; } let [obj, types] = &args[..] else { diff --git a/crates/ruff_linter/src/rules/pylint/rules/type_param_name_mismatch.rs b/crates/ruff_linter/src/rules/pylint/rules/type_param_name_mismatch.rs index a3afd61505e34b..2edaa11c50cf24 100644 --- a/crates/ruff_linter/src/rules/pylint/rules/type_param_name_mismatch.rs +++ b/crates/ruff_linter/src/rules/pylint/rules/type_param_name_mismatch.rs @@ -78,7 +78,7 @@ pub(crate) fn type_param_name_mismatch(checker: &mut Checker, value: &Expr, targ return; }; - if var_name == param_name { + if var_name.as_str() == param_name { return; } 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 462ea9ceab71a3..b31774dfc411e1 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 @@ -195,7 +195,7 @@ fn fields_from_dict_literal(keys: &[Option], values: &[Expr]) -> Option Option> { let ast::ExprName { id, .. } = func.as_name_expr()?; - if id != "dict" { + if id.as_str() != "dict" { return None; } diff --git a/crates/ruff_linter/src/rules/pyupgrade/rules/deprecated_unittest_alias.rs b/crates/ruff_linter/src/rules/pyupgrade/rules/deprecated_unittest_alias.rs index 58250d43a2b158..5e55597a74ffe9 100644 --- a/crates/ruff_linter/src/rules/pyupgrade/rules/deprecated_unittest_alias.rs +++ b/crates/ruff_linter/src/rules/pyupgrade/rules/deprecated_unittest_alias.rs @@ -88,7 +88,7 @@ pub(crate) fn deprecated_unittest_alias(checker: &mut Checker, expr: &Expr) { let Expr::Name(ast::ExprName { id, .. }) = value.as_ref() else { return; }; - if id != "self" { + if id.as_str() != "self" { return; } let mut diagnostic = Diagnostic::new( diff --git a/crates/ruff_linter/src/rules/pyupgrade/rules/native_literals.rs b/crates/ruff_linter/src/rules/pyupgrade/rules/native_literals.rs index 7f672851442aa7..2917d695a0a16c 100644 --- a/crates/ruff_linter/src/rules/pyupgrade/rules/native_literals.rs +++ b/crates/ruff_linter/src/rules/pyupgrade/rules/native_literals.rs @@ -36,7 +36,7 @@ impl From for Constant { fn from(value: LiteralType) -> Self { match value { LiteralType::Str => Constant::Str(ast::StringConstant { - value: String::new(), + value: "".into(), unicode: false, implicit_concatenated: false, }), 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 c8af446f4adcf7..ce5d10aa4bb040 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 @@ -120,7 +120,9 @@ pub(crate) fn super_call_with_parameters(checker: &mut Checker, call: &ast::Expr return; }; - if !(first_arg_id == parent_name.as_str() && second_arg_id == parent_arg.as_str()) { + if !(first_arg_id.as_str() == parent_name.as_str() + && second_arg_id.as_str() == parent_arg.as_str()) + { return; } @@ -137,7 +139,7 @@ pub(crate) fn super_call_with_parameters(checker: &mut Checker, call: &ast::Expr /// Returns `true` if a call is an argumented `super` invocation. fn is_super_call_with_arguments(call: &ast::ExprCall) -> bool { if let Expr::Name(ast::ExprName { id, .. }) = call.func.as_ref() { - id == "super" && !call.arguments.is_empty() + id.as_str() == "super" && !call.arguments.is_empty() } else { false } diff --git a/crates/ruff_linter/src/rules/pyupgrade/rules/use_pep695_type_alias.rs b/crates/ruff_linter/src/rules/pyupgrade/rules/use_pep695_type_alias.rs index 4e81b2e961deb3..9cf797d3adb3c3 100644 --- a/crates/ruff_linter/src/rules/pyupgrade/rules/use_pep695_type_alias.rs +++ b/crates/ruff_linter/src/rules/pyupgrade/rules/use_pep695_type_alias.rs @@ -93,7 +93,12 @@ pub(crate) fn non_pep695_type_alias(checker: &mut Checker, stmt: &StmtAnnAssign) // TODO(zanie): We should check for generic type variables used in the value and define them // as type params instead - let mut diagnostic = Diagnostic::new(NonPEP695TypeAlias { name: name.clone() }, stmt.range()); + let mut diagnostic = Diagnostic::new( + NonPEP695TypeAlias { + name: name.to_string(), + }, + stmt.range(), + ); let mut visitor = TypeVarReferenceVisitor { vars: vec![], semantic: checker.semantic(), diff --git a/crates/ruff_linter/src/rules/pyupgrade/rules/useless_metaclass_type.rs b/crates/ruff_linter/src/rules/pyupgrade/rules/useless_metaclass_type.rs index 612c94644cd8aa..b4cfbe03bba3ac 100644 --- a/crates/ruff_linter/src/rules/pyupgrade/rules/useless_metaclass_type.rs +++ b/crates/ruff_linter/src/rules/pyupgrade/rules/useless_metaclass_type.rs @@ -51,13 +51,13 @@ pub(crate) fn useless_metaclass_type( let [Expr::Name(ast::ExprName { id, .. })] = targets else { return; }; - if id != "__metaclass__" { + if id.as_str() != "__metaclass__" { return; } let Expr::Name(ast::ExprName { id, .. }) = value else { return; }; - if id != "type" { + if id.as_str() != "type" { return; } 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 83f9a417e8c6c5..65b2540480d714 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 @@ -54,7 +54,7 @@ pub(crate) fn useless_object_inheritance(checker: &mut Checker, class_def: &ast: let Expr::Name(ast::ExprName { id, .. }) = base else { continue; }; - if id != "object" { + if id.as_str() != "object" { continue; } if !checker.semantic().is_builtin("object") { diff --git a/crates/ruff_linter/src/rules/pyupgrade/rules/yield_in_for_loop.rs b/crates/ruff_linter/src/rules/pyupgrade/rules/yield_in_for_loop.rs index 6325cc9fd2b2f0..c1b23b42c48a7b 100644 --- a/crates/ruff_linter/src/rules/pyupgrade/rules/yield_in_for_loop.rs +++ b/crates/ruff_linter/src/rules/pyupgrade/rules/yield_in_for_loop.rs @@ -123,7 +123,7 @@ pub(crate) fn yield_in_for_loop(checker: &mut Checker, stmt_for: &ast::StmtFor) /// of tuples and names. fn is_same_expr(left: &Expr, right: &Expr) -> bool { match (&left, &right) { - (Expr::Name(left), Expr::Name(right)) => left.id == right.id, + (Expr::Name(left), Expr::Name(right)) => left.id.as_str() == right.id, (Expr::Tuple(left), Expr::Tuple(right)) => { left.elts.len() == right.elts.len() && left diff --git a/crates/ruff_linter/src/rules/refurb/helpers.rs b/crates/ruff_linter/src/rules/refurb/helpers.rs index e432d5b7b8a7f2..f9fe2b90f00472 100644 --- a/crates/ruff_linter/src/rules/refurb/helpers.rs +++ b/crates/ruff_linter/src/rules/refurb/helpers.rs @@ -6,14 +6,14 @@ use ruff_text_size::TextRange; pub(super) fn generate_method_call(name: &str, method: &str, generator: Generator) -> String { // Construct `name`. let var = ast::ExprName { - id: name.to_string(), + id: name.into(), ctx: ast::ExprContext::Load, range: TextRange::default(), }; // Construct `name.method`. let attr = ast::ExprAttribute { value: Box::new(var.into()), - attr: ast::Identifier::new(method.to_string(), TextRange::default()), + attr: ast::Identifier::new(method, TextRange::default()), ctx: ast::ExprContext::Load, range: TextRange::default(), }; 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 083c9a05e09635..ef3c4954a1d5e6 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 @@ -85,7 +85,7 @@ pub(crate) fn check_and_remove_from_set(checker: &mut Checker, if_stmt: &ast::St // ` // `set` in the check should be the same as `set` in the body - if check_set.id != remove_set.id + if check_set.id.as_str() !=remove_set.id // `element` in the check should be the same as `element` in the body || !compare(&check_element.into(), &remove_element.into()) // `element` shouldn't have a side effect, otherwise we might change the semantics of the program. 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 49a6bce3f3246a..b60a5656602d23 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 @@ -141,7 +141,7 @@ fn find_file_open<'a>( .. } = item.context_expr.as_call_expr()?; - if func.as_name_expr()?.id != "open" { + if func.as_name_expr()?.id.as_str() != "open" { return None; } @@ -319,7 +319,7 @@ fn make_suggestion(open: &FileOpen<'_>, generator: Generator) -> SourceCodeSnipp ReadMode::Bytes => "read_bytes", }; let name = ast::ExprName { - id: method_name.to_string(), + id: method_name.into(), ctx: ast::ExprContext::Load, range: TextRange::default(), }; 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 8f380a187b9520..b53b0dcf077e4d 100644 --- a/crates/ruff_linter/src/rules/refurb/rules/reimplemented_starmap.rs +++ b/crates/ruff_linter/src/rules/refurb/rules/reimplemented_starmap.rs @@ -297,7 +297,7 @@ fn try_construct_call( /// Construct the call to `itertools.starmap` for suggestion. fn construct_starmap_call(starmap_binding: String, iter: &Expr, func: &Expr) -> ast::ExprCall { let starmap = ast::ExprName { - id: starmap_binding, + id: starmap_binding.into(), ctx: ast::ExprContext::Load, range: TextRange::default(), }; @@ -315,7 +315,7 @@ fn construct_starmap_call(starmap_binding: String, iter: &Expr, func: &Expr) -> /// Wrap given function call with yet another call. fn wrap_with_call_to(call: ast::ExprCall, func_name: &str) -> ast::ExprCall { let name = ast::ExprName { - id: func_name.to_string(), + id: func_name.into(), ctx: ast::ExprContext::Load, range: TextRange::default(), }; 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 b5652ec02b0be8..c6e879aefb8900 100644 --- a/crates/ruff_linter/src/rules/refurb/rules/unnecessary_enumerate.rs +++ b/crates/ruff_linter/src/rules/refurb/rules/unnecessary_enumerate.rs @@ -106,7 +106,7 @@ pub(crate) fn unnecessary_enumerate(checker: &mut Checker, stmt_for: &ast::StmtF let Expr::Name(ast::ExprName { id, .. }) = func.as_ref() else { return; }; - if id != "enumerate" { + if id.as_str() != "enumerate" { return; }; if !checker.semantic().is_builtin("enumerate") { @@ -138,7 +138,7 @@ pub(crate) fn unnecessary_enumerate(checker: &mut Checker, stmt_for: &ast::StmtF ); // The index is unused, so replace with `for value in sequence`. - let replace_iter = Edit::range_replacement(sequence.into(), stmt_for.iter.range()); + let replace_iter = Edit::range_replacement(sequence.to_string(), stmt_for.iter.range()); let replace_target = Edit::range_replacement( pad( checker.locator().slice(value).to_string(), @@ -236,7 +236,7 @@ impl fmt::Display for EnumerateSubset { fn generate_range_len_call(name: &str, generator: Generator) -> String { // Construct `name`. let var = ast::ExprName { - id: name.to_string(), + id: name.into(), ctx: ast::ExprContext::Load, range: TextRange::default(), }; @@ -244,7 +244,7 @@ fn generate_range_len_call(name: &str, generator: Generator) -> String { let len = ast::ExprCall { func: Box::new( ast::ExprName { - id: "len".to_string(), + id: "len".into(), ctx: ast::ExprContext::Load, range: TextRange::default(), } @@ -261,7 +261,7 @@ fn generate_range_len_call(name: &str, generator: Generator) -> String { let range = ast::ExprCall { func: Box::new( ast::ExprName { - id: "range".to_string(), + id: "range".into(), ctx: ast::ExprContext::Load, range: TextRange::default(), } diff --git a/crates/ruff_linter/src/rules/ruff/rules/implicit_optional.rs b/crates/ruff_linter/src/rules/ruff/rules/implicit_optional.rs index 287ee0fbc10527..72e21125e1a449 100644 --- a/crates/ruff_linter/src/rules/ruff/rules/implicit_optional.rs +++ b/crates/ruff_linter/src/rules/ruff/rules/implicit_optional.rs @@ -148,7 +148,7 @@ fn generate_fix(checker: &Checker, conversion_type: ConversionType, expr: &Expr) let new_expr = Expr::Subscript(ast::ExprSubscript { range: TextRange::default(), value: Box::new(Expr::Name(ast::ExprName { - id: binding, + id: binding.into(), ctx: ast::ExprContext::Store, range: TextRange::default(), })), diff --git a/crates/ruff_linter/src/rules/ruff/rules/pairwise_over_zipped.rs b/crates/ruff_linter/src/rules/ruff/rules/pairwise_over_zipped.rs index c6f1de26f1f83a..3e97dd215f4a49 100644 --- a/crates/ruff_linter/src/rules/ruff/rules/pairwise_over_zipped.rs +++ b/crates/ruff_linter/src/rules/ruff/rules/pairwise_over_zipped.rs @@ -111,7 +111,7 @@ pub(crate) fn pairwise_over_zipped(checker: &mut Checker, func: &Expr, args: &[E }; // Require the function to be the builtin `zip`. - if !(id == "zip" && checker.semantic().is_builtin(id)) { + if !(id.as_str() == "zip" && checker.semantic().is_builtin(id)) { return; } @@ -138,7 +138,7 @@ pub(crate) fn pairwise_over_zipped(checker: &mut Checker, func: &Expr, args: &[E }; // Verify that the arguments match the same name. - if first_arg_info.id != second_arg_info.id { + if first_arg_info.id.as_str() != second_arg_info.id { return; } diff --git a/crates/ruff_linter/src/rules/ruff/rules/quadratic_list_summation.rs b/crates/ruff_linter/src/rules/ruff/rules/quadratic_list_summation.rs index 67de3f48eeff5f..9d6712c4398d34 100644 --- a/crates/ruff_linter/src/rules/ruff/rules/quadratic_list_summation.rs +++ b/crates/ruff_linter/src/rules/ruff/rules/quadratic_list_summation.rs @@ -124,7 +124,7 @@ fn func_is_builtin(func: &Expr, name: &str, semantic: &SemanticModel) -> bool { let Expr::Name(ast::ExprName { id, .. }) = func else { return false; }; - id == name && semantic.is_builtin(id) + id.as_str() == name && semantic.is_builtin(id) } /// Returns `true` if the `start` argument to a `sum()` call is an empty list. 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 fc5b0a88b2ee5e..7485a14ca172c7 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 @@ -253,7 +253,7 @@ fn match_simple_comprehension(elt: &Expr, generators: &[Comprehension]) -> Optio // Verify that the generator is, e.g. `i for i in x`, as opposed to `i for j in x`. let elt = elt.as_name_expr()?; let target = generator.target.as_name_expr()?; - if elt.id != target.id { + if elt.id.as_str() != target.id { return None; } diff --git a/crates/ruff_linter/src/rules/tryceratops/rules/useless_try_except.rs b/crates/ruff_linter/src/rules/tryceratops/rules/useless_try_except.rs index 755f849bc95223..c83cfc85b0eae3 100644 --- a/crates/ruff_linter/src/rules/tryceratops/rules/useless_try_except.rs +++ b/crates/ruff_linter/src/rules/tryceratops/rules/useless_try_except.rs @@ -54,7 +54,10 @@ pub(crate) fn useless_try_except(checker: &mut Checker, handlers: &[ExceptHandle if let Some(expr) = exc { // E.g., `except ... as e: raise e` if let Expr::Name(ast::ExprName { id, .. }) = expr.as_ref() { - if name.as_ref().is_some_and(|name| name.as_str() == id) { + if name + .as_ref() + .is_some_and(|name| name.as_str() == id.as_str()) + { return Some(Diagnostic::new(UselessTryExcept, handler.range())); } } diff --git a/crates/ruff_linter/src/rules/tryceratops/rules/verbose_log_message.rs b/crates/ruff_linter/src/rules/tryceratops/rules/verbose_log_message.rs index 8b3fad0f082d93..43351d94856438 100644 --- a/crates/ruff_linter/src/rules/tryceratops/rules/verbose_log_message.rs +++ b/crates/ruff_linter/src/rules/tryceratops/rules/verbose_log_message.rs @@ -88,7 +88,7 @@ pub(crate) fn verbose_log_message(checker: &mut Checker, handlers: &[ExceptHandl names }; for expr in names { - if expr.id == target.as_str() { + if expr.id.as_str() == target.as_str() { checker .diagnostics .push(Diagnostic::new(VerboseLogMessage, expr.range())); diff --git a/crates/ruff_linter/src/rules/tryceratops/rules/verbose_raise.rs b/crates/ruff_linter/src/rules/tryceratops/rules/verbose_raise.rs index bfe623a0a03815..16d02e46cec067 100644 --- a/crates/ruff_linter/src/rules/tryceratops/rules/verbose_raise.rs +++ b/crates/ruff_linter/src/rules/tryceratops/rules/verbose_raise.rs @@ -93,7 +93,7 @@ pub(crate) fn verbose_raise(checker: &mut Checker, handlers: &[ExceptHandler]) { if let Some(exc) = raise.exc.as_ref() { // ...and the raised object is bound to the same name... if let Expr::Name(ast::ExprName { id, .. }) = exc.as_ref() { - if id == exception_name.as_str() { + if id.as_str() == exception_name.as_str() { let mut diagnostic = Diagnostic::new(VerboseRaise, exc.range()); diagnostic.set_fix(Fix::unsafe_edit(Edit::range_replacement( "raise".to_string(), diff --git a/crates/ruff_python_ast/Cargo.toml b/crates/ruff_python_ast/Cargo.toml index c35a54bb5a58fe..12341f4e0c17a6 100644 --- a/crates/ruff_python_ast/Cargo.toml +++ b/crates/ruff_python_ast/Cargo.toml @@ -18,6 +18,7 @@ ruff_source_file = { path = "../ruff_source_file" } ruff_text_size = { path = "../ruff_text_size" } bitflags = { workspace = true } +compact_str = { workspace = true } is-macro = { workspace = true } itertools = { workspace = true } memchr = { workspace = true } diff --git a/crates/ruff_python_ast/src/all.rs b/crates/ruff_python_ast/src/all.rs index bd0bd66d04a7fa..12ab5ef0c067e3 100644 --- a/crates/ruff_python_ast/src/all.rs +++ b/crates/ruff_python_ast/src/all.rs @@ -52,7 +52,7 @@ where } Expr::Name(ast::ExprName { id, .. }) => { // Ex) `__all__ = __all__ + multiprocessing.__all__` - if id == "__all__" { + if id.as_str() == "__all__" { return (None, DunderAllFlags::empty()); } } diff --git a/crates/ruff_python_ast/src/helpers.rs b/crates/ruff_python_ast/src/helpers.rs index 4bd66427f8311c..28975203ae2352 100644 --- a/crates/ruff_python_ast/src/helpers.rs +++ b/crates/ruff_python_ast/src/helpers.rs @@ -1241,7 +1241,7 @@ mod tests { fn any_over_stmt_type_alias() { let seen = RefCell::new(Vec::new()); let name = Expr::Name(ExprName { - id: "x".to_string(), + id: "x".into(), range: TextRange::default(), ctx: ExprContext::Load, }); diff --git a/crates/ruff_python_ast/src/nodes.rs b/crates/ruff_python_ast/src/nodes.rs index 172ba5a93b90f6..36f8a31eb513b6 100644 --- a/crates/ruff_python_ast/src/nodes.rs +++ b/crates/ruff_python_ast/src/nodes.rs @@ -1,5 +1,6 @@ #![allow(clippy::derive_partial_eq_without_eq)] +use compact_str::{CompactString, ToCompactString}; use itertools::Itertools; use std::fmt; @@ -156,7 +157,7 @@ pub enum Stmt { pub struct StmtIpyEscapeCommand { pub range: TextRange, pub kind: IpyEscapeKind, - pub value: String, + pub value: CompactString, } impl From for Stmt { @@ -628,7 +629,7 @@ pub enum Expr { pub struct ExprIpyEscapeCommand { pub range: TextRange, pub kind: IpyEscapeKind, - pub value: String, + pub value: CompactString, } impl From for Expr { @@ -921,9 +922,9 @@ impl ConversionFlag { #[derive(Clone, Debug, PartialEq, Eq, Hash)] pub struct DebugText { /// The text between the `{` and the expression node. - pub leading: String, + pub leading: CompactString, /// The text between the expression and the conversion, the format_spec, or the `}`, depending on what's present in the source - pub trailing: String, + pub trailing: CompactString, } /// See also [JoinedStr](https://docs.python.org/3/library/ast.html#ast.JoinedStr) @@ -1002,7 +1003,7 @@ impl From for Expr { #[derive(Clone, Debug, PartialEq)] pub struct ExprName { pub range: TextRange, - pub id: String, + pub id: CompactString, pub ctx: ExprContext, } @@ -2502,13 +2503,13 @@ impl IpyEscapeKind { #[derive(Clone, Debug, PartialEq, Eq, Hash)] pub struct Identifier { - id: String, + id: CompactString, range: TextRange, } impl Identifier { #[inline] - pub fn new(id: impl Into, range: TextRange) -> Self { + pub fn new(id: impl Into, range: TextRange) -> Self { Self { id: id.into(), range, @@ -2526,14 +2527,14 @@ impl Identifier { impl PartialEq for Identifier { #[inline] fn eq(&self, other: &str) -> bool { - self.id == other + self.id.as_str() == other } } impl PartialEq for Identifier { #[inline] fn eq(&self, other: &String) -> bool { - &self.id == other + self.id.as_str() == other } } @@ -2552,9 +2553,9 @@ impl AsRef for Identifier { } } -impl AsRef for Identifier { +impl AsRef for Identifier { #[inline] - fn as_ref(&self) -> &String { + fn as_ref(&self) -> &CompactString { &self.id } } @@ -2565,9 +2566,9 @@ impl std::fmt::Display for Identifier { } } -impl From for String { +impl From for CompactString { #[inline] - fn from(identifier: Identifier) -> String { + fn from(identifier: Identifier) -> CompactString { identifier.id } } @@ -2614,7 +2615,7 @@ impl Constant { pub struct StringConstant { /// The string value as resolved by the parser (i.e., without quotes, or escape sequences, or /// implicit concatenations). - pub value: String, + pub value: CompactString, /// Whether the string is a Unicode string (i.e., `u"..."`). pub unicode: bool, /// Whether the string contains multiple string tokens that were implicitly concatenated. @@ -2628,10 +2629,20 @@ impl Deref for StringConstant { } } +impl From for StringConstant { + fn from(value: CompactString) -> StringConstant { + Self { + value, + unicode: false, + implicit_concatenated: false, + } + } +} + impl From for StringConstant { fn from(value: String) -> StringConstant { Self { - value, + value: value.into(), unicode: false, implicit_concatenated: false, } @@ -2671,8 +2682,15 @@ impl From> for Constant { }) } } -impl From for Constant { - fn from(value: String) -> Constant { + +impl From<&str> for Constant { + fn from(value: &str) -> Self { + Self::from(value.to_compact_string()) + } +} + +impl From for Constant { + fn from(value: CompactString) -> Constant { Self::Str(StringConstant { value, unicode: false, diff --git a/crates/ruff_python_parser/Cargo.toml b/crates/ruff_python_parser/Cargo.toml index 46a97eabd43c57..eca00fa4806d62 100644 --- a/crates/ruff_python_parser/Cargo.toml +++ b/crates/ruff_python_parser/Cargo.toml @@ -19,6 +19,7 @@ ruff_text_size = { path = "../ruff_text_size" } anyhow = { workspace = true } bitflags = { workspace = true } +compact_str = { workspace = true } is-macro = { workspace = true } itertools = { workspace = true } lalrpop-util = { version = "0.20.0", default-features = false } diff --git a/crates/ruff_python_parser/src/lexer.rs b/crates/ruff_python_parser/src/lexer.rs index d66dbb9534fdfc..3ee79a78064f41 100644 --- a/crates/ruff_python_parser/src/lexer.rs +++ b/crates/ruff_python_parser/src/lexer.rs @@ -31,6 +31,7 @@ use std::iter::FusedIterator; use std::{char, cmp::Ordering, str::FromStr}; +use compact_str::CompactString; use unicode_ident::{is_xid_continue, is_xid_start}; use ruff_python_ast::{Int, IpyEscapeKind}; @@ -239,11 +240,7 @@ impl<'source> Lexer<'source> { "while" => Tok::While, "with" => Tok::With, "yield" => Tok::Yield, - _ => { - return Ok(Tok::Name { - name: text.to_string(), - }) - } + _ => return Ok(Tok::Name { name: text.into() }), }; Ok(keyword) @@ -299,7 +296,7 @@ impl<'source> Lexer<'source> { debug_assert!(self.cursor.previous().is_ascii_digit() || self.cursor.previous() == '.'); let start_is_zero = first_digit_or_dot == '0'; - let mut number = LexedText::new(self.token_start(), self.source); + let mut number: LexedText<'_> = LexedText::new(self.token_start(), self.source); if first_digit_or_dot != '.' { number.push(first_digit_or_dot); self.radix_run(&mut number, Radix::Decimal); @@ -407,30 +404,16 @@ impl<'source> Lexer<'source> { #[cfg(debug_assertions)] debug_assert_eq!(self.cursor.previous(), '#'); - #[cfg(any( - target_arch = "x86_64", - target_arch = "aarch64", - target_arch = "wasm32" - ))] - { - let bytes = self.cursor.rest().as_bytes(); - let offset = memchr::memchr2(b'\n', b'\r', bytes).unwrap_or(bytes.len()); - self.cursor.skip_bytes(offset); - } - - #[cfg(not(any( - target_arch = "x86_64", - target_arch = "aarch64", - target_arch = "wasm32" - )))] - self.cursor.eat_while(|c| !matches!(c, '\n' | '\r')); + let bytes = self.cursor.rest().as_bytes(); + let offset = memchr::memchr2(b'\n', b'\r', bytes).unwrap_or(bytes.len()); + self.cursor.skip_bytes(offset); - Tok::Comment(self.token_text().to_string()) + Tok::Comment(CompactString::new(self.token_text())) } /// Lex a single IPython escape command. fn lex_ipython_escape_command(&mut self, escape_kind: IpyEscapeKind) -> Tok { - let mut value = String::new(); + let mut value = CompactString::new(""); loop { match self.cursor.first() { @@ -508,7 +491,7 @@ impl<'source> Lexer<'source> { // // For example, `??foo?` is recognized as `IpyEscapeKind::Help` and // `value` is `foo` instead of `??foo`. - value = value.trim_start_matches([' ', '?']).to_string(); + value = value.trim_start_matches([' ', '?']).into(); } else if escape_kind.is_magic() { // Between `%` and `?` (at the end), the `?` takes priority // over the `%` so `%foo?` is recognized as `IpyEscapeKind::Help` @@ -577,7 +560,7 @@ impl<'source> Lexer<'source> { // We have to decode `{{` and `}}` into `{` and `}` respectively. As an // optimization, we only allocate a new string we find any escaped curly braces, // otherwise this string will remain empty and we'll use a source slice instead. - let mut normalized = String::new(); + let mut normalized = CompactString::new(""); // Tracks the last offset of token value that has been written to `normalized`. let mut last_offset = self.offset(); @@ -681,7 +664,7 @@ impl<'source> Lexer<'source> { } let value = if normalized.is_empty() { - self.source[range].to_string() + self.source[range].into() } else { normalized.push_str(&self.source[TextRange::new(last_offset, self.offset())]); normalized @@ -773,7 +756,7 @@ impl<'source> Lexer<'source> { }; let tok = Tok::String { - value: self.source[TextRange::new(value_start, value_end)].to_string(), + value: self.source[TextRange::new(value_start, value_end)].into(), kind, triple_quoted, }; diff --git a/crates/ruff_python_parser/src/python.lalrpop b/crates/ruff_python_parser/src/python.lalrpop index a0a19f9305ea7e..92824a35313169 100644 --- a/crates/ruff_python_parser/src/python.lalrpop +++ b/crates/ruff_python_parser/src/python.lalrpop @@ -15,6 +15,7 @@ use crate::{ token::{self, StringKind}, }; use lalrpop_util::ParseError; +use compact_str::CompactString; grammar(source_code: &str, mode: Mode); @@ -371,7 +372,7 @@ IpyHelpEndEscapeCommandStatement: ast::Stmt = { // between the expression and the suffix while the IPython implementation doesn't allow it. // For example, `foo ?` would be valid in our case but invalid from IPython. > =>? { - fn unparse_expr(expr: &ast::Expr, buffer: &mut String) -> Result<(), LexicalError> { + fn unparse_expr(expr: &ast::Expr, buffer: &mut CompactString) -> Result<(), LexicalError> { match expr { ast::Expr::Name(ast::ExprName { id, .. }) => { buffer.push_str(id.as_str()); @@ -425,7 +426,7 @@ IpyHelpEndEscapeCommandStatement: ast::Stmt = { } }; - let mut value = String::new(); + let mut value = CompactString::new(""); unparse_expr(&e.into(), &mut value)?; Ok(ast::Stmt::IpyEscapeCommand( @@ -1634,8 +1635,8 @@ FStringReplacementField: ast::Expr = { ) }; ast::DebugText { - leading: source_code[TextRange::new(start_offset, value.range().start())].to_string(), - trailing: source_code[TextRange::new(value.range().end(), end_offset)].to_string(), + leading: source_code[TextRange::new(start_offset, value.range().start())].into(), + trailing: source_code[TextRange::new(value.range().end(), end_offset)].into(), } }); Ok( @@ -2044,18 +2045,18 @@ extern { float => token::Tok::Float { value: }, complex => token::Tok::Complex { real: , imag: }, string => token::Tok::String { - value: , + value: , kind: , triple_quoted: }, fstring_middle => token::Tok::FStringMiddle { - value: , + value: , is_raw: }, - name => token::Tok::Name { name: }, + name => token::Tok::Name { name: }, ipy_escape_command => token::Tok::IpyEscapeCommand { kind: , - value: + value: }, "\n" => token::Tok::Newline, ";" => token::Tok::Semi, diff --git a/crates/ruff_python_parser/src/python.rs b/crates/ruff_python_parser/src/python.rs index e53ba26da7a23b..6e7182a726ee5e 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: 01c7c57ce067fcf07c9a5450511cc48a2dd08cf821a5ff3b0f649e87d3c67022 +// sha3: 313a691d5a2867b72c354eab77ec93806cd5dc6e4e83ee18ac9d7f15f8cd282c use ruff_text_size::{Ranged, TextLen, TextRange, TextSize}; use ruff_python_ast::{self as ast, Int, IpyEscapeKind}; use crate::{ @@ -12,6 +12,7 @@ use crate::{ token::{self, StringKind}, }; use lalrpop_util::ParseError; +use compact_str::CompactString; #[allow(unused_extern_crates)] extern crate lalrpop_util as __lalrpop_util; #[allow(unused_imports)] @@ -35,6 +36,7 @@ mod __parse__Top { token::{self, StringKind}, }; use lalrpop_util::ParseError; + use compact_str::CompactString; #[allow(unused_extern_crates)] extern crate lalrpop_util as __lalrpop_util; #[allow(unused_imports)] @@ -48,11 +50,11 @@ mod __parse__Top { Variant0(token::Tok), Variant1((f64, f64)), Variant2(f64), - Variant3((String, bool)), + Variant3((CompactString, bool)), Variant4(Int), - Variant5((IpyEscapeKind, String)), - Variant6(String), - Variant7((String, StringKind, bool)), + Variant5((IpyEscapeKind, CompactString)), + Variant6(CompactString), + Variant7((CompactString, StringKind, bool)), Variant8(core::option::Option), Variant9(Option>), Variant10(core::option::Option>>), @@ -146,7 +148,7 @@ mod __parse__Top { Variant98(ast::TypeParams), Variant99(core::option::Option), Variant100(ast::UnaryOp), - Variant101(core::option::Option<(String, bool)>), + Variant101(core::option::Option<(CompactString, bool)>), } const __ACTION: &[i16] = &[ // State 0 @@ -18237,73 +18239,73 @@ mod __parse__Top { fn __symbol_type_mismatch() -> ! { panic!("symbol type mismatch") } - fn __pop_Variant5< + fn __pop_Variant7< >( __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)> - ) -> (TextSize, (IpyEscapeKind, String), TextSize) + ) -> (TextSize, (CompactString, StringKind, bool), TextSize) { match __symbols.pop() { - Some((__l, __Symbol::Variant5(__v), __r)) => (__l, __v, __r), + Some((__l, __Symbol::Variant7(__v), __r)) => (__l, __v, __r), _ => __symbol_type_mismatch() } } - fn __pop_Variant31< + fn __pop_Variant3< >( __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)> - ) -> (TextSize, (Option<(TextSize, TextSize, Option)>, ast::Expr), TextSize) + ) -> (TextSize, (CompactString, bool), TextSize) { match __symbols.pop() { - Some((__l, __Symbol::Variant31(__v), __r)) => (__l, __v, __r), + Some((__l, __Symbol::Variant3(__v), __r)) => (__l, __v, __r), _ => __symbol_type_mismatch() } } - fn __pop_Variant13< + fn __pop_Variant5< >( __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)> - ) -> (TextSize, (Option>, Vec, Option>), TextSize) + ) -> (TextSize, (IpyEscapeKind, CompactString), TextSize) { match __symbols.pop() { - Some((__l, __Symbol::Variant13(__v), __r)) => (__l, __v, __r), + Some((__l, __Symbol::Variant5(__v), __r)) => (__l, __v, __r), _ => __symbol_type_mismatch() } } - fn __pop_Variant60< + fn __pop_Variant31< >( __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)> - ) -> (TextSize, (Option>, ast::ParenthesizedExpr), TextSize) + ) -> (TextSize, (Option<(TextSize, TextSize, Option)>, ast::Expr), TextSize) { match __symbols.pop() { - Some((__l, __Symbol::Variant60(__v), __r)) => (__l, __v, __r), + Some((__l, __Symbol::Variant31(__v), __r)) => (__l, __v, __r), _ => __symbol_type_mismatch() } } - fn __pop_Variant77< + fn __pop_Variant13< >( __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)> - ) -> (TextSize, (Option, Option), TextSize) + ) -> (TextSize, (Option>, Vec, Option>), TextSize) { match __symbols.pop() { - Some((__l, __Symbol::Variant77(__v), __r)) => (__l, __v, __r), + Some((__l, __Symbol::Variant13(__v), __r)) => (__l, __v, __r), _ => __symbol_type_mismatch() } } - fn __pop_Variant7< + fn __pop_Variant60< >( __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)> - ) -> (TextSize, (String, StringKind, bool), TextSize) + ) -> (TextSize, (Option>, ast::ParenthesizedExpr), TextSize) { match __symbols.pop() { - Some((__l, __Symbol::Variant7(__v), __r)) => (__l, __v, __r), + Some((__l, __Symbol::Variant60(__v), __r)) => (__l, __v, __r), _ => __symbol_type_mismatch() } } - fn __pop_Variant3< + fn __pop_Variant77< >( __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)> - ) -> (TextSize, (String, bool), TextSize) + ) -> (TextSize, (Option, Option), TextSize) { match __symbols.pop() { - Some((__l, __Symbol::Variant3(__v), __r)) => (__l, __v, __r), + Some((__l, __Symbol::Variant77(__v), __r)) => (__l, __v, __r), _ => __symbol_type_mismatch() } } @@ -18407,6 +18409,16 @@ mod __parse__Top { _ => __symbol_type_mismatch() } } + fn __pop_Variant6< + >( + __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)> + ) -> (TextSize, CompactString, TextSize) + { + match __symbols.pop() { + Some((__l, __Symbol::Variant6(__v), __r)) => (__l, __v, __r), + _ => __symbol_type_mismatch() + } + } fn __pop_Variant4< >( __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)> @@ -18437,16 +18449,6 @@ mod __parse__Top { _ => __symbol_type_mismatch() } } - fn __pop_Variant6< - >( - __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)> - ) -> (TextSize, String, TextSize) - { - match __symbols.pop() { - Some((__l, __Symbol::Variant6(__v), __r)) => (__l, __v, __r), - _ => __symbol_type_mismatch() - } - } fn __pop_Variant70< >( __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)> @@ -19017,33 +19019,33 @@ mod __parse__Top { _ => __symbol_type_mismatch() } } - fn __pop_Variant72< + fn __pop_Variant101< >( __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)> - ) -> (TextSize, core::option::Option<(Option<(TextSize, TextSize, Option)>, ast::Expr)>, TextSize) + ) -> (TextSize, core::option::Option<(CompactString, bool)>, TextSize) { match __symbols.pop() { - Some((__l, __Symbol::Variant72(__v), __r)) => (__l, __v, __r), + Some((__l, __Symbol::Variant101(__v), __r)) => (__l, __v, __r), _ => __symbol_type_mismatch() } } - fn __pop_Variant14< + fn __pop_Variant72< >( __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)> - ) -> (TextSize, core::option::Option<(Option>, Vec, Option>)>, TextSize) + ) -> (TextSize, core::option::Option<(Option<(TextSize, TextSize, Option)>, ast::Expr)>, TextSize) { match __symbols.pop() { - Some((__l, __Symbol::Variant14(__v), __r)) => (__l, __v, __r), + Some((__l, __Symbol::Variant72(__v), __r)) => (__l, __v, __r), _ => __symbol_type_mismatch() } } - fn __pop_Variant101< + fn __pop_Variant14< >( __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)> - ) -> (TextSize, core::option::Option<(String, bool)>, TextSize) + ) -> (TextSize, core::option::Option<(Option>, Vec, Option>)>, TextSize) { match __symbols.pop() { - Some((__l, __Symbol::Variant101(__v), __r)) => (__l, __v, __r), + Some((__l, __Symbol::Variant14(__v), __r)) => (__l, __v, __r), _ => __symbol_type_mismatch() } } @@ -33431,7 +33433,7 @@ fn __action69< source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), - (_, n, _): (TextSize, String, TextSize), + (_, n, _): (TextSize, CompactString, TextSize), (_, end_location, _): (TextSize, TextSize, TextSize), ) -> ast::Identifier { @@ -33445,7 +33447,7 @@ fn __action70< source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), - (_, n, _): (TextSize, String, TextSize), + (_, n, _): (TextSize, CompactString, TextSize), (_, n2, _): (TextSize, alloc::vec::Vec<(token::Tok, ast::Identifier)>, TextSize), (_, end_location, _): (TextSize, TextSize, TextSize), ) -> ast::Identifier @@ -33529,7 +33531,7 @@ fn __action74< source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), - (_, c, _): (TextSize, (IpyEscapeKind, String), TextSize), + (_, c, _): (TextSize, (IpyEscapeKind, CompactString), TextSize), (_, end_location, _): (TextSize, TextSize, TextSize), ) -> Result> { @@ -33558,7 +33560,7 @@ fn __action75< source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), - (_, c, _): (TextSize, (IpyEscapeKind, String), TextSize), + (_, c, _): (TextSize, (IpyEscapeKind, CompactString), TextSize), (_, end_location, _): (TextSize, TextSize, TextSize), ) -> Result> { @@ -33598,7 +33600,7 @@ fn __action76< ) -> Result> { { - fn unparse_expr(expr: &ast::Expr, buffer: &mut String) -> Result<(), LexicalError> { + fn unparse_expr(expr: &ast::Expr, buffer: &mut CompactString) -> Result<(), LexicalError> { match expr { ast::Expr::Name(ast::ExprName { id, .. }) => { buffer.push_str(id.as_str()); @@ -33652,7 +33654,7 @@ fn __action76< } }; - let mut value = String::new(); + let mut value = CompactString::new(""); unparse_expr(&e.into(), &mut value)?; Ok(ast::Stmt::IpyEscapeCommand( @@ -35786,7 +35788,7 @@ fn __action183< (_, parameters, _): (TextSize, core::option::Option, TextSize), (_, end_location_args, _): (TextSize, TextSize, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), - (_, fstring_middle, _): (TextSize, core::option::Option<(String, bool)>, TextSize), + (_, fstring_middle, _): (TextSize, core::option::Option<(CompactString, bool)>, TextSize), (_, body, _): (TextSize, ast::ParenthesizedExpr, TextSize), (_, end_location, _): (TextSize, TextSize, TextSize), ) -> Result> @@ -36210,7 +36212,7 @@ fn __action214< source_code: &str, mode: Mode, (_, start_location, _): (TextSize, TextSize, TextSize), - (_, string, _): (TextSize, (String, StringKind, bool), TextSize), + (_, string, _): (TextSize, (CompactString, StringKind, bool), TextSize), ) -> Result> { { @@ -36260,7 +36262,7 @@ fn __action217< source_code: &str, mode: Mode, (_, start_location, _): (TextSize, TextSize, TextSize), - (_, fstring_middle, _): (TextSize, (String, bool), TextSize), + (_, fstring_middle, _): (TextSize, (CompactString, bool), TextSize), ) -> Result> { { @@ -36303,8 +36305,8 @@ fn __action218< ) }; ast::DebugText { - leading: source_code[TextRange::new(start_offset, value.range().start())].to_string(), - trailing: source_code[TextRange::new(value.range().end(), end_offset)].to_string(), + leading: source_code[TextRange::new(start_offset, value.range().start())].into(), + trailing: source_code[TextRange::new(value.range().end(), end_offset)].into(), } }); Ok( @@ -36364,7 +36366,7 @@ fn __action221< (_, location, _): (TextSize, TextSize, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), (_, name_location, _): (TextSize, TextSize, TextSize), - (_, s, _): (TextSize, String, TextSize), + (_, s, _): (TextSize, CompactString, TextSize), ) -> Result<(TextSize, ast::ConversionFlag),__lalrpop_util::ParseError> { { @@ -36749,7 +36751,7 @@ fn __action246< source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), - (_, s, _): (TextSize, String, TextSize), + (_, s, _): (TextSize, CompactString, TextSize), (_, end_location, _): (TextSize, TextSize, TextSize), ) -> ast::Identifier { @@ -37178,8 +37180,8 @@ fn __action276< >( source_code: &str, mode: Mode, - (_, __0, _): (TextSize, (String, bool), TextSize), -) -> core::option::Option<(String, bool)> + (_, __0, _): (TextSize, (CompactString, bool), TextSize), +) -> core::option::Option<(CompactString, bool)> { Some(__0) } @@ -37192,7 +37194,7 @@ fn __action277< mode: Mode, __lookbehind: &TextSize, __lookahead: &TextSize, -) -> core::option::Option<(String, bool)> +) -> core::option::Option<(CompactString, bool)> { None } @@ -47987,7 +47989,7 @@ fn __action790< >( source_code: &str, mode: Mode, - __0: (TextSize, String, TextSize), + __0: (TextSize, CompactString, TextSize), __1: (TextSize, TextSize, TextSize), ) -> ast::Identifier { @@ -48015,7 +48017,7 @@ fn __action791< >( source_code: &str, mode: Mode, - __0: (TextSize, String, TextSize), + __0: (TextSize, CompactString, TextSize), __1: (TextSize, alloc::vec::Vec<(token::Tok, ast::Identifier)>, TextSize), __2: (TextSize, TextSize, TextSize), ) -> ast::Identifier @@ -48368,7 +48370,7 @@ fn __action802< source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), - __1: (TextSize, String, TextSize), + __1: (TextSize, CompactString, TextSize), ) -> Result<(TextSize, ast::ConversionFlag),__lalrpop_util::ParseError> { let __start0 = __0.0; @@ -48465,7 +48467,7 @@ fn __action805< >( source_code: &str, mode: Mode, - __0: (TextSize, (String, bool), TextSize), + __0: (TextSize, (CompactString, bool), TextSize), ) -> Result> { let __start0 = __0.0; @@ -49167,7 +49169,7 @@ fn __action827< >( source_code: &str, mode: Mode, - __0: (TextSize, String, TextSize), + __0: (TextSize, CompactString, TextSize), __1: (TextSize, TextSize, TextSize), ) -> ast::Identifier { @@ -49477,7 +49479,7 @@ fn __action837< >( source_code: &str, mode: Mode, - __0: (TextSize, (IpyEscapeKind, String), TextSize), + __0: (TextSize, (IpyEscapeKind, CompactString), TextSize), __1: (TextSize, TextSize, TextSize), ) -> Result> { @@ -49505,7 +49507,7 @@ fn __action838< >( source_code: &str, mode: Mode, - __0: (TextSize, (IpyEscapeKind, String), TextSize), + __0: (TextSize, (IpyEscapeKind, CompactString), TextSize), __1: (TextSize, TextSize, TextSize), ) -> Result> { @@ -49567,7 +49569,7 @@ fn __action840< __1: (TextSize, core::option::Option, TextSize), __2: (TextSize, TextSize, TextSize), __3: (TextSize, token::Tok, TextSize), - __4: (TextSize, core::option::Option<(String, bool)>, TextSize), + __4: (TextSize, core::option::Option<(CompactString, bool)>, TextSize), __5: (TextSize, ast::ParenthesizedExpr, TextSize), __6: (TextSize, TextSize, TextSize), ) -> Result> @@ -52565,7 +52567,7 @@ fn __action934< >( source_code: &str, mode: Mode, - __0: (TextSize, (String, StringKind, bool), TextSize), + __0: (TextSize, (CompactString, StringKind, bool), TextSize), ) -> Result> { let __start0 = __0.0; @@ -64161,7 +64163,7 @@ fn __action1305< >( source_code: &str, mode: Mode, - __0: (TextSize, String, TextSize), + __0: (TextSize, CompactString, TextSize), ) -> ast::Identifier { let __start0 = __0.2; @@ -64187,7 +64189,7 @@ fn __action1306< >( source_code: &str, mode: Mode, - __0: (TextSize, String, TextSize), + __0: (TextSize, CompactString, TextSize), __1: (TextSize, alloc::vec::Vec<(token::Tok, ast::Identifier)>, TextSize), ) -> ast::Identifier { @@ -64959,7 +64961,7 @@ fn __action1333< >( source_code: &str, mode: Mode, - __0: (TextSize, String, TextSize), + __0: (TextSize, CompactString, TextSize), ) -> ast::Identifier { let __start0 = __0.2; @@ -65271,7 +65273,7 @@ fn __action1344< >( source_code: &str, mode: Mode, - __0: (TextSize, (IpyEscapeKind, String), TextSize), + __0: (TextSize, (IpyEscapeKind, CompactString), TextSize), ) -> Result> { let __start0 = __0.2; @@ -65297,7 +65299,7 @@ fn __action1345< >( source_code: &str, mode: Mode, - __0: (TextSize, (IpyEscapeKind, String), TextSize), + __0: (TextSize, (IpyEscapeKind, CompactString), TextSize), ) -> Result> { let __start0 = __0.2; @@ -65354,7 +65356,7 @@ fn __action1347< __0: (TextSize, token::Tok, TextSize), __1: (TextSize, core::option::Option, TextSize), __2: (TextSize, token::Tok, TextSize), - __3: (TextSize, core::option::Option<(String, bool)>, TextSize), + __3: (TextSize, core::option::Option<(CompactString, bool)>, TextSize), __4: (TextSize, ast::ParenthesizedExpr, TextSize), ) -> Result> { @@ -77480,7 +77482,7 @@ fn __action1723< __0: (TextSize, token::Tok, TextSize), __1: (TextSize, ast::Parameters, TextSize), __2: (TextSize, token::Tok, TextSize), - __3: (TextSize, core::option::Option<(String, bool)>, TextSize), + __3: (TextSize, core::option::Option<(CompactString, bool)>, TextSize), __4: (TextSize, ast::ParenthesizedExpr, TextSize), ) -> Result> { @@ -77511,7 +77513,7 @@ fn __action1724< mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, token::Tok, TextSize), - __2: (TextSize, core::option::Option<(String, bool)>, TextSize), + __2: (TextSize, core::option::Option<(CompactString, bool)>, TextSize), __3: (TextSize, ast::ParenthesizedExpr, TextSize), ) -> Result> { @@ -79416,7 +79418,7 @@ fn __action1781< __0: (TextSize, token::Tok, TextSize), __1: (TextSize, ast::Parameters, TextSize), __2: (TextSize, token::Tok, TextSize), - __3: (TextSize, (String, bool), TextSize), + __3: (TextSize, (CompactString, bool), TextSize), __4: (TextSize, ast::ParenthesizedExpr, TextSize), ) -> Result> { @@ -79479,7 +79481,7 @@ fn __action1783< mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, token::Tok, TextSize), - __2: (TextSize, (String, bool), TextSize), + __2: (TextSize, (CompactString, bool), TextSize), __3: (TextSize, ast::ParenthesizedExpr, TextSize), ) -> Result> { diff --git a/crates/ruff_python_parser/src/soft_keywords.rs b/crates/ruff_python_parser/src/soft_keywords.rs index f7aab9c1137a6b..23267ea04d42d6 100644 --- a/crates/ruff_python_parser/src/soft_keywords.rs +++ b/crates/ruff_python_parser/src/soft_keywords.rs @@ -157,7 +157,5 @@ fn soft_to_name(tok: &Tok) -> Tok { Tok::Type => "type", _ => unreachable!("other tokens never reach here"), }; - Tok::Name { - name: name.to_owned(), - } + Tok::Name { name: name.into() } } diff --git a/crates/ruff_python_parser/src/string.rs b/crates/ruff_python_parser/src/string.rs index 81cbe2f9a1ce34..898b1f247d2264 100644 --- a/crates/ruff_python_parser/src/string.rs +++ b/crates/ruff_python_parser/src/string.rs @@ -1,5 +1,6 @@ //! Parsing of string literals, bytes literals, and implicit string concatenation. +use compact_str::CompactString; use ruff_python_ast::{self as ast, BytesConstant, Constant, Expr, StringConstant}; use ruff_text_size::{Ranged, TextLen, TextRange, TextSize}; @@ -206,7 +207,7 @@ impl<'a> StringParser<'a> { } fn parse_fstring_middle(&mut self) -> Result { - let mut value = String::new(); + let mut value = CompactString::default(); let start_location = self.get_pos(); while let Some(ch) = self.next_char() { match ch { @@ -250,7 +251,7 @@ impl<'a> StringParser<'a> { } fn parse_bytes(&mut self) -> Result { - let mut content = String::new(); + let mut content = CompactString::default(); let start_location = self.get_pos(); while let Some(ch) = self.next_char() { match ch { @@ -278,7 +279,7 @@ impl<'a> StringParser<'a> { } fn parse_string(&mut self) -> Result { - let mut value = String::new(); + let mut value = CompactString::default(); let start_location = self.get_pos(); while let Some(ch) = self.next_char() { match ch { @@ -387,7 +388,7 @@ pub(crate) fn concatenate_strings( } if !has_fstring { - let mut content = String::new(); + let mut content = CompactString::default(); let is_unicode = strings.first().map_or(false, StringType::is_unicode); for string in strings { match string { @@ -411,12 +412,12 @@ pub(crate) fn concatenate_strings( // De-duplicate adjacent constants. let mut deduped: Vec = vec![]; - let mut current = String::new(); + let mut current = CompactString::new(""); let mut current_start = range.start(); let mut current_end = range.end(); let mut is_unicode = false; - let take_current = |current: &mut String, start, end, unicode| -> Expr { + let take_current = |current: &mut CompactString, start, end, unicode| -> Expr { Expr::Constant(ast::ExprConstant { value: Constant::Str(StringConstant { value: std::mem::take(current), diff --git a/crates/ruff_python_parser/src/token.rs b/crates/ruff_python_parser/src/token.rs index ac441395fffc2a..af227684e14645 100644 --- a/crates/ruff_python_parser/src/token.rs +++ b/crates/ruff_python_parser/src/token.rs @@ -6,6 +6,7 @@ //! [CPython source]: https://github.com/python/cpython/blob/dfc2e065a2e71011017077e549cd2f9bf4944c54/Include/internal/pycore_token.h; use crate::Mode; +use compact_str::CompactString; use ruff_python_ast::{Int, IpyEscapeKind}; use ruff_text_size::TextSize; use std::fmt; @@ -16,7 +17,7 @@ pub enum Tok { /// Token value for a name, commonly known as an identifier. Name { /// The name value. - name: String, + name: CompactString, }, /// Token value for an integer. Int { @@ -38,7 +39,7 @@ pub enum Tok { /// Token value for a string. String { /// The string value. - value: String, + value: CompactString, /// The kind of string. kind: StringKind, /// Whether the string is triple quoted. @@ -51,7 +52,7 @@ pub enum Tok { /// part of the expression part and isn't an opening or closing brace. FStringMiddle { /// The string value. - value: String, + value: CompactString, /// Whether the string is raw or not. is_raw: bool, }, @@ -61,12 +62,12 @@ pub enum Tok { /// only when the mode is [`Mode::Ipython`]. IpyEscapeCommand { /// The magic command value. - value: String, + value: CompactString, /// The kind of magic command. kind: IpyEscapeKind, }, /// Token value for a comment. These are filtered out of the token stream prior to parsing. - Comment(String), + Comment(CompactString), /// Token value for a newline. Newline, /// Token value for a newline that is not a logical line break. These are filtered out of diff --git a/crates/ruff_python_semantic/src/analyze/typing.rs b/crates/ruff_python_semantic/src/analyze/typing.rs index c1fcab65a82f4c..2608c1f24300f5 100644 --- a/crates/ruff_python_semantic/src/analyze/typing.rs +++ b/crates/ruff_python_semantic/src/analyze/typing.rs @@ -458,7 +458,7 @@ trait BuiltinTypeChecker { let Expr::Name(ast::ExprName { id, .. }) = type_expr else { return false; }; - id == Self::BUILTIN_TYPE_NAME && semantic.is_builtin(Self::BUILTIN_TYPE_NAME) + id.as_str() == Self::BUILTIN_TYPE_NAME && semantic.is_builtin(Self::BUILTIN_TYPE_NAME) } }