@@ -10,10 +10,15 @@ import core.Flags._
1010import core .Decorators ._
1111import core .StdNames .nme
1212import ast .Trees ._
13+ import dotty .tools .dotc .ast .tpd
14+ import dotty .tools .dotc .core .Constants ._
1315
1416/** This phase rewrites idempotent expressions with constant types to Literals.
1517 * The constant types are eliminated by erasure, so we need to keep
1618 * the info about constantness in the trees.
19+ *
20+ * The phase also makes sure that the constant of a literal is the same as the constant
21+ * in the type of the literal.
1722 */
1823class Literalize extends MiniPhaseTransform { thisTransform =>
1924 import ast .tpd ._
@@ -62,4 +67,25 @@ class Literalize extends MiniPhaseTransform { thisTransform =>
6267
6368 override def transformTypeApply (tree : TypeApply )(implicit ctx : Context , info : TransformerInfo ): Tree =
6469 literalize(tree)
70+
71+ override def transformLiteral (tree : Literal )(implicit ctx : Context , info : TransformerInfo ): Tree = tree.tpe match {
72+ case ConstantType (const) if tree.const.value != const.value || (tree.const.tag != const.tag) => Literal (const)
73+ case _ => tree
74+ }
75+
76+ /** Check that all literals have types match underlying constants
77+ */
78+ override def checkPostCondition (tree : Tree )(implicit ctx : Context ): Unit = {
79+ tree match {
80+ case Literal (c @ Constant (treeValue)) =>
81+ tree.tpe match {
82+ case ConstantType (c2 @ Constant (typeValue)) =>
83+ assert(treeValue == typeValue && c2.tag == c.tag,
84+ i " Type of Literal $tree is inconsistent with underlying constant " )
85+ case tpe =>
86+ assert(c.tpe =:= tpe, i " Type of Literal $tree is inconsistent with underlying constant type ${c.tpe}" )
87+ }
88+ case _ =>
89+ }
90+ }
6591}
0 commit comments