Skip to content

Add/elim static this #624

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 8 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions scripts/common
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ update() {
git fetch --tags "https://github.com/$1/$2.git"
(git fetch "https://github.com/$1/$2.git" $4 && git checkout -fq FETCH_HEAD) #|| git checkout -fq $4 # || fallback is for local testing on tag
git reset --hard
cd -
}

export LC_ALL=en_US.UTF-8
Expand Down
1 change: 1 addition & 0 deletions src/dotty/tools/dotc/Compiler.scala
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ class Compiler {
new Constructors,
new FunctionalInterfaces),
List(new LambdaLift, // in this mini-phase block scopes are incorrect. No phases that rely on scopes should be here
new ElimStaticThis,
new Flatten,
new RestoreScopes),
List(/*new PrivateToStatic,*/
Expand Down
2 changes: 1 addition & 1 deletion src/dotty/tools/dotc/ast/tpd.scala
Original file line number Diff line number Diff line change
Expand Up @@ -418,7 +418,7 @@ object tpd extends Trees.Instance[Type] with TypedTreeInfo {
Thicket(valdef, clsdef)
}

def initValue(tpe: Types.Type)(implicit ctx: Context) = {
def defaultValue(tpe: Types.Type)(implicit ctx: Context) = {
val tpw = tpe.widen

if (tpw isRef defn.IntClass) Literal(Constant(0))
Expand Down
24 changes: 24 additions & 0 deletions src/dotty/tools/dotc/transform/ElimStaticThis.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package dotty.tools.dotc
package transform

import core._
import Contexts.Context
import Flags._
import dotty.tools.dotc.core.StdNames._
import dotty.tools.dotc.core.SymDenotations.SymDenotation
import TreeTransforms.{MiniPhaseTransform, TransformerInfo}

/** Replace This references to module classes in static methods by global identifiers to the
* corresponding modules.
*/
class ElimStaticThis extends MiniPhaseTransform {
import ast.tpd._
def phaseName: String = "elimStaticThis"

override def transformThis(tree: This)(implicit ctx: Context, info: TransformerInfo): Tree =
if (!tree.symbol.is(Package) && ctx.owner.enclosingMethod.is(JavaStatic)) {
assert(tree.symbol.is(ModuleClass))
ref(tree.symbol.sourceModule)
}
else tree
}
48 changes: 18 additions & 30 deletions src/dotty/tools/dotc/transform/ElimWildcardIdents.scala
Original file line number Diff line number Diff line change
@@ -1,26 +1,14 @@
package dotty.tools.dotc.transform
package dotty.tools.dotc
package transform

import dotty.tools.dotc.transform.TreeTransforms.{TransformerInfo, TreeTransform, TreeTransformer, MiniPhaseTransform}
import dotty.tools.dotc.ast.{untpd, tpd}
import dotty.tools.dotc.core.Contexts.Context
import scala.collection.mutable.ListBuffer
import dotty.tools.dotc.core.{Scopes, Flags}
import dotty.tools.dotc.core.Symbols.NoSymbol
import scala.annotation.tailrec
import dotty.tools.dotc.core._
import TreeTransforms.{MiniPhaseTransform, TransformerInfo}
import ast.tpd
import ast.Trees._
import core._
import Contexts.Context
import Symbols._
import scala.Some
import dotty.tools.dotc.transform.TreeTransforms.{NXTransformations, TransformerInfo, TreeTransform, TreeTransformer}
import dotty.tools.dotc.core.Contexts.Context
import scala.collection.mutable
import dotty.tools.dotc.core.Names.Name
import NameOps._
import Types._
import scala.collection.SortedSet
import Decorators._
import StdNames._
import dotty.tools.dotc.util.Positions.Position
import dotty.tools.dotc.config.JavaPlatform

/**
* Replace Ident("_") in tree with default values of corresponding type:
Expand All @@ -29,21 +17,21 @@ import dotty.tools.dotc.config.JavaPlatform
* classes: `null`
*/
class ElimWildcardIdents extends MiniPhaseTransform {
import tpd._
import ast.tpd._
def phaseName: String = "elimWildcardIdents"


override def transformDefDef(tree: tpd.DefDef)(implicit ctx: Context, info: TransformerInfo): tpd.Tree = {
def stripBlocks(arg: Tree): Tree = arg match {
case b: Block if b.stats.isEmpty => stripBlocks(b.expr)
case _ => arg
}
val b = stripBlocks(tree.rhs)
b match {
case x: Ident if (x.name == nme.WILDCARD && x.symbol.isClass) =>
tpd.DefDef(tree.symbol.asTerm, tpd.initValue(x.tpe))
def wildcardToDefaultValue(tree: Tree)(implicit ctx: Context) = {
def recur(x: Tree): Tree = x match {
case x: Ident if x.name == nme.WILDCARD && x.symbol.isClass => defaultValue(tree.tpe)
case Block(Nil, y) => recur(y)
case _ => tree
}
recur(tree)
}

override def transformValDef(tree: tpd.ValDef)(implicit ctx: Context, info: TransformerInfo): tpd.Tree =
cpy.ValDef(tree)(rhs = wildcardToDefaultValue(tree.rhs))

override def transformDefDef(tree: tpd.DefDef)(implicit ctx: Context, info: TransformerInfo): tpd.Tree =
cpy.DefDef(tree)(rhs = wildcardToDefaultValue(tree.rhs))
}
2 changes: 1 addition & 1 deletion src/dotty/tools/dotc/transform/LambdaLift.scala
Original file line number Diff line number Diff line change
Expand Up @@ -292,7 +292,7 @@ class LambdaLift extends MiniPhase with IdentityDenotTransformer { thisTransform
val encClass = local.enclosingClass
val topClass = local.topLevelClass
// member of a static object
if (encClass.isStatic && encClass.isContainedIn(topClass)) {
if (encClass.isStatic && encClass.isProperlyContainedIn(topClass)) {
// though the second condition seems weird, it's not true for symbols which are defined in some
// weird combinations of super calls.
(encClass, EmptyFlags)
Expand Down
6 changes: 3 additions & 3 deletions src/dotty/tools/dotc/transform/LazyVals.scala
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,7 @@ class LazyVals extends MiniPhaseTransform with IdentityDenotTransformer {
tpe, coord = x.symbol.coord
).entered

val containerTree = ValDef(containerSymbol, initValue(tpe))
val containerTree = ValDef(containerSymbol, defaultValue(tpe))
if (x.tpe.isNotNull && tpe <:< defn.ObjectType) { // can use 'null' value instead of flag
val slowPath = DefDef(x.symbol.asTerm, mkDefNonThreadSafeNonNullable(containerSymbol, x.rhs))
Thicket(List(containerTree, slowPath))
Expand Down Expand Up @@ -234,7 +234,7 @@ class LazyVals extends MiniPhaseTransform with IdentityDenotTransformer {
val thiz = This(claz)(ctx.fresh.setOwner(claz))

val resultSymbol = ctx.newSymbol(methodSymbol, lazyNme.result, containerFlags, tp)
val resultDef = ValDef(resultSymbol, initValue(tp))
val resultDef = ValDef(resultSymbol, defaultValue(tp))

val retrySymbol = ctx.newSymbol(methodSymbol, lazyNme.retry, containerFlags, defn.BooleanType)
val retryDef = ValDef(retrySymbol, Literal(Constants.Constant(true)))
Expand Down Expand Up @@ -332,7 +332,7 @@ class LazyVals extends MiniPhaseTransform with IdentityDenotTransformer {

val containerName = ctx.freshName(x.name ++ StdNames.nme.LAZY_LOCAL).toTermName
val containerSymbol = ctx.newSymbol(claz, containerName, (x.mods &~ containerFlagsMask | containerFlags).flags, tpe, coord = x.symbol.coord).entered
val containerTree = ValDef(containerSymbol, initValue(tpe))
val containerTree = ValDef(containerSymbol, defaultValue(tpe))

val offset = ref(companion).ensureApplied.select(offsetSymbol)
val getFlag = Select(ref(helperModule), lazyNme.RLazyVals.get)
Expand Down
1 change: 0 additions & 1 deletion src/dotty/tools/dotc/transform/TraitConstructors.scala
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ class TraitConstructors extends MiniPhaseTransform with SymTransformer {
import dotty.tools.dotc.ast.tpd._
def phaseName: String = "traitConstructors"


override def treeTransformPhase: Phase = this.phase

def transformSym(sym: SymDenotation)(implicit ctx: Context): SymDenotation = {
Expand Down
14 changes: 13 additions & 1 deletion src/dotty/tools/dotc/typer/Typer.scala
Original file line number Diff line number Diff line change
Expand Up @@ -1337,10 +1337,22 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
}
}

/** Adapt an expression of constant type to a different constant type `tpe`. */
def adaptConstant(tree: Tree, tpe: ConstantType): Tree = {
def lit = Literal(tpe.value).withPos(tree.pos)
tree match {
case Literal(c) => lit
case tree @ Block(stats, expr) => tpd.cpy.Block(tree)(stats, adaptConstant(expr, tpe))
case tree =>
if (isIdempotentExpr(tree)) lit // See discussion in phase Literalize why we demand isIdempotentExpr
else Block(tree :: Nil, lit)
}
}

def adaptToSubType(wtp: Type): Tree = {
// try converting a constant to the target type
val folded = ConstFold(tree, pt)
if (folded ne tree) return folded
if (folded ne tree) return adaptConstant(folded, folded.tpe.asInstanceOf[ConstantType])
// drop type if prototype is Unit
if (pt isRef defn.UnitClass)
return tpd.Block(tree :: Nil, Literal(Constant(())))
Expand Down
2 changes: 1 addition & 1 deletion test/dotc/tests.scala
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ class tests extends CompilerTest {
@Test def neg_escapingRefs = compileFile(negDir, "escapingRefs", xerrors = 2)
@Test def neg_instantiateAbstract = compileFile(negDir, "instantiateAbstract", xerrors = 8)
@Test def neg_selfInheritance = compileFile(negDir, "selfInheritance", xerrors = 5)


@Test def run_all = runFiles(runDir)

Expand Down
File renamed without changes.
File renamed without changes.
13 changes: 8 additions & 5 deletions tests/run/t5375.scala
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
object Test extends dotty.runtime.LegacyApp {
object Test {
val foos = (1 to 1000).toSeq
try
foos.par.map(i => if (i % 37 == 0) sys.error("i div 37") else i)
catch {
case ex: RuntimeException => println("Runtime exception")

def main(args: Array[String]): Unit = {
try
foos.par.map(i => if (i % 37 == 0) sys.error("i div 37") else i)
catch {
case ex: RuntimeException => println("Runtime exception")
}
}
}
10 changes: 6 additions & 4 deletions tests/run/t6052.scala
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@



object Test extends dotty.runtime.LegacyApp {
object Test {
def seqarr(i: Int) = Array[Int]() ++ (0 until i)
def pararr(i: Int) = seqarr(i).par

Expand All @@ -15,7 +15,9 @@ object Test extends dotty.runtime.LegacyApp {
assert(gseq == gpar, (gseq, gpar))
}

for (i <- 0 until 20) check(i, _ > 0)
for (i <- 0 until 20) check(i, _ % 2)
for (i <- 0 until 20) check(i, _ % 4)
def main(args: Array[String]): Unit = {
for (i <- 0 until 20) check(i, _ > 0)
for (i <- 0 until 20) check(i, _ % 2)
for (i <- 0 until 20) check(i, _ % 4)
}
}
12 changes: 7 additions & 5 deletions tests/run/t6410.scala
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@



object Test extends dotty.runtime.LegacyApp {
val x = collection.parallel.mutable.ParArray.range(1,10) groupBy { _ % 2 } mapValues { _.size }
println(x)
val y = collection.parallel.immutable.ParVector.range(1,10) groupBy { _ % 2 } mapValues { _.size }
println(y)
object Test {
def main(args: Array[String]): Unit = {
val x = collection.parallel.mutable.ParArray.range(1,10) groupBy { _ % 2 } mapValues { _.size }
println(x)
val y = collection.parallel.immutable.ParVector.range(1,10) groupBy { _ % 2 } mapValues { _.size }
println(y)
}
}
12 changes: 7 additions & 5 deletions tests/run/t6467.scala
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,17 @@ import collection._



object Test extends dotty.runtime.LegacyApp {
object Test {

def compare(s1: String, s2: String): Unit = {
assert(s1 == s2, s1 + "\nvs.\n" + s2)
}

compare(List(1, 2, 3, 4).aggregate(new java.lang.StringBuffer)(_ append _, _ append _).toString, "1234")
compare(List(1, 2, 3, 4).par.aggregate(new java.lang.StringBuffer)(_ append _, _ append _).toString, "1234")
compare(Seq(0 until 100: _*).aggregate(new java.lang.StringBuffer)(_ append _, _ append _).toString, (0 until 100).mkString)
compare(Seq(0 until 100: _*).par.aggregate(new java.lang.StringBuffer)(_ append _, _ append _).toString, (0 until 100).mkString)
def main(args: Array[String]): Unit = {
compare(List(1, 2, 3, 4).aggregate(new java.lang.StringBuffer)(_ append _, _ append _).toString, "1234")
compare(List(1, 2, 3, 4).par.aggregate(new java.lang.StringBuffer)(_ append _, _ append _).toString, "1234")
compare(Seq(0 until 100: _*).aggregate(new java.lang.StringBuffer)(_ append _, _ append _).toString, (0 until 100).mkString)
compare(Seq(0 until 100: _*).par.aggregate(new java.lang.StringBuffer)(_ append _, _ append _).toString, (0 until 100).mkString)
}

}
10 changes: 6 additions & 4 deletions tests/run/t7498.scala
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,18 @@



object Test extends dotty.runtime.LegacyApp {
object Test {
import scala.collection.concurrent.TrieMap

class Collision(val idx: Int) {
override def hashCode = idx % 10
}

val tm = TrieMap[Collision, Unit]()
for (i <- 0 until 1000) tm(new Collision(i)) = ()
def main(args: Array[String]): Unit = {
val tm = TrieMap[Collision, Unit]()
for (i <- 0 until 1000) tm(new Collision(i)) = ()

tm.par.foreach(kv => ())
tm.par.foreach(kv => ())
}
}