aboutsummaryrefslogtreecommitdiff
path: root/src/dotty
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2015-09-08 10:39:44 +0200
committerDmitry Petrashko <dmitry.petrashko@gmail.com>2015-09-14 13:36:14 +0200
commit8a538ce728ed61c42ddb66f196dd217b8451bf9e (patch)
tree2241b2c4fe94918f38e23ac30d6ed5b64e479651 /src/dotty
parent8fc5835ca13ef5ab47b29d5240d5e8d79a870b7c (diff)
downloaddotty-8a538ce728ed61c42ddb66f196dd217b8451bf9e.tar.gz
dotty-8a538ce728ed61c42ddb66f196dd217b8451bf9e.tar.bz2
dotty-8a538ce728ed61c42ddb66f196dd217b8451bf9e.zip
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.
Diffstat (limited to 'src/dotty')
-rw-r--r--src/dotty/tools/dotc/Compiler.scala1
-rw-r--r--src/dotty/tools/dotc/transform/PostTyper.scala41
2 files changed, 38 insertions, 4 deletions
diff --git a/src/dotty/tools/dotc/Compiler.scala b/src/dotty/tools/dotc/Compiler.scala
index e4b328a82..c537d8885 100644
--- a/src/dotty/tools/dotc/Compiler.scala
+++ b/src/dotty/tools/dotc/Compiler.scala
@@ -56,7 +56,6 @@ class Compiler {
List(new VCInlineMethods,
new SeqLiterals,
new InterceptedMethods,
- new Literalize,
new Getters,
new ClassTags,
new ElimByName,
diff --git a/src/dotty/tools/dotc/transform/PostTyper.scala b/src/dotty/tools/dotc/transform/PostTyper.scala
index a0670bca0..7a25a9870 100644
--- a/src/dotty/tools/dotc/transform/PostTyper.scala
+++ b/src/dotty/tools/dotc/transform/PostTyper.scala
@@ -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
@@ -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)