KEMBAR78
Arguments incorrectly identified as being shadowed by a local variable · Issue #14497 · rubocop/rubocop · GitHub
Skip to content

Arguments incorrectly identified as being shadowed by a local variable #14497

@Rylan12

Description

@Rylan12

In certain situations, RuboCop incorrectly identifies arguments as being "shadowed by a local variable before it was used."

Take this example method that downloads a file if certain conditions are met, and then returns whether the file was downloaded or not

# target_exists: whether the target file exists or not. If it doesn't exist, we must download
# other_conditions_met: if these conditions are met and the file exists, skip the download
# skip_download: don't download, even if `other_conditions_met` is true. However, always download if `target_exists` is false
def download_to_target?(endpoint, target_exists:, other_conditions_met:, skip_download: false)
  skip_download = false unless target_exists
  skip_download ||= target_exists && other_conditions_met

  begin
    puts "Downloading file #{endpoint}" unless skip_download
  rescue StandardError
    skip_download = false
  end

  !skip_download
end

Normally, the download process is skipped if target_exists and other_conditions_met. The skip_download argument is used to override other_conditions_met, and skip the download even if those conditions are false. However, we never want to allow skipping the download if target_exists is false.

The effect of skip_download is demonstrated here:

$ bin/console
irb(main):001> download_to_target? "foo.txt", target_exists: true, other_conditions_met: false, skip_download: false
Downloading file foo.txt
=> true
irb(main):002> download_to_target? "foo.txt", target_exists: true, other_conditions_met: false, skip_download: true
=> false

As you can see, modifying skip_download has an effect on the output. However, rubocop gives the following message:

$ bundle exec rubocop
Inspecting 8 files
...W....

Offenses:

lib/rubocop/test.rb:13:78: W: Lint/ShadowedArgument: Argument skip_download was shadowed by a local variable before it was used.
    def download_to_target?(endpoint, target_exists:, other_conditions_met:, skip_download: false)
                                                                             ^^^^^^^^^^^^^^^^^^^^

8 files inspected, 1 offense detected

I believe this is incorrect, because as shown in the console output above, passing different values to skip_download returns a different result, indicating that skip_download is not actually shadowed.


Expected behavior

No RuboCop violations

Actual behavior

