diff options
| author | Peter Zhu <peter@peterzhu.ca> | 2024-01-09 10:52:23 -0500 |
|---|---|---|
| committer | Peter Zhu <peter@peterzhu.ca> | 2024-01-09 12:24:18 -0500 |
| commit | 55b7121358e2bed9b90001405b651f57fafbeaad (patch) | |
| tree | 1e30043d2a8f1c1b3571320d03426cd23d6a6b9b | |
| parent | 7015cb2479309541c58e4b269d6cb55f097be35e (diff) | |
[PRISM] Frozen string literals should be fstrings
Frozen string literals should not just be frozen, but deduplicated as an
fstring so that two string literals with the same contents are the exact
same object.
Fixes ruby/prism#2095.
| -rw-r--r-- | prism_compile.c | 2 | ||||
| -rw-r--r-- | test/ruby/test_compile_prism.rb | 25 |
2 files changed, 18 insertions, 9 deletions
diff --git a/prism_compile.c b/prism_compile.c index 1df2ccf8b2..c7824cde21 100644 --- a/prism_compile.c +++ b/prism_compile.c @@ -6338,7 +6338,7 @@ pm_compile_node(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const ret, pm_string_node_t *cast = (pm_string_node_t *) node; VALUE value = parse_string_encoded(node, &cast->unescaped, parser); if (node->flags & PM_STRING_FLAGS_FROZEN) { - ADD_INSN1(ret, &dummy_line_node, putobject, rb_str_freeze(value)); + ADD_INSN1(ret, &dummy_line_node, putobject, rb_fstring(value)); } else { ADD_INSN1(ret, &dummy_line_node, putstring, value); diff --git a/test/ruby/test_compile_prism.rb b/test/ruby/test_compile_prism.rb index 5482a1529d..b02c1d09a3 100644 --- a/test/ruby/test_compile_prism.rb +++ b/test/ruby/test_compile_prism.rb @@ -638,14 +638,23 @@ module Prism assert_prism_eval('"pit"') assert_prism_eval('"a".frozen?') - frozen_source = <<-CODE - # frozen_string_literal: true - "a".frozen? - CODE - ruby_eval = RubyVM::InstructionSequence.compile(frozen_source).eval - prism_eval = RubyVM::InstructionSequence.compile_prism(frozen_source).eval - - assert_equal ruby_eval, prism_eval + [ + # Test that string literal is frozen + <<~RUBY, + # frozen_string_literal: true + "a".frozen? + RUBY + # Test that two string literals with the same contents are the same string + <<~RUBY, + # frozen_string_literal: true + "hello".equal?("hello") + RUBY + ].each do |src| + ruby_eval = RubyVM::InstructionSequence.compile(src).eval + prism_eval = RubyVM::InstructionSequence.compile_prism(src).eval + + assert_equal ruby_eval, prism_eval, src + end end def test_SymbolNode |
