Skip to content

Commit 49680df

Browse files
oderskyKordyjan
authored andcommitted
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 8f3b3c2 commit 49680df

File tree

3 files changed

+28
-15
lines changed

3 files changed

+28
-15
lines changed

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)