From 693e71698532c6ee5a904427c968ff6a5b2ea07b Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Fri, 5 May 2017 16:35:55 +0200 Subject: [PATCH 1/8] Drop $$local whan mangling fields --- compiler/src/dotty/tools/dotc/core/NameKinds.scala | 4 +++- tests/run/paramForwarding.check | 12 ++++++------ tests/run/paramForwarding_separate.check | 2 +- tests/run/paramForwarding_together.check | 2 +- tests/run/paramForwarding_together_b.check | 2 +- tests/run/statics.scala | 8 ++++---- tests/run/variable-pattern-access.check | 4 ++-- 7 files changed, 18 insertions(+), 16 deletions(-) diff --git a/compiler/src/dotty/tools/dotc/core/NameKinds.scala b/compiler/src/dotty/tools/dotc/core/NameKinds.scala index 09a13e130f54..2915b7a8da9c 100644 --- a/compiler/src/dotty/tools/dotc/core/NameKinds.scala +++ b/compiler/src/dotty/tools/dotc/core/NameKinds.scala @@ -351,7 +351,9 @@ object NameKinds { val ProtectedSetterName = new PrefixNameKind(PROTECTEDSETTER, "protected$set") // dubious encoding, kept for Scala2 compatibility val AvoidClashName = new SuffixNameKind(AVOIDCLASH, "$_avoid_name_clash_$") val DirectMethodName = new SuffixNameKind(DIRECT, "$direct") { override def definesNewName = true } - val FieldName = new SuffixNameKind(FIELD, "$$local") + val FieldName = new SuffixNameKind(FIELD, "$$local") { + override def mkString(underlying: TermName, info: ThisInfo) = underlying.toString + } val ExtMethName = new SuffixNameKind(EXTMETH, "$extension") val ModuleVarName = new SuffixNameKind(OBJECTVAR, "$module") val ModuleClassName = new SuffixNameKind(OBJECTCLASS, "$", optInfoString = "ModuleClass") diff --git a/tests/run/paramForwarding.check b/tests/run/paramForwarding.check index e91447784f0d..1cadc5076a50 100644 --- a/tests/run/paramForwarding.check +++ b/tests/run/paramForwarding.check @@ -1,16 +1,16 @@ B: -private final int B.theValue$$local -private final int B.theValueInB$$local +private final int B.theValue +private final int B.theValueInB Bz: -private final int Bz.theValue$$local -private final int Bz.theValueInBz$$local +private final int Bz.theValue +private final int Bz.theValueInBz C: D: -private final int D.other$$local +private final int D.other NonVal: X: -private final int X.theValue$$local +private final int X.theValue Y: diff --git a/tests/run/paramForwarding_separate.check b/tests/run/paramForwarding_separate.check index 8df0c31008df..e1c4bc9a35f9 100644 --- a/tests/run/paramForwarding_separate.check +++ b/tests/run/paramForwarding_separate.check @@ -1,5 +1,5 @@ # Fields in A: -private final int A.member$$local +private final int A.member # Fields in SubA: # Fields in B: diff --git a/tests/run/paramForwarding_together.check b/tests/run/paramForwarding_together.check index 8df0c31008df..e1c4bc9a35f9 100644 --- a/tests/run/paramForwarding_together.check +++ b/tests/run/paramForwarding_together.check @@ -1,5 +1,5 @@ # Fields in A: -private final int A.member$$local +private final int A.member # Fields in SubA: # Fields in B: diff --git a/tests/run/paramForwarding_together_b.check b/tests/run/paramForwarding_together_b.check index 8df0c31008df..e1c4bc9a35f9 100644 --- a/tests/run/paramForwarding_together_b.check +++ b/tests/run/paramForwarding_together_b.check @@ -1,5 +1,5 @@ # Fields in A: -private final int A.member$$local +private final int A.member # Fields in SubA: # Fields in B: diff --git a/tests/run/statics.scala b/tests/run/statics.scala index 8425e7f77a3e..5d180074d4ad 100644 --- a/tests/run/statics.scala +++ b/tests/run/statics.scala @@ -2,18 +2,18 @@ import scala.annotation.static class Foo{ class Bar { - def qwa = + def qwa = Bar.field // 0: invokestatic #31 // Method Foo$Bar$.field:()I // 3: ireturn } object Bar { - @static + @static val field = 1 } } -object Foo{ +object Foo{ @static def method = 1 @@ -35,6 +35,6 @@ object Test { } class WithLazies{ - @volatile lazy val s = 1 + @volatile lazy val s = 1 // 98: getstatic #30 // Field WithLazies$.OFFSET$0:J } diff --git a/tests/run/variable-pattern-access.check b/tests/run/variable-pattern-access.check index 1039f6a25917..8ab43375fc97 100644 --- a/tests/run/variable-pattern-access.check +++ b/tests/run/variable-pattern-access.check @@ -1,6 +1,6 @@ # Fields of A: -private final int A.a$$local -private final int A.b$$local +private final int A.a +private final int A.b private final scala.Tuple2 A.$1$ # Methods of A: public int A.a() From a6efb02ba7daea0b0269c8447ef915f062e3be56 Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Fri, 5 May 2017 16:47:15 +0200 Subject: [PATCH 2/8] Make idempotency tests run last They take up time and should fail only rarely. --- compiler/test/dotty/tools/dotc/CompilationTests.scala | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/compiler/test/dotty/tools/dotc/CompilationTests.scala b/compiler/test/dotty/tools/dotc/CompilationTests.scala index 6ad8d3d6867f..5b788074de81 100644 --- a/compiler/test/dotty/tools/dotc/CompilationTests.scala +++ b/compiler/test/dotty/tools/dotc/CompilationTests.scala @@ -244,7 +244,8 @@ class CompilationTests extends ParallelTesting { }.map(_.checkCompile()).foreach(_.delete()) } - @Test def bytecodeIdempotency: Unit = { + /** Add a `z` so that hey run last. TODO: Only run them selectively? */ + @Test def zBytecodeIdempotency: Unit = { var failed = 0 var total = 0 val blacklisted = Set( From c6dafba7e5cb337095303b8a6da4139e17ef69af Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Sat, 6 May 2017 18:49:57 +0200 Subject: [PATCH 3/8] Adress reviewers comments --- .../src/dotty/tools/dotc/core/Names.scala | 2 +- .../tools/dotc/core/tasty/TastyFormat.scala | 30 +++++++++---------- .../dotty/tools/dotc/CompilationTests.scala | 2 +- 3 files changed, 17 insertions(+), 17 deletions(-) diff --git a/compiler/src/dotty/tools/dotc/core/Names.scala b/compiler/src/dotty/tools/dotc/core/Names.scala index bf14049dcdbc..9d6b03cf5afc 100644 --- a/compiler/src/dotty/tools/dotc/core/Names.scala +++ b/compiler/src/dotty/tools/dotc/core/Names.scala @@ -247,7 +247,7 @@ object Names { } @sharable // because it's just a cache for performance - private[Names] var myMangledString: String = null + private[this] var myMangledString: String = null @sharable // because it's just a cache for performance private[this] var myMangled: Name = null diff --git a/compiler/src/dotty/tools/dotc/core/tasty/TastyFormat.scala b/compiler/src/dotty/tools/dotc/core/tasty/TastyFormat.scala index 7ef92f038fab..9726315052c9 100644 --- a/compiler/src/dotty/tools/dotc/core/tasty/TastyFormat.scala +++ b/compiler/src/dotty/tools/dotc/core/tasty/TastyFormat.scala @@ -36,21 +36,21 @@ Macro-format: EXPANDEDPREFIX Length qualified_NameRef selector_NameRef TRAITSETTER Length qualified_NameRef selector_NameRef UNIQUE Length separator_NameRef uniqid_Nat underlying_NameRef? - DEFAULTGETTER Length underlying_NameRef index_Nat - VARIANT Length underlying_NameRef variance_Nat // 0: Contravariant, 1: Covariant - OUTERSELECT Length underlying_NameRef nhops_Nat // a reference to `nhops` selections, followed by `underlying` - - SUPERACCESSOR Length underlying_NameRef - PROTECTEDACCESSOR Length underlying_NameRef - PROTECTEDSETTER Length underlying_NameRef - INITIALIZER Length underlying_NameRef - SHADOWED Length underlying_NameRef - AVOIDCLASH Length underlying_NameRef - DIRECT Length underlying_NameRef - FIELD Length underlying_NameRef - EXTMETH Length underlying_NameRef - OBJECTVAR Length underlying_NameRef - OBJECTCLASS Length underlying_NameRef + DEFAULTGETTER Length underlying_NameRef index_Nat + VARIANT Length underlying_NameRef variance_Nat // 0: Contravariant, 1: Covariant + OUTERSELECT Length underlying_NameRef nhops_Nat // a reference to `nhops` selections, followed by `underlying` + + SUPERACCESSOR Length underlying_NameRef + PROTECTEDACCESSOR Length underlying_NameRef + PROTECTEDSETTER Length underlying_NameRef + INITIALIZER Length underlying_NameRef + SHADOWED Length underlying_NameRef + AVOIDCLASH Length underlying_NameRef + DIRECT Length underlying_NameRef + FIELD Length underlying_NameRef + EXTMETH Length underlying_NameRef + OBJECTVAR Length underlying_NameRef + OBJECTCLASS Length underlying_NameRef SIGNED Length original_NameRef resultSig_NameRef paramSig_NameRef* NameRef = Nat // ordinal number of name in name table, starting from 1. diff --git a/compiler/test/dotty/tools/dotc/CompilationTests.scala b/compiler/test/dotty/tools/dotc/CompilationTests.scala index 5b788074de81..c46d709a87ff 100644 --- a/compiler/test/dotty/tools/dotc/CompilationTests.scala +++ b/compiler/test/dotty/tools/dotc/CompilationTests.scala @@ -244,7 +244,7 @@ class CompilationTests extends ParallelTesting { }.map(_.checkCompile()).foreach(_.delete()) } - /** Add a `z` so that hey run last. TODO: Only run them selectively? */ + /** Add a `z` so that they run last. TODO: Only run them selectively? */ @Test def zBytecodeIdempotency: Unit = { var failed = 0 var total = 0 From dec083a2fcde7df0c8c12918f148b00de84bc616 Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Sun, 7 May 2017 11:54:22 +0200 Subject: [PATCH 4/8] Make all name kinds strict For many kinds this is needed because creation of a name kind involves a side effect, namely registering the name kind. If we delay this we might get a crash on unpickling because a tag is not set yet. This was observed when compiling the collection strawman test. --- compiler/src/dotty/tools/dotc/core/NameKinds.scala | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/compiler/src/dotty/tools/dotc/core/NameKinds.scala b/compiler/src/dotty/tools/dotc/core/NameKinds.scala index 2915b7a8da9c..4a6f27dbe499 100644 --- a/compiler/src/dotty/tools/dotc/core/NameKinds.scala +++ b/compiler/src/dotty/tools/dotc/core/NameKinds.scala @@ -62,7 +62,7 @@ object NameKinds { } /** The kind of SimpleNames */ - object SimpleNameKind extends NameKind(UTF8) { self => + val SimpleNameKind = new NameKind(UTF8) { self => type ThisInfo = Info val info = new Info def mkString(underlying: TermName, info: ThisInfo) = unsupported("mkString") @@ -311,7 +311,7 @@ object NameKinds { val PatMatSelectorName = new UniqueNameKind("selector") /** The kind of names of default argument getters */ - object DefaultGetterName extends NumberedNameKind(DEFAULTGETTER, "DefaultGetter") { + val DefaultGetterName = new NumberedNameKind(DEFAULTGETTER, "DefaultGetter") { def mkString(underlying: TermName, info: ThisInfo) = { val prefix = if (underlying.isConstructorName) nme.DEFAULT_GETTER_INIT else underlying prefix.toString + str.DEFAULT_GETTER + (info.num + 1) @@ -330,14 +330,14 @@ object NameKinds { } /** The kind of names that also encode a variance: 0 for contravariance, 1 for covariance. */ - object VariantName extends NumberedNameKind(VARIANT, "Variant") { + val VariantName = new NumberedNameKind(VARIANT, "Variant") { def mkString(underlying: TermName, info: ThisInfo) = "-+"(info.num).toString + underlying } /** Names of the form N_. Emitted by inliner, replaced by outer path * in ExplicitOuter. */ - object OuterSelectName extends NumberedNameKind(OUTERSELECT, "OuterSelect") { + val OuterSelectName = new NumberedNameKind(OUTERSELECT, "OuterSelect") { def mkString(underlying: TermName, info: ThisInfo) = { assert(underlying.isEmpty) info.num + "_" @@ -359,7 +359,7 @@ object NameKinds { val ModuleClassName = new SuffixNameKind(OBJECTCLASS, "$", optInfoString = "ModuleClass") /** A name together with a signature. Used in Tasty trees. */ - object SignedName extends NameKind(63) { + val SignedName = new NameKind(63) { case class SignedInfo(sig: Signature) extends Info { override def toString = s"$infoString $sig" From 76e31aa5152d3c5d44e026ae320b58254ca0d03a Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Sun, 7 May 2017 16:09:23 +0200 Subject: [PATCH 5/8] Fix bug in avoid --- compiler/src/dotty/tools/dotc/typer/TypeAssigner.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/src/dotty/tools/dotc/typer/TypeAssigner.scala b/compiler/src/dotty/tools/dotc/typer/TypeAssigner.scala index 71806facfd44..4496c2bcf1c7 100644 --- a/compiler/src/dotty/tools/dotc/typer/TypeAssigner.scala +++ b/compiler/src/dotty/tools/dotc/typer/TypeAssigner.scala @@ -94,7 +94,7 @@ trait TypeAssigner { val refinableDecls = info.decls.filter( sym => !(sym.is(TypeParamAccessor | Private) || sym.isConstructor)) val fullType = (parentType /: refinableDecls)(addRefinement) - mapOver(fullType) + apply(fullType) case TypeBounds(lo, hi) if variance > 0 => apply(hi) case _ => From b10eece1cc845a5c39522f750fd836468f43b86f Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Sun, 7 May 2017 16:10:30 +0200 Subject: [PATCH 6/8] Fix checking condition --- compiler/src/dotty/tools/dotc/core/Types.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/src/dotty/tools/dotc/core/Types.scala b/compiler/src/dotty/tools/dotc/core/Types.scala index 9d6bc0a01c55..637239db038c 100644 --- a/compiler/src/dotty/tools/dotc/core/Types.scala +++ b/compiler/src/dotty/tools/dotc/core/Types.scala @@ -2930,7 +2930,7 @@ object Types { case tycon: TypeRef if !tycon.symbol.isClass => case _: TypeParamRef | _: ErrorType | _: WildcardType => case _: TypeLambda => - assert(args.exists(_.isInstanceOf[TypeBounds]), s"unreduced type apply: $this") + assert(!args.exists(_.isInstanceOf[TypeBounds]), s"unreduced type apply: $this") case tycon: AnnotatedType => check(tycon.underlying) case _ => From 6e3f32562b63ba52abf90e4f81a677fb21101af8 Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Sun, 7 May 2017 16:11:51 +0200 Subject: [PATCH 7/8] Add test case --- tests/pos/avoid.scala | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/tests/pos/avoid.scala b/tests/pos/avoid.scala index 51471feaae65..a9b633b772e9 100644 --- a/tests/pos/avoid.scala +++ b/tests/pos/avoid.scala @@ -8,3 +8,20 @@ object test { } val z: String = x.y } + +// A tricky case involving inner classes, exercised +// in the large in dotty.tools.dotc.core.NameKinds.scala. +object Test2 { + + class NK { + class I + type T + } + + val x = new NK { type T = I } + + val y = { + class C extends NK { type T = I } + new C + } +} From d3501e1fb318fcfcdf10facf14de163ba776df2d Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Sun, 7 May 2017 16:57:00 +0200 Subject: [PATCH 8/8] Fix NameKinds The previous change hid the refinements of `info` and apply/unapply. Turning SimpleNameKind and SignedNameKind back into objects fixes that. Neither name kind installs anything as a side effect so turning them into objects is OK. --- compiler/src/dotty/tools/dotc/core/NameKinds.scala | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/compiler/src/dotty/tools/dotc/core/NameKinds.scala b/compiler/src/dotty/tools/dotc/core/NameKinds.scala index 4a6f27dbe499..d51a1d8cbfef 100644 --- a/compiler/src/dotty/tools/dotc/core/NameKinds.scala +++ b/compiler/src/dotty/tools/dotc/core/NameKinds.scala @@ -61,8 +61,7 @@ object NameKinds { def infoString: String } - /** The kind of SimpleNames */ - val SimpleNameKind = new NameKind(UTF8) { self => + object SimpleNameKind extends NameKind(UTF8) { self => type ThisInfo = Info val info = new Info def mkString(underlying: TermName, info: ThisInfo) = unsupported("mkString") @@ -359,7 +358,7 @@ object NameKinds { val ModuleClassName = new SuffixNameKind(OBJECTCLASS, "$", optInfoString = "ModuleClass") /** A name together with a signature. Used in Tasty trees. */ - val SignedName = new NameKind(63) { + object SignedName extends NameKind(63) { case class SignedInfo(sig: Signature) extends Info { override def toString = s"$infoString $sig"