Skip to content

Commit 88cfc02

Browse files
authored
Merge pull request #10794 from lrytz/t13007
Avoid call to inaccessible protected java method through self type
2 parents d800253 + 549ee23 commit 88cfc02

File tree

13 files changed

+192
-2
lines changed

13 files changed

+192
-2
lines changed

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

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1287,9 +1287,11 @@ abstract class Erasure extends InfoTransform
12871287

12881288
if (qualSym != owner)
12891289
tree.updateAttachment(new QualTypeSymAttachment(qualSym))
1290-
} else if (!isJvmAccessible(owner, context)) {
1290+
} else if (!isJvmAccessible(owner, context) ||
1291+
// scala/bug#13007: isJvmAccessible is true for a protected java method, even if accessed through erased self type
1292+
sym.isJavaDefined && sym.isProtected && !qual.tpe.typeSymbol.isSubClass(sym.owner)) {
12911293
val qualSym = qual.tpe.typeSymbol
1292-
if (qualSym != owner && isJvmAccessible(qualSym, context) && definesMemberAfterErasure(qualSym, sym))
1294+
if (qualSym != owner && isJvmAccessible(qualSym, context) && (definesMemberAfterErasure(qualSym, sym) || sym.overridingSymbol(qualSym).exists))
12931295
tree.updateAttachment(new QualTypeSymAttachment(qualSym))
12941296
else
12951297
reporter.error(tree.pos, s"Unable to emit reference to ${sym.fullLocationString}, $owner is not accessible in ${context.enclClass.owner}")

test/files/neg/t13007.check

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
Test.scala:9: error: Unable to emit reference to method j in class J, class J is not accessible in trait T
2+
def t4 = j()
3+
^
4+
Test.scala:10: error: Unable to emit reference to method j in class J, class J is not accessible in trait T
5+
def t5 = this.j()
6+
^
7+
Test.scala:11: error: Unable to emit reference to method j in class J, class J is not accessible in trait T
8+
def t6 = self.j()
9+
^
10+
3 errors

test/files/neg/t13007/J.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
package j;
2+
3+
public class J {
4+
protected boolean i() { return false; }
5+
protected boolean j() { return false; }
6+
public boolean k() { return false; }
7+
}

test/files/neg/t13007/Test.scala

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
package s
2+
3+
trait T { self: j.J =>
4+
override def i(): Boolean = true
5+
def t1 = i()
6+
def t2 = this.i()
7+
def t3 = self.i()
8+
9+
def t4 = j()
10+
def t5 = this.j()
11+
def t6 = self.j()
12+
13+
def t7 = k()
14+
def t8 = this.k()
15+
def t9 = self.k()
16+
}
17+
18+
class C extends j.J with T

test/files/neg/t13307b.check

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
Test.scala:8: error: Implementation restriction: trait T accesses protected method j inside a concrete trait method.
2+
Add an accessor in a class extending class J as a workaround.
3+
def t4 = j()
4+
^
5+
Test.scala:9: error: Implementation restriction: trait T accesses protected method j inside a concrete trait method.
6+
Add an accessor in a class extending class J as a workaround.
7+
def t5 = this.j()
8+
^
9+
2 errors

test/files/neg/t13307b/J.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
package j;
2+
3+
public class J {
4+
protected boolean i() { return false; }
5+
protected boolean j() { return false; }
6+
public boolean k() { return false; }
7+
}

test/files/neg/t13307b/Test.scala

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
package s
2+
3+
trait T extends j.J {
4+
override def i(): Boolean = true
5+
def t1 = i()
6+
def t2 = this.i()
7+
8+
def t4 = j()
9+
def t5 = this.j()
10+
11+
def t7 = k()
12+
def t8 = this.k()
13+
}
14+
15+
class C extends j.J with T

test/files/run/t13007/J.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
package j;
2+
3+
public class J {
4+
protected boolean i() { return false; }
5+
protected boolean j() { return false; }
6+
public boolean k() { return false; }
7+
}

test/files/run/t13007/Test.scala

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
package s {
2+
3+
trait T {
4+
self: j.J =>
5+
override def i(): Boolean = true
6+
7+
def t1 = i()
8+
def t2 = this.i()
9+
def t3 = self.i()
10+
11+
// def t4 = j()
12+
// def t5 = this.j()
13+
// def t6 = self.j()
14+
15+
def t7 = k()
16+
def t8 = this.k()
17+
def t9 = self.k()
18+
}
19+
20+
class C extends j.J with T
21+
}
22+
23+
object Test {
24+
def main(args: Array[String]): Unit = {
25+
val c = new s.C
26+
assert(c.t1)
27+
assert(c.t2)
28+
assert(c.t3)
29+
assert(!c.t7)
30+
assert(!c.t8)
31+
assert(!c.t9)
32+
}
33+
}

test/files/run/t13307b/J.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
package j;
2+
3+
public class J {
4+
protected boolean i() { return false; }
5+
protected boolean j() { return false; }
6+
public boolean k() { return false; }
7+
}

0 commit comments

Comments
 (0)