Skip to content

Commit

Permalink
Move literalize functionality to PostTyper
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
odersky authored and DarkDimius committed Sep 14, 2015
1 parent 8fc5835 commit 8a538ce
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 4 deletions.
1 change: 0 additions & 1 deletion src/dotty/tools/dotc/Compiler.scala
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,6 @@ class Compiler {
List(new VCInlineMethods,
new SeqLiterals,
new InterceptedMethods,
new Literalize,
new Getters,
new ClassTags,
new ElimByName,
Expand Down
41 changes: 38 additions & 3 deletions src/dotty/tools/dotc/transform/PostTyper.scala
Original file line number Diff line number Diff line change
Expand Up @@ -68,8 +68,43 @@ class PostTyper extends MacroTransform with IdentityDenotTransformer { thisTran
// TODO fill in
}

private def normalizeTypeTree(tree: Tree)(implicit ctx: Context) = {
def norm(tree: Tree) = if (tree.isType) TypeTree(tree.tpe).withPos(tree.pos) else tree
/** Check bounds of AppliedTypeTrees.
* Replace type trees with TypeTree nodes.
* Replace constant expressions with Literal nodes.
* Note: Demanding idempotency instead of purityin literalize is strictly speaking too loose.
* Example
*
* object O { final val x = 42; println("43") }
* O.x
*
* Strictly speaking we can't replace `O.x` with `42`. But this would make
* most expressions non-constant. Maybe we can change the spec to accept this
* kind of eliding behavior. Or else enforce true purity in the compiler.
* The choice will be affected by what we will do with `inline` and with
* Singleton type bounds (see SIP 23). Presumably
*
* object O1 { val x: Singleton = 42; println("43") }
* object O2 { inline val x = 42; println("43") }
*
* should behave differently.
*
* O1.x should have the same effect as { println("43"; 42 }
*
* whereas
*
* O2.x = 42
*
* Revisit this issue once we have implemented `inline`. Then we can demand
* purity of the prefix unless the selection goes to an inline val.
*/
private def normalizeTree(tree: Tree)(implicit ctx: Context): Tree = {
def literalize(tp: Type): Tree = tp.widenTermRefExpr match {
case ConstantType(value) if isIdempotentExpr(tree) => Literal(value)
case _ => tree
}
def norm(tree: Tree) =
if (tree.isType) TypeTree(tree.tpe).withPos(tree.pos)
else literalize(tree.tpe)
tree match {
case tree: TypeTree =>
tree
Expand Down Expand Up @@ -115,7 +150,7 @@ class PostTyper extends MacroTransform with IdentityDenotTransformer { thisTran
}

override def transform(tree: Tree)(implicit ctx: Context): Tree =
try normalizeTypeTree(tree) match {
try normalizeTree(tree) match {
case tree: Ident =>
tree.tpe match {
case tpe: ThisType => This(tpe.cls).withPos(tree.pos)
Expand Down

0 comments on commit 8a538ce

Please sign in to comment.