summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README.md24
-rwxr-xr-xscripts/jobs/integrate/bootstrap19
-rw-r--r--spec/04-basic-declarations-and-definitions.md9
-rw-r--r--spec/06-expressions.md4
-rw-r--r--src/compiler/scala/tools/nsc/backend/jvm/BCodeBodyBuilder.scala18
-rw-r--r--src/compiler/scala/tools/nsc/reporters/ConsoleReporter.scala4
-rw-r--r--src/library/scala/collection/immutable/Map.scala2
-rw-r--r--src/library/scala/collection/immutable/Set.scala2
-rw-r--r--src/library/scala/collection/mutable/HashMap.scala12
-rw-r--r--src/reflect/scala/reflect/internal/Depth.scala2
-rw-r--r--src/reflect/scala/reflect/internal/TreeInfo.scala1
-rw-r--r--src/repl/scala/tools/nsc/interpreter/ILoop.scala2
-rw-r--r--src/repl/scala/tools/nsc/interpreter/Pasted.scala7
-rw-r--r--test/benchmarks/src/main/scala/scala/collection/immutable/ListBenchmark.scala10
-rw-r--r--test/benchmarks/src/main/scala/scala/collection/immutable/MapBenchmark.scala29
-rw-r--r--test/benchmarks/src/main/scala/scala/collection/immutable/SetBenchmark.scala29
-rw-r--r--test/files/pos/t4237.scala15
-rw-r--r--test/files/run/number-parsing.scala4
-rw-r--r--test/files/run/sd329.scala76
-rw-r--r--test/junit/scala/collection/mutable/HashMapTest.scala38
-rw-r--r--test/junit/scala/tools/nsc/reporters/ConsoleReporterTest.scala173
21 files changed, 426 insertions, 54 deletions
diff --git a/README.md b/README.md
index c5a4c23d00..ac62c8b8e4 100644
--- a/README.md
+++ b/README.md
@@ -20,7 +20,7 @@ We're still using Jira for issue reporting, so please [report any issues](https:
# Get in touch!
If you need some help with your PR at any time, please feel free to @-mention anyone from the list below, and we will do our best to help you out:
- | username | talk to me about... |
+| | username | talk to me about... |
--------------------------------------------------------------------------------------------------|----------------------------------------------------------------|---------------------------------------------------|
<img src="https://avatars.githubusercontent.com/adriaanm" height="50px" title="Adriaan Moors"/> | [`@adriaanm`](https://github.com/adriaanm) | type checker, pattern matcher, infrastructure, language spec |
<img src="https://avatars.githubusercontent.com/SethTisue" height="50px" title="Seth Tisue"/> | [`@SethTisue`](https://github.com/SethTisue) | build, developer docs, community build, Jenkins, library, the welcome-to-Scala experience |
@@ -104,10 +104,13 @@ Core commands:
- `partest` runs partest tests (accepts options, try `partest --help`)
- `publishLocal` publishes a distribution locally (can be used as `scalaVersion` in
other sbt projects)
- - Optionally `set baseVersionSuffix := "abcd123-SNAPSHOT"`
+ - Optionally `set baseVersionSuffix := "-bin-abcd123-SNAPSHOT"`
where `abcd123` is the git hash of the revision being published. You can also
- use something custom like `"mypatch"`. This changes the version number from
- `2.12.0-SNAPSHOT` to something more stable (`2.12.0-abcd123-SNAPSHOT`).
+ use something custom like `"-bin-mypatch"`. This changes the version number from
+ `2.12.2-SNAPSHOT` to something more stable (`2.12.2-bin-abcd123-SNAPSHOT`).
+ - Note that the `-bin` string marks the version binary compatible. Using it in
+ sbt will cause the `scalaBinaryVersion` to be `2.12`. If the version is not
+ binary compatible, we recommend using `-pre`, e.g., `2.13.0-pre-abcd123-SNAPSHOT`.
- Optionally `set publishArtifact in (Compile, packageDoc) in ThisBuild := false`
to skip generating / publishing API docs (speeds up the process).
@@ -199,8 +202,9 @@ CI performs a full bootstrap. The first task, `validate-publish-core`, publishes
a build of your commit to the temporary repository
https://scala-ci.typesafe.com/artifactory/scala-pr-validation-snapshots.
Note that this build is not yet bootstrapped, its bytecode is built using the
-current `starr`. The version number is `2.12.0-abcd123-SNAPSHOT` where `abcd123`
-is the commit hash.
+current `starr`. The version number is `2.12.2-bin-abcd123-SNAPSHOT` where `abcd123`
+is the commit hash. For binary incompatible builds, the version number is
+`2.13.0-pre-abcd123-SNAPSHOT`.
You can use Scala builds in the validation repository locally by adding a resolver
and specifying the corresponding `scalaVersion`:
@@ -208,7 +212,7 @@ and specifying the corresponding `scalaVersion`:
```
$ sbt
> set resolvers += "pr" at "https://scala-ci.typesafe.com/artifactory/scala-pr-validation-snapshots/"
-> set scalaVersion := "2.12.0-abcd123-SNAPSHOT"
+> set scalaVersion := "2.12.2-bin-abcd123-SNAPSHOT"
> console
```
@@ -228,10 +232,8 @@ The CI also publishes nightly API docs:
- [2.11.x](http://www.scala-lang.org/files/archive/nightly/2.11.x/api/?C=M;O=D)
- [symlink to the latest](http://www.scala-lang.org/files/archive/nightly/2.11.x/api/2.11.x/)
-Note that we currently don't publish nightly (or SNAPSHOT) builds in maven or ivy
-format to any repository. You can track progress on this front at
-[scala-jenkins-infra#133](https://github.com/scala/scala-jenkins-infra/issues/133)
-and [scala-dev#68](https://github.com/scala/scala-dev/issues/68).
+Using a nightly build in sbt is explained in
+[this answer on Stack Overflow](http://stackoverflow.com/questions/40622878)
## Scala CI Internals
diff --git a/scripts/jobs/integrate/bootstrap b/scripts/jobs/integrate/bootstrap
index a071f3c45f..65c8ef5551 100755
--- a/scripts/jobs/integrate/bootstrap
+++ b/scripts/jobs/integrate/bootstrap
@@ -3,7 +3,7 @@
# Script Overview
# - determine scala version
# - determine module versions
-# - build minimal core (aka locker) of Scala, use the determined version number, publish to scala-release-temp
+# - build minimal core (aka locker) of Scala, use the determined version number, publish to scala-integration
# - build those modules where a binary compatible version doesn't exist, publish to scala-integration
# - build Scala using the previously built core and bootstrap modules, publish to scala-integration
# - for releases
@@ -98,15 +98,10 @@ mkdir -p $baseDir/ivy2
rm -rf $baseDir/resolutionScratch_
mkdir -p $baseDir/resolutionScratch_
-# repo for the starr and locker builds
-releaseTempRepoUrl=${releaseTempRepoUrl-"https://scala-ci.typesafe.com/artifactory/scala-release-temp/"}
-# repo for the modules and the quick build
+# repo to publish builds
integrationRepoUrl=${integrationRepoUrl-"https://scala-ci.typesafe.com/artifactory/scala-integration/"}
-# the `releaseTempRepoUrl` needs to be in the repositories file to get starr when building quick and the modules.
-# `integrationRepoUrl` is there to find modules when building quick and other modules (e.g., partest requires xml).
-# the file is re-generated for running the stability test, this time with only `integrationRepoUrl`.
-generateRepositoriesConfig $releaseTempRepoUrl $integrationRepoUrl
+generateRepositoriesConfig $integrationRepoUrl
# ARGH trying to get this to work on multiple versions of sbt-extras...
# the old version (on jenkins, and I don't want to upgrade for risk of breaking other builds) honors -sbt-dir
@@ -413,7 +408,7 @@ bootstrap() {
git clone --reference $WORKSPACE/.git $WORKSPACE/.git $STARR_DIR
cd $STARR_DIR
git co $STARR_REF
- $SBT_CMD -no-colors $sbtArgs --warn "setupBootstrapStarr $releaseTempRepoUrl $STARR_VER" $clean publish >> $baseDir/logs/builds 2>&1
+ $SBT_CMD -no-colors $sbtArgs --warn "setupBootstrapStarr $integrationRepoUrl $STARR_VER" $clean publish >> $baseDir/logs/builds 2>&1
)
fi
@@ -427,7 +422,7 @@ bootstrap() {
# publish more than just core: partest needs scalap
# in sabbus lingo, the resulting Scala build will be used as starr to build the released Scala compiler
if [ ! -z "$STARR_VER" ]; then SET_STARR=-Dstarr.version=$STARR_VER; fi
- $SBT_CMD -no-colors $sbtArgs $SET_STARR --warn "setupBootstrapLocker $releaseTempRepoUrl $SCALA_VER" $clean publish >> $baseDir/logs/builds 2>&1
+ $SBT_CMD -no-colors $sbtArgs $SET_STARR --warn "setupBootstrapLocker $integrationRepoUrl $SCALA_VER" $clean publish >> $baseDir/logs/builds 2>&1
echo "### Building modules using locker"
@@ -530,13 +525,9 @@ determineScalaVersion
deriveModuleVersions
removeExistingBuilds $integrationRepoUrl
-removeExistingBuilds $releaseTempRepoUrl
bootstrap
-# for stability testing and sonatype publishing, use artifacts in `integrationRepoUrl`
-generateRepositoriesConfig $integrationRepoUrl
-
if [ "$testStability" == "yes" ]
then testStability
fi
diff --git a/spec/04-basic-declarations-and-definitions.md b/spec/04-basic-declarations-and-definitions.md
index 53b34dedc5..c4d3425fff 100644
--- a/spec/04-basic-declarations-and-definitions.md
+++ b/spec/04-basic-declarations-and-definitions.md
@@ -669,6 +669,15 @@ def f(a: Int = 0)(b: Int = a + 1) = b // OK
f(10)() // returns 11 (not 1)
```
+If an [implicit argument](07-implicits.html#implicit-parameters)
+is not found by implicit search, it may be supplied using a default argument.
+
+```scala
+implicit val i: Int = 2
+def f(implicit x: Int, s: String = "hi") = s * x
+f // "hihi"
+```
+
### By-Name Parameters
```ebnf
diff --git a/spec/06-expressions.md b/spec/06-expressions.md
index 48cff1725a..581170c5f9 100644
--- a/spec/06-expressions.md
+++ b/spec/06-expressions.md
@@ -320,7 +320,7 @@ would not typecheck.
### Named and Default Arguments
-If an application might uses named arguments $p = e$ or default
+If an application is to use named arguments $p = e$ or default
arguments, the following conditions must hold.
- For every named argument $p_i = e_i$ which appears left of a positional argument
@@ -330,7 +330,7 @@ arguments, the following conditions must hold.
argument defines a parameter which is already specified by a
positional argument.
- Every formal parameter $p_j:T_j$ which is not specified by either a positional
- or a named argument has a default argument.
+ or named argument has a default argument.
If the application uses named or default
arguments the following transformation is applied to convert it into
diff --git a/src/compiler/scala/tools/nsc/backend/jvm/BCodeBodyBuilder.scala b/src/compiler/scala/tools/nsc/backend/jvm/BCodeBodyBuilder.scala
index 76d042ce3b..37dea477c6 100644
--- a/src/compiler/scala/tools/nsc/backend/jvm/BCodeBodyBuilder.scala
+++ b/src/compiler/scala/tools/nsc/backend/jvm/BCodeBodyBuilder.scala
@@ -1264,14 +1264,22 @@ abstract class BCodeBodyBuilder extends BCodeSkelBuilder {
def genEqEqPrimitive(l: Tree, r: Tree, success: asm.Label, failure: asm.Label, targetIfNoJump: asm.Label, pos: Position) {
/* True if the equality comparison is between values that require the use of the rich equality
- * comparator (scala.runtime.Comparator.equals). This is the case when either side of the
+ * comparator (scala.runtime.BoxesRunTime.equals). This is the case when either side of the
* comparison might have a run-time type subtype of java.lang.Number or java.lang.Character.
- * When it is statically known that both sides are equal and subtypes of Number of Character,
- * not using the rich equality is possible (their own equals method will do ok.)
+ *
+ * When it is statically known that both sides are equal and subtypes of Number or Character,
+ * not using the rich equality is possible (their own equals method will do ok), except for
+ * java.lang.Float and java.lang.Double: their `equals` have different behavior around `NaN`
+ * and `-0.0`, see Javadoc (scala-dev#329).
*/
val mustUseAnyComparator: Boolean = {
- val areSameFinals = l.tpe.isFinalType && r.tpe.isFinalType && (l.tpe =:= r.tpe)
- !areSameFinals && platform.isMaybeBoxed(l.tpe.typeSymbol) && platform.isMaybeBoxed(r.tpe.typeSymbol)
+ platform.isMaybeBoxed(l.tpe.typeSymbol) && platform.isMaybeBoxed(r.tpe.typeSymbol) && {
+ val areSameFinals = l.tpe.isFinalType && r.tpe.isFinalType && (l.tpe =:= r.tpe) && {
+ val sym = l.tpe.typeSymbol
+ sym != BoxedFloatClass && sym != BoxedDoubleClass
+ }
+ !areSameFinals
+ }
}
if (mustUseAnyComparator) {
diff --git a/src/compiler/scala/tools/nsc/reporters/ConsoleReporter.scala b/src/compiler/scala/tools/nsc/reporters/ConsoleReporter.scala
index f1f5f37c36..224de97734 100644
--- a/src/compiler/scala/tools/nsc/reporters/ConsoleReporter.scala
+++ b/src/compiler/scala/tools/nsc/reporters/ConsoleReporter.scala
@@ -77,10 +77,10 @@ class ConsoleReporter(val settings: Settings, reader: BufferedReader, writer: Pr
if (reader != null) {
reader.read match {
case 'a' | 'A' =>
- new Throwable().printStackTrace()
+ new Throwable().printStackTrace(writer)
System.exit(1)
case 's' | 'S' =>
- new Throwable().printStackTrace()
+ new Throwable().printStackTrace(writer)
writer.println()
writer.flush()
case _ =>
diff --git a/src/library/scala/collection/immutable/Map.scala b/src/library/scala/collection/immutable/Map.scala
index cbdf7b39f5..4107b6414d 100644
--- a/src/library/scala/collection/immutable/Map.scala
+++ b/src/library/scala/collection/immutable/Map.scala
@@ -198,7 +198,7 @@ object Map extends ImmutableMapFactory[Map] {
else if (key == key2) new Map4(key1, value1, key2, value, key3, value3, key4, value4)
else if (key == key3) new Map4(key1, value1, key2, value2, key3, value, key4, value4)
else if (key == key4) new Map4(key1, value1, key2, value2, key3, value3, key4, value)
- else new HashMap + ((key1, value1), (key2, value2), (key3, value3), (key4, value4), (key, value))
+ else (new HashMap).updated(key1,value1).updated(key2, value2).updated(key3, value3).updated(key4, value4).updated(key, value)
def + [V1 >: V](kv: (K, V1)): Map[K, V1] = updated(kv._1, kv._2)
def - (key: K): Map[K, V] =
if (key == key1) new Map3(key2, value2, key3, value3, key4, value4)
diff --git a/src/library/scala/collection/immutable/Set.scala b/src/library/scala/collection/immutable/Set.scala
index 047ea736bd..0f16f97cb0 100644
--- a/src/library/scala/collection/immutable/Set.scala
+++ b/src/library/scala/collection/immutable/Set.scala
@@ -193,7 +193,7 @@ object Set extends ImmutableSetFactory[Set] {
elem == elem1 || elem == elem2 || elem == elem3 || elem == elem4
def + (elem: A): Set[A] =
if (contains(elem)) this
- else new HashSet[A] + (elem1, elem2, elem3, elem4, elem)
+ else new HashSet[A] + elem1 + elem2 + elem3 + elem4 + elem
def - (elem: A): Set[A] =
if (elem == elem1) new Set3(elem2, elem3, elem4)
else if (elem == elem2) new Set3(elem1, elem3, elem4)
diff --git a/src/library/scala/collection/mutable/HashMap.scala b/src/library/scala/collection/mutable/HashMap.scala
index 11ff1f0893..de61ebb796 100644
--- a/src/library/scala/collection/mutable/HashMap.scala
+++ b/src/library/scala/collection/mutable/HashMap.scala
@@ -73,10 +73,18 @@ extends AbstractMap[A, B]
}
override def getOrElseUpdate(key: A, defaultValue: => B): B = {
- val i = index(elemHashCode(key))
+ val hash = elemHashCode(key)
+ val i = index(hash)
val entry = findEntry(key, i)
if (entry != null) entry.value
- else addEntry(createNewEntry(key, defaultValue), i)
+ else {
+ val table0 = table
+ val default = defaultValue
+ // Avoid recomputing index if the `defaultValue()` hasn't triggered
+ // a table resize.
+ val newEntryIndex = if (table0 eq table) i else index(hash)
+ addEntry(createNewEntry(key, default), newEntryIndex)
+ }
}
/* inlined HashTable.findEntry0 to preserve its visibility */
diff --git a/src/reflect/scala/reflect/internal/Depth.scala b/src/reflect/scala/reflect/internal/Depth.scala
index a330e0accb..5e7202f8bf 100644
--- a/src/reflect/scala/reflect/internal/Depth.scala
+++ b/src/reflect/scala/reflect/internal/Depth.scala
@@ -5,7 +5,7 @@ package internal
import Depth._
final class Depth private (val depth: Int) extends AnyVal with Ordered[Depth] {
- def max(that: Depth): Depth = if (this < that) that else this
+ def max(that: Depth): Depth = if (this.depth < that.depth) that else this
def decr(n: Int): Depth = if (isAnyDepth) this else Depth(depth - n)
def incr(n: Int): Depth = if (isAnyDepth) this else Depth(depth + n)
def decr: Depth = decr(1)
diff --git a/src/reflect/scala/reflect/internal/TreeInfo.scala b/src/reflect/scala/reflect/internal/TreeInfo.scala
index 1aef30819a..933afbea2b 100644
--- a/src/reflect/scala/reflect/internal/TreeInfo.scala
+++ b/src/reflect/scala/reflect/internal/TreeInfo.scala
@@ -274,6 +274,7 @@ abstract class TreeInfo {
def mayBeVarGetter(sym: Symbol): Boolean = sym.info match {
case NullaryMethodType(_) => sym.owner.isClass && !sym.isStable
case PolyType(_, NullaryMethodType(_)) => sym.owner.isClass && !sym.isStable
+ case PolyType(_, mt @ MethodType(_, _))=> mt.isImplicit && sym.owner.isClass && !sym.isStable
case mt @ MethodType(_, _) => mt.isImplicit && sym.owner.isClass && !sym.isStable
case _ => false
}
diff --git a/src/repl/scala/tools/nsc/interpreter/ILoop.scala b/src/repl/scala/tools/nsc/interpreter/ILoop.scala
index 9635f320fe..8be4d159f1 100644
--- a/src/repl/scala/tools/nsc/interpreter/ILoop.scala
+++ b/src/repl/scala/tools/nsc/interpreter/ILoop.scala
@@ -768,7 +768,7 @@ class ILoop(in0: Option[BufferedReader], protected val out: JPrintWriter)
result
}
- private object paste extends Pasted(prompt) {
+ private object paste extends Pasted(replProps.promptText) {
def interpret(line: String) = intp interpret line
def echo(message: String) = ILoop.this echo message
diff --git a/src/repl/scala/tools/nsc/interpreter/Pasted.scala b/src/repl/scala/tools/nsc/interpreter/Pasted.scala
index 3a7eda1b77..7ab5e5bb42 100644
--- a/src/repl/scala/tools/nsc/interpreter/Pasted.scala
+++ b/src/repl/scala/tools/nsc/interpreter/Pasted.scala
@@ -38,10 +38,9 @@ abstract class Pasted(prompt: String) {
def matchesContinue(line: String) = matchesString(line, ContinueString)
def running = isRunning
- private def matchesString(line: String, target: String): Boolean = (
- (line startsWith target) ||
- (line.nonEmpty && spacey(line.head) && matchesString(line.tail, target))
- )
+ private def matchesString(line: String, target: String): Boolean =
+ line.startsWith(target) || (line.nonEmpty && spacey(line.head) && matchesString(line.tail, target))
+
private def stripString(line: String, target: String) = line indexOf target match {
case -1 => line
case idx => line drop (idx + target.length)
diff --git a/test/benchmarks/src/main/scala/scala/collection/immutable/ListBenchmark.scala b/test/benchmarks/src/main/scala/scala/collection/immutable/ListBenchmark.scala
index 94844dcae2..36e2518993 100644
--- a/test/benchmarks/src/main/scala/scala/collection/immutable/ListBenchmark.scala
+++ b/test/benchmarks/src/main/scala/scala/collection/immutable/ListBenchmark.scala
@@ -23,12 +23,14 @@ class ListBenchmark {
var values: List[Content] = _
var mid: Content = _
var last: Content = _
+ var replacement: Content = _
@Setup(Level.Trial) def initKeys(): Unit = {
values = List.tabulate(size)(v => Content(v))
mid = Content(size / 2)
last = Content(Math.max(0,size -1))
+ replacement = Content(size * 2 + 1)
}
@Benchmark def filter_includeAll: Any = {
@@ -55,18 +57,14 @@ class ListBenchmark {
values.filter(v => v.value == last.value)
}
- @Setup(Level.Trial) def initKeys(): Unit = {
- values = List.tabulate(size)(n => if (n == size / 2) "mid" else "")
- }
-
@Benchmark def mapConserve_identity: Any = {
values.mapConserve(x => x)
}
@Benchmark def mapConserve_modifyAll: Any = {
- values.mapConserve(x => "replace")
+ values.mapConserve(x => replacement)
}
@Benchmark def mapConserve_modifyMid: Any = {
- values.mapConserve(x => if (x == "mid") "replace" else x)
+ values.mapConserve(x => if (x == mid) replacement else x)
}
}
diff --git a/test/benchmarks/src/main/scala/scala/collection/immutable/MapBenchmark.scala b/test/benchmarks/src/main/scala/scala/collection/immutable/MapBenchmark.scala
new file mode 100644
index 0000000000..a0358d6a1a
--- /dev/null
+++ b/test/benchmarks/src/main/scala/scala/collection/immutable/MapBenchmark.scala
@@ -0,0 +1,29 @@
+package scala.collection.immutable
+
+import java.util.concurrent.TimeUnit
+
+import org.openjdk.jmh.annotations._
+import org.openjdk.jmh.infra._
+
+@BenchmarkMode(Array(Mode.AverageTime))
+@Fork(2)
+@Threads(1)
+@Warmup(iterations = 10)
+@Measurement(iterations = 10)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+@State(Scope.Benchmark)
+class MapBenchmark {
+
+ var base: Map[String,String] = _
+
+
+ @Setup(Level.Trial) def initKeys(): Unit = {
+ base = Map("a" -> "a", "b" -> "b", "c" -> "c", "d" -> "d")
+ }
+
+ // immutable map is implemented as EmptyMap -> Map1 -> Map2 -> Map3 -> Map4 -> Hashmap
+ // add an extra entry to Map4 causes a lot of work, benchmark the transition
+ @Benchmark def map4AddElement(bh: Blackhole): Unit = {
+ bh.consume(base.updated("e", "e"))
+ }
+}
diff --git a/test/benchmarks/src/main/scala/scala/collection/immutable/SetBenchmark.scala b/test/benchmarks/src/main/scala/scala/collection/immutable/SetBenchmark.scala
new file mode 100644
index 0000000000..9330626691
--- /dev/null
+++ b/test/benchmarks/src/main/scala/scala/collection/immutable/SetBenchmark.scala
@@ -0,0 +1,29 @@
+package scala.collection.immutable
+
+import java.util.concurrent.TimeUnit
+
+import org.openjdk.jmh.annotations._
+import org.openjdk.jmh.infra._
+
+@BenchmarkMode(Array(Mode.AverageTime))
+@Fork(2)
+@Threads(1)
+@Warmup(iterations = 10)
+@Measurement(iterations = 10)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+@State(Scope.Benchmark)
+class SetBenchmark {
+
+ var base: Set[String] = _
+
+
+ @Setup(Level.Trial) def initKeys(): Unit = {
+ base = Set("a", "b", "c", "d")
+ }
+
+ // immutable map is implemented as EmptySet -> Set1 -> Set2 -> Set3 -> Set4 -> HashSet
+ // add an extra entry to Set4 causes a lot of work, benchmark the transition
+ @Benchmark def set4AddElement(bh: Blackhole): Unit = {
+ bh.consume(base + "e")
+ }
+}
diff --git a/test/files/pos/t4237.scala b/test/files/pos/t4237.scala
index fcf6eb8bf1..3f605607b2 100644
--- a/test/files/pos/t4237.scala
+++ b/test/files/pos/t4237.scala
@@ -2,5 +2,16 @@ class A {
(new { def field = 0; def field_=(i: Int) = () }).field = 5 // compiles as expected
(new { def field(implicit i: Int) = 0; def field_=(i: Int) = () }).field = 5 // compiles even with implicit params on getter
(new { def field = 0; def field_=[T](i: Int) = () }).field = 5 // compiles with type param on setter
- (new { def field[T] = 0; def field_=(i: Int) = () }).field = 5 // DOESN'T COMPILE
-} \ No newline at end of file
+ (new { def field[T] = 0; def field_=(i: Int) = () }).field = 5 // DIDN'T COMPILE
+
+ class Imp
+ implicit val imp: Imp = new Imp
+ implicit val implicitList: List[Int] = null
+
+ // compiles even with implicit params on setter
+ (new { def field(implicit i: Int) = 0; def field_=(i: Int)(implicit j: Imp) = () }).field = 5
+ (new { def field(implicit i: Int) = 0; def field_=[T <: Imp](i: Int)(implicit j: T) = () }).field = 5
+ // was reassignment to val
+ (new { def field[T](implicit ts: List[T]) = 0; def field_=[T](i: Int)(implicit ts: List[T]) = () }).field = 5
+ (new { def field[T](implicit ts: List[T]) = 0; def field_=[T](i: T)(implicit ts: List[T]) = () }).field = 5
+}
diff --git a/test/files/run/number-parsing.scala b/test/files/run/number-parsing.scala
index ad1481063e..5627ee9006 100644
--- a/test/files/run/number-parsing.scala
+++ b/test/files/run/number-parsing.scala
@@ -3,8 +3,8 @@ object Test {
val MinusZero = Float.box(-0.0f)
val PlusZero = Float.box(0.0f)
- assert(PlusZero match { case MinusZero => false ; case _ => true })
- assert(MinusZero match { case PlusZero => false ; case _ => true })
+ assert(PlusZero match { case MinusZero => true ; case _ => false })
+ assert(MinusZero match { case PlusZero => true ; case _ => false })
assert((MinusZero: scala.Float) == (PlusZero: scala.Float))
assert(!(MinusZero equals PlusZero))
diff --git a/test/files/run/sd329.scala b/test/files/run/sd329.scala
new file mode 100644
index 0000000000..c934e2c986
--- /dev/null
+++ b/test/files/run/sd329.scala
@@ -0,0 +1,76 @@
+object Test extends App {
+ def d1: Double = 0.0
+ def d2: Double = -0.0
+ def d3: Double = Double.NaN
+ def d4: Double = Double.NaN
+ assert(d1 == d2)
+ assert(d3 != d4)
+
+ def d1B: java.lang.Double = d1
+ def d2B: java.lang.Double = d2
+ def d3B: java.lang.Double = d3
+ def d4B: java.lang.Double = d4
+ assert(d1B == d2B)
+ assert(d1 == d1B)
+ assert(d1B == d1)
+ assert(d3B != d4B)
+ assert(d3 != d4B)
+ assert(d3B != d4)
+
+ assert(!d1B.equals(d2B)) // ! see javadoc
+ assert( d3B.equals(d4B)) // ! see javadoc
+
+ def d1A: Any = d1
+ def d2A: Any = d2
+ def d3A: Any = d3
+ def d4A: Any = d4
+ assert(d1A == d2A)
+ assert(d1 == d1A)
+ assert(d1A == d1)
+ assert(d1B == d1A)
+ assert(d1A == d1B)
+
+ assert(d3A != d4A)
+ assert(d3 != d4A)
+ assert(d3A != d4)
+ assert(d3B != d4A)
+ assert(d3A != d4B)
+
+
+ def f1: Float = 0.0f
+ def f2: Float = -0.0f
+ def f3: Float = Float.NaN
+ def f4: Float = Float.NaN
+ assert(f1 == f2)
+ assert(f3 != f4)
+
+ def f1B: java.lang.Float = f1
+ def f2B: java.lang.Float = f2
+ def f3B: java.lang.Float = f3
+ def f4B: java.lang.Float = f4
+ assert(f1B == f2B)
+ assert(f1 == f1B)
+ assert(f1B == f1)
+ assert(f3B != f4B)
+ assert(f3 != f4B)
+ assert(f3B != f4)
+
+ assert(!f1B.equals(f2B)) // ! see javadoc
+ assert( f3B.equals(f4B)) // ! see javadoc
+
+ def f1A: Any = f1
+ def f2A: Any = f2
+ def f3A: Any = f3
+ def f4A: Any = f4
+ assert(f1A == f2A)
+ assert(f1 == f1A)
+ assert(f1A == f1)
+ assert(f1B == f1A)
+ assert(f1A == f1B)
+
+ assert(f3A != f4A)
+ assert(f3 != f4A)
+ assert(f3A != f4)
+ assert(f3B != f4A)
+ assert(f3A != f4B)
+}
diff --git a/test/junit/scala/collection/mutable/HashMapTest.scala b/test/junit/scala/collection/mutable/HashMapTest.scala
new file mode 100644
index 0000000000..cc1979a920
--- /dev/null
+++ b/test/junit/scala/collection/mutable/HashMapTest.scala
@@ -0,0 +1,38 @@
+package scala.collection
+package mutable
+
+import org.junit.Assert._
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.JUnit4
+
+@RunWith(classOf[JUnit4])
+class HashMapTest {
+
+ @Test
+ def getOrElseUpdate_mutationInCallback() {
+ val hm = new mutable.HashMap[String, String]()
+ // add enough elements to resize the hash table in the callback
+ def add() = 1 to 100000 foreach (i => hm(i.toString) = "callback")
+ hm.getOrElseUpdate("0", {
+ add()
+ ""
+ })
+ assertEquals(Some(""), hm.get("0"))
+ }
+
+ @Test
+ def getOrElseUpdate_evalOnce(): Unit = {
+ var i = 0
+ val hm = new mutable.HashMap[Int, Int]()
+ hm.getOrElseUpdate(0, {i += 1; i})
+ assertEquals(1, hm(0))
+ }
+
+ @Test
+ def getOrElseUpdate_noEval(): Unit = {
+ val hm = new mutable.HashMap[Int, Int]()
+ hm.put(0, 0)
+ hm.getOrElseUpdate(0, throw new AssertionError())
+ }
+}
diff --git a/test/junit/scala/tools/nsc/reporters/ConsoleReporterTest.scala b/test/junit/scala/tools/nsc/reporters/ConsoleReporterTest.scala
new file mode 100644
index 0000000000..f24e11c9e2
--- /dev/null
+++ b/test/junit/scala/tools/nsc/reporters/ConsoleReporterTest.scala
@@ -0,0 +1,173 @@
+package scala
+package tools.nsc
+package reporters
+
+import java.io.{ByteArrayOutputStream, StringReader, BufferedReader, PrintStream, PrintWriter}
+import org.junit.Assert._
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.JUnit4
+
+import scala.reflect.internal.util._
+
+
+@RunWith(classOf[JUnit4])
+class ConsoleReporterTest {
+ val source = "Test_ConsoleReporter"
+ val batchFile = new BatchSourceFile(source, "For testing".toList)
+ val posWithSource = new OffsetPosition(batchFile, 4)
+ val content = posWithSource.lineContent
+ val writerOut = new ByteArrayOutputStream()
+ val echoWriterOut = new ByteArrayOutputStream()
+
+
+ def createConsoleReporter(inputForReader: String, errOut: ByteArrayOutputStream, echoOut: ByteArrayOutputStream = null): ConsoleReporter = {
+ val reader = new BufferedReader(new StringReader(inputForReader))
+
+ /** Create reporter with the same writer and echoWriter if echoOut is null */
+ echoOut match {
+ case null => new ConsoleReporter(new Settings(), reader, new PrintWriter(errOut))
+ case _ => new ConsoleReporter(new Settings(), reader, new PrintWriter(errOut), new PrintWriter(echoWriterOut))
+ }
+ }
+
+
+ def testHelper(pos: Position = NoPosition, msg: String, severity: String = "")(test: Position => Unit) = {
+ test(pos)
+ if (msg.isEmpty && severity.isEmpty) assertTrue(writerOut.toString.isEmpty)
+ else {
+ if (!pos.isDefined) assertEquals(severity + msg, writerOut.toString.lines.next)
+ else {
+ val it = writerOut.toString.lines
+ assertEquals(source + ":1: " + severity + msg, it.next)
+ assertEquals(content, it.next)
+ assertEquals(" ^", it.next)
+ }
+ }
+ writerOut.reset
+ }
+
+
+ @Test
+ def printMessageTest(): Unit = {
+ val reporter = createConsoleReporter("r", writerOut)
+ testHelper(msg = "Hello World!")(_ => reporter.printMessage("Hello World!"))
+ testHelper(msg = "Testing with NoPosition")(reporter.printMessage(_, "Testing with NoPosition"))
+ testHelper(posWithSource, "Testing with Defined Position")(reporter.printMessage(_, "Testing with Defined Position"))
+ }
+
+
+ @Test
+ def echoTest(): Unit = {
+ val reporter = createConsoleReporter("r", writerOut, echoWriterOut)
+ reporter.echo("Hello World!")
+ assertEquals("Hello World!", echoWriterOut.toString.lines.next)
+
+ /** Check with constructor which has the same writer and echoWriter */
+ val reporter2 = createConsoleReporter("r", writerOut)
+ testHelper(msg = "Hello World!")(_ => reporter2.echo("Hello World!"))
+ }
+
+
+ @Test
+ def printTest(): Unit = {
+ val reporter = createConsoleReporter("r", writerOut)
+ testHelper(msg = "test")(reporter.print(_, "test", reporter.INFO))
+ testHelper(msg = "test", severity = "warning: ")(reporter.print(_, "test", reporter.WARNING))
+ testHelper(msg = "test", severity = "error: ")(reporter.print(_, "test", reporter.ERROR))
+ testHelper(posWithSource, msg = "test")(reporter.print(_, "test", reporter.INFO))
+ testHelper(posWithSource, msg = "test", severity = "warning: ")(reporter.print(_, "test", reporter.WARNING))
+ testHelper(posWithSource, msg = "test", severity = "error: ")(reporter.print(_, "test", reporter.ERROR))
+ }
+
+
+ @Test
+ def printColumnMarkerTest(): Unit = {
+ val reporter = createConsoleReporter("r", writerOut)
+ testHelper(msg = "")(reporter.printColumnMarker(_))
+
+ reporter.printColumnMarker(posWithSource)
+ assertEquals(" ^", writerOut.toString.lines.next)
+ writerOut.reset
+ }
+
+
+ @Test
+ def displayTest(): Unit = {
+ val reporter = createConsoleReporter("r", writerOut)
+
+ /** Change maxerrs and maxwarns from default */
+ reporter.settings.maxerrs.value = 1
+ reporter.settings.maxwarns.value = 1
+
+ testHelper(msg = "Testing display")(reporter.display(_, "Testing display", reporter.INFO))
+ testHelper(msg = "Testing display", severity = "warning: ")(reporter.display(_, "Testing display", reporter.WARNING))
+ testHelper(msg = "Testing display", severity = "error: ")(reporter.display(_, "Testing display", reporter.ERROR))
+ testHelper(posWithSource, msg = "Testing display")(reporter.display(_, "Testing display", reporter.INFO))
+ testHelper(posWithSource, msg = "Testing display", severity = "warning: ")(reporter.display(_, "Testing display", reporter.WARNING))
+ testHelper(posWithSource, msg = "Testing display", severity = "error: ")(reporter.display(_, "Testing display", reporter.ERROR))
+
+ reporter.resetCount(reporter.ERROR)
+ reporter.resetCount(reporter.WARNING)
+
+ reporter.ERROR.count += 1
+ testHelper(posWithSource, msg = "Testing display for maxerrs to pass", severity = "error: ")(reporter.display(_, "Testing display for maxerrs to pass", reporter.ERROR))
+ reporter.ERROR.count += 1
+ testHelper(msg = "")(reporter.display(_, "Testing display for maxerrs to fail", reporter.ERROR))
+
+ reporter.WARNING.count += 1
+ testHelper(posWithSource, msg = "Testing display for maxwarns to pass", severity = "warning: ")(reporter.display(_, "Testing display for maxwarns to pass", reporter.WARNING))
+ reporter.WARNING.count += 1
+ testHelper(msg = "")(reporter.display(_, "Testing display for maxwarns to fail", reporter.WARNING))
+ }
+
+
+ @Test
+ def finishTest(): Unit = {
+ val reporter = createConsoleReporter("r", writerOut)
+
+ reporter.resetCount(reporter.ERROR)
+ reporter.resetCount(reporter.WARNING)
+ testHelper(msg = "")(_ => reporter.finish())
+
+ reporter.ERROR.count = 10
+ reporter.WARNING.count = 3
+ reporter.finish()
+ val it = writerOut.toString.lines
+ assertEquals("three warnings found", it.next)
+ assertEquals("10 errors found", it.next)
+ writerOut.reset
+ }
+
+
+ @Test
+ def displayPromptTest(): Unit = {
+ val output = "a)bort, s)tack, r)esume: "
+
+ /** Check for stack trace */
+ val reporter = createConsoleReporter("s", writerOut, echoWriterOut)
+ reporter.displayPrompt()
+ val it = writerOut.toString.lines
+ assertTrue(it.next.isEmpty)
+ assertEquals(output + "java.lang.Throwable", it.next)
+ assertTrue(it.hasNext)
+
+ /** Check for no stack trace */
+ val writerOut2 = new ByteArrayOutputStream()
+ val reporter2 = createConsoleReporter("w", writerOut2)
+ reporter2.displayPrompt()
+ val it2 = writerOut2.toString.lines
+ assertTrue(it2.next.isEmpty)
+ assertEquals(output, it2.next)
+ assertFalse(it2.hasNext)
+
+ /** Check for no stack trace */
+ val writerOut3 = new ByteArrayOutputStream()
+ val reporter3 = createConsoleReporter("r", writerOut3)
+ reporter3.displayPrompt()
+ val it3 = writerOut3.toString.lines
+ assertTrue(it3.next.isEmpty)
+ assertEquals(output, it3.next)
+ assertFalse(it3.hasNext)
+ }
+}