Skip to content

Commit 5d75937

Browse files
authored
Fix incorrect location for parenthesized union AST nodes (#16552)
1 parent 8bace21 commit 5d75937

File tree

2 files changed

+17
-1
lines changed

2 files changed

+17
-1
lines changed

spec/compiler/parser/parser_spec.cr

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3424,6 +3424,19 @@ module Crystal
34243424
node_source(source, expressions[1].as(TypeDeclaration).var).should eq("buzz")
34253425
end
34263426

3427+
it "sets correct location of a parenthesized union" do
3428+
source = "foo : (String | Nil) | Foo"
3429+
node = Parser.new(source).parse.as(TypeDeclaration)
3430+
3431+
union = node.declared_type.should be_a Union
3432+
node_source(source, union)
3433+
.should eq("(String | Nil) | Foo")
3434+
3435+
inner_union = union.types.first.should be_a Union
3436+
node_source(source, inner_union)
3437+
.should eq("(String | Nil)")
3438+
end
3439+
34273440
it "doesn't override yield with macro yield" do
34283441
parser = Parser.new("def foo; yield 1; {% begin %} yield 1 {% end %}; end")
34293442
a_def = parser.parse.as(Def)

src/compiler/crystal/syntax/parser.cr

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5053,7 +5053,7 @@ module Crystal
50535053
types << parse_atomic_type_with_suffix
50545054
end
50555055

5056-
Union.new(types).at(types.first).at_end(types.last)
5056+
Union.new(types).at(type).at_end(types.last)
50575057
end
50585058

50595059
def parse_atomic_type_with_suffix
@@ -5101,6 +5101,9 @@ module Crystal
51015101
when .op_lparen?
51025102
next_token_skip_space_or_newline
51035103
type = parse_type_splat { parse_union_type }
5104+
if type.is_a?(Union)
5105+
type.at(location).at_end(@token.location)
5106+
end
51045107
if @token.type.op_rparen?
51055108
next_token_skip_space
51065109
if @token.type.op_minus_gt? # `(A) -> B` case

0 commit comments

Comments
 (0)