summaryrefslogtreecommitdiff
Commit message (Collapse)AuthorAgeFilesLines
* Double-checked locking for local lazy vals.Adriaan Moors2016-08-292-28/+37
|
* Double-checked locking for modules.Adriaan Moors2016-08-295-46/+51
| | | | Inline `mkSynchronizedCheck`, whose abstraction obscured rather than clarified.
* Ensure access from subclass to trait lazy valAdriaan Moors2016-08-292-0/+7
| | | | | | | | | | | Since we need to refer to a trait lazy val's accessor using a super call in a subclass (when the field and bitmap are added), we must ensure that access is allowed. If the lazy val has an access boundary (e.g., `private[somePkg]`), make sure the `PROTECTED` flag is set, which widens access to `protected[somePkg]`. (As `member.hasAccessBoundary` implies `!member.hasFlag(PRIVATE)`, we don't have to `resetFlag PRIVATE`.)
* Move AccessorSynthesis out to its own fileAdriaan Moors2016-08-292-455/+466
|
* Fields does bitmaps & synch for lazy vals & modulesAdriaan Moors2016-08-2932-797/+940
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Essentially, we fuse mixin and lazyvals into the fields phase. With fields mixing in trait members into subclasses, we have all info needed to compute bitmaps, and thus we can synthesize the synchronisation logic as well. By doing this before erasure we get better signatures, and before specialized means specialized lazy vals work now. Mixins is now almost reduced to its essence: implementing super accessors and forwarders. It still synthesizes accessors for param accessors and early init trait vals. Concretely, trait lazy vals are mixed into subclasses with the needed synchronization logic in place, as do lazy vals in classes and methods. Similarly, modules are initialized using double checked locking. Since the code to initialize a module is short, we do not emit compute methods for modules (anymore). For simplicity, local lazy vals do not get a compute method either. The strange corner case of constant-typed final lazy vals is resolved in favor of laziness, by no longer assigning a constant type to a lazy val (see widenIfNecessary in namers). If you explicitly ask for something lazy, you get laziness; with the constant-typedness implicit, it yields to the conflicting `lazy` modifier because it is explicit. Co-Authored-By: Lukas Rytz <lukas@lightbend.com> Fixes scala/scala-dev#133 Inspired by dotc, desugar a local `lazy val x = rhs` into ``` val x$lzy = new scala.runtime.LazyInt() def x(): Int = { x$lzy.synchronized { if (!x$lzy.initialized) { x$lzy.initialized = true x$lzy.value = rhs } x$lzy.value } } ``` Note that the 2.11 decoding (into a local variable and a bitmap) also creates boxes for local lazy vals, in fact two for each lazy val: ``` def f = { lazy val x = 0 x } ``` desugars to ``` public int f() { IntRef x$lzy = IntRef.zero(); VolatileByteRef bitmap$0 = VolatileByteRef.create((byte)0); return this.x$1(x$lzy, bitmap$0); } private final int x$lzycompute$1(IntRef x$lzy$1, VolatileByteRef bitmap$0$1) { C c = this; synchronized (c) { if ((byte)(bitmap$0$1.elem & 1) == 0) { x$lzy$1.elem = 0; bitmap$0$1.elem = (byte)(bitmap$0$1.elem | 1); } return x$lzy$1.elem; } } private final int x$1(IntRef x$lzy$1, VolatileByteRef bitmap$0$1) { return (byte)(bitmap$0$1.elem & 1) == 0 ? this.x$lzycompute$1(x$lzy$1, bitmap$0$1) : x$lzy$1.elem; } ``` An additional problem with the above encoding is that the `lzycompute` method synchronizes on `this`. In connection with the new lambda encoding that no longer generates anonymous classes, captured lazy vals no longer synchronize on the lambda object. The new encoding solves this problem (scala/scala-dev#133) by synchronizing on the lazy holder. Currently, we don't exploit the fact that the initialized field is `@volatile`, because it's not clear the performance is needed for local lazy vals (as they are not contended, and as soon as the VM warms up, biased locking should deal with that) Note, be very very careful when moving to double-checked locking, as this needs a different variation than the one we use for class-member lazy vals. A read of a volatile field of a class does not necessarily impart any knowledge about a "subsequent" read of another non-volatile field of the same object. A pair of volatile reads and write can be used to implement a lock, but it's not clear if the complexity is worth an unproven performance gain. (Once the performance gain is proven, let's change the encoding.) - don't explicitly init bitmap in bytecode - must apply method to () explicitly after uncurry
* Precompute bitmap info for lazy/init-checked valsAdriaan Moors2016-08-291-255/+256
| | | | | | Instead of doing this lazily, rework the logic to make it suitable for operating first on symbols (during the info transform), then on trees (tree transform).
* [refactor] strictly reorder definitionsAdriaan Moors2016-08-291-456/+448
|
* [refactor] corral init bits some moreAdriaan Moors2016-08-291-355/+410
| | | | More code motion.
* [refactor] corral checkinit logicAdriaan Moors2016-08-291-57/+51
| | | | Just moving some code around to make it comprehensible.
* [refactor] lazy val expansion in mixins/lazyvalsAdriaan Moors2016-08-293-103/+68
| | | | Towards expanding lazy vals and modules during fields phase.
* optimize/simplify erasure of class info typeAdriaan Moors2016-08-291-10/+9
|
* SI-8873 don't propagate primary ctor arg to case class's applyAdriaan Moors2016-08-293-0/+13
| | | | Final implementation based on feedback by Jason
* Fields phase expands lazy vals like modulesAdriaan Moors2016-08-2946-607/+535
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | They remain ValDefs until then. - remove lazy accessor logic now that we have a single ValDef for lazy vals, with the underlying machinery being hidden until the fields phase leave a `@deprecated def lazyAccessor` for scala-refactoring - don't skolemize in purely synthetic getters, but *do* skolemize in lazy accessor during typers Lazy accessors have arbitrary user code, so have to skolemize. We exempt the purely synthetic accessors (`isSyntheticAccessor`) for strict vals, and lazy accessors emitted by the fields phase to avoid spurious type mismatches due to issues with existentials (That bug is tracked as https://github.com/scala/scala-dev/issues/165) When we're past typer, lazy accessors are synthetic, but before they are user-defined to make this hack less hacky, we could rework our flag usage to allow for requiring both the ACCESSOR and the SYNTHETIC bits to identify synthetic accessors and trigger the exemption. see also https://github.com/scala/scala-dev/issues/165 ok 7 - pos/existentials-harmful.scala ok 8 - pos/t2435.scala ok 9 - pos/existentials.scala previous attempt: skolemize type of val inside the private[this] val because its type is only observed from inside the accessor methods (inside the method scope its existentials are skolemized) - bean accessors have regular method types, not nullary method types - must re-infer type for param accessor some weirdness with scoping of param accessor vals and defs? - tailcalls detect lazy vals, which are defdefs after fields - can inline constant lazy val from trait - don't mix in fields etc for an overridden lazy val - need try-lift in lazy vals: the assign is not seen in uncurry because fields does the transform (see run/t2333.scala) - ensure field members end up final in bytecode - implicit class companion method: annot filter in completer - update check: previous error message was tangled up with unrelated field definitions (`var s` and `val s_scope`), now it behaves consistently whether those are val/vars or defs - analyzer plugin check update seems benign, but no way to know... - error message gen: there is no underlying symbol for a deferred var look for missing getter/setter instead - avoid retypechecking valdefs while duplicating for specialize see pos/spec-private - Scaladoc uniformly looks to field/accessor symbol - test updates to innerClassAttribute by Lukas
* asmutilsAdriaan Moors2016-08-291-13/+33
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | decompile classfiles in parallel to aid in diffing bytecode between quick & strap ``` mkdir class-repo cd class-repo git init . ( cd .. ; sbt publishLocal ) v="2.12.0-local-$(g rev-parse --short HEAD)" ( cd ~/git/scala-2 ; sbt -Dstarr.version=$v compile ) for i in compiler interactive junit library partest-extras partest-javaagent reflect repl repl-jline repl-jline-embedded scaladoc scalap do cp -a ~/git/scala/build/quick/classes/$i . ~/git/scala/build/quick/bin/scala scala.tools.nsc.backend.jvm.AsmUtils $(find $i -name "*.class" ) g add $(find $i -name "*.asm" ) done g commit -m"quick" for i in compiler interactive junit library partest-extras partest-javaagent reflect repl repl-jline repl-jline-embedded scaladoc scalap do cp -a ~/git/scala-2/build/quick/classes/$i/* $i/ ~/git/scala/build/quick/bin/scala scala.tools.nsc.backend.jvm.AsmUtils $(find $i -name "*.class" ) done git --no-pager diff | mate ```
* git ignore local.sbtAdriaan Moors2016-08-291-0/+1
| | | | | | | | | | | | | | | | | | | | my local.sbt: ``` resolvers += "pr" at "https://scala-ci.typesafe.com/artifactory/scala-pr-validation-snapshots/" publishArtifact in (Compile, packageDoc) in ThisBuild := false baseVersionSuffix := s"local-${Process("tools/get-scala-commit-sha").lines.head.substring(0, 7)}" antStyle := true ``` To bootstrap the compiler, assuming your git abbreviates shas to 7 long: ``` function strap () { sbt clean publishLocal sbt -Dstarr.version=2.12.0-local-$(g rev-parse --short HEAD) } ```
* clean up genprod, get rid of warning (#5361)Seth Tisue2016-08-291-10/+8
| | | | | No more "Selecting value MAX_ARITY from object genprod, which extends scala.DelayedInit, is likely to yield an uninitialized value" at start of every build.
* Merge pull request #5263 from retronym/review/5041Jason Zaugg2016-08-2918-148/+420
|\ | | | | SI-5294 SI-6161 Hard graft in asSeenFrom, refinements, and existentials [ci: last-only]
| * Improve RefinementTypeRef#normalizeJason Zaugg2016-08-231-1/+1
| |
| * Minor changes after reviewJason Zaugg2016-08-232-3/+3
| |
| * Address review commentsJason Zaugg2016-08-234-45/+52
| | | | | | | | | | | | | | | | | | | | - clarify the intent of tests - Consolidate stripExistentialsAndTypeVars with similar logic in mergePrefixAndArgs - Refactor special cases in maybeRewrap The name isn't great, but I'm struggling to come up with a pithy way to describe the rogue band of types.
| * Unit test for recent bug fix in LUBsJason Zaugg2016-08-231-0/+11
| |
| * Tone abort down to a dev warningJason Zaugg2016-08-231-1/+1
| |
| * SI-5294 Use bounds of abstract prefix in asSeenFromJason Zaugg2016-08-235-5/+108
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | ASF was failing to recognize the correspondence between a prefix if it has an abstract type symbol, even if it is bounded by the currently considered class. Distilling the test cases, this led to incorrect typechecking of the RHS of `G` in: ``` trait T { type A trait HasH { type H[U] <: U } type F[N <: HasH] = N#H[T] type G[N <: HasH] = F[N]#A // RHS was incorrectly reduced to T.this.A } ``` In the fuller examples (included as test cases), this meant that type level functions written as members of `HList` could not be implemented in terms of each other, e.g. defining `Apply[N]` as `Drop[N]#Head` had the wrong semantics. This commit checks checks if the prefix has the candidate class as a base type, rather than checking if its type symbol has this as a base class. The latter formulation discarded information about the instantation of the abstract type. Using the example above: ``` scala> val F = typeOf[T].member(TypeName("F")).info F: $r.intp.global.Type = [N <: T.this.HasH]N#H[T] scala> F.resultType.typeSymbol.baseClasses // old approach res14: List[$r.intp.global.Symbol] = List(class Any) scala> F.resultType.baseClasses // new approach res13: List[$r.intp.global.Symbol] = List(trait T, class Object, class Any) ``` It is worth noting that dotty rejects some of these programs, as it introduces the rule that: > // A type T is a legal prefix in a type selection T#A if > // T is stable or T contains no abstract types except possibly A. > final def isLegalPrefixFor(selector: Name)(implicit ctx: Context) However, typechecking the program above in this comment in dotty yields: <trait> trait T() extends Object { type A <trait> trait HasH() extends Object { type H <: [HK$0] => <: HK$0 } type F = [HK$0] => HK$0#H{HK$0 = T}#Apply type G = [HK$0] => HK$0#H{HK$0 = T}#Apply#A } As the equivalent code [1] in dotc's `asSeenFrom` already looks for a base type of the prefix, rather than looking for a superclass of the prefix's type symbol. [1] https://github.com/lampepfl/dotty/blob/d2c96d02fccef3a82b88ee1ff31253b6ef17f900/src/dotty/tools/dotc/core/TypeOps.scala#L62
| * Improved refinement type and existential type handlingJason Zaugg2016-08-238-103/+211
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Lazy base type seq elements are encoded as a refined type with an empty scope and a list of type refs over some common type symbol that will be merged when `BaseTypeSeq#apply` is called. The first change in this commit is to mark the creation and consumption of such elements with calls to `[is]IntersectionTypeForBaseTypeSeq`. They are distinguished by using the actual type symbol rather than a refinement class symbol, which in turn simplifies the code in `BaseTypeSeq#typeSymbol`. I have also made `lub` aware of this encoding: it is now able to "see through" to the parents of such refined types and merge them with other base types of the same class symbol (even other refined types representing lazy BTS elements.) To make this fix work, I also had to fix a bug in LUBs of multiple with existential types. Because of the way the recursion was structured in `mergePrefixAndArgs`, the order of list of types being merged changed behaviour: quantified varialbles of existential types were being rewrapped around the resultting type, but only if we hadn't encountered the first regular `TypeRef`. This can be seen with the following before/after shot: ``` // 2.11.8 scala> val ts = typeOf[Set[Any]] :: typeOf[Set[X] forSome { type X <: Y; type Y <: Int}] :: Nil; def merge(ts: List[Type]) = mergePrefixAndArgs(ts, Variance.Contravariant, lubDepth(ts)); val merged1 = merge(ts); val merged2 = merge(ts.reverse); (ts.forall(_ <:< merged1), ts.forall(_ <:< merged2)) ts: List[$r.intp.global.Type] = List(Set[Any], Set[_ <: Int]) merge: (ts: List[$r.intp.global.Type])$r.intp.global.Type merged1: $r.intp.global.Type = scala.collection.immutable.Set[_ >: Int] merged2: $r.intp.global.Type = scala.collection.immutable.Set[_53] forSome { type X <: Int; type _53 >: X } res0: (Boolean, Boolean) = (false,true) // HEAD ... merged1: $r.intp.global.Type = scala.collection.immutable.Set[_10] forSome { type X <: Int; type _10 >: X } merged2: $r.intp.global.Type = scala.collection.immutable.Set[_11] forSome { type X <: Int; type _11 >: X } res0: (Boolean, Boolean) = (true,true) ``` Furthermore, I have fixed the computation of the base type sequences of existential types over refinement types, in order to maintain the invariant that each slot of the base type sequence of a existential has the same type symbol as that of its underlying type. Before, what I've now called a `RefinementTypeRef` was transformed into a `RefinedType` during rewrapping in the existential, which led to it being wrongly considered as a lazy element of the base type sequence. The first change above should also be sufficient to avoid the bug, but I felt it was worth cleaning up `maybeRewrap` as an extra line of defence. Finally, I have added another special case to `BaseTypeSeq#apply` to be able to lazily compute elements that have been wrapped in an existential. The unit test cases in `TypesTest` rely on these changes. A subsequent commit will build on this foundation to make a fix to `asSeenFrom`.
| * Type#contains should peer into RefinementTypeRef-sJason Zaugg2016-08-194-6/+36
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Usually, `contains` should not look into class symbol infos. For instance, we expect that: ``` scala> trait C { def foo: Int }; typeOf[C].contains(IntClass) defined trait C res1: Boolean = false ``` We do, however, look at the decls of a `RefinedType` in contains: ``` scala> typeOf[{ def foo: Int }].contains(IntClass) res2: Boolean = true ``` Things get a little vague, however, when we consider a type ref to the refinement class symbol of a refined type. ``` scala> TypeRef(NoPrefix, typeOf[{ def foo: Int }].typeSymbol, Nil) res3: $r.intp.global.Type = AnyRef{def foo: Int} scala> .contains(IntClass) res4: Boolean = false ``` These show up in the first element of the base type seq of a refined type, e.g: ``` scala> typeOf[{ def foo: Int }].typeSymbol.tpe_* res5: $r.intp.global.Type = AnyRef{def foo: Int} scala> typeOf[{ def foo: Int }].baseTypeSeq(0).getClass res7: Class[_ <: $r.intp.global.Type] = class scala.reflect.internal.Types$RefinementTypeRef scala> typeOf[{ def foo: Int }].typeSymbol.tpe_*.getClass res6: Class[_ <: $r.intp.global.Type] = class scala.reflect.internal.Types$RefinementTypeRef ``` This commit takes the opinion that a `RefinementTypeRef` should be transparent with respect to `contains`. This paves the way for fixing the base type sequences of existential types over refinement types. The implementation of `ContainsCollector` was already calling `normalize`, which goes from `RefinementTypeRef` to `RefinedType`. This commit maps over the result, which looks in the parents and decls.
| * Determistically enter classes from directory into package scopeJason Zaugg2016-08-193-10/+23
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | On Linux, the directory listing is not automatically sorted on Mac. This leads to non-determistic ids of Symbols of the classes in a directory, which in turn leads to instability of the ordering of parents within inferred refinement types. Notable, with this patch, we will stably infer: ``` scala> case class C(); case class D(); List(C(), D()).head defined class C defined class D res0: Product with Serializable = C() ``` rather than sometimes getting `Serializable with Product` on Linux. As such, I've removed the workarounds for this instability in two test cases.
* | Merge pull request #5357 from SethTisue/topic/sd-206Seth Tisue2016-08-272-1/+5
|\ \ | | | | | | SAM for subtypes of FunctionN
| * | SAM for subtypes of FunctionNLukas Rytz2016-08-262-1/+5
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | only exclude FunctionN types themselves from SAM, don't exclude their subtypes; we want e.g. trait T extends Function1[String, String] (x => x) : T to compile reference: https://github.com/scala/scala-dev/issues/206
* | | Merge pull request #5360 from SethTisue/missing-x-bitSeth Tisue2016-08-271-0/+0
|\ \ \ | | | | | | | | supply missing execute bit on bootstrap script
| * | | supply missing execute bit on bootstrap scriptSeth Tisue2016-08-261-0/+0
|/ / / | | | | | | | | | | | | this was failing integrate-bootstrap on Jenkins with a "Permission denied" error
* | | Merge pull request #5362 from SethTisue/increase-stack-size-for-pagedseq-testSeth Tisue2016-08-261-0/+1
|\ \ \ | | | | | | | | increase stack size when running JUnit tests
| * | | increase stack size when running JUnit testsSeth Tisue2016-08-261-0/+1
|/ / / | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | scala.collection.immutable.PagedSeqTest.test_SI6615 was failing intermittently during PR validation I verified that this change fixes the problem by: - changing the PageSize constant in PagedSeq (as shown by Jason Zaugg) until the test failed every time locally - making this build change and seeing the test pass again 5M is just an arbitrary number, considerably over the default (which varies according to platform & CPU). 5M is a lot of stack, but not so vastly much that it appreciably eats into the heap
* | | Merge pull request #5349 from som-snytt/issue/9841-testAdriaan Moors2016-08-241-0/+12
|\ \ \ | |/ / |/| | SI-9841 Progression test for SO on init
| * | SI-9841 Progression test for SO on initSom Snytt2016-08-171-0/+12
| |/ | | | | | | Test as reported in ticket. Works on 2.12.
* | Merge pull request #5356 from szeiger/wip/raid-1Stefan Zeiger2016-08-236-37/+43
|\ \ | | | | | | Switch remaining uses of ant over to sbt
| * | Switch remaining uses of ant over to sbtStefan Zeiger2016-08-236-37/+43
|/ / | | | | | | | | | | | | | | | | | | | | | | | | | | - Modify `tools/scaladoc-diff` to use sbt instead of ant. - Move `stability-test.sh` from `tools` to `scripts`. With the new build process without separate `locker` and `strap` stages, it doesn’t make sense to call this script without first setting up the proper test environment in a CI build. - Replace the use of `build.number` in `bootstrap` with a new `SHA-NIGHTLY` mode for `baseVersionSuffix`. - Make `partest` call sbt instead of ant for initializing the classpath and use the new classpath location (`quick` instead of `pack`).
* | Merge pull request #5355 from dsbos/dsbos-SpecEditsAdriaan Moors2016-08-227-54/+54
|\ \ | | | | | | Italicize more defining occurrences of terms in Scala lang. spec.
| * | Editorial: Italicized more defining occurrences of terms.Daniel Barclay2016-08-217-54/+54
| | |
* | | Merge pull request #5322 from retronym/topic/SD-194Adriaan Moors2016-08-222-11/+18
|\ \ \ | |_|/ |/| | SD-194 Tweak module initialization to comply with JVM spec
| * | SD-194 Tweak module initialization to comply with JVM specJason Zaugg2016-08-182-11/+18
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Top level modules in Scala currently desugar as: ``` class C; object O extends C { toString } ``` ``` public final class O$ extends C { public static final O$ MODULE$; public static {}; Code: 0: new #2 // class O$ 3: invokespecial #12 // Method "<init>":()V 6: return private O$(); Code: 0: aload_0 1: invokespecial #13 // Method C."<init>":()V 4: aload_0 5: putstatic #15 // Field MODULE$:LO$; 8: aload_0 9: invokevirtual #21 // Method java/lang/Object.toString:()Ljava/lang/String; 12: pop 13: return } ``` The static initalizer `<clinit>` calls the constructor `<init>`, which invokes superclass constructor, assigns `MODULE$= this`, and then runs the remainder of the object's constructor (`toString` in the example above.) It turns out that this relies on a bug in the JVM's verifier: assignment to a static final must occur lexically within the <clinit>, not from within `<init>` (even if the latter is happens to be called by the former). I'd like to move the assignment to <clinit> but that would change behaviour of "benign" cyclic references between modules. Example: ``` package p1; class CC { def foo = O.bar}; object O {new CC().foo; def bar = println(1)}; // Exiting paste mode, now interpreting. scala> p1.O 1 ``` This relies on the way that we assign MODULE$ field after the super class constructors are finished, but before the rest of the module constructor is called. Instead, this commit removes the ACC_FINAL bit from the field. It actually wasn't behaving as final at all, precisely the issue that the stricter verifier now alerts us to. ``` scala> :paste -raw // Entering paste mode (ctrl-D to finish) package p1; object O // Exiting paste mode, now interpreting. scala> val O1 = p1.O O1: p1.O.type = p1.O$@ee7d9f1 scala> scala.reflect.ensureAccessible(p1.O.getClass.getDeclaredConstructor()).newInstance() res0: p1.O.type = p1.O$@64cee07 scala> O1 eq p1.O res1: Boolean = false ``` We will still achieve safe publication of the assignment to other threads by virtue of the fact that `<clinit>` is executed within the scope of an initlization lock, as specified by: https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-5.html#jvms-5.5 Fixes scala/scala-dev#SD-194
* | | Merge pull request #5344 from tomjridge/2.12.xLukas Rytz2016-08-171-3/+3
|\ \ \ | | | | | | | | Fix typos in syntax
| * | | Fix typos in syntaxtomjridge2016-08-151-3/+3
|/ / /
* | | Merge pull request #5317 from retronym/ticket/SD-192Lukas Rytz2016-08-1510-30/+42
|\ \ \ | | | | | | | | SD-192 Change scheme for trait super accessors
| * | | SD-192 Change scheme for trait super accessorsJason Zaugg2016-08-1510-30/+42
| |/ / | | | | | | | | | | | | | | | Rather than putting the code of a trait method body into a static method, leave it in the default method. The static method (needed as the target of the super calls) now uses `invokespecial` to exactly call that method.
* | | Merge pull request #5266 from som-snytt/issue/9847Adriaan Moors2016-08-1435-95/+207
|\ \ \ | | | | | | | | SI-9847 Nuance pure expr statement warning
| * | | SI-9847 Nuance pure expr statement warningSom Snytt2016-07-0835-95/+207
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Clarify the current warning, which means that an expression split over multiple lines may not be parsed as naively expected. When typing a block, attempt minor nuance. For instance, a single expression is not in need of parens. Try to avoid duplicate warnings for expressions that were adapted away from result position.
* | | | Merge pull request #5283 from lrytz/sd182Jason Zaugg2016-08-153-35/+73
|\ \ \ \ | |_|/ / |/| | | SD-182 compiler option -Xgen-mixin-forwarders
| * | | SD-182 compiler option -Xgen-mixin-forwardersLukas Rytz2016-07-153-35/+73
| | | | | | | | | | | | | | | | | | | | Introduce a compiler option -Xgen-mixin-forwarders to always generate mixin forwarder methods.
* | | | Merge pull request #5328 from szeiger/wip/better-testAll-resultsAdriaan Moors2016-08-131-3/+45
|\ \ \ \ | | | | | | | | | | Improve log output of the `testAll` task
| * | | | Split “partest run” off from “partest pos neg jvm”Stefan Zeiger2016-08-121-2/+4
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | We’ve seen several OOM failures in “run” tests lately. Maybe going back to more separate partest calls will help. Now that everything is launched from the same sbt instance and test results are always accumulated, this should not have any negative impact on build performance or usability.