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
Prefix for inner class of generic java classes is incorrect. #3943
Comments
Imported From: https://issues.scala-lang.org/browse/SI-3943?orig=1
|
Alec Zorab (aleczorab) said: |
Alec Zorab (aleczorab) said: |
Alec Zorab (aleczorab) said: |
Alec Zorab (aleczorab) said: class ActualClass[A] extends AnotherChild[A] { class ActualClass[A] extends AnotherChild[A] { but it's possible that there's some syntactic finesse I could apply but don't know about |
@adriaanm said: class ActualClass?[A] extends AnotherChild?[A] {
override def f(ic: TopLevelParent?[A]#Inner2) = ()
} I'll have a look whether it does or not. |
@adriaanm said: package test
trait AnotherChild[A3] extends AChild[A3]
// error: class ActualClass needs to be abstract, since method f in class AChild of type
// (x$$1: test.TopLevelParent[UpHere]#Inner2)Unit is not defined
class ActualClass[A] extends AnotherChild[A] {
def f(ic: test.TopLevelParent[A]#Inner2): Unit = () //Inner2
} package test;
public abstract class TopLevelParent<UpHere>{
public class Inner1 {
}
public class Inner2 extends Inner1 {
}
}
abstract class AChild<A1> extends TopLevelParent<A1> {
abstract void f(Inner2 ic);
}
class child2<A2> extends AChild<A2> {
void f(Inner2 ic){
}
} |
@adriaanm said: here's some annotated debug output when parsing the class file of package test;
public abstract class TopLevelParent<T> {
public class Inner { }
}
abstract class Child<C> extends TopLevelParent<C> {
abstract void f(Inner ic); // the implicit prefix for Inner is TopLevelParent<T> instead of TopLevelParent<C>
} sig: class TopLevelParent : test.TopLevelParent[C]
methSig: constructor Child has params: List()
sig: class Inner : test.TopLevelParent[T]#Inner
methSig: method f has params: List(test.TopLevelParent[T]#Inner) T is not in scope in Child, where method f is defined -- the culprit is probably on the line above (should be test.TopLevelParent[C]#Inner |
@adriaanm said: |
@adriaanm said: Outer.java: public class Outer<E> {
abstract class Inner {
abstract public void foo(E e);
}
}
class Child extends Outer<String> {
// the implicit prefix for Inner is Outer<E> instead of Outer<String>
public Inner getInner() {
return new Inner() {
public void foo(String e) { System.out.println("meh "+e); }
};
}
} object Test extends Application {
val x: Child = new Child
x.getInner.foo("meh")
// ^
// error: type mismatch;
// found : java.lang.String("meh")
// required: E
} |
@adriaanm said: After figuring out the problem and the obvious fix, I've spent more than a day looking for a way that does not cause cyclesr1 during quick.lib. The obvious fixr2 is to simply change the two occurrences of // SI-3943
// cls.tpe.prefix is the thisType of the enclosing class of cls's definition
// later, we'll widen the this-type to the corresponding typeref (with type arguments that blindly refer
// to the enclosing class's type parameters)
// since we're computing sym's signature, cls.tpe needs to be re-interpreted in the context of sym.enclClass.thisType
// otherwise, cls.tpe.widen may refer to type parameters of its enclosing class, which are not in scope where sym is defined
lazy val site = if(sym eq null) null else sym.enclClass.thisType
def transformedTpe(cls: Symbol) = if((site eq null) || cls.isStatic) cls.tpe else site.memberType(cls) I've tried various approaches with LazyTypes, but the fact that these prefixes may occur in the super class type, method parameter types&result type,... makes it seem like an unlikely solution. The only alternative I could think of was something like cooking raw types, but I can only hope there's a better way... r1 assertion failed: illegal class file dependency between 'object ListItr' and 'class ListItr' 69. assert(!busy.isDefined, {
val (s1, s2) = (busy.get, root)
if (s1 eq s2) "unsatisfiable cyclic dependency in '%s'".format(s1)
else "illegal class file dependency between '%s' and '%s'".format(s1, s2)
}) |
@paulp said: |
@retronym said: |
@retronym said (edited on May 15, 2013 8:42:57 AM UTC):
Test case: scala/scala#2534 |
scalac - classpath javaPart.jar ./test/Child.scala
scalac.bat : .\test\Child.scala:5: error: class ActualClass needs to be abstract, since method f in class AChild of type (x$$1: test.TopLevelP
arent[A]#Inner2)Unit is not defined
class ActualClass[A] extends AnotherChild[A] {
^
.\test\Child.scala:6: error: method f overrides nothing
override def f(ic: Inner2) = ()
^
two errors found
The text was updated successfully, but these errors were encountered: