aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/dotty/tools/dotc/Compiler.scala1
-rw-r--r--src/dotty/tools/dotc/transform/SelectStatic.scala60
-rw-r--r--tests/pos/i1442.scala24
-rw-r--r--tests/run/t4859.check2
4 files changed, 86 insertions, 1 deletions
diff --git a/src/dotty/tools/dotc/Compiler.scala b/src/dotty/tools/dotc/Compiler.scala
index d447c3826..d1f126860 100644
--- a/src/dotty/tools/dotc/Compiler.scala
+++ b/src/dotty/tools/dotc/Compiler.scala
@@ -91,6 +91,7 @@ class Compiler {
new Flatten, // Lift all inner classes to package scope
new RestoreScopes), // Repair scopes rendered invalid by moving definitions in prior phases of the group
List(new ExpandPrivate, // Widen private definitions accessed from nested classes
+ new SelectStatic, // get rid of selects that would be compiled into GetStatic
new CollectEntryPoints, // Find classes with main methods
new CollectSuperCalls, // Find classes that are called with super
new MoveStatics, // Move static methods to companion classes
diff --git a/src/dotty/tools/dotc/transform/SelectStatic.scala b/src/dotty/tools/dotc/transform/SelectStatic.scala
new file mode 100644
index 000000000..504a66c2f
--- /dev/null
+++ b/src/dotty/tools/dotc/transform/SelectStatic.scala
@@ -0,0 +1,60 @@
+package dotty.tools.dotc
+package transform
+
+import dotty.tools.dotc.ast.Trees._
+import dotty.tools.dotc.ast.tpd
+import dotty.tools.dotc.core.Contexts.Context
+import dotty.tools.dotc.core.DenotTransformers.IdentityDenotTransformer
+import dotty.tools.dotc.core.Flags._
+import dotty.tools.dotc.core.Symbols._
+import dotty.tools.dotc.core._
+import dotty.tools.dotc.transform.TreeTransforms._
+
+/** Removes selects that would be compiled into GetStatic
+ * otherwise backend needs to be aware that some qualifiers need to be dropped.
+ * Similar transformation seems to be performed by flatten in nsc
+ * @author Dmytro Petrashko
+ */
+class SelectStatic extends MiniPhaseTransform with IdentityDenotTransformer { thisTransform =>
+ import ast.tpd._
+
+ override def phaseName: String = "selectStatic"
+ private val isPackage = FlagConjunction(PackageCreationFlags.bits)
+
+ override def transformSelect(tree: tpd.Select)(implicit ctx: Context, info: TransformerInfo): tpd.Tree = {
+ val sym = tree.symbol
+ val r1 =
+ if (!sym.is(isPackage) && !sym.maybeOwner.is(isPackage) &&
+ (
+ ((sym is Flags.Module) && sym.maybeOwner.isStaticOwner) ||
+ (sym is Flags.JavaStatic) ||
+ (sym.maybeOwner is Flags.ImplClass) ||
+ sym.hasAnnotation(ctx.definitions.ScalaStaticAnnot)
+ )
+ )
+ if (!tree.qualifier.symbol.is(JavaModule) && !tree.qualifier.isType)
+ Block(List(tree.qualifier), ref(sym))
+ else tree
+ else tree
+
+ normalize(r1)
+ }
+
+ private def normalize(t: Tree)(implicit ctx: Context) = t match {
+ case Select(Block(stats, qual), nm) =>
+ Block(stats, cpy.Select(t)(qual, nm))
+ case Apply(Block(stats, qual), nm) =>
+ Block(stats, Apply(qual, nm))
+ case TypeApply(Block(stats, qual), nm) =>
+ Block(stats, TypeApply(qual, nm))
+ case _ => t
+ }
+
+ override def transformApply(tree: tpd.Apply)(implicit ctx: Context, info: TransformerInfo): tpd.Tree = {
+ normalize(tree)
+ }
+
+ override def transformTypeApply(tree: tpd.TypeApply)(implicit ctx: Context, info: TransformerInfo): tpd.Tree = {
+ normalize(tree)
+ }
+}
diff --git a/tests/pos/i1442.scala b/tests/pos/i1442.scala
new file mode 100644
index 000000000..abb46d3aa
--- /dev/null
+++ b/tests/pos/i1442.scala
@@ -0,0 +1,24 @@
+object Test1442 {
+ final def sumMinimized[B](num: Numeric[B]): Int = {
+ var cse: scala.math.Numeric.type = null.asInstanceOf[scala.math.Numeric.type]
+ ({cse = scala.math.Numeric; num eq cse.IntIsIntegral} ||
+ (num eq cse.DoubleAsIfIntegral))
+ 2
+ }
+
+ final def sum[B](implicit num: Numeric[B]): B = {
+ // arithmetic series formula can be used for regular addition
+ var cse: scala.math.Numeric.type = null.asInstanceOf[scala.math.Numeric.type]
+ if ({cse = scala.math.Numeric; num eq cse.IntIsIntegral}||
+ (num eq cse.BigIntIsIntegral)||
+ (num eq cse.ShortIsIntegral)||
+ (num eq cse.ByteIsIntegral)||
+ (num eq cse.CharIsIntegral)||
+ (num eq cse.LongIsIntegral)||
+ (num eq cse.FloatAsIfIntegral)||
+ (num eq cse.BigDecimalIsFractional)||
+ (num eq cse.DoubleAsIfIntegral)) {
+ null.asInstanceOf[B]
+ } else null.asInstanceOf[B]
+ }
+}
diff --git a/tests/run/t4859.check b/tests/run/t4859.check
index d329744ca..9c60ef339 100644
--- a/tests/run/t4859.check
+++ b/tests/run/t4859.check
@@ -1,7 +1,7 @@
+Outer
Inner
Inner.i
About to reference Inner.i
-Outer
Inner.i
About to reference O.N
About to reference O.N