Hello!
It is probably a bug. But it might be me missing something about Scala-
Java interop (which usually works perfectly!).
Let's write 2 classes in Java.
public class J<T> {
public class Inner {}
public void call(Inner i) {
System.out.println("ja");
}
}
public class J2<T> extends J<T> {
public void call(Inner i) {
System.out.println("va");
}
}
Now let's extend them in Scala.
class S extends J[String] {
override def call(i: J[String]#Inner) = println("sca")
}
class S2 extends J2[String] {
override def call(i: J[String]#Inner) = println("la")
}
Compilation fails.
[info] Compiling 1 Scala source and 2 Java sources to D:\dev\my\lazer
\target\sca
la-2.9.1\classes...
[error] D:\dev\my\lazer\S.scala:2: method call overrides nothing
[error] override def call(i: J[String]#Inner) = println("sca")
[error] ^
[error] D:\dev\my\lazer\S.scala:6: method call overrides nothing
[error] override def call(i: J[String]#Inner) = println("la")
[error] ^
[error] two errors found
Ok. Now we change scala code in two places from
override def call(i: J[String]#Inner)
to
override def call(i: Inner)
Compilation succeeds.
[info] Compiling 1 Scala source and 2 Java sources to D:\dev\my\lazer
\target\sca
la-2.9.1\classes...
Now wait for a full moon and change scala file in any way. Let's just
add a newline in the end.
Compilation fails.
[info] Compiling 1 Scala source to D:\dev\my\lazer\target
\scala-2.9.1\classes...
[error] D:\dev\my\lazer\S.scala:2: method call overrides nothing
[error] override def call(i: Inner) = println("sca")
[error] ^
[error] D:\dev\my\lazer\S.scala:6: method call overrides nothing
[error] override def call(i: Inner) = println("la")
[error] ^
[error] two errors found
Ok. Now we change scala code in two places from
override def call(i: Inner)
to
override def call(i: J[String]#Inner)
Compilation fails.
[info] Compiling 1 Scala source to D:\dev\my\lazer\target
\scala-2.9.1\classes...
[error] D:\dev\my\lazer\S.scala:6: name clash between defined and
inherited memb
er:
[error] method call:(i: J[String]#Inner)Unit and
[error] method call:(x$1: J[T]#Inner)Unit in class J2
[error] have same type after erasure: (i: J#Inner)Unit
[error] override def call(i: J[String]#Inner) = println("la")
[error] ^
[error] one error found
So it seems like we have different compiler behavior depending on
whether it uses java source or class files.
This problem prevents people from using Hadoop with Google App Engine:
http://groups.google.com/group/scala-user/browse_thread/thread/77eedf7ec579224
The questions:
1) What is the supposed way to use Java inner classes in Scala
subclasses? I thought it was
override def call(i: J[String]#Inner)
But I succeeded only compiling
override def call(i: Inner)
2) Why class S compiles with
override def call(i: J[String]#Inner)
but class S2 is not?
--
Sasha