aboutsummaryrefslogtreecommitdiff
path: root/src/dotty/tools/dotc/transform/CheckStatic.scala
diff options
context:
space:
mode:
authorDmitry Petrashko <dmitry.petrashko@gmail.com>2016-03-08 14:12:48 +0100
committerDmitry Petrashko <dmitry.petrashko@gmail.com>2016-03-08 14:12:48 +0100
commitead309423796f1a6ef59330112044b69ce719a58 (patch)
tree9f647b9dd725ab8c453a16649e447f78fe3636ca /src/dotty/tools/dotc/transform/CheckStatic.scala
parent51dfcb81cf9f1c6eb9fa6fbb7f77c81086af230f (diff)
downloaddotty-ead309423796f1a6ef59330112044b69ce719a58.tar.gz
dotty-ead309423796f1a6ef59330112044b69ce719a58.tar.bz2
dotty-ead309423796f1a6ef59330112044b69ce719a58.zip
CheckStatic: do not eliminate non-pure expressions.
Implemented by checking that tree is allowed to access the static member and all the members on the path to it. Needed as typer has a tendency to desugar calls into series of selections&calls to This.
Diffstat (limited to 'src/dotty/tools/dotc/transform/CheckStatic.scala')
-rw-r--r--src/dotty/tools/dotc/transform/CheckStatic.scala19
1 files changed, 15 insertions, 4 deletions
diff --git a/src/dotty/tools/dotc/transform/CheckStatic.scala b/src/dotty/tools/dotc/transform/CheckStatic.scala
index 264c20eb2..445e9f839 100644
--- a/src/dotty/tools/dotc/transform/CheckStatic.scala
+++ b/src/dotty/tools/dotc/transform/CheckStatic.scala
@@ -36,7 +36,7 @@ import TypeUtils._
class CheckStatic extends MiniPhaseTransform { thisTransformer =>
import ast.tpd._
- override def phaseName = "elimRepeated"
+ override def phaseName = "checkStatic"
def check(tree: tpd.DefTree)(implicit ctx: Context) = {
@@ -76,8 +76,19 @@ class CheckStatic extends MiniPhaseTransform { thisTransformer =>
}
override def transformSelect(tree: tpd.Select)(implicit ctx: Context, info: TransformerInfo): tpd.Tree = {
- if (tree.symbol.hasAnnotation(defn.ScalaStaticAnnot))
- ref(tree.symbol)
- else tree
+ if (tree.symbol.hasAnnotation(defn.ScalaStaticAnnot)) {
+ val symbolWhitelist = tree.symbol.ownersIterator.flatMap(x => if (x.is(Flags.Module)) List(x, x.companionModule) else List(x)).toSet
+ def isSafeQual(t: Tree): Boolean = { // follow the desugared paths created by typer
+ t match {
+ case t: This => true
+ case t: Select => isSafeQual(t.qualifier) && symbolWhitelist.contains(t.symbol)
+ case t: Ident => symbolWhitelist.contains(t.symbol)
+ case t: Block => t.stats.forall(tpd.isPureExpr) && isSafeQual(t.expr)
+ }
+ }
+ if (isSafeQual(tree.qualifier))
+ ref(tree.symbol)
+ else tree
+ } else tree
}
}