rubocop/rubocop

`Style/ArgumentsForwarding` enforce anonymous bad autocorrect

janklimo opened this issue · 3 comments

The following code:

    def validators_on(*args)
      [
        super,
        resource_class.validators_on(*args),
        *@auxiliary_resource_classes.map do |klass|
          klass.validators_on(*args)
        end,
      ].flatten
    end
  end

results in invalid autocorrect output with

Style/ArgumentsForwarding:
  UseAnonymousForwarding: true
  Enabled: true

Expected behavior

    def validators_on(*args)
      [
        super,
        resource_class.validators_on(*args),
        *@auxiliary_resource_classes.map do |klass|
          klass.validators_on(*args)
        end,
      ].flatten
    end
  end

Actual behavior

    def validators_on(*)
      [
        super,
        resource_class.validators_on(*),
        *@auxiliary_resource_classes.map do |klass|
          klass.validators_on(*args)
        end,
      ].flatten
    end
  end

*args will no longer be defined.

Steps to reproduce the problem

Example code above.

RuboCop version

1.63.4 (using Parser 3.3.1.0, rubocop-ast 1.31.2, running on ruby 3.3.1) [arm64-darwin23]
  - rubocop-capybara 2.20.0
  - rubocop-factory_bot 2.25.1
  - rubocop-performance 1.20.2
  - rubocop-rails 2.24.0
  - rubocop-rspec 2.27.1

I have also several patterns where the fixes in 1.66.1 are wrong. The example above is very much like my Block and Lambda case. Note that I was able to indeed use anonymous argument names, contrary to what the "Expected" above reported.

Input

class Brackets
  def [](*args, **kwargs)
    puts(*args)
    puts(**kwargs)
  end

  def call(*args, **kwargs)
    # The fix introduces incorrect parens.
    self[*args, **kwargs]
  end
end

class Lambda
  def foo(*args, **kwargs)
    rec = ->(*moreargs, **morekwargs) {
      # The fix forgot to rename args and kwargs.
      bar(*args, *moreargs, **kwargs, **morekwargs)
    }
    puts(*args)
    puts(**kwargs)
  end
end

class Block
  def foo(*args, **kwargs)
    self.method do
      # The fix forgot to rename args and kwargs.
      bar(*args, *moreargs, **kwargs, **morekwargs)
    end
    puts(*args)
    puts(**kwargs)
  end
end

Output (wrong)

class Brackets
  def [](*, **)
    puts(*)
    puts(**)
  end

  def call(*, **)
    # The fix introduces incorrect parens.
    self[*, **])(  end
end

class Lambda
  def foo(*, **)
    ->(*moreargs, **morekwargs) {
      # The fix forgot to rename args and kwargs.
      bar(*args, *moreargs, **kwargs, **morekwargs)
    }
    puts(*)
    puts(**)
  end
end

class Block
  def foo(*, **)
    self.method do
      # The fix forgot to rename args and kwargs.
      bar(*args, *moreargs, **kwargs, **morekwargs)
    end
    puts(*)
    puts(**)
  end
end

Expected

class Brackets
  def [](*, **)
    puts(*)
    puts(**)
  end

  def call(*, **)
    # The fix introduces incorrect parens.
    self[*, **]
 end
end

class Lambda
  def foo(*, **)
    ->(*moreargs, **morekwargs) {
      # The fix forgot to rename args and kwargs.
      bar(*, *moreargs, **, **morekwargs)
    }
    puts(*)
    puts(**)
  end
end

class Block
  def foo(*, **)
    self.method do
      # The fix forgot to rename args and kwargs.
      bar(*, *moreargs, **, **morekwargs)
    end
    puts(*)
    puts(**)
  end
end

@akimd can you make a new issue for the brackets case? That will require a different solution.

Sure. I was not sure whether it was preferred to have "fat" issues, or "many" issues :)

#13220