sam.saffron / gmail.com wrote:
> Workaround ... whenever de-duping strings always use `-+`

Yes, String#-@ documentation states:

    "If the string is frozen, then return the string itself."

So I guess it is spec...

However, it seems compile-time can skip freezestring instructions
for -@ like it does with +@ since r62039

```
diff --git a/compile.c b/compile.c
index 5bca0dca99..7d065b25d3 100644
--- a/compile.c
+++ b/compile.c
@@ -2851,11 +2851,11 @@ iseq_peephole_optimize(rb_iseq_t *iseq, LINK_ELEMENT *list, const int do_tailcal
 	struct rb_call_info *ci = (struct rb_call_info *)OPERAND_AT(niobj, 0);
 	/*
 	 *  freezestring debug_info
-	 *  send <:+@, 0, ARG_SIMPLE>
+	 *  send <:+@, 0, ARG_SIMPLE>  # :-@, too
 	 * =>
-	 *  send <:+@, 0, ARG_SIMPLE>
+	 *  send <:+@, 0, ARG_SIMPLE>  # :-@, too
 	 */
-	if (ci->mid == idUPlus &&
+	if ((ci->mid == idUPlus || ci->mid == idUMinus) &&
 	    (ci->flag & VM_CALL_ARGS_SIMPLE) &&
 	    ci->orig_argc == 0) {
 	    ELEM_REMOVE(list);
diff --git a/test/ruby/test_optimization.rb b/test/ruby/test_optimization.rb
index 6e463e1863..55e7acbbf0 100644
--- a/test/ruby/test_optimization.rb
+++ b/test/ruby/test_optimization.rb
@@ -567,6 +567,21 @@ def test_peephole_string_literal_range
     end
   end
 
+  def test_peephole_dstr
+    code = "#{<<~'begin;'}\n#{<<~'end;'}"
+    begin;
+      exp = (-'a').object_id
+      z = 'a'
+      exp == (-"#{z}").object_id
+    end;
+    [ false, true ].each do |fsl|
+      iseq = RubyVM::InstructionSequence.compile(code,
+                                                 frozen_string_literal: fsl)
+      assert_equal(true, iseq.eval,
+                  "[ruby-core:85542] [Bug #14475] fsl: #{fsl}")
+    end
+  end
+
   def test_branch_condition_backquote
     bug = '[ruby-core:80740] [Bug #13444] redefined backquote should be called'
     class << self
```

Unsubscribe: <mailto:ruby-core-request / ruby-lang.org?subject=unsubscribe>
<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-core>