Skip to content

Commit af98163

Browse files
committed
Move literalize functionality to PostTyper
Now, PostTyper replaces constant expressions with literals. If we wait any longer then any tree rewriting of an application node would have to do constant folding again, which is a hassle. With the previous late Literalize phase, constant expressions consisting of operations and arguments lost their constantness in PostTyper.
1 parent 5f6294f commit af98163

File tree

2 files changed

+38
-4
lines changed

2 files changed

+38
-4
lines changed

src/dotty/tools/dotc/Compiler.scala

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,6 @@ class Compiler {
5656
List(new VCInlineMethods,
5757
new SeqLiterals,
5858
new InterceptedMethods,
59-
new Literalize,
6059
new Getters,
6160
new ClassTags,
6261
new ElimByName,

src/dotty/tools/dotc/transform/PostTyper.scala

Lines changed: 38 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -68,8 +68,43 @@ class PostTyper extends MacroTransform with IdentityDenotTransformer { thisTran
6868
// TODO fill in
6969
}
7070

71-
private def normalizeTypeTree(tree: Tree)(implicit ctx: Context) = {
72-
def norm(tree: Tree) = if (tree.isType) TypeTree(tree.tpe).withPos(tree.pos) else tree
71+
/** Check bounds of AppliedTypeTrees.
72+
* Replace type trees with TypeTree nodes.
73+
* Replace constant expressions with Literal nodes.
74+
* Note: Demanding idempotency instead of purityin literalize is strictly speaking too loose.
75+
* Example
76+
*
77+
* object O { final val x = 42; println("43") }
78+
* O.x
79+
*
80+
* Strictly speaking we can't replace `O.x` with `42`. But this would make
81+
* most expressions non-constant. Maybe we can change the spec to accept this
82+
* kind of eliding behavior. Or else enforce true purity in the compiler.
83+
* The choice will be affected by what we will do with `inline` and with
84+
* Singleton type bounds (see SIP 23). Presumably
85+
*
86+
* object O1 { val x: Singleton = 42; println("43") }
87+
* object O2 { inline val x = 42; println("43") }
88+
*
89+
* should behave differently.
90+
*
91+
* O1.x should have the same effect as { println("43"; 42 }
92+
*
93+
* whereas
94+
*
95+
* O2.x = 42
96+
*
97+
* Revisit this issue once we have implemented `inline`. Then we can demand
98+
* purity of the prefix unless the selection goes to an inline val.
99+
*/
100+
private def normalizeTree(tree: Tree)(implicit ctx: Context): Tree = {
101+
def literalize(tp: Type): Tree = tp.widenTermRefExpr match {
102+
case ConstantType(value) if isIdempotentExpr(tree) => Literal(value)
103+
case _ => tree
104+
}
105+
def norm(tree: Tree) =
106+
if (tree.isType) TypeTree(tree.tpe).withPos(tree.pos)
107+
else literalize(tree.tpe)
73108
tree match {
74109
case tree: TypeTree =>
75110
tree
@@ -115,7 +150,7 @@ class PostTyper extends MacroTransform with IdentityDenotTransformer { thisTran
115150
}
116151

117152
override def transform(tree: Tree)(implicit ctx: Context): Tree =
118-
try normalizeTypeTree(tree) match {
153+
try normalizeTree(tree) match {
119154
case tree: Ident =>
120155
tree.tpe match {
121156
case tpe: ThisType => This(tpe.cls).withPos(tree.pos)

0 commit comments

Comments
 (0)