diff --git a/prism/prism.c b/prism/prism.c
index 1cc999e31e..9922f57722 100644
--- a/prism/prism.c
+++ b/prism/prism.c
@@ -12543,6 +12543,34 @@ parse_symbol(pm_parser_t *parser, pm_lex_mode_t *lex_mode, pm_lex_state_t next_s
content = parser->current;
unescaped = parser->current_string;
parser_lex(parser);
+
+ // If we have two string contents in a row, then the content of this
+ // symbol is split because of heredoc contents. This looks like:
+ //
+ // <current, &bounds, &parser->current_string);
+ pm_node_list_append(&parts, part);
+
+ if (next_state != PM_LEX_STATE_NONE) {
+ lex_state_set(parser, next_state);
+ }
+
+ parser_lex(parser);
+ expect1(parser, PM_TOKEN_STRING_END, PM_ERR_SYMBOL_TERM_DYNAMIC);
+ return (pm_node_t *) pm_interpolated_symbol_node_create(parser, &opening, &parts, &parser->previous);
+ }
} else {
content = (pm_token_t) { .type = PM_TOKEN_STRING_CONTENT, .start = parser->previous.end, .end = parser->previous.end };
pm_string_shared_init(&unescaped, content.start, content.end);
diff --git a/test/prism/fixtures/spanning_heredoc.txt b/test/prism/fixtures/spanning_heredoc.txt
index c1b9ec72f4..d09cb11b1f 100644
--- a/test/prism/fixtures/spanning_heredoc.txt
+++ b/test/prism/fixtures/spanning_heredoc.txt
@@ -53,3 +53,11 @@ p]
<)/ =~ ''
+
+<)"
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── unescaped: "(?)"
+ │ │ │ └── closing_loc: (55,6)-(55,7) = "/"
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :=~
+ │ │ ├── message_loc: (55,8)-(55,10) = "=~"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments:
+ │ │ │ @ ArgumentsNode (location: (55,11)-(55,13))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── arguments: (length: 1)
+ │ │ │ └── @ StringNode (location: (55,11)-(55,13))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── opening_loc: (55,11)-(55,12) = "'"
+ │ │ │ ├── content_loc: (55,12)-(55,12) = ""
+ │ │ │ ├── closing_loc: (55,12)-(55,13) = "'"
+ │ │ │ └── unescaped: ""
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ └── targets: (length: 1)
+ │ └── @ LocalVariableTargetNode (location: (53,5)-(55,7))
+ │ ├── name: :a
+ │ └── depth: 0
+ ├── @ StringNode (location: (57,0)-(57,3))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (57,0)-(57,3) = "<)"
- │ │ │ ├── closing_loc: ∅
- │ │ │ └── unescaped: "(?)"
- │ │ └── closing_loc: (55,6)-(55,7) = "/"
- │ ├── call_operator_loc: ∅
- │ ├── name: :=~
- │ ├── message_loc: (55,8)-(55,10) = "=~"
- │ ├── opening_loc: ∅
- │ ├── arguments:
- │ │ @ ArgumentsNode (location: (55,11)-(55,13))
- │ │ ├── flags: ∅
- │ │ └── arguments: (length: 1)
- │ │ └── @ StringNode (location: (55,11)-(55,13))
- │ │ ├── flags: ∅
- │ │ ├── opening_loc: (55,11)-(55,12) = "'"
- │ │ ├── content_loc: (55,12)-(55,12) = ""
- │ │ ├── closing_loc: (55,12)-(55,13) = "'"
- │ │ └── unescaped: ""
- │ ├── closing_loc: ∅
- │ └── block: ∅
- └── targets: (length: 1)
- └── @ LocalVariableTargetNode (location: (53,5)-(55,7))
- ├── name: :a
- └── depth: 0
+ │ │ ├── opening_loc: ∅
+ │ │ ├── content_loc: (61,7)-(62,0) = "a\n"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "a\n"
+ │ └── @ StringNode (location: (63,0)-(63,1))
+ │ ├── flags: ∅
+ │ ├── opening_loc: ∅
+ │ ├── content_loc: (63,0)-(63,1) = "b"
+ │ ├── closing_loc: ∅
+ │ └── unescaped: "b"
+ └── closing_loc: (63,1)-(63,2) = "\""