summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala61
-rw-r--r--src/compiler/scala/tools/nsc/interactive/CompilerControl.scala26
-rw-r--r--src/compiler/scala/tools/nsc/interactive/Global.scala34
-rw-r--r--src/compiler/scala/tools/nsc/interactive/PresentationCompilerThread.scala1
-rw-r--r--src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala2
-rw-r--r--src/compiler/scala/tools/nsc/transform/Erasure.scala83
-rw-r--r--src/compiler/scala/tools/nsc/transform/Mixin.scala2
-rw-r--r--src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala37
-rw-r--r--src/library/scala/collection/CustomParallelizable.scala18
-rw-r--r--src/library/scala/collection/Parallelizable.scala33
-rw-r--r--src/library/scala/collection/mutable/StringBuilder.scala12
-rw-r--r--src/library/scala/collection/parallel/Tasks.scala70
-rw-r--r--src/library/scala/concurrent/FutureTaskRunner.scala12
-rw-r--r--src/library/scala/concurrent/MailBox.scala6
-rw-r--r--src/library/scala/concurrent/TIMEOUT.scala1
-rw-r--r--src/library/scala/concurrent/ops.scala24
-rw-r--r--src/library/scala/concurrent/package.scala.disabled108
-rw-r--r--src/library/scala/concurrent/pilib.scala1
-rw-r--r--src/library/scala/parallel/package.scala.disabled (renamed from src/library/scala/parallel/package.scala)44
-rw-r--r--src/partest/scala/tools/partest/ReplTest.scala42
-rw-r--r--test/files/pos/hkarray.flags1
-rw-r--r--test/files/pos/hkarray.scala5
-rw-r--r--test/files/pos/javaReadsSigs/fromjava.java16
-rw-r--r--test/files/pos/switchUnbox-pos.log2
-rw-r--r--test/files/run/bug4291.check4
-rw-r--r--test/files/run/bug4291.scala10
-rw-r--r--test/files/run/sigtp.check7
-rw-r--r--test/files/run/t3857.check2
-rw-r--r--test/files/run/t3857.scala17
-rw-r--r--test/files/run/testblock.scala33
-rw-r--r--test/files/run/testpar.scala24
-rw-r--r--test/files/specialized/td3651.check2
-rw-r--r--test/files/specialized/td3651.scala19
-rw-r--r--test/pending/run/bug4291.check87
-rw-r--r--test/pending/run/bug4291.scala19
-rw-r--r--test/pending/run/sigtp.check11
-rw-r--r--test/pending/run/sigtp.scala (renamed from test/files/run/sigtp.scala)11
-rw-r--r--test/pending/run/t3857.check11
-rw-r--r--test/pending/run/t3857.scala13
39 files changed, 625 insertions, 286 deletions
diff --git a/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala b/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala
index b8aa8d7a8f..2305e22ed2 100644
--- a/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala
+++ b/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala
@@ -549,7 +549,7 @@ abstract class GenJVM extends SubComponent with GenJVMUtil with GenAndroid {
// @M don't generate java generics sigs for (members of) implementation
// classes, as they are monomorphic (TODO: ok?)
- private def noGenericSignature(sym: Symbol) = (
+ private def needsGenericSignature(sym: Symbol) = !(
// PP: This condition used to include sym.hasExpandedName, but this leads
// to the total loss of generic information if a private member is
// accessed from a closure: both the field and the accessor were generated
@@ -558,11 +558,11 @@ abstract class GenJVM extends SubComponent with GenJVMUtil with GenAndroid {
// unrelated change.
sym.isSynthetic
|| sym.isLiftedMethod
+ || sym.isBridge
|| (sym.ownerChain exists (_.isImplClass))
)
def addGenericSignature(jmember: JMember, sym: Symbol, owner: Symbol) {
- if (noGenericSignature(sym)) ()
- else {
+ if (needsGenericSignature(sym)) {
val memberTpe = atPhase(currentRun.erasurePhase)(owner.thisType.memberInfo(sym))
// println("addGenericSignature sym: " + sym.fullName + " : " + memberTpe + " sym.info: " + sym.info)
// println("addGenericSignature: "+ (sym.ownerChain map (x => (x.name, x.isImplClass))))
@@ -572,34 +572,37 @@ abstract class GenJVM extends SubComponent with GenJVMUtil with GenAndroid {
* in which case we treat every signature as valid. Medium term we
* should certainly write independent signature validation.
*/
- if (SigParser.isParserAvailable && isValidSignature(sym, sig)) {
+ if (SigParser.isParserAvailable && !isValidSignature(sym, sig)) {
+ clasz.cunit.warning(sym.pos,
+ """|compiler bug: created invalid generic signature for %s in %s
+ |signature: %s
+ |if this is reproducible, please report bug at http://lampsvn.epfl.ch/trac/scala
+ """.trim.stripMargin.format(sym, sym.owner.skipPackageObject.fullName, sig))
+ return
+ }
+ if ((settings.check.value contains "genjvm")) {
val normalizedTpe = atPhase(currentRun.erasurePhase)(erasure.prepareSigMap(memberTpe))
val bytecodeTpe = owner.thisType.memberInfo(sym)
- if (sym.isType || (erasure.erasure(normalizedTpe) =:= bytecodeTpe)) {
- val index = jmember.getConstantPool.addUtf8(sig).toShort
- if (opt.verboseDebug)
- atPhase(currentRun.erasurePhase) {
- println("add generic sig "+sym+":"+sym.info+" ==> "+sig+" @ "+index)
- }
- val buf = ByteBuffer.allocate(2)
- buf putShort index
- addAttribute(jmember, tpnme.SignatureATTR, buf)
- } else {
- if (sym.hasFlag(Flags.MIXEDIN))
- ()// println("suppressing signature for mixedin "+sym)
- else
- clasz.cunit.warning(sym.pos,
- """|compiler bug: created generic signature for %s in %s that does not conform to its erasure
- |signature: %s
- |erasure type: %s
- |if this is reproducible, please report bug at http://lampsvn.epfl.ch/trac/scala
- """.trim.stripMargin.format(sym, sym.owner.skipPackageObject.fullName, sig, bytecodeTpe))
+ if (!sym.isType && !sym.isConstructor && !(erasure.erasure(normalizedTpe) =:= bytecodeTpe)) {
+ clasz.cunit.warning(sym.pos,
+ """|compiler bug: created generic signature for %s in %s that does not conform to its erasure
+ |signature: %s
+ |original type: %s
+ |normalized type: %s
+ |erasure type: %s
+ |if this is reproducible, please report bug at http://lampsvn.epfl.ch/trac/scala
+ """.trim.stripMargin.format(sym, sym.owner.skipPackageObject.fullName, sig, memberTpe, normalizedTpe, bytecodeTpe))
+ return
+ }
+ }
+ val index = jmember.getConstantPool.addUtf8(sig).toShort
+ if (opt.verboseDebug)
+ atPhase(currentRun.erasurePhase) {
+ println("add generic sig "+sym+":"+sym.info+" ==> "+sig+" @ "+index)
}
- } else clasz.cunit.warning(sym.pos,
- """|compiler bug: created invalid generic signature for %s in %s
- |signature: %s
- |if this is reproducible, please report bug at http://lampsvn.epfl.ch/trac/scala
- """.trim.stripMargin.format(sym, sym.owner.skipPackageObject.fullName, sig))
+ val buf = ByteBuffer.allocate(2)
+ buf putShort index
+ addAttribute(jmember, tpnme.SignatureATTR, buf)
}
}
}
@@ -1858,7 +1861,7 @@ abstract class GenJVM extends SubComponent with GenJVMUtil with GenAndroid {
if (sym.isInterface) ACC_INTERFACE else 0,
if (sym.isFinal && !sym.enclClass.isInterface && !sym.isClassConstructor) ACC_FINAL else 0,
if (sym.isStaticMember) ACC_STATIC else 0,
- if (sym.isBridge) ACC_BRIDGE else 0,
+ if (sym.isBridge || sym.hasFlag(Flags.MIXEDIN) && sym.isMethod) ACC_BRIDGE else 0,
if (sym.isClass && !sym.isInterface) ACC_SUPER else 0,
if (sym.isVarargsMethod) ACC_VARARGS else 0
)
diff --git a/src/compiler/scala/tools/nsc/interactive/CompilerControl.scala b/src/compiler/scala/tools/nsc/interactive/CompilerControl.scala
index 7b9a7fdb85..2ced0788c1 100644
--- a/src/compiler/scala/tools/nsc/interactive/CompilerControl.scala
+++ b/src/compiler/scala/tools/nsc/interactive/CompilerControl.scala
@@ -103,6 +103,10 @@ trait CompilerControl { self: Global =>
throw new FatalError("no context found for "+pos)
}
+ private def postWorkItem(item: WorkItem) {
+ scheduler.postWorkItem(item)
+ }
+
/** Makes sure a set of compilation units is loaded and parsed.
* Returns () to syncvar `response` on completions.
* Afterwards a new background compiler run is started with
@@ -113,15 +117,15 @@ trait CompilerControl { self: Global =>
case ri: ReloadItem if ri.sources == sources => Some(ri)
case _ => None
}
- superseeded foreach (_.response.set())
- scheduler postWorkItem new ReloadItem(sources, response)
+ superseeded.foreach(_.response.set())
+ postWorkItem(new ReloadItem(sources, response))
}
/** Sets sync var `response` to the smallest fully attributed tree that encloses position `pos`.
* Note: Unlike for most other ask... operations, the source file belonging to `pos` needs not be be loaded.
*/
def askTypeAt(pos: Position, response: Response[Tree]) =
- scheduler postWorkItem new AskTypeAtItem(pos, response)
+ postWorkItem(new AskTypeAtItem(pos, response))
/** Sets sync var `response` to the fully attributed & typechecked tree contained in `source`.
* @pre `source` needs to be loaded.
@@ -131,7 +135,7 @@ trait CompilerControl { self: Global =>
println("ask type called")
new Exception().printStackTrace()
}
- scheduler postWorkItem new AskTypeItem(source, forceReload, response)
+ postWorkItem(new AskTypeItem(source, forceReload, response))
}
/** Sets sync var `response` to the position of the definition of the given link in
@@ -146,25 +150,25 @@ trait CompilerControl { self: Global =>
* is unloaded, it stays that way.
*/
def askLinkPos(sym: Symbol, source: SourceFile, response: Response[Position]) =
- scheduler postWorkItem new AskLinkPosItem(sym, source, response)
+ postWorkItem(new AskLinkPosItem(sym, source, response))
/** Sets sync var `response' to list of members that are visible
* as members of the tree enclosing `pos`, possibly reachable by an implicit.
* @pre source is loaded
*/
def askTypeCompletion(pos: Position, response: Response[List[Member]]) =
- scheduler postWorkItem new AskTypeCompletionItem(pos, response)
+ postWorkItem(new AskTypeCompletionItem(pos, response))
/** Sets sync var `response' to list of members that are visible
* as members of the scope enclosing `pos`.
* @pre source is loaded
*/
def askScopeCompletion(pos: Position, response: Response[List[Member]]) =
- scheduler postWorkItem new AskScopeCompletionItem(pos, response)
+ postWorkItem(new AskScopeCompletionItem(pos, response))
/** Asks to do unit corresponding to given source file on present and subsequent type checking passes */
def askToDoFirst(source: SourceFile) =
- scheduler postWorkItem new AskToDoFirstItem(source)
+ postWorkItem(new AskToDoFirstItem(source))
/** If source is not yet loaded, loads it, and starts a new run, otherwise
* continues with current pass.
@@ -175,7 +179,7 @@ trait CompilerControl { self: Global =>
* the a NoSuchUnitError is raised in the response.
*/
def askLoadedTyped(source: SourceFile, response: Response[Tree]) =
- scheduler postWorkItem new AskLoadedTypedItem(source, response)
+ postWorkItem(new AskLoadedTypedItem(source, response))
/** If source if not yet loaded, get an outline view with askParseEntered.
* If source is loaded, wait for it to be typechecked.
@@ -196,7 +200,7 @@ trait CompilerControl { self: Global =>
* @param response The response.
*/
def askParsedEntered(source: SourceFile, keepLoaded: Boolean, response: Response[Tree]) =
- scheduler postWorkItem new AskParsedEnteredItem(source, keepLoaded, response)
+ postWorkItem(new AskParsedEnteredItem(source, keepLoaded, response))
/** Cancels current compiler run and start a fresh one where everything will be re-typechecked
* (but not re-loaded).
@@ -314,3 +318,5 @@ object ShutdownReq extends ControlThrowable
class NoSuchUnitError(file: AbstractFile) extends Exception("no unit found for file "+file)
+class MissingResponse extends Exception("response missing")
+
diff --git a/src/compiler/scala/tools/nsc/interactive/Global.scala b/src/compiler/scala/tools/nsc/interactive/Global.scala
index 155597b559..95aec8b0a2 100644
--- a/src/compiler/scala/tools/nsc/interactive/Global.scala
+++ b/src/compiler/scala/tools/nsc/interactive/Global.scala
@@ -120,6 +120,22 @@ class Global(settings: Settings, reporter: Reporter)
}
}
+ private def cleanAllResponses() {
+ cleanResponses(waitLoadedTypeResponses)
+ cleanResponses(getParsedEnteredResponses)
+ }
+
+ private def checkNoOutstanding(rmap: ResponseMap): Unit =
+ for ((_, rs) <- rmap.toList; r <- rs) {
+ debugLog("ERROR: missing response, request will be discarded")
+ r raise new MissingResponse
+ }
+
+ def checkNoResponsesOutstanding() {
+ checkNoOutstanding(waitLoadedTypeResponses)
+ checkNoOutstanding(getParsedEnteredResponses)
+ }
+
/** The compilation unit corresponding to a source file
* if it does not yet exist create a new one atomically
* Note: We want to remove this.
@@ -417,8 +433,7 @@ class Global(settings: Settings, reporter: Reporter)
}
// clean out stale waiting responses
- cleanResponses(waitLoadedTypeResponses)
- cleanResponses(getParsedEnteredResponses)
+ cleanAllResponses()
// wind down
if (waitLoadedTypeResponses.nonEmpty || getParsedEnteredResponses.nonEmpty) {
@@ -841,8 +856,8 @@ class Global(settings: Settings, reporter: Reporter)
else { debugLog("wait for later"); outOfDate = true; waitLoadedTypeResponses(source) += response }
case None =>
debugLog("load unit and type")
- reloadSources(List(source))
- waitLoadedTyped(source, response)
+ try reloadSources(List(source))
+ finally waitLoadedTyped(source, response)
}
}
@@ -852,14 +867,13 @@ class Global(settings: Settings, reporter: Reporter)
case Some(unit) =>
getParsedEnteredNow(source, response)
case None =>
- if (keepLoaded) {
- reloadSources(List(source))
- getParsedEnteredNow(source, response)
- } else if (outOfDate) {
+ if (keepLoaded)
+ try reloadSources(List(source))
+ finally getParsedEnteredNow(source, response)
+ else if (outOfDate)
getParsedEnteredResponses(source) += response
- } else {
+ else
getParsedEnteredNow(source, response)
- }
}
}
diff --git a/src/compiler/scala/tools/nsc/interactive/PresentationCompilerThread.scala b/src/compiler/scala/tools/nsc/interactive/PresentationCompilerThread.scala
index 55f8264020..b61d7f6638 100644
--- a/src/compiler/scala/tools/nsc/interactive/PresentationCompilerThread.scala
+++ b/src/compiler/scala/tools/nsc/interactive/PresentationCompilerThread.scala
@@ -20,6 +20,7 @@ class PresentationCompilerThread(var compiler: Global, threadId: Int) extends Th
compiler.debugLog("starting new runner thread")
try {
while (true) {
+ compiler.checkNoResponsesOutstanding()
compiler.log.logreplay("wait for more work", { compiler.scheduler.waitForMoreWork(); true })
compiler.pollForWork(compiler.NoPosition)
while (compiler.isOutOfDate) {
diff --git a/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala b/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala
index de1a03cc5c..4eca9f140e 100644
--- a/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala
+++ b/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala
@@ -264,7 +264,7 @@ abstract class ClassfileParser {
// println("Looking for: " + name + ": " + tpe + " inside: " + ownerTpe.typeSymbol + "\n\tand found: " + ownerTpe.members)
}
}
- assert(f != NoSymbol, "could not find " + name + ": " + tpe + "inside: \n" + ownerTpe.members)
+ assert(f != NoSymbol, "could not find\n " + name + ": " + tpe + "\ninside:\n " + ownerTpe.members.mkString(", "))
values(index) = f
}
f
diff --git a/src/compiler/scala/tools/nsc/transform/Erasure.scala b/src/compiler/scala/tools/nsc/transform/Erasure.scala
index bdc0a1bfac..ca39ec4a4d 100644
--- a/src/compiler/scala/tools/nsc/transform/Erasure.scala
+++ b/src/compiler/scala/tools/nsc/transform/Erasure.scala
@@ -231,12 +231,21 @@ abstract class Erasure extends AddInterfaces
// for debugging signatures: traces logic given system property
private val traceSig = util.Tracer(sys.props contains "scalac.sigs.trace")
+ /** This object is only used for sanity testing when -check:genjvm is set.
+ * In that case we make sure that the erasure of the `normalized' type
+ * is the same as the erased type that's generated. Normalization means
+ * unboxing some primitive types and further simplifications as they are done in jsig.
+ */
val prepareSigMap = new TypeMap {
def squashBoxed(tp: Type): Type = tp.normalize match {
case t @ RefinedType(parents, decls) =>
val parents1 = parents mapConserve squashBoxed
if (parents1 eq parents) tp
else RefinedType(parents1, decls)
+ case t @ ExistentialType(tparams, tpe) =>
+ val tpe1 = squashBoxed(tpe)
+ if (tpe1 eq tpe) t
+ else ExistentialType(tparams, tpe1)
case t =>
if (boxedClass contains t.typeSymbol) ObjectClass.tpe
else tp
@@ -279,6 +288,10 @@ abstract class Erasure extends AddInterfaces
val parents1 = parents mapConserve apply
if (parents1 eq parents) tp1
else RefinedType(parents1, decls)
+ case t @ ExistentialType(tparams, tpe) =>
+ val tpe1 = apply(tpe)
+ if (tpe1 eq tpe) t
+ else ExistentialType(tparams, tpe1)
case tp1: ClassInfoType =>
tp1
case tp1 =>
@@ -290,56 +303,39 @@ abstract class Erasure extends AddInterfaces
* type for constructors.
*/
def javaSig(sym0: Symbol, info: Type): Option[String] = atPhase(currentRun.erasurePhase) {
- def jsig(tp: Type): String = jsig2(toplevel = false, Nil, tp)
-
- // Unit in return position is 'V', but that cannot appear elsewhere.
- def unboxedSig(tpe: Type, isReturnPosition: Boolean) = {
- val tsym = tpe.typeSymbol
- if (isReturnPosition && (tsym == UnitClass || sym0.isConstructor)) VOID_TAG
- else if (isNonUnitValueClass(tsym)) abbrvTag(tsym)
- else jsig(tpe)
- }
- def boxedSig(tp: Type) = jsig(squashBoxed(tp))
- def squashBoxed(tp: Type) =
- if (boxedClass contains tp.typeSymbol) ObjectClass.tpe
- else tp
+ def boxedSig(tp: Type) = jsig(tp, primitiveOK = false)
- def hiBounds(bounds: TypeBounds): List[Type] = (bounds.hi.normalize match {
+ def hiBounds(bounds: TypeBounds): List[Type] = bounds.hi.normalize match {
case RefinedType(parents, _) => parents map normalize
case tp => tp :: Nil
- }) map squashBoxed
+ }
- def jsig2(toplevel: Boolean, existentiallyBound: List[Symbol], tp0: Type): String = {
+ def jsig(tp0: Type, existentiallyBound: List[Symbol] = Nil, toplevel: Boolean = false, primitiveOK: Boolean = true): String = {
val tp = tp0.dealias
tp match {
case st: SubType =>
- jsig2(toplevel, existentiallyBound, st.supertype)
+ jsig(st.supertype, existentiallyBound, toplevel, primitiveOK)
case ExistentialType(tparams, tpe) =>
- jsig2(toplevel, tparams, tpe)
+ jsig(tpe, tparams, toplevel, primitiveOK)
case TypeRef(pre, sym, args) =>
def argSig(tp: Type) =
if (existentiallyBound contains tp.typeSymbol) {
val bounds = tp.typeSymbol.info.bounds
- if (AnyRefClass.tpe <:< bounds.hi) {
- if (bounds.lo <:< NullClass.tpe) "*"
- else "-" + boxedSig(bounds.lo)
- }
- else "+" + boxedSig(bounds.hi)
- }
- else if (tp.typeSymbol == UnitClass) {
- jsig(ObjectClass.tpe)
+ if (!(AnyRefClass.tpe <:< bounds.hi)) "+" + boxedSig(bounds.hi)
+ else if (!(bounds.lo <:< NullClass.tpe)) "-" + boxedSig(bounds.lo)
+ else "*"
} else {
boxedSig(tp)
}
- def classSig = (
+ def classSig: String =
"L"+atPhase(currentRun.icodePhase)(sym.fullName + global.genJVM.moduleSuffix(sym)).replace('.', '/')
- )
- def classSigSuffix = "." + sym.name
+ def classSigSuffix: String =
+ "."+sym.name
// If args isEmpty, Array is being used as a higher-kinded type
if (sym == ArrayClass && args.nonEmpty) {
if (unboundedGenericArrayLevel(tp) == 1) jsig(ObjectClass.tpe)
- else ARRAY_TAG.toString+(args map jsig).mkString
+ else ARRAY_TAG.toString+(args map (jsig(_))).mkString
}
else if (isTypeParameterInSig(sym, sym0)) {
assert(!sym.isAliasType, "Unexpected alias type: " + sym)
@@ -353,13 +349,18 @@ abstract class Erasure extends AddInterfaces
jsig(RuntimeNothingClass.tpe)
else if (sym == NullClass)
jsig(RuntimeNullClass.tpe)
+ else if (isValueClass(sym)) {
+ if (!primitiveOK) jsig(ObjectClass.tpe)
+ else if (sym == UnitClass) jsig(BoxedUnitClass.tpe)
+ else abbrvTag(sym).toString
+ }
else if (sym.isClass) {
val preRebound = pre.baseType(sym.owner) // #2585
traceSig.seq("sym.isClass", Seq(sym.ownerChain, preRebound, sym0.enclClassChain)) {
dotCleanup(
(
if (needsJavaSig(preRebound)) {
- val s = jsig(preRebound)
+ val s = jsig(preRebound, existentiallyBound)
if (s.charAt(0) == 'L') s.substring(0, s.length - 1) + classSigSuffix
else classSig
}
@@ -373,7 +374,7 @@ abstract class Erasure extends AddInterfaces
)
}
}
- else jsig(erasure(tp))
+ else jsig(erasure(tp), existentiallyBound, toplevel, primitiveOK)
case PolyType(tparams, restpe) =>
assert(tparams.nonEmpty)
def boundSig(bounds: List[Type]) = {
@@ -390,21 +391,17 @@ abstract class Erasure extends AddInterfaces
val paramString = if (toplevel) tparams map paramSig mkString ("<", "", ">") else ""
traceSig.seq("PolyType", Seq(tparams, restpe))(paramString + jsig(restpe))
case MethodType(params, restpe) =>
- traceSig.seq("MethodType", Seq(params, restpe)) {
- "(%s)%s".format(
- params map (p => unboxedSig(p.tpe, false)) mkString,
- unboxedSig(restpe, true)
- )
- }
+ "("+(params map (_.tpe) map (jsig(_))).mkString+")"+
+ (if (restpe.typeSymbol == UnitClass || sym0.isConstructor) VOID_TAG.toString else jsig(restpe))
case RefinedType(parent :: _, decls) =>
- jsig(parent)
+ boxedSig(parent)
case ClassInfoType(parents, _, _) =>
- (parents map jsig).mkString
+ (parents map (boxedSig(_))).mkString
case AnnotatedType(_, atp, _) =>
- jsig(atp)
+ jsig(atp, existentiallyBound, toplevel, primitiveOK)
case BoundedWildcardType(bounds) =>
println("something's wrong: "+sym0+":"+sym0.tpe+" has a bounded wildcard type")
- jsig(bounds.hi)
+ jsig(bounds.hi, existentiallyBound, toplevel, primitiveOK)
case _ =>
val etp = erasure(tp)
if (etp eq tp) throw new UnknownSig
@@ -413,7 +410,7 @@ abstract class Erasure extends AddInterfaces
}
traceSig.seq("javaSig", Seq(sym0, info)) {
if (needsJavaSig(info)) {
- try Some(jsig2(true, Nil, info))
+ try Some(jsig(info, toplevel = true))
catch { case ex: UnknownSig => None }
}
else None
diff --git a/src/compiler/scala/tools/nsc/transform/Mixin.scala b/src/compiler/scala/tools/nsc/transform/Mixin.scala
index caba8f9bd1..49f5907245 100644
--- a/src/compiler/scala/tools/nsc/transform/Mixin.scala
+++ b/src/compiler/scala/tools/nsc/transform/Mixin.scala
@@ -134,7 +134,7 @@ abstract class Mixin extends InfoTransform with ast.TreeDSL {
def addMember(clazz: Symbol, member: Symbol): Symbol = {
if (settings.debug.value) log("new member of " + clazz + ":" + member.defString)
clazz.info.decls enter member
- member setFlag MIXEDIN
+ member.setFlag(MIXEDIN)
}
def needsExpandedSetterName(field: Symbol) = !field.isLazy && (
diff --git a/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala b/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala
index 42ccae9a76..e33491aa29 100644
--- a/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala
+++ b/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala
@@ -40,6 +40,11 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers {
case _ => false
}
+ private def specializedOn(sym: Symbol) = sym.getAnnotation(SpecializedClass) match {
+ case Some(AnnotationInfo(_, args, _)) => args
+ case _ => Nil
+ }
+
object TypeEnv {
/** Return a new type environment binding specialized type parameters of sym to
* the given args. Expects the lists to have the same length.
@@ -226,7 +231,7 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers {
val specializedType = new TypeMap {
override def apply(tp: Type): Type = tp match {
- case TypeRef(pre, sym, args) if !args.isEmpty =>
+ case TypeRef(pre, sym, args) if args.nonEmpty =>
val pre1 = this(pre)
// when searching for a specialized class, take care to map all
// type parameters that are subtypes of AnyRef to AnyRef
@@ -536,7 +541,7 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers {
}
var parents = List(applyContext(atPhase(currentRun.typerPhase)(clazz.tpe)))
- // log("Parent: " + parents.head + ", sym: " + parents.head.typeSymbol)
+ // log("!!! Parents: " + parents + ", sym: " + parents.map(_.typeSymbol))
if (parents.head.typeSymbol.isTrait)
parents = parents.head.parents.head :: parents
val extraSpecializedMixins = specializedParents(clazz.info.parents.map(applyContext))
@@ -859,7 +864,7 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers {
* this method will return List('apply$spec$II')
*/
private def specialOverrides(clazz: Symbol): List[Symbol] = {
- log("specialOverrides(" + clazz + ")")
+ // log("--> specialOverrides(" + clazz + ")")
/** Return the overridden symbol in syms that needs a specialized overriding symbol,
* together with its specialization environment. The overridden symbol may not be
@@ -886,6 +891,7 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers {
"types: " + missing.mkString("", ", ", ""))
}
+ // log("checking: " + overriding + " - isParamAccessor: " + overriding.isParamAccessor)
if (!overriding.isParamAccessor) for (overridden <- syms) {
if (settings.debug.value)
log("Overridden: " + overridden.fullName + ": " + overridden.info
@@ -1068,6 +1074,29 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers {
// decl
}
+ /** Checks if the type parameter symbol is not specialized
+ * and is used as type parameters when extending a class with a specialized
+ * type parameter.
+ * At some point we may remove this restriction.
+ *
+ * Example:
+ *
+ * class Base[@specialized T]
+ * class Derived[T] extends Base[T] // a non-specialized T is
+ * // used as a type param for Base
+ * // -> returning true
+ */
+ private def notSpecializedIn(tsym: Symbol, supertpe: Type) = supertpe match {
+ case TypeRef(_, supersym, supertargs) =>
+ val tspec = specializedOn(tsym).toSet
+ for (supt <- supersym.typeParams) {
+ val supspec = specializedOn(supt).toSet
+ if (tspec != supspec && tspec.subsetOf(supspec))
+ reporter.error(tsym.pos, "Type parameter has to be specialized at least for the same types as in the superclass. Missing types: " + (supspec.diff(tspec)).mkString(", "))
+ }
+ case _ => //log("nope")
+ }
+
/** Type transformation. It is applied to all symbols, compiled or loaded.
* If it is a 'no-specialization' run, it is applied only to loaded symbols.
*/
@@ -1078,6 +1107,8 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers {
&& clazz != JavaRepeatedParamClass
&& !clazz.isJavaDefined =>
val parents = base map specializedType
+ // log("!!! %s[%s]) Parents: %s -> %s".format(sym, targs, base, parents))
+ // for (t <- targs; p <- parents) notSpecializedIn(t, p)
if (settings.debug.value) log("transformInfo (poly) " + clazz + " with parents1: " + parents + " ph: " + phase)
// if (clazz.name.toString == "$colon$colon")
// (new Throwable).printStackTrace
diff --git a/src/library/scala/collection/CustomParallelizable.scala b/src/library/scala/collection/CustomParallelizable.scala
new file mode 100644
index 0000000000..3d0b8af2f2
--- /dev/null
+++ b/src/library/scala/collection/CustomParallelizable.scala
@@ -0,0 +1,18 @@
+/* __ *\
+** ________ ___ / / ___ Scala API **
+** / __/ __// _ | / / / _ | (c) 2003-2011, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
+** /____/\___/_/ |_/____/_/ | | **
+** |/ **
+\* */
+
+package scala.collection
+
+import parallel.Combiner
+
+trait CustomParallelizable[+A, +ParRepr <: Parallel] extends Parallelizable[A, ParRepr] {
+ self: TraversableOnce[A] =>
+
+ override def par: ParRepr
+ override protected[this] def parCombiner: Combiner[A, ParRepr] = throw new UnsupportedOperationException("")
+}
diff --git a/src/library/scala/collection/Parallelizable.scala b/src/library/scala/collection/Parallelizable.scala
index 207bb25cb6..10ab248626 100644
--- a/src/library/scala/collection/Parallelizable.scala
+++ b/src/library/scala/collection/Parallelizable.scala
@@ -6,16 +6,10 @@
** |/ **
\* */
-
package scala.collection
-
-
-import parallel.ParIterableLike
import parallel.Combiner
-
-
/** This trait describes collections which can be turned into parallel collections
* by invoking the method `par`. Parallelizable collections may be parametrized with
* a target type different than their own.
@@ -24,7 +18,7 @@ import parallel.Combiner
* @tparam ParRepr the actual type of the collection, which has to be parallel
*/
trait Parallelizable[+A, +ParRepr <: Parallel] {
-self: TraversableOnce[A] =>
+ self: TraversableOnce[A] =>
/** Returns a parallel implementation of this collection.
*
@@ -53,29 +47,4 @@ self: TraversableOnce[A] =>
* @return a combiner for the parallel collection of type `ParRepr`
*/
protected[this] def parCombiner: Combiner[A, ParRepr]
-
}
-
-
-trait CustomParallelizable[+A, +ParRepr <: Parallel] extends Parallelizable[A, ParRepr] {
-self: TraversableOnce[A] =>
-
- override def par: ParRepr
-
- protected override def parCombiner = throw new UnsupportedOperationException("")
-}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/src/library/scala/collection/mutable/StringBuilder.scala b/src/library/scala/collection/mutable/StringBuilder.scala
index 73d3778650..0d1c51c42f 100644
--- a/src/library/scala/collection/mutable/StringBuilder.scala
+++ b/src/library/scala/collection/mutable/StringBuilder.scala
@@ -24,17 +24,17 @@ import immutable.StringLike
*/
@SerialVersionUID(0 - 8525408645367278351L)
final class StringBuilder(private val underlying: JavaStringBuilder)
- extends Builder[Char, StringBuilder]
- with java.lang.CharSequence
+ extends java.lang.CharSequence
with IndexedSeq[Char]
with StringLike[StringBuilder]
+ with Builder[Char, String]
with Serializable {
override protected[this] def thisCollection: StringBuilder = this
override protected[this] def toCollection(repr: StringBuilder): StringBuilder = repr
/** Creates a string builder buffer as builder for this class */
- override protected[this] def newBuilder = new StringBuilder
+ override protected[this] def newBuilder = new GrowingBuilder(new StringBuilder)
/** Constructs a string builder initialized with String initValue
* and with additional Char capacity initCapacity.
@@ -450,9 +450,9 @@ final class StringBuilder(private val underlying: JavaStringBuilder)
*
* @return this StringBuilder
*/
- def result(): StringBuilder = this
+ def result(): String = toString
}
object StringBuilder {
- def newBuilder = new StringBuilder mapResult (_.toString)
-} \ No newline at end of file
+ def newBuilder = new StringBuilder
+}
diff --git a/src/library/scala/collection/parallel/Tasks.scala b/src/library/scala/collection/parallel/Tasks.scala
index 0b220a020f..80cdd31fa1 100644
--- a/src/library/scala/collection/parallel/Tasks.scala
+++ b/src/library/scala/collection/parallel/Tasks.scala
@@ -279,7 +279,9 @@ trait ThreadPoolTasks extends Tasks {
}
override def release = synchronized {
completed = true
- decrTasks
+ executor.synchronized {
+ decrTasks
+ }
this.notifyAll
}
}
@@ -352,6 +354,70 @@ object ThreadPoolTasks {
}
+/** An implementation of tasks objects based on the Java thread pooling API and synchronization using futures. */
+trait FutureThreadPoolTasks extends Tasks {
+ import java.util.concurrent._
+
+ trait TaskImpl[R, +Tp] extends Runnable with super.TaskImpl[R, Tp] {
+ @volatile var future: Future[_] = null
+
+ def start = {
+ executor.synchronized {
+ future = executor.submit(this)
+ }
+ }
+ def sync = future.get
+ def tryCancel = false
+ def run = {
+ compute
+ }
+ }
+
+ protected def newTaskImpl[R, Tp](b: Task[R, Tp]): TaskImpl[R, Tp]
+
+ var environment: AnyRef = FutureThreadPoolTasks.defaultThreadPool
+ def executor = environment.asInstanceOf[ThreadPoolExecutor]
+
+ def execute[R, Tp](task: Task[R, Tp]): () => R = {
+ val t = newTaskImpl(task)
+
+ // debuglog("-----------> Executing without wait: " + task)
+ t.start
+
+ () => {
+ t.sync
+ t.body.forwardThrowable
+ t.body.result
+ }
+ }
+
+ def executeAndWaitResult[R, Tp](task: Task[R, Tp]): R = {
+ val t = newTaskImpl(task)
+
+ // debuglog("-----------> Executing with wait: " + task)
+ t.start
+
+ t.sync
+ t.body.forwardThrowable
+ t.body.result
+ }
+
+ def parallelismLevel = FutureThreadPoolTasks.numCores
+
+}
+
+object FutureThreadPoolTasks {
+ import java.util.concurrent._
+
+ val numCores = Runtime.getRuntime.availableProcessors
+
+ val tcount = new atomic.AtomicLong(0L)
+
+ val defaultThreadPool = Executors.newCachedThreadPool()
+}
+
+
+
/**
* A trait describing objects that provide a fork/join pool.
*/
@@ -430,7 +496,7 @@ trait ForkJoinTasks extends Tasks with HavingForkJoinPool {
object ForkJoinTasks {
- val defaultForkJoinPool: ForkJoinPool = scala.parallel.forkjoinpool
+ val defaultForkJoinPool: ForkJoinPool = new ForkJoinPool() // scala.parallel.forkjoinpool
// defaultForkJoinPool.setParallelism(Runtime.getRuntime.availableProcessors)
// defaultForkJoinPool.setMaximumPoolSize(Runtime.getRuntime.availableProcessors)
}
diff --git a/src/library/scala/concurrent/FutureTaskRunner.scala b/src/library/scala/concurrent/FutureTaskRunner.scala
index fe3728861f..206155ce2a 100644
--- a/src/library/scala/concurrent/FutureTaskRunner.scala
+++ b/src/library/scala/concurrent/FutureTaskRunner.scala
@@ -1,25 +1,25 @@
package scala.concurrent
-/** The <code>FutureTaskRunner</code> trait is a base trait of thread runners
- * that provide some sort of future abstractions.
+/** The <code>FutureTaskRunner</code> trait is a base trait of task runners
+ * that provide some sort of future abstraction.
*
* @author Philipp Haller
*/
trait FutureTaskRunner extends TaskRunner {
- /** The type of the futures that are provided.
+ /** The type of the futures that the underlying task runner supports.
*/
type Future[T]
- /** An implicit conversion from futures to zero-parameter functions
+ /** An implicit conversion from futures to zero-parameter functions.
*/
implicit def futureAsFunction[S](x: Future[S]): () => S
- /** Submits a task to run which returns its result in a futir
+ /** Submits a task to run which returns its result in a future.
*/
def submit[S](task: Task[S]): Future[S]
- /* Possibly blocks the current thread, for example waiting for
+ /* Possibly blocks the current thread, for example, waiting for
* a lock or condition.
*/
def managedBlock(blocker: ManagedBlocker): Unit
diff --git a/src/library/scala/concurrent/MailBox.scala b/src/library/scala/concurrent/MailBox.scala
index 14b67bea3f..d9a8746ba3 100644
--- a/src/library/scala/concurrent/MailBox.scala
+++ b/src/library/scala/concurrent/MailBox.scala
@@ -16,6 +16,7 @@ package scala.concurrent
* @version 1.0, 12/03/2003
*/
//class MailBox with Monitor with LinkedListQueueCreator {
+@deprecated("use actors instead")
class MailBox extends AnyRef with ListQueueCreator {
type Message = AnyRef
@@ -102,11 +103,12 @@ class MailBox extends AnyRef with ListQueueCreator {
}
-/////////////////////////////////////////////////////////////////
+
/**
* Module for dealing with queues.
*/
+@deprecated("use actors instead")
trait QueueModule[A] {
/** Type of queues. */
type T
@@ -119,6 +121,7 @@ trait QueueModule[A] {
}
/** Inefficient but simple queue module creator. */
+@deprecated("use actors instead")
trait ListQueueCreator {
def queueCreate[A]: QueueModule[A] = new QueueModule[A] {
type T = List[A]
@@ -140,6 +143,7 @@ trait ListQueueCreator {
}
/** Efficient queue module creator based on linked lists. */
+@deprecated("use actors instead")
trait LinkedListQueueCreator {
import scala.collection.mutable.LinkedList
def queueCreate[A >: Null <: AnyRef]: QueueModule[A] = new QueueModule[A] {
diff --git a/src/library/scala/concurrent/TIMEOUT.scala b/src/library/scala/concurrent/TIMEOUT.scala
index 7d3c0dfb4c..512879760b 100644
--- a/src/library/scala/concurrent/TIMEOUT.scala
+++ b/src/library/scala/concurrent/TIMEOUT.scala
@@ -17,4 +17,5 @@ package scala.concurrent
* @author Martin Odersky
* @version 1.0, 10/03/2003
*/
+@deprecated("use actors instead")
case object TIMEOUT
diff --git a/src/library/scala/concurrent/ops.scala b/src/library/scala/concurrent/ops.scala
index 4d6f4b29b1..5542472ce1 100644
--- a/src/library/scala/concurrent/ops.scala
+++ b/src/library/scala/concurrent/ops.scala
@@ -39,20 +39,25 @@ object ops
runner execute runner.functionAsTask(() => p)
}
- /**
- * @param p ...
- * @return ...
+ /** Evaluates an expression asynchronously, and returns a closure for retrieving
+ * the result.
+ *
+ * @param p the expression to evaluate
+ * @return a closure which returns the result once it has been computed
*/
def future[A](p: => A)(implicit runner: FutureTaskRunner = defaultRunner): () => A = {
runner.futureAsFunction(runner submit runner.functionAsTask(() => p))
}
- /**
- * @param xp ...
- * @param yp ...
- * @return ...
+ /** Evaluates two expressions in parallel. Invoking `par' blocks the current
+ * thread until both expressions have been evaluated.
+ *
+ * @param xp the first expression to evaluate
+ * @param yp the second expression to evaluate
+ *
+ * @return a pair holding the evaluation results
*/
- def par[A, B](xp: => A, yp: => B): (A, B) = {
+ def par[A, B](xp: => A, yp: => B)(implicit runner: TaskRunner = defaultRunner): (A, B) = {
val y = new SyncVar[Either[Throwable, B]]
spawn { y set tryCatch(yp) }
(xp, getOrThrow(y.get))
@@ -63,7 +68,8 @@ object ops
* @param end ...
* @param p ...
*/
- def replicate(start: Int, end: Int)(p: Int => Unit) {
+ @deprecated("use `collection.parallel.ParIterable.foreach' instead")
+ def replicate(start: Int, end: Int)(p: Int => Unit)(implicit runner: TaskRunner = defaultRunner) {
if (start == end)
()
else if (start + 1 == end)
diff --git a/src/library/scala/concurrent/package.scala.disabled b/src/library/scala/concurrent/package.scala.disabled
new file mode 100644
index 0000000000..42b4bf954c
--- /dev/null
+++ b/src/library/scala/concurrent/package.scala.disabled
@@ -0,0 +1,108 @@
+/* __ *\
+** ________ ___ / / ___ Scala API **
+** / __/ __// _ | / / / _ | (c) 2003-2011, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
+** /____/\___/_/ |_/____/_/ | | **
+** |/ **
+\* */
+
+
+
+package scala
+
+
+
+
+/** This package object contains primitives for parallel programming.
+ */
+package object concurrent {
+
+ /** Performs a call which can potentially block execution.
+ *
+ * Example:
+ * {{{
+ * val lock = new ReentrantLock
+ *
+ * // ... do something ...
+ *
+ * blocking {
+ * if (!lock.hasLock) lock.lock()
+ * }
+ * }}}
+ *
+ * '''Note:''' calling methods that wait arbitrary amounts of time
+ * (e.g. for I/O operations or locks) may severely decrease performance
+ * or even result in deadlocks. This does not include waiting for
+ * results of futures.
+ *
+ * @tparam T the result type of the blocking operation
+ * @param body the blocking operation
+ * @param runner the runner used for parallel computations
+ * @return the result of the potentially blocking operation
+ */
+ def blocking[T](body: =>T)(implicit runner: TaskRunner): T = {
+ null.asInstanceOf[T]
+ }
+
+ /** Invokes a computation asynchronously. Does not wait for the computation
+ * to finish.
+ *
+ * @tparam U the result type of the operation
+ * @param p the computation to be invoked asynchronously
+ * @param runner the runner used for parallel computations
+ */
+ def spawn[U](p: =>U)(implicit runner: TaskRunner): Unit = {
+ }
+
+ /** Starts 2 parallel computations and returns once they are completed.
+ *
+ * $invokingPar
+ *
+ * @tparam T1 the type of the result of 1st the parallel computation
+ * @tparam T2 the type of the result of 2nd the parallel computation
+ * @param b1 the 1st computation to be invoked in parallel
+ * @param b2 the 2nd computation to be invoked in parallel
+ * @param runner the runner used for parallel computations
+ * @return a tuple of results corresponding to parallel computations
+ */
+ def par[T1, T2](b1: =>T1)(b2: =>T2)(implicit runner: TaskRunner): (T1, T2) = {
+ null
+ }
+
+ /** Starts 3 parallel computations and returns once they are completed.
+ *
+ * $invokingPar
+ *
+ * @tparam T1 the type of the result of 1st the parallel computation
+ * @tparam T2 the type of the result of 2nd the parallel computation
+ * @tparam T3 the type of the result of 3rd the parallel computation
+ * @param b1 the 1st computation to be invoked in parallel
+ * @param b2 the 2nd computation to be invoked in parallel
+ * @param b3 the 3rd computation to be invoked in parallel
+ * @param runner the runner used for parallel computations
+ * @return a tuple of results corresponding to parallel computations
+ */
+ def par[T1, T2, T3](b1: =>T1)(b2: =>T2)(b3: =>T3)(implicit runner: TaskRunner): (T1, T2, T3) = {
+ null
+ }
+
+ /** Starts 4 parallel computations and returns once they are completed.
+ *
+ * $invokingPar
+ *
+ * @tparam T1 the type of the result of 1st the parallel computation
+ * @tparam T2 the type of the result of 2nd the parallel computation
+ * @tparam T3 the type of the result of 3rd the parallel computation
+ * @tparam T4 the type of the result of 4th the parallel computation
+ * @param b1 the 1st computation to be invoked in parallel
+ * @param b2 the 2nd computation to be invoked in parallel
+ * @param b3 the 3rd computation to be invoked in parallel
+ * @param b4 the 4th computation to be invoked in parallel
+ * @param runner the runner used for parallel computations
+ * @return a tuple of results corresponding to parallel computations
+ */
+ def par[T1, T2, T3, T4](b1: =>T1)(b2: =>T2)(b3: =>T3)(b4: =>T4)(implicit runner: TaskRunner): (T1, T2, T3, T4) = {
+ null
+ }
+
+}
diff --git a/src/library/scala/concurrent/pilib.scala b/src/library/scala/concurrent/pilib.scala
index 3c3b280e14..a81df2d622 100644
--- a/src/library/scala/concurrent/pilib.scala
+++ b/src/library/scala/concurrent/pilib.scala
@@ -29,6 +29,7 @@ package scala.concurrent
* @author Vincent Cremet, Martin Odersky
* @version 1.0
*/
+@deprecated("use actors instead")
object pilib {
import TaskRunners.threadRunner
diff --git a/src/library/scala/parallel/package.scala b/src/library/scala/parallel/package.scala.disabled
index 4cae1ad4b1..45f5470d03 100644
--- a/src/library/scala/parallel/package.scala
+++ b/src/library/scala/parallel/package.scala.disabled
@@ -15,13 +15,13 @@ import scala.concurrent.forkjoin._
* chain obtained by querying results of unfinished futures can have
* arbitrary lengths. However, care must be taken not to create a
* circular dependency, as this will result in a deadlock.
- *
+ *
* Additionally, if the parallel computation performs a blocking call
* (e.g. an I/O operation or waiting for a lock) other than waiting for a future,
* it should do so by invoking the `block` method. This is another
* form of waiting that could potentially create a circular dependency,
* an the user should take care not to do this.
- *
+ *
* Users should be aware that invoking a parallel computation has a
* certain overhead. Parallel computations should not be invoked for
* small computations, as this can lead to bad performance. A rule of the
@@ -31,36 +31,36 @@ import scala.concurrent.forkjoin._
* computationally equivalent to a loop with 10000 arithmetic operations.
*/
package object parallel {
-
+
private[scala] val forkjoinpool = new ForkJoinPool()
-
+
private class Task[T](body: =>T) extends RecursiveTask[T] with Future[T] {
def compute = body
def apply() = join()
}
-
+
private final def newTask[T](body: =>T) = new Task[T](body)
-
+
private final def executeTask[T](task: RecursiveTask[T]) {
if (Thread.currentThread().isInstanceOf[ForkJoinWorkerThread]) task.fork
else forkjoinpool.execute(task)
}
-
+
/* public methods */
-
+
/** Performs a call which can potentially block execution.
- *
+ *
* Example:
* {{{
* val lock = new ReentrantLock
- *
+ *
* // ... do something ...
- *
+ *
* blocking {
* if (!lock.hasLock) lock.lock()
* }
* }}}
- *
+ *
* '''Note:''' calling methods that wait arbitrary amounts of time
* (e.g. for I/O operations or locks) may severely decrease performance
* or even result in deadlocks. This does not include waiting for
@@ -82,11 +82,11 @@ package object parallel {
blocker.result.asInstanceOf[T]
} else body
}
-
+
/** Starts a parallel computation and returns a future.
- *
+ *
* $invokingPar
- *
+ *
* @tparam T the type of the result of the parallel computation
* @param body the computation to be invoked in parallel
* @return a future with the result
@@ -96,9 +96,9 @@ package object parallel {
executeTask(task)
task
}
-
+
/** Starts 2 parallel computations and returns a future.
- *
+ *
* $invokingPar
*
* @tparam T1 the type of the result of 1st the parallel computation
@@ -114,9 +114,9 @@ package object parallel {
executeTask(t2)
(t1, t2)
}
-
+
/** Starts 3 parallel computations and returns a future.
- *
+ *
* $invokingPar
*
* @tparam T1 the type of the result of 1st the parallel computation
@@ -136,9 +136,9 @@ package object parallel {
executeTask(t3)
(t1, t2, t3)
}
-
+
/** Starts 4 parallel computations and returns a future.
- *
+ *
* $invokingPar
*
* @tparam T1 the type of the result of 1st the parallel computation
@@ -162,7 +162,7 @@ package object parallel {
executeTask(t4)
(t1, t2, t3, t4)
}
-
+
}
diff --git a/src/partest/scala/tools/partest/ReplTest.scala b/src/partest/scala/tools/partest/ReplTest.scala
index b7bd8efcf4..2f6bcea78b 100644
--- a/src/partest/scala/tools/partest/ReplTest.scala
+++ b/src/partest/scala/tools/partest/ReplTest.scala
@@ -6,6 +6,7 @@
package scala.tools.partest
import scala.tools.nsc.interpreter.ILoop
+import java.lang.reflect.{ Method => JMethod, Field => JField }
/** A trait for testing repl code. It drops the first line
* of output because the real repl prints a version number.
@@ -19,11 +20,40 @@ abstract class ReplTest extends App {
}
trait SigTest {
- def returnType[T: Manifest](methodName: String) = (
- classManifest[T].erasure.getMethods
- . filter (x => !x.isBridge && x.getName == methodName)
- . map (_.getGenericReturnType.toString)
+ def mstr(m: JMethod) = " (m) %s%s".format(
+ m.toGenericString,
+ if (m.isBridge) " (bridge)" else ""
)
- def show[T: Manifest](methodName: String) =
- println(manifest[T].erasure.getName +: returnType[T](methodName).distinct mkString " ")
+ def fstr(f: JField) = " (f) %s".format(f.toGenericString)
+
+ def isObjectMethodName(name: String) = classOf[Object].getMethods exists (_.getName == name)
+
+ def fields[T: ClassManifest](p: JField => Boolean) = {
+ val cl = classManifest[T].erasure
+ val fs = (cl.getFields ++ cl.getDeclaredFields).distinct sortBy (_.getName)
+
+ fs filter p
+ }
+ def methods[T: ClassManifest](p: JMethod => Boolean) = {
+ val cl = classManifest[T].erasure
+ val ms = (cl.getMethods ++ cl.getDeclaredMethods).distinct sortBy (x => (x.getName, x.isBridge))
+
+ ms filter p
+ }
+ def allFields[T: ClassManifest]() = fields[T](_ => true)
+ def allMethods[T: ClassManifest]() = methods[T](m => !isObjectMethodName(m.getName))
+ def fieldsNamed[T: ClassManifest](name: String) = fields[T](_.getName == name)
+ def methodsNamed[T: ClassManifest](name: String) = methods[T](_.getName == name)
+
+ def allGenericStrings[T: ClassManifest]() =
+ (allMethods[T]() map mstr) ++ (allFields[T]() map fstr)
+
+ def genericStrings[T: ClassManifest](name: String) =
+ (methodsNamed[T](name) map mstr) ++ (fieldsNamed[T](name) map fstr)
+
+ def show[T: ClassManifest](name: String = "") = {
+ println(classManifest[T].erasure.getName)
+ if (name == "") allGenericStrings[T]() foreach println
+ else genericStrings[T](name) foreach println
+ }
}
diff --git a/test/files/pos/hkarray.flags b/test/files/pos/hkarray.flags
new file mode 100644
index 0000000000..e8fb65d50c
--- /dev/null
+++ b/test/files/pos/hkarray.flags
@@ -0,0 +1 @@
+-Xfatal-warnings \ No newline at end of file
diff --git a/test/files/pos/hkarray.scala b/test/files/pos/hkarray.scala
new file mode 100644
index 0000000000..af1160300a
--- /dev/null
+++ b/test/files/pos/hkarray.scala
@@ -0,0 +1,5 @@
+trait Foo[CC[_]] { }
+
+class Bip {
+ val x = new Foo[Array] { }
+} \ No newline at end of file
diff --git a/test/files/pos/javaReadsSigs/fromjava.java b/test/files/pos/javaReadsSigs/fromjava.java
new file mode 100644
index 0000000000..d31244bb95
--- /dev/null
+++ b/test/files/pos/javaReadsSigs/fromjava.java
@@ -0,0 +1,16 @@
+import scala.collection.immutable.Vector;
+import scala.collection.immutable.List;
+
+public class fromjava {
+
+ void main(String[] args, Vector<String> x) {
+ Vector<String> y = x.take(2);
+ String h = y.head();
+ System.out.println(h);
+ }
+ void main(String[] args, List<String> x) {
+ List<String> y = x.drop(2);
+ String h = y.head();
+ System.out.println(h);
+ }
+} \ No newline at end of file
diff --git a/test/files/pos/switchUnbox-pos.log b/test/files/pos/switchUnbox-pos.log
deleted file mode 100644
index 9c146726d7..0000000000
--- a/test/files/pos/switchUnbox-pos.log
+++ /dev/null
@@ -1,2 +0,0 @@
-partest error: bad flags: -Ysqueeze:on
-one error found
diff --git a/test/files/run/bug4291.check b/test/files/run/bug4291.check
deleted file mode 100644
index c2b58db6e6..0000000000
--- a/test/files/run/bug4291.check
+++ /dev/null
@@ -1,4 +0,0 @@
-scala.collection.immutable.List A
-scala.Option A
-scala.Function1 R
-scala.collection.Traversable That
diff --git a/test/files/run/bug4291.scala b/test/files/run/bug4291.scala
deleted file mode 100644
index 6053c7ac6a..0000000000
--- a/test/files/run/bug4291.scala
+++ /dev/null
@@ -1,10 +0,0 @@
-import scala.tools.partest._
-
-object Test extends SigTest {
- def main(args: Array[String]): Unit = {
- show[List[_]]("apply")
- show[Option[_]]("get")
- show[Function1[_, _]]("apply")
- show[Traversable[_]]("flatMap")
- }
-}
diff --git a/test/files/run/sigtp.check b/test/files/run/sigtp.check
deleted file mode 100644
index 6b961be3d0..0000000000
--- a/test/files/run/sigtp.check
+++ /dev/null
@@ -1,7 +0,0 @@
-public A Bug.key()
-public Bug<A, B> Bug.foo()
-public Bug<A, B> Bug.next()
-public void Bug.next_$eq(Bug<A, B>)
-public abstract A BugBase.key()
-public abstract E BugBase.next()
-public abstract void BugBase.next_$eq(E)
diff --git a/test/files/run/t3857.check b/test/files/run/t3857.check
deleted file mode 100644
index 45e9fb23a6..0000000000
--- a/test/files/run/t3857.check
+++ /dev/null
@@ -1,2 +0,0 @@
-private java.util.Set<java.lang.String> ScalaGeneric.s
-private java.util.Set<java.lang.String> ScalaGeneric2.s
diff --git a/test/files/run/t3857.scala b/test/files/run/t3857.scala
deleted file mode 100644
index 0c8dc996ce..0000000000
--- a/test/files/run/t3857.scala
+++ /dev/null
@@ -1,17 +0,0 @@
-class ScalaGeneric { var s: java.util.Set[String] = _ }
-
-trait ScalaGeneric2Trait { var s: java.util.Set[String] = _ }
-class ScalaGeneric2 extends ScalaGeneric2Trait
-
-object Test extends App {
- println(classOf[ScalaGeneric].getDeclaredField("s").toGenericString)
- // java.util.Set<java.lang.String> ScalaGeneric.s
-
- println(classOf[ScalaGeneric2].getDeclaredField("s").toGenericString)
- // After r24319 this comment was:
- // java.util.Set ScalaGeneric2.s -- no signature should be found because it was mixed in.
- //
- // Having reverted that with this commit, I note the original comment since
- // the original signature is also back.
- // java.util.Set ScalaGeneric2.s -- should be same as above
-}
diff --git a/test/files/run/testblock.scala b/test/files/run/testblock.scala
deleted file mode 100644
index a334b668fd..0000000000
--- a/test/files/run/testblock.scala
+++ /dev/null
@@ -1,33 +0,0 @@
-
-
-
-
-import scala.parallel._
-
-
-
-
-object Test {
-
- def main(args: Array[String]) {
- if (util.Properties.isJavaAtLeast("1.6")) {
- val vendor = util.Properties.javaVmVendor
- if ((vendor contains "Sun") || (vendor contains "Apple")) blockcomp(10)
- }
- }
-
- val lock = new java.util.concurrent.locks.ReentrantLock
-
- def blockcomp(n: Int): Unit = if (n > 0) {
- val (x, y) = par(blockcomp(n - 1), blockcomp(n - 1))
- if (n == 8) blocking { // without this blocking block, deadlock occurs
- lock.lock()
- }
- x()
- y()
- if (n == 8) {
- lock.unlock()
- }
- }
-
-}
diff --git a/test/files/run/testpar.scala b/test/files/run/testpar.scala
deleted file mode 100644
index c4c813ee00..0000000000
--- a/test/files/run/testpar.scala
+++ /dev/null
@@ -1,24 +0,0 @@
-
-
-
-import scala.parallel._
-
-
-
-
-
-object Test {
-
- def main(args: Array[String]) {
- if (util.Properties.isJavaAtLeast("1.6")) {
- val vendor = util.Properties.javaVmVendor
- if ((vendor contains "Sun") || (vendor contains "Apple")) assert(fib(40) == 102334155)
- }
- }
-
- def fib(n: Int): Int = if (n < 3) 1 else if (n < 35) fib(n - 1) + fib(n - 2) else {
- val (p, pp) = par(fib(n - 1), fib(n - 2))
- p() + pp()
- }
-
-}
diff --git a/test/files/specialized/td3651.check b/test/files/specialized/td3651.check
new file mode 100644
index 0000000000..9aea9e0ce5
--- /dev/null
+++ b/test/files/specialized/td3651.check
@@ -0,0 +1,2 @@
+0
+0 \ No newline at end of file
diff --git a/test/files/specialized/td3651.scala b/test/files/specialized/td3651.scala
new file mode 100644
index 0000000000..117710b6dc
--- /dev/null
+++ b/test/files/specialized/td3651.scala
@@ -0,0 +1,19 @@
+
+
+
+
+class Base[@specialized(Double) A](val a: A)
+
+class Derived(override val a: Double) extends Base[Double](a)
+
+object Test {
+ def main(args: Array[String]) {
+ val b: Base[Double] = new Derived(10)
+ b.a
+ println(runtime.BoxesRunTime.doubleBoxCount)
+
+ val der = new Derived(10)
+ der.a
+ println(runtime.BoxesRunTime.doubleBoxCount)
+ }
+}
diff --git a/test/pending/run/bug4291.check b/test/pending/run/bug4291.check
new file mode 100644
index 0000000000..30bacfac28
--- /dev/null
+++ b/test/pending/run/bug4291.check
@@ -0,0 +1,87 @@
+scala.collection.immutable.List
+ (m) public java.lang.Object scala.collection.immutable.List.apply(java.lang.Object) (bridge)
+ (m) public A scala.collection.immutable.List.apply(int) (bridge)
+scala.Option
+ (m) public abstract A scala.Option.get()
+scala.Function1
+ (m) public abstract R scala.Function1.apply(T1)
+scala.collection.Traversable
+ (m) public abstract <B,That> That scala.collection.TraversableLike.map(scala.Function1<A, B>,scala.collection.generic.CanBuildFrom<Repr, B, That>)
+scala.collection.Iterable
+ (m) public abstract <B,That> That scala.collection.TraversableLike.map(scala.Function1<A, B>,scala.collection.generic.CanBuildFrom<Repr, B, That>)
+scala.collection.Seq
+ (m) public abstract <B,That> That scala.collection.TraversableLike.map(scala.Function1<A, B>,scala.collection.generic.CanBuildFrom<Repr, B, That>)
+scala.collection.immutable.Set
+ (m) public abstract <B,That> That scala.collection.TraversableLike.map(scala.Function1<A, B>,scala.collection.generic.CanBuildFrom<Repr, B, That>)
+ (m) public abstract <B,That> That scala.collection.SetLike.map(scala.Function1<A, B>,scala.collection.generic.CanBuildFrom<This, B, That>)
+scala.collection.immutable.Map
+ (m) public abstract <B,That> That scala.collection.TraversableLike.map(scala.Function1<A, B>,scala.collection.generic.CanBuildFrom<Repr, B, That>)
+scala.collection.immutable.Vector
+ (m) public <B,That> That scala.collection.immutable.Vector.map(scala.Function1<A, B>,scala.collection.generic.CanBuildFrom<scala.collection.immutable.Vector<A>, B, That>) (bridge)
+scala.collection.immutable.Range
+ (m) public <B,That> That scala.collection.immutable.Range.map(scala.Function1<java.lang.Object, B>,scala.collection.generic.CanBuildFrom<scala.collection.immutable.IndexedSeq<java.lang.Object>, B, That>) (bridge)
+scala.collection.Traversable
+ (m) public abstract <B,That> That scala.collection.TraversableLike.flatMap(scala.Function1<A, scala.collection.TraversableOnce<B>>,scala.collection.generic.CanBuildFrom<Repr, B, That>)
+scala.collection.Iterable
+ (m) public abstract <B,That> That scala.collection.TraversableLike.flatMap(scala.Function1<A, scala.collection.TraversableOnce<B>>,scala.collection.generic.CanBuildFrom<Repr, B, That>)
+scala.collection.Seq
+ (m) public abstract <B,That> That scala.collection.TraversableLike.flatMap(scala.Function1<A, scala.collection.TraversableOnce<B>>,scala.collection.generic.CanBuildFrom<Repr, B, That>)
+scala.collection.immutable.Set
+ (m) public abstract <B,That> That scala.collection.TraversableLike.flatMap(scala.Function1<A, scala.collection.TraversableOnce<B>>,scala.collection.generic.CanBuildFrom<Repr, B, That>)
+scala.collection.immutable.Map
+ (m) public abstract <B,That> That scala.collection.TraversableLike.flatMap(scala.Function1<A, scala.collection.TraversableOnce<B>>,scala.collection.generic.CanBuildFrom<Repr, B, That>)
+scala.collection.immutable.Vector
+ (m) public <B,That> That scala.collection.immutable.Vector.flatMap(scala.Function1<A, scala.collection.TraversableOnce<B>>,scala.collection.generic.CanBuildFrom<scala.collection.immutable.Vector<A>, B, That>) (bridge)
+scala.collection.immutable.Range
+ (m) public <B,That> That scala.collection.immutable.Range.flatMap(scala.Function1<java.lang.Object, scala.collection.TraversableOnce<B>>,scala.collection.generic.CanBuildFrom<scala.collection.immutable.IndexedSeq<java.lang.Object>, B, That>) (bridge)
+scala.collection.Traversable
+ (m) public abstract Repr scala.collection.TraversableLike.filter(scala.Function1<A, java.lang.Object>)
+scala.collection.Iterable
+ (m) public abstract Repr scala.collection.TraversableLike.filter(scala.Function1<A, java.lang.Object>)
+scala.collection.Seq
+ (m) public abstract Repr scala.collection.TraversableLike.filter(scala.Function1<A, java.lang.Object>)
+scala.collection.immutable.Set
+ (m) public abstract Repr scala.collection.TraversableLike.filter(scala.Function1<A, java.lang.Object>)
+scala.collection.immutable.Map
+ (m) public abstract Repr scala.collection.TraversableLike.filter(scala.Function1<A, java.lang.Object>)
+scala.collection.immutable.Vector
+ (m) public scala.collection.immutable.Vector<A> scala.collection.immutable.Vector.filter(scala.Function1<A, java.lang.Object>) (bridge)
+scala.collection.immutable.Range
+ (m) public scala.collection.immutable.IndexedSeq<java.lang.Object> scala.collection.immutable.Range.filter(scala.Function1<java.lang.Object, java.lang.Object>) (bridge)
+scala.collection.Traversable
+ (m) public abstract A scala.collection.TraversableLike.head()
+ (m) public abstract A scala.collection.generic.GenericTraversableTemplate.head()
+scala.collection.Iterable
+ (m) public abstract A scala.collection.TraversableLike.head()
+ (m) public abstract A scala.collection.generic.GenericTraversableTemplate.head()
+ (m) public abstract A scala.collection.IterableLike.head()
+scala.collection.Seq
+ (m) public abstract A scala.collection.TraversableLike.head()
+ (m) public abstract A scala.collection.generic.GenericTraversableTemplate.head()
+ (m) public abstract A scala.collection.IterableLike.head()
+scala.collection.immutable.Set
+ (m) public abstract A scala.collection.TraversableLike.head()
+ (m) public abstract A scala.collection.generic.GenericTraversableTemplate.head()
+ (m) public abstract A scala.collection.IterableLike.head()
+scala.collection.immutable.Map
+ (m) public abstract A scala.collection.TraversableLike.head()
+ (m) public abstract A scala.collection.generic.GenericTraversableTemplate.head()
+ (m) public abstract A scala.collection.IterableLike.head()
+scala.collection.immutable.Vector
+ (m) public A scala.collection.immutable.Vector.head()
+scala.collection.immutable.Range
+ (m) public java.lang.Object scala.collection.immutable.Range.head() (bridge)
+scala.collection.Traversable
+ (m) public abstract <K> scala.collection.immutable.Map<K, Repr> scala.collection.TraversableLike.groupBy(scala.Function1<A, K>)
+scala.collection.Iterable
+ (m) public abstract <K> scala.collection.immutable.Map<K, Repr> scala.collection.TraversableLike.groupBy(scala.Function1<A, K>)
+scala.collection.Seq
+ (m) public abstract <K> scala.collection.immutable.Map<K, Repr> scala.collection.TraversableLike.groupBy(scala.Function1<A, K>)
+scala.collection.immutable.Set
+ (m) public abstract <K> scala.collection.immutable.Map<K, Repr> scala.collection.TraversableLike.groupBy(scala.Function1<A, K>)
+scala.collection.immutable.Map
+ (m) public abstract <K> scala.collection.immutable.Map<K, Repr> scala.collection.TraversableLike.groupBy(scala.Function1<A, K>)
+scala.collection.immutable.Vector
+ (m) public <K> scala.collection.immutable.Map<K, scala.collection.immutable.Vector<A>> scala.collection.immutable.Vector.groupBy(scala.Function1<A, K>) (bridge)
+scala.collection.immutable.Range
+ (m) public <K> scala.collection.immutable.Map<K, scala.collection.immutable.IndexedSeq<java.lang.Object>> scala.collection.immutable.Range.groupBy(scala.Function1<java.lang.Object, K>) (bridge)
diff --git a/test/pending/run/bug4291.scala b/test/pending/run/bug4291.scala
new file mode 100644
index 0000000000..0213bb2c20
--- /dev/null
+++ b/test/pending/run/bug4291.scala
@@ -0,0 +1,19 @@
+import scala.tools.partest._
+
+object Test extends SigTest {
+ def main(args: Array[String]): Unit = {
+ show[List[_]]("apply")
+ show[Option[_]]("get")
+ show[Function1[_, _]]("apply")
+
+ for (name <- List("map", "flatMap", "filter", "head", "groupBy")) {
+ show[Traversable[_]](name)
+ show[Iterable[_]](name)
+ show[Seq[_]](name)
+ show[Set[_]](name)
+ show[Map[_,_]](name)
+ show[Vector[_]](name)
+ show[Range](name)
+ }
+ }
+}
diff --git a/test/pending/run/sigtp.check b/test/pending/run/sigtp.check
new file mode 100644
index 0000000000..a4d0f55ece
--- /dev/null
+++ b/test/pending/run/sigtp.check
@@ -0,0 +1,11 @@
+BugBase
+ (m) public abstract A BugBase.key()
+ (m) public abstract E BugBase.next()
+ (m) public abstract void BugBase.next_$eq(E)
+Bug
+ (m) public Bug<A, B> Bug.foo()
+ (m) public A Bug.key()
+ (m) public Bug<A, B> Bug.next() (bridge)
+ (m) public void Bug.next_$eq(Bug<A, B>) (bridge)
+ (f) private final A Bug.key
+ (f) private java.lang.Object Bug.next
diff --git a/test/files/run/sigtp.scala b/test/pending/run/sigtp.scala
index f0cac859f5..3e162cfdba 100644
--- a/test/files/run/sigtp.scala
+++ b/test/pending/run/sigtp.scala
@@ -1,3 +1,5 @@
+import scala.tools.partest._
+
trait BugBase [A, E] {
val key: A
var next: E = _
@@ -7,12 +9,9 @@ final class Bug[A, B](val key: A) extends BugBase[A, Bug[A, B]] {
def foo = next
}
-object Test {
- def f(clazz: Class[_]) =
- clazz.getDeclaredMethods.toList.map(_.toGenericString).sorted foreach println
-
+object Test extends SigTest {
def main(args: Array[String]): Unit = {
- f(classOf[Bug[_, _]])
- f(classOf[BugBase[_, _]])
+ show[BugBase[_, _]]()
+ show[Bug[_, _]]()
}
}
diff --git a/test/pending/run/t3857.check b/test/pending/run/t3857.check
new file mode 100644
index 0000000000..520b350ff5
--- /dev/null
+++ b/test/pending/run/t3857.check
@@ -0,0 +1,11 @@
+ScalaGeneric
+ (m) public java.util.Set<java.lang.String> ScalaGeneric.s()
+ (m) public void ScalaGeneric.s_$eq(java.util.Set<java.lang.String>)
+ (f) private java.util.Set<java.lang.String> ScalaGeneric.s
+ScalaGeneric2Trait
+ (m) public abstract java.util.Set<java.lang.String> ScalaGeneric2Trait.s()
+ (m) public abstract void ScalaGeneric2Trait.s_$eq(java.util.Set<java.lang.String>)
+ScalaGeneric2
+ (m) public java.util.Set<java.lang.String> ScalaGeneric2.s() (bridge)
+ (m) public void ScalaGeneric2.s_$eq(java.util.Set<java.lang.String>) (bridge)
+ (f) private java.util.Set<java.lang.String> ScalaGeneric2.s
diff --git a/test/pending/run/t3857.scala b/test/pending/run/t3857.scala
new file mode 100644
index 0000000000..94f52f72fe
--- /dev/null
+++ b/test/pending/run/t3857.scala
@@ -0,0 +1,13 @@
+import scala.tools.partest._
+
+class ScalaGeneric { var s: java.util.Set[String] = _ }
+trait ScalaGeneric2Trait { var s: java.util.Set[String] = _ }
+class ScalaGeneric2 extends ScalaGeneric2Trait { }
+
+object Test extends SigTest {
+ def main(args: Array[String]): Unit = {
+ show[ScalaGeneric]()
+ show[ScalaGeneric2Trait]()
+ show[ScalaGeneric2]()
+ }
+}