Actions
Bug #21758
closedPrism fails to parse heredoc within %Q literal split by another heredoc
Bug #21758:
Prism fails to parse heredoc within %Q literal split by another heredoc
ruby -v:
ruby 4.0.0dev (2025-12-02T16:20:43Z master c06c2203ed) +PRISM [x86_64-linux]
Description
Prism fails to parse this code
<<A; %Q
A
#{<<B}
B
Parse error:
a.rb:4: syntax error found (SyntaxError)
2 | A
3 | #{<<B}
> 4 | B
| ^ unexpected constant, expecting end-of-input
B at line 4 appears twice in lex result:
Prism.lex('<<A; %Q
A
#{<<B}
B
').value
#=>
[[HEREDOC_START(1,0)-(1,3)("<<A"), 1],
[HEREDOC_END(2,0)-(3,0)("A\n"), 2],
[SEMICOLON(1,3)-(1,4)(";"), 1],
[STRING_BEGIN(1,5)-(2,0)("%Q\n"), 1],
[EMBEXPR_BEGIN(3,0)-(3,2)("\#{"), 1],
[HEREDOC_START(3,2)-(3,5)("<<B"), 1],
[HEREDOC_END(4,0)-(5,0)("B\n"), 2], # B\n here
[EMBEXPR_END(3,5)-(3,6)("}"), 2],
[STRING_END(3,6)-(4,0)("\n"), 2],
[CONSTANT(4,0)-(4,1)("B"), 2], # Same B again here
[NEWLINE(4,1)-(5,0)("\n"), 1],
[EOF(4,1)-(5,0)("\n"), 1]]
Updated by Earlopain (Earlopain _) 20 days ago
It can be even simpler:
%Q
#{<<B}
B
Lex output similarly contains B twice.
Updated by kddnewton (Kevin Newton) 19 days ago
- Assignee set to prism
Updated by Earlopain (Earlopain _) 19 days ago
- Status changed from Open to Closed
Applied in changeset git|465a86c3417d2936c311d9571aa9b6494a83eed8.
[ruby/prism] Fix %Q with newline delimiter and heredoc interpolation
The lexer did not jump to the heredoc_end, causing the heredoc end delimiter
to be parsed twice.
Normally the heredocs get flushed when a newline is encountered. But because
the newline is part of the string delimiter, that codepath is not taken.
Fixes [Bug #21758]
https://github.com/ruby/prism/commit/7440eb4b11
Actions