Hello. When I was playing with a code I received a message:
Module validation failed: Stored value type does not match pointer operand type!
store i16 0, i32* %0, !dbg !13
i32Stored value type does not match pointer operand type!
store i64 0, i32* %1, !dbg !14
i32Call parameter type does not match function signature!
%33 = load i32, i32* %32, !dbg !27
i16 %34 = call %"IO::FileDescriptor"* @"*UInt16@Int#inspect<IO::FileDescriptor>:IO::FileDescriptor"(i32 %33, %"IO::FileDescriptor"* %io), !dbg !27
Call parameter type does not match function signature!
%38 = load i32, i32* %37, !dbg !27
i64 %39 = call %"IO::FileDescriptor"* @"*UInt64@Int#inspect<IO::FileDescriptor>:IO::FileDescriptor"(i32 %38, %"IO::FileDescriptor"* %io), !dbg !27
(Exception)
from ???
[… dupes skipped …]
from ???
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
The code to reproduce:
class AnotherClass(T)
@sum : T
@count : UInt64
def initialize(val)
@sum = 0
@count = 0
end
end
class SomeClass(T)
class AnotherClass(T) < AnotherClass(T)
def initialize(el : Array(T))
super
end
def initialize(el : T)
@sum = 0
@count = 0
end
end
@values = [] of AnotherClass(T)
def initialize(values : Array(Array(T) | T) = [] of T)
@values = values.map { |el| AnotherClass(T).new(el) }
puts @values
end
end
bar = SomeClass(UInt16).new([[1_u16, 2_u16]])
OS:
Debian GNU/Linux 9.5 (stretch)
Crystal version:
Crystal 0.25.1 [b782738ff] (2018-06-27)
LLVM: 4.0.0
Default target: x86_64-unknown-linux-gnu
The bug also can be reproduced on master branch with a detailed backtrace:
Crystal 0.25.1+86 [d454f6973] (2018-08-04)
LLVM: 4.0.1
Default target: x86_64-pc-linux-gnu
Module validation failed: Stored value type does not match pointer operand type!
store i16 0, i32* %0, !dbg !13
i32Stored value type does not match pointer operand type!
store i64 0, i32* %1, !dbg !14
i32Call parameter type does not match function signature!
%33 = load i32, i32* %32, !dbg !27
i16 %34 = call %"IO::FileDescriptor"* @"*UInt16@Int#inspect<IO::FileDescriptor>:IO::FileDescriptor"(i32 %33, %"IO::FileDescriptor"* %io), !dbg !27
Call parameter type does not match function signature!
%38 = load i32, i32* %37, !dbg !27
i64 %39 = call %"IO::FileDescriptor"* @"*UInt64@Int#inspect<IO::FileDescriptor>:IO::FileDescriptor"(i32 %38, %"IO::FileDescriptor"* %io), !dbg !27
(Exception)
from /tmp/crystal/src/llvm/module.cr:78:9 in 'verify'
from /tmp/crystal/src/compiler/crystal/codegen/codegen.cr:343:9 in 'finish'
from /tmp/crystal/src/compiler/crystal/codegen/codegen.cr:67:7 in 'codegen'
from /tmp/crystal/src/compiler/crystal/codegen/codegen.cr:63:5 in 'codegen:debug:single_module'
from /tmp/crystal/src/compiler/crystal/compiler.cr:22:7 in 'codegen'
from /tmp/crystal/src/compiler/crystal/compiler.cr:145:16 in 'compile'
from /tmp/crystal/src/compiler/crystal/command.cr:260:7 in 'compile'
from /tmp/crystal/src/compiler/crystal/command.cr:179:14 in 'run_command'
from /tmp/crystal/src/compiler/crystal/command.cr:87:7 in 'run'
from /tmp/crystal/src/compiler/crystal/command.cr:48:5 in 'run'
from /tmp/crystal/src/compiler/crystal/command.cr:47:3 in 'run'
from /tmp/crystal/src/compiler/crystal.cr:8:1 in '__crystal_main'
from /tmp/crystal/src/crystal/main.cr:104:5 in 'main_user_code'
from /tmp/crystal/src/crystal/main.cr:93:7 in 'main'
from /tmp/crystal/src/crystal/main.cr:133:3 in 'main'
from __libc_start_main
from _start
from ???
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
The code works if you redeclare @sum : T and @count : UInt64 in SomeClass::AnotherClass (carc.in link here).
Minified example:
class A(T)
@count : UInt64
def initialize(val)
@count = 0
end
end
class C(T) < A(T)
def initialize(el : Array(T))
super
end
def initialize(el : T)
@count = 1
end
end
class B(T)
@values = [] of C(T)
def initialize(values : Array(T))
@values = values.map { |el| C(T).new(el) }
end
end
bar = B(UInt16).new([1_u16, 2_u16])
This is probably an issue with automatic casting, which doesn't get activated with @count = 1 in C(T)#initialize in the above example - I can remove @count : UInt64 and it works, or change it to @count : UInt16 to have it still break. See #6074 for the PR.
I'm not sure if this is intended behaviour or not, to not have automatic casting "carry over" with instance vars during inheritance. If this is intended behaviour, the LLVM error message should be caught as a compile error or something. (CC @asterite)
Thank you for your proposal! When you work in the night almost falling asleep strange things happen. Cut here, paste there, build, WTF? Next day you read yesterdays code and think "What idiot wrote that?". :)
See #6074 for the PR
Thanks, that is really great description!
@serge-name Ah, fair enough. Sorry for the statement at the end, I thought it came off as a bit harsh (which is why I removed it). But seriously though, that code is so obscure I had to comment on it.
Never mind. Let's make Crystal more stable and shiny :)
Still being reproduced on
Crystal 0.27.0 [c9d1eef8f] (2018-11-01)
LLVM: 4.0.0
Default target: x86_64-unknown-linux-gnu