@@ -21,18 +21,19 @@ import Simplify.desugarIdent
2121 * out (nested) if with equivalent branches wrt to isSimilar. For example:
2222 * - if (b) exp else exp → b; exp
2323 * - if (b1) e1 else if (b2) e1 else e2 → if (b1 || b2) e1 else e2
24+ * - if(!b) e1 else e2 → if(b) e2 else e1
2425 *
2526 * - Constant propagation over pattern matching.
2627 *
27- * @author DarkDimius, OlivierBlanvillain
28+ * @author DarkDimius, OlivierBlanvillain, gan74
2829 */
2930 class ConstantFold (val simplifyPhase : Simplify ) extends Optimisation {
3031 import ast .tpd ._
3132
3233 def visitor (implicit ctx : Context ) = NoVisitor
3334 def clear (): Unit = ()
3435
35- def transformer (implicit ctx : Context ): Tree => Tree = { x => preEval(x) match {
36+ def transformer (implicit ctx : Context ): Tree => Tree = { x => x match {
3637 // TODO: include handling of isInstanceOf similar to one in IsInstanceOfEvaluator
3738 // TODO: include methods such as Int.int2double(see ./tests/pos/harmonize.scala)
3839 case If (cond1, thenp, elsep) if isSimilar(thenp, elsep) =>
@@ -76,9 +77,6 @@ import Simplify.desugarIdent
7677 // cond.select(defn.Boolean_&&).appliedTo(elsep)
7778 // the other case ins't handled intentionally. See previous case for explanation
7879
79- case If (t @ Select (recv, _), thenp, elsep) if t.symbol eq defn.Boolean_! =>
80- If (recv, elsep, thenp)
81-
8280 case If (t @ Apply (Select (recv, _), Nil ), thenp, elsep) if t.symbol eq defn.Boolean_! =>
8381 If (recv, elsep, thenp)
8482
@@ -141,7 +139,16 @@ import Simplify.desugarIdent
141139 // Block(List(lhs),
142140 // ref(defn.throwMethod).appliedTo(New(defn.ArithmeticExceptionClass.typeRef, defn.ArithmeticExceptionClass_stringConstructor, Literal(Constant("/ by zero")) :: Nil)))
143141
144- case _ => t
142+ case _ =>
143+ val lhType = lhs.tpe.widenTermRefExpr
144+ val rhType = rhs.tpe.widenTermRefExpr
145+ (lhType, rhType) match {
146+ case (ConstantType (_), ConstantType (_)) =>
147+ val s = ConstFold .apply(t)
148+ if ((s ne null ) && s.tpe.isInstanceOf [ConstantType ]) Literal (s.tpe.asInstanceOf [ConstantType ].value)
149+ else t
150+ case _ => t
151+ }
145152 }
146153
147154 // This case can only be triggered when running Simplify before pattern matching:
@@ -157,26 +164,11 @@ import Simplify.desugarIdent
157164
158165 case t : Literal => t
159166 case t : CaseDef => t
160- case t if ! isPureExpr(t) => t
161- case t =>
162- val s = ConstFold .apply(t)
163- if ((s ne null ) && s.tpe.isInstanceOf [ConstantType ]) {
164- val constant = s.tpe.asInstanceOf [ConstantType ].value
165- Literal (constant)
166- } else t
167+ case t => t
167168 }
168169 }
169170
170- def preEval (t : Tree )(implicit ctx : Context ) = {
171- if (t.isInstanceOf [Literal ] || t.isInstanceOf [CaseDef ] || ! isPureExpr(t)) t
172- else {
173- val s = ConstFold .apply(t)
174- if ((s ne null ) && s.tpe.isInstanceOf [ConstantType ]) {
175- val constant = s.tpe.asInstanceOf [ConstantType ].value
176- Literal (constant)
177- } else t
178- }
179- }
171+
180172
181173 def isSimilar (t1 : Tree , t2 : Tree )(implicit ctx : Context ): Boolean = t1 match {
182174 case t1 : Apply =>
0 commit comments