summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Zhu <peter@peterzhu.ca>2024-01-09 10:52:23 -0500
committerPeter Zhu <peter@peterzhu.ca>2024-01-09 12:24:18 -0500
commit55b7121358e2bed9b90001405b651f57fafbeaad (patch)
tree1e30043d2a8f1c1b3571320d03426cd23d6a6b9b
parent7015cb2479309541c58e4b269d6cb55f097be35e (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.c2
-rw-r--r--test/ruby/test_compile_prism.rb25
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