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 on recursive generics (without alias) #13704

Open
wolfgang371 opened this issue Jul 25, 2023 · 1 comment
Open

Compiler bug on recursive generics (without alias) #13704

wolfgang371 opened this issue Jul 25, 2023 · 1 comment

Comments

@wolfgang371
Copy link

This is probably in relation to #13702 and #5155 , but without use of alias.

abstract class Base(T)
    abstract def mysize :  Array(Int32)
    def to_s
        if !(mysize.size>2)
        else
            raise("foo")
        end
        Array(Array(T)).new.map {|row| row.map {|el| el.to_s.size}.max}
    end
end

class Child(T) < Base(T)
    def mysize :  Array(Int32)
        [0]
    end
end

table = Child(Base(Int32)).new
table.to_s

Leads to...

BUG: `!(::raise("can't execute `().size` at /home/user/compiler-bug.cr:4:14: `` has no type"))` at /home/user/compiler-bug.cr:4:12 has no type (Exception)
  from /crystal/src/compiler/crystal/codegen/cond.cr:4 in 'codegen_cond'
  from /crystal/src/compiler/crystal/codegen/codegen.cr:909:7 in 'visit'
  from /crystal/src/compiler/crystal/syntax/visitor.cr:27:12 in 'accept'
[...]
  from /crystal/src/crystal/main.cr:129:5 in 'main'
  from src/env/__libc_start_main.c:95: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

I'm running

Crystal 1.9.2 [1908c816f] (2023-07-19)
LLVM: 15.0.7
Default target: x86_64-unknown-linux-gnu

on Ubuntu 18.04

@straight-shoota
Copy link
Member

straight-shoota commented Jul 25, 2023

This looks completely unrelated to recursive aliases.

I have managed to reduce the reproduction a bit further. The conditional with empty then branch is very conspicuous. The condition needs to include negation.

abstract class Base(T)
  abstract def mysize :  Array(Int32)
  def to_s
    if !mysize.size
    end

    Array(T).new.map {|el| el.to_s.size}
  end
end

class Child(T) < Base(T)
  def mysize :  Array(Int32)
    [0]
  end
end

table = Child(Base(Int32)).new
table.to_s

Changing the condition to !mysize results in a slightly different error: BUG: `` at has no type. So it seems the cause of the problem lies with the implementations of Base(T)#mysize.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants