`Lint/RedundantCopDisableDirective` leaves an orphan `enable` directive when the cop is not enabled
Before submitting
- I have searched the existing issues and this hasn't been reported yet.
- I am running the latest stable version of RuboCop.
Issue type
Incorrect autocorrect
Cop name
Lint/RedundantCopDisableDirective, Lint/RedundantCopEnableDirective
Steps to reproduce the problem
This happens with a matching disable / enable pair when the target cop is not enabled.
- Create a
.rubocop.ymlwith the following content:
# The bug reproduces with any cop
Style/StringLiterals:
Enabled: false(This step is unnecessary if you use a cop that is disabled by default.)
- Create an
example.rbwith a matchingdisable/enablepair:
# frozen_string_literal: true
# rubocop:disable Style/StringLiterals
FOO = "double quoted"
# rubocop:enable Style/StringLiterals- Run
rubocop -a example.rb
Expected behavior
Since the disable and the enable form a matching pair, I would expect autocorrect to remove
both of them:
# frozen_string_literal: true
FOO = "double quoted"Actual behavior
Only the disable is removed, and the enable is left behind.
Running rubocop -a example.rb gives:
$ rubocop -a example.rb
Offenses:
example.rb:3:1: W: [Corrected] Lint/RedundantCopDisableDirective: Unnecessary disabling of Style/StringLiterals.
# rubocop:disable Style/StringLiterals
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
1 file inspected, 1 offense detected, 1 offense correctedexample.rb after the correction:
# frozen_string_literal: true
FOO = "double quoted"
# rubocop:enable Style/StringLiteralsRunning RuboCop again does not report the leftover enable either:
$ rubocop example.rb
Inspecting 1 file
.
1 file inspected, no offenses detectedSince #10987, Lint/RedundantCopEnableDirective treats an enable directive for a cop that is
not enabled as temporarily enabling that cop, and therefore does not register an offense. The
leftover directive is never reported, no matter how many times RuboCop runs.
As a result, autocorrect is no longer idempotent, and RuboCop considers the state it produced itself to be clean.
For reference, when the target cop is enabled (either explicitly in .rubocop.yml, or by default
when left unconfigured), everything works as expected: both
Lint/RedundantCopDisableDirective and Lint/RedundantCopEnableDirective register an offense
and both directives are removed.
RuboCop configuration
Style/StringLiterals:
Enabled: falseRuboCop version
$ bundle exec rubocop -V
1.90.0 (using Parser 3.3.12.0, Prism 1.9.0, rubocop-ast 1.50.0, analyzing as Ruby 4.0, running on ruby 4.0.2) [arm64-darwin24]
- rubocop-performance 1.27.0
- rubocop-rails 2.37.0
- rubocop-rspec 3.10.2
- rubocop-factory_bot 2.28.0
- rubocop-rspec_rails 2.32.0Source: rubocop/rubocop