I'm maintaining https://github.com/chenkovsky/docopt.cr 。after upgrading to 0.19.X, I find compiler complains "no overload matches". but when I remove the types from init function, it compiles.
I try to find a smaller example, but failed. sorry.
my code looks like that
class MyClass
....
@name : (String | Nil)
@value : (Nil | String | Int32 | Bool | Array(String))
def initialize(@name : (String | Nil), @value : (Nil | String | Int32 | Bool | Array(String)) = nil)
# def initialize(@name, @value = nil) # if I use this function, it compiles.
....
end
@chenkovsky:
What kind of benefits are you looking for, declaring the types in the body of the class and in the constructor?
This similar code works
class MyClass
@name : (String | Nil)
@value : (Nil | String | Int32 | Bool | Array(String))
def initialize(@name = nil, @value = nil)
pp @name
end
end
MyClass.new name: "test"
# MyClass.new name: 1 => This doesn't compile because instantiation of @name Class variable doesn't allow Int32 type
@chenkovsky:
I could not replicate this issue in the play.crystal-lang.org environment.
https://play.crystal-lang.org/#/r/1atz
@raydf , the code just shows where the compiler complains. it's not the simplest case that you can replicate this issue(I try to find one, but failed). If you want to replicate this issue. please checkout the repo https://github.com/chenkovsky/docopt.cr, and apply the patch. then run crystal spec
@chenkovsky
In the shard code i replicated the error, maybe someone else could reduce the code further.
Just as additional information using aliases for the union types in the constructor method, works correct:
alias NameType = (String | Nil)
alias ValueType = (Nil | String | Int32 | Bool | Array(String))
getter name : NameType
property value : ValueType
def initialize(@name : NameType, @value : ValueType = nil)
@children = nil.as(Array(Pattern) | Nil)
end
in my another project, compiler always complain.
no overload matches 'MyClass.new' with type Array(String)+
Overloads are:
i think these are the same bug.
@chenkovsky can you provide a sample code on how MyClass is being initialized?
Reduced:
class Gen(T)
end
class Sub < Gen(String)
end
def foo(x : Gen(String))
end
foo(Gen(String).new.as(Gen(String)))
Most helpful comment
Reduced: