Skip to content

Commit 594e8dd

Browse files
committed
Fix #1442: add new phase, SelectStatic
GenBCode has an implicit assumption that I wasn't aware of: GetStatic should not be emitted against a valid selector. If it is, GenBCode messes up the stack by not pop-ing the selector. Surprisingly, this transformation is perfumed in nsc by flatten.
1 parent 62348de commit 594e8dd

File tree

2 files changed

+38
-0
lines changed

2 files changed

+38
-0
lines changed

src/dotty/tools/dotc/Compiler.scala

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@ class Compiler {
9191
new Flatten, // Lift all inner classes to package scope
9292
new RestoreScopes), // Repair scopes rendered invalid by moving definitions in prior phases of the group
9393
List(new ExpandPrivate, // Widen private definitions accessed from nested classes
94+
new SelectStatic, // get rid of selects that would be compiled into GetStatic
9495
new CollectEntryPoints, // Find classes with main methods
9596
new CollectSuperCalls, // Find classes that are called with super
9697
new MoveStatics, // Move static methods to companion classes
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
package dotty.tools.dotc
2+
package transform
3+
4+
import dotty.tools.dotc.ast.tpd
5+
import dotty.tools.dotc.core.Contexts.Context
6+
import dotty.tools.dotc.core.DenotTransformers.IdentityDenotTransformer
7+
import dotty.tools.dotc.core.Flags._
8+
import dotty.tools.dotc.core.Symbols._
9+
import dotty.tools.dotc.core._
10+
import dotty.tools.dotc.transform.TreeTransforms._
11+
12+
/** Removes selects that would be compiled into GetStatic
13+
* otherwise backend needs to be aware that some qualifiers need to be dropped.
14+
* Similar transformation seems to be performed by flatten in nsc
15+
*
16+
* @author Dmytro Petrashko
17+
*/
18+
class SelectStatic extends MiniPhaseTransform with IdentityDenotTransformer { thisTransform =>
19+
import ast.tpd._
20+
21+
override def phaseName: String = "selectStatic"
22+
private val isPackage = FlagConjunction(PackageCreationFlags.bits)
23+
24+
override def transformSelect(tree: tpd.Select)(implicit ctx: Context, info: TransformerInfo): tpd.Tree = {
25+
val sym = tree.symbol
26+
if (!sym.is(isPackage) && !sym.owner.is(isPackage) &&
27+
(
28+
((sym is Flags.Module) && sym.owner.isStaticOwner) ||
29+
(sym is Flags.JavaStatic) ||
30+
(sym.owner is Flags.ImplClass) ||
31+
sym.hasAnnotation(ctx.definitions.ScalaStaticAnnot)
32+
)
33+
)
34+
Block(List(tree.qualifier), ref(sym))
35+
else tree
36+
}
37+
}

0 commit comments

Comments
 (0)