Skip to content

Commit 11d54d3

Browse files
committed
Fix accessibleType for package object prefixes
Making a package object explicit re-computes the denotations of an overloaded method. So it should not be done after we have pruned down those denotations by an accessibility test. We now do it before checking accessibility. Fixes #15821
1 parent db2d197 commit 11d54d3

File tree

3 files changed

+28
-15
lines changed

3 files changed

+28
-15
lines changed

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

Lines changed: 2 additions & 2 deletions
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

Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -81,21 +81,25 @@ trait TypeAssigner {
8181
* (2) in Java compilation units, `Object` is replaced by `defn.FromJavaObjectType`
8282
*/
8383
def accessibleType(tpe: Type, superAccess: Boolean)(using Context): Type =
84-
tpe match
84+
if ctx.isJava && tpe.isAnyRef then
85+
defn.FromJavaObjectType
86+
else tpe match
8587
case tpe: NamedType =>
86-
val pre = tpe.prefix
87-
val name = tpe.name
88-
def postProcess(d: Denotation) =
89-
if ctx.isJava && tpe.isAnyRef then defn.FromJavaObjectType
90-
else TypeOps.makePackageObjPrefixExplicit(tpe withDenot d)
91-
val d = tpe.denot.accessibleFrom(pre, superAccess)
92-
if d.exists then postProcess(d)
88+
val tpe1 = TypeOps.makePackageObjPrefixExplicit(tpe)
89+
if tpe1 ne tpe then
90+
accessibleType(tpe1, superAccess)
9391
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 postProcess(d2)
98-
else NoType
92+
val pre = tpe.prefix
93+
val name = tpe.name
94+
val d = tpe.denot.accessibleFrom(pre, superAccess)
95+
if d eq tpe.denot then tpe
96+
else if d.exists then tpe.withDenot(d)
97+
else
98+
// it could be that we found an inaccessible private member, but there is
99+
// an inherited non-private member with the same name and signature.
100+
val d2 = pre.nonPrivateMember(name).accessibleFrom(pre, superAccess)
101+
if reallyExists(d2) then tpe.withDenot(d2)
102+
else NoType
99103
case tpe => tpe
100104

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

tests/pos/i15821.scala

Lines changed: 9 additions & 0 deletions
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)