Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Compiler error when subclassing HTTP::Handler with a generic class #2051

Closed
porras opened this issue Jan 24, 2016 · 2 comments
Closed

Compiler error when subclassing HTTP::Handler with a generic class #2051

porras opened this issue Jan 24, 2016 · 2 comments
Labels
kind:bug A bug in the code. Does not apply to documentation, specs, etc. topic:compiler

Comments

@porras
Copy link
Contributor

porras commented Jan 24, 2016

Hi, I think I hit a weird one 😁

There is a very specific combination of things that I need to do to trigger this bug. I think this is the minimal code that reproduces the bug, at least anything that I remove from it fixes the issue:

require "http/server"

class MyGenericHandler(T) < HTTP::Handler
  def call(context)
    call_next(context)
  end
end

class MyNormalHandler < HTTP::Handler
  def call(context)
  end
end

my = MyNormalHandler.new

p my

server = HTTP::Server.new("0.0.0.0", "3000", [
  HTTP::ErrorHandler.new,
  MyGenericHandler(String).new,
  my,
])

Output on current master (cf019e2):

$ ../crystal/bin/crystal build bug.cr
Using compiled compiler at .build/crystal
Bug: MyGenericHandler(String) doesn't implement add_def
[4315258786] *CallStack::unwind:Array(Pointer(Void)) +82
[4315258689] *CallStack#initialize<CallStack>:Array(Pointer(Void)) +17
[4315258648] *CallStack::new:CallStack +40
[4315262321] *Exception#initialize<Exception, String, Nil>:CallStack +33
[4315262252] *Exception::new<String>:Exception +92
[4315101497] *raise<String>:NoReturn +9
[4316424383] *Crystal::Type+@Crystal::Type#add_def<Crystal::Type+, Crystal::Def>:NoReturn +79
[4316686014] *Crystal::VirtualType@Crystal::VirtualTypeLookup#lookup_matches<Crystal::VirtualType, Crystal::CallSignature, Crystal::VirtualType, Crystal::VirtualType>:Crystal::Matches +13166
[4316672732] *Crystal::VirtualType@Crystal::VirtualTypeLookup#lookup_matches<Crystal::VirtualType, Crystal::CallSignature>:Crystal::Matches +108
[4319476613] *Crystal::Call#lookup_matches_with_signature<Crystal::Call, Crystal::Type+, Crystal::CallSignature, Bool>:Crystal::Matches +389
[4319474882] *Crystal::Call#lookup_matches_checking_expansion<Crystal::Call, Crystal::Type+, Crystal::CallSignature, Bool>:Crystal::Matches +9570
[4319443184] *Crystal::Call#lookup_matches_in_type<Crystal::Call, Crystal::Type+, Array(Crystal::Type+), Nil, String, Bool>:Array(Crystal::Def+) +624
[4319442544] *Crystal::Call#lookup_matches_in<Crystal::Call, Crystal::Type+, Array(Crystal::Type+), Nil, String, Bool>:Array(Crystal::Def+) +16
[4319442508] *Crystal::Call#lookup_matches_in:search_in_parents<Crystal::Call, Crystal::Type+, Array(Crystal::Type+), Bool>:Array(Crystal::Def+) +508
[4319310501] *Crystal::Call#lookup_matches_in<Crystal::Call, Crystal::UnionType+, Array(Crystal::Type+), Nil, String, Bool>:Array(Crystal::Def+) +581
[4319533601] *Crystal::Call#lookup_matches_in<Crystal::Call, Crystal::UnionType+, Array(Crystal::Type+)>:Array(Crystal::Def+) +65
[4319308375] *Crystal::Call#lookup_matches_without_splat<Crystal::Call, Array(Crystal::Type+)>:Array(Crystal::Def+) +199
[4319307700] *Crystal::Call#lookup_matches<Crystal::Call>:Array(Crystal::Def+) +420
[4319203854] *Crystal::Call#recalculate<Crystal::Call>:Array(Crystal::Def+)? +1534
[4324645970] *Crystal::TypeVisitor#visit<Crystal::TypeVisitor, Crystal::Call>:Bool +2322
[4315519909] *Crystal::ASTNode+@Crystal::ASTNode#accept<Crystal::ASTNode+, Crystal::TypeVisitor>:Nil +1589
[4318904672] *Crystal::Expressions#accept_children<Crystal::Expressions, Crystal::TypeVisitor>:Array(Crystal::ASTNode+) +96
[4315527441] *Crystal::ASTNode+@Crystal::ASTNode#accept<Crystal::ASTNode+, Crystal::TypeVisitor>:Nil +9121
[4324671985] *Crystal::TypeVisitor#visit<Crystal::TypeVisitor, Crystal::Block>:(Nil | Bool) +1953
[4319628928] *Crystal::Block@Crystal::ASTNode#accept<Crystal::Block, Crystal::TypeVisitor>:Nil +48
[4324642119] *Crystal::TypeVisitor#visit<Crystal::TypeVisitor, Crystal::Yield>:Bool +4215
[4315519545] *Crystal::ASTNode+@Crystal::ASTNode#accept<Crystal::ASTNode+, Crystal::TypeVisitor>:Nil +1225
[4324630920] *Crystal::TypeVisitor#type_assign<Crystal::TypeVisitor, Crystal::Var+, Crystal::ASTNode+, Crystal::Assign>:Crystal::MetaVar? +40
[4324629997] *Crystal::TypeVisitor#visit<Crystal::TypeVisitor, Crystal::Assign>:Bool +109
[4315519282] *Crystal::ASTNode+@Crystal::ASTNode#accept<Crystal::ASTNode+, Crystal::TypeVisitor>:Nil +962
[4318904672] *Crystal::Expressions#accept_children<Crystal::Expressions, Crystal::TypeVisitor>:Array(Crystal::ASTNode+) +96
[4315527441] *Crystal::ASTNode+@Crystal::ASTNode#accept<Crystal::ASTNode+, Crystal::TypeVisitor>:Nil +9121
[4324695405] *Crystal::TypeVisitor#visit<Crystal::TypeVisitor, Crystal::If>:Bool +1021
[4315521413] *Crystal::ASTNode+@Crystal::ASTNode#accept<Crystal::ASTNode+, Crystal::TypeVisitor>:Nil +3093
[4318904672] *Crystal::Expressions#accept_children<Crystal::Expressions, Crystal::TypeVisitor>:Array(Crystal::ASTNode+) +96
[4315527441] *Crystal::ASTNode+@Crystal::ASTNode#accept<Crystal::ASTNode+, Crystal::TypeVisitor>:Nil +9121
[4319532159] *Crystal::Call#instantiate<Crystal::Call, Crystal::Matches, Crystal::Type+, Nil>:Array(Crystal::Def+) +9375
[4319462508] *Crystal::Call#lookup_matches_in_type<Crystal::Call, Crystal::Type+, Array(Crystal::Type+), Nil, String, Bool>:Array(Crystal::Def+) +19948
[4319442544] *Crystal::Call#lookup_matches_in<Crystal::Call, Crystal::Type+, Array(Crystal::Type+), Nil, String, Bool>:Array(Crystal::Def+) +16
[4319534705] *Crystal::Call#lookup_matches_in<Crystal::Call, Crystal::Type+, Array(Crystal::Type+)>:Array(Crystal::Def+) +513
[4319309197] *Crystal::Call#lookup_matches_without_splat<Crystal::Call, Array(Crystal::Type+)>:Array(Crystal::Def+) +1021
[4319307700] *Crystal::Call#lookup_matches<Crystal::Call>:Array(Crystal::Def+) +420
[4319203854] *Crystal::Call#recalculate<Crystal::Call>:Array(Crystal::Def+)? +1534
[4324645970] *Crystal::TypeVisitor#visit<Crystal::TypeVisitor, Crystal::Call>:Bool +2322
[4315519909] *Crystal::ASTNode+@Crystal::ASTNode#accept<Crystal::ASTNode+, Crystal::TypeVisitor>:Nil +1589
[4324630920] *Crystal::TypeVisitor#type_assign<Crystal::TypeVisitor, Crystal::Var+, Crystal::ASTNode+, Crystal::Assign>:Crystal::MetaVar? +40
[4324629997] *Crystal::TypeVisitor#visit<Crystal::TypeVisitor, Crystal::Assign>:Bool +109
[4315519282] *Crystal::ASTNode+@Crystal::ASTNode#accept<Crystal::ASTNode+, Crystal::TypeVisitor>:Nil +962
[4318904672] *Crystal::Expressions#accept_children<Crystal::Expressions, Crystal::TypeVisitor>:Array(Crystal::ASTNode+) +96
[4315527441] *Crystal::ASTNode+@Crystal::ASTNode#accept<Crystal::ASTNode+, Crystal::TypeVisitor>:Nil +9121
[4316098524] *Crystal::Program#expand_macro_def<Crystal::Program, Crystal::Def+>:Nil +2252
[4316096253] *Crystal::Program#expand_macro_defs<Crystal::Program>:Nil +77
[4316096096] *Crystal::Program#infer_type_intermediate<Crystal::Program, Crystal::Expressions>:Crystal::Expressions +80
[4316095867] *Crystal::Program#infer_type<Crystal::Program, Crystal::Expressions>:Crystal::Expressions +59
[4325162883] *Crystal::Compiler#infer_type<Crystal::Compiler, Crystal::Program, Crystal::Expressions>:Crystal::Expressions +211
[4325159432] *Crystal::Compiler#compile<Crystal::Compiler, Array(Crystal::Compiler::Source), String>:Crystal::Compiler::Result +456
[4326310684] *Crystal::Command::CompilerConfig#compile<Crystal::Command::CompilerConfig, String>:Crystal::Compiler::Result +92
[4326277855] *Crystal::Command#run_command<Crystal::Command>:Nil +399
[4326267394] *Crystal::Command#run<Crystal::Command>:(Nil | Bool | Array(String) | IO::FileDescriptor+ | Crystal::Compiler::Result | Array(Crystal::ImplementationTrace) | Array(Crystal::Init::View+:Class)) +1586
[4326265500] *Crystal::Command::run<Array(String)>:(Nil | Bool | Array(String) | IO::FileDescriptor+ | Crystal::Compiler::Result | Array(Crystal::ImplementationTrace) | Array(Crystal::Init::View+:Class)) +44
[4326265373] *Crystal::Command::run:(Nil | Bool | Array(String) | IO::FileDescriptor+ | Crystal::Compiler::Result | Array(Crystal::ImplementationTrace) | Array(Crystal::Init::View+:Class)) +45
[4315101006] __crystal_main +56734
[4315132063] main +47

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/manastech/crystal/issues

