From 7bc7c9ba5e04b9a17ed7d548f3ea8caf7bd8c4a7 Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Fri, 29 May 2015 14:14:28 +0200 Subject: [PATCH 1/8] Fix compilation failure by refining adaptation of constants Constants that are adapted to a different supertype need to do this explicitly (not just by changing the type). Otherwise tree checkers will compute the original type and fail. This caused a test failure in pos/harmonize. The mystery is why this was not caught in the checkin tests. --- src/dotty/tools/dotc/typer/Typer.scala | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/src/dotty/tools/dotc/typer/Typer.scala b/src/dotty/tools/dotc/typer/Typer.scala index ea19dd1c9f9e..acf4f38459ee 100644 --- a/src/dotty/tools/dotc/typer/Typer.scala +++ b/src/dotty/tools/dotc/typer/Typer.scala @@ -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(()))) From 78aa68223cc0869d2b103805ccc85d6bdf54a4e7 Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Fri, 29 May 2015 15:46:05 +0200 Subject: [PATCH 2/8] Revert "Fix #580: use isContainedIn to support cases where the enclosing class is also the top-level class" This reverts commit 6898d2c296326779d373ef0e0b84e4451550120a. --- .../tools/dotc/transform/LambdaLift.scala | 2 +- tests/run/innerInObject.check | 2 -- tests/run/innerInObject.scala | 24 ------------------- 3 files changed, 1 insertion(+), 27 deletions(-) delete mode 100644 tests/run/innerInObject.check delete mode 100644 tests/run/innerInObject.scala diff --git a/src/dotty/tools/dotc/transform/LambdaLift.scala b/src/dotty/tools/dotc/transform/LambdaLift.scala index 0cbbb769f458..42c6e85af4d1 100644 --- a/src/dotty/tools/dotc/transform/LambdaLift.scala +++ b/src/dotty/tools/dotc/transform/LambdaLift.scala @@ -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) diff --git a/tests/run/innerInObject.check b/tests/run/innerInObject.check deleted file mode 100644 index 1191247b6d9a..000000000000 --- a/tests/run/innerInObject.check +++ /dev/null @@ -1,2 +0,0 @@ -1 -2 diff --git a/tests/run/innerInObject.scala b/tests/run/innerInObject.scala deleted file mode 100644 index 5a5ece416d99..000000000000 --- a/tests/run/innerInObject.scala +++ /dev/null @@ -1,24 +0,0 @@ -object Test { - def foo(x: Int) = { - println(x) - } - - def outer(x: Int) = { - def inner() = { - foo(x) - } - inner() - } - - def outer2(x: Int) = { - def inner2() = { - Test.foo(x) - } - inner2() - } - - def main(args: Array[String]): Unit = { - outer(1) - outer2(2) - } -} From d471211cf023a9aaf2c866fb0360cfed306d17d7 Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Fri, 29 May 2015 15:55:33 +0200 Subject: [PATCH 3/8] Move test that fails again to disabled. --- tests/disabled/run/innerObject.check | 2 ++ tests/disabled/run/innerObject.scala | 24 ++++++++++++++++++++++++ 2 files changed, 26 insertions(+) create mode 100644 tests/disabled/run/innerObject.check create mode 100644 tests/disabled/run/innerObject.scala diff --git a/tests/disabled/run/innerObject.check b/tests/disabled/run/innerObject.check new file mode 100644 index 000000000000..1191247b6d9a --- /dev/null +++ b/tests/disabled/run/innerObject.check @@ -0,0 +1,2 @@ +1 +2 diff --git a/tests/disabled/run/innerObject.scala b/tests/disabled/run/innerObject.scala new file mode 100644 index 000000000000..5a5ece416d99 --- /dev/null +++ b/tests/disabled/run/innerObject.scala @@ -0,0 +1,24 @@ +object Test { + def foo(x: Int) = { + println(x) + } + + def outer(x: Int) = { + def inner() = { + foo(x) + } + inner() + } + + def outer2(x: Int) = { + def inner2() = { + Test.foo(x) + } + inner2() + } + + def main(args: Array[String]): Unit = { + outer(1) + outer2(2) + } +} From 3350907bf1ec570a7a7f645c57f74a620cc49664 Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Fri, 29 May 2015 15:56:15 +0200 Subject: [PATCH 4/8] Stop running scala/scala tests instead of our junit tests. --- scripts/common | 1 + 1 file changed, 1 insertion(+) diff --git a/scripts/common b/scripts/common index 50b13f8d7c81..4924538f08b0 100755 --- a/scripts/common +++ b/scripts/common @@ -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 From c65504d92444ffb63b385aaa0900f08912033f74 Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Fri, 29 May 2015 17:21:58 +0200 Subject: [PATCH 5/8] Eliminate `_' from rhs of ValDefs Previously was only done for DefDefs. Caused backend failure. --- src/dotty/tools/dotc/ast/tpd.scala | 2 +- .../dotc/transform/ElimWildcardIdents.scala | 48 +++++++------------ src/dotty/tools/dotc/transform/LazyVals.scala | 6 +-- .../dotc/transform/TraitConstructors.scala | 1 - test/dotc/tests.scala | 2 +- 5 files changed, 23 insertions(+), 36 deletions(-) diff --git a/src/dotty/tools/dotc/ast/tpd.scala b/src/dotty/tools/dotc/ast/tpd.scala index cf5ba6850d66..a38a238c80e8 100644 --- a/src/dotty/tools/dotc/ast/tpd.scala +++ b/src/dotty/tools/dotc/ast/tpd.scala @@ -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)) diff --git a/src/dotty/tools/dotc/transform/ElimWildcardIdents.scala b/src/dotty/tools/dotc/transform/ElimWildcardIdents.scala index 5ef0dfe8468b..29194d2353c0 100644 --- a/src/dotty/tools/dotc/transform/ElimWildcardIdents.scala +++ b/src/dotty/tools/dotc/transform/ElimWildcardIdents.scala @@ -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: @@ -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)) } diff --git a/src/dotty/tools/dotc/transform/LazyVals.scala b/src/dotty/tools/dotc/transform/LazyVals.scala index 925646ca5e74..5b146a7856d5 100644 --- a/src/dotty/tools/dotc/transform/LazyVals.scala +++ b/src/dotty/tools/dotc/transform/LazyVals.scala @@ -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)) @@ -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))) @@ -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) diff --git a/src/dotty/tools/dotc/transform/TraitConstructors.scala b/src/dotty/tools/dotc/transform/TraitConstructors.scala index 99ae3e187f07..32c4b9da4e2f 100644 --- a/src/dotty/tools/dotc/transform/TraitConstructors.scala +++ b/src/dotty/tools/dotc/transform/TraitConstructors.scala @@ -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 = { diff --git a/test/dotc/tests.scala b/test/dotc/tests.scala index 42ce1136c75e..b017211a9eec 100644 --- a/test/dotc/tests.scala +++ b/test/dotc/tests.scala @@ -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) From 878b55a95b3567cd2d83753208ea3c43c9cb6434 Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Fri, 29 May 2015 17:55:03 +0200 Subject: [PATCH 6/8] Bring back disabled test. --- tests/{disabled => }/run/innerObject.check | 0 tests/{disabled => }/run/innerObject.scala | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename tests/{disabled => }/run/innerObject.check (100%) rename tests/{disabled => }/run/innerObject.scala (100%) diff --git a/tests/disabled/run/innerObject.check b/tests/run/innerObject.check similarity index 100% rename from tests/disabled/run/innerObject.check rename to tests/run/innerObject.check diff --git a/tests/disabled/run/innerObject.scala b/tests/run/innerObject.scala similarity index 100% rename from tests/disabled/run/innerObject.scala rename to tests/run/innerObject.scala From db11fc579f0bcfc9eaac94756538ddb0bad754df Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Fri, 29 May 2015 18:04:47 +0200 Subject: [PATCH 7/8] New phase ElimStaticThis --- src/dotty/tools/dotc/Compiler.scala | 1 + .../tools/dotc/transform/ElimStaticThis.scala | 24 +++++++++++++++++++ 2 files changed, 25 insertions(+) create mode 100644 src/dotty/tools/dotc/transform/ElimStaticThis.scala diff --git a/src/dotty/tools/dotc/Compiler.scala b/src/dotty/tools/dotc/Compiler.scala index 1569d360d1ae..d7ef441441a9 100644 --- a/src/dotty/tools/dotc/Compiler.scala +++ b/src/dotty/tools/dotc/Compiler.scala @@ -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,*/ diff --git a/src/dotty/tools/dotc/transform/ElimStaticThis.scala b/src/dotty/tools/dotc/transform/ElimStaticThis.scala new file mode 100644 index 000000000000..13a2ddacd0c6 --- /dev/null +++ b/src/dotty/tools/dotc/transform/ElimStaticThis.scala @@ -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 +} From fc1d8e62dc86f268cda14f3ec2b1fae961482807 Mon Sep 17 00:00:00 2001 From: Guillaume Martres Date: Sat, 30 May 2015 19:04:23 +0200 Subject: [PATCH 8/8] Avoid static initialization deadlock in run tests See https://github.com/lampepfl/dotty/pull/624#issuecomment-107064519 for a lengthy explanation. --- tests/run/t5375.scala | 13 ++++++++----- tests/run/t6052.scala | 10 ++++++---- tests/run/t6410.scala | 12 +++++++----- tests/run/t6467.scala | 12 +++++++----- tests/run/t7498.scala | 10 ++++++---- 5 files changed, 34 insertions(+), 23 deletions(-) diff --git a/tests/run/t5375.scala b/tests/run/t5375.scala index 8c2c06fde30a..256f5435e0b5 100644 --- a/tests/run/t5375.scala +++ b/tests/run/t5375.scala @@ -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") + } } } diff --git a/tests/run/t6052.scala b/tests/run/t6052.scala index e740f00e16d0..15bffc1eb946 100644 --- a/tests/run/t6052.scala +++ b/tests/run/t6052.scala @@ -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 @@ -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) + } } diff --git a/tests/run/t6410.scala b/tests/run/t6410.scala index 0855ffecdb2e..51aaad839e5a 100644 --- a/tests/run/t6410.scala +++ b/tests/run/t6410.scala @@ -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) + } } diff --git a/tests/run/t6467.scala b/tests/run/t6467.scala index e02fb166993e..048ef25e2403 100644 --- a/tests/run/t6467.scala +++ b/tests/run/t6467.scala @@ -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) + } } diff --git a/tests/run/t7498.scala b/tests/run/t7498.scala index cab598405766..a2555c6b11a2 100644 --- a/tests/run/t7498.scala +++ b/tests/run/t7498.scala @@ -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 => ()) + } }