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

javainterop: Builder pattern from scala to java returns upperbound type e.g. Foo[Bar] in java instead of concrete type e.g. Bar #6243

Open
scabug opened this issue Aug 15, 2012 · 4 comments
Milestone

Comments

@scabug
Copy link

scabug commented Aug 15, 2012

Consider a recursive type definition on the scala side and Test on the java side and a Test2 on the scala side.

recurse.scala

package test
trait Foo[A <: Foo[A]] { 
      this: A =>
      def qux(): A = this
} 
class Bar extends Foo[Bar] 
class Duh extends Foo[Duh]

object Test2 extends App {
  val bar: Bar = new Bar().qux(); 
  val duh: Duh = new Duh().qux();
  
  println(bar)
  println(duh)
}

and

Test.java

package test;

public class Test {

  public static void main(String[] args) {
     Bar bar = new Bar().qux();
     Duh duh = new Duh().qux();
     System.out.println(bar); 
     System.out.println(duh); 
     
  }
}

Then the scala side Test2 will compile without problem and run while the java side will generate an error

C:\scala-2.10.0-M6\recurse>javac -d . -cp .;..\lib\scala-library.jar *.java
Test.java:6: incompatible types
found   : test.Foo
required: test.Bar
     Bar bar = new Bar().qux();
                            ^
Test.java:7: incompatible types
found   : test.Foo
required: test.Duh
     Duh duh = new Duh().qux();
                            ^
2 errors

A workaround is to either cast it on the java side to the proper type like Duh or override the method in the concrete class to return a concrete type like Bar.

recurse.scala

package test
trait Foo[A <: Foo[A]] { 
      this: A =>
      def qux(): A = this
} 
class Bar extends Foo[Bar] {
  override def qux(): Bar = super.qux()
}
class Duh extends Foo[Duh]

object Test2 extends App {
  val bar: Bar = new Bar().qux(); 
  val duh: Duh = new Duh().qux();
  
  println(bar)
  println(duh)
}

and

Test.java

package test;

public class Test {

  public static void main(String[] args) {
     Bar bar = new Bar().qux();
     Duh duh = (Duh) new Duh().qux();
     System.out.println(bar); 
     System.out.println(duh); 
     
  }
}

see thread
https://groups.google.com/forum/?hl=en&fromgroups#!topic/scala-user/PPDIPfeKGzo%5B1-25%5D

@scabug
Copy link
Author

scabug commented Aug 15, 2012

Imported From: https://issues.scala-lang.org/browse/SI-6243?orig=1
Reporter: DaveScala (davescala)
Affected Versions: 2.10.0-M6
See #5289, #6169, #6168

@scabug
Copy link
Author

scabug commented Oct 25, 2012

@adriaanm said:
probably can't do this in 2.10 since it would affect binary compatibility

@scabug
Copy link
Author

scabug commented Jan 26, 2016

@szeiger said:
Possibly a duplicate of #5289

@scabug
Copy link
Author

scabug commented Jul 6, 2016

@lrytz said:
I think it's not related to #5289. That one is about static forwarders generated for scala modules. The one here is about types, possibly signatures, but the Java code does not use static forwarders.

@scabug scabug added this to the Backlog milestone Apr 7, 2017
@scala scala deleted a comment from scabug May 1, 2023
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

1 participant