From 3a1c0f413ff4f2225f75bae531f7e213df727d45 Mon Sep 17 00:00:00 2001 From: Guillaume Raffin Date: Tue, 9 May 2023 17:55:08 +0200 Subject: [PATCH 1/2] Constant fold (almost) all the number conversion methods Co-authored-by: Eugene Flesselle Co-authored-by: Martin Kucera --- .../dotty/tools/dotc/typer/ConstFold.scala | 12 ++++++++- tests/pos/i13990.scala | 26 +++++++++++++++++++ 2 files changed, 37 insertions(+), 1 deletion(-) create mode 100644 tests/pos/i13990.scala diff --git a/compiler/src/dotty/tools/dotc/typer/ConstFold.scala b/compiler/src/dotty/tools/dotc/typer/ConstFold.scala index 81b1de67b707..b55c8c64e3b1 100644 --- a/compiler/src/dotty/tools/dotc/typer/ConstFold.scala +++ b/compiler/src/dotty/tools/dotc/typer/ConstFold.scala @@ -23,7 +23,11 @@ object ConstFold: nme.ADD, nme.SUB, nme.MUL, nme.DIV, nme.MOD) val foldedUnops = Set[Name]( - nme.UNARY_!, nme.UNARY_~, nme.UNARY_+, nme.UNARY_-) + nme.UNARY_!, nme.UNARY_~, nme.UNARY_+, nme.UNARY_-, + nme.toChar, nme.toInt, nme.toFloat, nme.toLong, nme.toDouble, + // toByte and toShort are NOT included because we cannot write + // the type of a constant byte or short + ) def Apply[T <: Apply](tree: T)(using Context): T = tree.fun match @@ -89,6 +93,12 @@ object ConstFold: case (nme.UNARY_- , FloatTag ) => Constant(-x.floatValue) case (nme.UNARY_- , DoubleTag ) => Constant(-x.doubleValue) + case (nme.toChar , _ ) if x.isNumeric => Constant(x.charValue) + case (nme.toInt , _ ) if x.isNumeric => Constant(x.intValue) + case (nme.toLong , _ ) if x.isNumeric => Constant(x.longValue) + case (nme.toFloat , _ ) if x.isNumeric => Constant(x.floatValue) + case (nme.toDouble, _ ) if x.isNumeric => Constant(x.doubleValue) + case _ => null } diff --git a/tests/pos/i13990.scala b/tests/pos/i13990.scala new file mode 100644 index 000000000000..80740e47bde0 --- /dev/null +++ b/tests/pos/i13990.scala @@ -0,0 +1,26 @@ + +object Test: + + inline val myInt = 1 << 6 + + // toLong + inline val char2Long: 99L = 'c'.toLong + inline val int2Long: 0L = 0.toLong + inline val long2Long: 0L = 0L.toLong + inline val int2LongPropagated: 64L = myInt.toLong + + // toInt + inline val char2Int: 99 = 'c'.toInt + inline val int2Int: 0 = 0.toInt + inline val long2Int: 0 = 0L.toInt + inline val long2IntWrapped: -2147483648 = 2147483648L.toInt + inline val int2IntPropagated: 64 = myInt.toInt + + // toChar + inline val char2Char: 'c' = 'c'.toChar + inline val int2Char: 'c' = 99.toChar + inline val long2Char: 'c' = 99L.toChar + inline val int2CharPropagated: '@' = myInt.toChar + + // chain everything + inline val wow: 1.0 = 1.toChar.toInt.toLong.toFloat.toDouble From d8832bf0118834bd9598b0dc1efa3caf796ddae1 Mon Sep 17 00:00:00 2001 From: Guillaume Raffin Date: Wed, 24 May 2023 14:20:06 +0200 Subject: [PATCH 2/2] Fix serialversionud test: toLong is now const-folded --- tests/neg/serialversionuid-not-const.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/neg/serialversionuid-not-const.scala b/tests/neg/serialversionuid-not-const.scala index 1b24112dbf70..88e87221d21f 100644 --- a/tests/neg/serialversionuid-not-const.scala +++ b/tests/neg/serialversionuid-not-const.scala @@ -1,4 +1,4 @@ -@SerialVersionUID(13l.toLong) class C1 extends Serializable // error +@SerialVersionUID(13l.toLong) class C1 extends Serializable // OK because toLong is constant-folded @SerialVersionUID(13l) class C2 extends Serializable // OK @SerialVersionUID(13.asInstanceOf[Long]) class C3 extends Serializable // error @SerialVersionUID(Test.bippy) class C4 extends Serializable // error