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
name clash after erasure error can be bypassed by anonymous classes or private methods #9286
Comments
Imported From: https://issues.scala-lang.org/browse/SI-9286?orig=1 |
@retronym said (edited on May 1, 2015 1:50:49 AM UTC): class M[_]
trait T {
def foo(m: M[_ >: String]) = 42
}
// class C extends T {
// def foo(m: M[_ >: Any]) = 0 // gives "same type after erasure error"
// }
object Test {
def t: T = new T {
def foo(m: M[_ >: Any]) = 0
}
def main(args: Array[String]): Unit = {
val m: M[String] = null
t.foo(m) // VeriyError: Duplicate method name&signature
}
} This no doubt stems from the acrobatics performed in typechecking when deciding what declarations of anonymous classes ought to be hidden: https://github.com/scala/scala/blob/v2.11.6/src/compiler/scala/tools/nsc/typechecker/Typers.scala#L2327-L2384 Workaround is to use the |
@retronym said: import java.util.PrimitiveIterator
import java.util.function.Consumer
class Bar {
def pi: PrimitiveIterator.OfLong = new PrimitiveIterator.OfLong {
// Adding override modifier offers: "method forEachRemaining overrides nothing"
// The compiler should disallow this under the "double definition after erasure" rule.
def forEachRemaining(c: Consumer[_ >: scala.Long]) { ??? }
def hasNext: Boolean = false
def nextLong: Long = ???
}
}
object Test {
def main(args: Array[String]): Unit = {
val consumer: Consumer[java.lang.Long] = null
new Bar().pi.forEachRemaining(consumer) // IllegalAccessError: Bar$$anon$1.forEachRemaining(Ljava/util/function/Consumer;)V
}
} |
@retronym said: class T {
def foo(o: Tuple1[String]) = ()
}
class U extends T {
private def foo(o: Tuple1[Any]) = ()
}
object Test {
def main(args: Array[String]): Unit = {
new U().foo(null) // IllegalAccessError: tried to access method U.foo(Lscala/Tuple1;)V from class Test$
}
} |
@retronym said: scala> class C { def foo = 0 }; class D extends C { private def foo[A] = 0 }
defined class C
defined class D
scala> new D().foo
java.lang.IllegalAccessError: tried to access method D.foo()I from class
... 33 elided
scala> (new D() : C).foo
res1: Int = 0 |
@retronym said (edited on May 1, 2015 2:20:19 AM UTC):
|
@retronym said: |
The following minimization illustrates the bug:
Note that only when the return type is a generic (even if the exact type is specified) does the compiler silently...do...I'm not even sure what it's doing. It's confused about what
Long
should be, and somehow that causes it to emit the method asprivate
even though it's not markedprivate
and it is identical after erasure to apublic
method.The
Bippy
version (where the return type is not in any way generic) does not exhibit this problem, andBaz
andQuux
show that it works the way it ought to if you get the correct type in place.The text was updated successfully, but these errors were encountered: