abstract struct Parent
abstract def work(a : Int32, b : Int32)
def get
->work(Int32,Int32)
end
end
struct Child1 < Parent
def work(a : Int32, b : Int32)
a + b
end
end
struct Child2 < Parent
def work(a : Int32, b : Int32)
a - b
end
end
pp [Child1.new,Child2.new].map(&.get)
Above code triggers below Compiler exception
2 target defs for work(arg0, arg1) (Exception)
from raise<Exception>:NoReturn
from raise<String>:NoReturn
from Crystal::ASTNode+@Crystal::ASTNode#accept<Crystal::CodeGenVisitor>:Nil
from Crystal::CodeGenVisitor#codegen_fun<String, Crystal::Def+, Crystal::Type+, Bool, Crystal::CodeGenVisitor::ModuleInfo, Bool, Bool>:LLVM::Function
from Crystal::CodeGenVisitor#target_def_fun<Crystal::Def+, Crystal::Type+>:LLVM::Function
from Crystal::CodeGenVisitor#visit<Crystal::Call>:Bool
from Crystal::ASTNode+@Crystal::ASTNode#accept<Crystal::CodeGenVisitor>:Nil
from Crystal::ASTNode+@Crystal::ASTNode#accept<Crystal::CodeGenVisitor>:Nil
from Crystal::ASTNode+@Crystal::ASTNode#accept<Crystal::CodeGenVisitor>:Nil
from Crystal::CodeGenVisitor#prepare_call_args_non_external<Crystal::Call, Crystal::Def+, Crystal::Type+>:Tuple(Array(LLVM::Value), Bool)
from Crystal::CodeGenVisitor#visit<Crystal::Call>:Bool
from Crystal::ASTNode+@Crystal::ASTNode#accept<Crystal::CodeGenVisitor>:Nil
from Crystal::ASTNode+@Crystal::ASTNode#accept<Crystal::CodeGenVisitor>:Nil
from Crystal::ASTNode+@Crystal::ASTNode#accept<Crystal::CodeGenVisitor>:Nil
from Crystal::ASTNode+@Crystal::ASTNode#accept<Crystal::CodeGenVisitor>:Nil
from Crystal::ASTNode+@Crystal::ASTNode#accept<Crystal::CodeGenVisitor>:Nil
from Crystal::CodeGenVisitor#visit<Crystal::Call>:Bool
from Crystal::ASTNode+@Crystal::ASTNode#accept<Crystal::CodeGenVisitor>:Nil
from Crystal::ASTNode+@Crystal::ASTNode#accept<Crystal::CodeGenVisitor>:Nil
from Crystal::ASTNode+@Crystal::ASTNode#accept<Crystal::CodeGenVisitor>:Nil
from Crystal::CodeGenVisitor#prepare_call_args_non_external<Crystal::Call, Crystal::Def+, Crystal::Type+>:Tuple(Array(LLVM::Value), Bool)
from Crystal::CodeGenVisitor#visit<Crystal::Call>:Bool
from Crystal::ASTNode+@Crystal::ASTNode#accept<Crystal::CodeGenVisitor>:Nil
from Crystal::CodeGenVisitor#prepare_call_args_non_external<Crystal::Call, Crystal::Def+, Crystal::Type+>:Tuple(Array(LLVM::Value), Bool)
from Crystal::CodeGenVisitor#visit<Crystal::Call>:Bool
from Crystal::ASTNode+@Crystal::ASTNode#accept<Crystal::CodeGenVisitor>:Nil
from Crystal::ASTNode+@Crystal::ASTNode#accept<Crystal::CodeGenVisitor>:Nil
from Crystal::CodeGenVisitor#visit<Crystal::Call>:Bool
from Crystal::ASTNode+@Crystal::ASTNode#accept<Crystal::CodeGenVisitor>:Nil
from Crystal::CodeGenVisitor#visit<Crystal::Call>:Bool
from Crystal::ASTNode+@Crystal::ASTNode#accept<Crystal::CodeGenVisitor>:Nil
from Crystal::CodeGenVisitor#visit<Crystal::Call>:Bool
from Crystal::ASTNode+@Crystal::ASTNode#accept<Crystal::CodeGenVisitor>:Nil
from Crystal::CodeGenVisitor#prepare_call_args_non_external<Crystal::Call, Crystal::Def+, Crystal::Type+>:Tuple(Array(LLVM::Value), Bool)
from Crystal::CodeGenVisitor#visit<Crystal::Call>:Bool
from Crystal::ASTNode+@Crystal::ASTNode#accept<Crystal::CodeGenVisitor>:Nil
from Crystal::ASTNode+@Crystal::ASTNode#accept<Crystal::CodeGenVisitor>:Nil
from Crystal::Compiler#codegen<Crystal::Program, Crystal::ASTNode+, Array(Crystal::Compiler::Source), String>:(Tuple(Array(Crystal::Compiler::CompilationUnit), Array(String)) | Nil)
from Crystal::Compiler#compile<Array(Crystal::Compiler::Source), String>:Crystal::Compiler::Result
from Crystal::Command#run_command<Bool>:Nil
from Crystal::Command#run:(Bool | Nil)
from __crystal_main
from main
Error: you've found a bug in the Crystal compiler. Please open an issue, including source code that will allow us to reproduce the bug: https://github.com/crystal-lang/crystal/issues
is this a bug? or code logic is defeating the intention? Intention of raising this was to bring this (assumed bug) to light, but if this is intended behavior, then better close this issue to avoid false alarm.
It's a bug
To clarify a bit more, ->work(Int32,Int32) refers to a Proc that will have to do multiple dispatch over the Parent subclasses. But that (multidispatch) wasn't contemplated when we implemented procs so it's not working right. Ideally it should work but it's a bit hard to implement.
As a workaround use ->self.work(Int32, Int32) on 1.0.0-dev
abstract struct Parent
abstract def work(a : Int32, b : Int32)
def get
->self.work(Int32, Int32)
end
end
Most helpful comment
As a workaround use
->self.work(Int32, Int32)on 1.0.0-dev