Skip to content

Commit 6177066

Browse files
committed
SI-5162 Exclude super.foo from the erasure cast of SI-4283
If the target method is defined in Java, treat the super reference as an error, otherwise allow it in the knowledge that Scala loosens the access restrictions on its generated classes. Moves the test for that bug out of pending-ville. It's sufficient to place Test in the empty package to exercise the right code paths.
1 parent 30ef129 commit 6177066

File tree

10 files changed

+61
-12
lines changed

10 files changed

+61
-12
lines changed

src/compiler/scala/tools/nsc/transform/Erasure.scala

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1042,18 +1042,27 @@ abstract class Erasure extends AddInterfaces
10421042
assert(overridden != NoSymbol, tree.symbol)
10431043
tree.symbol = overridden
10441044
}
1045+
10451046
def isAccessible(sym: Symbol) = localTyper.context.isAccessible(sym, sym.owner.thisType)
10461047
if (!isAccessible(owner) && qual.tpe != null) {
1047-
// Todo: Figure out how qual.tpe could be null in the check above (it does appear in build where SwingWorker.this
1048-
// has a null type).
1049-
val qualSym = qual.tpe.widen.typeSymbol
1050-
if (isAccessible(qualSym) && !qualSym.isPackageClass && !qualSym.isPackageObjectClass) {
1051-
// insert cast to prevent illegal access error (see #4283)
1052-
// util.trace("insert erasure cast ") (*/
1053-
treeCopy.Select(tree, gen.mkAttributedCast(qual, qual.tpe.widen), name) //)
1054-
} else tree
1048+
qual match {
1049+
case Super(_, _) =>
1050+
// Insert a cast here at your peril -- see SI-5162. Bail out if the target method is defined in
1051+
// Java, otherwise, we'd get an IllegalAccessError at runtime. If the target method is defined in
1052+
// Scala, however, we should have access.
1053+
if (owner.isJavaDefined) unit.error(tree.pos, s"Unable to access ${tree.symbol.fullLocationString} with a super reference.")
1054+
tree
1055+
case _ =>
1056+
// Todo: Figure out how qual.tpe could be null in the check above (it does appear in build where SwingWorker.this
1057+
// has a null type).
1058+
val qualSym = qual.tpe.widen.typeSymbol
1059+
if (isAccessible(qualSym) && !qualSym.isPackageClass && !qualSym.isPackageObjectClass) {
1060+
// insert cast to prevent illegal access error (see #4283)
1061+
// util.trace("insert erasure cast ") (*/
1062+
treeCopy.Select(tree, gen.mkAttributedCast(qual, qual.tpe.widen), name) //)
1063+
} else tree
1064+
}
10551065
} else tree
1056-
10571066
case Template(parents, self, body) =>
10581067
assert(!currentOwner.isImplClass)
10591068
//Console.println("checking no dble defs " + tree)//DEBUG

test/files/neg/t4283b.check

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
Test.scala:2: error: Unable to access method f in class AbstractFoo with a super reference.
2+
override def f(): Int = super.f()
3+
^
4+
one error found
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
package test;
2+
3+
/* package private */ class AbstractFoo {
4+
public int f() { return 2; }
5+
}
File renamed without changes.

test/files/neg/t4283b/Test.scala

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
object Derived extends test.ScalaBipp {
2+
override def f(): Int = super.f()
3+
}

test/files/run/t4283.check

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
2
2+
2
3+
1
4+
1
5+
1
File renamed without changes.
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
package test
2+
3+
class ScalaBipp extends AbstractFoo {
4+
def make: Option[ScalaBipp] = Option(this)
5+
}

test/pending/run/t4283/IllegalAccess.scala renamed to test/files/run/t4283/Test.scala

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
1-
package other
1+
object Test {
22

3-
object IllegalAccess {
43
def main(args: Array[String]) {
5-
val x = (new test.ScalaBipp).make.get.asInstanceOf[test.ScalaBipp].f()
4+
val x = (new test.ScalaBipp).make.get.asInstanceOf[test.ScalaBipp].f()
65
println(x)
76
val y = (new test.ScalaBipp).make.get.f()
87
println(y)

test/files/run/t5162.scala

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
// In run, rather than pos, to check for problems like SI-4283
2+
object O1 {
3+
private[O1] class Base {
4+
def foo: Int = 0
5+
}
6+
class Mediator extends Base
7+
}
8+
9+
object O2 {
10+
class Derived extends O1.Mediator {
11+
override def foo: Int = super.foo
12+
}
13+
}
14+
15+
object Test {
16+
def main(args: Array[String]) {
17+
new O2.Derived().foo
18+
}
19+
}

0 commit comments

Comments
 (0)