From 1043dfade258c1cc21befc2703e668c2b4322f91 Mon Sep 17 00:00:00 2001 From: Cam McHenry Date: Fri, 30 Oct 2026 12:26:35 -0400 Subject: [PATCH] perf(linter): avoid collecting prefer-const binding identifiers (#28484) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Use the alloc-free `all_binding_identifiers` instead of the allocating `get_binding_identifiers`. On local fixtures: Allocations: 4,911 → 3,288 (−33.1%) Allocated bytes: 189,869 → 137,901 (−27.4%) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .../oxc_linter/src/rules/eslint/prefer_const.rs | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/crates/oxc_linter/src/rules/eslint/prefer_const.rs b/crates/oxc_linter/src/rules/eslint/prefer_const.rs index 46e9478c58..d9a635f7ac 100644 --- a/crates/oxc_linter/src/rules/eslint/prefer_const.rs +++ b/crates/oxc_linter/src/rules/eslint/prefer_const.rs @@ -7,6 +7,7 @@ use oxc_ast::{ }, }; use oxc_diagnostics::OxcDiagnostic; +use oxc_ecmascript::BoundNames; use oxc_macros::declare_oxc_lint; use oxc_semantic::SymbolId; use oxc_span::{GetSpan, Span}; @@ -136,8 +137,8 @@ impl Rule for PreferConst { if is_for_statement_init && decl.declarations.len() > 1 { let any_reassigned = decl.declarations.iter().any(|declarator| { let has_init = declarator.init.is_some(); - declarator.id.get_binding_identifiers().iter().any(|ident| { - !self.should_be_const(ident.symbol_id(), has_init, is_for_in_of_init, ctx) + !declarator.id.all_binding_identifiers(&mut |ident| { + self.should_be_const(ident.symbol_id(), has_init, is_for_in_of_init, ctx) }) }); @@ -148,11 +149,10 @@ impl Rule for PreferConst { let mut all_declarators_const = true; for (declarator_index, declarator) in decl.declarations.iter().enumerate() { - let binding_identifiers = declarator.id.get_binding_identifiers(); let has_init = declarator.init.is_some(); let is_destructuring = declarator.id.is_destructuring_pattern(); - let all_const = binding_identifiers.iter().all(|ident| { + let all_const = declarator.id.all_binding_identifiers(&mut |ident| { let symbol_id = ident.symbol_id(); self.should_be_const(symbol_id, has_init, is_for_in_of_init, ctx) }); @@ -162,7 +162,7 @@ impl Rule for PreferConst { if matches!(self.0.destructuring, Destructuring::All) && is_destructuring { if all_const { // Flag all variables in the destructuring pattern - for ident in binding_identifiers { + declarator.id.bound_names(&mut |ident| { ctx.diagnostic_with_fix( prefer_const_diagnostic(ident.name.as_str(), ident.span), |fixer| { @@ -176,12 +176,12 @@ impl Rule for PreferConst { ) }, ); - } + }); } // If not all_const, don't flag any of them in "all" mode } else { // "any" mode (default): check each binding identifier independently - for ident in binding_identifiers { + declarator.id.bound_names(&mut |ident| { if self.should_be_const(ident.symbol_id(), has_init, is_for_in_of_init, ctx) { ctx.diagnostic_with_fix( prefer_const_diagnostic(ident.name.as_str(), ident.span), @@ -197,7 +197,7 @@ impl Rule for PreferConst { }, ); } - } + }); } } }