standardrb / standard-performance

Standard Ruby Plugin providing configuration for rubocop-performance

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

RuboCop::Cop::Performance::Count is not safe and should be moved to the unsafe set

jon-rse opened this issue · comments

Expected behavior: Running standardrb --fix will not break code.
Observed behavior: standard --fix includes cops which are unsafe.
Environment: Ruby 3.2.0, default standardrb install,

standard (1.28.2)
      language_server-protocol (~> 3.17.0.2)
      lint_roller (~> 1.0)
      rubocop (~> 1.50.2)
      standard-custom (~> 1.0.0)
      standard-performance (~> 1.0.1)

The count cop will transform

 hash.select { |k,v| k == "count me" }.count

into

 hash.count { |k,v| k == "count me" }

However the count method on a hash does not pass |k,v| to the block, but rather an array, [k,v]. This is not a safe transformation, and requires modification to the block, or the caller for the transformed code to operate correctly eg:

 hash.keys.count { |k| k == "count me" }

See this issue in rubocop where they mark the count cop as unsafe, rubocop/rubocop-performance#69

Confirmed this with a test in standard.

$ bundle exec m test/standard/cli_test.rb:36
Run options: -n "/^(test_unsafely_fixable_is_not_fixed_unsafely)$/" --seed 2437

# Running:

F

Finished in 0.551967s, 1.8117 runs/s, 7.2468 assertions/s.

  1) Failure:
Standard::CliTest#test_unsafely_fixable_is_not_fixed_unsafely [/Users/justin/code/standardrb/standard/test/standard/cli_test.rb:36]:
--- expected
+++ actual
@@ -2,7 +2,5 @@
 " +
 "  test/fixture/cli/unsafecorrectable-bad.rb:1:7: Lint/BooleanSymbol: Symbol with a boolean name - you probably meant to use `true`.
 " +
-"  test/fixture/cli/unsafecorrectable-bad.rb:6:24: Performance/Count: Use `count` instead of `select...count`.
-" +
-"standard: Run `standardrb --fix-unsafely` to DANGEROUSLY fix 2 problems.
+"standard: Run `standardrb --fix-unsafely` to DANGEROUSLY fix one problem.
 "

@koic, can you help me understand this? When I look at the source for these two unsafe cops (Performance/Count and Lint/BooleanSymbol, I can't tell what in their code listings are doing to tell RuboCop that their fix is unsafe, so I can't figure out what Standard is doing wrong here.

AFAICT, we're setting the two autocorrection flags correctly in our CLI config: https://github.com/standardrb/standard/blob/main/lib/standard/merges_settings.rb#L27-L40