Skip to content

Merge 2.11.x to 2.12.x#4272

Merged
retronym merged 401 commits intoscala:2.12.xfrom
retronym:merge/2.11.x-to-2.12.x-20150129
Feb 2, 2015
Merged

Merge 2.11.x to 2.12.x#4272
retronym merged 401 commits intoscala:2.12.xfrom
retronym:merge/2.11.x-to-2.12.x-20150129

Conversation

@retronym
Copy link
Member

% export MB=$(git merge-base origin/2.12.x origin/2.11.x)
% echo $MB
2cfac1a3516850a40728fefd8f808613d2e83f84
% transcript git log --graph --oneline --decorate $MB...origin/2.11.x
https://gist.github.com/7c59590812a10f819070
% git merge eb15950
% git merge -sours 767cc44
% git merge 7ba38a0
% git merge -sours 421c599
% git merge origin/2.11.x

Review by @adriaanm. Please check changes to versions.properties and build.number.

These are the two nomerge commits that I skirted around with -sours.

| * | | | | | | 2c4ef6b (origin/pr/4196) [nomerge] SI-9030 don't call private BoxesRunTime.equalsNumChar

| * | | | | 38587c5 (origin/pr/4048) [nomerge] SI-8899 Revert "SI-8627 make Stream.filterNot non-eager"

gourlaysama and others added 30 commits November 5, 2014 11:54
…sfiles

An optimization was introduced in 7a99c03 (SI-5278) to remove redundant
interfaces from the list of implemented interfaces in the bytecode.
However the same change was not propagated to the generic signature
of a class, which also contains a list of direct parent classes and
interfaces.

The JVM does not check the well-formedness of signatures at class
loading or linking (see §4.3.4 of jdk7 jvms), but other tools might
assume the number of implemented interfaces is the same whether one
asked for generic or erased interfaces.

It doesn't break reflection so nobody complained, but it does show:

scala> val c = classOf[Tuple1[String]]
c: Class[(String,)] = class scala.Tuple1

scala> c.getInterfaces // Product is gone
res0: Array[Class[_]] = Array(interface scala.Product1, interface
scala.Serializable)

scala> c.getGenericInterfaces // Product is back!
res1: Array[java.lang.reflect.Type] = Array(scala.Product1<T1>,
interface scala.Product, interface scala.Serializable)

This moves the optimization to erasure, for use in emitting the generic
signature, and the backend calls into it later for the list of
interfaces.
In scaladoc, this turns exceptions in @throws tags into links
(when it can find the target exception), instead of just showing
the name.
 - there is no need for explicit links with [[ and ]]
 - there is no need for explicit backquoting
In PR scala#1673 / 4267444, the annotation `SerialVersionId` was changed
from a `StaticAnnotation` to `ClassFileAnnotation` in order to enforce
annotation arguments to be constants. That was 2.11.0.

The ID value in the AnnotationInfo moved from `args` to `assocs`, but
the backend was not adjusted. This was fixed in PR scala#3711 / ecbc9d0 for
2.11.1.

Unfortunately, the synthetic AnnotationInfo that is added to anonymous
function classes still used the old constructor (`args` instead of
`assocs`), so extracting the value failed, and no field was added to
the classfile.
SI-6541 valid wildcard existentials for case-module-unapply
SI-5091 Move named-args cycle test from pending to neg
SI-8898 javap -fun under new style lambdas
SI-5217 Companion privates in scope of class parms
…ows-links

SI-6626 make @throws tags create links to exceptions
….10)

Fixes SI-6502, reenables loading jars into the running REPL
(regression in 2.10). This PR allows adding a jar to the compile
and runtime classpaths without resetting the REPL state (crucial
for Spark SPARK-3257).

