diff --git a/src/dotty/tools/dotc/Compiler.scala b/src/dotty/tools/dotc/Compiler.scala index d447c3826a37..d1f12686046d 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 000000000000..504a66c2f26d --- /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 000000000000..abb46d3aaf91 --- /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 d329744ca037..9c60ef339d36 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