Skip to content

Commit 1bef624

Browse files
committed
Fix #4430: Disallow access to Java bridge methods before typer
Scala bridge methods only come to existence during erasure, so are not visible before. But Java bridge methods come with their class files. To get parity, we have to ignore them before erasure. We do this by marking them as private and turning off the private flag at erasure.
1 parent 5a9a8c2 commit 1bef624

File tree

6 files changed

+19
-3
lines changed

6 files changed

+19
-3
lines changed

compiler/src/dotty/tools/dotc/core/Flags.scala

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -632,6 +632,9 @@ object Flags {
632632
/** A Java companion object */
633633
final val JavaProtected = allOf(JavaDefined, Protected)
634634

635+
/** A private Java bridge method */
636+
final val PrivateJavaBridge = allOf(Private, JavaDefined, Bridge)
637+
635638
/** A Java enum */
636639
final val JavaEnum = allOf(JavaDefined, Enum)
637640

compiler/src/dotty/tools/dotc/core/classfile/ClassfileParser.scala

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -212,8 +212,10 @@ class ClassfileParser(
212212
else fieldTranslation.flags(jflags)
213213
val name = pool.getName(in.nextChar)
214214
if (!(sflags is Flags.Private) || name == nme.CONSTRUCTOR) {
215+
val sflags1 =
216+
if (sflags.is(Flags.Bridge) && !ctx.erasedTypes) sflags | Flags.Private else sflags
215217
val member = ctx.newSymbol(
216-
getOwner(jflags), name, sflags, memberCompleter, coord = start)
218+
getOwner(jflags), name, sflags1, memberCompleter, coord = start)
217219
getScope(jflags).enter(member)
218220
}
219221
// skip rest of member for now

compiler/src/dotty/tools/dotc/core/tasty/TreeUnpickler.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -971,7 +971,7 @@ class TreeUnpickler(reader: TastyReader,
971971

972972
def accessibleDenot(pre: Type, name: Name, sig: Signature) = {
973973
val d = pre.member(name).atSignature(sig)
974-
if (!d.symbol.exists || d.symbol.isAccessibleFrom(pre)) d
974+
if (d.exists && !d.symbol.exists || d.symbol.isAccessibleFrom(pre)) d
975975
else pre.nonPrivateMember(name).atSignature(sig)
976976
}
977977

compiler/src/dotty/tools/dotc/transform/Erasure.scala

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,8 @@ class Erasure extends Phase with DenotTransformer {
7474
val newInfo = transformInfo(oldSymbol, oldInfo)
7575
val oldFlags = ref.flags
7676
val newFlags =
77-
if (oldSymbol.is(Flags.TermParam) && isCompacted(oldSymbol.owner)) oldFlags &~ Flags.Param
77+
if (oldFlags.is(Flags.TermParam) && isCompacted(oldSymbol.owner)) oldFlags &~ Flags.Param
78+
else if (oldFlags.is(Flags.PrivateJavaBridge)) oldFlags &~ Flags.Private
7879
else oldFlags &~ Flags.HasDefaultParams // HasDefaultParams needs to be dropped because overriding might become overloading
7980

8081
// TODO: define derivedSymDenotation?

tests/pickling/i4430.scala

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
object Test {
2+
def main(args: Array[String]): Unit = {
3+
(new java.lang.StringBuilder()).append(Array[Char](), 0, 0)
4+
}
5+
}

tests/run/i4430.scala

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
object Test {
2+
def main(args: Array[String]): Unit = {
3+
(new java.lang.StringBuilder()).append(Array[Char](), 0, 0)
4+
}
5+
}

0 commit comments

Comments
 (0)