You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Scala bridge methods only come to existence during erasure, so are not visible
before. But Java bridge methods come with their class files. It first I thought
we should get parity, so have to ignore Java bridge methods before erasure. But
that did not work, because unlike for Scala, some Java bridges are generated
to allow access to inherited methods. The situation can be described using
StringBuilder. It inherits a class AbstractStringBuilder which is not accessible
from Scala. Here's a minimized version highlighting the problem:
private class AbstractStringBuilder {
def length: Int = ...
def append(xs: Array[Char]): AbstractStringBuilder = ...
}
class StringBuilder extends AbstractStringBuilder {
override def append(xs: Array[Char]): StringBuilder = ...
<bridge> def length: Int = super.length
<bridge> def append(xs: Array[Char]): AbstractStringBuilder = this.append(xs)
}
User code
val sb = new StringBuilder
sb.length // needs to access bridge in StringBuilder
sb.append(arr) // should not access bridge in StringBuilder
In the first case, `sb.length` needs to access the bridge method, as
the inherited method is inaccssible. So we cannot simply hide bridge
methods before erasure, as we do for Scala bridges. But in the second
case, we should not access the bridge append, because it refers an
inaccessible class in its result type.
The fix is simple, but it took me a long time finding it: When merging denotations
with the same signature (which is the case for the two appends, since results are
ignored), always prefer a non-bridge over a bridge as the symbol of a JointRefDenotation.
0 commit comments