@@ -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 = {
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) =>
@@ -75,7 +76,7 @@ import Simplify.desugarIdent
7576 // isBool(ift.tpe) && !elsep.const.booleanValue =>
7677 // cond.select(defn.Boolean_&&).appliedTo(elsep)
7778 // the other case ins't handled intentionally. See previous case for explanation
78-
79+
7980 case If (t @ Select (recv, _), thenp, elsep) if t.symbol eq defn.Boolean_! =>
8081 If (recv, elsep, thenp)
8182
@@ -141,6 +142,15 @@ import Simplify.desugarIdent
141142 // Block(List(lhs),
142143 // ref(defn.throwMethod).appliedTo(New(defn.ArithmeticExceptionClass.typeRef, defn.ArithmeticExceptionClass_stringConstructor, Literal(Constant("/ by zero")) :: Nil)))
143144
145+ case (l : Literal , r : Literal ) =>
146+ (l.tpe.widenTermRefExpr, r.tpe.widenTermRefExpr) match {
147+ case (ConstantType (_), ConstantType (_)) =>
148+ val s = ConstFold .apply(t)
149+ if ((s ne null ) && s.tpe.isInstanceOf [ConstantType ]) Literal (s.tpe.asInstanceOf [ConstantType ].value)
150+ else t
151+ case _ => t
152+ }
153+
144154 case _ => t
145155 }
146156
@@ -157,26 +167,10 @@ import Simplify.desugarIdent
157167
158168 case t : Literal => t
159169 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- }
170+ case t => t
168171 }
169172
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- }
173+
180174
181175 def isSimilar (t1 : Tree , t2 : Tree )(implicit ctx : Context ): Boolean = t1 match {
182176 case t1 : Apply =>
0 commit comments