crystal-lang / crystal

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

Internal compiler BUG check "has no type" triggered at semantic/bindings.cr:13 #9702

Open BrucePerens opened 4 years ago

BrucePerens commented 4 years ago

This code fragment triggers the internal compiler BUG check for "has no type" at semantic/bindings.cr:13

class AnyValue
end

class MyValue(MyValueType, DataType)
  def set_data(value)
    t = DataType
    if t.is_a?(Array(AnyValue))
      new_array = t.new
      value.each do |v|
        if v.is_a?(typeof(new_array.last))
        end
      end
    end
  end
end

n = MyValue(Bool, AnyValue).new
a = Array(AnyValue).new
n.set_data(a)

I get this stack dump:

BUG: `typeof(new_array.last)` at /home/bruce/Crystal/pbx/funky/foo.cr:10:20 has no type (Exception)
  from ../../../../../crystal/src/compiler/crystal/semantic/bindings.cr:13:18 in 'visit'
  from ../../../../../crystal/src/compiler/crystal/syntax/visitor.cr:27:12 in 'accept'
  from ../../../../../crystal/src/compiler/crystal/semantic/main_visitor.cr:3318:9 in 'visit'
  from ../../../../../crystal/src/compiler/crystal/syntax/visitor.cr:27:12 in 'accept'
  from ../../../../../crystal/src/compiler/crystal/semantic/main_visitor.cr:1137:7 in 'visit'
  from ../../../../../crystal/src/compiler/crystal/syntax/visitor.cr:27:12 in 'accept'
  from ../../../../../crystal/src/compiler/crystal/semantic/main_visitor.cr:1051:9 in 'visit'
  from ../../../../../crystal/src/compiler/crystal/syntax/visitor.cr:27:12 in 'accept'
  from ../../../../../crystal/src/compiler/crystal/semantic/main_visitor.cr:1137:7 in 'visit'
  from ../../../../../crystal/src/compiler/crystal/syntax/visitor.cr:27:12 in 'accept'
  from ../../../../../crystal/src/compiler/crystal/semantic/main_visitor.cr:1051:9 in 'visit'
  from ../../../../../crystal/src/compiler/crystal/syntax/visitor.cr:27:12 in 'accept'
  from ../../../../../crystal/src/compiler/crystal/syntax/ast.cr:169:27 in 'accept'
  from ../../../../../crystal/src/compiler/crystal/semantic/main_visitor.cr:2134:9 in 'visit'
  from ../../../../../crystal/src/compiler/crystal/syntax/visitor.cr:27:12 in 'accept'
  from ../../../../../crystal/src/compiler/crystal/syntax/ast.cr:169:27 in 'accept'
  from ../../../../../crystal/src/compiler/crystal/semantic/call.cr:438:13 in 'instantiate'
  from ../../../../../crystal/src/compiler/crystal/semantic/call.cr:313:5 in 'lookup_matches_in_type'
  from ../../../../../crystal/src/compiler/crystal/semantic/call.cr:262:3 in 'lookup_matches_in:with_literals'
  from ../../../../../crystal/src/compiler/crystal/semantic/call.cr:135:7 in 'lookup_matches:with_literals'
  from ../../../../../crystal/src/compiler/crystal/semantic/call.cr:121:5 in 'recalculate'
  from ../../../../../crystal/src/compiler/crystal/semantic/main_visitor.cr:1475:7 in 'visit'
  from ../../../../../crystal/src/compiler/crystal/syntax/visitor.cr:27:12 in 'accept'
  from ../../../../../crystal/src/compiler/crystal/semantic/call.cr:438:13 in 'instantiate'
  from ../../../../../crystal/src/compiler/crystal/semantic/call.cr:313:5 in 'lookup_matches_in_type'
  from ../../../../../crystal/src/compiler/crystal/semantic/call.cr:262:3 in 'lookup_matches_in:with_literals'
  from ../../../../../crystal/src/compiler/crystal/semantic/call.cr:135:7 in 'lookup_matches:with_literals'
  from ../../../../../crystal/src/compiler/crystal/semantic/call.cr:121:5 in 'recalculate'
  from ../../../../../crystal/src/compiler/crystal/semantic/main_visitor.cr:1475:7 in 'visit'
  from ../../../../../crystal/src/compiler/crystal/syntax/visitor.cr:27:12 in 'accept'
  from ../../../../../crystal/src/compiler/crystal/syntax/ast.cr:169:27 in 'accept'
  from ../../../../../crystal/src/compiler/crystal/semantic/main_visitor.cr:1938:7 in 'visit'
  from ../../../../../crystal/src/compiler/crystal/syntax/visitor.cr:27:12 in 'accept'
  from ../../../../../crystal/src/compiler/crystal/syntax/ast.cr:169:27 in 'accept'
  from ../../../../../crystal/src/compiler/crystal/semantic/call.cr:438:13 in 'instantiate'
  from ../../../../../crystal/src/compiler/crystal/semantic/call.cr:313:5 in 'lookup_matches_in_type'
  from ../../../../../crystal/src/compiler/crystal/semantic/call.cr:262:3 in 'lookup_matches_in:with_literals'
  from ../../../../../crystal/src/compiler/crystal/semantic/call.cr:135:7 in 'lookup_matches:with_literals'
  from ../../../../../crystal/src/compiler/crystal/semantic/call.cr:121:5 in 'recalculate'
  from ../../../../../crystal/src/compiler/crystal/semantic/main_visitor.cr:1475:7 in 'visit'
  from ../../../../../crystal/src/compiler/crystal/syntax/visitor.cr:27:12 in 'accept'
  from ../../../../../crystal/src/compiler/crystal/syntax/ast.cr:169:27 in 'accept'
  from ../../../../../crystal/src/compiler/crystal/semantic/main_visitor.cr:6:7 in 'visit_main'
  from ../../../../../crystal/src/compiler/crystal/semantic/main_visitor.cr:5:5 in 'semantic'
  from ../../../../../crystal/src/compiler/crystal/compiler.cr:171:14 in 'compile'
  from ../../../../../crystal/src/compiler/crystal/command.cr:295:3 in 'run'
  from ../../../../../crystal/src/compiler/crystal.cr:11:1 in '__crystal_main'
  from ../../../../../crystal/src/crystal/main.cr:105: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

Version:

Crystal 0.35.1 [5999ae29b] (2020-06-19)

LLVM: 8.0.0
Default target: x86_64-unknown-linux-gnu
asterite commented 4 years ago

Thank you for this report.

When pasting crystal code, if you put "crystal" next to the three fist backquotes you'll get syntax highlighting, which helps understanding the code faster. I've been doing that for you in the last bug reports, just letting you know.

asterite commented 4 years ago

I think this is pretty hard to fix, so my idea of a solution would be to disallow typeof inside is_a?.

BrucePerens commented 4 years ago

In this particular example, I can work out another way to get a class object for the contents of an array, so that would be OK. So, "Error: typeof() within type restriction doesn't work yet"?

Blacksmoke16 commented 4 years ago

I would also probably try and avoid having an AnyType. At that point you kinda lose the benefits of static typing...

asterite commented 4 years ago

More like "Can't use typeof inside is_a?". I wouldn't say "yet" because I think there's no way to fix it without a major rewrite of the compiler.

BrucePerens commented 4 years ago

OK. Please document what operators don't work within is_a? as part of the fix.

The AnyType in this case gives a name to a type union that the compiler would otherwise call Value+. This is a fragment of a computer language with some dyadic operators that can compare the Crystal types Bool, String, or Int64|Float64. So, those operators do type checking in its compile pass.