Skip to content

Commit d6af4f9

Browse files
authored
Backport "Fix accessibleType for package object prefixes" (#18088)
Backports #18057 Fixes #15821
2 parents 8f3b3c2 + 186e4be commit d6af4f9

File tree

4 files changed

+34
-16
lines changed

4 files changed

+34
-16
lines changed

community-build/test/scala/dotty/communitybuild/CommunityBuildTest.scala

+6-1
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,12 @@ class CommunityBuildTestC:
9393
@Test def sconfig = projects.sconfig.run()
9494
@Test def shapeless = projects.shapeless.run()
9595
@Test def sourcecode = projects.sourcecode.run()
96-
@Test def specs2 = projects.specs2.run()
96+
97+
// Disabled. Currently fails in FutureMatchers.scala. The call to
98+
// `checkResultFailure` goes to a protected method which is not accessible.
99+
// I tried to fix it, but get test failures.
100+
// @Test def specs2 = projects.specs2.run()
101+
97102
@Test def stdLib213 = projects.stdLib213.run()
98103
@Test def ujson = projects.ujson.run()
99104
@Test def upickle = projects.upickle.run()

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

+2-2
Original file line numberDiff line numberDiff line change
@@ -1269,8 +1269,8 @@ object Denotations {
12691269
def hasAltWith(p: SingleDenotation => Boolean): Boolean =
12701270
denot1.hasAltWith(p) || denot2.hasAltWith(p)
12711271
def accessibleFrom(pre: Type, superAccess: Boolean)(using Context): Denotation = {
1272-
val d1 = denot1 accessibleFrom (pre, superAccess)
1273-
val d2 = denot2 accessibleFrom (pre, superAccess)
1272+
val d1 = denot1.accessibleFrom(pre, superAccess)
1273+
val d2 = denot2.accessibleFrom(pre, superAccess)
12741274
if (!d1.exists) d2
12751275
else if (!d2.exists) d1
12761276
else derivedUnionDenotation(d1, d2)

compiler/src/dotty/tools/dotc/typer/TypeAssigner.scala

+17-13
Original file line numberDiff line numberDiff line change
@@ -77,21 +77,25 @@ trait TypeAssigner {
7777
* (2) in Java compilation units, `Object` is replaced by `defn.FromJavaObjectType`
7878
*/
7979
def accessibleType(tpe: Type, superAccess: Boolean)(using Context): Type =
80-
tpe match
80+
if ctx.isJava && tpe.isAnyRef then
81+
defn.FromJavaObjectType
82+
else tpe match
8183
case tpe: NamedType =>
82-
val pre = tpe.prefix
83-
val name = tpe.name
84-
def postProcess(d: Denotation) =
85-
if ctx.isJava && tpe.isAnyRef then defn.FromJavaObjectType
86-
else TypeOps.makePackageObjPrefixExplicit(tpe withDenot d)
87-
val d = tpe.denot.accessibleFrom(pre, superAccess)
88-
if d.exists then postProcess(d)
84+
val tpe1 = TypeOps.makePackageObjPrefixExplicit(tpe)
85+
if tpe1 ne tpe then
86+
accessibleType(tpe1, superAccess)
8987
else
90-
// it could be that we found an inaccessible private member, but there is
91-
// an inherited non-private member with the same name and signature.
92-
val d2 = pre.nonPrivateMember(name).accessibleFrom(pre, superAccess)
93-
if reallyExists(d2) then postProcess(d2)
94-
else NoType
88+
val pre = tpe.prefix
89+
val name = tpe.name
90+
val d = tpe.denot.accessibleFrom(pre, superAccess)
91+
if d eq tpe.denot then tpe
92+
else if d.exists then tpe.withDenot(d)
93+
else
94+
// it could be that we found an inaccessible private member, but there is
95+
// an inherited non-private member with the same name and signature.
96+
val d2 = pre.nonPrivateMember(name).accessibleFrom(pre, superAccess)
97+
if reallyExists(d2) then tpe.withDenot(d2)
98+
else NoType
9599
case tpe => tpe
96100

97101
/** Try to make `tpe` accessible, emit error if not possible */

tests/pos/i15821.scala

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
def main =
2+
foo.bar(42)
3+
foo.bar
4+
5+
package object foo {
6+
def bar[F[_]]: Unit = ???
7+
def bar[F[_]](x: Int): Unit = ???
8+
private[foo] def bar[F[_]](x: Int)(implicit dummy: DummyImplicit): Unit = ???
9+
}

0 commit comments

Comments
 (0)