Open Blacksmoke16 opened 6 months ago
It looks like this snippet straight up parses to something without the id
at all:
macro f(x)
{% p x %} # => class Foo; property = 1; end
end
f(class Foo
property id: Int32? = 1
end)
So it turns out the parser is very lax when detecting valid assignment targets. In particular, Crystal::Parser#can_be_assigned?
accepts far more Call
nodes than #multi_assign_target?
, so all the following lines have a similar issue:
foo() = 1 # => foo = 1
foo(x: 1) = 2 # => foo = 2
foo.[](1) = 2 # => foo[1] = 2
foo.[](x: 1) = 2 # => foo[x: 1] = 2
foo.[](&.bar) = 2 # => foo.[]=(2, &.bar)
foo x: 1 = 2 # => foo = 2
# these type names are also valid regular code
foo x: T? = 1 # => foo = 1
foo x: {T} = 1 # => foo = 1
foo x: {y: T} = 1 # => foo = 1
But note:
foo x: T = 1 # => foo(x: T = 1)
foo x: T[1] = 1 # => foo(x: T[1] = 1)
foo x: T* = 1 # Error: unexpected token: "="
The lines that involve parentheses should definitely be syntax errors.
Trying to format this results in:
Seems it does not like the invalid syntax in combination with an assignment to a nilable type.
Also somewhat related to https://github.com/crystal-lang/crystal/issues/10698.