@@ -10,10 +10,15 @@ import core.Flags._
10
10
import core .Decorators ._
11
11
import core .StdNames .nme
12
12
import ast .Trees ._
13
+ import dotty .tools .dotc .ast .tpd
14
+ import dotty .tools .dotc .core .Constants ._
13
15
14
16
/** This phase rewrites idempotent expressions with constant types to Literals.
15
17
* The constant types are eliminated by erasure, so we need to keep
16
18
* 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.
17
22
*/
18
23
class Literalize extends MiniPhaseTransform { thisTransform =>
19
24
import ast .tpd ._
@@ -62,4 +67,25 @@ class Literalize extends MiniPhaseTransform { thisTransform =>
62
67
63
68
override def transformTypeApply (tree : TypeApply )(implicit ctx : Context , info : TransformerInfo ): Tree =
64
69
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
+ }
65
91
}
0 commit comments