crystal icon indicating copy to clipboard operation
crystal copied to clipboard

Abstract def overload with free var

Open Blacksmoke16 opened this issue 1 year ago • 2 comments

Given the following code:

class Foo; end
 
module TestInterface
  abstract def add(foo : Foo) : Foo
  abstract def add(bar : T) : Nil forall T
end
 
class Test
  include TestInterface
  
  def add(foo : Foo) : Foo
    foo
  end
  
  def add(bar : T) : Nil forall T
    
  end
end
 
t = Test.new
 
pp t.add Foo.new
pp t.add 123

It fails to compile due to:

 11 | def add(foo : Foo) : Foo
                           ^--
Error: this method must return Nil, which is the return type of the overridden method TestInterface#add(bar : T) forall T, or a subtype of it, not Foo

I also tried with -Dpreview_overload_order which resulted in the same error.

It seems the abstract def checker thinks the overload with the explicit type is overriding the free var overload, instead of treating them separately.

I was able to work around this for now by defining the free var method in the interface as:

def add(bar : T) : Nil forall T
  {% @type.raise "abstract `def TestInterface#add(bar : T) : Nil forall T` must be implemented by #{@type}" %}
end

Which works for now :shrug:.

Blacksmoke16 avatar Apr 07 '24 18:04 Blacksmoke16

Duplicate of #10699?

HertzDevil avatar Apr 22 '24 11:04 HertzDevil

I found that one, but the error in this one was different so reported it separately.

Blacksmoke16 avatar Apr 22 '24 13:04 Blacksmoke16