Skip to content

Commit fac74a6

Browse files
committed
Fix #1569: Improve avoidance algorithm
The essential change is that we do not throw away more precise info of the avoided type if the expected type is fully defined.
1 parent b2d3b89 commit fac74a6

File tree

3 files changed

+16
-13
lines changed

3 files changed

+16
-13
lines changed

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

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -642,12 +642,18 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
642642
}
643643
val leaks = escapingRefs(tree, localSyms)
644644
if (leaks.isEmpty) tree
645-
else if (isFullyDefined(pt, ForceDegree.none)) ascribeType(tree, pt)
646645
else if (!forcedDefined) {
647646
fullyDefinedType(tree.tpe, "block", tree.pos)
648-
val tree1 = ascribeType(tree, avoid(tree.tpe, localSyms))
649-
ensureNoLocalRefs(tree1, pt, localSyms, forcedDefined = true)
650-
} else
647+
val avoidingType = avoid(tree.tpe, localSyms)
648+
if (isFullyDefined(pt, ForceDegree.none) && !(avoidingType <:< pt))
649+
ascribeType(tree, pt)
650+
else {
651+
val tree1 = ascribeType(tree, avoidingType)
652+
ensureNoLocalRefs(tree1, pt, localSyms, forcedDefined = true)
653+
}
654+
} else if (isFullyDefined(pt, ForceDegree.none))
655+
ascribeType(tree, pt)
656+
else
651657
errorTree(tree,
652658
em"local definition of ${leaks.head.name} escapes as part of expression's type ${tree.tpe}"/*; full type: ${result.tpe.toString}"*/)
653659
}

tests/neg/t1569-failedAvoid.scala

Lines changed: 0 additions & 9 deletions
This file was deleted.

tests/pos/t1569.scala

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
// See pos/t1569a.scala for related examples that work.
2+
object Bug {
3+
class C { type T }
4+
def foo(x: Int)(y: C)(z: y.T): Unit = {}
5+
foo(3)(new C { type T = String })("hello")
6+
}

0 commit comments

Comments
 (0)