[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.
This commit is contained in:
Peter Zhu 2024-01-09 10:52:23 -05:00
parent 7015cb2479
commit 55b7121358
2 changed files with 17 additions and 8 deletions

View File

@ -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);

View File

@ -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
[
# 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
assert_equal ruby_eval, prism_eval, src
end
end
def test_SymbolNode