Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

infinite loop between Style/TernaryParentheses and Style/RedundantParentheses #7716

Closed
senhalil opened this issue Feb 14, 2020 · 0 comments · Fixed by #7718
Closed

infinite loop between Style/TernaryParentheses and Style/RedundantParentheses #7716

senhalil opened this issue Feb 14, 2020 · 0 comments · Fixed by #7718
Labels

Comments

@senhalil
Copy link

!foo.nil? ? 1 : 2
# => Use parentheses for ternary expressions with complex conditions. (convention:Style/TernaryParentheses)

(!foo.nil?) ? 1 : 2 
# => Don't use parentheses around an unary operation. (convention:Style/RedundantParentheses)

not nil is considered as a complex condition by Style/TernaryParentheses (EnforcedStyle: require_parentheses_when_complex) ; however, since it is a unary operation, adding parenthesis violates Style/RedundantParentheses which leads to infinite loop in the auto-correct mechanism.


Expected behavior

TernaryParentheses and RedundantParentheses can agree if not nil is complex or not.

Actual behavior

They don't agree.

Steps to reproduce the problem

Running rubocop --safe-auto-correct on above snippet with the setting below leads to infinite loop

AllCops:
  TargetRubyVersion: 2.3

Style/TernaryParentheses:
  EnforcedStyle: require_parentheses_when_complex
$  rubocop --safe-auto-correct rubocop_bug.rb 
Inspecting 1 file
C

Offenses:

rubocop_bug.rb:3:1: C: [Corrected] Style/RedundantParentheses: Don't use parentheses around an unary operation.
(!foo.nil?) ? 1 : 2
^^^^^^^^^^^
rubocop_bug.rb:3:1: C: [Corrected] Style/TernaryParentheses: Use parentheses for ternary expressions with complex conditions.
!foo.nil? ? 1 : 2
^^^^^^^^^^^^^^^^^

0 files inspected, 2 offenses detected, 2 offenses corrected
Infinite loop detected in dev/rubocop_bug.rb.
.rbenv/versions/2.3.8/lib/ruby/gems/2.3.0/gems/rubocop-0.79.0/lib/rubocop/runner.rb:287:in `check_for_infinite_loop'
.rbenv/versions/2.3.8/lib/ruby/gems/2.3.0/gems/rubocop-0.79.0/lib/rubocop/runner.rb:270:in `block in iterate_until_no_changes'
.rbenv/versions/2.3.8/lib/ruby/gems/2.3.0/gems/rubocop-0.79.0/lib/rubocop/runner.rb:269:in `loop'
.rbenv/versions/2.3.8/lib/ruby/gems/2.3.0/gems/rubocop-0.79.0/lib/rubocop/runner.rb:269:in `iterate_until_no_changes'
.rbenv/versions/2.3.8/lib/ruby/gems/2.3.0/gems/rubocop-0.79.0/lib/rubocop/runner.rb:240:in `do_inspection_loop'
.rbenv/versions/2.3.8/lib/ruby/gems/2.3.0/gems/rubocop-0.79.0/lib/rubocop/runner.rb:119:in `block in file_offenses'
.rbenv/versions/2.3.8/lib/ruby/gems/2.3.0/gems/rubocop-0.79.0/lib/rubocop/runner.rb:143:in `file_offense_cache'
.rbenv/versions/2.3.8/lib/ruby/gems/2.3.0/gems/rubocop-0.79.0/lib/rubocop/runner.rb:117:in `file_offenses'
.rbenv/versions/2.3.8/lib/ruby/gems/2.3.0/gems/rubocop-0.79.0/lib/rubocop/runner.rb:108:in `process_file'
.rbenv/versions/2.3.8/lib/ruby/gems/2.3.0/gems/rubocop-0.79.0/lib/rubocop/runner.rb:87:in `block in each_inspected_file'
.rbenv/versions/2.3.8/lib/ruby/gems/2.3.0/gems/rubocop-0.79.0/lib/rubocop/runner.rb:86:in `each'
.rbenv/versions/2.3.8/lib/ruby/gems/2.3.0/gems/rubocop-0.79.0/lib/rubocop/runner.rb:86:in `reduce'
.rbenv/versions/2.3.8/lib/ruby/gems/2.3.0/gems/rubocop-0.79.0/lib/rubocop/runner.rb:86:in `each_inspected_file'
.rbenv/versions/2.3.8/lib/ruby/gems/2.3.0/gems/rubocop-0.79.0/lib/rubocop/runner.rb:73:in `inspect_files'
.rbenv/versions/2.3.8/lib/ruby/gems/2.3.0/gems/rubocop-0.79.0/lib/rubocop/runner.rb:39:in `run'
.rbenv/versions/2.3.8/lib/ruby/gems/2.3.0/gems/rubocop-0.79.0/lib/rubocop/cli/command/execute_runner.rb:21:in `execute_runner'
.rbenv/versions/2.3.8/lib/ruby/gems/2.3.0/gems/rubocop-0.79.0/lib/rubocop/cli/command/execute_runner.rb:13:in `run'
.rbenv/versions/2.3.8/lib/ruby/gems/2.3.0/gems/rubocop-0.79.0/lib/rubocop/cli/command.rb:10:in `run'
.rbenv/versions/2.3.8/lib/ruby/gems/2.3.0/gems/rubocop-0.79.0/lib/rubocop/cli/environment.rb:17:in `run'
.rbenv/versions/2.3.8/lib/ruby/gems/2.3.0/gems/rubocop-0.79.0/lib/rubocop/cli.rb:65:in `run_command'
.rbenv/versions/2.3.8/lib/ruby/gems/2.3.0/gems/rubocop-0.79.0/lib/rubocop/cli.rb:72:in `execute_runners'
.rbenv/versions/2.3.8/lib/ruby/gems/2.3.0/gems/rubocop-0.79.0/lib/rubocop/cli.rb:41:in `run'
.rbenv/versions/2.3.8/lib/ruby/gems/2.3.0/gems/rubocop-0.79.0/exe/rubocop:13:in `block in <top (required)>'
.rbenv/versions/2.3.8/lib/ruby/2.3.0/benchmark.rb:308:in `realtime'
.rbenv/versions/2.3.8/lib/ruby/gems/2.3.0/gems/rubocop-0.79.0/exe/rubocop:12:in `<top (required)>'
.rbenv/versions/2.3.8/bin/rubocop:22:in `load'
.rbenv/versions/2.3.8/bin/rubocop:22:in `<main>'

RuboCop version

$ rubocop -V

0.79.0 (using Parser 2.7.0.2, running on ruby 2.3.8 x86_64-linux)
@koic koic added the bug label Feb 15, 2020
koic added a commit to koic/rubocop that referenced this issue Feb 15, 2020
…theses`

