Skip to content

Commit 35e6553

Browse files
committed
TypeAssigner#avoid: more precise types for inner classes
When we need to avoid `A` in the class `A#B`, we can try to replace `A` by a supertype. Previously, we only tried to replace `A#B` itself by a supertype. Fixes scala#711.
1 parent a537ac1 commit 35e6553

File tree

2 files changed

+19
-1
lines changed

2 files changed

+19
-1
lines changed

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

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,14 +52,20 @@ trait TypeAssigner {
5252
case _ =>
5353
false
5454
}
55-
def apply(tp: Type) = tp match {
55+
def apply(tp: Type): Type = tp match {
5656
case tp: TermRef if toAvoid(tp) && variance > 0 =>
5757
apply(tp.info.widenExpr)
5858
case tp: TypeRef if (forbidden contains tp.symbol) || toAvoid(tp.prefix) =>
5959
tp.info match {
6060
case TypeAlias(ref) =>
6161
apply(ref)
6262
case info: ClassInfo if variance > 0 =>
63+
if (!(forbidden contains tp.symbol)) {
64+
val prefix = apply(tp.prefix)
65+
val tp1 = tp.derivedSelect(prefix)
66+
if (tp1.typeSymbol eq tp.symbol)
67+
return tp1
68+
}
6369
val parentType = info.instantiatedParents.reduceLeft(ctx.typeComparer.andType(_, _))
6470
def addRefinement(parent: Type, decl: Symbol) = {
6571
val inherited =

tests/pos/escapingRefs.scala

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
class Outer {
2+
class Inner
3+
}
4+
5+
object Test {
6+
def test = {
7+
val a: Outer#Inner = {
8+
val o = new Outer
9+
new o.Inner
10+
}
11+
}
12+
}

0 commit comments

Comments
 (0)