Skip to content

Commit ead3094

Browse files
committed
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.
1 parent 51dfcb8 commit ead3094

File tree

1 file changed

+15
-4
lines changed

1 file changed

+15
-4
lines changed

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

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ import TypeUtils._
3636
class CheckStatic extends MiniPhaseTransform { thisTransformer =>
3737
import ast.tpd._
3838

39-
override def phaseName = "elimRepeated"
39+
override def phaseName = "checkStatic"
4040

4141

4242
def check(tree: tpd.DefTree)(implicit ctx: Context) = {
@@ -76,8 +76,19 @@ class CheckStatic extends MiniPhaseTransform { thisTransformer =>
7676
}
7777

7878
override def transformSelect(tree: tpd.Select)(implicit ctx: Context, info: TransformerInfo): tpd.Tree = {
79-
if (tree.symbol.hasAnnotation(defn.ScalaStaticAnnot))
80-
ref(tree.symbol)
81-
else tree
79+
if (tree.symbol.hasAnnotation(defn.ScalaStaticAnnot)) {
80+
val symbolWhitelist = tree.symbol.ownersIterator.flatMap(x => if (x.is(Flags.Module)) List(x, x.companionModule) else List(x)).toSet
81+
def isSafeQual(t: Tree): Boolean = { // follow the desugared paths created by typer
82+
t match {
83+
case t: This => true
84+
case t: Select => isSafeQual(t.qualifier) && symbolWhitelist.contains(t.symbol)
85+
case t: Ident => symbolWhitelist.contains(t.symbol)
86+
case t: Block => t.stats.forall(tpd.isPureExpr) && isSafeQual(t.expr)
87+
}
88+
}
89+
if (isSafeQual(tree.qualifier))
90+
ref(tree.symbol)
91+
else tree
92+
} else tree
8293
}
8394
}

0 commit comments

Comments
 (0)