This follows the lead taken by @som-snytt in PR scala#3986, which
differentiates two jar-loading behaviors (muddled by cp):

  - adding jars and replaying REPL expressions (using replay)
  - adding jars without resetting the REPL (deprecated cp,
    introduced require) This PR implements require (left
    unimplemented in scala#3986)

This PR is a simplification of a similar approach taken by
@gkossakowski in scala#3884. In this attempt, we check first to make
sure that a jar is only added if it only contains new
classes/traits/objects, otherwise we emit an error. This differs
from the old invalidation approach which also tracked deleted
classpath entries.
During the refactoring of error reporting in 258d95c, the result
of `Context#reportError` was changed once we had switched to
using a `ThrowingReporter`, which is still the case in post
typer phase typechecking

This was enough to provoke a type error in the enclosed test.
Here's a diff of the typer log:

    %  scalac-hash 258d95~1 -Ytyper-debug sandbox/test.scala 2>&1 | tee sandbox/good.log
    %  scalac-hash 258d95 -Ytyper-debug sandbox/test.scala 2>&1 | tee sandbox/bad.log
    %  diff -U100 sandbox/{good,bad}.log | gist --filename=SI-8962-typer-log.diff
    https://gist.github.com/retronym/3ccbe7e0791447d272a6

The test `Context#reportError` happens to be used when deciding
whether the type checker should be lenient when it hits a type error.
In lenient mode (see `adaptMismatchedSkolems`), it `adapt` retries
with after slackening the expected type by replacing GADT and
existential skolems with wildcard types. This is to accomodate
known type-incorrect trees generated by the pattern matcher.

This commit restores the old semantics of `reportError`, which means
it is `false` when a `ThrowingReporter` is being used.

For those still reading, here's some more details.

The trees of the `run2` example from the enclosed test. Notice that
after typechecking, `expr` has a type containing GADT skolems. The
pattern matcher assumes that calling the case field accessor `expr`
on the temporary val `x2 : Let[A with A]` containing the scrutinee
will result in a compatible expression, however this it does not.
Perhaps the pattern matcher should generate casts, rather than
relying on the typer to turn a blind eye.

```
[[syntax trees at end of                     typer]] // t8962b.scala
...
    def run2[A](nc: Outer2[A,A]): Outer2[Inner2[A],A] = nc match {
      case (expr: Outer2[Inner2[?A2 with ?A1],?A2 with ?A1])Let2[A with A]((expr @ _{Outer2[Inner2[?A2 with ?A1],?A2 with ?A1]}){Outer2[Inner2[?A2 with ?A1],?A2 with ?A1]}){Let2[A with A]} =>
        (expr{Outer2[Inner2[?A2 with ?A1],?A2 with ?A1]}: Outer2[Inner2[A],A]){Outer2[Inner2[A],A]}
    }{Outer2[Inner2[A],A]}

[[syntax trees at end of                    patmat]] // t8962b.scala

    def run2[A](nc: Outer2[A,A]): Outer2[Inner2[A],A] = {
      case <synthetic> val x1: Outer2[A,A] = nc{Outer2[A,A]};
      case5(){
        if (x1.isInstanceOf[Let2[A with A]])
          {
            <synthetic> val x2: Let2[A with A] = (x1.asInstanceOf[Let2[A with A]]: Let2[A with A]){Let2[A with A]};
            {
              val expr: Outer2[Inner2[?A2 with ?A1],?A2 with ?A1] = x2.expr{<null>};
              matchEnd4{<null>}((expr{Outer2[Inner2[?A2 with ?A1],?A2 with ?A1]}: Outer2[Inner2[A],A]){Outer2[Inner2[A],A]}){<null>}
              ...
```
As suggested in review:

  - Use `abort` rather than `{error; EmptyTree} when we hit an
    error in reification or tag materialization.
  - Explicitly avoid adding the `MacroExpansionAttachment` to the
    macro expansion if it an `EmptyTree`
  - Emit a `-Xdev` warning if any other code paths find a way to
    mutate attachments in places they shouldn't.
In code like:

    object O { val x = A; def x(a: Any) = ... }
    object P extends O.x.A

The unpickler was using an overloaded symbol for `x` in the
parent type of `P`. This led to compilation failures under
separate compilation.

The code that leads to this is in `Unpicklers`:

    def fromName(name: Name) = name.toTermName match {
      case nme.ROOT     => loadingMirror.RootClass
      case nme.ROOTPKG  => loadingMirror.RootPackage
      case _            => adjust(owner.info.decl(name))
    }

This commit filters the overloaded symbol based its stability
unpickling a singleton type. That seemed a slightly safer place
than in `fromName`.
SI-8960 Bring back the SerialVersionUID to anonymous function classes
When we move the body of value class methods to the corresponding
extension method, we typecheck a forward method that remains
in the class. In order to allow access, this commit weakens the
access of `private[local]` extension methods to `private`.
Playing with Java 8 Streams from the repl showed
we weren't eta-expanding, nor resolving overloading for SAMs.

Also, the way Java uses wildcards to represent use-site variance
stresses type inference past its bendiness point (due to excessive existentials).

I introduce `wildcardExtrapolation` to simplify the resulting types
(without losing precision): `wildcardExtrapolation(tp) =:= tp`.

For example, the `MethodType` given by `def bla(x: (_ >: String)): (_ <: Int)`
is both a subtype and a supertype of `def bla(x: String): Int`.

Translating http://winterbe.com/posts/2014/07/31/java8-stream-tutorial-examples/
into Scala shows most of this works, though we have some more work to do (see near the end).

```
scala> import java.util.Arrays
scala> import java.util.stream.Stream
scala> import java.util.stream.IntStream
scala> val myList = Arrays.asList("a1", "a2", "b1", "c2", "c1")
myList: java.util.List[String] = [a1, a2, b1, c2, c1]

scala> myList.stream.filter(_.startsWith("c")).map(_.toUpperCase).sorted.forEach(println)
C1
C2

scala> myList.stream.filter(_.startsWith("c")).map(_.toUpperCase).sorted
res8: java.util.stream.Stream[?0] = java.util.stream.SortedOps$OfRef@133e7789

scala> Arrays.asList("a1", "a2", "a3").stream.findFirst.ifPresent(println)
a1

scala> Stream.of("a1", "a2", "a3").findFirst.ifPresent(println)
a1

scala> IntStream.range(1, 4).forEach(println)
<console>:37: error: object creation impossible, since method accept in trait IntConsumer of type (x$1: Int)Unit is not defined
(Note that Int does not match Any: class Int in package scala is a subclass of class Any in package scala, but method parameter types must match exactly.)
              IntStream.range(1, 4).forEach(println)
                                            ^

scala> IntStream.range(1, 4).forEach(println(_: Int)) // TODO: can we avoid this annotation?
1
2
3

scala> Arrays.stream(Array(1, 2, 3)).map(n => 2 * n + 1).average.ifPresent(println(_: Double))
5.0

scala> Stream.of("a1", "a2", "a3").map(_.substring(1)).mapToInt(_.parseInt).max.ifPresent(println(_: Int)) // whoops!
ReplGlobal.abort: Unknown type: <error>, <error> [class scala.reflect.internal.Types$ErrorType$, class scala.reflect.internal.Types$ErrorType$] TypeRef? false
error: Unknown type: <error>, <error> [class scala.reflect.internal.Types$ErrorType$, class scala.reflect.internal.Types$ErrorType$] TypeRef? false
scala.reflect.internal.FatalError: Unknown type: <error>, <error> [class scala.reflect.internal.Types$ErrorType$, class scala.reflect.internal.Types$ErrorType$] TypeRef? false
	at scala.reflect.internal.Reporting$class.abort(Reporting.scala:59)

scala> IntStream.range(1, 4).mapToObj(i => "a" + i).forEach(println)
a1
a2
a3

```
SI-8962 Fix regression with skolems in pattern translation
This makes sure that:
 - there is no warning for a @deprecated class inheriting a
   @deprecatedInheritance class
 - there is no warning for a @deprecated method overriding a
   @deprecatedOverriding method
 - there is no "deprecation won't work" warning when overriding a member
   of a @deprecatedInheritance class with a @deprecated member
 - the above works even if the classes/methods are indirectly deprecated
   (i.e. enclosed in something @deprecated)

This should remove quite a few useless deprecation warnings from the
library.
SI-8947 Avoid cross talk between tag materializers and reify
If a class contains a double defintion of a method that overrides
an interface method, LUBs could run into a spot where filtering
overloaded alternatives to those that match the interface method
fails to resolve to a single overload, which crashes the compiler.

This commit uses `filter` rather than `suchThat` to avoid the crash.
SI-7019 Fix crasher with private[this] extension methods
SI-7602 Avoid crash in LUBs with erroneous code
…terfaces-2

SI-8931 make generic signature consistent with interface list in classfiles
retronym and others added 11 commits January 22, 2015 15:02
SI-5154 Parse leading literal brace in XML pattern
IMPORTANT: Base your PR on this one --> New PR validation <--
We can now edit these in IntelliJ, as per the regular JUnit tests.
We use the PAX Exam framework to integration test that the
OSGi metadata we add to our JARs allows them to be loaded
into the Felix and Equinox containers. However, we had to
disable this test under Java 8 due to an incompatibility between
that framework and the modern Java version.

I have found a combination that works in Java 6, 7, and 8,
so the test is now run under all Java versions.

I have left a `skip` property to disable them, following the
established convention.

Tip of the hat to:

  - @soc / @rkrzewski for the work in scala#4066 that paved the way
    for this small change
  - Harald Wellman, for sharing [1] the Java 8 compatible combination
    of PAX and Felix .

Testing:

```
for V in 1.6 1.7 1.8; do java_use $V; ant -q test.osgi; done
java version "1.6.0_65"
Java(TM) SE Runtime Environment (build 1.6.0_65-b14-466.1-11M4716)
Java HotSpot(TM) 64-Bit Server VM (build 20.65-b04-466.1, mixed mode)
     ...
     [echo] Running OSGi JUnit tests. Output in /Users/jason/code/scala3/build/osgi
     [echo] Test pass 1 of 2 using Apache Felix 4.4.0
     [echo] Test pass 2 of 2 using Eclipse Equinox 3.7.1

BUILD SUCCESSFUL
Total time: 31 seconds
java version "1.7.0_71"
Java(TM) SE Runtime Environment (build 1.7.0_71-b14)
Java HotSpot(TM) 64-Bit Server VM (build 24.71-b01, mixed mode)
     ...
     [echo] Running OSGi JUnit tests. Output in /Users/jason/code/scala3/build/osgi
     [echo] Test pass 1 of 2 using Apache Felix 4.4.0
     [echo] Test pass 2 of 2 using Eclipse Equinox 3.7.1

BUILD SUCCESSFUL
Total time: 22 seconds
java version "1.8.0_25"
Java(TM) SE Runtime Environment (build 1.8.0_25-b17)
Java HotSpot(TM) 64-Bit Server VM (build 25.25-b02, mixed mode)
     ...
     [echo] Running OSGi JUnit tests. Output in /Users/jason/code/scala3/build/osgi
     [echo] Test pass 1 of 2 using Apache Felix 4.4.0
     [echo] Test pass 2 of 2 using Eclipse Equinox 3.7.1

BUILD SUCCESSFUL
Total time: 16 seconds
```

[1] https://groups.google.com/d/msg/ops4j/TN0sZFf6wLs/vUP0GML6-TQJ
SI-8642 Enable OSGi tests under Java 8
Conflicts:
	build.number
	src/compiler/scala/tools/nsc/transform/ExtensionMethods.scala
	src/library/scala/collection/Iterator.scala
	versions.properties
…2.x-20150129

Conflicts:
	build.number
	src/library/scala/concurrent/Future.scala
	versions.properties
@scala-jenkins scala-jenkins added this to the 2.12.0-M1 milestone Jan 29, 2015
@retronym
Copy link
Member Author

PR Validation might not work until scala/scala-jenkins-infra#16 is completed.

@retronym
Copy link
Member Author

@adriaanm Please also review the last commit, 4176653.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Purely FYI, this line is also obsolete in 2.11.x -- I removed version numbers from script names for this reason, but forgot to update the comment.

@adriaanm
Copy link
Contributor

Quite the stress test for scabot on its first official day! I'll investigate why so many statuses are out of date tomorrow.

@adriaanm
Copy link
Contributor

/synch

@retronym
Copy link
Member Author

Most of the commits in the PR will predate the dawn of Scalabot. Plenty of the xxx-es come from

/tmp/hudson1067010863983445703.sh: line 2: scripts/jobs/validate/publish-core: No such file or directory
Build step 'Execute shell' marked build as failure

Was scabot even supposed to validate commits that were previously validated by the old validator?

image

@adriaanm
Copy link
Contributor

Nope, the divide between old and new, botwise, is purely based on PR number. My disappointment was that I had to /synch to get the statuses to go from orange-? to red-X

@som-snytt
Copy link
Contributor

Someone has been busy.

@adriaanm
Copy link
Contributor

LGTM

@adriaanm
Copy link
Contributor

I hope there won't be too much rebasing in the other 2.12.0-M1 PRs' futures.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.