From fac74a618ae4666490cd8c7fd3f9604d877562d9 Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Sat, 11 Mar 2017 20:56:02 +0100 Subject: 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. --- compiler/src/dotty/tools/dotc/typer/Typer.scala | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) (limited to 'compiler/src/dotty/tools/dotc/typer/Typer.scala') diff --git a/compiler/src/dotty/tools/dotc/typer/Typer.scala b/compiler/src/dotty/tools/dotc/typer/Typer.scala index ba14b7498..c43a8adcd 100644 --- a/compiler/src/dotty/tools/dotc/typer/Typer.scala +++ b/compiler/src/dotty/tools/dotc/typer/Typer.scala @@ -642,12 +642,18 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit } val leaks = escapingRefs(tree, localSyms) if (leaks.isEmpty) tree - else if (isFullyDefined(pt, ForceDegree.none)) ascribeType(tree, pt) else if (!forcedDefined) { fullyDefinedType(tree.tpe, "block", tree.pos) - val tree1 = ascribeType(tree, avoid(tree.tpe, localSyms)) - ensureNoLocalRefs(tree1, pt, localSyms, forcedDefined = true) - } else + val avoidingType = avoid(tree.tpe, localSyms) + if (isFullyDefined(pt, ForceDegree.none) && !(avoidingType <:< pt)) + ascribeType(tree, pt) + else { + val tree1 = ascribeType(tree, avoidingType) + ensureNoLocalRefs(tree1, pt, localSyms, forcedDefined = true) + } + } else if (isFullyDefined(pt, ForceDegree.none)) + ascribeType(tree, pt) + else errorTree(tree, em"local definition of ${leaks.head.name} escapes as part of expression's type ${tree.tpe}"/*; full type: ${result.tpe.toString}"*/) } -- cgit v1.2.3