crystal-lang / crystal

The Crystal Programming Language
https://crystal-lang.org
Apache License 2.0
19.46k stars 1.62k forks source link

BUG: called type_id for A+.class (Crystal::VirtualMetaclassType) #11668

Open BrucePerens opened 2 years ago

BrucePerens commented 2 years ago

I reached this while tracing the cause of #11657

Crystal 1.2.2 [6529d725a] (2021-11-10)

LLVM: 10.0.0
Default target: x86_64-unknown-linux-gnu

This program:

class A
end

class B < A
end

klass : A.class = B.class.as(A.class)

Causes the compiler to report a bug this way:

BUG: called type_id for A+.class (Crystal::VirtualMetaclassType) (Exception)
  from /crystal/src/string.cr:5232:0 in 'type_id'
  from /crystal/src/int.cr:1277:11 in 'type_id'
  from /crystal/src/compiler/crystal/codegen/match.cr:25:5 in 'match_type_id'
  from /crystal/src/compiler/crystal/codegen/codegen.cr:1313:17 in 'accept'
  from /crystal/src/compiler/crystal/codegen/codegen.cr:2274:9 in 'codegen_assign'
  from /crystal/src/compiler/crystal/codegen/codegen.cr:1169:11 in 'accept'
  from /crystal/src/compiler/crystal/codegen/codegen.cr:667:9 in 'accept'
  from /crystal/src/compiler/crystal/codegen/codegen.cr:2244:7 in 'codegen'
  from /crystal/src/compiler/crystal/compiler.cr:169:16 in 'compile'
  from /crystal/src/compiler/crystal/command.cr:210:5 in 'run_command'
  from /crystal/src/compiler/crystal/command.cr:117:7 in 'run'
  from /crystal/src/compiler/crystal.cr:11:1 in '__crystal_main'
  from /crystal/src/crystal/main.cr:110:5 in 'main'
  from src/env/__libc_start_main.c:94:2 in 'libc_start_main_stage2'
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

Use case is a table of classes derived from A, which are instantiated by calling table[n].new . My code does not hit the above report, but code generation for instantiating the derived class fails with a null reference in llvm if the derived class has any member variables.

Blacksmoke16 commented 2 years ago

Actually unintentionally managed to reproduce this in a different way:

ccrystal eval 'Union(ArgumentError, IndexError)'
Using compiled compiler at /home/george/dev/git/crystal/.build/crystal
BUG: called type_id for Exception+.class (Crystal::VirtualMetaclassType) (Exception)
from /home/george/dev/git/crystal/src/compiler/crystal/codegen/llvm_id.cr:43:5 in 'type_id'
from /home/george/dev/git/crystal/src/compiler/crystal/codegen/type_id.cr:68:9 in 'type_id_impl'
from /home/george/dev/git/crystal/src/compiler/crystal/codegen/type_id.cr:9:5 in 'type_id'
from /home/george/dev/git/crystal/src/compiler/crystal/codegen/codegen.cr:1493:15 in 'visit'
from /home/george/dev/git/crystal/src/compiler/crystal/syntax/visitor.cr:27:12 in 'accept'
from /home/george/dev/git/crystal/src/compiler/crystal/codegen/codegen.cr:2281:7 in 'accept'
from /home/george/dev/git/crystal/src/compiler/crystal/codegen/codegen.cr:667:9 in 'visit'
from /home/george/dev/git/crystal/src/compiler/crystal/syntax/visitor.cr:27:12 in 'accept'
from /home/george/dev/git/crystal/src/compiler/crystal/codegen/codegen.cr:2281:7 in 'accept'
from /home/george/dev/git/crystal/src/compiler/crystal/codegen/codegen.cr:69:7 in 'codegen'
from /home/george/dev/git/crystal/src/compiler/crystal/codegen/codegen.cr:67:5 in 'codegen:debug:single_module'
from /home/george/dev/git/crystal/src/compiler/crystal/progress_tracker.cr:22:7 in 'codegen'
from /home/george/dev/git/crystal/src/compiler/crystal/compiler.cr:173:16 in 'compile'
from /home/george/dev/git/crystal/src/compiler/crystal/command/eval.cr:29:14 in 'eval'
from /home/george/dev/git/crystal/src/compiler/crystal/command.cr:99:7 in 'run'
from /home/george/dev/git/crystal/src/compiler/crystal/command.cr:51:5 in 'run'
from /home/george/dev/git/crystal/src/compiler/crystal/command.cr:50:3 in 'run'
from /home/george/dev/git/crystal/src/compiler/crystal.cr:11:1 in '__crystal_main'
from /home/george/dev/git/crystal/src/crystal/main.cr:115:5 in 'main_user_code'
from /home/george/dev/git/crystal/src/crystal/main.cr:101:7 in 'main'
from /home/george/dev/git/crystal/src/crystal/main.cr:127:3 in 'main'
from /usr/lib/libc.so.6 in '__libc_start_main'
from /home/george/dev/git/crystal/.build/crystal in '_start'
from ??

Assuming it's the same bug based on the exception, but :shrug:.

HertzDevil commented 2 years ago

B.class in normal code is the value Class of type Class, so there is a downcast involved here. You probably want B.as(A.class).

BrucePerens commented 2 years ago

B.class in normal code is the value Class of type Class, so there is a downcast involved here. You probably want B.as(A.class).

Oh, you're right. Still a compiler bug :-) . I'll take a closer look at the actual problem code in my application, but what I am getting is that a class derived from A is instantiated through table[n].new and the code generation fails if there is any member variable in the class.

BrucePerens commented 2 years ago

It turns out the cause of #11657 is a different bug, see #11673

digitalshow commented 1 year ago

I got the same error message (don't have a stack trace) in another case (Crystal 1.6.2):

require "json"

abstract class A
  include JSON::Serializable

  use_json_discriminator "type", {b: B, c: C}
  property type : String
end

class B < A
end

class C < A
end

Tuple(String, A).from_json("")

It seems to only happen with Tuple though.