From f0d28aa4851d7b4195c7d2c8aaf49d6b9eaafd86 Mon Sep 17 00:00:00 2001 From: Blair Zajac Date: Thu, 8 Dec 2011 17:40:41 -0800 Subject: Clarify scala.collection.immutable.Map#withDefaultValue() docs. Copy the documentation from Map#withDefault() that get(), contains(), iterator(), and keys() keys are not affected by withDefaultValue(). --- src/library/scala/collection/immutable/Map.scala | 1 + 1 file changed, 1 insertion(+) diff --git a/src/library/scala/collection/immutable/Map.scala b/src/library/scala/collection/immutable/Map.scala index 45cf088dd9..bbefd983fd 100644 --- a/src/library/scala/collection/immutable/Map.scala +++ b/src/library/scala/collection/immutable/Map.scala @@ -47,6 +47,7 @@ trait Map[A, +B] extends Iterable[(A, B)] def withDefault[B1 >: B](d: A => B1): immutable.Map[A, B1] = new Map.WithDefault[A, B1](this, d) /** The same map with a given default value. + * Note: `get`, `contains`, `iterator`, `keys`, etc are not affected by `withDefaultValue`. * * Invoking transformer methods (e.g. `map`) will not preserve the default value. * -- cgit v1.2.3 From d718a7c7f31afee174958f63d23ede87394a7a4a Mon Sep 17 00:00:00 2001 From: Eugene Burmako Date: Fri, 9 Dec 2011 22:33:01 +0100 Subject: Batch files no longer swallow exit codes Usually scripts like scala.bat and scalac.bat correctly propagate exit codes from underlying Java invocations. However, if you run these scripts as follows: "cmd /c scala ...", then errorlevel gets swallowed. This simple patch fixes the aforementioned problem. Fixes SI-5295, no review. --- src/compiler/scala/tools/ant/templates/tool-windows.tmpl | 1 + test/files/jvm/mkLibNatives.bat | 2 +- test/partest.bat | 1 + 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/compiler/scala/tools/ant/templates/tool-windows.tmpl b/src/compiler/scala/tools/ant/templates/tool-windows.tmpl index c59d46683e..9f1fbc4524 100644 --- a/src/compiler/scala/tools/ant/templates/tool-windows.tmpl +++ b/src/compiler/scala/tools/ant/templates/tool-windows.tmpl @@ -86,3 +86,4 @@ goto :eof :end @@endlocal +exit /b %errorlevel% diff --git a/test/files/jvm/mkLibNatives.bat b/test/files/jvm/mkLibNatives.bat index e11b6ee21c..2f99f7aab5 100755 --- a/test/files/jvm/mkLibNatives.bat +++ b/test/files/jvm/mkLibNatives.bat @@ -67,4 +67,4 @@ goto end :end if "%OS%"=="Windows_NT" @endlocal - +exit /b %errorlevel% diff --git a/test/partest.bat b/test/partest.bat index 0b3f5fbf33..4c97a53122 100755 --- a/test/partest.bat +++ b/test/partest.bat @@ -101,3 +101,4 @@ goto end :end if "%OS%"=="Windows_NT" @endlocal +exit /b %errorlevel% -- cgit v1.2.3 From 7d2db571b41f3c23e91ad27ee5b81a421f312e00 Mon Sep 17 00:00:00 2001 From: Paul Phillips Date: Fri, 9 Dec 2011 20:45:52 -0800 Subject: Hardening get-scala-version. Reimplementing without git-describe to harden against old gits and make any kind of reference tag unnecessary. Conflicts: tools/get-scala-revision --- tools/get-scala-revision | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100755 tools/get-scala-revision diff --git a/tools/get-scala-revision b/tools/get-scala-revision new file mode 100755 index 0000000000..dc0ee561dd --- /dev/null +++ b/tools/get-scala-revision @@ -0,0 +1,22 @@ +#!/usr/bin/env bash +# +# Usage: get-scala-revision [dir] +# Figures out current scala revision of a git clone. +# +# If no dir is given, current working dir is used. + +# not like releases come out so often that we are duty-bound +# to recalculate this every time. +# git merge-base v2.9.1 master +devbase="d6f3184fc8" + +# reimplementing git describe hopefully in a way which works +# without any particular tags, branches, or recent versions of git. +# this is supposed to generate +# dev-NNNN-g +# where NNNN is the number of commits since devbase, which +# is the merge-base of the most recent release and master. +# Presently hardcoded to reduce uncertainty, v2.9.1/master. +commits=$(GIT_PAGER=cat git log --oneline $devbase..HEAD | wc -l) +sha=$(git log -1 --abbrev-commit --abbrev=7 --format="%h") +printf "dev-%s-g%s\n" $commits $sha -- cgit v1.2.3 From 9437b3528cdc5a9ab30d456ad2dedf0e802503bc Mon Sep 17 00:00:00 2001 From: Eugene Burmako Date: Mon, 12 Dec 2011 20:36:47 +0100 Subject: typeParams now performs one more completion When tracking a problem in type inference during reflective compilation, Martin and I have discovered that under certain circumstances typeParams does not fully load the type. During a debugging session we found out that info first had the type of TopLevelCompleter, and after the load it was still not completed, having the type of UnPickler$something$LazyTypeRef. After that discovery it became apparent that typeParams need to behave similarly to the info getter - allow for two completions, not just one. Review by @odersky, @adriaanm. --- src/compiler/scala/reflect/internal/Symbols.scala | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/compiler/scala/reflect/internal/Symbols.scala b/src/compiler/scala/reflect/internal/Symbols.scala index 75fd733e7e..bc0c81a54b 100644 --- a/src/compiler/scala/reflect/internal/Symbols.scala +++ b/src/compiler/scala/reflect/internal/Symbols.scala @@ -1097,6 +1097,10 @@ trait Symbols extends api.Symbols { self: SymbolTable => def typeParams: List[Symbol] = if (isMonomorphicType) Nil else { + // analogously to the "info" getter, here we allow for two completions: + // one: sourceCompleter to LazyType, two: LazyType to completed type + if (validTo == NoPeriod) + atPhase(phaseOf(infos.validFrom))(rawInfo load this) if (validTo == NoPeriod) atPhase(phaseOf(infos.validFrom))(rawInfo load this) -- cgit v1.2.3 From a348cc3f8310bee4b3053412106ecbc21718cc83 Mon Sep 17 00:00:00 2001 From: Paul Phillips Date: Fri, 9 Dec 2011 21:33:13 -0800 Subject: More on get-scala-revision. Now that I've resorted to building git 1.5.4, I can stop trying to reverse engineer it through jenkins. This implementation feels winnerish. --- tools/get-scala-revision | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tools/get-scala-revision b/tools/get-scala-revision index dc0ee561dd..3977a61040 100755 --- a/tools/get-scala-revision +++ b/tools/get-scala-revision @@ -17,6 +17,6 @@ devbase="d6f3184fc8" # where NNNN is the number of commits since devbase, which # is the merge-base of the most recent release and master. # Presently hardcoded to reduce uncertainty, v2.9.1/master. -commits=$(GIT_PAGER=cat git log --oneline $devbase..HEAD | wc -l) -sha=$(git log -1 --abbrev-commit --abbrev=7 --format="%h") -printf "dev-%s-g%s\n" $commits $sha +commits=$(git --no-pager log --pretty=oneline $devbase..HEAD | wc -l) +sha=$(git rev-list -n 1 HEAD) +printf "dev-%s-g%s\n" $commits ${sha:0:7} -- cgit v1.2.3 From 3a3832700f1a61477931fac730200510ffa6bbb1 Mon Sep 17 00:00:00 2001 From: Paul Phillips Date: Mon, 12 Dec 2011 12:56:23 -0800 Subject: Tweaking build string some more. Reintroduced date and an "r" to meet IDE needs. Moved reference commit backward to accomodate 2.8.x. Merging changes into 2.8.x, 2.9.x, and master. --- tools/get-scala-revision | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/tools/get-scala-revision b/tools/get-scala-revision index 3977a61040..b27b6ddc82 100755 --- a/tools/get-scala-revision +++ b/tools/get-scala-revision @@ -7,8 +7,8 @@ # not like releases come out so often that we are duty-bound # to recalculate this every time. -# git merge-base v2.9.1 master -devbase="d6f3184fc8" +# git merge-base v2.8.2 v2.9.1 master +devbase="df13e31bbb" # reimplementing git describe hopefully in a way which works # without any particular tags, branches, or recent versions of git. @@ -16,7 +16,9 @@ devbase="d6f3184fc8" # dev-NNNN-g # where NNNN is the number of commits since devbase, which # is the merge-base of the most recent release and master. -# Presently hardcoded to reduce uncertainty, v2.9.1/master. +# Presently hardcoded to reduce uncertainty, v2.8.2/v2.9.1/master. commits=$(git --no-pager log --pretty=oneline $devbase..HEAD | wc -l) sha=$(git rev-list -n 1 HEAD) -printf "dev-%s-g%s\n" $commits ${sha:0:7} +datestr=$(date "+%Y-%m-%d") + +printf "rdev-%s-%s-g%s\n" $commits $datestr ${sha:0:7} -- cgit v1.2.3 From 4cfc633fc6cb2ab0f473c2e5141724017d444dc6 Mon Sep 17 00:00:00 2001 From: Paul Phillips Date: Mon, 12 Dec 2011 06:40:18 -0800 Subject: Range.foreach optimization. This makes code like 0 to 100 foreach (x += _) as fast as (often faster than, in fact) a while loop. See the comment in Range for the gory details. More investigation should be done regarding total impact on inlining behavior. Review by @odersky. --- src/library/scala/collection/immutable/Range.scala | 89 +++++++++++++++++++--- .../scala/collection/immutable/range-bench.scala | 61 +++++++++++++++ 2 files changed, 138 insertions(+), 12 deletions(-) create mode 100644 test/benchmarks/src/scala/collection/immutable/range-bench.scala diff --git a/src/library/scala/collection/immutable/Range.scala b/src/library/scala/collection/immutable/Range.scala index e891f8bec8..16d7e68dee 100644 --- a/src/library/scala/collection/immutable/Range.scala +++ b/src/library/scala/collection/immutable/Range.scala @@ -71,18 +71,6 @@ extends collection.AbstractSeq[Int] def isInclusive = false - @inline final override def foreach[@specialized(Unit) U](f: Int => U) { - if (length > 0) { - val last = this.last - var i = start - while (i != last) { - f(i) - i += step - } - f(i) - } - } - override def length: Int = numRangeElements override lazy val last: Int = if (length == 0) Nil.last @@ -95,6 +83,83 @@ extends collection.AbstractSeq[Int] if (idx < 0 || idx >= length) throw new IndexOutOfBoundsException(idx.toString) locationAfterN(idx) } + + /** @note Making foreach run as fast as a while loop is a challenge. + * The key elements which I can observe making a difference are: + * + * - the inner loop should be as small as possible + * - the inner loop should be monomorphic + * - the inner loop should perform no boxing and no avoidable tests + * + * This is achieved by: + * + * - keeping initialization logic out of the inner loop + * - dispatching to custom variations based on initial conditions + * - tricking the compiler into always calling Function1#apply$mcVI$sp + * + * The last one is important and less than obvious. Even when foreach + * was specialized on Unit, only Int => Unit arguments benefited from it. + * Other function types would be accepted, but in the absence of full + * specialization the integer argument was boxed on every call. For example: + * + class A { + final def f(x: Int): Int = x + 1 + // Calls Range.foreach, which calls Function1.apply + def g1 = 1 until 100 foreach { x => f(x) } + // Calls Range.foreach$mVc$sp, which calls Function1.apply$mcVI$sp + def g2 = 1 until 100 foreach { x => f(x) ; () } + } + * + * However! Since the result of the closure is always discarded, we + * simply cast it to Int => Unit, thereby executing the fast version. + * The seemingly looming ClassCastException can never arrive. + */ + @inline final override def foreach[U](f: Int => U) { + if (step < 0) { + if (isInclusive) foreachDownIn(f.asInstanceOf[Int => Unit]) + else foreachDownEx(f.asInstanceOf[Int => Unit]) + } + else { + if (isInclusive) foreachUpIn(f.asInstanceOf[Int => Unit]) + else foreachUpEx(f.asInstanceOf[Int => Unit]) + } + } + + /** !!! These methods must be public or they will not be inlined. + * But they are certainly not intended to be part of the API. + * This collision between inlining requirements and access semantics + * is highly unfortunate and must be resolved. + * + * Proposed band-aid: an @internal annotation. + */ + @inline final def foreachDownIn(f: Int => Unit) { + var i = start + while (i >= end) { + f(i) + i += step + } + } + @inline final def foreachUpIn(f: Int => Unit) { + var i = start + while (i <= end) { + f(i) + i += step + } + } + @inline final def foreachDownEx(f: Int => Unit) { + var i = start + while (i > end) { + f(i) + i += step + } + } + @inline final def foreachUpEx(f: Int => Unit) { + var i = start + while (i < end) { + f(i) + i += step + } + } /** Creates a new range containing the first `n` elements of this range. * diff --git a/test/benchmarks/src/scala/collection/immutable/range-bench.scala b/test/benchmarks/src/scala/collection/immutable/range-bench.scala new file mode 100644 index 0000000000..e167ff04e8 --- /dev/null +++ b/test/benchmarks/src/scala/collection/immutable/range-bench.scala @@ -0,0 +1,61 @@ +package scala.collection.immutable +package benchmarks + +object RangeTest { + // not inlined any more, needs investigation + // + // class XXS { + // private val array = Array.range(0, 100) + // def tst = { var sum = 0; for (i <- 0 until array.length) sum += array(i); sum } + // } + + var x: Int = 0 + + def foreachSum(max: Int): Int = { + var sum = 0 + 1 to max foreach (sum += _) + sum + } + def whileSum(max: Int) = { + var sum = 0 + var num = 1 + while (num <= max) { + sum += num + num += 1 + } + sum + } + + def show(max: Int, foreachNanos: Long, whileNanos: Long) { + val winner = if (foreachNanos < whileNanos) "foreachSum" else "whileSum" + val ratio = if (foreachNanos < whileNanos) foreachNanos.toDouble / whileNanos else whileNanos.toDouble / foreachNanos + println("1 to %d:, %12s wins, %.3f: foreach %.3f while %.3f".format( + max, winner, ratio, + foreachNanos.toDouble / 1000000L, + whileNanos.toDouble / 1000000L) + ) + } + + def run(max: Int) = { + val foreachFirst = util.Random.nextBoolean + val t1 = System.nanoTime + x = if (foreachFirst) foreachSum(max) else whileSum(max) + val t2 = System.nanoTime + x = if (foreachFirst) whileSum(max) else foreachSum(max) + val t3 = System.nanoTime + + val foreachNanos = if (foreachFirst) t2 - t1 else t3 - t2 + val whileNanos = if (foreachFirst) t3 - t2 else t2 - t1 + show(max, foreachNanos, whileNanos) + } + + def main(args: Array[String]): Unit = { + var max = if (args.isEmpty) 100 else args(0).toInt + while (max > 0) { + run(max) + run(max) + run(max) + max += (max / 7) + } + } +} -- cgit v1.2.3 From 23687eb2e2e4b7e0e8f4b5386320c539664e3542 Mon Sep 17 00:00:00 2001 From: Paul Phillips Date: Mon, 12 Dec 2011 13:11:53 -0800 Subject: Added cast to ParRange. To get the same benefit as in Range. Review by @prokpec. --- src/library/scala/collection/parallel/immutable/ParRange.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/library/scala/collection/parallel/immutable/ParRange.scala b/src/library/scala/collection/parallel/immutable/ParRange.scala index 2a10458457..350e64739f 100644 --- a/src/library/scala/collection/parallel/immutable/ParRange.scala +++ b/src/library/scala/collection/parallel/immutable/ParRange.scala @@ -88,7 +88,7 @@ self => /* accessors */ override def foreach[U](f: Int => U): Unit = { - rangeleft.foreach(f) + rangeleft.foreach(f.asInstanceOf[Int => Unit]) ind = len } -- cgit v1.2.3 From 5c7086b3c89ef5b7483bf5750b31dd76ab8b0cee Mon Sep 17 00:00:00 2001 From: Paul Phillips Date: Mon, 12 Dec 2011 13:25:39 -0800 Subject: More build.xml massaging. Backporting auto starr download to 2.8.x and 2.9.x build.xmls. Trying to get build strings consistent. --- build.xml | 46 ++++++++++++++++++++++++++++---------------- tools/get-scala-revision.bat | 22 +++++++++++++++++++++ 2 files changed, 51 insertions(+), 17 deletions(-) create mode 100644 tools/get-scala-revision.bat diff --git a/build.xml b/build.xml index 47e5a679ca..c18da4820d 100644 --- a/build.xml +++ b/build.xml @@ -192,13 +192,22 @@ PROPERTIES INITIALISATION ============================================================================ --> - + + + + + + + + + + + - - + @@ -212,24 +221,27 @@ INITIALISATION - - - - - + + + + + - + + - - - + value="${version.major}.${version.minor}.${version.patch}.${git.describe}"/> + + + + + + + + + diff --git a/tools/get-scala-revision.bat b/tools/get-scala-revision.bat new file mode 100644 index 0000000000..f4dc24b71f --- /dev/null +++ b/tools/get-scala-revision.bat @@ -0,0 +1,22 @@ +@echo off +rem +rem Usage: get-scala-revison.bat [dir] +rem Figures out current scala revision of a git clone. +rem +rem If no dir is given, current working dir is used. + +@setlocal +set _DIR= +if "%*"=="" ( + for /f "delims=;" %%i in ('cd') do set "_DIR=%%i" +) else ( + set "_DIR=%~1" +) +cd %_DIR% + +if exist .git\NUL ( + git describe HEAD --abbrev=7 --match dev +) + +:end +@endlocal -- cgit v1.2.3 From 5aebaac08a0debfdc366330937e3a8ecf6892f78 Mon Sep 17 00:00:00 2001 From: Paul Phillips Date: Mon, 12 Dec 2011 23:17:23 -0800 Subject: Test case closes SI-4273. --- test/files/pos/t4273.scala | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 test/files/pos/t4273.scala diff --git a/test/files/pos/t4273.scala b/test/files/pos/t4273.scala new file mode 100644 index 0000000000..9a942e8325 --- /dev/null +++ b/test/files/pos/t4273.scala @@ -0,0 +1,8 @@ +class A { + implicit def compareComparables[T](x: T)(implicit ord: Ordering[T]) = new ord.Ops(x) + + class Bippy + implicit val bippyOrdering = new Ordering[Bippy] { def compare(x: Bippy, y: Bippy) = util.Random.nextInt } + + (new Bippy) < (new Bippy) +} \ No newline at end of file -- cgit v1.2.3 From 177baffa6133a5f3e1308f6e3f1306cfa4804ce0 Mon Sep 17 00:00:00 2001 From: Paul Phillips Date: Mon, 12 Dec 2011 23:21:24 -0800 Subject: Test case closes SI-4063. --- test/files/pos/t4063.scala | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 test/files/pos/t4063.scala diff --git a/test/files/pos/t4063.scala b/test/files/pos/t4063.scala new file mode 100644 index 0000000000..5e19c42edc --- /dev/null +++ b/test/files/pos/t4063.scala @@ -0,0 +1,39 @@ +trait Parallel +trait Parallelizable[+ParRepr <: Parallel] + +trait PIterableLike[+T, +Repr <: Parallel] extends Parallel with Parallelizable[PIterableLike[T, Repr]] + +trait PMap[K, V] extends PIterableLike[(K, V), PMap[K, V]] +trait PSet[T] extends PIterableLike[T, PSet[T]] + +trait CIterableLike[+T, +Repr] + +trait CSet[T] extends CIterableLike[T, CSet[T]] with Parallelizable[PSet[T]] + +trait CMap[K, V] extends CIterableLike[(K, V), CMap[K, V]] with Parallelizable[PMap[K, V]] + +object Test { + var x = 0 + + def main() { + val map: CMap[Int, CSet[Int]] = new CMap[Int, CSet[Int]] {} + val set: CSet[Int] = new CSet[Int] {} + + // should infer type argument + //map.synchronized[CIterableLike[Any, Any] with Parallelizable[PIterableLike[Any, Parallel with Parallelizable[Parallel]]]] { + // or: + //map.synchronized[CIterableLike[Any, Any] with Parallelizable[PIterableLike[Any, Parallel]]] { + // or, maybe it could also infer existential types: + //map.synchronized[CIterableLike[Any, _] with Parallelizable[PIterableLike[Any, _]]] { + + map.synchronized { + if (x == 0) { + map + } else { + set + } + } + + } +} + -- cgit v1.2.3 From 53a1a578e1237296d45cd34b363e229d60f50fa7 Mon Sep 17 00:00:00 2001 From: Paul Phillips Date: Mon, 12 Dec 2011 11:33:20 -0800 Subject: Faster char2uescape. No StringBuilder, no closure, no toHexString, no string concatenation, no unnecessary math, no call to reverse, only the necessary allocation. --- src/compiler/scala/reflect/internal/Chars.scala | 36 ++++++++++++++----------- 1 file changed, 20 insertions(+), 16 deletions(-) diff --git a/src/compiler/scala/reflect/internal/Chars.scala b/src/compiler/scala/reflect/internal/Chars.scala index 7bd37618ed..f2c90a6721 100644 --- a/src/compiler/scala/reflect/internal/Chars.scala +++ b/src/compiler/scala/reflect/internal/Chars.scala @@ -21,27 +21,31 @@ trait Chars { final val SU = '\u001A' /** Convert a character digit to an Int according to given base, - * -1 if no success */ + * -1 if no success + */ def digit2int(ch: Char, base: Int): Int = { - if ('0' <= ch && ch <= '9' && ch < '0' + base) - ch - '0' - else if ('A' <= ch && ch < 'A' + base - 10) - ch - 'A' + 10 - else if ('a' <= ch && ch < 'a' + base - 10) - ch - 'a' + 10 - else - -1 + val num = ( + if (ch <= '9') ch - '0' + else if ('a' <= ch && ch <= 'z') ch - 'a' + 10 + else if ('A' <= ch && ch <= 'Z') ch - 'A' + 10 + else -1 + ) + if (0 <= num && num < base) num else -1 } + /** Buffer for creating '\ u XXXX' strings. */ + private[this] val char2uescapeArray = Array[Char]('\\', 'u', 0, 0, 0, 0) /** Convert a character to a backslash-u escape */ def char2uescape(c: Char): String = { - var rest = c.toInt - val buf = new StringBuilder - for (i <- 1 to 4) { - buf ++= (rest % 16).toHexString - rest = rest / 16 - } - "\\u" + buf.toString.reverse + @inline def hexChar(ch: Int): Char = + ( if (ch < 10) '0' else 'A' - 10 ) + ch toChar + + char2uescapeArray(2) = hexChar((c >> 12) ) + char2uescapeArray(3) = hexChar((c >> 8) % 16) + char2uescapeArray(4) = hexChar((c >> 4) % 16) + char2uescapeArray(5) = hexChar((c ) % 16) + + new String(char2uescapeArray) } /** Is character a line break? */ -- cgit v1.2.3 From 6912ff828db28a4277ab78fea8266f2904bc2a6b Mon Sep 17 00:00:00 2001 From: Paul Phillips Date: Mon, 12 Dec 2011 23:59:05 -0800 Subject: Fix for seq/array varargs crasher. Closes SI-4024. --- src/compiler/scala/tools/nsc/transform/UnCurry.scala | 4 +++- test/files/run/t4024.scala | 11 +++++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/src/compiler/scala/tools/nsc/transform/UnCurry.scala b/src/compiler/scala/tools/nsc/transform/UnCurry.scala index 91ac00d946..f319abd060 100644 --- a/src/compiler/scala/tools/nsc/transform/UnCurry.scala +++ b/src/compiler/scala/tools/nsc/transform/UnCurry.scala @@ -374,7 +374,9 @@ abstract class UnCurry extends InfoTransform assert(toArraySym != NoSymbol) def getManifest(tp: Type): Tree = { val manifestOpt = localTyper.findManifest(tp, false) - if (!manifestOpt.tree.isEmpty) manifestOpt.tree + // Don't want bottom types getting any further than this (SI-4024) + if (tp.typeSymbol.isBottomClass) getManifest(AnyClass.tpe) + else if (!manifestOpt.tree.isEmpty) manifestOpt.tree else if (tp.bounds.hi ne tp) getManifest(tp.bounds.hi) else localTyper.getManifestTree(tree.pos, tp, false) } diff --git a/test/files/run/t4024.scala b/test/files/run/t4024.scala index ef768beb99..7c62a3fc6e 100644 --- a/test/files/run/t4024.scala +++ b/test/files/run/t4024.scala @@ -5,5 +5,16 @@ object Test extends App { val m = x.getClass.getMethod("toString") assert(m.invoke(x, (Nil: List[AnyRef]): _*) == "abc") + + Test2.main(Array()) } + +object Test2 { + def main(args: Array[String]): Unit = { + val x = "abc" + val m = x.getClass.getMethod("toString") + m.invoke(x, Nil: _*) + m.invoke(x, Seq(): _*) + } +} -- cgit v1.2.3 From 182e6947c6bd27cf66e435292df2858609139782 Mon Sep 17 00:00:00 2001 From: Josh Suereth Date: Wed, 14 Dec 2011 13:51:55 -0500 Subject: Improved error output. * One SHA resolve, now outputs lots of stack traces if parallel execution failure. --- project/ShaResolve.scala | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/project/ShaResolve.scala b/project/ShaResolve.scala index c6034bbf01..82139ee591 100644 --- a/project/ShaResolve.scala +++ b/project/ShaResolve.scala @@ -4,7 +4,7 @@ import Build._ import Keys._ import Project.Initialize import scala.collection.{ mutable, immutable } - +import scala.collection.parallel.CompositeThrowable @@ -22,7 +22,7 @@ object ShaResolve { pullBinaryLibs in ThisBuild <<= (baseDirectory, binaryLibCache, streams) map resolveLibs ) - def resolveLibs(dir: File, cacheDir: File, s: TaskStreams): Unit = { + def resolveLibs(dir: File, cacheDir: File, s: TaskStreams): Unit = loggingParallelExceptions(s) { val files = (dir / "test" / "files" ** "*.desired.sha1") +++ (dir / "lib" ** "*.desired.sha1") for { (file, name) <- (files x relativeTo(dir)).par @@ -33,6 +33,13 @@ object ShaResolve { } pullFile(jar, sha + "/" + uri, cacheDir, s) } + @inline final def loggingParallelExceptions[U](s: TaskStreams)(f: => U): U = try f catch { + case t: CompositeThrowable => + s.log.error("Error during parallel execution, GET READ FOR STACK TRACES!!") + t.throwables foreach (t2 => s.log.trace(t2)) + throw t + } + def getShaFromShafile(file: File): String = (IO read file split "\\s" headOption) getOrElse error("No SHA found for " + file) -- cgit v1.2.3 From 249be0ce81c89302b06aa3ed6444aa5bd55659db Mon Sep 17 00:00:00 2001 From: Josh Suereth Date: Wed, 14 Dec 2011 16:58:11 -0500 Subject: Fixes windows issues. --- project/ShaResolve.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/project/ShaResolve.scala b/project/ShaResolve.scala index 82139ee591..5cc99fd9cf 100644 --- a/project/ShaResolve.scala +++ b/project/ShaResolve.scala @@ -26,7 +26,7 @@ object ShaResolve { val files = (dir / "test" / "files" ** "*.desired.sha1") +++ (dir / "lib" ** "*.desired.sha1") for { (file, name) <- (files x relativeTo(dir)).par - uri = name.dropRight(13) + uri = name.dropRight(13).replace('\\', '/') jar = dir / uri if !jar.exists || !isValidSha(file) sha = getShaFromShafile(file) -- cgit v1.2.3