Nim
Nim copied to clipboard
Compiler crashses when generic value should be inferred from an array and its a default value for another argument (?)
Its a pretty specific error, but i have simplified my code to 4 examples that showcase when the compiler crashes and when it doesnt.
Example
# Example 1
proc splitArray*[T](arr: array[T, int]; x, y: static[int]): array[y - x, int] = # compiles with nim -v 1.4.2 and above
discard
# Example 2
proc splitArray*[T: static[int]](arr: array[T, int]; x: static[int] = T; y: static[int]): array[y - x, int] = # compile time error (although it shouldnt error afaik)
discard
# Example 3
proc splitArray*[T: static[int]](arr: array[T, int]; x = T, y: static[int]): array[y - x, int] = # segfault (coment example 3 to check)
discard
# Example 4
proc splitArray*[T](arr: array[T, int]; x = T, y: static[int]): array[y - x, int] = # segfault (coment example 3 to check)
discard
Current Output
Example 2
Error: cannot generate code for: T
Examples 3 and 4
....SIGSEGV: Illegal storage access. (Attempt to read from nil?)
Expected Output
compiles (?) (or at least output a proper error message if this is not intended to compile)
Additional Information
Segfault occurs with versions 0.19 to 1.5.1 (that i have tested, probably still happens in devel), so the segfault was introduced somewhere inbetween 0.18 and 0.19.
Versions 0.19 to 1.4 throw an ordinal type expected error on the first example, while versions 0.18 and below throw a cannot evaluate at compile time: y.
Similarly, in example 2, when using nim -v 0.18 and below, Error: cannot evaluate at compile time: y occurs, and from version 0.19 to 1.5.1 (and probably devel) (5, 71) Error: cannot generate code for: T is raised instead.
So probably, a PR that had something to do with examples 1 and/or 2 broke something and has passed unoticed until now.
I am unsure if this is a separate issue, but the following also leads to a compiler crash. Removing Foo.b, or initializing it with a constant value works.
type Foo = tuple[a: int8, b: set[int8]]
func makeFoo(p: int8): Foo =
(a: p, b: {0'i8 .. p})
template boom(t: static Foo): untyped =
t[0]
const f = makeFoo(1'i8)
discard boom(f)
Examples 3 and 4 work now, example 2 culprit is here