Can't run specs, compilation fails
Closed this issue · 2 comments
Hi,
I thought I'd try upgrading some code to Crystal 0.16.0, but the compiler failed with a problem in the matrix code (on which my code relies). I tried running the specs for the matrix shard and the compiler doesn't like what it sees:
$ crystal spec
Error in ./spec/matrix_spec.cr:7: instantiating 'Matrix(T):Class#rows(Array(Array(Int32)))'
m = Matrix.rows([[1, 2], [3, 4], [5, 6]])
^~~~
in ./src/matrix.cr:60: instantiating 'Matrix(T):Class#new(Int32, Int32)'
Matrix.new(rows.size.to_i32, rows.first.size.to_i32) do |i, r, c|
^~~
in ./src/matrix.cr:38: instantiating 'Matrix(Int32):Class#new(Int32, Int32)'
matrix = Matrix(T).new(rows, columns)
^~~
instantiating 'Matrix(Int32)#initialize(Int32, Int32)'
in ./src/matrix.cr:28: instantiating 'size()'
@buffer = Pointer(T).malloc(size)
^~~~
in ./src/matrix.cr:454: undefined method '*' for Int+ (compile-time type is (Int+ | Int32))
@rows * @columns
^
$ crystal --version
Crystal 0.16.0 (Sun May 8 12:21:15 UTC 2016)
I almost think this is a problem with Crystal itself, given that I'm not really sure what an Int+ is, but thought I'd check here first. If you think I should file a bug in the main Crystal repo let me know, I'm happy to do that. Thanks!
Yeah thanks for reporting. It's fixed now.
I think the error happened because the type restriction of @rows
and @columns
was limited to Int
which doesn't define a #*
method itself although (AFAIK) all its subclasses do.
Int+
means Int
or any of its subclasses. According to the docs it would work if Int
was an abstract struct (which I thought it was).
Also, the fact that Crystal makes an union of Int+ | Int32
strikes me as oddly redundant but I don't know if it's unintended.
Looks like Int
is just a regular struct, not abstract: https://github.com/crystal-lang/crystal/blob/master/src/int.cr#L58
Anyway, thanks for the fix!