Skip to content

Commit 4a27365

Browse files
Backport "Fixes IllegalAccessError with Java package protected class" to LTS (#22123)
Backports #21362 to the 3.3.5. PR submitted by the release tooling. [skip ci]
2 parents ad9cf71 + 2d434f7 commit 4a27365

File tree

4 files changed

+64
-25
lines changed

4 files changed

+64
-25
lines changed

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

+28-25
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ import ExplicitOuter.*
3535
import core.Mode
3636
import util.Property
3737
import reporting.*
38+
import scala.annotation.tailrec
3839

3940
class Erasure extends Phase with DenotTransformer {
4041

@@ -755,7 +756,8 @@ object Erasure {
755756
(ctx.owner.enclosingPackageClass eq boundary)
756757
}
757758

758-
def recur(qual: Tree): Tree = {
759+
@tailrec
760+
def recur(qual: Tree): Tree =
759761
val qualIsPrimitive = qual.tpe.widen.isPrimitiveValueType
760762
val symIsPrimitive = sym.owner.isPrimitiveValueClass
761763

@@ -764,33 +766,34 @@ object Erasure {
764766
inContext(preErasureCtx):
765767
tree.qualifier.typeOpt.widen.finalResultType)
766768

767-
if (qualIsPrimitive && !symIsPrimitive || qual.tpe.widenDealias.isErasedValueType)
769+
if qualIsPrimitive && !symIsPrimitive || qual.tpe.widenDealias.isErasedValueType then
768770
recur(box(qual))
769-
else if (!qualIsPrimitive && symIsPrimitive)
771+
else if !qualIsPrimitive && symIsPrimitive then
770772
recur(unbox(qual, sym.owner.typeRef))
771-
else if (sym.owner eq defn.ArrayClass)
773+
else if sym.owner eq defn.ArrayClass then
772774
selectArrayMember(qual, originalQual)
773-
else {
774-
val qual1 = adaptIfSuper(qual)
775-
if (qual1.tpe.derivesFrom(sym.owner) || qual1.isInstanceOf[Super])
776-
select(qual1, sym)
777-
else
778-
val castTarget = // Avoid inaccessible cast targets, see i8661
779-
if isJvmAccessible(sym.owner) && sym.owner.isType
780-
then
781-
sym.owner.typeRef
782-
else
783-
// If the owner is inaccessible, try going through the qualifier,
784-
// but be careful to not go in an infinite loop in case that doesn't
785-
// work either.
786-
val tp = originalQual
787-
if tp =:= qual1.tpe.widen then
788-
return errorTree(qual1,
789-
em"Unable to emit reference to ${sym.showLocated}, ${sym.owner} is not accessible in ${ctx.owner.enclosingClass}")
790-
tp
791-
recur(cast(qual1, castTarget))
792-
}
793-
}
775+
else
776+
adaptIfSuper(qual) match
777+
case qual1: Super =>
778+
select(qual1, sym)
779+
case qual1 if !isJvmAccessible(qual1.tpe.typeSymbol)
780+
|| !qual1.tpe.derivesFrom(sym.owner) =>
781+
val castTarget = // Avoid inaccessible cast targets, see i8661
782+
if isJvmAccessible(sym.owner) && sym.owner.isType then
783+
sym.owner.typeRef
784+
else
785+
// If the owner is inaccessible, try going through the qualifier,
786+
// but be careful to not go in an infinite loop in case that doesn't
787+
// work either.
788+
val tp = originalQual
789+
if tp =:= qual1.tpe.widen then
790+
return errorTree(qual1,
791+
em"Unable to emit reference to ${sym.showLocated}, ${sym.owner} is not accessible in ${ctx.owner.enclosingClass}")
792+
tp
793+
recur(cast(qual1, castTarget))
794+
case qual1 =>
795+
select(qual1, sym)
796+
end recur
794797

795798
checkNotErased(recur(qual1))
796799
}
+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
// filter: unchecked
2+
package a;
3+
4+
/** This is package protected. */
5+
class B<T extends B<T>> {
6+
private int connectTimeout = 10000;
7+
private int failedAttempts = 3;
8+
9+
public T setConnectTimeout(int connectTimeout) {
10+
this.connectTimeout = connectTimeout;
11+
return (T) this;
12+
}
13+
14+
public T setFailedAttempts(int failedAttempts) {
15+
this.failedAttempts = failedAttempts;
16+
return (T) this;
17+
}
18+
}
19+
20+
/** This is public. */
21+
public class A extends B<A> { }
+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
package b
2+
3+
import a.*
4+
5+
object C:
6+
def m: Int =
7+
val a = new A()
8+
.setConnectTimeout(1)
9+
.setFailedAttempts(1)
10+
0
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
// scalajs: --skip
2+
3+
object Test extends App:
4+
assert(b.C.m == 0)
5+
end Test

0 commit comments

Comments
 (0)