Skip to content

Commit 009137f

Browse files
committed
Split out testing code from ensureAccessible
1 parent 1f68f97 commit 009137f

File tree

1 file changed

+48
-1
lines changed

1 file changed

+48
-1
lines changed

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

Lines changed: 48 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,53 @@ trait TypeAssigner {
7070
case ex: StaleSymbol => false
7171
}
7272

73+
def accessibleType(tpe: Type, superAccess: Boolean)(using Context): Type =
74+
tpe match
75+
case tpe: NamedType =>
76+
val pre = tpe.prefix
77+
val name = tpe.name
78+
def postProcess(d: Denotation) =
79+
if ctx.isJava && tpe.isAnyRef then defn.FromJavaObjectType
80+
else TypeOps.makePackageObjPrefixExplicit(tpe withDenot d)
81+
val d = tpe.denot.accessibleFrom(pre, superAccess)
82+
if d.exists then postProcess(d)
83+
else
84+
// it could be that we found an inaccessible private member, but there is
85+
// an inherited non-private member with the same name and signature.
86+
val d2 = pre.nonPrivateMember(name).accessibleFrom(pre, superAccess)
87+
if reallyExists(d2) then
88+
postProcess(d2)
89+
else if (pre.derivesFrom(defn.DynamicClass) && name.isTermName)
90+
TryDynamicCallType // TODO: drop
91+
else
92+
NoType
93+
case tpe => tpe
94+
95+
def ensureAccessible(tpe: Type, superAccess: Boolean, pos: SrcPos)(using Context): Type =
96+
val tpe1 = accessibleType(tpe, superAccess)
97+
if tpe1.exists then tpe1
98+
else tpe match
99+
case tpe: NamedType =>
100+
val pre = tpe.prefix
101+
val name = tpe.name
102+
val alts = tpe.denot.alternatives.map(_.symbol).filter(_.exists)
103+
var packageAccess = false
104+
val whatCanNot = alts match {
105+
case Nil =>
106+
em"$name cannot"
107+
case sym :: Nil =>
108+
em"${if (sym.owner == pre.typeSymbol) sym.show else sym.showLocated} cannot"
109+
case _ =>
110+
em"none of the overloaded alternatives named $name can"
111+
}
112+
val where = if (ctx.owner.exists) s" from ${ctx.owner.enclosingClass}" else ""
113+
val whyNot = new StringBuffer
114+
alts.foreach(_.isAccessibleFrom(pre, superAccess, whyNot))
115+
if tpe.isError then tpe
116+
else errorType(ex"$whatCanNot be accessed as a member of $pre$where.$whyNot", pos)
117+
case _ =>
118+
tpe
119+
73120
/** If `tpe` is a named type, check that its denotation is accessible in the
74121
* current context. Return the type with those alternatives as denotations
75122
* which are accessible.
@@ -80,7 +127,7 @@ trait TypeAssigner {
80127
* that the package object shows up as the prefix.
81128
* (3) in Java compilation units, `Object` is replaced by `defn.FromJavaObjectType`
82129
*/
83-
def ensureAccessible(tpe: Type, superAccess: Boolean, pos: SrcPos)(using Context): Type = {
130+
def ensureAccessibleOLD(tpe: Type, superAccess: Boolean, pos: SrcPos)(using Context): Type = {
84131
def test(tpe: Type, firstTry: Boolean): Type = tpe match {
85132
case tpe: NamedType =>
86133
val pre = tpe.prefix

0 commit comments

Comments
 (0)