Crystal: Error setting ivar to generic Proc type with non abstract parent

Created on 1 Feb 2020  路  3Comments  路  Source: crystal-lang/crystal

If someone has a better title suggestion I'm open to it :laughing:.

https://play.crystal-lang.org/#/r/8ht3

class Response; end

class RedirectResponse < Response; end

class Test(T)
  def initialize(@action : T); end
end

def greet(name : String) : Response
  Response.new
end

Test(Proc(String, Response)).new ->greet(String)
#Test(Proc(String, Response)).new Proc(String, Response).new { |str| Response.new }
Showing last frame. Use --error-trace for full trace.

error in line 13
Error: no overload matches 'Test(Proc(String, Response)).new' with type Proc(String, Response)

Overloads are:
 - Test(T).new(action : T)

An issue seems to exist where the compiler is not happy if the return type of a method that is turned into a proc is non abstract with a sub class.

Using Proc.new ... works fine.

I was able to work around it by defining an abstract parent type and having Response and RedirectResponse inherit from that so that neither is a parent type.

bug topicsemantic

Most helpful comment

All 3 comments

@Sija no... That creates a new T unrelated to the T in Test(T)

it's the same as

class Test(T)
  def initialize(@action : U) forall U
  end
end

which is the same as

class Test(T)
  def initialize(@action)
  end
end

A workaround is to define it as

def greet(name : String) : Response
  Response.new.as(Response)
end

There must be a bug between this-concrete-type and any-of-the-subclasses . The .as(Response) is forcing the any-of-the-subclasses

Was this page helpful?
0 / 5 - 0 ratings

Related issues

RX14 picture RX14  路  3Comments

cjgajard picture cjgajard  路  3Comments

costajob picture costajob  路  3Comments

Sija picture Sija  路  3Comments

asterite picture asterite  路  3Comments