$ bundle exec rubocop --debug
For /Users/rylanpolster/Desktop/rubocop-test: configuration from /Users/rylanpolster/Desktop/rubocop-test/.rubocop.yml
Use parallel by default.
Running parallel inspection
Loading cache from /Users/rylanpolster/.cache/rubocop_cache/2c9471a62bcb70567f347d769fb45cd0173313ed/6d7a3b621ca1730e04accd938619e4bdab66cfb1/6cb3c8aa5d0a05ad7ae243b17f0c0ebfe575bbaf
Loading cache from /Users/rylanpolster/.cache/rubocop_cache/2c9471a62bcb70567f347d769fb45cd0173313ed/6d7a3b621ca1730e04accd938619e4bdab66cfb1/58bb370c1ae436abce2481ae7f2faaf723af28bc
Loading cache from /Users/rylanpolster/.cache/rubocop_cache/2c9471a62bcb70567f347d769fb45cd0173313ed/6d7a3b621ca1730e04accd938619e4bdab66cfb1/14c9461f0e85c5bba9e1a207e916ec1318c1a7d6
Loading cache from /Users/rylanpolster/.cache/rubocop_cache/2c9471a62bcb70567f347d769fb45cd0173313ed/6d7a3b621ca1730e04accd938619e4bdab66cfb1/251face88f94ebec482a3320c71fedb341db40c6
Loading cache from /Users/rylanpolster/.cache/rubocop_cache/2c9471a62bcb70567f347d769fb45cd0173313ed/6d7a3b621ca1730e04accd938619e4bdab66cfb1/46f5f04a2f99cf23d920e6e24fc4aea8caab1eeb
Loading cache from /Users/rylanpolster/.cache/rubocop_cache/2c9471a62bcb70567f347d769fb45cd0173313ed/6d7a3b621ca1730e04accd938619e4bdab66cfb1/278c4c969bf9a250ce7dea8a0a74a2489e9948c4
Loading cache from /Users/rylanpolster/.cache/rubocop_cache/2c9471a62bcb70567f347d769fb45cd0173313ed/6d7a3b621ca1730e04accd938619e4bdab66cfb1/30efeb7f71f0ff8b0eac9f82e5d911ebcaa5a2ae
Loading cache from /Users/rylanpolster/.cache/rubocop_cache/2c9471a62bcb70567f347d769fb45cd0173313ed/6d7a3b621ca1730e04accd938619e4bdab66cfb1/79fa9b3dc047bc6568f24fd1af5f3b8bbae7a04e
Inspecting 8 files
Scanning /Users/rylanpolster/Desktop/rubocop-test/Gemfile
Loading cache from /Users/rylanpolster/.cache/rubocop_cache/2c9471a62bcb70567f347d769fb45cd0173313ed/6d7a3b621ca1730e04accd938619e4bdab66cfb1/251face88f94ebec482a3320c71fedb341db40c6
.Scanning /Users/rylanpolster/Desktop/rubocop-test/Rakefile
Loading cache from /Users/rylanpolster/.cache/rubocop_cache/2c9471a62bcb70567f347d769fb45cd0173313ed/6d7a3b621ca1730e04accd938619e4bdab66cfb1/46f5f04a2f99cf23d920e6e24fc4aea8caab1eeb
.Scanning /Users/rylanpolster/Desktop/rubocop-test/bin/console
Loading cache from /Users/rylanpolster/.cache/rubocop_cache/2c9471a62bcb70567f347d769fb45cd0173313ed/6d7a3b621ca1730e04accd938619e4bdab66cfb1/58bb370c1ae436abce2481ae7f2faaf723af28bc
.Scanning /Users/rylanpolster/Desktop/rubocop-test/lib/rubocop/test.rb
Loading cache from /Users/rylanpolster/.cache/rubocop_cache/2c9471a62bcb70567f347d769fb45cd0173313ed/6d7a3b621ca1730e04accd938619e4bdab66cfb1/6cb3c8aa5d0a05ad7ae243b17f0c0ebfe575bbaf
WScanning /Users/rylanpolster/Desktop/rubocop-test/lib/rubocop/test/version.rb
Loading cache from /Users/rylanpolster/.cache/rubocop_cache/2c9471a62bcb70567f347d769fb45cd0173313ed/6d7a3b621ca1730e04accd938619e4bdab66cfb1/278c4c969bf9a250ce7dea8a0a74a2489e9948c4
.Scanning /Users/rylanpolster/Desktop/rubocop-test/rubocop-test.gemspec
Loading cache from /Users/rylanpolster/.cache/rubocop_cache/2c9471a62bcb70567f347d769fb45cd0173313ed/6d7a3b621ca1730e04accd938619e4bdab66cfb1/30efeb7f71f0ff8b0eac9f82e5d911ebcaa5a2ae
.Scanning /Users/rylanpolster/Desktop/rubocop-test/spec/rubocop/test_spec.rb
Loading cache from /Users/rylanpolster/.cache/rubocop_cache/2c9471a62bcb70567f347d769fb45cd0173313ed/6d7a3b621ca1730e04accd938619e4bdab66cfb1/14c9461f0e85c5bba9e1a207e916ec1318c1a7d6
.Scanning /Users/rylanpolster/Desktop/rubocop-test/spec/spec_helper.rb
Loading cache from /Users/rylanpolster/.cache/rubocop_cache/2c9471a62bcb70567f347d769fb45cd0173313ed/6d7a3b621ca1730e04accd938619e4bdab66cfb1/79fa9b3dc047bc6568f24fd1af5f3b8bbae7a04e
.

Offenses:

lib/rubocop/test.rb:13:78: W: Lint/ShadowedArgument: Argument skip_download was shadowed by a local variable before it was used.
    def download_to_target?(endpoint, target_exists:, other_conditions_met:, skip_download: false)
                                                                             ^^^^^^^^^^^^^^^^^^^^

8 files inspected, 1 offense detected
Finished in 0.1190679999999702 seconds

Steps to reproduce the problem

Run RuboCop on this method:

def download_to_target?(endpoint, target_exists:, other_conditions_met:, skip_download: false)
  skip_download = false unless target_exists
  skip_download ||= target_exists && other_conditions_met

  begin
    puts "Downloading file #{endpoint}" unless skip_download
  rescue StandardError
    skip_download = false
  end

  !skip_download
end

RuboCop version

$ bundle exec rubocop -V
1.80.1 (using Parser 3.3.9.0, rubocop-ast 1.46.0, analyzing as Ruby 3.1, running on ruby 3.4.4) +server [arm64-darwin24]

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