crystal
crystal copied to clipboard
Bug: Nil assertion failed (NilAssertionError)
The following code:
alias RecType = Int32 | Array(RecType)
Proc(NamedTuple(value: Int32 | RecType)?).new do
next {value: 1} if false
Proc(NamedTuple(value: RecType)?).new {}.call
end
produces this output:
Nil assertion failed (NilAssertionError)
from /crystal/src/nil.cr:108:5 in 'not_nil!'
from /crystal/src/compiler/crystal/codegen/cast.cr:588:29 in 'upcast_distinct'
from /crystal/src/compiler/crystal/codegen/cast.cr:523:15 in 'upcast'
from /crystal/src/compiler/crystal/codegen/codegen.cr:709:17 in 'codegen_return'
from /crystal/src/compiler/crystal/codegen/fun.cr:229:5 in 'codegen_fun'
from /crystal/src/compiler/crystal/codegen/fun.cr:51:3 in 'accept'
from /crystal/src/compiler/crystal/codegen/call.cr:331:5 in 'visit'
from /crystal/src/compiler/crystal/syntax/visitor.cr:27:12 in 'accept'
from /crystal/src/compiler/crystal/codegen/codegen.cr:665:9 in 'accept'
from /crystal/src/compiler/crystal/codegen/codegen.cr:2244:7 in 'codegen'
from /crystal/src/compiler/crystal/compiler.cr:173:16 in 'compile'
from /crystal/src/compiler/crystal/command.cr:215:5 in 'run_command'
from /crystal/src/compiler/crystal/command.cr:64:5 in '__crystal_main'
from /crystal/src/crystal/main.cr:115: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
Not using a recursive type alias:
Proc(NamedTuple(value: Int32 | String)?).new do
next {value: 1} if false
Proc(NamedTuple(value: String)?).new {}.call
end
is perfectly fine, as is not using NamedTuple
:
alias RecType = Int32 | Array(RecType)
Proc(Box(Int32 | RecType)?).new do
next Box.new(1) if false
Proc(Box(RecType)?).new {}.call
end
(probably has something to do with **T
)
Also making the proc return non-nil value (removing the ?
) produces no error.
Line 4 is there to make the compiler happy but if if false
is removed, no error occurs.
If the union type of value
includes a type not in the definition of the recursive type, no error occurs:
alias RecType = Int32 | Array(RecType)
Proc(NamedTuple(value: String | RecType)?).new do
next {value: 1} if false
Proc(NamedTuple(value: RecType)?).new {}.call
end # No errors
alias RecType = String | Int32 | Array(RecType)
Proc(NamedTuple(value: String | RecType)?).new do
next {value: 1} if false
Proc(NamedTuple(value: RecType)?).new {}.call
end # Nil assertion error
alias RecType = String | Int32 | Array(RecType)
Proc(NamedTuple(value: String | Int32 | RecType)?).new do
next {value: 1} if false
Proc(NamedTuple(value: RecType)?).new {}.call
end # Also a nil assertion error
And the alias doesn't have to be a union:
alias RecType = Array(RecType)
Proc(NamedTuple(value: Array(RecType) | RecType)?).new do
next {value: [] of RecType} if false
Proc(NamedTuple(value: RecType)?).new {}.call
end # A nil assertion error yet again
However, not using a union does not produce an error:
alias RecType = Int32 | Array(RecType)
Proc(NamedTuple(value: RecType)?).new do
next {value: 1} if false
Proc(NamedTuple(value: RecType)?).new {}.call
end # No errors
Crystal version:
Crystal 1.5.0 [994c70b10] (2022-07-06)
LLVM: 10.0.0
Default target: x86_64-unknown-linux-gnu
Running on Ubuntu 20.04 on WSL 2 on Windows 10 (I was able to reproduce the examples on play.crystal-lang.org
as well)