Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Compiler bug in Array#unshift #10211

Closed
mcarpenter opened this issue Jan 6, 2021 · 5 comments · Fixed by #10214 or #10224
Closed

Compiler bug in Array#unshift #10211

mcarpenter opened this issue Jan 6, 2021 · 5 comments · Fixed by #10214 or #10224
Labels
kind:bug A bug in the code. Does not apply to documentation, specs, etc. topic:compiler:codegen

Comments

@mcarpenter
Copy link

mcarpenter commented Jan 6, 2021

Description

I have a table (matrix, 2D array) of type Array(Array(Int32 | String)). If I #unshift a row of type Array(String) onto it then the compiler crashes with Function return type does not match operand type of return inst!. Running 0.35.1 from the official PPA (Ubuntu repo) on Ubuntu 18.

The error appears to be related to the union type: it goes away with Array(Array(String)) at least. Other methods (<<, +) seem to be okay.

Reproducer

foo.cr:

table = [["x", 1]]
header = [] of String
table.unshift(header)
$ crystal foo.cr
Module validation failed: Function return type does not match operand type of return inst!
  ret i32* %1, !dbg !69
 %"Array(Int32 | String)"* (Exception)
  from ../../../../../crystal/src/int.cr:1091:11 in 'finish'
  from ../../../../../crystal/src/compiler/crystal/codegen/codegen.cr:69:7 in 'codegen'
  from ../../../../../crystal/src/compiler/crystal/compiler.cr:172:16 in 'compile'
  from ../../../../../crystal/src/compiler/crystal/command.cr:209:5 in 'run_command'
  from ../../../../../crystal/src/compiler/crystal/command.cr:116:7 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 and platform information

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

LLVM: 8.0.0
Default target: x86_64-unknown-linux-gnu
$ cat /etc/lsb-release 
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=18.04
DISTRIB_CODENAME=bionic
DISTRIB_DESCRIPTION="Ubuntu 18.04.5 LTS"
$ uname -a 
Linux juliet 4.15.0-128-lowlatency #131-Ubuntu SMP PREEMPT Wed Dec 9 08:07:00 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux
@straight-shoota straight-shoota added kind:bug A bug in the code. Does not apply to documentation, specs, etc. topic:compiler:codegen labels Jan 6, 2021
@Sija
Copy link
Contributor

Sija commented Jan 6, 2021

Same here on macOS (10.14.6):

Module validation failed: Function return type does not match operand type of return inst!
  ret i32* %1, !dbg !71
 %"Array(Int32 | String)"* (Exception)
  from src/llvm/module.cr:80:9 in 'verify'
  from src/compiler/crystal/codegen/codegen.cr:369:9 in 'finish'
  from src/compiler/crystal/codegen/codegen.cr:69:7 in 'codegen'
  from src/compiler/crystal/codegen/codegen.cr:65:5 in 'codegen:debug:single_module'
  from src/compiler/crystal/progress_tracker.cr:22:7 in 'codegen'
  from src/compiler/crystal/compiler.cr:172:16 in 'compile'
  from src/compiler/crystal/command/eval.cr:29:14 in 'eval'
  from src/compiler/crystal/command.cr:97:7 in 'run'
  from src/compiler/crystal/command.cr:49:5 in 'run'
  from src/compiler/crystal/command.cr:48:3 in 'run'
  from src/compiler/crystal.cr:11:1 in '__crystal_main'
  from src/crystal/main.cr:105:5 in 'main_user_code'
  from src/crystal/main.cr:91:7 in 'main'
  from src/crystal/main.cr:114:3 in 'main'
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

crystal --version:

Crystal 1.0.0-dev [7d9bbdd6e] (2021-01-06)

LLVM: 11.0.0
Default target: x86_64-apple-macosx

@asterite
Copy link
Member

asterite commented Jan 6, 2021

Reduced:

class Gen(T)
end

ptr = Pointer(Gen(Int32 | Char)).malloc(1_u64)
ptr.value = Gen(Int32).new

The above shouldn't compile. It's the same with every generic type. I think for Pointer specially we need to match generic in an invariant way.

@mcarpenter
Copy link
Author

mcarpenter commented Jan 7, 2021

Hi, thanks for the quick response and detailed explanation.

For others that may stumble on this: I tried a few workarounds and found that I can nudge the compiler in the right direction.

I aimed to do:

header : Array(String|Int32) = %w{Name Size} # Error: type must be Array(String | Int32), not Array(String)

Instead:

header : Array(String|Int32) = ["Name", "Size"] # Error: type must be Array(String | Int32), not Array(String)
header : Array(String|Int32) = ["Name", Int32.new(5)] # OK (but not useful for me)
header : Array(String|Int32) = ["Name", "Size"].as(Array(String|Int32)) # Error: can't cast Array(String) to Array(String | Int32)
header : Array(String|Int32) = ["Name".as(String|Int32), "Size"] # OK
header : Array(String|Int32) = [] of (String|Int32) << "Name" << "Size" # OK
header : Array(String|Int32) = [] of (String|Int32) + %w{Name Size} # OK
header = [] of (String|Int32) + %w{Name Size} # OK

@Blacksmoke16
Copy link
Member

@mcarpenter You should just be able to do header : Array(String|Int32) = ["Name", "Size"] of String | Int32.

@mcarpenter
Copy link
Author

mcarpenter commented Jan 7, 2021

I can drop the type restriction too:

header = ["Name", "Size"] of String|Int32

Kind of a shame that doesn't work with %w{} but it's certainly nicer than what I had. Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
kind:bug A bug in the code. Does not apply to documentation, specs, etc. topic:compiler:codegen
Projects
None yet
5 participants