Fix rubocop#7716.

This PR fixes an infinite loop error for `Style/TernaryParentheses` with
`Style/RedundantParentheses` when using `EnforcedStyle: require_parentheses_when_complex`.

```ruby
# example.rb
!foo.nil? ? 1 : 2
```

```yaml
# .rubocop.yml
Style/TernaryParentheses:
  EnforcedStyle: require_parentheses_when_complex
```

First, auto-corrected by `Style/TernaryParentheses`
(`EnforcedStyle: require_parentheses_when_complex`).

```console
% bundle exec rubocop -a --only Style/TernaryParentheses

Offenses:

example.rb:2:1: C: [Corrected] Style/TernaryParentheses: Use parentheses
for ternary expressions with complex conditions.
!foo.nil? ? 1 : 2
^^^^^^^^^^^^^^^^^

1 file inspected, 1 offense detected, 1 offense corrected
```

```diff
% git diff example.rb
diff --git a/7716/example.rb b/7716/example.rb
index ae08c67..31212d8 100644
--- a/7716/example.rb
+++ b/7716/example.rb
@@ -1,2 +1,2 @@
 # example.rb
 -!foo.nil? ? 1 : 2
 +(!foo.nil?) ? 1 : 2
```

Next, auto-corrected by `Style/RedundantParentheses`.

```console
% bundle exec rubocop -a --only Style/RedundantParentheses

Offenses:

example.rb:2:1: C: [Corrected] Style/RedundantParentheses: Don't use
parentheses around an unary operation.
(!foo.nil?) ? 1 : 2
^^^^^^^^^^^

1 file inspected, 1 offense detected, 1 offense corrected
```

This will return to the original code.

```diff
% git diff example.rb
diff --git a/7716/example.rb b/7716/example.rb
index 31212d8..ae08c67 100644
--- a/7716/example.rb
+++ b/7716/example.rb
@@ -1,2 +1,2 @@
 # example.rb
 -(!foo.nil?) ? 1 : 2
 +!foo.nil? ? 1 : 2
```

That caused the infinite loop in `Style/TernaryParentheses`
(`EnforcedStyle: require_parentheses_when_complex`) and
`Style/RedundantParentheses`.

With this PR, `Style/TernaryParentheses` cop makes aware of
`Style/RedundantParentheses` cop when setting
`EnforcedStyle: require_parentheses_when_complex`.

This does the same thing as `EnforcedStyle: require_parentheses` for
infinite loop error.
koic added a commit that referenced this issue Feb 16, 2020
…undant_parentheses

[Fix #7716] Fix an infinite loop error for `Style/TernaryParentheses`
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants