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

Stack overflow during compilation #7125

Open
max-codeware opened this issue Nov 28, 2018 · 6 comments
Open

Stack overflow during compilation #7125

max-codeware opened this issue Nov 28, 2018 · 6 comments

Comments

@max-codeware
Copy link
Contributor

I'm facing a stack overflow during Semantic (main). I think this problem has something in common with #2604 (this issue made me understand what the problem was).

The line that's causing the compiler crash is this

@@sym_dict = uninitialized Hash(Class,LcClass)

LcClass is a defined type (not part of the problem).

If I change that line with

@@sym_dict = uninitialized Hash(String,LcClass)

The program compiles with no problems, but I must tell the compiler the keys of the hash will be classes and not strings.
I tried to reproduce this with a smaller code using the online compiler, but with no success..

How can I solve this issue?

@asterite
Copy link
Member

Right now you can't store things with a Class type. That's why it probably crashes.

@max-codeware
Copy link
Contributor Author

I dag a bit more on the problem: since if I create a literal hash with classes as keys it compiles, I run this simple cone on the online Crystal compiler

dummy = {String => 1}
p typeof(dummy)

ant it returned

Hash(String.class,Int32)

This can be a solution to my problem.
However, it is slightly uncomfortable as declaration, since String.class is Class. I'm not aware of the compiler's implementation, but could it be possible to allow a declaration like Hash(Class,Int32)?

Stepping back, the code I put in the first comment makes crystal running in stack overflow during compilation without raising any specific exception...

@max-codeware
Copy link
Contributor Author

Closed by mistake..

@z64
Copy link
Contributor

z64 commented Nov 30, 2018

Actually, I'm curious why is Class allowed as a generic argument in these examples?

A program entirely of

Hash(Class, Int32)

fails with Error in line 1: can't use Class as generic type argument yet, use a more specific type; is this check just missing for this case..?

In any case @max-codeware - do you actually need this for user types, or an unknown number of types? Or just primitives / some finite collection of types? I think an explicit Union of *.class should work in the latter:

# Alias for ease of reference in multiple locations, if needed:
alias Any = String.class | Int32.class | Bool.class

hash = Hash(Any, Int32).new
hash[String] = 1
hash[Int32] = 2
hash[Bool] = 3
p typeof(hash) # Hash(Bool.class | Int32.class | String.class, Int32)
p hash # {String => 1, Int32 => 2, Bool => 3}

Maybe a macro could be applied to make this flexible, but I don't know enough about your use case at a glance.

@max-codeware
Copy link
Contributor Author

@z64 I was curious too: I just tried this script on the online compiler and I report it here:

module A
  @@var = uninitialized Hash(Class,Int32)
  def self.var
    @@var = {String => 1}
  end
end

p A.var

And it gave me back this error:
Error in line 8: instantiating 'A:Module#var()' in line 4: class variable '@@var' of A must be Hash(Object.class, Int32), not Hash(String.class, Int32)
So uninitialized Hash(Class,Int32) is like uninitialized Hash(Object.class,Int32) and this is the reason the inference doesn't complain, but the compiler runs into some infinite recursion during Semantic (main) (in my code).
The reason that makes this code working and not mine is still obscure.

About my case, here I have a Hash that has many classes as key. I could , of course, use the top level class SbaseC and solving the problem as you pointed out (this is the solution to my problem).
But as a programmer I'm rather lazy and it's quicker to write Hash(Class,Other) especially in case of many classes without any superclass in common...

@rdp
Copy link
Contributor

rdp commented Nov 10, 2021

Can it repro still? I seem to get this now:
Error: can't use Class as generic type argument yet, use a more specific type

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

5 participants