Skip to content

Commit c9c8f22

Browse files
committed
TypeAssigner#avoid: don't miss escaping refs in complex types
1 parent 48acd08 commit c9c8f22

File tree

2 files changed

+20
-15
lines changed

2 files changed

+20
-15
lines changed

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

Lines changed: 11 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -42,22 +42,19 @@ trait TypeAssigner {
4242
def avoid(tp: Type, symsToAvoid: => List[Symbol])(implicit ctx: Context): Type = {
4343
val widenMap = new TypeMap {
4444
lazy val forbidden = symsToAvoid.toSet
45-
def toAvoid(tp: Type): Boolean = tp match {
46-
case tp: TermRef =>
47-
val sym = tp.symbol
48-
sym.exists && (
49-
sym.owner.isTerm && (forbidden contains sym)
50-
|| !(sym.owner is Package) && toAvoid(tp.prefix)
51-
)
52-
case tp: TypeRef =>
53-
forbidden contains tp.symbol
54-
case _ =>
55-
false
56-
}
45+
def toAvoid(tp: Type): Boolean =
46+
// TODO: measure the cost of using `existsPart`, and if necessary replace it
47+
// by a `TypeAccumulator` where we have set `stopAtStatic = true`.
48+
tp existsPart {
49+
case tp: NamedType =>
50+
forbidden contains tp.symbol
51+
case _ =>
52+
false
53+
}
5754
def apply(tp: Type): Type = tp match {
5855
case tp: TermRef if toAvoid(tp) && variance > 0 =>
5956
apply(tp.info.widenExpr)
60-
case tp: TypeRef if (forbidden contains tp.symbol) || toAvoid(tp.prefix) =>
57+
case tp: TypeRef if toAvoid(tp) =>
6158
tp.info match {
6259
case TypeAlias(ref) =>
6360
apply(ref)
@@ -92,7 +89,7 @@ trait TypeAssigner {
9289
}
9390
case tp: RefinedType =>
9491
val tp1 @ RefinedType(parent1, _) = mapOver(tp)
95-
if (tp1.refinedInfo.existsPart(toAvoid) && variance > 0) {
92+
if (toAvoid(tp1.refinedInfo) && variance > 0) {
9693
typr.println(s"dropping refinement from $tp1")
9794
parent1
9895
}

tests/pos/escapingRefs.scala

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
class Outer {
2-
class Inner
2+
class Inner {
3+
class Inner2
4+
}
35
}
46

57
object Test {
@@ -8,5 +10,11 @@ object Test {
810
val o = new Outer
911
new o.Inner
1012
}
13+
14+
val b: Outer#Inner#Inner2 = {
15+
val o = new Outer
16+
val i = new o.Inner
17+
new i.Inner2
18+
}
1119
}
1220
}

0 commit comments

Comments
 (0)