Skip to content

Commit 1962ada

Browse files
committed
Merge pull request #633 from dotty-staging/fix/refs-to-inner-objects
Fix/refs to inner objects
2 parents 6ca52b0 + 4c659a3 commit 1962ada

File tree

10 files changed

+33
-36
lines changed

10 files changed

+33
-36
lines changed

src/dotty/tools/dotc/ast/tpd.scala

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -326,23 +326,24 @@ object tpd extends Trees.Instance[Type] with TypedTreeInfo {
326326
def ref(tp: NamedType)(implicit ctx: Context): Tree =
327327
if (tp.isType) TypeTree(tp)
328328
else if (prefixIsElidable(tp)) Ident(tp)
329+
else if (tp.symbol.is(Module) && ctx.owner.isContainedIn(tp.symbol.moduleClass))
330+
followOuterLinks(This(tp.symbol.moduleClass.asClass))
329331
else tp.prefix match {
330-
case pre: SingletonType =>
331-
val prefix =
332-
singleton(pre) match {
333-
case t: This if ctx.erasedTypes && !(t.symbol == ctx.owner.enclosingClass || t.symbol.isStaticOwner) =>
334-
// after erasure outer paths should be respected
335-
new ExplicitOuter.OuterOps(ctx).path(t.tpe.widen.classSymbol)
336-
case t =>
337-
t
338-
}
339-
prefix.select(tp)
332+
case pre: SingletonType => followOuterLinks(singleton(pre)).select(tp)
340333
case pre => SelectFromTypeTree(TypeTree(pre), tp)
341334
} // no checks necessary
342335

343336
def ref(sym: Symbol)(implicit ctx: Context): Tree =
344337
ref(NamedType(sym.owner.thisType, sym.name, sym.denot))
345338

339+
private def followOuterLinks(t: Tree)(implicit ctx: Context) = t match {
340+
case t: This if ctx.erasedTypes && !(t.symbol == ctx.owner.enclosingClass || t.symbol.isStaticOwner) =>
341+
// after erasure outer paths should be respected
342+
new ExplicitOuter.OuterOps(ctx).path(t.tpe.widen.classSymbol)
343+
case t =>
344+
t
345+
}
346+
346347
def singleton(tp: Type)(implicit ctx: Context): Tree = tp match {
347348
case tp: TermRef => ref(tp)
348349
case tp: ThisType => This(tp.cls)

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

Lines changed: 10 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -274,24 +274,17 @@ object Denotations {
274274
val sym1 = denot1.symbol
275275
val sym2 = denot2.symbol
276276
val sym2Accessible = sym2.isAccessibleFrom(pre)
277-
def shadows(sym1: Symbol, sym2: Symbol) = {
278-
val owner1 = sym1.owner
279-
val owner2 = sym2.owner
280-
owner1.derivesFrom(owner2) && owner1.ne(owner2)
277+
def unshadowed(sym: Symbol, from: Symbol) = {
278+
val symOwner = sym.owner
279+
val fromOwner = from.owner
280+
!fromOwner.derivesFrom(symOwner) || fromOwner.eq(symOwner)
281281
}
282-
/** Preference according to order (overrides, isAsConcrete, shadows)*/
282+
/** Preference according to partial pre-order (isConcrete, unshadowed) */
283+
def preferSym(sym1: Symbol, sym2: Symbol) =
284+
sym1.isAsConcrete(sym2) && (!sym2.isAsConcrete(sym1) || unshadowed(sym1, sym2))
285+
/** Sym preference provided types also override */
283286
def prefer(info1: Type, sym1: Symbol, info2: Type, sym2: Symbol) =
284-
info1.overrides(info2) && (
285-
// non-standard ordering of tests for efficiency -
286-
// overrides is costlier to compute than the others, so its 2nd test comes last.
287-
sym1.isAsConcrete(sym2) && (
288-
!sym2.isAsConcrete(sym1)
289-
||
290-
shadows(sym1, sym2)
291-
)
292-
||
293-
!info2.overrides(info1)
294-
)
287+
preferSym(sym1, sym2) && info1.overrides(info2)
295288
if (sym2Accessible && prefer(info2, sym2, info1, sym1)) denot2
296289
else {
297290
val sym1Accessible = sym1.isAccessibleFrom(pre)
@@ -302,7 +295,7 @@ object Denotations {
302295
val sym =
303296
if (!sym1.exists) sym2
304297
else if (!sym2.exists) sym1
305-
else if (sym2 isAsConcrete sym1) sym2
298+
else if (preferSym(sym2, sym1)) sym2
306299
else sym1
307300
new JointRefDenotation(sym, info1 & info2, denot1.validFor & denot2.validFor)
308301
}

src/dotty/tools/dotc/transform/ExplicitOuter.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -221,7 +221,7 @@ object ExplicitOuter {
221221
case nw: New =>
222222
isOuter(nw.tpe.classSymbol.owner.enclosingClass)
223223
case _ =>
224-
false
224+
false
225225
}
226226
}
227227

src/dotty/tools/dotc/typer/RefChecks.scala

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -420,7 +420,7 @@ object RefChecks {
420420
for (member <- missing) {
421421
val memberSym = member.symbol
422422
def undefined(msg: String) =
423-
abstractClassError(false, member.showDcl + " is not defined" + msg)
423+
abstractClassError(false, s"${member.showDcl} is not defined $msg")
424424
val underlying = memberSym.underlyingSymbol
425425

426426
// Give a specific error message for abstract vars based on why it fails:
@@ -456,9 +456,8 @@ object RefChecks {
456456
case (pa, pc) :: Nil =>
457457
val abstractSym = pa.typeSymbol
458458
val concreteSym = pc.typeSymbol
459-
def subclassMsg(c1: Symbol, c2: Symbol) = (
460-
": %s is a subclass of %s, but method parameter types must match exactly.".format(
461-
c1.showLocated, c2.showLocated))
459+
def subclassMsg(c1: Symbol, c2: Symbol) =
460+
s": ${c1.showLocated} is a subclass of ${c2.showLocated}, but method parameter types must match exactly."
462461
val addendum =
463462
if (abstractSym == concreteSym) {
464463
val paArgs = pa.argInfos
@@ -478,12 +477,14 @@ object RefChecks {
478477
subclassMsg(concreteSym, abstractSym)
479478
else ""
480479

481-
undefined("\n(Note that %s does not match %s%s)".format(pa, pc, addendum))
480+
undefined(s"\n(Note that $pa does not match $pc$addendum)")
482481
case xs =>
483-
undefined("")
482+
undefined(s"\n(The class implements a member with a different type: ${concrete.showDcl})")
484483
}
485-
case _ =>
484+
case Nil =>
486485
undefined("")
486+
case concretes =>
487+
undefined(s"\n(The class implements members with different types: ${concretes.map(_.showDcl)}%\n %)")
487488
}
488489
} else undefined("")
489490
}
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.

tests/disabled/pos/t3174.scala renamed to tests/pos/t3174.scala

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@ object test {
22
def method(): Unit = {
33
class Foo extends AnyRef {
44
object Color {
5-
object Blue
5+
object Blue {
6+
//val b = new Board
7+
}
68
}
79

810
class Board {
File renamed without changes.

0 commit comments

Comments
 (0)