Java raw types and recursive type bounds

Hello everyone,

I was recently proposed the following puzzle and I failed to solve it. I tried finding a similar problem in https://github.com/scala/bug to no avail. This precise variation doesn’t seem to have been reported or my understanding of the problem is lacking. Hopefully you can enlighten me :slight_smile:

Given the following java type:

public class A<T extends A<T>> {}

and the following java interface

public interface IA {
    void foo(A a);
}

How can I define an implementation in scala ?

class IAImpl extends IA{
  override def foo(a: A[_]): Unit = ???
}

fails to compile with

class IAImpl needs to be abstract, since method foo in trait IA of type (a: A)Unit is not defined
(Note that A does not match A[_]. To implement a raw type, use A[_])
class IAImpl extends IA{
      ^

trying to include the type bound in the signature :

class IAImpl extends IA{
  override def foo(a: A[_ <: A[_]]): Unit = ???
}

fails with

class IAImpl needs to be abstract, since method foo in trait IA of type (a: A)Unit is not defined
(Note that A does not match A[_ <: A[_]]. To implement a raw type, use A[_])
class IAImpl extends IA{
      ^

any idea how to make this work apart from changing the definition of the interface or creating a bridge implementation in java ?

The actual use case is implementing a WaitStrategy as defined by testcontainer

thank you !

First you should kick the person that’s still using raw types in Java. Then you might consider filing a bug report, cause that doesn’t look right to me. Or wait until someone more knowledgeable comes in to tell you that this is not a bug for some strange reason.

Hello,

At the very least, the error message that says that the raw type A can be
implemented by A[_] is a compiler bug. This only works for parameters
without bounds.

I can’t figure out how to override this method even in Java without using
another raw type.

In order to convey the bound, the method needs a parameter, but I can’t
figure out how to do this and still override the original method, neither
in Java nor in Scala.

 Best, Oliver

@curoli in java it’s not much of an issue since you can use a raw type in the override :slight_smile:

public class JavaIA implements IA {
    @Override
    public void foo(A a) {

    }
}

but raw types are not available in scala …

By the way. How you can get this to compile is this.

class IAImpl extends IA { 
  override def foo(a: A[X] forSome {type X <: A[X]}): Unit = ??? 
}

But indeed, the error message is wrong. That’s a bug.

1 Like

Hello,

Yes, I meant I can do it in Java but only by using a raw type.

 Best, Oliver

I reported the error message as a bug for the scala compiler

github issues be blessed :raised_hands: