From b68f94fca39221aa228c6cd7e74af0a403b2ced8 Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Wed, 13 Jan 2021 16:39:43 +0100 Subject: [PATCH 1/2] Constant fold String.== --- compiler/src/dotty/tools/dotc/typer/ConstFold.scala | 7 ++++++- tests/pos/i10521.scala | 8 ++++++++ tests/pos/stringConstantFold.scala | 5 +++++ tests/pos/t5856b.scala | 3 +++ 4 files changed, 22 insertions(+), 1 deletion(-) create mode 100644 tests/pos/i10521.scala create mode 100644 tests/pos/stringConstantFold.scala create mode 100644 tests/pos/t5856b.scala diff --git a/compiler/src/dotty/tools/dotc/typer/ConstFold.scala b/compiler/src/dotty/tools/dotc/typer/ConstFold.scala index 958aba7eaf9b..0bf1e4a076ea 100644 --- a/compiler/src/dotty/tools/dotc/typer/ConstFold.scala +++ b/compiler/src/dotty/tools/dotc/typer/ConstFold.scala @@ -163,6 +163,11 @@ object ConstFold: case nme.MOD => Constant(x.doubleValue % y.doubleValue) case _ => null } + private def foldStringOp(op: Name, x: Constant, y: Constant): Constant = op match { + case nme.ADD => Constant(x.stringValue + y.stringValue) + case nme.EQ => Constant(x.stringValue == y.stringValue) + case _ => null + } private def foldBinop(op: Name, x: Constant, y: Constant): Constant = val optag = @@ -176,7 +181,7 @@ object ConstFold: case LongTag => foldLongOp(op, x, y) case FloatTag => foldFloatOp(op, x, y) case DoubleTag => foldDoubleOp(op, x, y) - case StringTag if op == nme.ADD => Constant(x.stringValue + y.stringValue) + case StringTag => foldStringOp(op, x, y) case _ => null catch case ex: ArithmeticException => null // the code will crash at runtime, // but that is better than the diff --git a/tests/pos/i10521.scala b/tests/pos/i10521.scala new file mode 100644 index 000000000000..dc01bd32a1e0 --- /dev/null +++ b/tests/pos/i10521.scala @@ -0,0 +1,8 @@ +transparent inline def default(inline name: String): Any = + inline if name == "Int" then 0 + else inline if name == "String" then "" + else ??? + + +def test = + default("Int") diff --git a/tests/pos/stringConstantFold.scala b/tests/pos/stringConstantFold.scala new file mode 100644 index 000000000000..000fed488897 --- /dev/null +++ b/tests/pos/stringConstantFold.scala @@ -0,0 +1,5 @@ +def test = + ("A" + "B": "AB") + + ("A" == "A": true) + ("A" == "B": false) diff --git a/tests/pos/t5856b.scala b/tests/pos/t5856b.scala new file mode 100644 index 000000000000..b266aa6fad6a --- /dev/null +++ b/tests/pos/t5856b.scala @@ -0,0 +1,3 @@ +class Test: + def test = f("a" == s"a") + inline def f(inline b: Boolean): Boolean = !b From 730127bda00a100be1d8f7a3b4f6a7252d66c8b4 Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Thu, 14 Jan 2021 10:25:37 +0100 Subject: [PATCH 2/2] Constant fold on StringInterpolatorOpt --- .../localopt/StringInterpolatorOpt.scala | 15 ++++++++++++++- tests/run-macros/tasty-extractors-1.check | 4 ++-- 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/compiler/src/dotty/tools/dotc/transform/localopt/StringInterpolatorOpt.scala b/compiler/src/dotty/tools/dotc/transform/localopt/StringInterpolatorOpt.scala index a1c1708302f2..8f4aa6af8783 100644 --- a/compiler/src/dotty/tools/dotc/transform/localopt/StringInterpolatorOpt.scala +++ b/compiler/src/dotty/tools/dotc/transform/localopt/StringInterpolatorOpt.scala @@ -11,6 +11,7 @@ import dotty.tools.dotc.core.NameKinds._ import dotty.tools.dotc.core.Symbols._ import dotty.tools.dotc.core.Types._ import dotty.tools.dotc.transform.MegaPhase.MiniPhase +import dotty.tools.dotc.typer.ConstFold /** * MiniPhase to transform s and raw string interpolators from using StringContext to string @@ -162,6 +163,18 @@ class StringInterpolatorOpt extends MiniPhase { } } else - tree + tree.tpe match + case _: ConstantType => tree + case _ => + ConstFold.Apply(tree).tpe match + case ConstantType(x) => Literal(x).withSpan(tree.span).ensureConforms(tree.tpe) + case _ => tree } + + override def transformSelect(tree: Select)(using Context): Tree = { + ConstFold.Select(tree).tpe match + case ConstantType(x) => Literal(x).withSpan(tree.span).ensureConforms(tree.tpe) + case _ => tree + } + } diff --git a/tests/run-macros/tasty-extractors-1.check b/tests/run-macros/tasty-extractors-1.check index 7d8d642dad85..3e8aeef7adf4 100644 --- a/tests/run-macros/tasty-extractors-1.check +++ b/tests/run-macros/tasty-extractors-1.check @@ -73,8 +73,8 @@ ConstantType(IntConstant(2)) Inlined(None, Nil, Try(Literal(IntConstant(3)), List(CaseDef(Ident("_"), None, Block(Nil, Literal(UnitConstant())))), Some(Literal(UnitConstant())))) OrType(ConstantType(IntConstant(3)), TypeRef(ThisType(TypeRef(NoPrefix(), "scala")), "Unit")) -Inlined(None, Nil, Apply(Select(Literal(StringConstant("a")), "=="), List(Literal(StringConstant("b"))))) -TypeRef(ThisType(TypeRef(NoPrefix(), "scala")), "Boolean") +Inlined(None, Nil, Literal(BooleanConstant(false))) +ConstantType(BooleanConstant(false)) Inlined(None, Nil, Apply(Select(New(TypeIdent("Object")), ""), Nil)) TypeRef(ThisType(TypeRef(NoPrefix(), "lang")), "Object")