From ff7a67cf086ed1c0d005de10e83881f0385875a3 Mon Sep 17 00:00:00 2001 From: Dmitry Petrashko Date: Mon, 30 Mar 2015 21:38:36 +0200 Subject: [PATCH] Fix #444: be more conservative on when Block and If types should be recomputed. --- compiler/src/dotty/tools/dotc/ast/tpd.scala | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/compiler/src/dotty/tools/dotc/ast/tpd.scala b/compiler/src/dotty/tools/dotc/ast/tpd.scala index 5672feb468b4..77e655bbe098 100644 --- a/compiler/src/dotty/tools/dotc/ast/tpd.scala +++ b/compiler/src/dotty/tools/dotc/ast/tpd.scala @@ -572,7 +572,12 @@ object tpd extends Trees.Instance[Type] with TypedTreeInfo { override def Block(tree: Tree)(stats: List[Tree], expr: Tree)(implicit ctx: Context): Block = { val tree1 = untpdCpy.Block(tree)(stats, expr) tree match { - case tree: Block if expr.tpe eq tree.expr.tpe => tree1.withTypeUnchecked(tree.tpe) + case tree: Block if (expr.tpe eq tree.expr.tpe) && (expr.tpe eq tree.tpe) => + // the second guard is needed in case avoid somehow widened the type. + // if it did it could potentially need to rewiden it + // eg {val s = ...; s} + // changing type of s should change type of block, though type of expr is unchanged - TermRef(s) + tree1.withTypeUnchecked(tree.tpe) case _ => ta.assignType(tree1, stats, expr) } } @@ -580,7 +585,12 @@ object tpd extends Trees.Instance[Type] with TypedTreeInfo { override def If(tree: Tree)(cond: Tree, thenp: Tree, elsep: Tree)(implicit ctx: Context): If = { val tree1 = untpdCpy.If(tree)(cond, thenp, elsep) tree match { - case tree: If if (thenp.tpe eq tree.thenp.tpe) && (elsep.tpe eq tree.elsep.tpe) => tree1.withTypeUnchecked(tree.tpe) + case tree: If if (thenp.tpe eq tree.thenp.tpe) && (elsep.tpe eq tree.elsep.tpe) && + ((tree.tpe eq thenp.tpe) || (tree.tpe eq elsep.tpe)) => + // last guard is needed in case previous if had computed a widened ORType that needs to be recomputed + // eg {val a = ...; val b = ...; if(...) a else b} + // changing type of a or b should change type of if, though types of both trees remain unchanged + tree1.withTypeUnchecked(tree.tpe) case _ => ta.assignType(tree1, thenp, elsep) } }