From ead309423796f1a6ef59330112044b69ce719a58 Mon Sep 17 00:00:00 2001 From: Dmitry Petrashko Date: Tue, 8 Mar 2016 14:12:48 +0100 Subject: 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. --- src/dotty/tools/dotc/transform/CheckStatic.scala | 19 +++++++++++++++---- 1 file 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 } } -- cgit v1.2.3