Note that I don't need to call server.listen for the issue to appear (but doing it doesn't fix it).

When I say “anything that I remove from it fixes the issue” I specifically include:

  • Removing the type parameter on the handler subclass
  • Removing the generic handler from the handlers chain
  • Removing the normal handler from the handlers chain
  • Removing the error handler from the handlers chain (other builtin handlers such as the log handler didn't cause the issue)
  • And, in case some of those are not weird enough, here comes the weirdest: removing the inspection of the handler instance. Note that I'm not inspecting the potentially problematic one with the type parameter, but the other one 😮

When I start the server with any of those fixes applied, it works perfectly fine. I'm on a Mac with Yosemite, in case that's relevant.

I wasn't sure whether subclassing a non-generic class adding a type parameter was supported but it seems to work fine everywhere else (and in fact here unless this specific combination of things are present).

@asterite
Copy link
Member

Seems like a duplicate of #846, but I'm not sure. Now that there's a first pass that defines classes and methods this might be easier to solve.

@asterite asterite added kind:bug A bug in the code. Does not apply to documentation, specs, etc. topic:compiler labels Jan 24, 2016
@asterite
Copy link
Member

Closed in favor of #2665

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
kind:bug A bug in the code. Does not apply to documentation, specs, etc. topic:compiler
Projects
None yet
Development

No branches or pull requests

2 participants