Skip to content

Incorrect suggestion in Style/BitwisePredicate #14469

@herwinw

Description

@herwinw

The following line:

(1 & num) == 1

does raise the following error with Rubocop:

Style/BitwisePredicate: Replace with 1.allbits?(num) for comparison with bit flags.
  (1 & num) == 1
  ^^^^^^^^^^^^^^

But these are not the same statements. It's easiest to see with num = 3:

irb(main):001> (1 & 3) == 1
=> true
irb(main):002> 1.allbits?(3)
=> false

It looks like the actual fix in this case is the other way around:

irb(main):003> 3.allbits?(1)
=> true

If the original source is (num & 1) == 1, the suggested fix is num.allbits?(1), which is actually correct.

The matcher is defined as follows:

# @!method allbits?(node)
def_node_matcher :allbits?, <<~PATTERN
  {
    (send (begin (send _ :& _flags)) :== _flags)
    (send (begin (send _flags :& _)) :== _flags)
  }
PATTERN

And the suggestion as:

bit_operation = node.receiver.children.first
lhs, _operator, rhs = *bit_operation
preferred = "#{lhs.source}.#{preferred_method}(#{rhs.source})"

So this probably needs to flip the lhs and rhs in the output in case the _flags matches the lhs.


RuboCop version

1.79.2 (using Parser 3.3.9.0, rubocop-ast 1.46.0, analyzing as Ruby 2.7, running on ruby 3.3.7) [x86_64-linux-gnu]

(Seen on older versions too)

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions