Trying to use aliases outside a namespace doesn't compile correctly:
alias Block = Array(ASTNode2)
alias ASTNode2 = Tuple(Block)
block = [] of ASTNode2
p ASTNode2.from([block])
will result in
Error in test2.cr:6: undefined method 'from' for ASTNode2:Class
p ASTNode2.from([block])
Wrapping this inside a module will work:
module Test2
alias Block = Array(ASTNode2)
alias ASTNode2 = Tuple(Block)
def self.run
block = [] of ASTNode2
p ASTNode2.from([block])
end
end
Test2.run
Using:
Crystal 0.25.1 [b782738ff] (2018-06-27)
LLVM: 4.0.0
Default target: x86_64-unknown-linux-gnu
Haven't read through https://github.com/crystal-lang/crystal/issues/5155 but this case might have been covered in that.
It looks like it's a recursive alias. Recursive aliases behave strange, they can't have class methods. You are lucky it works in some cases.
Recursive aliases will be eventually removed from the language, so it's better if you don't use them.
Yeah, it's a bummer that I made it this far without any issues with recursive aliases. If Crystal is going to eventually remove alias then the documentation shouldn't suggest using an alias for a recursive type alias. :(
How difficult would it be to fix this bug?
I just tried to understand when and how recursive aliases are solved/determined and I can't understand it. So for me the difficulty is "impossible" right now. But if someone else wants go give it a try, please go ahead.
Lets remove them.
Is that going to affect alias A = A | Array(A) ?
That's a recursive alias, so yes. However, thats also a non-terminating recursive alias so I can't see how it can be used currently.
Most helpful comment
Yeah, it's a bummer that I made it this far without any issues with recursive aliases. If Crystal is going to eventually remove alias then the documentation shouldn't suggest using an alias for a recursive type alias. :(