diff options
author | Guillaume Martres <smarter@ubuntu.com> | 2015-10-02 11:56:44 +0200 |
---|---|---|
committer | Guillaume Martres <smarter@ubuntu.com> | 2015-10-09 14:59:59 +0200 |
commit | c9c8f223f832a602f4487f3a6a5b75b8affe6280 (patch) | |
tree | ad26b1161fcc1fdb69a6a968d46b0d4da1267ca1 | |
parent | 48acd08ac7e6346ffa573163fc1993cbdae458cd (diff) | |
download | dotty-c9c8f223f832a602f4487f3a6a5b75b8affe6280.tar.gz dotty-c9c8f223f832a602f4487f3a6a5b75b8affe6280.tar.bz2 dotty-c9c8f223f832a602f4487f3a6a5b75b8affe6280.zip |
TypeAssigner#avoid: don't miss escaping refs in complex types
-rw-r--r-- | src/dotty/tools/dotc/typer/TypeAssigner.scala | 25 | ||||
-rw-r--r-- | tests/pos/escapingRefs.scala | 10 |
2 files changed, 20 insertions, 15 deletions
diff --git a/src/dotty/tools/dotc/typer/TypeAssigner.scala b/src/dotty/tools/dotc/typer/TypeAssigner.scala index 496380b3a..22c062243 100644 --- a/src/dotty/tools/dotc/typer/TypeAssigner.scala +++ b/src/dotty/tools/dotc/typer/TypeAssigner.scala @@ -42,22 +42,19 @@ trait TypeAssigner { def avoid(tp: Type, symsToAvoid: => List[Symbol])(implicit ctx: Context): Type = { val widenMap = new TypeMap { lazy val forbidden = symsToAvoid.toSet - def toAvoid(tp: Type): Boolean = tp match { - case tp: TermRef => - val sym = tp.symbol - sym.exists && ( - sym.owner.isTerm && (forbidden contains sym) - || !(sym.owner is Package) && toAvoid(tp.prefix) - ) - case tp: TypeRef => - forbidden contains tp.symbol - case _ => - false - } + def toAvoid(tp: Type): Boolean = + // TODO: measure the cost of using `existsPart`, and if necessary replace it + // by a `TypeAccumulator` where we have set `stopAtStatic = true`. + tp existsPart { + case tp: NamedType => + forbidden contains tp.symbol + case _ => + false + } def apply(tp: Type): Type = tp match { case tp: TermRef if toAvoid(tp) && variance > 0 => apply(tp.info.widenExpr) - case tp: TypeRef if (forbidden contains tp.symbol) || toAvoid(tp.prefix) => + case tp: TypeRef if toAvoid(tp) => tp.info match { case TypeAlias(ref) => apply(ref) @@ -92,7 +89,7 @@ trait TypeAssigner { } case tp: RefinedType => val tp1 @ RefinedType(parent1, _) = mapOver(tp) - if (tp1.refinedInfo.existsPart(toAvoid) && variance > 0) { + if (toAvoid(tp1.refinedInfo) && variance > 0) { typr.println(s"dropping refinement from $tp1") parent1 } diff --git a/tests/pos/escapingRefs.scala b/tests/pos/escapingRefs.scala index a7960bee4..c18720764 100644 --- a/tests/pos/escapingRefs.scala +++ b/tests/pos/escapingRefs.scala @@ -1,5 +1,7 @@ class Outer { - class Inner + class Inner { + class Inner2 + } } object Test { @@ -8,5 +10,11 @@ object Test { val o = new Outer new o.Inner } + + val b: Outer#Inner#Inner2 = { + val o = new Outer + val i = new o.Inner + new i.Inner2 + } } } |