diff options
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]() + } +} |