diff --git a/changelog/new_optimized_string_dup_for_performance_unfreeze_string.md b/changelog/new_optimized_string_dup_for_performance_unfreeze_string.md new file mode 100644 index 0000000000..120cb7695a --- /dev/null +++ b/changelog/new_optimized_string_dup_for_performance_unfreeze_string.md @@ -0,0 +1 @@ +* [#384](https://github.com/rubocop/rubocop-performance/issues/384): Support optimized `String#dup` for `Performance/UnfreezeString` when Ruby 3.3+. ([@koic][]) diff --git a/lib/rubocop/cop/performance/unfreeze_string.rb b/lib/rubocop/cop/performance/unfreeze_string.rb index 1b101dc8c8..7f4ef6bd67 100644 --- a/lib/rubocop/cop/performance/unfreeze_string.rb +++ b/lib/rubocop/cop/performance/unfreeze_string.rb @@ -15,8 +15,8 @@ module Performance # # @example # # bad - # ''.dup - # "something".dup + # ''.dup # when Ruby 3.2 or lower + # "something".dup # when Ruby 3.2 or lower # String.new # String.new('') # String.new('something') @@ -45,7 +45,7 @@ class UnfreezeString < Base PATTERN def on_send(node) - return unless dup_string?(node) || string_new?(node) + return unless (dup_string?(node) && target_ruby_version <= 3.2) || string_new?(node) add_offense(node) do |corrector| string_value = "+#{string_value(node)}" diff --git a/spec/rubocop/cop/performance/unfreeze_string_spec.rb b/spec/rubocop/cop/performance/unfreeze_string_spec.rb index d8e27b6151..c782e78966 100644 --- a/spec/rubocop/cop/performance/unfreeze_string_spec.rb +++ b/spec/rubocop/cop/performance/unfreeze_string_spec.rb @@ -1,15 +1,25 @@ # frozen_string_literal: true RSpec.describe RuboCop::Cop::Performance::UnfreezeString, :config do - it 'registers an offense and corrects for an empty string with `.dup`' do - expect_offense(<<~RUBY) - "".dup - ^^^^^^ Use unary plus to get an unfrozen string literal. - RUBY + context 'when Ruby <= 3.2', :ruby32 do + it 'registers an offense and corrects for an empty string with `.dup`' do + expect_offense(<<~RUBY) + "".dup + ^^^^^^ Use unary plus to get an unfrozen string literal. + RUBY - expect_correction(<<~RUBY) - +"" - RUBY + expect_correction(<<~RUBY) + +"" + RUBY + end + end + + context 'when Ruby >= 3.3', :ruby33 do + it 'does not register an offense and corrects for an empty string with `.dup`' do + expect_no_offenses(<<~RUBY) + "".dup + RUBY + end end it 'registers an offense and corrects for a string with `.dup`' do