From 983ce8da3ce321bed7f8100c00b4aa709528208e Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Mon, 17 Apr 2017 17:22:48 +0200 Subject: Pruning branch of constant type condition. As done in inliner. --- .../src/dotty/tools/dotc/transform/FirstTransform.scala | 17 ++++++++++++----- tests/run/if-with-constant-cond.check | 4 ++++ tests/run/if-with-constant-cond.scala | 9 +++++++++ 3 files changed, 25 insertions(+), 5 deletions(-) create mode 100644 tests/run/if-with-constant-cond.check create mode 100644 tests/run/if-with-constant-cond.scala diff --git a/compiler/src/dotty/tools/dotc/transform/FirstTransform.scala b/compiler/src/dotty/tools/dotc/transform/FirstTransform.scala index a3cf71ef2..767ee0901 100644 --- a/compiler/src/dotty/tools/dotc/transform/FirstTransform.scala +++ b/compiler/src/dotty/tools/dotc/transform/FirstTransform.scala @@ -9,7 +9,7 @@ import dotty.tools.dotc.transform.TreeTransforms._ import ast.Trees._ import Flags._ import Types._ -import Constants.Constant +import Constants._ import Contexts.Context import Symbols._ import SymDenotations._ @@ -34,6 +34,8 @@ import StdNames._ * - drops branches of ifs using the rules * if (true) A else B --> A * if (false) A else B --> B + * if (C: true) A else B --> C; A + * if (C: false) A else B --> C; B */ class FirstTransform extends MiniPhaseTransform with InfoTransformer with AnnotationTransformer { thisTransformer => import ast.tpd._ @@ -190,11 +192,16 @@ class FirstTransform extends MiniPhaseTransform with InfoTransformer with Annota override def transformBlock(tree: Block)(implicit ctx: Context, info: TransformerInfo) = constToLiteral(tree) - override def transformIf(tree: If)(implicit ctx: Context, info: TransformerInfo) = - tree.cond match { - case Literal(Constant(c: Boolean)) => if (c) tree.thenp else tree.elsep - case _ => tree + override def transformIf(tree: If)(implicit ctx: Context, info: TransformerInfo) = { + tree.cond.tpe.widenTermRefExpr match { + case ConstantType(Constant(condVal: Boolean)) => + val selected = if (condVal) tree.thenp else tree.elsep + if (isPureExpr(tree.cond)) selected + else Block(tree.cond :: Nil, selected) + case _ => + tree } + } // invariants: all modules have companion objects // all types are TypeTrees diff --git a/tests/run/if-with-constant-cond.check b/tests/run/if-with-constant-cond.check new file mode 100644 index 000000000..2e31d4f23 --- /dev/null +++ b/tests/run/if-with-constant-cond.check @@ -0,0 +1,4 @@ +cond1 +then1 +cond2 +else2 diff --git a/tests/run/if-with-constant-cond.scala b/tests/run/if-with-constant-cond.scala new file mode 100644 index 000000000..db5959c84 --- /dev/null +++ b/tests/run/if-with-constant-cond.scala @@ -0,0 +1,9 @@ + +object Test { + + def main(args: Array[String]): Unit = { + if ({ println("cond1"); true }: true) println("then1") else println("else1") + if ({ println("cond2"); false }: false) println("then2") else println("else2") + } + +} \ No newline at end of file -- cgit v1.2.3