@@ -21,6 +21,7 @@ import config.MigrationVersion
2121import config .Printers .refcheck
2222import reporting .*
2323import Constants .Constant
24+ import dotty .tools .dotc .printing .Formatting .hl
2425
2526object RefChecks {
2627 import tpd .*
@@ -1257,6 +1258,18 @@ object RefChecks {
12571258 case tp : NamedType if tp.prefix.typeSymbol != ctx.owner.enclosingClass =>
12581259 report.warning(UnqualifiedCallToAnyRefMethod (tree, tree.symbol), tree)
12591260 case _ => ()
1261+
1262+ def checkJavaStaticProtected (tree : tpd.Apply | tpd.Select | tpd.Assign )(using Context ): Unit =
1263+ val sym = tree.symbol
1264+ if sym.isAllOf(StaticProtected ) then
1265+ val definedPackage = sym.enclosingPackageClass
1266+ val definedClass = sym.owner.companionClass // it's _not_ sym.enclosingClass because it's static, therefore enclosed in a companion object, not a class
1267+ val enclosingPackage = ctx.owner.enclosingPackageClass
1268+
1269+ if definedPackage != enclosingPackage && ! ctx.owner.ownersIterator.exists(_.derivesFrom(definedClass)) then
1270+ report.error(em " ${StaticProtected } $sym which is defined in $definedPackage is inaccessible at runtime from $enclosingPackage" , tree.srcPos)
1271+ end checkJavaStaticProtected
1272+
12601273}
12611274import RefChecks .*
12621275
@@ -1346,6 +1359,15 @@ class RefChecks extends MiniPhase { thisPhase =>
13461359 override def transformSelect (tree : tpd.Select )(using Context ): tpd.Tree =
13471360 if defn.ScalaBoxedClasses ().contains(tree.qualifier.tpe.typeSymbol) && tree.name == nme.synchronized_ then
13481361 report.warning(SynchronizedCallOnBoxedClass (tree), tree.srcPos)
1362+ checkJavaStaticProtected(tree)
1363+ tree
1364+
1365+ override def transformApply (tree : tpd.Apply )(using Context ): tpd.Apply =
1366+ checkJavaStaticProtected(tree)
1367+ tree
1368+
1369+ override def transformAssign (tree : tpd.Assign )(using Context ): tpd.Assign =
1370+ checkJavaStaticProtected(tree)
13491371 tree
13501372}
13511373
0 commit comments