diff options
343 files changed, 9089 insertions, 3521 deletions
@@ -1252,6 +1252,7 @@ QUICK BUILD (QUICK) <pathelement location="${build-quick.dir}/classes/partest"/> <pathelement location="${ant.jar}"/> <path refid="forkjoin.classpath"/> + <path refid="asm.classpath"/> <pathelement location="${scalacheck.jar}"/> </compilationpath> </scalacfork> diff --git a/project/Packaging.scala b/project/Packaging.scala index 6cb51a10a6..b0060283ac 100644 --- a/project/Packaging.scala +++ b/project/Packaging.scala @@ -24,7 +24,7 @@ trait Packaging { self: ScalaBuild.type => genBinQuick <<= genBinTask(genBinRunner, binDir in genBinQuick, fullClasspath in Runtime in genBinQuick, true), runManmakerMan <<= runManmakerTask(fullClasspath in Runtime in manmaker, runner in manmaker, "scala.tools.docutil.EmitManPage", "man1", ".1"), runManmakerHtml <<= runManmakerTask(fullClasspath in Runtime in manmaker, runner in manmaker, "scala.tools.docutil.EmitHtml", "doc", ".html"), - // TODO - We could *really* clean this up in many ways. Let's look into making a a Seq of "direct jars" (scalaLibrary, scalaCompiler, jline, scalap) + // TODO - We could *really* clean this up in many ways. Let's look into making a Seq of "direct jars" (scalaLibrary, scalaCompiler, jline, scalap) // a seq of "plugin jars" (continuationsPlugin) and "binaries" (genBin) and "documentation" mappings (genBin) that this can aggregate. // really need to figure out a better way to pull jline + jansi. makeDistMappings <<= (genBin, diff --git a/src/compiler/scala/reflect/reify/Taggers.scala b/src/compiler/scala/reflect/reify/Taggers.scala index af0341fd38..9659134e5b 100644 --- a/src/compiler/scala/reflect/reify/Taggers.scala +++ b/src/compiler/scala/reflect/reify/Taggers.scala @@ -58,7 +58,7 @@ abstract class Taggers { val result = tpe match { case coreTpe if coreTags contains coreTpe => - val ref = if (tagModule.owner.isPackageClass) Ident(tagModule) else Select(prefix, tagModule.name) + val ref = if (tagModule.isTopLevel) Ident(tagModule) else Select(prefix, tagModule.name) Select(ref, coreTags(coreTpe)) case _ => translatingReificationErrors(materializer) diff --git a/src/compiler/scala/reflect/reify/package.scala b/src/compiler/scala/reflect/reify/package.scala index 7be57c0cb7..78f85c2634 100644 --- a/src/compiler/scala/reflect/reify/package.scala +++ b/src/compiler/scala/reflect/reify/package.scala @@ -56,7 +56,7 @@ package object reify { if (concrete) throw new ReificationException(enclosingMacroPosition, "tpe %s is an unresolved spliceable type".format(tpe)) } - tpe.normalize match { + tpe.dealiasWiden match { case TypeRef(_, ArrayClass, componentTpe :: Nil) => val componentErasure = reifyRuntimeClass(global)(typer0, componentTpe, concrete) gen.mkMethodCall(arrayClassMethod, List(componentErasure)) diff --git a/src/compiler/scala/tools/nsc/CompileServer.scala b/src/compiler/scala/tools/nsc/CompileServer.scala index e4c250a3d9..72e8cc69c7 100644 --- a/src/compiler/scala/tools/nsc/CompileServer.scala +++ b/src/compiler/scala/tools/nsc/CompileServer.scala @@ -87,10 +87,11 @@ class StandardCompileServer extends SocketServer { val args = input.split("\0", -1).toList val newSettings = new FscSettings(fscError) - this.verbose = newSettings.verbose.value val command = new OfflineCompilerCommand(args, newSettings) + this.verbose = newSettings.verbose.value info("Settings after normalizing paths: " + newSettings) + if (!command.files.isEmpty) info("Input files after normalizing paths: " + (command.files mkString ",")) printMemoryStats() // Update the idle timeout if given @@ -168,11 +169,22 @@ object CompileServer extends StandardCompileServer { /** A directory holding redirected output */ private lazy val redirectDir = (compileSocket.tmpDir / "output-redirects").createDirectory() - private def redirect(setter: PrintStream => Unit, filename: String) { - setter(new PrintStream((redirectDir / filename).createFile().bufferedOutput())) - } + private def createRedirect(filename: String) = + new PrintStream((redirectDir / filename).createFile().bufferedOutput()) + + def main(args: Array[String]) = + execute(() => (), args) - def main(args: Array[String]) { + /** + * Used for internal testing. The callback is called upon + * server start, notifying the caller that the server is + * ready to run. WARNING: the callback runs in the + * server's thread, blocking the server from doing any work + * until the callback is finished. Callbacks should be kept + * simple and clients should not try to interact with the + * server while the callback is processing. + */ + def execute(startupCallback : () => Unit, args: Array[String]) { val debug = args contains "-v" if (debug) { @@ -180,14 +192,16 @@ object CompileServer extends StandardCompileServer { echo("Redirect dir is " + redirectDir) } - redirect(System.setOut, "scala-compile-server-out.log") - redirect(System.setErr, "scala-compile-server-err.log") - System.err.println("...starting server on socket "+port+"...") - System.err.flush() - compileSocket setPort port - run() + Console.withErr(createRedirect("scala-compile-server-err.log")) { + Console.withOut(createRedirect("scala-compile-server-out.log")) { + Console.err.println("...starting server on socket "+port+"...") + Console.err.flush() + compileSocket setPort port + startupCallback() + run() - compileSocket deletePort port - sys exit 0 + compileSocket deletePort port + } + } } } diff --git a/src/compiler/scala/tools/nsc/CompileSocket.scala b/src/compiler/scala/tools/nsc/CompileSocket.scala index 6b55537195..b9f62f49b3 100644 --- a/src/compiler/scala/tools/nsc/CompileSocket.scala +++ b/src/compiler/scala/tools/nsc/CompileSocket.scala @@ -68,7 +68,7 @@ class CompileSocket extends CompileOutputCommon { /** A temporary directory to use */ val tmpDir = { val udir = Option(Properties.userName) getOrElse "shared" - val f = (Path(Properties.tmpDir) / "scala-devel" / udir).createDirectory() + val f = (Path(Properties.tmpDir) / ("scala-devel" + udir)).createDirectory() if (f.isDirectory && f.canWrite) { info("[Temp directory: " + f + "]") diff --git a/src/compiler/scala/tools/nsc/Global.scala b/src/compiler/scala/tools/nsc/Global.scala index 05d0bcf6b0..d751669612 100644 --- a/src/compiler/scala/tools/nsc/Global.scala +++ b/src/compiler/scala/tools/nsc/Global.scala @@ -1378,7 +1378,7 @@ class Global(var currentSettings: Settings, var reporter: Reporter) def compiles(sym: Symbol): Boolean = if (sym == NoSymbol) false else if (symSource.isDefinedAt(sym)) true - else if (!sym.owner.isPackageClass) compiles(sym.enclosingTopLevelClass) + else if (!sym.isTopLevel) compiles(sym.enclosingTopLevelClass) else if (sym.isModuleClass) compiles(sym.sourceModule) else false diff --git a/src/compiler/scala/tools/nsc/OfflineCompilerCommand.scala b/src/compiler/scala/tools/nsc/OfflineCompilerCommand.scala index 2f4975e681..8c54c4a1b0 100644 --- a/src/compiler/scala/tools/nsc/OfflineCompilerCommand.scala +++ b/src/compiler/scala/tools/nsc/OfflineCompilerCommand.scala @@ -33,7 +33,7 @@ class OfflineCompilerCommand(arguments: List[String], settings: FscSettings) ext } else { // Otherwise we're on the server and will use it to absolutize the paths. - settings.absolutize(currentDir.value) + settings.absolutize() } } diff --git a/src/compiler/scala/tools/nsc/ast/DocComments.scala b/src/compiler/scala/tools/nsc/ast/DocComments.scala index c9bf131b79..7e6a323d3d 100755 --- a/src/compiler/scala/tools/nsc/ast/DocComments.scala +++ b/src/compiler/scala/tools/nsc/ast/DocComments.scala @@ -320,7 +320,7 @@ trait DocComments { self: Global => } /** Expand variable occurrences in string `str`, until a fix point is reached or - * a expandLimit is exceeded. + * an expandLimit is exceeded. * * @param str The string to be expanded * @param sym The symbol for which doc comments are generated diff --git a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala index 744644fd49..61c65c211b 100644 --- a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala +++ b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala @@ -1584,14 +1584,9 @@ self => * }}} */ def argumentExprs(): List[Tree] = { - def args(): List[Tree] = commaSeparated { - val maybeNamed = isIdent - expr() match { - case a @ Assign(id, rhs) if maybeNamed => - atPos(a.pos) { AssignOrNamedArg(id, rhs) } - case e => e - } - } + def args(): List[Tree] = commaSeparated( + if (isIdent) treeInfo.assignmentToMaybeNamedArg(expr()) else expr() + ) in.token match { case LBRACE => List(blockExpr()) case LPAREN => inParens(if (in.token == RPAREN) Nil else args()) @@ -1962,11 +1957,11 @@ self => /** Drop `private` modifier when followed by a qualifier. * Contract `abstract` and `override` to ABSOVERRIDE */ - private def normalize(mods: Modifiers): Modifiers = + private def normalizeModifers(mods: Modifiers): Modifiers = if (mods.isPrivate && mods.hasAccessBoundary) - normalize(mods &~ Flags.PRIVATE) + normalizeModifers(mods &~ Flags.PRIVATE) else if (mods hasAllFlags (Flags.ABSTRACT | Flags.OVERRIDE)) - normalize(mods &~ (Flags.ABSTRACT | Flags.OVERRIDE) | Flags.ABSOVERRIDE) + normalizeModifers(mods &~ (Flags.ABSTRACT | Flags.OVERRIDE) | Flags.ABSOVERRIDE) else mods @@ -2011,7 +2006,7 @@ self => * AccessModifier ::= (private | protected) [AccessQualifier] * }}} */ - def accessModifierOpt(): Modifiers = normalize { + def accessModifierOpt(): Modifiers = normalizeModifers { in.token match { case m @ (PRIVATE | PROTECTED) => in.nextToken() ; accessQualifierOpt(Modifiers(flagTokens(m))) case _ => NoMods @@ -2025,7 +2020,7 @@ self => * | override * }}} */ - def modifiers(): Modifiers = normalize { + def modifiers(): Modifiers = normalizeModifers { def loop(mods: Modifiers): Modifiers = in.token match { case PRIVATE | PROTECTED => loop(accessQualifierOpt(addMod(mods, flagTokens(in.token), tokenRange(in)))) diff --git a/src/compiler/scala/tools/nsc/ast/parser/TreeBuilder.scala b/src/compiler/scala/tools/nsc/ast/parser/TreeBuilder.scala index 39270719fb..5497719f89 100644 --- a/src/compiler/scala/tools/nsc/ast/parser/TreeBuilder.scala +++ b/src/compiler/scala/tools/nsc/ast/parser/TreeBuilder.scala @@ -171,15 +171,10 @@ abstract class TreeBuilder { /** Create tree representing (unencoded) binary operation expression or pattern. */ def makeBinop(isExpr: Boolean, left: Tree, op: TermName, right: Tree, opPos: Position): Tree = { - def mkNamed(args: List[Tree]) = - if (isExpr) args map { - case a @ Assign(id @ Ident(name), rhs) => - atPos(a.pos) { AssignOrNamedArg(id, rhs) } - case e => e - } else args + def mkNamed(args: List[Tree]) = if (isExpr) args map treeInfo.assignmentToMaybeNamedArg else args val arguments = right match { case Parens(args) => mkNamed(args) - case _ => List(right) + case _ => List(right) } if (isExpr) { if (treeInfo.isLeftAssoc(op)) { @@ -254,7 +249,7 @@ abstract class TreeBuilder { /** Create tree representing a while loop */ def makeWhile(lname: TermName, cond: Tree, body: Tree): Tree = { - val continu = atPos(o2p(body.pos.endOrPoint)) { Apply(Ident(lname), Nil) } + val continu = atPos(o2p(body.pos pointOrElse wrappingPos(List(cond, body)).pos.endOrPoint)) { Apply(Ident(lname), Nil) } val rhs = If(cond, Block(List(body), continu), Literal(Constant())) LabelDef(lname, Nil, rhs) } diff --git a/src/compiler/scala/tools/nsc/backend/icode/GenICode.scala b/src/compiler/scala/tools/nsc/backend/icode/GenICode.scala index 2ea26ddaa9..3363f19025 100644 --- a/src/compiler/scala/tools/nsc/backend/icode/GenICode.scala +++ b/src/compiler/scala/tools/nsc/backend/icode/GenICode.scala @@ -835,13 +835,18 @@ abstract class GenICode extends SubComponent { generatedType = toTypeKind(sym.info) val hostClass = findHostClass(qualifier.tpe, sym) log(s"Host class of $sym with qual $qualifier (${qualifier.tpe}) is $hostClass") + val qualSafeToElide = treeInfo isQualifierSafeToElide qualifier + + def genLoadQualUnlessElidable: Context = + if (qualSafeToElide) ctx else genLoadQualifier(tree, ctx) if (sym.isModule) { - genLoadModule(ctx, tree) + genLoadModule(genLoadQualUnlessElidable, tree) } else if (sym.isStaticMember) { - ctx.bb.emit(LOAD_FIELD(sym, true) setHostClass hostClass, tree.pos) - ctx + val ctx1 = genLoadQualUnlessElidable + ctx1.bb.emit(LOAD_FIELD(sym, true) setHostClass hostClass, tree.pos) + ctx1 } else { val ctx1 = genLoadQualifier(tree, ctx) ctx1.bb.emit(LOAD_FIELD(sym, false) setHostClass hostClass, tree.pos) diff --git a/src/compiler/scala/tools/nsc/backend/icode/ICodeCheckers.scala b/src/compiler/scala/tools/nsc/backend/icode/ICodeCheckers.scala index 95913c7768..5d32795e24 100644 --- a/src/compiler/scala/tools/nsc/backend/icode/ICodeCheckers.scala +++ b/src/compiler/scala/tools/nsc/backend/icode/ICodeCheckers.scala @@ -464,7 +464,7 @@ abstract class ICodeCheckers { subtypeTest(elem, kind) pushStack(elem) case (a, b) => - icodeError(" expected and INT and a array reference, but " + + icodeError(" expected an INT and an array reference, but " + a + ", " + b + " found"); } diff --git a/src/compiler/scala/tools/nsc/backend/icode/TypeKinds.scala b/src/compiler/scala/tools/nsc/backend/icode/TypeKinds.scala index 84f5fe2678..a32b00f385 100644 --- a/src/compiler/scala/tools/nsc/backend/icode/TypeKinds.scala +++ b/src/compiler/scala/tools/nsc/backend/icode/TypeKinds.scala @@ -368,10 +368,10 @@ trait TypeKinds { self: ICodes => /** Return the TypeKind of the given type * - * Call to .normalize fixes #3003 (follow type aliases). Otherwise, + * Call to dealiasWiden fixes #3003 (follow type aliases). Otherwise, * arrayOrClassType below would return ObjectReference. */ - def toTypeKind(t: Type): TypeKind = t.normalize match { + def toTypeKind(t: Type): TypeKind = t.dealiasWiden match { case ThisType(ArrayClass) => ObjectReference case ThisType(sym) => REFERENCE(sym) case SingleType(_, sym) => primitiveOrRefType(sym) diff --git a/src/compiler/scala/tools/nsc/backend/jvm/GenASM.scala b/src/compiler/scala/tools/nsc/backend/jvm/GenASM.scala index 92d732ed04..45c366cc69 100644 --- a/src/compiler/scala/tools/nsc/backend/jvm/GenASM.scala +++ b/src/compiler/scala/tools/nsc/backend/jvm/GenASM.scala @@ -1036,7 +1036,7 @@ abstract class GenASM extends SubComponent with BytecodeWriters with GenJVMASM { if (needsAnnotation) { val c = Constant(RemoteExceptionClass.tpe) val arg = Literal(c) setType c.tpe - meth.addAnnotation(ThrowsClass, arg) + meth.addAnnotation(appliedType(ThrowsClass, c.tpe), arg) } } @@ -1274,7 +1274,6 @@ abstract class GenASM extends SubComponent with BytecodeWriters with GenJVMASM { // Additional interface parents based on annotations and other cues def newParentForAttr(attr: Symbol): Option[Symbol] = attr match { - case CloneableAttr => Some(CloneableClass) case RemoteAttr => Some(RemoteInterfaceClass) case _ => None } diff --git a/src/compiler/scala/tools/nsc/backend/opt/DeadCodeElimination.scala b/src/compiler/scala/tools/nsc/backend/opt/DeadCodeElimination.scala index f7e743a6f1..0282457a12 100644 --- a/src/compiler/scala/tools/nsc/backend/opt/DeadCodeElimination.scala +++ b/src/compiler/scala/tools/nsc/backend/opt/DeadCodeElimination.scala @@ -144,6 +144,8 @@ abstract class DeadCodeElimination extends SubComponent { } } if (necessary) worklist += ((bb, idx)) + case LOAD_MODULE(sym) if isLoadNeeded(sym) => + worklist += ((bb, idx)) // SI-4859 Module initialization might side-effect. case _ => () } rd = rdef.interpret(bb, idx, rd) diff --git a/src/compiler/scala/tools/nsc/dependencies/Changes.scala b/src/compiler/scala/tools/nsc/dependencies/Changes.scala index b3cacee20a..7807f0ba03 100644 --- a/src/compiler/scala/tools/nsc/dependencies/Changes.scala +++ b/src/compiler/scala/tools/nsc/dependencies/Changes.scala @@ -90,11 +90,11 @@ abstract class Changes { } else !sym1.isTypeParameter || !changedTypeParams.contains(sym1.fullName) + // @M! normalize reduces higher-kinded case to PolyType's testSymbols && sameType(pre1, pre2) && (sym1.variance == sym2.variance) && ((tp1.isHigherKinded && tp2.isHigherKinded && tp1.normalize =:= tp2.normalize) || sameTypes(args1, args2)) - // @M! normalize reduces higher-kinded case to PolyType's case (RefinedType(parents1, ref1), RefinedType(parents2, ref2)) => def isSubScope(s1: Scope, s2: Scope): Boolean = s2.toList.forall { diff --git a/src/compiler/scala/tools/nsc/doc/html/SyntaxHigh.scala b/src/compiler/scala/tools/nsc/doc/html/SyntaxHigh.scala index 2783a27811..db9edd165d 100644 --- a/src/compiler/scala/tools/nsc/doc/html/SyntaxHigh.scala +++ b/src/compiler/scala/tools/nsc/doc/html/SyntaxHigh.scala @@ -29,8 +29,8 @@ private[html] object SyntaxHigh { /** Annotations, sorted alphabetically */ val annotations = Array( "BeanProperty", "SerialVersionUID", - "beanGetter", "beanSetter", "bridge", "cloneable", - "deprecated", "deprecatedName", + "beanGetter", "beanSetter", "bridge", + "deprecated", "deprecatedName", "deprecatedOverriding", "deprecatedInheritance", "elidable", "field", "getter", "inline", "migration", "native", "noinline", "param", "remote", "setter", "specialized", "strictfp", "switch", diff --git a/src/compiler/scala/tools/nsc/doc/html/page/Template.scala b/src/compiler/scala/tools/nsc/doc/html/page/Template.scala index ff64fb4c0f..0685f9ad70 100644 --- a/src/compiler/scala/tools/nsc/doc/html/page/Template.scala +++ b/src/compiler/scala/tools/nsc/doc/html/page/Template.scala @@ -760,7 +760,7 @@ class Template(universe: doc.Universe, generator: DiagramGenerator, tpl: DocTemp if (isReduced) NodeSeq.Empty else { def paramsToHtml(vlsss: List[List[ValueParam]]): NodeSeq = { def param0(vl: ValueParam): NodeSeq = - // notice the }{ in the next lines, they are necessary to avoid a undesired withspace in output + // notice the }{ in the next lines, they are necessary to avoid an undesired withspace in output <span name={ vl.name }>{ Text(vl.name) }{ Text(": ") ++ typeToHtml(vl.resultType, hasLinks) }{ diff --git a/src/compiler/scala/tools/nsc/doc/model/IndexModelFactory.scala b/src/compiler/scala/tools/nsc/doc/model/IndexModelFactory.scala index 1d6063255d..1272906df5 100755 --- a/src/compiler/scala/tools/nsc/doc/model/IndexModelFactory.scala +++ b/src/compiler/scala/tools/nsc/doc/model/IndexModelFactory.scala @@ -18,7 +18,7 @@ object IndexModelFactory { object result extends mutable.HashMap[Char,SymbolMap] { /* symbol name ordering */ - implicit def orderingMap = math.Ordering.String.on { x: String => x.toLowerCase } + implicit def orderingMap = math.Ordering.String def addMember(d: MemberEntity) = { val firstLetter = { diff --git a/src/compiler/scala/tools/nsc/doc/model/ModelFactoryImplicitSupport.scala b/src/compiler/scala/tools/nsc/doc/model/ModelFactoryImplicitSupport.scala index 5d5d7d483c..c00afee064 100644 --- a/src/compiler/scala/tools/nsc/doc/model/ModelFactoryImplicitSupport.scala +++ b/src/compiler/scala/tools/nsc/doc/model/ModelFactoryImplicitSupport.scala @@ -65,7 +65,7 @@ trait ModelFactoryImplicitSupport { * class A[T] * class B extends A[Int] * class C extends A[String] - * implicit def pimpA[T: Numeric](a: A[T]): D + * implicit def enrichA[T: Numeric](a: A[T]): D * }}} * For B, no constraints are generated as Numeric[Int] is already in the default scope. On the other hand, for the * conversion from C to D, depending on -implicits-show-all, the conversion can: @@ -121,13 +121,13 @@ trait ModelFactoryImplicitSupport { * What? in details: * - say we start from a class A[T1, T2, T3, T4] * - we have an implicit function (view) in scope: - * def pimpA[T3 <: Long, T4](a: A[Int, Foo[Bar[X]], T3, T4])(implicit ev1: TypeTag[T4], ev2: Numeric[T4]): PimpedA - * - A is converted to PimpedA ONLY if a couple of constraints are satisfied: + * def enrichA[T3 <: Long, T4](a: A[Int, Foo[Bar[X]], T3, T4])(implicit ev1: TypeTag[T4], ev2: Numeric[T4]): EnrichedA + * - A is converted to EnrichedA ONLY if a couple of constraints are satisfied: * * T1 must be equal to Int * * T2 must be equal to Foo[Bar[X]] * * T3 must be upper bounded by Long * * there must be evidence of Numeric[T4] and a TypeTag[T4] within scope - * - the final type is PimpedA and A therefore inherits a couple of members from pimpedA + * - the final type is EnrichedA and A therefore inherits a couple of members from enrichA * * How? * some notes: @@ -495,11 +495,11 @@ trait ModelFactoryImplicitSupport { * returns the simplified type of the view * * for the example view: - * implicit def pimpMyClass[T](a: MyClass[T])(implicit ev: Numeric[T]): PimpedMyClass[T] + * implicit def enrichMyClass[T](a: MyClass[T])(implicit ev: Numeric[T]): EnrichedMyClass[T] * the implicit view result type is: - * (a: MyClass[T])(implicit ev: Numeric[T]): PimpedMyClass[T] + * (a: MyClass[T])(implicit ev: Numeric[T]): EnrichedMyClass[T] * and the simplified type will be: - * MyClass[T] => PimpedMyClass[T] + * MyClass[T] => EnrichedMyClass[T] */ def removeImplicitParameters(viewType: Type): (Type, List[Type]) = { diff --git a/src/compiler/scala/tools/nsc/interactive/Global.scala b/src/compiler/scala/tools/nsc/interactive/Global.scala index e3d59d83ea..2f63fbbff2 100644 --- a/src/compiler/scala/tools/nsc/interactive/Global.scala +++ b/src/compiler/scala/tools/nsc/interactive/Global.scala @@ -948,7 +948,7 @@ class Global(settings: Settings, _reporter: Reporter, projectName: String = "") for (sym <- ownerTpe.members) addTypeMember(sym, pre, sym.owner != ownerTpe.typeSymbol, NoSymbol) members.allMembers #:: { - //print("\nadd pimped") + //print("\nadd enrichment") val applicableViews: List[SearchResult] = if (ownerTpe.isErroneous) List() else new ImplicitSearch( diff --git a/src/compiler/scala/tools/nsc/interpreter/CompletionOutput.scala b/src/compiler/scala/tools/nsc/interpreter/CompletionOutput.scala index c5bb8494ce..d24ad60974 100644 --- a/src/compiler/scala/tools/nsc/interpreter/CompletionOutput.scala +++ b/src/compiler/scala/tools/nsc/interpreter/CompletionOutput.scala @@ -75,7 +75,7 @@ trait CompletionOutput { } def methodString() = - method.keyString + " " + method.nameString + (method.info.normalize match { + method.keyString + " " + method.nameString + (method.info.dealiasWiden match { case NullaryMethodType(resType) => ": " + typeToString(resType) case PolyType(tparams, resType) => tparamsString(tparams) + typeToString(resType) case mt @ MethodType(_, _) => methodTypeToString(mt) diff --git a/src/compiler/scala/tools/nsc/interpreter/IMain.scala b/src/compiler/scala/tools/nsc/interpreter/IMain.scala index 4f23d9902e..7f177c7ce4 100644 --- a/src/compiler/scala/tools/nsc/interpreter/IMain.scala +++ b/src/compiler/scala/tools/nsc/interpreter/IMain.scala @@ -386,8 +386,8 @@ class IMain(initialSettings: Settings, protected val out: JPrintWriter) extends // be what people want so I'm waiting until I can do it better. exitingTyper { req.defines filterNot (s => req.defines contains s.companionSymbol) foreach { newSym => - val companion = newSym.name.companionName - replScope lookup companion andAlso { oldSym => + val oldSym = replScope lookup newSym.name.companionName + if (Seq(oldSym, newSym).permutations exists { case Seq(s1, s2) => s1.isClass && s2.isModule }) { replwarn(s"warning: previously defined $oldSym is not a companion to $newSym.") replwarn("Companions must be defined together; you may wish to use :paste mode for this.") } @@ -521,8 +521,8 @@ class IMain(initialSettings: Settings, protected val out: JPrintWriter) extends Right(buildRequest(line, trees)) } - // normalize non-public types so we don't see protected aliases like Self - def normalizeNonPublic(tp: Type) = tp match { + // dealias non-public types so we don't see protected aliases like Self + def dealiasNonPublic(tp: Type) = tp match { case TypeRef(_, sym, _) if sym.isAliasType && !sym.isPublic => tp.dealias case _ => tp } @@ -980,7 +980,7 @@ class IMain(initialSettings: Settings, protected val out: JPrintWriter) extends def cleanTypeAfterTyper(sym: => Symbol): Type = { exitingTyper( - normalizeNonPublic( + dealiasNonPublic( dropNullaryMethod( sym.tpe_* ) diff --git a/src/compiler/scala/tools/nsc/interpreter/JLineReader.scala b/src/compiler/scala/tools/nsc/interpreter/JLineReader.scala index a620c7c75a..5d41f1bbb4 100644 --- a/src/compiler/scala/tools/nsc/interpreter/JLineReader.scala +++ b/src/compiler/scala/tools/nsc/interpreter/JLineReader.scala @@ -34,6 +34,11 @@ class JLineReader(_completion: => Completion) extends InteractiveReader { } class JLineConsoleReader extends ConsoleReader with ConsoleReaderHelper { + // working around protected/trait/java insufficiencies. + def goBack(num: Int): Unit = back(num) + if ((history: History) ne NoHistory) + this setHistory history + def readOneKey(prompt: String) = { this.print(prompt) this.flush() @@ -45,8 +50,6 @@ class JLineReader(_completion: => Completion) extends InteractiveReader { // A hook for running code after the repl is done initializing. lazy val postInit: Unit = { this setBellEnabled false - if ((history: History) ne NoHistory) - this setHistory history if (completion ne NoCompletion) { val argCompletor: ArgumentCompleter = diff --git a/src/compiler/scala/tools/nsc/io/Lexer.scala b/src/compiler/scala/tools/nsc/io/Lexer.scala index e843f8d5ce..aed6e882e6 100644 --- a/src/compiler/scala/tools/nsc/io/Lexer.scala +++ b/src/compiler/scala/tools/nsc/io/Lexer.scala @@ -7,8 +7,8 @@ import java.io.Reader */ object Lexer { - /** An exception raised if a if input does not correspond to what's expected - * @param rdr the lexer form which the bad input is read + /** An exception raised if an input does not correspond to what's expected + * @param rdr the lexer from which the bad input is read * @param msg the error message */ class MalformedInput(val rdr: Lexer, val msg: String) extends Exception("Malformed JSON input at "+rdr.tokenPos+": "+msg) diff --git a/src/compiler/scala/tools/nsc/settings/FscSettings.scala b/src/compiler/scala/tools/nsc/settings/FscSettings.scala index 14b398e50a..34c8e8df9a 100644 --- a/src/compiler/scala/tools/nsc/settings/FscSettings.scala +++ b/src/compiler/scala/tools/nsc/settings/FscSettings.scala @@ -39,13 +39,24 @@ class FscSettings(error: String => Unit) extends Settings(error) { d, dependencyfile, pluginsDir, Ygenjavap ) - /** All user set settings rewritten with absolute paths. */ - def absolutize(root: Path) { - def rewrite(p: String) = (root resolve Path(p)).normalize.path + override def processArguments(arguments: List[String], processAll: Boolean): (Boolean, List[String]) = { + val (r, args) = super.processArguments(arguments, processAll) + // we need to ensure the files specified with relative locations are absolutized based on the currentDir + (r, args map {a => absolutizePath(a)}) + } + + /** + * Take an individual path and if it's not absolute turns it into an absolute path based on currentDir. + * If it's already absolute then it's left alone. + */ + private[this] def absolutizePath(p: String) = (Path(currentDir.value) resolve Path(p)).normalize.path + + /** All user set settings rewritten with absolute paths based on currentDir */ + def absolutize() { userSetSettings foreach { - case p: OutputSetting => p.outputDirs setSingleOutput AbstractFile.getDirectory(rewrite(p.value)) - case p: PathSetting => p.value = ClassPath.map(p.value, rewrite) - case p: StringSetting => if (holdsPath(p)) p.value = rewrite(p.value) + case p: OutputSetting => p.outputDirs setSingleOutput AbstractFile.getDirectory(absolutizePath(p.value)) + case p: PathSetting => p.value = ClassPath.map(p.value, absolutizePath) + case p: StringSetting => if (holdsPath(p)) p.value = absolutizePath(p.value) case _ => () } } diff --git a/src/compiler/scala/tools/nsc/settings/MutableSettings.scala b/src/compiler/scala/tools/nsc/settings/MutableSettings.scala index 748c6069f0..0e44ef63a1 100644 --- a/src/compiler/scala/tools/nsc/settings/MutableSettings.scala +++ b/src/compiler/scala/tools/nsc/settings/MutableSettings.scala @@ -213,6 +213,7 @@ class MutableSettings(val errorFn: String => Unit) def OutputSetting(outputDirs: OutputDirs, default: String) = add(new OutputSetting(outputDirs, default)) def PhasesSetting(name: String, descr: String, default: String = "") = add(new PhasesSetting(name, descr, default)) def StringSetting(name: String, arg: String, descr: String, default: String) = add(new StringSetting(name, arg, descr, default)) + def ScalaVersionSetting(name: String, arg: String, descr: String, default: ScalaVersion) = add(new ScalaVersionSetting(name, arg, descr, default)) def PathSetting(name: String, descr: String, default: String): PathSetting = { val prepend = StringSetting(name + "/p", "", "", "").internalOnly() val append = StringSetting(name + "/a", "", "", "").internalOnly() @@ -478,6 +479,35 @@ class MutableSettings(val errorFn: String => Unit) withHelpSyntax(name + " <" + arg + ">") } + /** A setting represented by a Scala version, (`default` unless set) */ + class ScalaVersionSetting private[nsc]( + name: String, + val arg: String, + descr: String, + default: ScalaVersion) + extends Setting(name, descr) { + import ScalaVersion._ + + type T = ScalaVersion + protected var v: T = NoScalaVersion + + override def tryToSet(args: List[String]) = { + value = default + Some(args) + } + + override def tryToSetColon(args: List[String]) = args match { + case Nil => value = default; Some(Nil) + case x :: xs => value = ScalaVersion(x, errorFn) ; Some(xs) + } + + override def tryToSetFromPropertyValue(s: String) = tryToSet(List(s)) + + def unparse: List[String] = if (value == NoScalaVersion) Nil else List(s"${name}:${value.unparse}") + + withHelpSyntax(s"${name}:<${arg}>") + } + class PathSetting private[nsc]( name: String, descr: String, diff --git a/src/compiler/scala/tools/nsc/settings/ScalaSettings.scala b/src/compiler/scala/tools/nsc/settings/ScalaSettings.scala index 0875c1879a..9fe3016c02 100644 --- a/src/compiler/scala/tools/nsc/settings/ScalaSettings.scala +++ b/src/compiler/scala/tools/nsc/settings/ScalaSettings.scala @@ -82,8 +82,7 @@ trait ScalaSettings extends AbsScalaSettings val logFreeTerms = BooleanSetting ("-Xlog-free-terms", "Print a message when reification creates a free term.") val logFreeTypes = BooleanSetting ("-Xlog-free-types", "Print a message when reification resorts to generating a free type.") val maxClassfileName = IntSetting ("-Xmax-classfile-name", "Maximum filename length for generated classes", 255, Some((72, 255)), _ => None) - val Xmigration28 = BooleanSetting ("-Xmigration", "Warn about constructs whose behavior may have changed between 2.7 and 2.8."). - withDeprecationMessage("This setting is no longer useful and will be removed. Please remove it from your build.") + val Xmigration = ScalaVersionSetting("-Xmigration", "version", "Warn about constructs whose behavior may have changed since version.", AnyScalaVersion) val nouescape = BooleanSetting ("-Xno-uescape", "Disable handling of \\u unicode escapes.") val Xnojline = BooleanSetting ("-Xnojline", "Do not use JLine for editing.") val Xverify = BooleanSetting ("-Xverify", "Verify generic signatures in generated bytecode (asm backend only.)") diff --git a/src/compiler/scala/tools/nsc/settings/ScalaVersion.scala b/src/compiler/scala/tools/nsc/settings/ScalaVersion.scala new file mode 100644 index 0000000000..d6a0149411 --- /dev/null +++ b/src/compiler/scala/tools/nsc/settings/ScalaVersion.scala @@ -0,0 +1,194 @@ +/* NSC -- new Scala compiler + * Copyright 2005-2013 LAMP/EPFL + * @author James Iry + */ +// $Id$ + +package scala.tools.nsc.settings + +/** + * Represents a single Scala version in a manner that + * supports easy comparison and sorting. + */ +abstract class ScalaVersion extends Ordered[ScalaVersion] { + def unparse: String +} + +/** + * A scala version that sorts higher than all actual versions + */ +case object NoScalaVersion extends ScalaVersion { + def unparse = "none" + + def compare(that: ScalaVersion): Int = that match { + case NoScalaVersion => 0 + case _ => 1 + } +} + +/** + * A specific Scala version, not one of the magic min/max versions. An SpecificScalaVersion + * may or may not be a released version - i.e. this same class is used to represent + * final, release candidate, milestone, and development builds. The build argument is used + * to segregate builds + */ +case class SpecificScalaVersion(major: Int, minor: Int, rev: Int, build: ScalaBuild) extends ScalaVersion { + def unparse = s"${major}.${minor}.${rev}.${build.unparse}" + + def compare(that: ScalaVersion): Int = that match { + case SpecificScalaVersion(thatMajor, thatMinor, thatRev, thatBuild) => + // this could be done more cleanly by importing scala.math.Ordering.Implicits, but we have to do these + // comparisons a lot so I'm using brute force direct style code + if (major < thatMajor) -1 + else if (major > thatMajor) 1 + else if (minor < thatMinor) -1 + else if (minor > thatMinor) 1 + else if (rev < thatRev) -1 + else if (rev > thatRev) 1 + else build compare thatBuild + case AnyScalaVersion => 1 + case NoScalaVersion => -1 + } +} + +/** + * A Scala version that sorts lower than all actual versions + */ +case object AnyScalaVersion extends ScalaVersion { + def unparse = "any" + + def compare(that: ScalaVersion): Int = that match { + case AnyScalaVersion => 0 + case _ => -1 + } +} + +/** + * Factory methods for producing ScalaVersions + */ +object ScalaVersion { + private val dot = "\\." + private val dash = "\\-" + private def not(s:String) = s"[^${s}]" + private val R = s"((${not(dot)}*)(${dot}(${not(dot)}*)(${dot}(${not(dash)}*)(${dash}(.*))?)?)?)".r + + def apply(versionString : String, errorHandler: String => Unit): ScalaVersion = { + def errorAndValue() = { + errorHandler( + s"There was a problem parsing ${versionString}. " + + "Versions should be in the form major[.minor[.revision]] " + + "where each part is a positive number, as in 2.10.1. " + + "The minor and revision parts are optional." + ) + AnyScalaVersion + } + + def toInt(s: String) = s match { + case null | "" => 0 + case _ => s.toInt + } + + def isInt(s: String) = util.Try(toInt(s)).isSuccess + + def toBuild(s: String) = s match { + case null | "FINAL" => Final + case s if (s.toUpperCase.startsWith("RC") && isInt(s.substring(2))) => RC(toInt(s.substring(2))) + case s if (s.toUpperCase.startsWith("M") && isInt(s.substring(1))) => Milestone(toInt(s.substring(1))) + case _ => Development(s) + } + + try versionString match { + case "none" => NoScalaVersion + case "any" => AnyScalaVersion + case R(_, majorS, _, minorS, _, revS, _, buildS) => + SpecificScalaVersion(toInt(majorS), toInt(minorS), toInt(revS), toBuild(buildS)) + case _ => + errorAndValue() + } catch { + case e: NumberFormatException => errorAndValue() + } + } + + def apply(versionString: String): ScalaVersion = + apply(versionString, msg => throw new NumberFormatException(msg)) + + /** + * The version of the compiler running now + */ + val current = apply(util.Properties.versionNumberString) + + /** + * The 2.8.0 version. + */ + val twoDotEight = SpecificScalaVersion(2, 8, 0, Final) +} + +/** + * Represents the data after the dash in major.minor.rev-build + */ +abstract class ScalaBuild extends Ordered[ScalaBuild] { + /** + * Return a version of this build information that can be parsed back into the + * same ScalaBuild + */ + def unparse: String +} +/** + * A development, test, nightly, snapshot or other "unofficial" build + */ +case class Development(id: String) extends ScalaBuild { + def unparse = s"-${id}" + + def compare(that: ScalaBuild) = that match { + // sorting two development builds based on id is reasonably valid for two versions created with the same schema + // otherwise it's not correct, but since it's impossible to put a total ordering on development build versions + // this is a pragmatic compromise + case Development(thatId) => id compare thatId + // assume a development build is newer than anything else, that's not really true, but good luck + // mapping development build versions to other build types + case _ => 1 + } +} +/** + * A final final + */ +case object Final extends ScalaBuild { + def unparse = "" + + def compare(that: ScalaBuild) = that match { + case Final => 0 + // a final is newer than anything other than a development build or another final + case Development(_) => -1 + case _ => 1 + } +} + +/** + * A candidate for final release + */ +case class RC(n: Int) extends ScalaBuild { + def unparse = s"-RC${n}" + + def compare(that: ScalaBuild) = that match { + // compare two rcs based on their RC numbers + case RC(thatN) => n - thatN + // an rc is older than anything other than a milestone or another rc + case Milestone(_) => 1 + case _ => -1 + } +} + +/** + * An intermediate release + */ +case class Milestone(n: Int) extends ScalaBuild { + def unparse = s"-M${n}" + + def compare(that: ScalaBuild) = that match { + // compare two milestones based on their milestone numbers + case Milestone(thatN) => n - thatN + // a milestone is older than anything other than another milestone + case _ => -1 + + } +} diff --git a/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala b/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala index 04e860f9db..5ce4466897 100644 --- a/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala +++ b/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala @@ -29,8 +29,8 @@ abstract class ClassfileParser { protected var in: AbstractFileReader = _ // the class file reader protected var clazz: Symbol = _ // the class symbol containing dynamic members protected var staticModule: Symbol = _ // the module symbol containing static members - protected var instanceScope: Scope = _ // the scope of all instance definitions - protected var staticScope: Scope = _ // the scope of all static definitions + protected var instanceScope: Scope = _ // the scope of all instance definitions + protected var staticScope: Scope = _ // the scope of all static definitions protected var pool: ConstantPool = _ // the classfile's constant pool protected var isScala: Boolean = _ // does class file describe a scala class? protected var isScalaAnnot: Boolean = _ // does class file describe a scala class with its pickled info in an annotation? @@ -739,15 +739,9 @@ abstract class ClassfileParser { // isMonomorphicType is false if the info is incomplete, as it usually is here // so have to check unsafeTypeParams.isEmpty before worrying about raw type case below, // or we'll create a boatload of needless existentials. - else if (classSym.isMonomorphicType || classSym.unsafeTypeParams.isEmpty) { - tp - } - else { - // raw type - existentially quantify all type parameters - val eparams = typeParamsToExistentials(classSym, classSym.unsafeTypeParams) - val t = typeRef(pre, classSym, eparams.map(_.tpeHK)) - logResult(s"raw type from $classSym")(newExistentialType(eparams, t)) - } + else if (classSym.isMonomorphicType || classSym.unsafeTypeParams.isEmpty) tp + // raw type - existentially quantify all type parameters + else logResult(s"raw type from $classSym")(definitions.unsafeClassExistentialType(classSym)) case tp => assert(sig.charAt(index) != '<', tp) tp @@ -1044,7 +1038,13 @@ abstract class ClassfileParser { val nClasses = in.nextChar for (n <- 0 until nClasses) { val cls = pool.getClassSymbol(in.nextChar.toInt) - sym.addAnnotation(definitions.ThrowsClass, Literal(Constant(cls.tpe))) + val tp = if (cls.isMonomorphicType) cls.tpe else { + debuglog(s"Encountered polymorphic exception `${cls.fullName}` while parsing class file.") + // in case we encounter polymorphic exception the best we can do is to convert that type to + // monomorphic one by introducing existientals, see SI-7009 for details + typer.packSymbols(cls.typeParams, cls.tpe) + } + sym.addAnnotation(appliedType(definitions.ThrowsClass, tp), Literal(Constant(tp))) } } diff --git a/src/compiler/scala/tools/nsc/transform/CleanUp.scala b/src/compiler/scala/tools/nsc/transform/CleanUp.scala index 39460ef004..f5c8907991 100644 --- a/src/compiler/scala/tools/nsc/transform/CleanUp.scala +++ b/src/compiler/scala/tools/nsc/transform/CleanUp.scala @@ -201,12 +201,17 @@ abstract class CleanUp extends Transform with ast.TreeDSL { var reflPoly$Cache: SoftReference[scala.runtime.MethodCache] = new SoftReference(new EmptyMethodCache()) def reflMethod$Method(forReceiver: JClass[_]): JMethod = { - var method: JMethod = reflPoly$Cache.find(forReceiver) - if (method != null) + var methodCache: MethodCache = reflPoly$Cache.find(forReceiver) + if (methodCache eq null) { + methodCache = new EmptyMethodCache + reflPoly$Cache = new SoftReference(methodCache) + } + var method: JMethod = methodCache.find(forReceiver) + if (method ne null) return method else { method = ScalaRunTime.ensureAccessible(forReceiver.getMethod("xyz", reflParams$Cache)) - reflPoly$Cache = new SoftReference(reflPoly$Cache.get.add(forReceiver, method)) + reflPoly$Cache = new SoftReference(methodCache.add(forReceiver, method)) return method } } @@ -223,16 +228,22 @@ abstract class CleanUp extends Transform with ast.TreeDSL { def getPolyCache = gen.mkCast(fn(REF(reflPolyCacheSym), nme.get), MethodCacheClass.tpe) addStaticMethodToClass((reflMethodSym, forReceiverSym) => { + val methodCache = reflMethodSym.newVariable(mkTerm("methodCache"), ad.pos) setInfo MethodCacheClass.tpe val methodSym = reflMethodSym.newVariable(mkTerm("method"), ad.pos) setInfo MethodClass.tpe BLOCK( - IF (getPolyCache OBJ_EQ NULL) THEN (REF(reflPolyCacheSym) === mkNewPolyCache) ENDIF, - VAL(methodSym) === ((getPolyCache DOT methodCache_find)(REF(forReceiverSym))) , - IF (REF(methodSym) OBJ_!= NULL) . + VAL(methodCache) === getPolyCache, + IF (REF(methodCache) OBJ_EQ NULL) THEN BLOCK( + REF(methodCache) === NEW(TypeTree(EmptyMethodCacheClass.tpe)), + REF(reflPolyCacheSym) === gen.mkSoftRef(REF(methodCache)) + ) ENDIF, + + VAL(methodSym) === (REF(methodCache) DOT methodCache_find)(REF(forReceiverSym)), + IF (REF(methodSym) OBJ_NE NULL) . THEN (Return(REF(methodSym))) ELSE { def methodSymRHS = ((REF(forReceiverSym) DOT Class_getMethod)(LIT(method), REF(reflParamsCacheSym))) - def cacheRHS = ((getPolyCache DOT methodCache_add)(REF(forReceiverSym), REF(methodSym))) + def cacheRHS = ((REF(methodCache) DOT methodCache_add)(REF(forReceiverSym), REF(methodSym))) BLOCK( REF(methodSym) === (REF(ensureAccessibleMethod) APPLY (methodSymRHS)), REF(reflPolyCacheSym) === gen.mkSoftRef(cacheRHS), @@ -241,6 +252,7 @@ abstract class CleanUp extends Transform with ast.TreeDSL { } ) }) + } /* ### HANDLING METHODS NORMALLY COMPILED TO OPERATORS ### */ diff --git a/src/compiler/scala/tools/nsc/transform/Erasure.scala b/src/compiler/scala/tools/nsc/transform/Erasure.scala index e3b5efde1f..f380b9d04f 100644 --- a/src/compiler/scala/tools/nsc/transform/Erasure.scala +++ b/src/compiler/scala/tools/nsc/transform/Erasure.scala @@ -50,7 +50,7 @@ abstract class Erasure extends AddInterfaces if (sym == ArrayClass) args foreach traverse else if (sym.isTypeParameterOrSkolem || sym.isExistentiallyBound || !args.isEmpty) result = true else if (sym.isClass) traverse(rebindInnerClass(pre, sym)) // #2585 - else if (!sym.owner.isPackageClass) traverse(pre) + else if (!sym.isTopLevel) traverse(pre) case PolyType(_, _) | ExistentialType(_, _) => result = true case RefinedType(parents, _) => @@ -101,7 +101,7 @@ abstract class Erasure extends AddInterfaces * 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 { + def squashBoxed(tp: Type): Type = tp.dealiasWiden match { case t @ RefinedType(parents, decls) => val parents1 = parents mapConserve squashBoxed if (parents1 eq parents) tp @@ -114,7 +114,7 @@ abstract class Erasure extends AddInterfaces if (boxedClass contains t.typeSymbol) ObjectClass.tpe else tp } - def apply(tp: Type): Type = tp.normalize match { + def apply(tp: Type): Type = tp.dealiasWiden match { case tp1 @ TypeBounds(lo, hi) => val lo1 = squashBoxed(apply(lo)) val hi1 = squashBoxed(apply(hi)) @@ -145,7 +145,7 @@ abstract class Erasure extends AddInterfaces } case tp1 @ MethodType(params, restpe) => val params1 = mapOver(params) - val restpe1 = if (restpe.normalize.typeSymbol == UnitClass) UnitClass.tpe else apply(restpe) + val restpe1 = if (restpe.typeSymbol == UnitClass) UnitClass.tpe else apply(restpe) if ((params1 eq params) && (restpe1 eq restpe)) tp1 else MethodType(params1, restpe1) case tp1 @ RefinedType(parents, decls) => @@ -163,8 +163,8 @@ abstract class Erasure extends AddInterfaces } } - private def hiBounds(bounds: TypeBounds): List[Type] = bounds.hi.normalize match { - case RefinedType(parents, _) => parents map (_.normalize) + private def hiBounds(bounds: TypeBounds): List[Type] = bounds.hi.dealiasWiden match { + case RefinedType(parents, _) => parents map (_.dealiasWiden) case tp => tp :: Nil } @@ -341,13 +341,18 @@ abstract class Erasure extends AddInterfaces case _ => tp.deconst } } - // Methods on Any/Object which we rewrite here while we still know what - // is a primitive and what arrived boxed. - private lazy val interceptedMethods = Set[Symbol](Any_##, Object_##, Any_getClass, AnyVal_getClass) ++ ( - // Each value class has its own getClass for ultra-precise class object typing. + + // Each primitive value class has its own getClass for ultra-precise class object typing. + private lazy val primitiveGetClassMethods = Set[Symbol](Any_getClass, AnyVal_getClass) ++ ( ScalaValueClasses map (_.tpe member nme.getClass_) ) + // ## requires a little translation + private lazy val poundPoundMethods = Set[Symbol](Any_##, Object_##) + // Methods on Any/Object which we rewrite here while we still know what + // is a primitive and what arrived boxed. + private lazy val interceptedMethods = poundPoundMethods ++ primitiveGetClassMethods + // -------- erasure on trees ------------------------------------------ override def newTyper(context: Context) = new Eraser(context) @@ -1130,7 +1135,7 @@ abstract class Erasure extends AddInterfaces } } else if (args.isEmpty && interceptedMethods(fn.symbol)) { - if (fn.symbol == Any_## || fn.symbol == Object_##) { + if (poundPoundMethods.contains(fn.symbol)) { // This is unattractive, but without it we crash here on ().## because after // erasure the ScalaRunTime.hash overload goes from Unit => Int to BoxedUnit => Int. // This must be because some earlier transformation is being skipped on ##, but so @@ -1157,9 +1162,18 @@ abstract class Erasure extends AddInterfaces } else if (isPrimitiveValueClass(qual.tpe.typeSymbol)) { // Rewrite 5.getClass to ScalaRunTime.anyValClass(5) global.typer.typed(gen.mkRuntimeCall(nme.anyValClass, List(qual, typer.resolveClassTag(tree.pos, qual.tpe.widen)))) - } else if (fn.symbol == AnyVal_getClass) { + } else if (primitiveGetClassMethods.contains(fn.symbol)) { + // if we got here then we're trying to send a primitive getClass method to either + // a) an Any, in which cage Object_getClass works because Any erases to object. Or + // + // b) a non-primitive, e.g. because the qualifier's type is a refinement type where one parent + // of the refinement is a primitive and another is AnyRef. In that case + // we get a primitive form of _getClass trying to target a boxed value + // so we need replace that method name with Object_getClass to get correct behavior. + // See SI-5568. tree setSymbol Object_getClass } else { + debugwarn(s"The symbol '${fn.symbol}' was interecepted but didn't match any cases, that means the intercepted methods set doesn't match the code") tree } } else qual match { diff --git a/src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala b/src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala index 9696692146..45ec73ab99 100644 --- a/src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala +++ b/src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala @@ -9,6 +9,7 @@ package transform import symtab._ import Flags.{ CASE => _, _ } import scala.collection.mutable.ListBuffer +import scala.tools.nsc.settings.ScalaVersion /** This class ... * @@ -104,7 +105,7 @@ abstract class ExplicitOuter extends InfoTransform * <ol> * <li> * Add an outer parameter to the formal parameters of a constructor - * in a inner non-trait class; + * in an inner non-trait class; * </li> * <li> * Add a protected $outer field to an inner class which is diff --git a/src/compiler/scala/tools/nsc/transform/ExtensionMethods.scala b/src/compiler/scala/tools/nsc/transform/ExtensionMethods.scala index 77e7e013ab..672d9d232a 100644 --- a/src/compiler/scala/tools/nsc/transform/ExtensionMethods.scala +++ b/src/compiler/scala/tools/nsc/transform/ExtensionMethods.scala @@ -60,14 +60,30 @@ abstract class ExtensionMethods extends Transform with TypingTransformers { } } - /** Return the extension method that corresponds to given instance method `meth`. - */ + private def companionModuleForce(sym: Symbol) = { + sym.andAlso(_.owner.initialize) // See SI-6976. `companionModule` only calls `rawInfo`. (Why?) + sym.companionModule + } + + /** Return the extension method that corresponds to given instance method `meth`. */ def extensionMethod(imeth: Symbol): Symbol = enteringPhase(currentRun.refchecksPhase) { - val companionInfo = imeth.owner.companionModule.info + val companionInfo = companionModuleForce(imeth.owner).info val candidates = extensionNames(imeth) map (companionInfo.decl(_)) filter (_.exists) val matching = candidates filter (alt => normalize(alt.tpe, imeth.owner) matches imeth.tpe) assert(matching.nonEmpty, - s"no extension method found for $imeth:${imeth.tpe} among ${candidates map (c => c.name+":"+c.tpe)} / ${extensionNames(imeth)}") + sm"""|no extension method found for: + | + | $imeth:${imeth.tpe} + | + | Candidates: + | + | ${candidates.map(c => c.name+":"+c.tpe).mkString("\n")} + | + | Candidates (signatures normalized): + | + | ${candidates.map(c => c.name+":"+normalize(c.tpe, imeth.owner)).mkString("\n")} + | + | Eligible Names: ${extensionNames(imeth).mkString(",")}" """) matching.head } @@ -82,7 +98,7 @@ abstract class ExtensionMethods extends Transform with TypingTransformers { object ExtensionMethodType { def unapply(tp: Type) = tp match { case MethodType(thiz :: rest, restpe) if thiz.name == nme.SELF => - Some( if (rest.isEmpty) restpe else MethodType(rest, restpe) ) + Some((thiz, if (rest.isEmpty) restpe else MethodType(rest, restpe) )) case _ => None } @@ -98,9 +114,10 @@ abstract class ExtensionMethods extends Transform with TypingTransformers { case PolyType(tparams, restpe) => // method type parameters, class type parameters val (mtparams, ctparams) = tparams splitAt (tparams.length - clazz.typeParams.length) - GenPolyType(mtparams, normalize(restpe.substSym(ctparams, clazz.typeParams), clazz)) - case ExtensionMethodType(etpe) => - etpe + GenPolyType(mtparams, + normalize(restpe.substSym(ctparams, clazz.typeParams), clazz)) + case ExtensionMethodType(thiz, etpe) => + etpe.substituteTypes(thiz :: Nil, clazz.thisType :: Nil) case _ => stpe } @@ -137,17 +154,20 @@ abstract class ExtensionMethods extends Transform with TypingTransformers { // Start with the class type parameters - clones will be method type parameters // so must drop their variance. val tparamsFromClass = cloneSymbolsAtOwner(clazz.typeParams, extensionMeth) map (_ resetFlag COVARIANT | CONTRAVARIANT) - def fix(tp: Type) = tp.substSym(clazz.typeParams, tparamsFromClass) val thisParamType = appliedType(clazz, tparamsFromClass map (_.tpeHK): _*) val thisParam = extensionMeth.newValueParameter(nme.SELF, extensionMeth.pos) setInfo thisParamType val resultType = MethodType(List(thisParam), dropNullaryMethod(methodResult)) + val selfParamType = singleType(currentOwner.companionModule.thisType, thisParam) + + def fixres(tp: Type) = tp substThisAndSym (clazz, selfParamType, clazz.typeParams, tparamsFromClass) + def fixtparam(tp: Type) = tp substSym (clazz.typeParams, tparamsFromClass) // We can't substitute symbols on the entire polytype because we // need to modify the bounds of the cloned type parameters, but we // don't want to substitute for the cloned type parameters themselves. val tparams = tparamsFromMethod ::: tparamsFromClass - GenPolyType(tparams map (_ modifyInfo fix), fix(resultType)) + GenPolyType(tparams map (_ modifyInfo fixtparam), fixres(resultType)) // For reference, calling fix on the GenPolyType plays out like this: // error: scala.reflect.internal.Types$TypeError: type arguments [B#7344,A#6966] @@ -161,6 +181,7 @@ abstract class ExtensionMethods extends Transform with TypingTransformers { // bad: [B#16154 >: A#16149, A#16155 <: AnyRef#2189]($this#16156: Foo#6965[A#16155])(x#16157: B#16154)List#2457[B#16154] // good: [B#16151 >: A#16149, A#16149 <: AnyRef#2189]($this#16150: Foo#6965[A#16149])(x#16153: B#16151)List#2457[B#16151] } + override def transform(tree: Tree): Tree = { tree match { case Template(_, _, _) => @@ -182,9 +203,9 @@ abstract class ExtensionMethods extends Transform with TypingTransformers { val companion = origThis.companionModule def makeExtensionMethodSymbol = { - val extensionName = extensionNames(origMeth).head + val extensionName = extensionNames(origMeth).head.toTermName val extensionMeth = ( - companion.moduleClass.newMethod(extensionName.toTermName, origMeth.pos, origMeth.flags & ~OVERRIDE & ~PROTECTED | FINAL) + companion.moduleClass.newMethod(extensionName, origMeth.pos, origMeth.flags & ~OVERRIDE & ~PROTECTED | FINAL) setAnnotations origMeth.annotations ) companion.info.decls.enter(extensionMeth) @@ -198,7 +219,7 @@ abstract class ExtensionMethods extends Transform with TypingTransformers { val GenPolyType(extensionTpeParams, MethodType(thiz :: Nil, extensionMono)) = newInfo val extensionParams = allParameters(extensionMono) - val extensionThis = gen.mkAttributedIdent(thiz setPos extensionMeth.pos) + val extensionThis = gen.mkAttributedStableRef(thiz setPos extensionMeth.pos) val extensionBody = ( rhs diff --git a/src/compiler/scala/tools/nsc/transform/Flatten.scala b/src/compiler/scala/tools/nsc/transform/Flatten.scala index b2602f47de..a370b45be0 100644 --- a/src/compiler/scala/tools/nsc/transform/Flatten.scala +++ b/src/compiler/scala/tools/nsc/transform/Flatten.scala @@ -12,6 +12,7 @@ import scala.collection.mutable.ListBuffer abstract class Flatten extends InfoTransform { import global._ + import treeInfo.isQualifierSafeToElide /** the following two members override abstract members in Transform */ val phaseName: String = "flatten" @@ -116,8 +117,14 @@ abstract class Flatten extends InfoTransform { case ClassDef(_, _, _, _) if sym.isNestedClass => liftedDefs(sym.enclosingTopLevelClass.owner) += tree EmptyTree - case Select(qual, name) if (sym.isStaticModule && !sym.owner.isPackageClass) => - exitingFlatten(atPos(tree.pos)(gen.mkAttributedRef(sym))) + case Select(qual, name) if sym.isStaticModule && !sym.isTopLevel => + exitingFlatten { + atPos(tree.pos) { + val ref = gen.mkAttributedRef(sym) + if (isQualifierSafeToElide(qual)) ref + else Block(List(qual), ref).setType(tree.tpe) // need to execute the qualifier but refer directly to the lifted module. + } + } case _ => tree } diff --git a/src/compiler/scala/tools/nsc/transform/LambdaLift.scala b/src/compiler/scala/tools/nsc/transform/LambdaLift.scala index 0198f959e3..0180271925 100644 --- a/src/compiler/scala/tools/nsc/transform/LambdaLift.scala +++ b/src/compiler/scala/tools/nsc/transform/LambdaLift.scala @@ -245,7 +245,7 @@ abstract class LambdaLift extends InfoTransform { freshen(sym.name + nme.NAME_JOIN_STRING + sym.owner.name + nme.NAME_JOIN_STRING) } else { // SI-5652 If the lifted symbol is accessed from an inner class, it will be made public. (where?) - // Generating a a unique name, mangled with the enclosing class name, avoids a VerifyError + // Generating a unique name, mangled with the enclosing class name, avoids a VerifyError // in the case that a sub-class happens to lifts out a method with the *same* name. val name = freshen("" + sym.name + nme.NAME_JOIN_STRING) if (originalName.isTermName && !sym.enclClass.isImplClass && calledFromInner(sym)) nme.expandedName(name.toTermName, sym.enclClass) @@ -320,12 +320,24 @@ abstract class LambdaLift extends InfoTransform { private def memberRef(sym: Symbol) = { val clazz = sym.owner.enclClass //Console.println("memberRef from "+currentClass+" to "+sym+" in "+clazz) - val qual = if (clazz == currentClass) gen.mkAttributedThis(clazz) - else { - sym resetFlag(LOCAL | PRIVATE) - if (clazz.isStaticOwner) gen.mkAttributedQualifier(clazz.thisType) - else outerPath(outerValue, currentClass.outerClass, clazz) - } + def prematureSelfReference() { + val what = + if (clazz.isStaticOwner) clazz.fullLocationString + else s"the unconstructed `this` of ${clazz.fullLocationString}" + val msg = s"Implementation restriction: access of ${sym.fullLocationString} from ${currentClass.fullLocationString}, would require illegal premature access to $what" + currentUnit.error(curTree.pos, msg) + } + val qual = + if (clazz == currentClass) gen.mkAttributedThis(clazz) + else { + sym resetFlag (LOCAL | PRIVATE) + if (selfOrSuperCalls exists (_.owner == clazz)) { + prematureSelfReference() + EmptyTree + } + else if (clazz.isStaticOwner) gen.mkAttributedQualifier(clazz.thisType) + else outerPath(outerValue, currentClass.outerClass, clazz) + } Select(qual, sym) setType sym.tpe } @@ -352,6 +364,7 @@ abstract class LambdaLift extends InfoTransform { copyDefDef(tree)(vparamss = List(vparams ++ freeParams)) case ClassDef(_, _, _, _) => + // SI-6231 // Disabled attempt to to add getters to freeParams // this does not work yet. Problem is that local symbols need local names // and references to local symbols need to be transformed into @@ -369,7 +382,7 @@ abstract class LambdaLift extends InfoTransform { tree } -/* Something like this will be necessary to eliminate the implementation +/* SI-6231: Something like this will be necessary to eliminate the implementation * restiction from paramGetter above: * We need to pass getters to the interface of an implementation class. private def fixTraitGetters(lifted: List[Tree]): List[Tree] = @@ -430,28 +443,53 @@ abstract class LambdaLift extends InfoTransform { /* Creating a constructor argument if one isn't present. */ val constructorArg = rhs match { case EmptyTree => - sym.primaryConstructor.info.paramTypes match { + sym.tpe.typeSymbol.primaryConstructor.info.paramTypes match { case List(tp) => gen.mkZero(tp) case _ => - log("Couldn't determine how to properly construct " + sym) + debugwarn("Couldn't determine how to properly construct " + sym) rhs } case arg => arg } - /** Wrap expr argument in new *Ref(..) constructor, but make - * sure that Try expressions stay at toplevel. + + /** Wrap expr argument in new *Ref(..) constructor. But try/catch + * is a problem because a throw will clear the stack and post catch + * we would expect the partially-constructed object to be on the stack + * for the call to init. So we recursively + * search for "leaf" result expressions where we know its safe + * to put the new *Ref(..) constructor or, if all else fails, transform + * an expr to { val temp=expr; new *Ref(temp) }. + * The reason we narrowly look for try/catch in captured var definitions + * is because other try/catch expression have already been lifted + * see SI-6863 */ - def refConstr(expr: Tree): Tree = expr match { + def refConstr(expr: Tree): Tree = typer.typedPos(expr.pos)(expr match { + // very simple expressions can be wrapped in a new *Ref(expr) because they can't have + // a try/catch in final expression position. + case Ident(_) | Apply(_, _) | Literal(_) | New(_) | Select(_, _) | Throw(_) | Assign(_, _) | ValDef(_, _, _, _) | Return(_) | EmptyTree => + New(sym.tpe, expr) case Try(block, catches, finalizer) => Try(refConstr(block), catches map refConstrCase, finalizer) + case Block(stats, expr) => + Block(stats, refConstr(expr)) + case If(cond, trueBranch, falseBranch) => + If(cond, refConstr(trueBranch), refConstr(falseBranch)) + case Match(selector, cases) => + Match(selector, cases map refConstrCase) + // if we can't figure out what else to do, turn expr into {val temp1 = expr; new *Ref(temp1)} to avoid + // any possibility of try/catch in the *Ref constructor. This should be a safe tranformation as a default + // though it potentially wastes a variable slot. In particular this case handles LabelDefs. case _ => - New(sym.tpe, expr) - } + debuglog("assigning expr to temp: " + (expr.pos)) + val tempSym = currentOwner.newValue(unit.freshTermName("temp"), expr.pos) setInfo expr.tpe + val tempDef = ValDef(tempSym, expr) setPos expr.pos + val tempRef = Ident(tempSym) setPos expr.pos + Block(tempDef, New(sym.tpe, tempRef)) + }) def refConstrCase(cdef: CaseDef): CaseDef = CaseDef(cdef.pat, cdef.guard, refConstr(cdef.body)) - treeCopy.ValDef(tree, mods, name, tpt1, typer.typedPos(rhs.pos) { - refConstr(constructorArg) - }) + + treeCopy.ValDef(tree, mods, name, tpt1, refConstr(constructorArg)) } else tree case Return(Block(stats, value)) => Block(stats, treeCopy.Return(tree, value)) setType tree.tpe setPos tree.pos @@ -495,13 +533,25 @@ abstract class LambdaLift extends InfoTransform { private def preTransform(tree: Tree) = super.transform(tree) setType lifted(tree.tpe) + /** The stack of constructor symbols in which a call to this() or to the super + * constructor is active. + */ + private val selfOrSuperCalls = mutable.Stack[Symbol]() + @inline private def inSelfOrSuperCall[A](sym: Symbol)(a: => A) = try { + selfOrSuperCalls push sym + a + } finally selfOrSuperCalls.pop() + override def transform(tree: Tree): Tree = tree match { case Select(ReferenceToBoxed(idt), elem) if elem == nme.elem => postTransform(preTransform(idt), isBoxedRef = false) case ReferenceToBoxed(idt) => postTransform(preTransform(idt), isBoxedRef = true) case _ => - postTransform(preTransform(tree)) + def transformTree = postTransform(preTransform(tree)) + if (treeInfo isSelfOrSuperConstrCall tree) + inSelfOrSuperCall(currentOwner)(transformTree) + else transformTree } /** Transform statements and add lifted definitions to them. */ diff --git a/src/compiler/scala/tools/nsc/transform/Mixin.scala b/src/compiler/scala/tools/nsc/transform/Mixin.scala index 6a253a98b1..3e5ac6922e 100644 --- a/src/compiler/scala/tools/nsc/transform/Mixin.scala +++ b/src/compiler/scala/tools/nsc/transform/Mixin.scala @@ -1214,9 +1214,24 @@ abstract class Mixin extends InfoTransform with ast.TreeDSL { // refer to fields in some implementation class via an abstract // getter in the interface. val iface = toInterface(sym.owner.tpe).typeSymbol - val getter = sym getter iface orElse abort("No getter for " + sym + " in " + iface) + val ifaceGetter = sym getter iface + + def si6231Restriction() { + // See SI-6231 comments in LamdaLift for ideas on how to lift the restriction. + val msg = sm"""Implementation restriction: local ${iface.fullLocationString} is unable to automatically capture the + |free variable ${sym} on behalf of ${currentClass}. You can manually assign it to a val inside the trait, + |and refer that that val in ${currentClass}. For more details, see SI-6231.""" + reporter.error(tree.pos, msg) + } - typedPos(tree.pos)((qual DOT getter)()) + if (ifaceGetter == NoSymbol) { + if (sym.isParamAccessor) { + si6231Restriction() + EmptyTree + } + else abort("No getter for " + sym + " in " + iface) + } + else typedPos(tree.pos)((qual DOT ifaceGetter)()) case Assign(Apply(lhs @ Select(qual, _), List()), rhs) => // assign to fields in some implementation class via an abstract diff --git a/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala b/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala index 116b6ab58f..0cd7f516ef 100644 --- a/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala +++ b/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala @@ -424,7 +424,7 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers { def specializedTypeVars(tpe: Type): immutable.Set[Symbol] = tpe match { case TypeRef(pre, sym, args) => if (sym.isAliasType) - specializedTypeVars(tpe.normalize) + specializedTypeVars(tpe.dealiasWiden) else if (sym.isTypeParameter && sym.isSpecialized || (sym.isTypeSkolem && sym.deSkolemize.isSpecialized)) Set(sym) else if (sym == ArrayClass) @@ -1365,7 +1365,7 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers { debuglog("obtained env: " + e) e.keySet == env.keySet } catch { - case _ => + case _: Throwable => debuglog("Could not unify.") false } diff --git a/src/compiler/scala/tools/nsc/transform/UnCurry.scala b/src/compiler/scala/tools/nsc/transform/UnCurry.scala index afe853e06e..413ef473c3 100644 --- a/src/compiler/scala/tools/nsc/transform/UnCurry.scala +++ b/src/compiler/scala/tools/nsc/transform/UnCurry.scala @@ -213,15 +213,22 @@ abstract class UnCurry extends InfoTransform * new $anon() * */ - def transformFunction(fun: Function): Tree = + def transformFunction(fun: Function): Tree = { + fun.tpe match { + // can happen when analyzer plugins assign refined types to functions, e.g. + // (() => Int) { def apply(): Int @typeConstraint } + case RefinedType(List(funTp), decls) => + debuglog(s"eliminate refinement from function type ${fun.tpe}") + fun.tpe = funTp + case _ => + () + } + deEta(fun) match { // nullary or parameterless case fun1 if fun1 ne fun => fun1 case _ => - val parents = ( - if (isFunctionType(fun.tpe)) addSerializable(abstractFunctionForFunctionType(fun.tpe)) - else addSerializable(ObjectClass.tpe, fun.tpe) - ) + val parents = addSerializable(abstractFunctionForFunctionType(fun.tpe)) val anonClass = fun.symbol.owner newAnonymousFunctionClass(fun.pos, inConstructorFlag) addAnnotation serialVersionUIDAnnotation anonClass setInfo ClassInfoType(parents, newScope, anonClass) @@ -254,6 +261,7 @@ abstract class UnCurry extends InfoTransform } } + } def transformArgs(pos: Position, fun: Symbol, args: List[Tree], formals: List[Type]) = { val isJava = fun.isJavaDefined @@ -451,8 +459,6 @@ abstract class UnCurry extends InfoTransform } case ValDef(_, _, _, rhs) => if (sym eq NoSymbol) throw new IllegalStateException("Encountered Valdef without symbol: "+ tree + " in "+ unit) - // a local variable that is mutable and free somewhere later should be lifted - // as lambda lifting (coming later) will wrap 'rhs' in an Ref object. if (!sym.owner.isSourceMethod) withNeedLift(true) { super.transform(tree) } else @@ -563,15 +569,22 @@ abstract class UnCurry extends InfoTransform } case dd @ DefDef(_, _, _, vparamss0, _, rhs0) => - val vparamss1 = vparamss0 match { - case _ :: Nil => vparamss0 - case _ => vparamss0.flatten :: Nil - } + val (newParamss, newRhs): (List[List[ValDef]], Tree) = + if (dependentParamTypeErasure isDependent dd) + dependentParamTypeErasure erase dd + else { + val vparamss1 = vparamss0 match { + case _ :: Nil => vparamss0 + case _ => vparamss0.flatten :: Nil + } + (vparamss1, rhs0) + } + val flatdd = copyDefDef(dd)( - vparamss = vparamss1, + vparamss = newParamss, rhs = nonLocalReturnKeys get dd.symbol match { - case Some(k) => atPos(rhs0.pos)(nonLocalReturnTry(rhs0, k, dd.symbol)) - case None => rhs0 + case Some(k) => atPos(newRhs.pos)(nonLocalReturnTry(newRhs, k, dd.symbol)) + case None => newRhs } ) addJavaVarargsForwarders(dd, flatdd) @@ -599,6 +612,104 @@ abstract class UnCurry extends InfoTransform } } + /** + * When we concatenate parameter lists, formal parameter types that were dependent + * on prior parameter values will no longer be correctly scoped. + * + * For example: + * + * {{{ + * def foo(a: A)(b: a.B): a.type = {b; b} + * // after uncurry + * def foo(a: A, b: a/* NOT IN SCOPE! */.B): a.B = {b; b} + * }}} + * + * This violates the principle that each compiler phase should produce trees that + * can be retyped (see [[scala.tools.nsc.typechecker.TreeCheckers]]), and causes + * a practical problem in `erasure`: it is not able to correctly determine if + * such a signature overrides a corresponding signature in a parent. (SI-6443). + * + * This transformation erases the dependent method types by: + * - Widening the formal parameter type to existentially abstract + * over the prior parameters (using `packSymbols`) + * - Inserting casts in the method body to cast to the original, + * precise type. + * + * For the example above, this results in: + * + * {{{ + * def foo(a: A, b: a.B forSome { val a: A }): a.B = { val b$1 = b.asInstanceOf[a.B]; b$1; b$1 } + * }}} + */ + private object dependentParamTypeErasure { + sealed abstract class ParamTransform { + def param: ValDef + } + final case class Identity(param: ValDef) extends ParamTransform + final case class Packed(param: ValDef, tempVal: ValDef) extends ParamTransform + + def isDependent(dd: DefDef): Boolean = + enteringUncurry { + val methType = dd.symbol.info + methType.isDependentMethodType && mexists(methType.paramss)(_.info exists (_.isImmediatelyDependent)) + } + + /** + * @return (newVparamss, newRhs) + */ + def erase(dd: DefDef): (List[List[ValDef]], Tree) = { + import dd.{ vparamss, rhs } + val vparamSyms = vparamss flatMap (_ map (_.symbol)) + + val paramTransforms: List[ParamTransform] = + vparamss.flatten.map { p => + val declaredType = p.symbol.info + // existentially abstract over value parameters + val packedType = typer.packSymbols(vparamSyms, declaredType) + if (packedType =:= declaredType) Identity(p) + else { + // Change the type of the param symbol + p.symbol updateInfo packedType + + // Create a new param tree + val newParam: ValDef = copyValDef(p)(tpt = TypeTree(packedType)) + + // Within the method body, we'll cast the parameter to the originally + // declared type and assign this to a synthetic val. Later, we'll patch + // the method body to refer to this, rather than the parameter. + val tempVal: ValDef = { + val tempValName = unit freshTermName (p.name + "$") + val newSym = dd.symbol.newTermSymbol(tempValName, p.pos, SYNTHETIC).setInfo(declaredType) + atPos(p.pos)(ValDef(newSym, gen.mkAttributedCast(Ident(p.symbol), declaredType))) + } + Packed(newParam, tempVal) + } + } + + val allParams = paramTransforms map (_.param) + val (packedParams, tempVals) = paramTransforms.collect { + case Packed(param, tempVal) => (param, tempVal) + }.unzip + + val rhs1 = localTyper.typedPos(rhs.pos) { + // Patch the method body to refer to the temp vals + val rhsSubstituted = rhs.substituteSymbols(packedParams map (_.symbol), tempVals map (_.symbol)) + // The new method body: { val p$1 = p.asInstanceOf[<dependent type>]; ...; <rhsSubstituted> } + Block(tempVals, rhsSubstituted) + } + + // update the type of the method after uncurry. + dd.symbol updateInfo { + val GenPolyType(tparams, tp) = dd.symbol.info + logResult("erased dependent param types for ${dd.symbol.info}") { + GenPolyType(tparams, MethodType(allParams map (_.symbol), tp.finalResultType)) + } + } + (allParams :: Nil, rhs1) + } + } + + /* Analyzes repeated params if method is annotated as `varargs`. * If the repeated params exist, it saves them into the `repeatedParams` map, * which is used later. diff --git a/src/compiler/scala/tools/nsc/typechecker/Analyzer.scala b/src/compiler/scala/tools/nsc/typechecker/Analyzer.scala index d4d6def3cb..36121f2653 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Analyzer.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Analyzer.scala @@ -24,6 +24,7 @@ trait Analyzer extends AnyRef with TypeDiagnostics with ContextErrors with StdAttachments + with AnalyzerPlugins { val global : Global import global._ diff --git a/src/compiler/scala/tools/nsc/typechecker/AnalyzerPlugins.scala b/src/compiler/scala/tools/nsc/typechecker/AnalyzerPlugins.scala new file mode 100644 index 0000000000..4210d0b9fb --- /dev/null +++ b/src/compiler/scala/tools/nsc/typechecker/AnalyzerPlugins.scala @@ -0,0 +1,225 @@ +/* NSC -- new Scala compiler + * Copyright 2005-2013 LAMP/EPFL + * @author Martin Odersky + */ + +package scala.tools.nsc +package typechecker + +/** + * @author Lukas Rytz + * @version 1.0 + */ +trait AnalyzerPlugins { self: Analyzer => + import global._ + + + trait AnalyzerPlugin { + /** + * Selectively activate this analyzer plugin, e.g. according to the compiler phase. + * + * Note that the current phase can differ from the global compiler phase (look for `enteringPhase` + * invocations in the compiler). For instance, lazy types created by the UnPickler are completed + * at the phase in which their symbol is created. Observations show that this can even be the + * parser phase. Since symbol completion can trigger subtyping, typing etc, your plugin might + * need to be active also in phases other than namer and typer. + * + * Typically, this method can be implemented as + * + * global.phase.id < global.currentRun.picklerPhase.id + */ + def isActive(): Boolean = true + + /** + * Let analyzer plugins change the expected type before type checking a tree. + */ + def pluginsPt(pt: Type, typer: Typer, tree: Tree, mode: Mode): Type = pt + + /** + * Let analyzer plugins modify the type that has been computed for a tree. + * + * @param tpe The type inferred by the type checker, initially (for first plugin) `tree.tpe` + * @param typer The yper that type checked `tree` + * @param tree The type-checked tree + * @param mode Mode that was used for typing `tree` + * @param pt Expected type that was used for typing `tree` + */ + def pluginsTyped(tpe: Type, typer: Typer, tree: Tree, mode: Mode, pt: Type): Type = tpe + + /** + * Let analyzer plugins change the types assigned to definitions. For definitions that have + * an annotated type, the assigned type is obtained by typing that type tree. Otherwise, the + * type is inferred by typing the definition's righthand side. + * + * In order to know if the type was inferred, you can query the `wasEmpty` field in the `tpt` + * TypeTree of the definition (for DefDef and ValDef). + * + * (*) If the type of a method or value is inferred, the type-checked tree is stored in the + * `analyzer.transformed` hash map, indexed by the definition's rhs tree. + * + * NOTE: Invoking the type checker can lead to cyclic reference errors. For instance, if this + * method is called from the type completer of a recursive method, type checking the mehtod + * rhs will invoke the same completer again. It might be possible to avoid this situation by + * assigning `tpe` to `defTree.symbol` (untested) - the final type computed by this method + * will then be assigned to the definition's symbol by monoTypeCompleter (in Namers). + * + * The hooks into `typeSig` allow analyzer plugins to add annotations to (or change the types + * of) definition symbols. This cannot not be achieved by using `pluginsTyped`: this method + * is only called during type checking, so changing the type of a symbol at this point is too + * late: references to the symbol might already be typed and therefore obtain the the original + * type assigned during naming. + * + * @param defTree is the definition for which the type was computed. The different cases are + * outlined below. Note that this type is untyped (for methods and values with inferred type, + * the typed rhs trees are available in analyzer.transformed). + * + * Case defTree: Template + * - tpe : A ClassInfoType for the template + * - typer: The typer for template members, i.e. expressions and definitions of defTree.body + * - pt : WildcardType + * - the class symbol is accessible through typer.context.owner + * + * Case defTree: ClassDef + * - tpe : A ClassInfoType, or a PolyType(params, ClassInfoType) for polymorphic classes. + * The class type is the one computed by templateSig, i.e. through the above case + * - typer: The typer for the class. Note that this typer has a different context than the + * typer for the template. + * - pt : WildcardType + * + * Case defTree: ModuleDef + * - tpe : A ClassInfoType computed by templateSig + * - typer: The typer for the module. context.owner of this typer is the module class symbol + * - pt : WildcardType + * + * Case defTree: DefDef + * - tpe : The type of the method (MethodType, PolyType or NullaryMethodType). (*) + * - typer: The typer the rhs of this method + * - pt : If tpt.isEmpty, either the result type from the overridden method, or WildcardType. + * Otherwise the type obtained from typing tpt. + * - Note that for constructors, pt is the class type which the constructor creates. To type + * check the rhs of the constructor however, the expected type has to be WildcardType (see + * Typers.typedDefDef) + * + * Case defTree: ValDef + * - tpe : The type of this value. (*) + * - typer: The typer for the rhs of this value + * - pt : If tpt.isEmpty, WildcardType. Otherwise the type obtained from typing tpt. + * - Note that pluginsTypeSig might be called multiple times for the same ValDef since it is + * used to compute the types of the accessor methods (see `pluginsTypeSigAccessor`) + * + * Case defTree: TypeDef + * - tpe : The type obtained from typing rhs (PolyType if the TypeDef defines a polymorphic type) + * - typer: The typer for the rhs of this type + * - pt : WildcardType + */ + def pluginsTypeSig(tpe: Type, typer: Typer, defTree: Tree, pt: Type): Type = tpe + + /** + * Modify the types of field accessors. The namer phase creates method types for getters and + * setters based on the type of the corresponding field. + * + * Note: in order to compute the method type of an accessor, the namer calls `typeSig` on the + * `ValDef` tree of the corresponding field. This implies that the `pluginsTypeSig` method + * is potentially called multiple times for the same ValDef tree. + * + * @param tpe The method type created by the namer for the accessor + * @param typer The typer for the ValDef (not for the rhs) + * @param tree The ValDef corresponding to the accessor + * @param sym The accessor method symbol (getter, setter, beanGetter or beanSetter) + */ + def pluginsTypeSigAccessor(tpe: Type, typer: Typer, tree: ValDef, sym: Symbol): Type = tpe + + /** + * Decide whether this analyzer plugin can adapt a tree that has an annotated type to the + * given type tp, taking into account the given mode (see method adapt in trait Typers). + */ + def canAdaptAnnotations(tree: Tree, typer: Typer, mode: Mode, pt: Type): Boolean = false + + /** + * Adapt a tree that has an annotated type to the given type tp, taking into account the given + * mode (see method adapt in trait Typers). + * + * An implementation cannot rely on canAdaptAnnotations being called before. If the implementing + * class cannot do the adapting, it should return the tree unchanged. + */ + def adaptAnnotations(tree: Tree, typer: Typer, mode: Mode, pt: Type): Tree = tree + + /** + * Modify the type of a return expression. By default, return expressions have type + * NothingClass.tpe. + * + * @param tpe The type of the return expression + * @param typer The typer that was used for typing the return tree + * @param tree The typed return expression tree + * @param pt The return type of the enclosing method + */ + def pluginsTypedReturn(tpe: Type, typer: Typer, tree: Return, pt: Type): Type = tpe + } + + + + /** A list of registered analyzer plugins */ + private var analyzerPlugins: List[AnalyzerPlugin] = Nil + + /** Registers a new analyzer plugin */ + def addAnalyzerPlugin(plugin: AnalyzerPlugin) { + if (!analyzerPlugins.contains(plugin)) + analyzerPlugins = plugin :: analyzerPlugins + } + + + /** @see AnalyzerPlugin.pluginsPt */ + def pluginsPt(pt: Type, typer: Typer, tree: Tree, mode: Mode): Type = + if (analyzerPlugins.isEmpty) pt + else analyzerPlugins.foldLeft(pt)((pt, plugin) => + if (!plugin.isActive()) pt else plugin.pluginsPt(pt, typer, tree, mode)) + + /** @see AnalyzerPlugin.pluginsTyped */ + def pluginsTyped(tpe: Type, typer: Typer, tree: Tree, mode: Mode, pt: Type): Type = { + // support deprecated methods in annotation checkers + val annotCheckersTpe = addAnnotations(tree, tpe) + if (analyzerPlugins.isEmpty) annotCheckersTpe + else analyzerPlugins.foldLeft(annotCheckersTpe)((tpe, plugin) => + if (!plugin.isActive()) tpe else plugin.pluginsTyped(tpe, typer, tree, mode, pt)) + } + + /** @see AnalyzerPlugin.pluginsTypeSig */ + def pluginsTypeSig(tpe: Type, typer: Typer, defTree: Tree, pt: Type): Type = + if (analyzerPlugins.isEmpty) tpe + else analyzerPlugins.foldLeft(tpe)((tpe, plugin) => + if (!plugin.isActive()) tpe else plugin.pluginsTypeSig(tpe, typer, defTree, pt)) + + /** @see AnalyzerPlugin.pluginsTypeSigAccessor */ + def pluginsTypeSigAccessor(tpe: Type, typer: Typer, tree: ValDef, sym: Symbol): Type = + if (analyzerPlugins.isEmpty) tpe + else analyzerPlugins.foldLeft(tpe)((tpe, plugin) => + if (!plugin.isActive()) tpe else plugin.pluginsTypeSigAccessor(tpe, typer, tree, sym)) + + /** @see AnalyzerPlugin.canAdaptAnnotations */ + def canAdaptAnnotations(tree: Tree, typer: Typer, mode: Mode, pt: Type): Boolean = { + // support deprecated methods in annotation checkers + val annotCheckersExists = global.canAdaptAnnotations(tree, mode, pt) + annotCheckersExists || { + if (analyzerPlugins.isEmpty) false + else analyzerPlugins.exists(plugin => + plugin.isActive() && plugin.canAdaptAnnotations(tree, typer, mode, pt)) + } + } + + /** @see AnalyzerPlugin.adaptAnnotations */ + def adaptAnnotations(tree: Tree, typer: Typer, mode: Mode, pt: Type): Tree = { + // support deprecated methods in annotation checkers + val annotCheckersTree = global.adaptAnnotations(tree, mode, pt) + if (analyzerPlugins.isEmpty) annotCheckersTree + else analyzerPlugins.foldLeft(annotCheckersTree)((tree, plugin) => + if (!plugin.isActive()) tree else plugin.adaptAnnotations(tree, typer, mode, pt)) + } + + /** @see AnalyzerPlugin.pluginsTypedReturn */ + def pluginsTypedReturn(tpe: Type, typer: Typer, tree: Return, pt: Type): Type = { + val annotCheckersType = adaptTypeOfReturn(tree.expr, pt, tpe) + if (analyzerPlugins.isEmpty) annotCheckersType + else analyzerPlugins.foldLeft(annotCheckersType)((tpe, plugin) => + if (!plugin.isActive()) tpe else plugin.pluginsTypedReturn(tpe, typer, tree, pt)) + } +} diff --git a/src/compiler/scala/tools/nsc/typechecker/Checkable.scala b/src/compiler/scala/tools/nsc/typechecker/Checkable.scala index fb3909746f..88bfa6099d 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Checkable.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Checkable.scala @@ -62,6 +62,9 @@ trait Checkable { bases foreach { bc => val tps1 = (from baseType bc).typeArgs val tps2 = (tvarType baseType bc).typeArgs + if (tps1.size != tps2.size) + devWarning(s"Unequally sized type arg lists in propagateKnownTypes($from, $to): ($tps1, $tps2)") + (tps1, tps2).zipped foreach (_ =:= _) // Alternate, variance respecting formulation causes // neg/unchecked3.scala to fail (abstract types). TODO - @@ -78,7 +81,7 @@ trait Checkable { val resArgs = tparams zip tvars map { case (_, tvar) if tvar.instValid => tvar.constr.inst - case (tparam, _) => tparam.tpe + case (tparam, _) => tparam.tpeHK } appliedType(to, resArgs: _*) } @@ -108,7 +111,7 @@ trait Checkable { private class CheckabilityChecker(val X: Type, val P: Type) { def Xsym = X.typeSymbol def Psym = P.typeSymbol - def XR = propagateKnownTypes(X, Psym) + def XR = if (Xsym == AnyClass) classExistentialType(Psym) else propagateKnownTypes(X, Psym) // sadly the spec says (new java.lang.Boolean(true)).isInstanceOf[scala.Boolean] def P1 = X matchesPattern P def P2 = !Psym.isPrimitiveValueClass && isNeverSubType(X, P) diff --git a/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala b/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala index 2d4054e93b..580f024b40 100644 --- a/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala +++ b/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala @@ -153,7 +153,7 @@ trait ContextErrors { // members present, then display along with the expected members. This is done here because // this is the last point where we still have access to the original tree, rather than just // the found/req types. - val foundType: Type = req.normalize match { + val foundType: Type = req.dealiasWiden match { case RefinedType(parents, decls) if !decls.isEmpty && found.typeSymbol.isAnonOrRefinementClass => val retyped = typed (tree.duplicate.clearType()) val foundDecls = retyped.tpe.decls filter (sym => !sym.isConstructor && !sym.isSynthetic) @@ -736,7 +736,7 @@ trait ContextErrors { } catch { // the code above tries various tricks to detect the relevant portion of the stack trace // if these tricks fail, just fall back to uninformative, but better than nothing, getMessage - case NonFatal(ex) => + case NonFatal(ex) => // currently giving a spurious warning, see SI-6994 macroLogVerbose("got an exception when processing a macro generated exception\n" + "offender = " + stackTraceString(realex) + "\n" + "error = " + stackTraceString(ex)) @@ -772,10 +772,14 @@ trait ContextErrors { )) } - def MacroImplementationNotFoundError(expandee: Tree) = - macroExpansionError(expandee, + def MacroImplementationNotFoundError(expandee: Tree) = { + val message = "macro implementation not found: " + expandee.symbol.name + " " + - "(the most common reason for that is that you cannot use macro implementations in the same compilation run that defines them)") + "(the most common reason for that is that you cannot use macro implementations in the same compilation run that defines them)" + + (if (forScaladoc) ". When generating scaladocs for multiple projects at once, consider using -Ymacro-no-expand to disable macro expansions altogether." + else "") + macroExpansionError(expandee, message) + } } } @@ -1048,8 +1052,8 @@ trait ContextErrors { val s1 = if (prevSym.isModule) "case class companion " else "" val s2 = if (prevSym.isSynthetic) "(compiler-generated) " + s1 else "" val s3 = if (prevSym.isCase) "case class " + prevSym.name else "" + prevSym - val where = if (currentSym.owner.isPackageClass != prevSym.owner.isPackageClass) { - val inOrOut = if (prevSym.owner.isPackageClass) "outside of" else "in" + val where = if (currentSym.isTopLevel != prevSym.isTopLevel) { + val inOrOut = if (prevSym.isTopLevel) "outside of" else "in" " %s package object %s".format(inOrOut, ""+prevSym.effectiveOwner.name) } else "" diff --git a/src/compiler/scala/tools/nsc/typechecker/Contexts.scala b/src/compiler/scala/tools/nsc/typechecker/Contexts.scala index 274a567075..22a28b7895 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Contexts.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Contexts.scala @@ -39,7 +39,7 @@ trait Contexts { self: Analyzer => def ambiguousDefnAndImport(owner: Symbol, imp: ImportInfo) = LookupAmbiguous(s"it is both defined in $owner and imported subsequently by \n$imp") - private val startContext = { + private lazy val startContext = { NoContext.make( Template(List(), emptyValDef, List()) setSymbol global.NoSymbol setType global.NoType, rootMirror.RootClass, @@ -169,6 +169,7 @@ trait Contexts { self: Analyzer => def typingIndent = " " * typingIndentLevel var buffer: mutable.Set[AbsTypeError] = _ + var warningsBuffer: mutable.Set[(Position, String)] = _ def enclClassOrMethod: Context = if ((owner eq NoSymbol) || (owner.isClass) || (owner.isMethod)) this @@ -190,6 +191,7 @@ trait Contexts { self: Analyzer => def errBuffer = buffer def hasErrors = buffer.nonEmpty + def hasWarnings = warningsBuffer.nonEmpty def state: Int = mode def restoreState(state0: Int) = mode = state0 @@ -218,6 +220,11 @@ trait Contexts { self: Analyzer => buffer.clear() current } + def flushAndReturnWarningsBuffer(): mutable.Set[(Position, String)] = { + val current = warningsBuffer.clone() + warningsBuffer.clear() + current + } def withImplicitsEnabled[T](op: => T): T = { val saved = implicitsEnabled @@ -305,6 +312,7 @@ trait Contexts { self: Analyzer => c.retyping = this.retyping c.openImplicits = this.openImplicits c.buffer = if (this.buffer == null) mutable.LinkedHashSet[AbsTypeError]() else this.buffer // need to initialize + c.warningsBuffer = if (this.warningsBuffer == null) mutable.LinkedHashSet[(Position, String)]() else this.warningsBuffer registerContext(c.asInstanceOf[analyzer.Context]) debuglog("[context] ++ " + c.unit + " / " + tree.summaryString) c @@ -353,6 +361,16 @@ trait Contexts { self: Analyzer => c } + /** + * A context for typing constructor parameter ValDefs, super or self invocation arguments and default getters + * of constructors. These expressions need to be type checked in a scope outside the class, cf. spec 5.3.1. + * + * This method is called by namer / typer where `this` is the context for the constructor DefDef. The + * owner of the resulting (new) context is the outer context for the Template, i.e. the context for the + * ClassDef. This means that class type parameters will be in scope. The value parameters of the current + * constructor are also entered into the new constructor scope. Members of the class however will not be + * accessible. + */ def makeConstructorContext = { var baseContext = enclClass.outer while (baseContext.tree.isInstanceOf[Template]) @@ -372,6 +390,8 @@ trait Contexts { self: Analyzer => enterLocalElems(c.scope.elems) } } + // Enter the scope elements of this (the scope for the constructor DefDef) into the new constructor scope. + // Concretely, this will enter the value parameters of constructor. enterElems(this) argContext } @@ -427,6 +447,7 @@ trait Contexts { self: Analyzer => def warning(pos: Position, msg: String): Unit = warning(pos, msg, false) def warning(pos: Position, msg: String, force: Boolean) { if (reportErrors || force) unit.warning(pos, msg) + else if (bufferErrors) warningsBuffer += ((pos, msg)) } def isLocal(): Boolean = tree match { diff --git a/src/compiler/scala/tools/nsc/typechecker/Implicits.scala b/src/compiler/scala/tools/nsc/typechecker/Implicits.scala index bcf9910c5a..d32930f4f2 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Implicits.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Implicits.scala @@ -347,7 +347,7 @@ trait Implicits { * if one or both are intersection types with a pair of overlapping parent types. */ private def dominates(dtor: Type, dted: Type): Boolean = { - def core(tp: Type): Type = tp.normalize match { + def core(tp: Type): Type = tp.dealiasWiden match { case RefinedType(parents, defs) => intersectionType(parents map core, tp.typeSymbol.owner) case AnnotatedType(annots, tp, selfsym) => core(tp) case ExistentialType(tparams, result) => core(result).subst(tparams, tparams map (t => core(t.info.bounds.hi))) @@ -362,11 +362,11 @@ trait Implicits { deriveTypeWithWildcards(syms.distinct)(tp) } def sum(xs: List[Int]) = (0 /: xs)(_ + _) - def complexity(tp: Type): Int = tp.normalize match { + def complexity(tp: Type): Int = tp.dealiasWiden match { case NoPrefix => 0 case SingleType(pre, sym) => - if (sym.isPackage) 0 else complexity(tp.normalize.widen) + if (sym.isPackage) 0 else complexity(tp.dealiasWiden) case TypeRef(pre, sym, args) => complexity(pre) + sum(args map complexity) + 1 case RefinedType(parents, _) => diff --git a/src/compiler/scala/tools/nsc/typechecker/Infer.scala b/src/compiler/scala/tools/nsc/typechecker/Infer.scala index 4177b7cdfa..27f157e3a6 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Infer.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Infer.scala @@ -244,6 +244,8 @@ trait Infer extends Checkable { * This method seems to be performance critical. */ def normalize(tp: Type): Type = tp match { + case pt @ PolyType(tparams, restpe) => + logResult(s"Normalizing $tp in infer")(normalize(restpe)) case mt @ MethodType(params, restpe) if mt.isImplicit => normalize(restpe) case mt @ MethodType(_, restpe) if !mt.isDependentMethodType => @@ -256,8 +258,8 @@ trait Infer extends Checkable { tp1 // @MAT aliases already handled by subtyping } - private val stdErrorClass = rootMirror.RootClass.newErrorClass(tpnme.ERROR) - private val stdErrorValue = stdErrorClass.newErrorValue(nme.ERROR) + private lazy val stdErrorClass = rootMirror.RootClass.newErrorClass(tpnme.ERROR) + private lazy val stdErrorValue = stdErrorClass.newErrorValue(nme.ERROR) /** The context-dependent inferencer part */ class Inferencer(context: Context) extends InferencerContextErrors with InferCheckable { @@ -866,7 +868,7 @@ trait Infer extends Checkable { val (argtpes1, argPos, namesOK) = checkNames(argtpes0, params) // when using named application, the vararg param has to be specified exactly once ( namesOK - && (isIdentity(argPos) || sameLength(formals, params)) + && (allArgsArePositional(argPos) || sameLength(formals, params)) && typesCompatible(reorderArgs(argtpes1, argPos)) // nb. arguments and names are OK, check if types are compatible ) } @@ -1222,8 +1224,6 @@ trait Infer extends Checkable { } } - def widen(tp: Type): Type = abstractTypesToBounds(tp) - /** Substitute free type variables `undetparams` of type constructor * `tree` in pattern, given prototype `pt`. * @@ -1232,7 +1232,7 @@ trait Infer extends Checkable { * @param pt the expected result type of the instance */ def inferConstructorInstance(tree: Tree, undetparams: List[Symbol], pt0: Type) { - val pt = widen(pt0) + val pt = abstractTypesToBounds(pt0) val ptparams = freeTypeParamsOfTerms(pt) val ctorTp = tree.tpe val resTp = ctorTp.finalResultType @@ -1371,7 +1371,7 @@ trait Infer extends Checkable { } def inferTypedPattern(tree0: Tree, pattp: Type, pt0: Type, canRemedy: Boolean): Type = { - val pt = widen(pt0) + val pt = abstractTypesToBounds(pt0) val ptparams = freeTypeParamsOfTerms(pt) val tpparams = freeTypeParamsOfTerms(pattp) diff --git a/src/compiler/scala/tools/nsc/typechecker/Macros.scala b/src/compiler/scala/tools/nsc/typechecker/Macros.scala index 5b27fd9352..fb8d6b934f 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Macros.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Macros.scala @@ -124,7 +124,7 @@ trait Macros extends scala.tools.reflect.FastTrack with Traces { // todo. refactor when fixing SI-5498 def className: String = { def loop(sym: Symbol): String = sym match { - case sym if sym.owner.isPackageClass => + case sym if sym.isTopLevel => val suffix = if (sym.isModuleClass) "$" else "" sym.fullName + suffix case sym => @@ -450,7 +450,7 @@ trait Macros extends scala.tools.reflect.FastTrack with Traces { if (aparam.name != rparam.name && !rparam.isSynthetic) MacroImplParamNameMismatchError(aparam, rparam) if (isRepeated(aparam) ^ isRepeated(rparam)) MacroImplVarargMismatchError(aparam, rparam) val aparamtpe = aparam.tpe.dealias match { - case RefinedType(List(tpe), Scope(sym)) if tpe == MacroContextClass.tpe && sym.allOverriddenSymbols.contains(MacroContextPrefixType) => tpe + case RefinedType(List(tpe), Scope(sym)) if tpe =:= MacroContextClass.tpe && sym.allOverriddenSymbols.contains(MacroContextPrefixType) => tpe case tpe => tpe } checkMacroImplParamTypeMismatch(atpeToRtpe(aparamtpe), rparam) diff --git a/src/compiler/scala/tools/nsc/typechecker/MethodSynthesis.scala b/src/compiler/scala/tools/nsc/typechecker/MethodSynthesis.scala index b226591c8d..ed1334e857 100644 --- a/src/compiler/scala/tools/nsc/typechecker/MethodSynthesis.scala +++ b/src/compiler/scala/tools/nsc/typechecker/MethodSynthesis.scala @@ -219,8 +219,8 @@ trait MethodSynthesis { context.unit.synthetics get meth match { case Some(mdef) => context.unit.synthetics -= meth - meth setAnnotations deriveAnnotations(annotations, MethodTargetClass, false) - cd.symbol setAnnotations deriveAnnotations(annotations, ClassTargetClass, true) + meth setAnnotations deriveAnnotations(annotations, MethodTargetClass, keepClean = false) + cd.symbol setAnnotations deriveAnnotations(annotations, ClassTargetClass, keepClean = true) List(cd, mdef) case _ => // Shouldn't happen, but let's give ourselves a reasonable error when it does @@ -311,6 +311,7 @@ trait MethodSynthesis { */ def category: Symbol + /* Explicit isSetter required for bean setters (beanSetterSym.isSetter is false) */ final def completer(sym: Symbol) = namerOf(sym).accessorTypeCompleter(tree, isSetter) final def fieldSelection = Select(This(enclClass), basisSym) final def derivedMods: Modifiers = mods & flagsMask | flagsExtra mapAnnotations (_ => Nil) diff --git a/src/compiler/scala/tools/nsc/typechecker/Namers.scala b/src/compiler/scala/tools/nsc/typechecker/Namers.scala index 352090892e..6fde0b7370 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Namers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Namers.scala @@ -63,7 +63,18 @@ trait Namers extends MethodSynthesis { case ModuleDef(_, _, _) => tree.symbol.moduleClass case _ => tree.symbol } - newNamer(context.makeNewScope(tree, sym)) + def isConstrParam(vd: ValDef) = { + (sym hasFlag PARAM | PRESUPER) && + !vd.mods.isJavaDefined && + sym.owner.isConstructor + } + val ownerCtx = tree match { + case vd: ValDef if isConstrParam(vd) => + context.makeConstructorContext + case _ => + context + } + newNamer(ownerCtx.makeNewScope(tree, sym)) } def createInnerNamer() = { newNamer(context.make(context.tree, owner, newScope)) @@ -134,7 +145,7 @@ trait Namers extends MethodSynthesis { sym reset NoType setFlag newFlags setPos pos sym.moduleClass andAlso (updatePosFlags(_, pos, moduleClassFlags(flags))) - if (sym.owner.isPackageClass) { + if (sym.isTopLevel) { companionSymbolOf(sym, context) andAlso { companion => val assignNoType = companion.rawInfo match { case _: SymLoader => true @@ -163,7 +174,7 @@ trait Namers extends MethodSynthesis { protected def conflict(newS: Symbol, oldS: Symbol) = ( ( !oldS.isSourceMethod || nme.isSetterName(newS.name) - || newS.owner.isPackageClass + || newS.isTopLevel ) && !( // @M: allow repeated use of `_` for higher-order type params (newS.owner.isTypeParameter || newS.owner.isAbstractType) @@ -174,7 +185,7 @@ trait Namers extends MethodSynthesis { ) private def allowsOverload(sym: Symbol) = ( - sym.isSourceMethod && sym.owner.isClass && !sym.owner.isPackageClass + sym.isSourceMethod && sym.owner.isClass && !sym.isTopLevel ) private def inCurrentScope(m: Symbol): Boolean = { @@ -352,7 +363,7 @@ trait Namers extends MethodSynthesis { val existing = context.scope.lookup(tree.name) val isRedefinition = ( existing.isType - && existing.owner.isPackageClass + && existing.isTopLevel && context.scope == existing.owner.info.decls && currentRun.canRedefine(existing) ) @@ -365,8 +376,8 @@ trait Namers extends MethodSynthesis { else assignAndEnterSymbol(tree) setFlag inConstructorFlag } clazz match { - case csym: ClassSymbol if csym.owner.isPackageClass => enterClassSymbol(tree, csym) - case _ => clazz + case csym: ClassSymbol if csym.isTopLevel => enterClassSymbol(tree, csym) + case _ => clazz } } @@ -425,7 +436,7 @@ trait Namers extends MethodSynthesis { m.moduleClass setFlag moduleClassFlags(moduleFlags) setPrivateWithin(tree, m.moduleClass) } - if (m.owner.isPackageClass && !m.isPackage) { + if (m.isTopLevel && !m.isPackage) { m.moduleClass.associatedFile = contextFile currentRun.symSource(m) = m.moduleClass.sourceFile registerTopLevelSym(m) @@ -436,6 +447,7 @@ trait Namers extends MethodSynthesis { def enterSyms(trees: List[Tree]): Namer = { trees.foldLeft(this: Namer) { (namer, t) => val ctx = namer enterSym t + // for Import trees, enterSym returns a changed context, so we need a new namer if (ctx eq namer.context) namer else newNamer(ctx) } @@ -534,20 +546,19 @@ trait Namers extends MethodSynthesis { noDuplicates(selectors map (_.rename), AppearsTwice) } - def enterCopyMethod(copyDefDef: Tree, tparams: List[TypeDef]): Symbol = { - val sym = copyDefDef.symbol - val lazyType = completerOf(copyDefDef, tparams) + def enterCopyMethod(copyDef: DefDef): Symbol = { + val sym = copyDef.symbol + val lazyType = completerOf(copyDef) /** Assign the types of the class parameters to the parameters of the * copy method. See comment in `Unapplies.caseClassCopyMeth` */ def assignParamTypes() { val clazz = sym.owner val constructorType = clazz.primaryConstructor.tpe - val subst = new SubstSymMap(clazz.typeParams, tparams map (_.symbol)) + val subst = new SubstSymMap(clazz.typeParams, copyDef.tparams map (_.symbol)) val classParamss = constructorType.paramss - val DefDef(_, _, _, copyParamss, _, _) = copyDefDef - map2(copyParamss, classParamss)((copyParams, classParams) => + map2(copyDef.vparamss, classParamss)((copyParams, classParams) => map2(copyParams, classParams)((copyP, classP) => copyP.tpt setType subst(classP.tpe) ) @@ -555,24 +566,28 @@ trait Namers extends MethodSynthesis { } sym setInfo { - mkTypeCompleter(copyDefDef) { sym => + mkTypeCompleter(copyDef) { sym => assignParamTypes() lazyType complete sym } } } - def completerOf(tree: Tree): TypeCompleter = completerOf(tree, treeInfo.typeParameters(tree)) - def completerOf(tree: Tree, tparams: List[TypeDef]): TypeCompleter = { + + def completerOf(tree: Tree): TypeCompleter = { val mono = namerOf(tree.symbol) monoTypeCompleter tree + val tparams = treeInfo.typeParameters(tree) if (tparams.isEmpty) mono else { - //@M! TypeDef's type params are handled differently - //@M e.g., in [A[x <: B], B], A and B are entered first as both are in scope in the definition of x - //@M x is only in scope in `A[x <: B]' + /* @M! TypeDef's type params are handled differently, e.g., in `type T[A[x <: B], B]`, A and B are entered + * first as both are in scope in the definition of x. x is only in scope in `A[x <: B]`. + * No symbols are created for the abstract type's params at this point, i.e. the following assertion holds: + * !tree.symbol.isAbstractType || { tparams.forall(_.symbol == NoSymbol) + * (tested with the above example, `trait C { type T[A[X <: B], B] }`). See also comment in PolyTypeCompleter. + */ if (!tree.symbol.isAbstractType) //@M TODO: change to isTypeMember ? createNamer(tree) enterSyms tparams - new PolyTypeCompleter(tparams, mono, tree, context) //@M + new PolyTypeCompleter(tparams, mono, context) //@M } } @@ -634,9 +649,9 @@ trait Namers extends MethodSynthesis { val sym = assignAndEnterSymbol(tree) setFlag bridgeFlag if (name == nme.copy && sym.isSynthetic) - enterCopyMethod(tree, tparams) + enterCopyMethod(tree) else - sym setInfo completerOf(tree, tparams) + sym setInfo completerOf(tree) } def enterClassDef(tree: ClassDef) { @@ -763,13 +778,13 @@ trait Namers extends MethodSynthesis { } } - def accessorTypeCompleter(tree: ValDef, isSetter: Boolean = false) = mkTypeCompleter(tree) { sym => + /* Explicit isSetter required for bean setters (beanSetterSym.isSetter is false) */ + def accessorTypeCompleter(tree: ValDef, isSetter: Boolean) = mkTypeCompleter(tree) { sym => logAndValidate(sym) { sym setInfo { - if (isSetter) - MethodType(List(sym.newSyntheticValueParam(typeSig(tree))), UnitClass.tpe) - else - NullaryMethodType(typeSig(tree)) + val tp = if (isSetter) MethodType(List(sym.newSyntheticValueParam(typeSig(tree))), UnitClass.tpe) + else NullaryMethodType(typeSig(tree)) + pluginsTypeSigAccessor(tp, typer, tree, sym) } } } @@ -832,17 +847,12 @@ trait Namers extends MethodSynthesis { * assigns the type to the tpt's node. Returns the type. */ private def assignTypeToTree(tree: ValOrDefDef, defnTyper: Typer, pt: Type): Type = { - // compute result type from rhs - val typedBody = + val rhsTpe = if (tree.symbol.isTermMacro) defnTyper.computeMacroDefType(tree, pt) else defnTyper.computeType(tree.rhs, pt) - val typedDefn = widenIfNecessary(tree.symbol, typedBody, pt) - assignTypeToTree(tree, typedDefn) - } - - private def assignTypeToTree(tree: ValOrDefDef, tpe: Type): Type = { - tree.tpt defineType tpe setPos tree.pos.focus + val defnTpe = widenIfNecessary(tree.symbol, rhsTpe, pt) + tree.tpt defineType defnTpe setPos tree.pos.focus tree.tpt.tpe } @@ -918,163 +928,257 @@ trait Namers extends MethodSynthesis { for (cda <- module.attachments.get[ConstructorDefaultsAttachment]) { cda.companionModuleClassNamer = templateNamer } - ClassInfoType(parents, decls, clazz) + val classTp = ClassInfoType(parents, decls, clazz) + pluginsTypeSig(classTp, templateNamer.typer, templ, WildcardType) } - private def classSig(tparams: List[TypeDef], impl: Template): Type = { + private def classSig(cdef: ClassDef): Type = { + val clazz = cdef.symbol + val ClassDef(_, _, tparams, impl) = cdef val tparams0 = typer.reenterTypeParams(tparams) val resultType = templateSig(impl) - GenPolyType(tparams0, resultType) + val res = GenPolyType(tparams0, resultType) + val pluginsTp = pluginsTypeSig(res, typer, cdef, WildcardType) + + // Already assign the type to the class symbol (monoTypeCompleter will do it again). + // Allows isDerivedValueClass to look at the info. + clazz setInfo pluginsTp + if (clazz.isDerivedValueClass) { + log("Ensuring companion for derived value class " + cdef.name + " at " + cdef.pos.show) + clazz setFlag FINAL + // Don't force the owner's info lest we create cycles as in SI-6357. + enclosingNamerWithScope(clazz.owner.rawInfo.decls).ensureCompanionObject(cdef) + } + pluginsTp } - private def methodSig(ddef: DefDef, mods: Modifiers, tparams: List[TypeDef], - vparamss: List[List[ValDef]], tpt: Tree, rhs: Tree): Type = { - val meth = owner - val clazz = meth.owner - // enters the skolemized version into scope, returns the deSkolemized symbols - val tparamSyms = typer.reenterTypeParams(tparams) - // since the skolemized tparams are in scope, the TypeRefs in vparamSymss refer to skolemized tparams - var vparamSymss = enterValueParams(vparamss) + private def moduleSig(mdef: ModuleDef): Type = { + val moduleSym = mdef.symbol + // The info of both the module and the moduleClass symbols need to be assigned. monoTypeCompleter assigns + // the result of typeSig to the module symbol. The module class info is assigned here as a side-effect. + val result = templateSig(mdef.impl) + val pluginsTp = pluginsTypeSig(result, typer, mdef, WildcardType) + // Assign the moduleClass info (templateSig returns a ClassInfoType) + val clazz = moduleSym.moduleClass + clazz setInfo pluginsTp + // clazz.tpe_* returns a `ModuleTypeRef(clazz)`, a typeRef that links to the module class `clazz` + // (clazz.info would the ClassInfoType, which is not what should be assigned to the module symbol) + clazz.tpe_* + } + + /** + * The method type for `ddef`. + * + * If a PolyType(tparams, restp) is returned, `tparams` are the external symbols (not type skolems), + * i.e. instances of AbstractTypeSymbol. All references in `restp` to the type parameters are TypeRefs + * to these non-skolems. + * + * For type-checking the rhs (in case the result type is inferred), the type skolems of the type parameters + * are entered in scope. Equally, the parameter symbols entered into scope have types which refer to those + * skolems: when type-checking the rhs, references to parameters need to have types that refer to the skolems. + * In summary, typing an rhs happens with respect to the skolems. + * + * This means that the method's result type computed by the typer refers to skolems. In order to put it + * into the method type (the result of methodSig), typeRefs to skolems have to be replaced by references + * to the non-skolems. + */ + private def methodSig(ddef: DefDef): Type = { // DEPMETTODO: do we need to skolemize value parameter symbols? - if (tpt.isEmpty && meth.name == nme.CONSTRUCTOR) { - tpt defineType context.enclClass.owner.tpe_* - tpt setPos meth.pos.focus - } - var resultPt = if (tpt.isEmpty) WildcardType else typer.typedType(tpt).tpe - val site = clazz.thisType - /** Called for all value parameter lists, right to left - * @param vparams the symbols of one parameter list - * @param restpe the result type (possibly a MethodType) + val DefDef(_, _, tparams, vparamss, tpt, _) = ddef + + val meth = owner + val methOwner = meth.owner + val site = methOwner.thisType + + /* tparams already have symbols (created in enterDefDef/completerOf), namely the skolemized ones (created + * by the PolyTypeCompleter constructor, and assigned to tparams). reenterTypeParams enters the type skolems + * into scope and returns the non-skolems. */ - def makeMethodType(vparams: List[Symbol], restpe: Type) = { - // TODODEPMET: check that we actually don't need to do anything here - // new dependent method types: probably OK already, since 'enterValueParams' above - // enters them in scope, and all have a lazy type. so they may depend on other params. but: need to - // check that params only depend on ones in earlier sections, not the same. (done by checkDependencies, - // so re-use / adapt that) - if (owner.isJavaDefined) - // TODODEPMET necessary?? new dependent types: replace symbols in restpe with the ones in vparams - JavaMethodType(vparams map (p => p setInfo objToAny(p.tpe)), restpe) - else - MethodType(vparams, restpe) - } + val tparamSyms = typer.reenterTypeParams(tparams) + + val tparamSkolems = tparams.map(_.symbol) + + /* since the skolemized tparams are in scope, the TypeRefs in types of vparamSymss refer to the type skolems + * note that for parameters with missing types, `methodSig` reassigns types of these symbols (the parameter + * types from the overridden method). + */ + var vparamSymss = enterValueParams(vparamss) + + /** + * Creates a method type using tparamSyms and vparamsSymss as argument symbols and `respte` as result type. + * All typeRefs to type skolems are replaced by references to the corresponding non-skolem type parameter, + * so the resulting type is a valid external method type, it does not contain (references to) skolems. + */ def thisMethodType(restpe: Type) = { val checkDependencies = new DependentTypeChecker(context)(this) checkDependencies check vparamSymss // DEPMETTODO: check not needed when they become on by default checkDependencies(restpe) - GenPolyType( + val makeMethodType = (vparams: List[Symbol], restpe: Type) => { + // TODODEPMET: check that we actually don't need to do anything here + // new dependent method types: probably OK already, since 'enterValueParams' above + // enters them in scope, and all have a lazy type. so they may depend on other params. but: need to + // check that params only depend on ones in earlier sections, not the same. (done by checkDependencies, + // so re-use / adapt that) + if (meth.isJavaDefined) + // TODODEPMET necessary?? new dependent types: replace symbols in restpe with the ones in vparams + JavaMethodType(vparams map (p => p setInfo objToAny(p.tpe)), restpe) + else + MethodType(vparams, restpe) + } + + + val res = GenPolyType( tparamSyms, // deSkolemized symbols -- TODO: check that their infos don't refer to method args? if (vparamSymss.isEmpty) NullaryMethodType(restpe) // vparamss refer (if they do) to skolemized tparams else (vparamSymss :\ restpe) (makeMethodType) ) + res.substSym(tparamSkolems, tparamSyms) } - def transformedResult = - thisMethodType(resultPt).substSym(tparams map (_.symbol), tparamSyms) + /** + * Creates a schematic method type which has WildcardTypes for non specified + * return or parameter types. For instance, in `def f[T](a: T, b) = ...`, the + * type schema is + * + * PolyType(T, MethodType(List(a: T, b: WildcardType), WildcardType)) + * + * where T are non-skolems. + */ + def methodTypeSchema(resTp: Type) = { + // for all params without type set WildcaradType + mforeach(vparamss)(v => if (v.tpt.isEmpty) v.symbol setInfo WildcardType) + thisMethodType(resTp) + } - // luc: added .substSym from skolemized to deSkolemized - // site.memberType(sym): PolyType(tparams, MethodType(..., ...)) - // ==> all references to tparams are deSkolemized - // thisMethodType: tparams in PolyType are deSkolemized, the references in the MethodTypes are skolemized. - // ==> the two didn't match - // - // for instance, B.foo would not override A.foo, and the default on parameter b would not be inherited - // class A { def foo[T](a: T)(b: T = a) = a } - // class B extends A { override def foo[U](a: U)(b: U) = b } - def overriddenSymbol = - intersectionType(clazz.info.parents).nonPrivateMember(meth.name).filter { sym => - sym != NoSymbol && (site.memberType(sym) matches transformedResult) + def overriddenSymbol(resTp: Type) = { + intersectionType(methOwner.info.parents).nonPrivateMember(meth.name).filter { sym => + sym != NoSymbol && (site.memberType(sym) matches methodTypeSchema(resTp)) } - // TODO: see whether this or something similar would work instead. - // + } + // TODO: see whether this or something similar would work instead: // def overriddenSymbol = meth.nextOverriddenSymbol - // fill in result type and parameter types from overridden symbol if there is a unique one. - if (clazz.isClass && (tpt.isEmpty || mexists(vparamss)(_.tpt.isEmpty))) { - // try to complete from matching definition in base type - mforeach(vparamss)(v => if (v.tpt.isEmpty) v.symbol setInfo WildcardType) - val overridden = overriddenSymbol - if (overridden != NoSymbol && !overridden.isOverloaded) { - overridden.cookJavaRawInfo() // #3404 xform java rawtypes into existentials - resultPt = site.memberType(overridden) match { - case PolyType(tparams, rt) => rt.substSym(tparams, tparamSyms) - case mt => mt - } + /** + * If `meth` doesn't have an explicit return type, extracts the return type from the method + * overridden by `meth` (if there's an unique one). This type is lateron used as the expected + * type for computing the type of the rhs. The resulting type references type skolems for + * type parameters (consistent with the result of `typer.typedType(tpt).tpe`). + * + * As a first side effect, this method assigns a MethodType constructed using this + * return type to `meth`. This allows omitting the result type for recursive methods. + * + * As another side effect, this method also assigns paramter types from the overridden + * method to parameters of `meth` that have missing types (the parser accepts missing + * parameter types under -Yinfer-argument-types). + */ + def typesFromOverridden(methResTp: Type): Type = { + val overridden = overriddenSymbol(methResTp) + if (overridden == NoSymbol || overridden.isOverloaded) { + methResTp + } else { + overridden.cookJavaRawInfo() // #3404 xform java rawtypes into existentials + var overriddenTp = site.memberType(overridden) match { + case PolyType(tparams, rt) => rt.substSym(tparams, tparamSkolems) + case mt => mt + } for (vparams <- vparamss) { - var pps = resultPt.params + var overriddenParams = overriddenTp.params for (vparam <- vparams) { if (vparam.tpt.isEmpty) { - val paramtpe = pps.head.tpe - vparam.symbol setInfo paramtpe - vparam.tpt defineType paramtpe setPos vparam.pos.focus + val overriddenParamTp = overriddenParams.head.tpe + // references to type parameteres in overriddenParamTp link to the type skolems, so the + // assigned type is consistent with the other / existing parameter types in vparamSymss. + vparam.symbol setInfo overriddenParamTp + vparam.tpt defineType overriddenParamTp setPos vparam.pos.focus } - pps = pps.tail + overriddenParams = overriddenParams.tail } - resultPt = resultPt.resultType + overriddenTp = overriddenTp.resultType } - resultPt match { - case NullaryMethodType(rtpe) => resultPt = rtpe - case MethodType(List(), rtpe) => resultPt = rtpe + + overriddenTp match { + case NullaryMethodType(rtpe) => overriddenTp = rtpe + case MethodType(List(), rtpe) => overriddenTp = rtpe case _ => } + if (tpt.isEmpty) { // provisionally assign `meth` a method type with inherited result type // that way, we can leave out the result type even if method is recursive. - meth setInfo thisMethodType(resultPt) + meth setInfo thisMethodType(overriddenTp) + overriddenTp + } else { + methResTp } } } - // Add a () parameter section if this overrides some method with () parameters. - if (clazz.isClass && vparamss.isEmpty && overriddenSymbol.alternatives.exists( - _.info.isInstanceOf[MethodType])) { + + if (tpt.isEmpty && meth.name == nme.CONSTRUCTOR) { + tpt defineType context.enclClass.owner.tpe_* + tpt setPos meth.pos.focus + } + + val methResTp = if (tpt.isEmpty) WildcardType else typer.typedType(tpt).tpe + val resTpFromOverride = if (methOwner.isClass && (tpt.isEmpty || mexists(vparamss)(_.tpt.isEmpty))) { + typesFromOverridden(methResTp) + } else { + methResTp + } + + // Add a () parameter section if this overrides some method with () parameters + if (methOwner.isClass && vparamss.isEmpty && + overriddenSymbol(methResTp).alternatives.exists(_.info.isInstanceOf[MethodType])) { vparamSymss = ListOfNil } + + // issue an error for missing parameter types mforeach(vparamss) { vparam => if (vparam.tpt.isEmpty) { MissingParameterOrValTypeError(vparam) vparam.tpt defineType ErrorType } } - addDefaultGetters(meth, vparamss, tparams, overriddenSymbol) + + addDefaultGetters(meth, vparamss, tparams, overriddenSymbol(methResTp)) // fast track macros, i.e. macros defined inside the compiler, are hardcoded // hence we make use of that and let them have whatever right-hand side they need // (either "macro ???" as they used to or just "???" to maximally simplify their compilation) - if (fastTrack contains ddef.symbol) ddef.symbol setFlag MACRO + if (fastTrack contains meth) meth setFlag MACRO // macro defs need to be typechecked in advance // because @macroImpl annotation only gets assigned during typechecking // otherwise macro defs wouldn't be able to robustly coexist with their clients // because a client could be typechecked before a macro def that it uses - if (ddef.symbol.isMacro) { - val pt = resultPt.substSym(tparamSyms, tparams map (_.symbol)) - typer.computeMacroDefType(ddef, pt) + if (meth.isMacro) { + typer.computeMacroDefType(ddef, resTpFromOverride) } - thisMethodType({ + val res = thisMethodType({ val rt = ( if (!tpt.isEmpty) { - typer.typedType(tpt).tpe + methResTp } else { - // replace deSkolemized symbols with skolemized ones - // (for resultPt computed by looking at overridden symbol, right?) - val pt = resultPt.substSym(tparamSyms, tparams map (_.symbol)) - assignTypeToTree(ddef, typer, pt) - } - ) + // return type is inferred, we don't just use resTpFromOverride. Here, C.f has type String: + // trait T { def f: Object }; class C <: T { def f = "" } + // using resTpFromOverride as expected type allows for the following (C.f has type A): + // trait T { def f: A }; class C <: T { implicit def b2a(t: B): A = ???; def f = new B } + assignTypeToTree(ddef, typer, resTpFromOverride) + }) // #2382: return type of default getters are always @uncheckedVariance if (meth.hasDefault) rt.withAnnotation(AnnotationInfo(uncheckedVarianceClass.tpe, List(), List())) else rt }) + pluginsTypeSig(res, typer, ddef, methResTp) } /** @@ -1086,9 +1190,9 @@ trait Namers extends MethodSynthesis { * flag. */ private def addDefaultGetters(meth: Symbol, vparamss: List[List[ValDef]], tparams: List[TypeDef], overriddenSymbol: => Symbol) { - val clazz = meth.owner + val methOwner = meth.owner val isConstr = meth.isConstructor - val overridden = if (isConstr || !clazz.isClass) NoSymbol else overriddenSymbol + val overridden = if (isConstr || !methOwner.isClass) NoSymbol else overriddenSymbol val overrides = overridden != NoSymbol && !overridden.isOverloaded // value parameters of the base class (whose defaults might be overridden) var baseParamss = (vparamss, overridden.tpe.paramss) match { @@ -1138,7 +1242,7 @@ trait Namers extends MethodSynthesis { val parentNamer = if (isConstr) { val (cdef, nmr) = moduleNamer.getOrElse { - val module = companionSymbolOf(clazz, context) + val module = companionSymbolOf(methOwner, context) module.initialize // call type completer (typedTemplate), adds the // module's templateNamer to classAndNamerOfModule module.attachments.get[ConstructorDefaultsAttachment] match { @@ -1184,7 +1288,7 @@ trait Namers extends MethodSynthesis { name, deftParams, defvParamss, defTpt, defRhs) } if (!isConstr) - clazz.resetFlag(INTERFACE) // there's a concrete member now + methOwner.resetFlag(INTERFACE) // there's a concrete member now val default = parentNamer.enterSyntheticSym(defaultTree) if (forInteractive && default.owner.isTerm) { // save the default getters as attachments in the method symbol. if compiling the @@ -1209,15 +1313,31 @@ trait Namers extends MethodSynthesis { } } + private def valDefSig(vdef: ValDef) = { + val ValDef(_, _, tpt, rhs) = vdef + val result = if (tpt.isEmpty) { + if (rhs.isEmpty) { + MissingParameterOrValTypeError(tpt) + ErrorType + } + else assignTypeToTree(vdef, typer, WildcardType) + } else { + typer.typedType(tpt).tpe + } + pluginsTypeSig(result, typer, vdef, if (tpt.isEmpty) WildcardType else result) + + } + //@M! an abstract type definition (abstract type member/type parameter) // may take type parameters, which are in scope in its bounds - private def typeDefSig(tpsym: Symbol, tparams: List[TypeDef], rhs: Tree) = { + private def typeDefSig(tdef: TypeDef) = { + val TypeDef(_, _, tparams, rhs) = tdef // log("typeDefSig(" + tpsym + ", " + tparams + ")") val tparamSyms = typer.reenterTypeParams(tparams) //@M make tparams available in scope (just for this abstypedef) val tp = typer.typedType(rhs).tpe match { case TypeBounds(lt, rt) if (lt.isError || rt.isError) => TypeBounds.empty - case tp @ TypeBounds(lt, rt) if (tpsym hasFlag JAVA) => + case tp @ TypeBounds(lt, rt) if (tdef.symbol hasFlag JAVA) => TypeBounds(lt, objToAny(rt)) case tp => tp @@ -1239,9 +1359,31 @@ trait Namers extends MethodSynthesis { // However, separate compilation requires the symbol info to be // loaded to do this check, but loading the info will probably // lead to spurious cyclic errors. So omit the check. - GenPolyType(tparamSyms, tp) + val res = GenPolyType(tparamSyms, tp) + pluginsTypeSig(res, typer, tdef, WildcardType) } + private def importSig(imp: Import) = { + val Import(expr, selectors) = imp + val expr1 = typer.typedQualifier(expr) + typer checkStable expr1 + if (expr1.symbol != null && expr1.symbol.isRootPackage) + RootImportError(imp) + + if (expr1.isErrorTyped) + ErrorType + else { + val newImport = treeCopy.Import(imp, expr1, selectors).asInstanceOf[Import] + checkSelectors(newImport) + transformed(imp) = newImport + // copy symbol and type attributes back into old expression + // so that the structure builder will find it. + expr setSymbol expr1.symbol setType expr1.tpe + ImportType(expr1) + } + } + + /** Given a case class * case class C[Ts] (ps: Us) * Add the following methods to toScope: @@ -1265,6 +1407,11 @@ trait Namers extends MethodSynthesis { caseClassCopyMeth(cdef) foreach namer.enterSyntheticSym } + /** + * TypeSig is invoked by monoTypeCompleters. It returns the type of a definition which + * is then assigned to the corresponding symbol (typeSig itself does not need to assign + * the type to the symbol, but it can if necessary). + */ def typeSig(tree: Tree): Type = { // log("typeSig " + tree) /** For definitions, transform Annotation trees to AnnotationInfos, assign @@ -1297,83 +1444,33 @@ trait Namers extends MethodSynthesis { } val sym: Symbol = tree.symbol - // @Lukas: I am not sure this is the right way to do things. - // We used to only decorate the module class with annotations, which is - // clearly wrong. Now we decorate both the class and the object. - // But maybe some annotations are only meant for one of these but not for the other? - // - // TODO: meta-annotations to indicate class vs. object. + + // TODO: meta-annotations to indicate where module annotations should go (module vs moduleClass) annotate(sym) if (sym.isModule) annotate(sym.moduleClass) def getSig = tree match { - case cdef @ ClassDef(_, name, tparams, impl) => - val clazz = tree.symbol - val result = createNamer(tree).classSig(tparams, impl) - clazz setInfo result - if (clazz.isDerivedValueClass) { - log("Ensuring companion for derived value class " + name + " at " + cdef.pos.show) - clazz setFlag FINAL - // Don't force the owner's info lest we create cycles as in SI-6357. - enclosingNamerWithScope(clazz.owner.rawInfo.decls).ensureCompanionObject(cdef) - } - result - - case ModuleDef(_, _, impl) => - val clazz = sym.moduleClass - clazz setInfo createNamer(tree).templateSig(impl) - clazz.tpe - - case ddef @ DefDef(mods, _, tparams, vparamss, tpt, rhs) => - // TODO: cleanup parameter list - createNamer(tree).methodSig(ddef, mods, tparams, vparamss, tpt, rhs) - - case vdef @ ValDef(mods, name, tpt, rhs) => - val isBeforeSupercall = ( - (sym hasFlag PARAM | PRESUPER) - && !mods.isJavaDefined - && sym.owner.isConstructor - ) - val typer1 = typer.constrTyperIf(isBeforeSupercall) - if (tpt.isEmpty) { - if (rhs.isEmpty) { - MissingParameterOrValTypeError(tpt) - ErrorType - } - else assignTypeToTree(vdef, newTyper(typer1.context.make(vdef, sym)), WildcardType) - } - else typer1.typedType(tpt).tpe - - case TypeDef(_, _, tparams, rhs) => - createNamer(tree).typeDefSig(sym, tparams, rhs) //@M! - - case Import(expr, selectors) => - val expr1 = typer.typedQualifier(expr) - typer checkStable expr1 - if (expr1.symbol != null && expr1.symbol.isRootPackage) - RootImportError(tree) - - if (expr1.isErrorTyped) - ErrorType - else { - val newImport = treeCopy.Import(tree, expr1, selectors).asInstanceOf[Import] - checkSelectors(newImport) - transformed(tree) = newImport - // copy symbol and type attributes back into old expression - // so that the structure builder will find it. - expr setSymbol expr1.symbol setType expr1.tpe - ImportType(expr1) - } - } + case cdef: ClassDef => + createNamer(tree).classSig(cdef) + + case mdef: ModuleDef => + createNamer(tree).moduleSig(mdef) + + case ddef: DefDef => + createNamer(tree).methodSig(ddef) - val result = - try getSig - catch typeErrorHandler(tree, ErrorType) + case vdef: ValDef => + createNamer(tree).valDefSig(vdef) - result match { - case PolyType(tparams @ (tp :: _), _) if tp.owner.isTerm => deskolemizeTypeParams(tparams)(result) - case _ => result + case tdef: TypeDef => + createNamer(tree).typeDefSig(tdef) //@M! + + case imp: Import => + importSig(imp) } + + try getSig + catch typeErrorHandler(tree, ErrorType) } def includeParent(tpe: Type, parent: Symbol): Type = tpe match { @@ -1446,7 +1543,7 @@ trait Namers extends MethodSynthesis { fail(ImplicitConstr) if (!(sym.isTerm || (sym.isClass && !sym.isTrait))) fail(ImplicitNotTermOrClass) - if (sym.owner.isPackageClass) + if (sym.isTopLevel) fail(ImplicitAtToplevel) } if (sym.isClass) { @@ -1527,14 +1624,25 @@ trait Namers extends MethodSynthesis { } } - /** A class representing a lazy type with known type parameters. + /** + * A class representing a lazy type with known type parameters. `ctx` is the namer context in which the + * `owner` is defined. + * + * Constructing a PolyTypeCompleter for a DefDef creates type skolems for the type parameters and + * assigns them to the `tparams` trees. */ - class PolyTypeCompleter(tparams: List[TypeDef], restp: TypeCompleter, owner: Tree, ctx: Context) extends LockingTypeCompleter with FlagAgnosticCompleter { - private val ownerSym = owner.symbol - override val typeParams = tparams map (_.symbol) //@M - override val tree = restp.tree + class PolyTypeCompleter(tparams: List[TypeDef], restp: TypeCompleter, ctx: Context) extends LockingTypeCompleter with FlagAgnosticCompleter { + // @M. If `owner` is an abstract type member, `typeParams` are all NoSymbol (see comment in `completerOf`), + // otherwise, the non-skolemized (external) type parameter symbols + override val typeParams = tparams map (_.symbol) + + /* The definition tree (poly ClassDef, poly DefDef or HK TypeDef) */ + override val tree = restp.tree + + private val defnSym = tree.symbol - if (ownerSym.isTerm) { + if (defnSym.isTerm) { + // for polymorphic DefDefs, create type skolems and assign them to the tparam trees. val skolems = deriveFreshSkolems(tparams map (_.symbol)) map2(tparams, skolems)(_ setSymbol _) } @@ -1542,8 +1650,8 @@ trait Namers extends MethodSynthesis { def completeImpl(sym: Symbol) = { // @M an abstract type's type parameters are entered. // TODO: change to isTypeMember ? - if (ownerSym.isAbstractType) - newNamerFor(ctx, owner) enterSyms tparams //@M + if (defnSym.isAbstractType) + newNamerFor(ctx, tree) enterSyms tparams //@M restp complete sym } } diff --git a/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala b/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala index f5884e5c34..fa141e95e1 100644 --- a/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala +++ b/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala @@ -41,11 +41,11 @@ trait NamesDefaults { self: Analyzer => blockTyper: Typer ) { } - def nameOf(arg: Tree) = arg match { - case AssignOrNamedArg(Ident(name), rhs) => Some(name) - case _ => None + private def nameOfNamedArg(arg: Tree) = Some(arg) collect { case AssignOrNamedArg(Ident(name), _) => name } + def isNamedArg(arg: Tree) = arg match { + case AssignOrNamedArg(Ident(_), _) => true + case _ => false } - def isNamed(arg: Tree) = nameOf(arg).isDefined /** @param pos maps indices from old to new */ def reorderArgs[T: ClassTag](args: List[T], pos: Int => Int): List[T] = { @@ -55,13 +55,13 @@ trait NamesDefaults { self: Analyzer => } /** @param pos maps indices from new to old (!) */ - def reorderArgsInv[T: ClassTag](args: List[T], pos: Int => Int): List[T] = { + private def reorderArgsInv[T: ClassTag](args: List[T], pos: Int => Int): List[T] = { val argsArray = args.toArray (argsArray.indices map (i => argsArray(pos(i)))).toList } /** returns `true` if every element is equal to its index */ - def isIdentity(a: Array[Int]) = (0 until a.length).forall(i => a(i) == i) + def allArgsArePositional(a: Array[Int]) = (0 until a.length).forall(i => a(i) == i) /** * Transform a function application into a Block, and assigns typer.context @@ -265,26 +265,32 @@ trait NamesDefaults { self: Analyzer => * * For by-name parameters, create a value * x$n: () => T = () => arg + * + * For Ident(<unapply-selector>) arguments, no ValDef is created (SI-3353). */ - def argValDefs(args: List[Tree], paramTypes: List[Type], blockTyper: Typer): List[ValDef] = { + def argValDefs(args: List[Tree], paramTypes: List[Type], blockTyper: Typer): List[Option[ValDef]] = { val context = blockTyper.context - val symPs = map2(args, paramTypes)((arg, tpe) => { - val byName = isByNameParamType(tpe) - val repeated = isScalaRepeatedParamType(tpe) - val argTpe = ( - if (repeated) arg match { - case Typed(expr, Ident(tpnme.WILDCARD_STAR)) => expr.tpe - case _ => seqType(arg.tpe) - } - else arg.tpe - ).widen // have to widen or types inferred from literal defaults will be singletons - val s = context.owner.newValue(unit.freshTermName("x$"), arg.pos, newFlags = ARTIFACT) setInfo ( - if (byName) functionType(Nil, argTpe) else argTpe - ) - (context.scope.enter(s), byName, repeated) + val symPs = map2(args, paramTypes)((arg, tpe) => arg match { + case Ident(nme.SELECTOR_DUMMY) => + None // don't create a local ValDef if the argument is <unapply-selector> + case _ => + val byName = isByNameParamType(tpe) + val repeated = isScalaRepeatedParamType(tpe) + val argTpe = ( + if (repeated) arg match { + case Typed(expr, Ident(tpnme.WILDCARD_STAR)) => expr.tpe + case _ => seqType(arg.tpe) + } + else arg.tpe + ).widen // have to widen or types inferred from literal defaults will be singletons + val s = context.owner.newValue(unit.freshTermName("x$"), arg.pos, newFlags = ARTIFACT) setInfo ( + if (byName) functionType(Nil, argTpe) else argTpe + ) + Some((context.scope.enter(s), byName, repeated)) }) map2(symPs, args) { - case ((sym, byName, repeated), arg) => + case (None, _) => None + case (Some((sym, byName, repeated)), arg) => val body = if (byName) { val res = blockTyper.typed(Function(List(), arg)) @@ -300,7 +306,7 @@ trait NamesDefaults { self: Analyzer => blockTyper.typed(Apply(factory, List(resetLocalAttrs(arg)))) } else arg } - atPos(body.pos)(ValDef(sym, body).setType(NoType)) + Some(atPos(body.pos)(ValDef(sym, body).setType(NoType))) } } @@ -326,27 +332,29 @@ trait NamesDefaults { self: Analyzer => // ValDef's in the block), change the arguments to these local values. case Apply(expr, typedArgs) => // typedArgs: definition-site order - val formals = formalTypes(expr.tpe.paramTypes, typedArgs.length, false, false) + val formals = formalTypes(expr.tpe.paramTypes, typedArgs.length, removeByName = false, removeRepeated = false) // valDefs: call-site order val valDefs = argValDefs(reorderArgsInv(typedArgs, argPos), reorderArgsInv(formals, argPos), blockTyper) // refArgs: definition-site order again - val refArgs = map2(reorderArgs(valDefs, argPos), formals)((vDef, tpe) => { - val ref = gen.mkAttributedRef(vDef.symbol) - atPos(vDef.pos.focus) { - // for by-name parameters, the local value is a nullary function returning the argument - tpe.typeSymbol match { - case ByNameParamClass => Apply(ref, Nil) - case RepeatedParamClass => Typed(ref, Ident(tpnme.WILDCARD_STAR)) - case _ => ref + val refArgs = map3(reorderArgs(valDefs, argPos), formals, typedArgs)((vDefOpt, tpe, origArg) => vDefOpt match { + case None => origArg + case Some(vDef) => + val ref = gen.mkAttributedRef(vDef.symbol) + atPos(vDef.pos.focus) { + // for by-name parameters, the local value is a nullary function returning the argument + tpe.typeSymbol match { + case ByNameParamClass => Apply(ref, Nil) + case RepeatedParamClass => Typed(ref, Ident(tpnme.WILDCARD_STAR)) + case _ => ref + } } - } }) // cannot call blockTyper.typedBlock here, because the method expr might be partially applied only val res = blockTyper.doTypedApply(tree, expr, refArgs, mode, pt) res.setPos(res.pos.makeTransparent) - val block = Block(stats ::: valDefs, res).setType(res.tpe).setPos(tree.pos.makeTransparent) + val block = Block(stats ::: valDefs.flatten, res).setType(res.tpe).setPos(tree.pos.makeTransparent) context.namedApplyBlockInfo = Some((block, NamedApplyInfo(qual, targs, vargss :+ refArgs, blockTyper))) block @@ -359,7 +367,7 @@ trait NamesDefaults { self: Analyzer => } } - def missingParams[T](args: List[T], params: List[Symbol], argName: T => Option[Name] = nameOf _): (List[Symbol], Boolean) = { + def missingParams[T](args: List[T], params: List[Symbol], argName: T => Option[Name] = nameOfNamedArg _): (List[Symbol], Boolean) = { val namedArgs = args.dropWhile(arg => { val n = argName(arg) n.isEmpty || params.forall(p => p.name != n.get) diff --git a/src/compiler/scala/tools/nsc/typechecker/PatternMatching.scala b/src/compiler/scala/tools/nsc/typechecker/PatternMatching.scala index 48bdd07e66..24f406236f 100644 --- a/src/compiler/scala/tools/nsc/typechecker/PatternMatching.scala +++ b/src/compiler/scala/tools/nsc/typechecker/PatternMatching.scala @@ -477,7 +477,7 @@ trait PatternMatching extends Transform with TypingTransformers with ast.TreeDSL **/ // must treat Typed and Bind together -- we need to know the patBinder of the Bind pattern to get at the actual type case MaybeBoundTyped(subPatBinder, pt) => - val next = glb(List(patBinder.info.widen, pt)).normalize + val next = glb(List(patBinder.info.dealiasWiden, pt)).normalize // a typed pattern never has any subtrees noFurtherSubPats(TypeTestTreeMaker(subPatBinder, patBinder, pt, next)(pos)) @@ -742,26 +742,8 @@ trait PatternMatching extends Transform with TypingTransformers with ast.TreeDSL // reference the (i-1)th case accessor if it exists, otherwise the (i-1)th tuple component override protected def tupleSel(binder: Symbol)(i: Int): Tree = { import CODE._ - // caseFieldAccessors is messed up after typers (reversed, names mangled for non-public fields) - // TODO: figure out why... val accessors = binder.caseFieldAccessors - // luckily, the constrParamAccessors are still sorted properly, so sort the field-accessors using them - // (need to undo name-mangling, including the sneaky trailing whitespace) - val constrParamAccessors = binder.constrParamAccessors - - def indexInCPA(acc: Symbol) = - constrParamAccessors indexWhere { orig => - // patmatDebug("compare: "+ (orig, acc, orig.name, acc.name, (acc.name == orig.name), (acc.name startsWith (orig.name append "$")))) - val origName = orig.name.toString.trim - val accName = acc.name.toString.trim - (accName == origName) || (accName startsWith (origName + "$")) - } - - // patmatDebug("caseFieldAccessors: "+ (accessors, binder.caseFieldAccessors map indexInCPA)) - // patmatDebug("constrParamAccessors: "+ constrParamAccessors) - - val accessorsSorted = accessors sortBy indexInCPA - if (accessorsSorted isDefinedAt (i-1)) REF(binder) DOT accessorsSorted(i-1) + if (accessors isDefinedAt (i-1)) REF(binder) DOT accessors(i-1) else codegen.tupleSel(binder)(i) // this won't type check for case classes, as they do not inherit ProductN } @@ -1887,17 +1869,24 @@ trait PatternMatching extends Transform with TypingTransformers with ast.TreeDSL case object False extends Prop // symbols are propositions - case class Sym(val variable: Var, val const: Const) extends Prop { - private[this] val id = nextSymId + abstract case class Sym(val variable: Var, val const: Const) extends Prop { + private[this] val id = Sym.nextSymId + override def toString = variable +"="+ const +"#"+ id } - private def nextSymId = {_symId += 1; _symId}; private var _symId = 0 - + class UniqueSym(variable: Var, const: Const) extends Sym(variable, const) + object Sym { + private val uniques: util.HashSet[Sym] = new util.HashSet("uniques", 512) + def apply(variable: Var, const: Const): Sym = { + val newSym = new UniqueSym(variable, const) + (uniques findEntryOrUpdate newSym) + } + private def nextSymId = {_symId += 1; _symId}; private var _symId = 0 + } def /\(props: Iterable[Prop]) = if (props.isEmpty) True else props.reduceLeft(And(_, _)) def \/(props: Iterable[Prop]) = if (props.isEmpty) False else props.reduceLeft(Or(_, _)) - trait PropTraverser { def apply(x: Prop): Unit = x match { case And(a, b) => apply(a); apply(b) @@ -1944,7 +1933,8 @@ trait PatternMatching extends Transform with TypingTransformers with ast.TreeDSL // // TODO: for V1 representing x1 and V2 standing for x1.head, encode that // V1 = Nil implies -(V2 = Ci) for all Ci in V2's domain (i.e., it is unassignable) - def removeVarEq(props: List[Prop], modelNull: Boolean = false): (Prop, List[Prop]) = { + // may throw an AnalysisBudget.Exception + def removeVarEq(props: List[Prop], modelNull: Boolean = false): (Formula, List[Formula]) = { val start = if (Statistics.canEnable) Statistics.startTimer(patmatAnaVarEq) else null val vars = new scala.collection.mutable.HashSet[Var] @@ -1968,10 +1958,10 @@ trait PatternMatching extends Transform with TypingTransformers with ast.TreeDSL props foreach gatherEqualities.apply if (modelNull) vars foreach (_.registerNull) - val pure = props map rewriteEqualsToProp.apply + val pure = props map (p => eqFreePropToSolvable(rewriteEqualsToProp(p))) - var eqAxioms: Prop = True - def addAxiom(p: Prop) = eqAxioms = And(eqAxioms, p) + val eqAxioms = formulaBuilder + @inline def addAxiom(p: Prop) = addFormula(eqAxioms, eqFreePropToSolvable(p)) patmatDebug("removeVarEq vars: "+ vars) vars.foreach { v => @@ -1997,23 +1987,37 @@ trait PatternMatching extends Transform with TypingTransformers with ast.TreeDSL } } - patmatDebug("eqAxioms:\n"+ cnfString(eqFreePropToSolvable(eqAxioms))) - patmatDebug("pure:"+ pure.map(p => cnfString(eqFreePropToSolvable(p))).mkString("\n")) + patmatDebug("eqAxioms:\n"+ cnfString(toFormula(eqAxioms))) + patmatDebug("pure:"+ pure.map(p => cnfString(p)).mkString("\n")) if (Statistics.canEnable) Statistics.stopTimer(patmatAnaVarEq, start) - (eqAxioms, pure) + (toFormula(eqAxioms), pure) } + // an interface that should be suitable for feeding a SAT solver when the time comes type Formula + type FormulaBuilder + + // creates an empty formula builder to which more formulae can be added + def formulaBuilder: FormulaBuilder + + // val f = formulaBuilder; addFormula(f, f1); ... addFormula(f, fN) + // toFormula(f) == andFormula(f1, andFormula(..., fN)) + def addFormula(buff: FormulaBuilder, f: Formula): Unit + def toFormula(buff: FormulaBuilder): Formula + + // the conjunction of formulae `a` and `b` def andFormula(a: Formula, b: Formula): Formula + // equivalent formula to `a`, but simplified in a lightweight way (drop duplicate clauses) + def simplifyFormula(a: Formula): Formula // may throw an AnalysisBudget.Exception def propToSolvable(p: Prop): Formula = { val (eqAxioms, pure :: Nil) = removeVarEq(List(p), modelNull = false) - eqFreePropToSolvable(And(eqAxioms, pure)) + andFormula(eqAxioms, pure) } // may throw an AnalysisBudget.Exception @@ -2029,24 +2033,35 @@ trait PatternMatching extends Transform with TypingTransformers with ast.TreeDSL } trait CNF extends Logic { - // CNF: a formula is a conjunction of clauses - type Formula = Array[Clause] /** Override Array creation for efficiency (to not go through reflection). */ private implicit val clauseTag: scala.reflect.ClassTag[Clause] = new scala.reflect.ClassTag[Clause] { def runtimeClass: java.lang.Class[Clause] = classOf[Clause] final override def newArray(len: Int): Array[Clause] = new Array[Clause](len) } - def formula(c: Clause*): Formula = c.toArray - def andFormula(a: Formula, b: Formula): Formula = a ++ b + import scala.collection.mutable.ArrayBuffer + type FormulaBuilder = ArrayBuffer[Clause] + def formulaBuilder = ArrayBuffer[Clause]() + def formulaBuilderSized(init: Int) = new ArrayBuffer[Clause](init) + def addFormula(buff: FormulaBuilder, f: Formula): Unit = buff ++= f + def toFormula(buff: FormulaBuilder): Formula = buff + + // CNF: a formula is a conjunction of clauses + type Formula = FormulaBuilder + def formula(c: Clause*): Formula = ArrayBuffer(c: _*) + + type Clause = Set[Lit] // a clause is a disjunction of distinct literals - type Clause = Set[Lit] def clause(l: Lit*): Clause = l.toSet - private def merge(a: Clause, b: Clause) = a ++ b type Lit def Lit(sym: Sym, pos: Boolean = true): Lit + def andFormula(a: Formula, b: Formula): Formula = a ++ b + def simplifyFormula(a: Formula): Formula = a.distinct + + private def merge(a: Clause, b: Clause) = a ++ b + // throws an AnalysisBudget.Exception when the prop results in a CNF that's too big // TODO: be smarter/more efficient about this (http://lara.epfl.ch/w/sav09:tseitin_s_encoding) def eqFreePropToSolvable(p: Prop): Formula = { @@ -2132,7 +2147,7 @@ trait PatternMatching extends Transform with TypingTransformers with ast.TreeDSL class Lit(val sym: Sym, val pos: Boolean) { override def toString = if (!pos) "-"+ sym.toString else sym.toString override def equals(o: Any) = o match { - case o: Lit => (o.sym == sym) && (o.pos == pos) + case o: Lit => (o.sym eq sym) && (o.pos == pos) case _ => false } override def hashCode = sym.hashCode + pos.hashCode @@ -2181,13 +2196,18 @@ trait PatternMatching extends Transform with TypingTransformers with ast.TreeDSL } private def withLit(res: Model, l: Lit): Model = if (res eq NoModel) NoModel else res + (l.sym -> l.pos) - private def dropUnit(f: Formula, unitLit: Lit) = { + private def dropUnit(f: Formula, unitLit: Lit): Formula = { val negated = -unitLit // drop entire clauses that are trivially true // (i.e., disjunctions that contain the literal we're making true in the returned model), // and simplify clauses by dropping the negation of the literal we're making true // (since False \/ X == X) - f.filterNot(_.contains(unitLit)).map(_ - negated) + val dropped = formulaBuilderSized(f.size) + for { + clause <- f + if !(clause contains unitLit) + } dropped += (clause - negated) + dropped } def findModelFor(f: Formula): Model = { @@ -2617,23 +2637,22 @@ trait PatternMatching extends Transform with TypingTransformers with ast.TreeDSL val propsCasesOk = testCasesOk map (t => symbolicCase(t, modelNull = true)) val propsCasesFail = testCasesFail map (t => Not(symbolicCase(t, modelNull = true))) - val (eqAxiomsFail, symbolicCasesFail) = removeVarEq(propsCasesFail, modelNull = true) - val (eqAxiomsOk, symbolicCasesOk) = removeVarEq(propsCasesOk, modelNull = true) try { - // most of the time eqAxiomsFail == eqAxiomsOk, but the different approximations might cause different variables to disapper in general - val eqAxiomsCNF = - if (eqAxiomsFail == eqAxiomsOk) eqFreePropToSolvable(eqAxiomsFail) - else eqFreePropToSolvable(And(eqAxiomsFail, eqAxiomsOk)) + val (eqAxiomsFail, symbolicCasesFail) = removeVarEq(propsCasesFail, modelNull = true) + val (eqAxiomsOk, symbolicCasesOk) = removeVarEq(propsCasesOk, modelNull = true) + val eqAxioms = simplifyFormula(andFormula(eqAxiomsOk, eqAxiomsFail)) // I'm pretty sure eqAxiomsOk == eqAxiomsFail, but not 100% sure. + + val prefix = formulaBuilder + addFormula(prefix, eqAxioms) - var prefix = eqAxiomsCNF var prefixRest = symbolicCasesFail var current = symbolicCasesOk var reachable = true var caseIndex = 0 patmatDebug("reachability, vars:\n"+ ((propsCasesFail flatMap gatherVariables).distinct map (_.describe) mkString ("\n"))) - patmatDebug("equality axioms:\n"+ cnfString(eqAxiomsCNF)) + patmatDebug("equality axioms:\n"+ cnfString(eqAxiomsOk)) // invariant (prefixRest.length == current.length) && (prefix.reverse ++ prefixRest == symbolicCasesFail) // termination: prefixRest.length decreases by 1 @@ -2643,11 +2662,11 @@ trait PatternMatching extends Transform with TypingTransformers with ast.TreeDSL prefixRest = prefixRest.tail if (prefixRest.isEmpty) reachable = true else { - prefix = andFormula(eqFreePropToSolvable(prefHead), prefix) + addFormula(prefix, prefHead) current = current.tail - val model = findModelFor(andFormula(eqFreePropToSolvable(current.head), prefix)) + val model = findModelFor(andFormula(current.head, toFormula(prefix))) - // patmatDebug("trying to reach:\n"+ cnfString(eqFreePropToSolvable(current.head)) +"\nunder prefix:\n"+ cnfString(prefix)) + // patmatDebug("trying to reach:\n"+ cnfString(current.head) +"\nunder prefix:\n"+ cnfString(prefix)) // if (NoModel ne model) patmatDebug("reached: "+ modelString(model)) reachable = NoModel ne model @@ -3213,6 +3232,7 @@ trait PatternMatching extends Transform with TypingTransformers with ast.TreeDSL // TODO: make more fine-grained, as we don't always need to jump def canJump: Boolean + /** Should exhaustivity analysis be skipped? */ def unchecked: Boolean @@ -3446,12 +3466,10 @@ trait PatternMatching extends Transform with TypingTransformers with ast.TreeDSL case Some(cds) => cds } - val allReachable = unchecked || { - // a switch with duplicate cases yields a verify error, - // and a switch with duplicate cases and guards cannot soundly be rewritten to an unguarded switch - // (even though the verify error would disappear, the behaviour would change) - unreachableCase(caseDefsWithGuards) map (cd => reportUnreachable(cd.body.pos)) isEmpty - } + // a switch with duplicate cases yields a verify error, + // and a switch with duplicate cases and guards cannot soundly be rewritten to an unguarded switch + // (even though the verify error would disappear, the behaviour would change) + val allReachable = unreachableCase(caseDefsWithGuards) map (cd => reportUnreachable(cd.body.pos)) isEmpty if (!allReachable) Nil else if (noGuards(caseDefsWithGuards)) { @@ -3487,8 +3505,10 @@ trait PatternMatching extends Transform with TypingTransformers with ast.TreeDSL val alternativesSupported = true val canJump = true - object SwitchablePattern { def unapply(pat: Tree): Option[Tree] = pat match { - case Literal(const@Constant((_: Byte ) | (_: Short) | (_: Int ) | (_: Char ))) => + // Constant folding sets the type of a constant tree to `ConstantType(Constant(folded))` + // The tree itself can be a literal, an ident, a selection, ... + object SwitchablePattern { def unapply(pat: Tree): Option[Tree] = pat.tpe match { + case ConstantType(const) if const.isIntRange => Some(Literal(Constant(const.intValue))) // TODO: Java 7 allows strings in switches case _ => None }} @@ -3692,10 +3712,10 @@ trait PatternMatching extends Transform with TypingTransformers with ast.TreeDSL with SymbolicMatchAnalysis with DPLLSolver { self: TreeMakers => override def optimizeCases(prevBinder: Symbol, cases: List[List[TreeMaker]], pt: Type, unchecked: Boolean): (List[List[TreeMaker]], List[Tree]) = { + unreachableCase(prevBinder, cases, pt) foreach { caseIndex => + reportUnreachable(cases(caseIndex).last.pos) + } if (!unchecked) { - unreachableCase(prevBinder, cases, pt) foreach { caseIndex => - reportUnreachable(cases(caseIndex).last.pos) - } val counterExamples = exhaustive(prevBinder, cases, pt) if (counterExamples.nonEmpty) reportMissingCases(prevBinder.pos, counterExamples) diff --git a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala index e88447c46d..7c60ce275a 100644 --- a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala +++ b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala @@ -11,6 +11,9 @@ import scala.collection.{ mutable, immutable } import transform.InfoTransform import scala.collection.mutable.ListBuffer import scala.language.postfixOps +import scala.tools.nsc.settings.ScalaVersion +import scala.tools.nsc.settings.AnyScalaVersion +import scala.tools.nsc.settings.NoScalaVersion /** <p> * Post-attribution checking and transformation. @@ -68,7 +71,7 @@ abstract class RefChecks extends InfoTransform with scala.reflect.internal.trans if (sym.hasAccessBoundary) "" + sym.privateWithin.name else "" ) - def overridesTypeInPrefix(tp1: Type, tp2: Type, prefix: Type): Boolean = (tp1.normalize, tp2.normalize) match { + def overridesTypeInPrefix(tp1: Type, tp2: Type, prefix: Type): Boolean = (tp1.dealiasWiden, tp2.dealiasWiden) match { case (MethodType(List(), rtp1), NullaryMethodType(rtp2)) => rtp1 <:< rtp2 case (NullaryMethodType(rtp1), MethodType(List(), rtp2)) => @@ -472,12 +475,12 @@ abstract class RefChecks extends InfoTransform with scala.reflect.internal.trans // check a type alias's RHS corresponds to its declaration // this overlaps somewhat with validateVariance if(member.isAliasType) { - // println("checkKindBounds" + ((List(member), List(memberTp.normalize), self, member.owner))) - val kindErrors = typer.infer.checkKindBounds(List(member), List(memberTp.normalize), self, member.owner) + // println("checkKindBounds" + ((List(member), List(memberTp.dealiasWiden), self, member.owner))) + val kindErrors = typer.infer.checkKindBounds(List(member), List(memberTp.dealiasWiden), self, member.owner) if(!kindErrors.isEmpty) unit.error(member.pos, - "The kind of the right-hand side "+memberTp.normalize+" of "+member.keyString+" "+ + "The kind of the right-hand side "+memberTp.dealiasWiden+" of "+member.keyString+" "+ member.varianceString + member.nameString+ " does not conform to its expected kind."+ kindErrors.toList.mkString("\n", ", ", "")) } else if (member.isAbstractType) { @@ -496,7 +499,7 @@ abstract class RefChecks extends InfoTransform with scala.reflect.internal.trans if (member.isStable && !otherTp.isVolatile) { if (memberTp.isVolatile) overrideError("has a volatile type; cannot override a member with non-volatile type") - else memberTp.normalize.resultType match { + else memberTp.dealiasWiden.resultType match { case rt: RefinedType if !(rt =:= otherTp) && !(checkedCombinations contains rt.parents) => // might mask some inconsistencies -- check overrides checkedCombinations += rt.parents @@ -1233,10 +1236,18 @@ abstract class RefChecks extends InfoTransform with scala.reflect.internal.trans * indicating it has changed semantics between versions. */ private def checkMigration(sym: Symbol, pos: Position) = { - if (sym.hasMigrationAnnotation) - unit.warning(pos, "%s has changed semantics in version %s:\n%s".format( - sym.fullLocationString, sym.migrationVersion.get, sym.migrationMessage.get) - ) + if (sym.hasMigrationAnnotation) { + val changed = try + settings.Xmigration.value < ScalaVersion(sym.migrationVersion.get) + catch { + case e : NumberFormatException => + unit.warning(pos, s"${sym.fullLocationString} has an unparsable version number: ${e.getMessage()}") + // if we can't parse the format on the migration annotation just conservatively assume it changed + true + } + if (changed) + unit.warning(pos, s"${sym.fullLocationString} has changed semantics in version ${sym.migrationVersion.get}:\n${sym.migrationMessage.get}") + } } private def checkCompileTimeOnly(sym: Symbol, pos: Position) = { @@ -1298,7 +1309,7 @@ abstract class RefChecks extends InfoTransform with scala.reflect.internal.trans // if the unnormalized type is accessible, that's good enough if (inaccessible.isEmpty) () // or if the normalized type is, that's good too - else if ((tpe ne tpe.normalize) && lessAccessibleSymsInType(tpe.normalize, member).isEmpty) () + else if ((tpe ne tpe.normalize) && lessAccessibleSymsInType(tpe.dealiasWiden, member).isEmpty) () // otherwise warn about the inaccessible syms in the unnormalized type else inaccessible foreach (sym => warnLessAccessible(sym, member)) } @@ -1389,9 +1400,13 @@ abstract class RefChecks extends InfoTransform with scala.reflect.internal.trans case TypeApply(fun, targs) => isClassTypeAccessible(fun) case Select(module, apply) => - // Fixes SI-5626. Classes in refinement types cannot be constructed with `new`. In this case, - // the companion class is actually not a ClassSymbol, but a reference to an abstract type. - module.symbol.companionClass.isClass + ( // SI-4859 `CaseClass1().InnerCaseClass2()` must not be rewritten to `new InnerCaseClass2()`; + // {expr; Outer}.Inner() must not be rewritten to `new Outer.Inner()`. + treeInfo.isQualifierSafeToElide(module) && + // SI-5626 Classes in refinement types cannot be constructed with `new`. In this case, + // the companion class is actually not a ClassSymbol, but a reference to an abstract type. + module.symbol.companionClass.isClass + ) } val doTransform = @@ -1445,7 +1460,7 @@ abstract class RefChecks extends InfoTransform with scala.reflect.internal.trans * arbitrarily choose one as more important than the other. */ checkDeprecated(sym, tree.pos) - if (settings.Xmigration28.value) + if(settings.Xmigration.value != NoScalaVersion) checkMigration(sym, tree.pos) checkCompileTimeOnly(sym, tree.pos) @@ -1617,7 +1632,7 @@ abstract class RefChecks extends InfoTransform with scala.reflect.internal.trans result match { case ClassDef(_, _, _, _) | TypeDef(_, _, _, _) => - if (result.symbol.isLocal || result.symbol.owner.isPackageClass) + if (result.symbol.isLocal || result.symbol.isTopLevel) varianceValidator.traverse(result) case _ => } diff --git a/src/compiler/scala/tools/nsc/typechecker/SyntheticMethods.scala b/src/compiler/scala/tools/nsc/typechecker/SyntheticMethods.scala index ff3e856471..9949e9181b 100644 --- a/src/compiler/scala/tools/nsc/typechecker/SyntheticMethods.scala +++ b/src/compiler/scala/tools/nsc/typechecker/SyntheticMethods.scala @@ -76,14 +76,7 @@ trait SyntheticMethods extends ast.TreeDSL { else templ } - val originalAccessors = clazz.caseFieldAccessors - // private ones will have been renamed -- make sure they are entered - // in the original order. - def accessors = clazz.caseFieldAccessors sortBy { acc => - originalAccessors indexWhere { orig => - (acc.name == orig.name) || (acc.name startsWith (orig.name append "$")) - } - } + def accessors = clazz.caseFieldAccessors val arity = accessors.size // If this is ProductN[T1, T2, ...], accessorLub is the lub of T1, T2, ..., . // !!! Hidden behind -Xexperimental due to bummer type inference bugs. diff --git a/src/compiler/scala/tools/nsc/typechecker/TreeCheckers.scala b/src/compiler/scala/tools/nsc/typechecker/TreeCheckers.scala index 1c1e9c10fb..a112516b59 100644 --- a/src/compiler/scala/tools/nsc/typechecker/TreeCheckers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/TreeCheckers.scala @@ -116,7 +116,8 @@ abstract class TreeCheckers extends Analyzer { try p.source.path + ":" + p.line catch { case _: UnsupportedOperationException => p.toString } - def errorFn(msg: Any): Unit = println("[check: %s] %s".format(phase.prev, msg)) + private var hasError: Boolean = false + def errorFn(msg: Any): Unit = {hasError = true; println("[check: %s] %s".format(phase.prev, msg))} def errorFn(pos: Position, msg: Any): Unit = errorFn(posstr(pos) + ": " + msg) def informFn(msg: Any) { if (settings.verbose.value || settings.debug.value) @@ -143,6 +144,7 @@ abstract class TreeCheckers extends Analyzer { } def runWithUnit[T](unit: CompilationUnit)(body: => Unit): Unit = { + hasError = false val unit0 = currentUnit currentRun.currentUnit = unit body @@ -161,6 +163,7 @@ abstract class TreeCheckers extends Analyzer { checker.precheck.traverse(unit.body) checker.typed(unit.body) checker.postcheck.traverse(unit.body) + if (hasError) unit.warning(NoPosition, "TreeCheckers detected non-compliant trees in " + unit) } } @@ -202,8 +205,11 @@ abstract class TreeCheckers extends Analyzer { case _ => () } - object precheck extends Traverser { + object precheck extends TreeStackTraverser { override def traverse(tree: Tree) { + checkSymbolRefsRespectScope(tree) + checkReturnReferencesDirectlyEnclosingDef(tree) + val sym = tree.symbol def accessed = sym.accessed def fail(msg: String) = errorFn(tree.pos, msg + classstr(tree) + " / " + tree) @@ -274,6 +280,41 @@ abstract class TreeCheckers extends Analyzer { } super.traverse(tree) } + + private def checkSymbolRefsRespectScope(tree: Tree) { + def symbolOf(t: Tree): Symbol = Option(tree.symbol).getOrElse(NoSymbol) + def definedSymbolOf(t: Tree): Symbol = if (t.isDef) symbolOf(t) else NoSymbol + val info = Option(symbolOf(tree).info).getOrElse(NoType) + val referencedSymbols: List[Symbol] = { + val directRef = tree match { + case _: RefTree => symbolOf(tree).toOption + case _ => None + } + def referencedSyms(tp: Type) = (tp collect { + case TypeRef(_, sym, _) => sym + }).toList + val indirectRefs = referencedSyms(info) + (indirectRefs ++ directRef).distinct + } + for { + sym <- referencedSymbols + if (sym.isTypeParameter || sym.isLocal) && !(tree.symbol hasTransOwner sym.owner) + } errorFn(s"The symbol, tpe or info of tree `(${tree}) : ${info}` refers to a out-of-scope symbol, ${sym.fullLocationString}. tree.symbol.ownerChain: ${tree.symbol.ownerChain.mkString(", ")}") + } + + private def checkReturnReferencesDirectlyEnclosingDef(tree: Tree) { + tree match { + case _: Return => + path.collectFirst { + case dd: DefDef => dd + } match { + case None => errorFn(s"Return node ($tree) must be enclosed in a DefDef") + case Some(dd) => + if (tree.symbol != dd.symbol) errorFn(s"Return symbol (${tree.symbol}} does not reference directly enclosing DefDef (${dd.symbol})") + } + case _ => + } + } } object postcheck extends Traverser { diff --git a/src/compiler/scala/tools/nsc/typechecker/TypeDiagnostics.scala b/src/compiler/scala/tools/nsc/typechecker/TypeDiagnostics.scala index ab1751b4f0..af484a47e2 100644 --- a/src/compiler/scala/tools/nsc/typechecker/TypeDiagnostics.scala +++ b/src/compiler/scala/tools/nsc/typechecker/TypeDiagnostics.scala @@ -213,7 +213,7 @@ trait TypeDiagnostics { // force measures than comparing normalized Strings were producing error messages // like "and java.util.ArrayList[String] <: java.util.ArrayList[String]" but there // should be a cleaner way to do this. - if (found.normalize.toString == tp.normalize.toString) "" + if (found.dealiasWiden.toString == tp.dealiasWiden.toString) "" else " (and %s <: %s)".format(found, tp) ) val explainDef = { diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala index 45f290d6c1..6cf9dfdd5b 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala @@ -126,10 +126,7 @@ trait Typers extends Adaptations with Tags { // paramFailed cannot be initialized with params.exists(_.tpe.isError) because that would // hide some valid errors for params preceding the erroneous one. var paramFailed = false - - def mkPositionalArg(argTree: Tree, paramName: Name) = argTree - def mkNamedArg(argTree: Tree, paramName: Name) = atPos(argTree.pos)(new AssignOrNamedArg(Ident(paramName), (argTree))) - var mkArg: (Tree, Name) => Tree = mkPositionalArg + var mkArg: (Name, Tree) => Tree = (_, tree) => tree // DEPMETTODO: instantiate type vars that depend on earlier implicit args (see adapt (4.1)) // @@ -144,9 +141,9 @@ trait Typers extends Adaptations with Tags { argResultsBuff += res if (res.isSuccess) { - argBuff += mkArg(res.tree, param.name) + argBuff += mkArg(param.name, res.tree) } else { - mkArg = mkNamedArg // don't pass the default argument (if any) here, but start emitting named arguments for the following args + mkArg = gen.mkNamedArg // don't pass the default argument (if any) here, but start emitting named arguments for the following args if (!param.hasDefault && !paramFailed) { context.errBuffer.find(_.kind == ErrorKinds.Divergent) match { case Some(divergentImplicit) => @@ -432,12 +429,12 @@ trait Typers extends Adaptations with Tags { def reenterValueParams(vparamss: List[List[ValDef]]) { for (vparams <- vparamss) for (vparam <- vparams) - vparam.symbol = context.scope enter vparam.symbol + context.scope enter vparam.symbol } def reenterTypeParams(tparams: List[TypeDef]): List[Symbol] = for (tparam <- tparams) yield { - tparam.symbol = context.scope enter tparam.symbol + context.scope enter tparam.symbol tparam.symbol.deSkolemize } @@ -683,7 +680,15 @@ trait Typers extends Adaptations with Tags { if (context1.hasErrors) { stopStats() SilentTypeError(context1.errBuffer.head) - } else SilentResultValue(result) + } else { + // If we have a successful result, emit any warnings it created. + if (context1.hasWarnings) { + context1.flushAndReturnWarningsBuffer() foreach { + case (pos, msg) => unit.warning(pos, msg) + } + } + SilentResultValue(result) + } } else { assert(context.bufferErrors || isPastTyper, "silent mode is not available past typer") withSavedContext(context){ @@ -817,9 +822,9 @@ trait Typers extends Adaptations with Tags { orElse { _ => debuglog("fallback on implicits: " + tree + "/" + resetAllAttrs(original)) val tree1 = typed(resetAllAttrs(original), mode, WildcardType) - // Q: `typed` already calls `addAnnotations` and `adapt`. the only difference here is that + // Q: `typed` already calls `pluginsTyped` and `adapt`. the only difference here is that // we pass `EmptyTree` as the `original`. intended? added in 2009 (53d98e7d42) by martin. - tree1 setType addAnnotations(tree1, tree1.tpe) + tree1 setType pluginsTyped(tree1.tpe, this, tree1, mode, pt) if (tree1.isEmpty) tree1 else adapt(tree1, mode, pt, EmptyTree) } ) @@ -1027,8 +1032,8 @@ trait Typers extends Adaptations with Tags { // begin adapt tree.tpe match { - case atp @ AnnotatedType(_, _, _) if canAdaptAnnotations(tree, mode, pt) => // (-1) - adaptAnnotations(tree, mode, pt) + case atp @ AnnotatedType(_, _, _) if canAdaptAnnotations(tree, this, mode, pt) => // (-1) + adaptAnnotations(tree, this, mode, pt) case ct @ ConstantType(value) if mode.inNone(TYPEmode | FUNmode) && (ct <:< pt) && !forScaladoc && !forInteractive => // (0) val sym = tree.symbol if (sym != null && sym.isDeprecated) { @@ -1128,8 +1133,8 @@ trait Typers extends Adaptations with Tags { Select(tree, "to" + sym.name) } } - case AnnotatedType(_, _, _) if canAdaptAnnotations(tree, mode, pt) => // (13) - return typed(adaptAnnotations(tree, mode, pt), mode, pt) + case AnnotatedType(_, _, _) if canAdaptAnnotations(tree, this, mode, pt) => // (13) + return typed(adaptAnnotations(tree, this, mode, pt), mode, pt) case _ => } if (!context.undetparams.isEmpty) { @@ -1391,7 +1396,7 @@ trait Typers extends Adaptations with Tags { case DefDef(_, name, _, _, _, rhs) => if (stat.symbol.isAuxiliaryConstructor) notAllowed("secondary constructor") - else if (isValueClass && (name == nme.equals_ || name == nme.hashCode_)) + else if (isValueClass && (name == nme.equals_ || name == nme.hashCode_) && !stat.symbol.isSynthetic) notAllowed(s"redefinition of $name method. See SIP-15, criterion 4.") else if (stat.symbol != null && stat.symbol.isParamAccessor) notAllowed("additional parameter") @@ -1690,8 +1695,8 @@ trait Typers extends Adaptations with Tags { */ def validateParentClasses(parents: List[Tree], selfType: Type) { val pending = ListBuffer[AbsTypeError]() - def validateDynamicParent(parent: Symbol) = - if (parent == DynamicClass) checkFeature(parent.pos, DynamicsFeature) + def validateDynamicParent(parent: Symbol, parentPos: Position) = + if (parent == DynamicClass) checkFeature(parentPos, DynamicsFeature) def validateParentClass(parent: Tree, superclazz: Symbol) = if (!parent.isErrorTyped) { @@ -1738,7 +1743,7 @@ trait Typers extends Adaptations with Tags { if (parents exists (p => p != parent && p.tpe.typeSymbol == psym && !psym.isError)) pending += ParentInheritedTwiceError(parent, psym) - validateDynamicParent(psym) + validateDynamicParent(psym, parent.pos) } if (!parents.isEmpty && parents.forall(!_.isErrorTyped)) { @@ -1781,12 +1786,16 @@ trait Typers extends Adaptations with Tags { val impl2 = finishMethodSynthesis(impl1, clazz, context) if (clazz.isTrait && clazz.info.parents.nonEmpty && clazz.info.firstParent.typeSymbol == AnyClass) checkEphemeral(clazz, impl2.body) - if ((clazz != ClassfileAnnotationClass) && - (clazz isNonBottomSubClass ClassfileAnnotationClass)) - restrictionWarning(cdef.pos, unit, - "subclassing Classfile does not\n"+ - "make your annotation visible at runtime. If that is what\n"+ - "you want, you must write the annotation class in Java.") + + if ((clazz isNonBottomSubClass ClassfileAnnotationClass) && (clazz != ClassfileAnnotationClass)) { + if (!clazz.owner.isPackageClass) + unit.error(clazz.pos, "inner classes cannot be classfile annotations") + else restrictionWarning(cdef.pos, unit, + """|subclassing Classfile does not + |make your annotation visible at runtime. If that is what + |you want, you must write the annotation class in Java.""".stripMargin) + } + if (!isPastTyper) { for (ann <- clazz.getAnnotation(DeprecatedAttr)) { val m = companionSymbolOf(clazz, context) @@ -1919,7 +1928,7 @@ trait Typers extends Adaptations with Tags { if (clazz.isTrait && hasSuperArgs(parents1.head)) ConstrArgsInParentOfTraitError(parents1.head, clazz) - if ((clazz isSubClass ClassfileAnnotationClass) && !clazz.owner.isPackageClass) + if ((clazz isSubClass ClassfileAnnotationClass) && !clazz.isTopLevel) unit.error(clazz.pos, "inner classes cannot be classfile annotations") if (!phase.erasedTypes && !clazz.info.resultType.isError) // @S: prevent crash for duplicated type members @@ -1971,12 +1980,23 @@ trait Typers extends Adaptations with Tags { mods.copy(annotations = Nil) setPositions mods.positions def typedValDef(vdef: ValDef): ValDef = { + val sym = vdef.symbol + val valDefTyper = { + val maybeConstrCtx = + if ((sym.isParameter || sym.isEarlyInitialized) && sym.owner.isConstructor) context.makeConstructorContext + else context + newTyper(maybeConstrCtx.makeNewScope(vdef, sym)) + } + valDefTyper.typedValDefImpl(vdef) + } + + // use typedValDef instead. this version is called after creating a new context for the ValDef + private def typedValDefImpl(vdef: ValDef) = { val sym = vdef.symbol.initialize - val typer1 = constrTyperIf(sym.isParameter && sym.owner.isConstructor) val typedMods = typedModifiers(vdef.mods) sym.annotations.map(_.completeInfo) - val tpt1 = checkNoEscaping.privates(sym, typer1.typedType(vdef.tpt)) + val tpt1 = checkNoEscaping.privates(sym, typedType(vdef.tpt)) checkNonCyclic(vdef, tpt1) if (sym.hasAnnotation(definitions.VolatileAttr) && !sym.isMutable) @@ -2004,7 +2024,7 @@ trait Typers extends Adaptations with Tags { else subst(tpt1.tpe.typeArgs(0)) else subst(tpt1.tpe) } else tpt1.tpe - newTyper(typer1.context.make(vdef, sym)).transformedOrTyped(vdef.rhs, EXPRmode | BYVALmode, tpt2) + transformedOrTyped(vdef.rhs, EXPRmode | BYVALmode, tpt2) } treeCopy.ValDef(vdef, typedMods, vdef.name, tpt1, checkDead(rhs1)) setType NoType } @@ -2254,13 +2274,12 @@ trait Typers extends Adaptations with Tags { } def typedTypeDef(tdef: TypeDef): TypeDef = - typerWithCondLocalContext(context.makeNewScope(tdef, tdef.symbol))(tdef.tparams.nonEmpty){ - _.typedTypeDef0(tdef) + typerWithCondLocalContext(context.makeNewScope(tdef, tdef.symbol))(tdef.tparams.nonEmpty) { + _.typedTypeDefImpl(tdef) } - // call typedTypeDef instead - // a TypeDef with type parameters must always be type checked in a new scope - private def typedTypeDef0(tdef: TypeDef): TypeDef = { + // use typedTypeDef instead. this version is called after creating a new context for the TypeDef + private def typedTypeDefImpl(tdef: TypeDef): TypeDef = { tdef.symbol.initialize reenterTypeParams(tdef.tparams) val tparams1 = tdef.tparams mapConserve typedTypeDef @@ -2428,7 +2447,7 @@ trait Typers extends Adaptations with Tags { // but not in real life (i.e., now that's we've reset the method's type skolems' // infos back to their pre-GADT-constraint state) if (isFullyDefined(pt) && !(body1.tpe <:< pt)) - body1 = typedPos(body1.pos)(gen.mkCast(body1, pt.normalize)) + body1 = typedPos(body1.pos)(gen.mkCast(body1, pt.dealiasWiden)) } @@ -2498,7 +2517,7 @@ trait Typers extends Adaptations with Tags { */ def synthesizePartialFunction(paramName: TermName, paramPos: Position, tree: Tree, mode: Mode, pt: Type): Tree = { assert(pt.typeSymbol == PartialFunctionClass, s"PartialFunction synthesis for match in $tree requires PartialFunction expected type, but got $pt.") - val targs = pt.normalize.typeArgs + val targs = pt.dealiasWiden.typeArgs // if targs.head isn't fully defined, we can translate --> error targs match { @@ -2656,10 +2675,10 @@ trait Typers extends Adaptations with Tags { def decompose(pt: Type): (Symbol, List[Type], Type) = if ((isFunctionType(pt) || (pt.typeSymbol == PartialFunctionClass && numVparams == 1 && fun.body.isInstanceOf[Match])) && // see bug901 for a reason why next conditions are needed - ( pt.normalize.typeArgs.length - 1 == numVparams + ( pt.dealiasWiden.typeArgs.length - 1 == numVparams || fun.vparams.exists(_.tpt.isEmpty) )) - (pt.typeSymbol, pt.normalize.typeArgs.init, pt.normalize.typeArgs.last) + (pt.typeSymbol, pt.dealiasWiden.typeArgs.init, pt.dealiasWiden.typeArgs.last) else (FunctionClass(numVparams), fun.vparams map (x => NoType), WildcardType) @@ -3093,10 +3112,10 @@ trait Typers extends Adaptations with Tags { val (namelessArgs, argPos) = removeNames(Typer.this)(args, params) if (namelessArgs exists (_.isErroneous)) { duplErrTree - } else if (!isIdentity(argPos) && !sameLength(formals, params)) - // !isIdentity indicates that named arguments are used to re-order arguments + } else if (!allArgsArePositional(argPos) && !sameLength(formals, params)) + // !allArgsArePositional indicates that named arguments are used to re-order arguments duplErrorTree(MultipleVarargError(tree)) - else if (isIdentity(argPos) && !isNamedApplyBlock(fun)) { + else if (allArgsArePositional(argPos) && !isNamedApplyBlock(fun)) { // if there's no re-ordering, and fun is not transformed, no need to transform // more than an optimization, e.g. important in "synchronized { x = update-x }" checkNotMacro() @@ -3146,7 +3165,7 @@ trait Typers extends Adaptations with Tags { } if (!sameLength(formals, args) || // wrong nb of arguments - (args exists isNamed) || // uses a named argument + (args exists isNamedArg) || // uses a named argument isNamedApplyBlock(fun)) { // fun was transformed to a named apply block => // integrate this application into the block if (dyna.isApplyDynamicNamed(fun)) dyna.typedNamedApply(tree, fun, args, mode, pt) @@ -3307,7 +3326,7 @@ trait Typers extends Adaptations with Tags { if (fun1.tpe.isErroneous) duplErrTree else { - val resTp = fun1.tpe.finalResultType.normalize + val resTp = fun1.tpe.finalResultType.dealiasWiden val nbSubPats = args.length val (formals, formalsExpanded) = extractorFormalTypes(fun0.pos, resTp, nbSubPats, fun1.symbol) @@ -3354,7 +3373,12 @@ trait Typers extends Adaptations with Tags { // return the corresponding extractor (an instance of ClassTag[`pt`]) def extractorForUncheckedType(pos: Position, pt: Type): Option[Tree] = if (isPastTyper) None else { // only look at top-level type, can't (reliably) do anything about unchecked type args (in general) - pt.normalize.typeConstructor match { + // but at least make a proper type before passing it elsewhere + val pt1 = pt.dealiasWiden match { + case tr @ TypeRef(pre, sym, args) if args.nonEmpty => copyTypeRef(tr, pre, sym, sym.typeParams map (_.tpeHK)) // replace actual type args with dummies + case pt1 => pt1 + } + pt1 match { // if at least one of the types in an intersection is checkable, use the checkable ones // this avoids problems as in run/matchonseq.scala, where the expected type is `Coll with scala.collection.SeqLike` // Coll is an abstract type, but SeqLike of course is not @@ -3369,18 +3393,24 @@ trait Typers extends Adaptations with Tags { else None case _ => None - } + } } /** * Convert an annotation constructor call into an AnnotationInfo. - * - * @param annClass the expected annotation class */ - def typedAnnotation(ann: Tree, mode: Mode = EXPRmode, selfsym: Symbol = NoSymbol, annClass: Symbol = AnnotationClass, requireJava: Boolean = false): AnnotationInfo = { + def typedAnnotation(ann: Tree, mode: Mode = EXPRmode, selfsym: Symbol = NoSymbol): AnnotationInfo = { var hasError: Boolean = false val pending = ListBuffer[AbsTypeError]() + def finish(res: AnnotationInfo): AnnotationInfo = { + if (hasError) { + pending.foreach(ErrorUtils.issueTypeError) + ErroneousAnnotation + } + else res + } + def reportAnnotationError(err: AbsTypeError) = { pending += err hasError = true @@ -3391,7 +3421,10 @@ trait Typers extends Adaptations with Tags { * floats and literals in particular) are not yet folded. */ def tryConst(tr: Tree, pt: Type): Option[LiteralAnnotArg] = { - val const: Constant = typed(constfold(tr), EXPRmode, pt) match { + // The typed tree may be relevantly different than the tree `tr`, + // e.g. it may have encountered an implicit conversion. + val ttree = typed(constfold(tr), EXPRmode, pt) + val const: Constant = ttree match { case l @ Literal(c) if !l.isErroneous => c case tree => tree.tpe match { case ConstantType(c) => c @@ -3400,7 +3433,7 @@ trait Typers extends Adaptations with Tags { } if (const == null) { - reportAnnotationError(AnnotationNotAConstantError(tr)); None + reportAnnotationError(AnnotationNotAConstantError(ttree)); None } else if (const.value == null) { reportAnnotationError(AnnotationArgNullError(tr)); None } else @@ -3415,7 +3448,14 @@ trait Typers extends Adaptations with Tags { reportAnnotationError(ArrayConstantsError(tree)); None case ann @ Apply(Select(New(tpt), nme.CONSTRUCTOR), args) => - val annInfo = typedAnnotation(ann, mode, NoSymbol, pt.typeSymbol, true) + val annInfo = typedAnnotation(ann, mode, NoSymbol) + val annType = annInfo.tpe + + if (!annType.typeSymbol.isSubClass(pt.typeSymbol)) + reportAnnotationError(AnnotationTypeMismatchError(tpt, annType, annType)) + else if (!annType.typeSymbol.isSubClass(ClassfileAnnotationClass)) + reportAnnotationError(NestedAnnotationError(ann, annType)) + if (annInfo.atp.isErroneous) { hasError = true; None } else Some(NestedAnnotArg(annInfo)) @@ -3450,44 +3490,42 @@ trait Typers extends Adaptations with Tags { } // begin typedAnnotation - val (fun, argss) = { - def extract(fun: Tree, outerArgss: List[List[Tree]]): - (Tree, List[List[Tree]]) = fun match { - case Apply(f, args) => - extract(f, args :: outerArgss) - case Select(New(tpt), nme.CONSTRUCTOR) => - (fun, outerArgss) - case _ => - reportAnnotationError(UnexpectedTreeAnnotation(fun)) - (setError(fun), outerArgss) - } - extract(ann, List()) - } - - val res = if (fun.isErroneous) ErroneousAnnotation - else { - val typedFun @ Select(New(tpt), _) = typed(fun, mode.forFunMode, WildcardType) - val annType = tpt.tpe + val treeInfo.Applied(fun0, targs, argss) = ann + if (fun0.isErroneous) + return finish(ErroneousAnnotation) + val typedFun0 = typed(fun0, mode.forFunMode, WildcardType) + val typedFunPart = ( + // If there are dummy type arguments in typeFun part, it suggests we + // must type the actual constructor call, not only the select. The value + // arguments are how the type arguments will be inferred. + if (targs.isEmpty && typedFun0.exists(t => isDummyAppliedType(t.tpe))) + logResult(s"Retyped $typedFun0 to find type args")(typed(argss.foldLeft(fun0)(Apply(_, _)))) + else + typedFun0 + ) + val treeInfo.Applied(typedFun @ Select(New(annTpt), _), _, _) = typedFunPart + val annType = annTpt.tpe - if (typedFun.isErroneous) ErroneousAnnotation + finish( + if (typedFun.isErroneous) + ErroneousAnnotation else if (annType.typeSymbol isNonBottomSubClass ClassfileAnnotationClass) { // annotation to be saved as java classfile annotation val isJava = typedFun.symbol.owner.isJavaDefined - if (!annType.typeSymbol.isNonBottomSubClass(annClass)) { - reportAnnotationError(AnnotationTypeMismatchError(tpt, annClass.tpe, annType)) - } else if (argss.length > 1) { + if (argss.length > 1) { reportAnnotationError(MultipleArgumentListForAnnotationError(ann)) - } else { + } + else { val annScope = annType.decls .filter(sym => sym.isMethod && !sym.isConstructor && sym.isJavaDefined) val names = new scala.collection.mutable.HashSet[Symbol] - def hasValue = names exists (_.name == nme.value) names ++= (if (isJava) annScope.iterator else typedFun.tpe.params.iterator) + + def hasValue = names exists (_.name == nme.value) val args = argss match { - case List(List(arg)) if !isNamed(arg) && hasValue => - List(new AssignOrNamedArg(Ident(nme.value), arg)) - case as :: _ => as + case (arg :: Nil) :: Nil if !isNamedArg(arg) && hasValue => gen.mkNamedArg(nme.value, arg) :: Nil + case args :: Nil => args } val nvPairs = args map { @@ -3520,13 +3558,12 @@ trait Typers extends Adaptations with Tags { if (hasError) ErroneousAnnotation else AnnotationInfo(annType, List(), nvPairs map {p => (p._1, p._2.get)}).setOriginal(Apply(typedFun, args).setPos(ann.pos)) } - } else if (requireJava) { - reportAnnotationError(NestedAnnotationError(ann, annType)) - } else { + } + else { val typedAnn = if (selfsym == NoSymbol) { // local dummy fixes SI-5544 val localTyper = newTyper(context.make(ann, context.owner.newLocalDummy(ann.pos))) - localTyper.typed(ann, mode, annClass.tpe) + localTyper.typed(ann, mode, annType) } else { // Since a selfsym is supplied, the annotation should have an extra @@ -3540,11 +3577,11 @@ trait Typers extends Adaptations with Tags { // sometimes does. The problem is that "self" ident's within // annot.constr will retain the old symbol from the previous typing. val func = Function(funcparm :: Nil, ann.duplicate) - val funcType = appliedType(FunctionClass(1), selfsym.info, annClass.tpe_*) + val funcType = appliedType(FunctionClass(1), selfsym.info, annType) val Function(arg :: Nil, rhs) = typed(func, mode, funcType) rhs.substituteSymbols(arg.symbol :: Nil, selfsym :: Nil) - } + } def annInfo(t: Tree): AnnotationInfo = t match { case Apply(Select(New(tpt), nme.CONSTRUCTOR), args) => @@ -3571,13 +3608,7 @@ trait Typers extends Adaptations with Tags { if ((typedAnn.tpe == null) || typedAnn.tpe.isErroneous) ErroneousAnnotation else annInfo(typedAnn) - } - } - - if (hasError) { - pending.foreach(ErrorUtils.issueTypeError) - ErroneousAnnotation - } else res + }) } def isRawParameter(sym: Symbol) = // is it a type parameter leaked by a raw type? @@ -3697,7 +3728,8 @@ trait Typers extends Adaptations with Tags { else containsDef(owner, sym) || isRawParameter(sym) || isCapturedExistential(sym) def containsLocal(tp: Type): Boolean = tp exists (t => isLocal(t.typeSymbol) || isLocal(t.termSymbol)) - val normalizeLocals = new TypeMap { + + val dealiasLocals = new TypeMap { def apply(tp: Type): Type = tp match { case TypeRef(pre, sym, args) => if (sym.isAliasType && containsLocal(tp)) apply(tp.dealias) @@ -3750,9 +3782,9 @@ trait Typers extends Adaptations with Tags { for (sym <- remainingSyms) addLocals(sym.existentialBound) } - val normalizedTpe = normalizeLocals(tree.tpe) - addLocals(normalizedTpe) - packSymbols(localSyms.toList, normalizedTpe) + val dealiasedType = dealiasLocals(tree.tpe) + addLocals(dealiasedType) + packSymbols(localSyms.toList, dealiasedType) } def typedClassOf(tree: Tree, tpt: Tree, noGen: Boolean = false) = @@ -3959,7 +3991,8 @@ trait Typers extends Adaptations with Tags { // Lookup in the given qualifier. Used in last-ditch efforts by typedIdent and typedSelect. def lookupInRoot(name: Name): Symbol = lookupInOwner(rootMirror.RootClass, name) - def lookupInEmpty(name: Name): Symbol = lookupInOwner(rootMirror.EmptyPackageClass, name) + def lookupInEmpty(name: Name): Symbol = rootMirror.EmptyPackageClass.info member name + def lookupInQualifier(qual: Tree, name: Name): Symbol = ( if (name == nme.ERROR || qual.tpe.widen.isErroneous) NoSymbol @@ -4187,7 +4220,7 @@ trait Typers extends Adaptations with Tags { if (newPatternMatching && (pt.typeSymbol == PartialFunctionClass)) synthesizePartialFunction(newTermName(context.unit.fresh.newName("x")), tree.pos, tree, mode, pt) else { - val arity = if (isFunctionType(pt)) pt.normalize.typeArgs.length - 1 else 1 + val arity = if (isFunctionType(pt)) pt.dealiasWiden.typeArgs.length - 1 else 1 val params = for (i <- List.range(0, arity)) yield atPos(tree.pos.focusStart) { ValDef(Modifiers(PARAM | SYNTHETIC), @@ -4225,8 +4258,9 @@ trait Typers extends Adaptations with Tags { if (typed(expr).tpe.typeSymbol != UnitClass) unit.warning(tree.pos, "enclosing method " + name + " has result type Unit: return value discarded") } - treeCopy.Return(tree, checkDead(expr1)).setSymbol(enclMethod.owner) - .setType(adaptTypeOfReturn(expr1, restpt.tpe, NothingClass.tpe)) + val res = treeCopy.Return(tree, checkDead(expr1)).setSymbol(enclMethod.owner) + val tp = pluginsTypedReturn(NothingClass.tpe, this, res, restpt.tpe) + res.setType(tp) } } } @@ -4753,7 +4787,7 @@ trait Typers extends Adaptations with Tags { * (2) Change imported symbols to selections */ def typedIdent(tree: Tree, name: Name): Tree = { - // setting to enable unqualified idents in empty package + // setting to enable unqualified idents in empty package (used by the repl) def inEmptyPackage = if (settings.exposeEmptyPackage.value) lookupInEmpty(name) else NoSymbol def issue(err: AbsTypeError) = { @@ -4788,7 +4822,7 @@ trait Typers extends Adaptations with Tags { else if (isPredefMemberNamed(sym, nme.classOf) && pt.typeSymbol == ClassClass && pt.typeArgs.nonEmpty) typedClassOf(tree, TypeTree(pt.typeArgs.head)) else { - val pre1 = if (sym.owner.isPackageClass) sym.owner.thisType else if (qual == EmptyTree) NoPrefix else qual.tpe + val pre1 = if (sym.isTopLevel) sym.owner.thisType else if (qual == EmptyTree) NoPrefix else qual.tpe val tree1 = if (qual == EmptyTree) tree else atPos(tree.pos)(Select(atPos(tree.pos.focusStart)(qual), name)) val (tree2, pre2) = makeAccessible(tree1, sym, pre1, qual) // SI-5967 Important to replace param type A* with Seq[A] when seen from from a reference, to avoid @@ -4891,10 +4925,15 @@ trait Typers extends Adaptations with Tags { .typedStats(pdef.stats, NoSymbol) treeCopy.PackageDef(tree, pid1, stats1) setType NoType } + + /** + * The typer with the correct context for a method definition. If the method is a default getter for + * a constructor default, the resulting typer has a constructor context (fixes SI-5543). + */ def defDefTyper(ddef: DefDef) = { - val flag = ddef.mods.hasDefaultFlag && sym.owner.isModuleClass && + val isConstrDefaultGetter = ddef.mods.hasDefaultFlag && sym.owner.isModuleClass && nme.defaultGetterToMethod(sym.name) == nme.CONSTRUCTOR - newTyper(context.makeNewScope(ddef, sym)).constrTyperIf(flag) + newTyper(context.makeNewScope(ddef, sym)).constrTyperIf(isConstrDefaultGetter) } def typedAlternative(alt: Alternative) = { @@ -4919,13 +4958,15 @@ trait Typers extends Adaptations with Tags { var block1 = typed(tree.block, pt) var catches1 = typedCases(tree.catches, ThrowableClass.tpe, pt) - for (cdef <- catches1; if treeInfo catchesThrowable cdef) { - val name = (treeInfo assignedNameOfPattern cdef).decoded - context.warning(cdef.pat.pos, - s"""|This catches all Throwables, which often has undesirable consequences. - |If intentional, use `case $name : Throwable` to clear this warning.""".stripMargin - ) + for (cdef <- catches1 if !isPastTyper && cdef.guard.isEmpty) { + def warn(name: Name) = context.warning(cdef.pat.pos, s"This catches all Throwables. If this is really intended, use `case ${name.decoded} : Throwable` to clear this warning.") + def unbound(t: Tree) = t.symbol == null || t.symbol == NoSymbol + cdef.pat match { + case Bind(name, i @ Ident(_)) if unbound(i) => warn(name) + case i @ Ident(name) if unbound(i) => warn(name) + case _ => } + } val finalizer1 = if (tree.finalizer.isEmpty) tree.finalizer @@ -5173,11 +5214,13 @@ trait Typers extends Adaptations with Tags { lastTreeToTyper = tree indentTyping() + val ptPlugins = pluginsPt(pt, this, tree, mode) + val startByType = if (Statistics.canEnable) Statistics.pushTimer(byTypeStack, byTypeNanos(tree.getClass)) else null if (Statistics.canEnable) Statistics.incCounter(visitsByType, tree.getClass) try { if (context.retyping && - (tree.tpe ne null) && (tree.tpe.isErroneous || !(tree.tpe <:< pt))) { + (tree.tpe ne null) && (tree.tpe.isErroneous || !(tree.tpe <:< ptPlugins))) { tree.clearType() if (tree.hasSymbolField) tree.symbol = NoSymbol } @@ -5185,7 +5228,7 @@ trait Typers extends Adaptations with Tags { val alreadyTyped = tree.tpe ne null val tree1: Tree = if (alreadyTyped) tree else { printTyping( - ptLine("typing %s: pt = %s".format(ptTree(tree), pt), + ptLine("typing %s: pt = %s".format(ptTree(tree), ptPlugins), "undetparams" -> context.undetparams, "implicitsEnabled" -> context.implicitsEnabled, "enrichmentEnabled" -> context.enrichmentEnabled, @@ -5194,7 +5237,7 @@ trait Typers extends Adaptations with Tags { "context.owner" -> context.owner ) ) - typed1(tree, mode, dropExistential(pt)) + typed1(tree, mode, dropExistential(ptPlugins)) } // Can happen during erroneous compilation - error(s) have been // reported, but we need to avoid causing an NPE with this tree @@ -5208,17 +5251,17 @@ trait Typers extends Adaptations with Tags { ) } - tree1 modifyType (addAnnotations(tree1, _)) + tree1 modifyType (pluginsTyped(_, this, tree1, mode, ptPlugins)) val result = if (tree1.isEmpty) tree1 else { - val result = adapt(tree1, mode, pt, tree) + val result = adapt(tree1, mode, ptPlugins, tree) if (hasPendingMacroExpansions) macroExpandAll(this, result) else result } if (!alreadyTyped) { printTyping("adapted %s: %s to %s, %s".format( - tree1, tree1.tpe.widen, pt, context.undetparamsString) + tree1, tree1.tpe.widen, ptPlugins, context.undetparamsString) ) //DEBUG } if (!isPastTyper) signalDone(context.asInstanceOf[analyzer.Context], tree, result) @@ -5233,7 +5276,7 @@ trait Typers extends Adaptations with Tags { setError(tree) case ex: Exception => if (settings.debug.value) // @M causes cyclic reference error - Console.println("exception when typing "+tree+", pt = "+pt) + Console.println("exception when typing "+tree+", pt = "+ptPlugins) if (context != null && context.unit.exists && tree != null) logError("AT: " + (tree.pos).dbgString, ex) throw ex diff --git a/src/compiler/scala/tools/nsc/typechecker/Unapplies.scala b/src/compiler/scala/tools/nsc/typechecker/Unapplies.scala index e95184ac6d..9c04462d7a 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Unapplies.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Unapplies.scala @@ -100,7 +100,7 @@ trait Unapplies extends ast.TreeDSL def createFun = gen.scalaFunctionConstr(primaries, toIdent(cdef), abstractFun = true) def parents = if (inheritFromFun) List(createFun) else Nil def toString = DefDef( - Modifiers(OVERRIDE | FINAL), + Modifiers(OVERRIDE | FINAL | SYNTHETIC), nme.toString_, Nil, ListOfNil, diff --git a/src/compiler/scala/tools/util/SocketServer.scala b/src/compiler/scala/tools/util/SocketServer.scala index d29a370c28..1b06ce2ff2 100644 --- a/src/compiler/scala/tools/util/SocketServer.scala +++ b/src/compiler/scala/tools/util/SocketServer.scala @@ -16,8 +16,8 @@ trait CompileOutputCommon { def verbose: Boolean def info(msg: String) = if (verbose) echo(msg) - def echo(msg: String) = Console println msg - def warn(msg: String) = System.err println msg + def echo(msg: String) = {Console println msg; Console.flush} + def warn(msg: String) = {Console.err println msg; Console.flush} def fatal(msg: String) = { warn(msg) ; sys.exit(1) } } diff --git a/src/continuations/plugin/scala/tools/selectivecps/CPSAnnotationChecker.scala b/src/continuations/plugin/scala/tools/selectivecps/CPSAnnotationChecker.scala index 600b51f376..beab271a3b 100644 --- a/src/continuations/plugin/scala/tools/selectivecps/CPSAnnotationChecker.scala +++ b/src/continuations/plugin/scala/tools/selectivecps/CPSAnnotationChecker.scala @@ -8,6 +8,7 @@ import scala.tools.nsc.MissingRequirementError abstract class CPSAnnotationChecker extends CPSUtils { val global: Global import global._ + import analyzer.{AnalyzerPlugin, Typer} import definitions._ //override val verbose = true @@ -17,12 +18,12 @@ abstract class CPSAnnotationChecker extends CPSUtils { * Checks whether @cps annotations conform */ object checker extends AnnotationChecker { - private def addPlusMarker(tp: Type) = tp withAnnotation newPlusMarker() - private def addMinusMarker(tp: Type) = tp withAnnotation newMinusMarker() + private[CPSAnnotationChecker] def addPlusMarker(tp: Type) = tp withAnnotation newPlusMarker() + private[CPSAnnotationChecker] def addMinusMarker(tp: Type) = tp withAnnotation newMinusMarker() - private def cleanPlus(tp: Type) = + private[CPSAnnotationChecker] def cleanPlus(tp: Type) = removeAttribs(tp, MarkerCPSAdaptPlus, MarkerCPSTypes) - private def cleanPlusWith(tp: Type)(newAnnots: AnnotationInfo*) = + private[CPSAnnotationChecker] def cleanPlusWith(tp: Type)(newAnnots: AnnotationInfo*) = cleanPlus(tp) withAnnotations newAnnots.toList /** Check annotations to decide whether tpe1 <:< tpe2 */ @@ -115,8 +116,13 @@ abstract class CPSAnnotationChecker extends CPSUtils { } else bounds } + } + + object plugin extends AnalyzerPlugin { + + import checker._ - override def canAdaptAnnotations(tree: Tree, mode: Mode, pt: Type): Boolean = { + override def canAdaptAnnotations(tree: Tree, typer: Typer, mode: Mode, pt: Type): Boolean = { if (!cpsEnabled) return false vprintln("can adapt annotations? " + tree + " / " + tree.tpe + " / " + mode + " / " + pt) @@ -182,7 +188,7 @@ abstract class CPSAnnotationChecker extends CPSUtils { } else false } - override def adaptAnnotations(tree: Tree, mode: Mode, pt: Type): Tree = { + override def adaptAnnotations(tree: Tree, typer: Typer, mode: Mode, pt: Type): Tree = { if (!cpsEnabled) return tree vprintln("adapt annotations " + tree + " / " + tree.tpe + " / " + mode + " / " + pt) @@ -238,14 +244,15 @@ abstract class CPSAnnotationChecker extends CPSUtils { * is in tail position. Therefore, we are making sure that only the types of return expressions * are adapted which will either be removed, or lead to an error. */ - override def adaptTypeOfReturn(tree: Tree, pt: Type, default: => Type): Type = { + override def pluginsTypedReturn(default: Type, typer: Typer, tree: Return, pt: Type): Type = { + val expr = tree.expr // only adapt if method's result type (pt) is cps type val annots = cpsParamAnnotation(pt) if (annots.nonEmpty) { - // return type of `tree` without plus marker, but only if it doesn't have other cps annots - if (hasPlusMarker(tree.tpe) && !hasCpsParamTypes(tree.tpe)) - tree.setType(removeAttribs(tree.tpe, MarkerCPSAdaptPlus)) - tree.tpe + // return type of `expr` without plus marker, but only if it doesn't have other cps annots + if (hasPlusMarker(expr.tpe) && !hasCpsParamTypes(expr.tpe)) + expr.setType(removeAttribs(expr.tpe, MarkerCPSAdaptPlus)) + expr.tpe } else default } @@ -392,7 +399,7 @@ abstract class CPSAnnotationChecker extends CPSUtils { /** Modify the type that has thus far been inferred * for a tree. All this should do is add annotations. */ - override def addAnnotations(tree: Tree, tpe: Type): Type = { + override def pluginsTyped(tpe: Type, typer: Typer, tree: Tree, mode: Mode, pt: Type): Type = { import scala.util.control._ if (!cpsEnabled) { val report = try hasCpsParamTypes(tpe) catch { case _: MissingRequirementError => false } diff --git a/src/continuations/plugin/scala/tools/selectivecps/CPSUtils.scala b/src/continuations/plugin/scala/tools/selectivecps/CPSUtils.scala index 4924e056af..29480576ea 100644 --- a/src/continuations/plugin/scala/tools/selectivecps/CPSUtils.scala +++ b/src/continuations/plugin/scala/tools/selectivecps/CPSUtils.scala @@ -61,7 +61,7 @@ trait CPSUtils { // annotation checker protected def annTypes(ann: AnnotationInfo): (Type, Type) = { - val tp0 :: tp1 :: Nil = ann.atp.normalize.typeArgs + val tp0 :: tp1 :: Nil = ann.atp.dealiasWiden.typeArgs ((tp0, tp1)) } protected def hasMinusMarker(tpe: Type) = tpe hasAnnotation MarkerCPSAdaptMinus diff --git a/src/continuations/plugin/scala/tools/selectivecps/SelectiveCPSPlugin.scala b/src/continuations/plugin/scala/tools/selectivecps/SelectiveCPSPlugin.scala index 90e64d8171..c16cce2f2c 100644 --- a/src/continuations/plugin/scala/tools/selectivecps/SelectiveCPSPlugin.scala +++ b/src/continuations/plugin/scala/tools/selectivecps/SelectiveCPSPlugin.scala @@ -28,6 +28,7 @@ class SelectiveCPSPlugin(val global: Global) extends Plugin { val global: SelectiveCPSPlugin.this.global.type = SelectiveCPSPlugin.this.global } global.addAnnotationChecker(checker.checker) + global.analyzer.addAnalyzerPlugin(checker.plugin) global.log("instantiated cps plugin: " + this) diff --git a/src/library/scala/Enumeration.scala b/src/library/scala/Enumeration.scala index 47d7840e27..21f0c8fd3e 100644 --- a/src/library/scala/Enumeration.scala +++ b/src/library/scala/Enumeration.scala @@ -56,14 +56,6 @@ abstract class Enumeration (initial: Int) extends Serializable { def this() = this(0) - @deprecated("Names should be specified individually or discovered via reflection", "2.10.0") - def this(initial: Int, names: String*) = { - this(initial) - this.nextName = names.iterator - } - @deprecated("Names should be specified individually or discovered via reflection", "2.10.0") - def this(names: String*) = this(0, names: _*) - /* Note that `readResolve` cannot be private, since otherwise the JVM does not invoke it when deserializing subclasses. */ protected def readResolve(): AnyRef = thisenum.getClass.getField(MODULE_INSTANCE_NAME).get(null) @@ -71,7 +63,7 @@ abstract class Enumeration (initial: Int) extends Serializable { /** The name of this enumeration. */ override def toString = - ((getClass.getName stripSuffix MODULE_SUFFIX_STRING split '.').last split + ((getClass.getName stripSuffix MODULE_SUFFIX_STRING split '.').last split Pattern.quote(NAME_JOIN_STRING)).last /** The mapping from the integer used to identify values to the actual @@ -126,7 +118,7 @@ abstract class Enumeration (initial: Int) extends Serializable { * * @param s an `Enumeration` name * @return the `Value` of this `Enumeration` if its name matches `s` - * @throws java.util.NoSuchElementException if no `Value` with a matching + * @throws NoSuchElementException if no `Value` with a matching * name is in this `Enumeration` */ final def withName(s: String): Value = values.find(_.toString == s).get diff --git a/src/library/scala/Predef.scala b/src/library/scala/Predef.scala index 9bb57877d9..be57c38298 100644 --- a/src/library/scala/Predef.scala +++ b/src/library/scala/Predef.scala @@ -147,9 +147,6 @@ object Predef extends LowPriorityImplicits { @deprecated("Use `sys.exit(status)` instead", "2.9.0") def exit(status: Int): Nothing = sys.exit(status) - @deprecated("Use `formatString.format(args: _*)` or `arg.formatted(formatString)` instead", "2.9.0") - def format(text: String, xs: Any*) = augmentString(text).format(xs: _*) - // errors and asserts ------------------------------------------------- /** Tests an expression, throwing an `AssertionError` if false. @@ -236,8 +233,6 @@ object Predef extends LowPriorityImplicits { final class Ensuring[A](val __resultOfEnsuring: A) extends AnyVal { // `__resultOfEnsuring` must be a public val to allow inlining. // See comments in ArrowAssoc for more. - @deprecated("Use `__resultOfEnsuring` instead", "2.10.0") - def x = __resultOfEnsuring def ensuring(cond: Boolean): A = { assert(cond); __resultOfEnsuring } def ensuring(cond: Boolean, msg: => Any): A = { assert(cond, msg); __resultOfEnsuring } @@ -271,10 +266,7 @@ object Predef extends LowPriorityImplicits { // reduces the chances of a user's writing `foo.__leftOfArrow` and // being confused why they get an ambiguous implicit conversion // error. (`foo.x` used to produce this error since both - // any2Ensuring and any2ArrowAssoc pimped an `x` onto everything) - @deprecated("Use `__leftOfArrow` instead", "2.10.0") - def x = __leftOfArrow - + // any2Ensuring and any2ArrowAssoc enrich everything with an `x`) @inline def -> [B](y: B): Tuple2[A, B] = Tuple2(__leftOfArrow, y) def →[B](y: B): Tuple2[A, B] = ->(y) } @@ -335,33 +327,6 @@ object Predef extends LowPriorityImplicits { implicit def shortArrayOps(xs: Array[Short]): ArrayOps[Short] = new ArrayOps.ofShort(xs) implicit def unitArrayOps(xs: Array[Unit]): ArrayOps[Unit] = new ArrayOps.ofUnit(xs) - // Primitive Widenings -------------------------------------------------------------- - - @deprecated("Use `.toShort` for explicit conversion and `Byte.byte2short` for implicit conversion", "2.10.0") def byte2short(x: Byte): Short = x.toShort - @deprecated("Use `.toInt` for explicit conversion and `Byte.byte2int` for implicit conversion", "2.10.0") def byte2int(x: Byte): Int = x.toInt - @deprecated("Use `.toLong` for explicit conversion and `Byte.byte2long for implicit conversion", "2.10.0") def byte2long(x: Byte): Long = x.toLong - @deprecated("Use `.toFloat` for explicit conversion and `Byte.byte2float` for implicit conversion", "2.10.0") def byte2float(x: Byte): Float = x.toFloat - @deprecated("Use `.toDouble` for explicit conversion and `Byte.byte2double` for implicit conversion", "2.10.0") def byte2double(x: Byte): Double = x.toDouble - - @deprecated("Use `.toInt` for explicit conversion and `Short.short2int` for implicit conversion", "2.10.0") def short2int(x: Short): Int = x.toInt - @deprecated("Use `.toLong` for explicit conversion and `Short.short2long` for implicit conversion", "2.10.0") def short2long(x: Short): Long = x.toLong - @deprecated("Use `.toFloat` for explicit conversion and `Short.short2float` for implicit conversion", "2.10.0") def short2float(x: Short): Float = x.toFloat - @deprecated("Use `.toDouble` for explicit conversion and `Short.short2double` for implicit conversion", "2.10.0") def short2double(x: Short): Double = x.toDouble - - @deprecated("Use `.toInt` for explicit conversion and `Char.char2int` for implicit conversion", "2.10.0") def char2int(x: Char): Int = x.toInt - @deprecated("Use `.toLong` for explicit conversion and `Char.char2long` for implicit conversion", "2.10.0") def char2long(x: Char): Long = x.toLong - @deprecated("Use `.toFloat` for explicit conversion and `Char.char2float` for implicit conversion", "2.10.0") def char2float(x: Char): Float = x.toFloat - @deprecated("Use `.toDouble` for explicit conversion and `Char.char2double` for implicit conversion", "2.10.0") def char2double(x: Char): Double = x.toDouble - - @deprecated("Use `.toLong` for explicit conversion and `Int.int2long` for implicit conversion", "2.10.0") def int2long(x: Int): Long = x.toLong - @deprecated("Use `.toFloat` for explicit conversion and `Int.int2float` for implicit conversion", "2.10.0") def int2float(x: Int): Float = x.toFloat - @deprecated("Use `.toDouble` for explicit conversion and `Int.int2double` for implicit conversion", "2.10.0") def int2double(x: Int): Double = x.toDouble - - @deprecated("Use `.toFloat` for explicit conversion and `Long.long2float` for implicit conversion", "2.10.0") def long2float(x: Long): Float = x.toFloat - @deprecated("Use `.toDouble` for explicit conversion and `Long.long2double` for implicit conversion", "2.10.0") def long2double(x: Long): Double = x.toDouble - - @deprecated("Use `.toDouble` for explicit conversion and `Float.float2double` for implicit conversion", "2.10.0") def float2double(x: Float): Double = x.toDouble - // "Autoboxing" and "Autounboxing" --------------------------------------------------- implicit def byte2Byte(x: Byte) = java.lang.Byte.valueOf(x) @@ -402,9 +367,6 @@ object Predef extends LowPriorityImplicits { implicit def any2stringadd(x: Any) = new runtime.StringAdd(x) implicit def unaugmentString(x: StringOps): String = x.repr - @deprecated("Use `StringCanBuildFrom`", "2.10.0") - def stringCanBuildFrom: CanBuildFrom[String, Char, String] = StringCanBuildFrom - implicit val StringCanBuildFrom: CanBuildFrom[String, Char, String] = new CanBuildFrom[String, Char, String] { def apply(from: String) = apply() def apply() = mutable.StringBuilder.newBuilder diff --git a/src/library/scala/ScalaObject.scala b/src/library/scala/ScalaObject.scala deleted file mode 100644 index f67dc3a6c5..0000000000 --- a/src/library/scala/ScalaObject.scala +++ /dev/null @@ -1,16 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ Scala API ** -** / __/ __// _ | / / / _ | (c) 2003-2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** -** /____/\___/_/ |_/____/_/ | | ** -** |/ ** -\* */ - -package scala - -/** Until scala 2.10.0 this marker trait was added to - * scala-compiled classes. Now it only exists for backward - * compatibility. - */ -@deprecated("ScalaObject will be removed", "2.10.0") -trait ScalaObject diff --git a/src/library/scala/Specializable.scala b/src/library/scala/Specializable.scala index c7a6091a65..137598c28d 100644 --- a/src/library/scala/Specializable.scala +++ b/src/library/scala/Specializable.scala @@ -11,7 +11,7 @@ package scala /** A common supertype for companions of specializable types. * Should not be extended in user code. */ -trait Specializable extends SpecializableCompanion +trait Specializable object Specializable { // No type parameter in @specialized annotation. diff --git a/src/library/scala/SpecializableCompanion.scala b/src/library/scala/SpecializableCompanion.scala deleted file mode 100644 index 1a9ce71d2a..0000000000 --- a/src/library/scala/SpecializableCompanion.scala +++ /dev/null @@ -1,14 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ Scala API ** -** / __/ __// _ | / / / _ | (c) 2002-2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** -** /____/\___/_/ |_/____/_/ | | ** -** |/ ** -\* */ - -package scala - -/** A common supertype for companion classes which specialization takes into account. - */ -@deprecated("Use Specializable instead", "2.10.0") -private[scala] trait SpecializableCompanion diff --git a/src/library/scala/annotation/migration.scala b/src/library/scala/annotation/migration.scala index 49fea9434c..adb6de6afd 100644 --- a/src/library/scala/annotation/migration.scala +++ b/src/library/scala/annotation/migration.scala @@ -17,7 +17,8 @@ package scala.annotation * order between Scala 2.7 and 2.8. * * @param message A message describing the change, which is emitted - * by the compiler if the flag `-Xmigration` is set. + * by the compiler if the flag `-Xmigration` indicates a version + * prior to the changedIn version. * * @param changedIn The version, in which the behaviour change was * introduced. diff --git a/src/library/scala/annotation/serializable.scala b/src/library/scala/annotation/serializable.scala deleted file mode 100644 index 1e1aff19d3..0000000000 --- a/src/library/scala/annotation/serializable.scala +++ /dev/null @@ -1,15 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ Scala API ** -** / __/ __// _ | / / / _ | (c) 2002-2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** -** /____/\___/_/ |_/____/_/ | | ** -** |/ ** -\* */ - -package scala.annotation - -/** - * An annotation that designates the class to which it is applied as serializable - */ -@deprecated("instead of `@serializable class C`, use `class C extends Serializable`", "2.9.0") -class serializable extends scala.annotation.StaticAnnotation diff --git a/src/library/scala/annotation/target/package.scala b/src/library/scala/annotation/target/package.scala deleted file mode 100644 index ac2836c0a8..0000000000 --- a/src/library/scala/annotation/target/package.scala +++ /dev/null @@ -1,29 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ Scala API ** -** / __/ __// _ | / / / _ | (c) 2003-2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** -** /____/\___/_/ |_/____/_/ | | ** -** |/ ** -\* */ - -package scala.annotation - -package object target { - @deprecated("Use `@scala.annotation.meta.beanGetter` instead", "2.10.0") - type beanGetter = scala.annotation.meta.beanGetter - - @deprecated("Use `@scala.annotation.meta.beanSetter` instead", "2.10.0") - type beanSetter = scala.annotation.meta.beanSetter - - @deprecated("Use `@scala.annotation.meta.field` instead", "2.10.0") - type field = scala.annotation.meta.field - - @deprecated("Use `@scala.annotation.meta.getter` instead", "2.10.0") - type getter = scala.annotation.meta.getter - - @deprecated("Use `@scala.annotation.meta.param` instead", "2.10.0") - type param = scala.annotation.meta.param - - @deprecated("Use `@scala.annotation.meta.setter` instead", "2.10.0") - type setter = scala.annotation.meta.setter -} diff --git a/src/library/scala/collection/GenTraversableLike.scala b/src/library/scala/collection/GenTraversableLike.scala index 46134c921e..1080c54325 100644 --- a/src/library/scala/collection/GenTraversableLike.scala +++ b/src/library/scala/collection/GenTraversableLike.scala @@ -238,7 +238,7 @@ trait GenTraversableLike[+A, +Repr] extends Any with GenTraversableOnce[A] with * // lettersOf will return a Set[Char], not a Seq * def lettersOf(words: Seq[String]) = words.toSet flatMap (word => word.toSeq) * - * // xs will be a an Iterable[Int] + * // xs will be an Iterable[Int] * val xs = Map("a" -> List(11,111), "b" -> List(22,222)).flatMap(_._2) * * // ys will be a Map[Int, Int] diff --git a/src/library/scala/collection/GenTraversableOnce.scala b/src/library/scala/collection/GenTraversableOnce.scala index afaced4264..a05ee0fb54 100644 --- a/src/library/scala/collection/GenTraversableOnce.scala +++ b/src/library/scala/collection/GenTraversableOnce.scala @@ -119,19 +119,6 @@ trait GenTraversableOnce[+A] extends Any { */ def fold[A1 >: A](z: A1)(op: (A1, A1) => A1): A1 - /** A syntactic sugar for out of order folding. See `fold`. - * - * Example: - * {{{ - * scala> val a = LinkedList(1,2,3,4) - * a: scala.collection.mutable.LinkedList[Int] = LinkedList(1, 2, 3, 4) - * - * scala> val b = (a /:\ 5)(_+_) - * b: Int = 15 - * }}}*/ - @deprecated("use fold instead", "2.10.0") - def /:\[A1 >: A](z: A1)(op: (A1, A1) => A1): A1 = fold(z)(op) - /** Applies a binary operator to a start value and all elements of this $coll, * going left to right. * diff --git a/src/library/scala/collection/JavaConversions.scala b/src/library/scala/collection/JavaConversions.scala index 7ff29650fa..3cb7edacd6 100644 --- a/src/library/scala/collection/JavaConversions.scala +++ b/src/library/scala/collection/JavaConversions.scala @@ -21,7 +21,6 @@ import convert._ * scala.collection.mutable.Buffer <=> java.util.List * scala.collection.mutable.Set <=> java.util.Set * scala.collection.mutable.Map <=> java.util.{ Map, Dictionary } - * scala.collection.mutable.ConcurrentMap (deprecated since 2.10) <=> java.util.concurrent.ConcurrentMap * scala.collection.concurrent.Map <=> java.util.concurrent.ConcurrentMap *}}} * In all cases, converting from a source type to a target type and back diff --git a/src/library/scala/collection/JavaConverters.scala b/src/library/scala/collection/JavaConverters.scala index 439991708e..7700d90560 100755 --- a/src/library/scala/collection/JavaConverters.scala +++ b/src/library/scala/collection/JavaConverters.scala @@ -24,7 +24,7 @@ import convert._ * - `scala.collection.mutable.Buffer` <=> `java.util.List` * - `scala.collection.mutable.Set` <=> `java.util.Set` * - `scala.collection.mutable.Map` <=> `java.util.Map` - * - `scala.collection.mutable.ConcurrentMap` <=> `java.util.concurrent.ConcurrentMap` + * - `scala.collection.mutable.concurrent.Map` <=> `java.util.concurrent.ConcurrentMap` * * In all cases, converting from a source type to a target type and back * again will return the original source object, e.g. diff --git a/src/library/scala/collection/TraversableOnce.scala b/src/library/scala/collection/TraversableOnce.scala index 2de0fdd38c..7345ef8328 100644 --- a/src/library/scala/collection/TraversableOnce.scala +++ b/src/library/scala/collection/TraversableOnce.scala @@ -378,11 +378,6 @@ trait TraversableOnce[+A] extends Any with GenTraversableOnce[A] { object TraversableOnce { - @deprecated("use OnceCanBuildFrom instead", "2.10.0") - def traversableOnceCanBuildFrom[T] = new OnceCanBuildFrom[T] - @deprecated("use MonadOps instead", "2.10.0") - def wrapTraversableOnce[A](trav: TraversableOnce[A]) = new MonadOps(trav) - implicit def alternateImplicit[A](trav: TraversableOnce[A]) = new ForceImplicitAmbiguity implicit def flattenTraversableOnce[A, CC[_]](travs: TraversableOnce[CC[A]])(implicit ev: CC[A] => TraversableOnce[A]) = new FlattenOps[A](travs map ev) diff --git a/src/library/scala/collection/convert/DecorateAsJava.scala b/src/library/scala/collection/convert/DecorateAsJava.scala index 87bcae3923..7447c1bbaf 100644 --- a/src/library/scala/collection/convert/DecorateAsJava.scala +++ b/src/library/scala/collection/convert/DecorateAsJava.scala @@ -25,7 +25,7 @@ import scala.language.implicitConversions * - `scala.collection.mutable.Buffer` <=> `java.util.List` * - `scala.collection.mutable.Set` <=> `java.util.Set` * - `scala.collection.mutable.Map` <=> `java.util.Map` - * - `scala.collection.mutable.ConcurrentMap` <=> `java.util.concurrent.ConcurrentMap` + * - `scala.collection.mutable.concurrent.Map` <=> `java.util.concurrent.ConcurrentMap` * * In all cases, converting from a source type to a target type and back * again will return the original source object, e.g. @@ -279,26 +279,6 @@ trait DecorateAsJava { /** * Adds an `asJava` method that implicitly converts a Scala mutable - * `ConcurrentMap` to a Java `ConcurrentMap`. - * - * The returned Java `ConcurrentMap` is backed by the provided Scala - * `ConcurrentMap` and any side-effects of using it via the Java interface - * will be visible via the Scala interface and vice versa. - * - * If the Scala `ConcurrentMap` was previously obtained from an implicit or - * explicit call of `asConcurrentMap(java.util.concurrect.ConcurrentMap)` - * then the original Java `ConcurrentMap` will be returned. - * - * @param m The `ConcurrentMap` to be converted. - * @return An object with an `asJava` method that returns a Java - * `ConcurrentMap` view of the argument. - */ - @deprecated("Use `concurrent.Map` instead of `ConcurrentMap`.", "2.10.0") - implicit def asJavaConcurrentMapConverter[A, B](m: mutable.ConcurrentMap[A, B]): AsJava[juc.ConcurrentMap[A, B]] = - new AsJava(asJavaConcurrentMap(m)) - - /** - * Adds an `asJava` method that implicitly converts a Scala mutable * `concurrent.Map` to a Java `ConcurrentMap`. * * The returned Java `ConcurrentMap` is backed by the provided Scala diff --git a/src/library/scala/collection/convert/DecorateAsScala.scala b/src/library/scala/collection/convert/DecorateAsScala.scala index 94847a76e3..90e8dded6e 100644 --- a/src/library/scala/collection/convert/DecorateAsScala.scala +++ b/src/library/scala/collection/convert/DecorateAsScala.scala @@ -144,25 +144,6 @@ trait DecorateAsScala { /** * Adds an `asScala` method that implicitly converts a Java `ConcurrentMap` - * to a Scala mutable `ConcurrentMap`. The returned Scala `ConcurrentMap` is - * backed by the provided Java `ConcurrentMap` and any side-effects of using - * it via the Scala interface will be visible via the Java interface and - * vice versa. - * - * If the Java `ConcurrentMap` was previously obtained from an implicit or - * explicit call of `asConcurrentMap(scala.collection.mutable.ConcurrentMap)` - * then the original Scala `ConcurrentMap` will be returned. - * - * @param m The `ConcurrentMap` to be converted. - * @return An object with an `asScala` method that returns a Scala mutable - * `ConcurrentMap` view of the argument. - */ - @deprecated("Use `mapAsScalaConcurrentMapConverter` instead, and use `concurrent.Map` instead of `ConcurrentMap`.", "2.10.0") - def asScalaConcurrentMapConverter[A, B](m: juc.ConcurrentMap[A, B]): AsScala[mutable.ConcurrentMap[A, B]] = - new AsScala(asScalaConcurrentMap(m)) - - /** - * Adds an `asScala` method that implicitly converts a Java `ConcurrentMap` * to a Scala mutable `concurrent.Map`. The returned Scala `concurrent.Map` is * backed by the provided Java `ConcurrentMap` and any side-effects of using * it via the Scala interface will be visible via the Java interface and diff --git a/src/library/scala/collection/convert/WrapAsJava.scala b/src/library/scala/collection/convert/WrapAsJava.scala index 5e6126a7cf..9665ffa045 100644 --- a/src/library/scala/collection/convert/WrapAsJava.scala +++ b/src/library/scala/collection/convert/WrapAsJava.scala @@ -235,27 +235,6 @@ trait WrapAsJava { } /** - * Implicitly converts a Scala mutable `ConcurrentMap` to a Java - * `ConcurrentMap`. - * - * The returned Java `ConcurrentMap` is backed by the provided Scala - * `ConcurrentMap` and any side-effects of using it via the Java interface - * will be visible via the Scala interface and vice versa. - * - * If the Scala `ConcurrentMap` was previously obtained from an implicit or - * explicit call of `asScalaConcurrentMap(java.util.concurrect.ConcurrentMap)` - * then the original Java ConcurrentMap will be returned. - * - * @param m The `ConcurrentMap` to be converted. - * @return A Java `ConcurrentMap` view of the argument. - */ - @deprecated("Use `concurrent.Map` instead of `ConcurrentMap`.", "2.10.0") - implicit def asJavaConcurrentMap[A, B](m: mutable.ConcurrentMap[A, B]): juc.ConcurrentMap[A, B] = m match { - case JConcurrentMapDeprecatedWrapper(wrapped) => wrapped - case _ => new ConcurrentMapDeprecatedWrapper(m) - } - - /** * Implicitly converts a Scala mutable `concurrent.Map` to a Java * `ConcurrentMap`. * diff --git a/src/library/scala/collection/convert/WrapAsScala.scala b/src/library/scala/collection/convert/WrapAsScala.scala index ffcca62291..f43eae10d6 100644 --- a/src/library/scala/collection/convert/WrapAsScala.scala +++ b/src/library/scala/collection/convert/WrapAsScala.scala @@ -12,30 +12,7 @@ package convert import java.{ lang => jl, util => ju }, java.util.{ concurrent => juc } import scala.language.implicitConversions -trait LowPriorityWrapAsScala { - this: WrapAsScala => - - import Wrappers._ - - /** - * Implicitly converts a Java ConcurrentMap to a Scala mutable ConcurrentMap. - * The returned Scala ConcurrentMap is backed by the provided Java - * ConcurrentMap and any side-effects of using it via the Scala interface will - * be visible via the Java interface and vice versa. - * - * If the Java ConcurrentMap was previously obtained from an implicit or - * explicit call of `asConcurrentMap(scala.collection.mutable.ConcurrentMap)` - * then the original Scala ConcurrentMap will be returned. - * - * @param m The ConcurrentMap to be converted. - * @return A Scala mutable ConcurrentMap view of the argument. - */ - @deprecated("Use `mapAsScalaConcurrentMap` instead, and use `concurrent.Map` instead of `ConcurrentMap`.", "2.10.0") - implicit def mapAsScalaDeprecatedConcurrentMap[A, B](m: juc.ConcurrentMap[A, B]): mutable.ConcurrentMap[A, B] = - asScalaConcurrentMap(m) -} - -trait WrapAsScala extends LowPriorityWrapAsScala { +trait WrapAsScala { import Wrappers._ /** * Implicitly converts a Java `Iterator` to a Scala `Iterator`. @@ -178,25 +155,6 @@ trait WrapAsScala extends LowPriorityWrapAsScala { * @param m The ConcurrentMap to be converted. * @return A Scala mutable ConcurrentMap view of the argument. */ - @deprecated("Use `mapAsScalaConcurrentMap` instead, and use `concurrent.Map` instead of `ConcurrentMap`.", "2.10.0") - def asScalaConcurrentMap[A, B](m: juc.ConcurrentMap[A, B]): mutable.ConcurrentMap[A, B] = m match { - case cmw: ConcurrentMapDeprecatedWrapper[a, b] => cmw.underlying - case _ => new JConcurrentMapDeprecatedWrapper(m) - } - - /** - * Implicitly converts a Java ConcurrentMap to a Scala mutable ConcurrentMap. - * The returned Scala ConcurrentMap is backed by the provided Java - * ConcurrentMap and any side-effects of using it via the Scala interface will - * be visible via the Java interface and vice versa. - * - * If the Java ConcurrentMap was previously obtained from an implicit or - * explicit call of `asConcurrentMap(scala.collection.mutable.ConcurrentMap)` - * then the original Scala ConcurrentMap will be returned. - * - * @param m The ConcurrentMap to be converted. - * @return A Scala mutable ConcurrentMap view of the argument. - */ implicit def mapAsScalaConcurrentMap[A, B](m: juc.ConcurrentMap[A, B]): concurrent.Map[A, B] = m match { case cmw: ConcurrentMapWrapper[a, b] => cmw.underlying case _ => new JConcurrentMapWrapper(m) diff --git a/src/library/scala/collection/convert/Wrappers.scala b/src/library/scala/collection/convert/Wrappers.scala index 20add3365d..0f4506b5d5 100644 --- a/src/library/scala/collection/convert/Wrappers.scala +++ b/src/library/scala/collection/convert/Wrappers.scala @@ -276,28 +276,6 @@ private[collection] trait Wrappers { override def empty = JMapWrapper(new ju.HashMap[A, B]) } - class ConcurrentMapDeprecatedWrapper[A, B](override val underlying: mutable.ConcurrentMap[A, B]) extends MutableMapWrapper[A, B](underlying) with juc.ConcurrentMap[A, B] { - - def putIfAbsent(k: A, v: B) = underlying.putIfAbsent(k, v) match { - case Some(v) => v - case None => null.asInstanceOf[B] - } - - def remove(k: AnyRef, v: AnyRef) = try { - underlying.remove(k.asInstanceOf[A], v.asInstanceOf[B]) - } catch { - case ex: ClassCastException => - false - } - - def replace(k: A, v: B): B = underlying.replace(k, v) match { - case Some(v) => v - case None => null.asInstanceOf[B] - } - - def replace(k: A, oldval: B, newval: B) = underlying.replace(k, oldval, newval) - } - class ConcurrentMapWrapper[A, B](override val underlying: concurrent.Map[A, B]) extends MutableMapWrapper[A, B](underlying) with juc.ConcurrentMap[A, B] { def putIfAbsent(k: A, v: B) = underlying.putIfAbsent(k, v) match { @@ -320,31 +298,6 @@ private[collection] trait Wrappers { def replace(k: A, oldval: B, newval: B) = underlying.replace(k, oldval, newval) } - case class JConcurrentMapDeprecatedWrapper[A, B](val underlying: juc.ConcurrentMap[A, B]) extends mutable.AbstractMap[A, B] with JMapWrapperLike[A, B, JConcurrentMapDeprecatedWrapper[A, B]] with mutable.ConcurrentMap[A, B] { - override def get(k: A) = { - val v = underlying get k - if (v != null) Some(v) - else None - } - - override def empty = new JConcurrentMapDeprecatedWrapper(new juc.ConcurrentHashMap[A, B]) - - def putIfAbsent(k: A, v: B): Option[B] = { - val r = underlying.putIfAbsent(k, v) - if (r != null) Some(r) else None - } - - def remove(k: A, v: B): Boolean = underlying.remove(k, v) - - def replace(k: A, v: B): Option[B] = { - val prev = underlying.replace(k, v) - if (prev != null) Some(prev) else None - } - - def replace(k: A, oldvalue: B, newvalue: B): Boolean = - underlying.replace(k, oldvalue, newvalue) - } - case class JConcurrentMapWrapper[A, B](val underlying: juc.ConcurrentMap[A, B]) extends mutable.AbstractMap[A, B] with JMapWrapperLike[A, B, JConcurrentMapWrapper[A, B]] with concurrent.Map[A, B] { override def get(k: A) = { val v = underlying get k diff --git a/src/library/scala/collection/generic/IndexedSeqFactory.scala b/src/library/scala/collection/generic/IndexedSeqFactory.scala index 451e5e0f46..e86d163b3c 100644 --- a/src/library/scala/collection/generic/IndexedSeqFactory.scala +++ b/src/library/scala/collection/generic/IndexedSeqFactory.scala @@ -13,7 +13,7 @@ import language.higherKinds /** A template for companion objects of IndexedSeq and subclasses thereof. * - * @since 2.10 + * @since 2.11 */ abstract class IndexedSeqFactory[CC[X] <: IndexedSeq[X] with GenericTraversableTemplate[X, CC]] extends SeqFactory[CC] { override def ReusableCBF: GenericCanBuildFrom[Nothing] = diff --git a/src/library/scala/collection/immutable/BitSet.scala b/src/library/scala/collection/immutable/BitSet.scala index ed3630edc1..2824309ca2 100644 --- a/src/library/scala/collection/immutable/BitSet.scala +++ b/src/library/scala/collection/immutable/BitSet.scala @@ -31,9 +31,6 @@ abstract class BitSet extends scala.collection.AbstractSet[Int] with Serializable { override def empty = BitSet.empty - @deprecated("Use BitSet.fromBitMask[NoCopy] instead of fromArray", "2.10.0") - def fromArray(elems: Array[Long]): BitSet = fromBitMaskNoCopy(elems) - protected def fromBitMaskNoCopy(elems: Array[Long]): BitSet = BitSet.fromBitMaskNoCopy(elems) /** Update word at index `idx`; enlarge set if `idx` outside range of set. @@ -82,10 +79,6 @@ object BitSet extends BitSetFactory[BitSet] { implicit def canBuildFrom: CanBuildFrom[BitSet, Int, BitSet] = bitsetCanBuildFrom /** A bitset containing all the bits in an array */ - @deprecated("Use fromBitMask[NoCopy] instead of fromArray", "2.10.0") - def fromArray(elems: Array[Long]): BitSet = fromBitMaskNoCopy(elems) - - /** A bitset containing all the bits in an array */ def fromBitMask(elems: Array[Long]): BitSet = { val len = elems.length if (len == 0) empty diff --git a/src/library/scala/collection/immutable/HashMap.scala b/src/library/scala/collection/immutable/HashMap.scala index 29267f22dc..83f0d2c8a2 100644 --- a/src/library/scala/collection/immutable/HashMap.scala +++ b/src/library/scala/collection/immutable/HashMap.scala @@ -87,9 +87,6 @@ class HashMap[A, +B] extends AbstractMap[A, B] def split: Seq[HashMap[A, B]] = Seq(this) - @deprecated("Use the `merged` method instead.", "2.10.0") - def merge[B1 >: B](that: HashMap[A, B1], mergef: MergeFunction[A, B1] = null): HashMap[A, B1] = merge0(that, 0, liftMerger(mergef)) - /** Creates a new map which is the merge of this and the argument hash map. * * Uses the specified collision resolution function if two keys are the same. diff --git a/src/library/scala/collection/immutable/List.scala b/src/library/scala/collection/immutable/List.scala index aeaa479e2f..654ed0286a 100644 --- a/src/library/scala/collection/immutable/List.scala +++ b/src/library/scala/collection/immutable/List.scala @@ -305,6 +305,9 @@ sealed abstract class List[+A] extends AbstractSeq[A] } result } + + override def foldRight[B](z: B)(op: (A, B) => B): B = + reverse.foldLeft(z)((right, left) => op(left, right)) override def stringPrefix = "List" diff --git a/src/library/scala/collection/immutable/RedBlack.scala b/src/library/scala/collection/immutable/RedBlack.scala deleted file mode 100644 index 9739e8f3f3..0000000000 --- a/src/library/scala/collection/immutable/RedBlack.scala +++ /dev/null @@ -1,293 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ Scala API ** -** / __/ __// _ | / / / _ | (c) 2005-2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** -** /____/\___/_/ |_/____/_/ | | ** -** |/ ** -\* */ - - - -package scala -package collection -package immutable - -/** Old base class that was used by previous implementations of `TreeMaps` and `TreeSets`. - * - * Deprecated due to various performance bugs (see [[https://issues.scala-lang.org/browse/SI-5331 SI-5331]] for more information). - * - * @since 2.3 - */ -@deprecated("use `TreeMap` or `TreeSet` instead", "2.10.0") -@SerialVersionUID(8691885935445612921L) -abstract class RedBlack[A] extends Serializable { - - def isSmaller(x: A, y: A): Boolean - - private def blacken[B](t: Tree[B]): Tree[B] = t match { - case RedTree(k, v, l, r) => BlackTree(k, v, l, r) - case t => t - } - private def mkTree[B](isBlack: Boolean, k: A, v: B, l: Tree[B], r: Tree[B]) = - if (isBlack) BlackTree(k, v, l, r) else RedTree(k, v, l, r) - - abstract class Tree[+B] extends Serializable { - def isEmpty: Boolean - def isBlack: Boolean - def lookup(x: A): Tree[B] - def update[B1 >: B](k: A, v: B1): Tree[B1] = blacken(upd(k, v)) - def delete(k: A): Tree[B] = blacken(del(k)) - def range(from: Option[A], until: Option[A]): Tree[B] = blacken(rng(from, until)) - def foreach[U](f: (A, B) => U) - def toStream: Stream[(A,B)] - def iterator: Iterator[(A, B)] - def upd[B1 >: B](k: A, v: B1): Tree[B1] - def del(k: A): Tree[B] - def smallest: NonEmpty[B] - def rng(from: Option[A], until: Option[A]): Tree[B] - def first : A - def last : A - def count : Int - } - abstract class NonEmpty[+B] extends Tree[B] with Serializable { - def isEmpty = false - def key: A - def value: B - def left: Tree[B] - def right: Tree[B] - def lookup(k: A): Tree[B] = - if (isSmaller(k, key)) left.lookup(k) - else if (isSmaller(key, k)) right.lookup(k) - else this - private[this] def balanceLeft[B1 >: B](isBlack: Boolean, z: A, zv: B, l: Tree[B1], d: Tree[B1])/*: NonEmpty[B1]*/ = l match { - case RedTree(y, yv, RedTree(x, xv, a, b), c) => - RedTree(y, yv, BlackTree(x, xv, a, b), BlackTree(z, zv, c, d)) - case RedTree(x, xv, a, RedTree(y, yv, b, c)) => - RedTree(y, yv, BlackTree(x, xv, a, b), BlackTree(z, zv, c, d)) - case _ => - mkTree(isBlack, z, zv, l, d) - } - private[this] def balanceRight[B1 >: B](isBlack: Boolean, x: A, xv: B, a: Tree[B1], r: Tree[B1])/*: NonEmpty[B1]*/ = r match { - case RedTree(z, zv, RedTree(y, yv, b, c), d) => - RedTree(y, yv, BlackTree(x, xv, a, b), BlackTree(z, zv, c, d)) - case RedTree(y, yv, b, RedTree(z, zv, c, d)) => - RedTree(y, yv, BlackTree(x, xv, a, b), BlackTree(z, zv, c, d)) - case _ => - mkTree(isBlack, x, xv, a, r) - } - def upd[B1 >: B](k: A, v: B1): Tree[B1] = { - if (isSmaller(k, key)) balanceLeft(isBlack, key, value, left.upd(k, v), right) - else if (isSmaller(key, k)) balanceRight(isBlack, key, value, left, right.upd(k, v)) - else mkTree(isBlack, k, v, left, right) - } - // Based on Stefan Kahrs' Haskell version of Okasaki's Red&Black Trees - // http://www.cse.unsw.edu.au/~dons/data/RedBlackTree.html - def del(k: A): Tree[B] = { - def balance(x: A, xv: B, tl: Tree[B], tr: Tree[B]) = (tl, tr) match { - case (RedTree(y, yv, a, b), RedTree(z, zv, c, d)) => - RedTree(x, xv, BlackTree(y, yv, a, b), BlackTree(z, zv, c, d)) - case (RedTree(y, yv, RedTree(z, zv, a, b), c), d) => - RedTree(y, yv, BlackTree(z, zv, a, b), BlackTree(x, xv, c, d)) - case (RedTree(y, yv, a, RedTree(z, zv, b, c)), d) => - RedTree(z, zv, BlackTree(y, yv, a, b), BlackTree(x, xv, c, d)) - case (a, RedTree(y, yv, b, RedTree(z, zv, c, d))) => - RedTree(y, yv, BlackTree(x, xv, a, b), BlackTree(z, zv, c, d)) - case (a, RedTree(y, yv, RedTree(z, zv, b, c), d)) => - RedTree(z, zv, BlackTree(x, xv, a, b), BlackTree(y, yv, c, d)) - case (a, b) => - BlackTree(x, xv, a, b) - } - def subl(t: Tree[B]) = t match { - case BlackTree(x, xv, a, b) => RedTree(x, xv, a, b) - case _ => sys.error("Defect: invariance violation; expected black, got "+t) - } - def balLeft(x: A, xv: B, tl: Tree[B], tr: Tree[B]) = (tl, tr) match { - case (RedTree(y, yv, a, b), c) => - RedTree(x, xv, BlackTree(y, yv, a, b), c) - case (bl, BlackTree(y, yv, a, b)) => - balance(x, xv, bl, RedTree(y, yv, a, b)) - case (bl, RedTree(y, yv, BlackTree(z, zv, a, b), c)) => - RedTree(z, zv, BlackTree(x, xv, bl, a), balance(y, yv, b, subl(c))) - case _ => sys.error("Defect: invariance violation at "+right) - } - def balRight(x: A, xv: B, tl: Tree[B], tr: Tree[B]) = (tl, tr) match { - case (a, RedTree(y, yv, b, c)) => - RedTree(x, xv, a, BlackTree(y, yv, b, c)) - case (BlackTree(y, yv, a, b), bl) => - balance(x, xv, RedTree(y, yv, a, b), bl) - case (RedTree(y, yv, a, BlackTree(z, zv, b, c)), bl) => - RedTree(z, zv, balance(y, yv, subl(a), b), BlackTree(x, xv, c, bl)) - case _ => sys.error("Defect: invariance violation at "+left) - } - def delLeft = left match { - case _: BlackTree[_] => balLeft(key, value, left.del(k), right) - case _ => RedTree(key, value, left.del(k), right) - } - def delRight = right match { - case _: BlackTree[_] => balRight(key, value, left, right.del(k)) - case _ => RedTree(key, value, left, right.del(k)) - } - def append(tl: Tree[B], tr: Tree[B]): Tree[B] = (tl, tr) match { - case (Empty, t) => t - case (t, Empty) => t - case (RedTree(x, xv, a, b), RedTree(y, yv, c, d)) => - append(b, c) match { - case RedTree(z, zv, bb, cc) => RedTree(z, zv, RedTree(x, xv, a, bb), RedTree(y, yv, cc, d)) - case bc => RedTree(x, xv, a, RedTree(y, yv, bc, d)) - } - case (BlackTree(x, xv, a, b), BlackTree(y, yv, c, d)) => - append(b, c) match { - case RedTree(z, zv, bb, cc) => RedTree(z, zv, BlackTree(x, xv, a, bb), BlackTree(y, yv, cc, d)) - case bc => balLeft(x, xv, a, BlackTree(y, yv, bc, d)) - } - case (a, RedTree(x, xv, b, c)) => RedTree(x, xv, append(a, b), c) - case (RedTree(x, xv, a, b), c) => RedTree(x, xv, a, append(b, c)) - } - // RedBlack is neither A : Ordering[A], nor A <% Ordered[A] - k match { - case _ if isSmaller(k, key) => delLeft - case _ if isSmaller(key, k) => delRight - case _ => append(left, right) - } - } - - def smallest: NonEmpty[B] = if (left.isEmpty) this else left.smallest - - def toStream: Stream[(A,B)] = - left.toStream ++ Stream((key,value)) ++ right.toStream - - def iterator: Iterator[(A, B)] = - left.iterator ++ Iterator.single(Pair(key, value)) ++ right.iterator - - def foreach[U](f: (A, B) => U) { - left foreach f - f(key, value) - right foreach f - } - - override def rng(from: Option[A], until: Option[A]): Tree[B] = { - if (from == None && until == None) return this - if (from != None && isSmaller(key, from.get)) return right.rng(from, until); - if (until != None && (isSmaller(until.get,key) || !isSmaller(key,until.get))) - return left.rng(from, until); - val newLeft = left.rng(from, None) - val newRight = right.rng(None, until) - if ((newLeft eq left) && (newRight eq right)) this - else if (newLeft eq Empty) newRight.upd(key, value); - else if (newRight eq Empty) newLeft.upd(key, value); - else rebalance(newLeft, newRight) - } - - // The zipper returned might have been traversed left-most (always the left child) - // or right-most (always the right child). Left trees are traversed right-most, - // and right trees are traversed leftmost. - - // Returns the zipper for the side with deepest black nodes depth, a flag - // indicating whether the trees were unbalanced at all, and a flag indicating - // whether the zipper was traversed left-most or right-most. - - // If the trees were balanced, returns an empty zipper - private[this] def compareDepth(left: Tree[B], right: Tree[B]): (List[NonEmpty[B]], Boolean, Boolean, Int) = { - // Once a side is found to be deeper, unzip it to the bottom - def unzip(zipper: List[NonEmpty[B]], leftMost: Boolean): List[NonEmpty[B]] = { - val next = if (leftMost) zipper.head.left else zipper.head.right - next match { - case node: NonEmpty[_] => unzip(node :: zipper, leftMost) - case Empty => zipper - } - } - - // Unzip left tree on the rightmost side and right tree on the leftmost side until one is - // found to be deeper, or the bottom is reached - def unzipBoth(left: Tree[B], - right: Tree[B], - leftZipper: List[NonEmpty[B]], - rightZipper: List[NonEmpty[B]], - smallerDepth: Int): (List[NonEmpty[B]], Boolean, Boolean, Int) = (left, right) match { - case (l @ BlackTree(_, _, _, _), r @ BlackTree(_, _, _, _)) => - unzipBoth(l.right, r.left, l :: leftZipper, r :: rightZipper, smallerDepth + 1) - case (l @ RedTree(_, _, _, _), r @ RedTree(_, _, _, _)) => - unzipBoth(l.right, r.left, l :: leftZipper, r :: rightZipper, smallerDepth) - case (_, r @ RedTree(_, _, _, _)) => - unzipBoth(left, r.left, leftZipper, r :: rightZipper, smallerDepth) - case (l @ RedTree(_, _, _, _), _) => - unzipBoth(l.right, right, l :: leftZipper, rightZipper, smallerDepth) - case (Empty, Empty) => - (Nil, true, false, smallerDepth) - case (Empty, r @ BlackTree(_, _, _, _)) => - val leftMost = true - (unzip(r :: rightZipper, leftMost), false, leftMost, smallerDepth) - case (l @ BlackTree(_, _, _, _), Empty) => - val leftMost = false - (unzip(l :: leftZipper, leftMost), false, leftMost, smallerDepth) - } - unzipBoth(left, right, Nil, Nil, 0) - } - - private[this] def rebalance(newLeft: Tree[B], newRight: Tree[B]) = { - // This is like drop(n-1), but only counting black nodes - def findDepth(zipper: List[NonEmpty[B]], depth: Int): List[NonEmpty[B]] = zipper match { - case BlackTree(_, _, _, _) :: tail => - if (depth == 1) zipper else findDepth(tail, depth - 1) - case _ :: tail => findDepth(tail, depth) - case Nil => sys.error("Defect: unexpected empty zipper while computing range") - } - - // Blackening the smaller tree avoids balancing problems on union; - // this can't be done later, though, or it would change the result of compareDepth - val blkNewLeft = blacken(newLeft) - val blkNewRight = blacken(newRight) - val (zipper, levelled, leftMost, smallerDepth) = compareDepth(blkNewLeft, blkNewRight) - - if (levelled) { - BlackTree(key, value, blkNewLeft, blkNewRight) - } else { - val zipFrom = findDepth(zipper, smallerDepth) - val union = if (leftMost) { - RedTree(key, value, blkNewLeft, zipFrom.head) - } else { - RedTree(key, value, zipFrom.head, blkNewRight) - } - val zippedTree = zipFrom.tail.foldLeft(union: Tree[B]) { (tree, node) => - if (leftMost) - balanceLeft(node.isBlack, node.key, node.value, tree, node.right) - else - balanceRight(node.isBlack, node.key, node.value, node.left, tree) - } - zippedTree - } - } - def first = if (left .isEmpty) key else left.first - def last = if (right.isEmpty) key else right.last - def count = 1 + left.count + right.count - } - case object Empty extends Tree[Nothing] { - def isEmpty = true - def isBlack = true - def lookup(k: A): Tree[Nothing] = this - def upd[B](k: A, v: B): Tree[B] = RedTree(k, v, Empty, Empty) - def del(k: A): Tree[Nothing] = this - def smallest: NonEmpty[Nothing] = throw new NoSuchElementException("empty map") - def iterator: Iterator[(A, Nothing)] = Iterator.empty - def toStream: Stream[(A,Nothing)] = Stream.empty - - def foreach[U](f: (A, Nothing) => U) {} - - def rng(from: Option[A], until: Option[A]) = this - def first = throw new NoSuchElementException("empty map") - def last = throw new NoSuchElementException("empty map") - def count = 0 - } - case class RedTree[+B](override val key: A, - override val value: B, - override val left: Tree[B], - override val right: Tree[B]) extends NonEmpty[B] { - def isBlack = false - } - case class BlackTree[+B](override val key: A, - override val value: B, - override val left: Tree[B], - override val right: Tree[B]) extends NonEmpty[B] { - def isBlack = true - } -} diff --git a/src/library/scala/collection/immutable/TreeMap.scala b/src/library/scala/collection/immutable/TreeMap.scala index 5b4db2686a..9a87d8636b 100644 --- a/src/library/scala/collection/immutable/TreeMap.scala +++ b/src/library/scala/collection/immutable/TreeMap.scala @@ -51,9 +51,6 @@ class TreeMap[A, +B] private (tree: RB.Tree[A, B])(implicit val ordering: Orderi with MapLike[A, B, TreeMap[A, B]] with Serializable { - @deprecated("use `ordering.lt` instead", "2.10.0") - def isSmaller(x: A, y: A) = ordering.lt(x, y) - override protected[this] def newBuilder : Builder[(A, B), TreeMap[A, B]] = TreeMap.newBuilder[A, B] diff --git a/src/library/scala/collection/immutable/TreeSet.scala b/src/library/scala/collection/immutable/TreeSet.scala index 494776587d..8bceb936aa 100644 --- a/src/library/scala/collection/immutable/TreeSet.scala +++ b/src/library/scala/collection/immutable/TreeSet.scala @@ -96,9 +96,6 @@ class TreeSet[A] private (tree: RB.Tree[A, Unit])(implicit val ordering: Orderin override def takeWhile(p: A => Boolean) = take(countWhile(p)) override def span(p: A => Boolean) = splitAt(countWhile(p)) - @deprecated("use `ordering.lt` instead", "2.10.0") - def isSmaller(x: A, y: A) = compare(x,y) < 0 - def this()(implicit ordering: Ordering[A]) = this(null)(ordering) private def newSet(t: RB.Tree[A, Unit]) = new TreeSet[A](t) diff --git a/src/library/scala/collection/immutable/package.scala b/src/library/scala/collection/immutable/package.scala deleted file mode 100644 index ed0c1b3736..0000000000 --- a/src/library/scala/collection/immutable/package.scala +++ /dev/null @@ -1,93 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ Scala API ** -** / __/ __// _ | / / / _ | (c) 2003-2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** -** /____/\___/_/ |_/____/_/ | | ** -** |/ ** -\* */ - -package scala.collection - -package immutable { - /** It looks like once upon a time this was used by ParRange, but - * since December 2010 in r23721 it is not used by anything. We - * should not have public API traits with seductive names like - * "RangeUtils" which are neither documented nor used. - */ - @deprecated("this class will be removed", "2.10.0") - trait RangeUtils[+Repr <: RangeUtils[Repr]] { - def start: Int - def end: Int - def step: Int - def inclusive: Boolean - def create(_start: Int, _end: Int, _step: Int, _inclusive: Boolean): Repr - - private final def inclusiveLast: Int = { - val size = end.toLong - start.toLong - (size / step.toLong * step.toLong + start.toLong).toInt - } - - final def _last: Int = ( - if (!inclusive) { - if (step == 1 || step == -1) end - step - else { - val inclast = inclusiveLast - if ((end.toLong - start.toLong) % step == 0) inclast - step else inclast - } - } - else if (step == 1 || step == -1) end - else inclusiveLast - ) - - final def _foreach[U](f: Int => U) = if (_length > 0) { - var i = start - val last = _last - while (i != last) { - f(i) - i += step - } - } - - final def _length: Int = ( - if (!inclusive) { - if (end > start == step > 0 && start != end) { - (_last.toLong - start.toLong) / step.toLong + 1 - } else 0 - }.toInt - else { - if (end > start == step > 0 || start == end) { - (_last.toLong - start.toLong) / step.toLong + 1 - } else 0 - }.toInt - ) - - final def _apply(idx: Int): Int = { - if (idx < 0 || idx >= _length) throw new IndexOutOfBoundsException(idx.toString) - start + idx * step - } - - private def locationAfterN(n: Int) = ( - if (n > 0) { - if (step > 0) - scala.math.min(start.toLong + step.toLong * n.toLong, _last.toLong).toInt - else - scala.math.max(start.toLong + step.toLong * n.toLong, _last.toLong).toInt - } - else start - ) - - final def _take(n: Int) = ( - if (n > 0 && _length > 0) - create(start, locationAfterN(n), step, true) - else - create(start, start, step, false) - ) - - final def _drop(n: Int) = create(locationAfterN(n), end, step, inclusive) - final def _slice(from: Int, until: Int) = _drop(from)._take(until - from) - } -} - -package object immutable { - /** Nothing left after I promoted RangeUtils to the package. */ -} diff --git a/src/library/scala/collection/mutable/ConcurrentMap.scala b/src/library/scala/collection/mutable/ConcurrentMap.scala deleted file mode 100644 index 5b5d738d03..0000000000 --- a/src/library/scala/collection/mutable/ConcurrentMap.scala +++ /dev/null @@ -1,90 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ Scala API ** -** / __/ __// _ | / / / _ | (c) 2010-2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** -** /____/\___/_/ |_/____/_/ | | ** -** |/ ** -\* */ - -package scala.collection -package mutable - -/** A template trait for mutable maps that allow concurrent access. - * - * $concurrentmapinfo - * - * @since 2.8 - * @see [[http://docs.scala-lang.org/overviews/collections/concrete-mutable-collection-classes.html#concurrent_maps "Scala's Collection Library overview"]] - * section on `Concurrent Maps` for more information. - * - * @tparam A the key type of the map - * @tparam B the value type of the map - * - * @define Coll `ConcurrentMap` - * @define coll concurrent map - * @define concurrentmapinfo - * This is a base trait for all Scala concurrent map implementations. It - * provides all of the methods a `Map` does, with the difference that all the - * changes are atomic. It also describes methods specific to concurrent maps. - * - * '''Note''': The concurrent maps do not accept `'''null'''` for keys or values. - * - * @define atomicop - * This is an atomic operation. - */ -@deprecated("Use `scala.collection.concurrent.Map` instead.", "2.10.0") -trait ConcurrentMap[A, B] extends Map[A, B] { - - /** - * Associates the given key with a given value, unless the key was already - * associated with some other value. - * - * $atomicop - * - * @param k key with which the specified value is to be associated with - * @param v value to be associated with the specified key - * @return `Some(oldvalue)` if there was a value `oldvalue` previously - * associated with the specified key, or `None` if there was no - * mapping for the specified key - */ - def putIfAbsent(k: A, v: B): Option[B] - - /** - * Removes the entry for the specified key if its currently mapped to the - * specified value. - * - * $atomicop - * - * @param k key for which the entry should be removed - * @param v value expected to be associated with the specified key if - * the removal is to take place - * @return `true` if the removal took place, `false` otherwise - */ - def remove(k: A, v: B): Boolean - - /** - * Replaces the entry for the given key only if it was previously mapped to - * a given value. - * - * $atomicop - * - * @param k key for which the entry should be replaced - * @param oldvalue value expected to be associated with the specified key - * if replacing is to happen - * @param newvalue value to be associated with the specified key - * @return `true` if the entry was replaced, `false` otherwise - */ - def replace(k: A, oldvalue: B, newvalue: B): Boolean - - /** - * Replaces the entry for the given key only if it was previously mapped - * to some value. - * - * $atomicop - * - * @param k key for which the entry should be replaced - * @param v value to be associated with the specified key - * @return `Some(v)` if the given key was previously mapped to some value `v`, or `None` otherwise - */ - def replace(k: A, v: B): Option[B] -} diff --git a/src/library/scala/collection/mutable/HashSet.scala b/src/library/scala/collection/mutable/HashSet.scala index b5fa557687..c4c68fdb7a 100644 --- a/src/library/scala/collection/mutable/HashSet.scala +++ b/src/library/scala/collection/mutable/HashSet.scala @@ -86,7 +86,7 @@ extends AbstractSet[A] } private def readObject(in: java.io.ObjectInputStream) { - init(in, x => x) + init(in, x => ()) } /** Toggles whether a size map is used to track hash map statistics. diff --git a/src/library/scala/collection/mutable/ListMap.scala b/src/library/scala/collection/mutable/ListMap.scala index 212ee917c5..7f05deffc8 100644 --- a/src/library/scala/collection/mutable/ListMap.scala +++ b/src/library/scala/collection/mutable/ListMap.scala @@ -12,6 +12,7 @@ package scala.collection package mutable import generic._ +import annotation.tailrec /** A simple mutable map backed by a list. * @@ -47,13 +48,17 @@ extends AbstractMap[A, B] def get(key: A): Option[B] = elems find (_._1 == key) map (_._2) def iterator: Iterator[(A, B)] = elems.iterator - def += (kv: (A, B)) = { elems = remove(kv._1, elems); elems = kv :: elems; siz += 1; this } - def -= (key: A) = { elems = remove(key, elems); this } - private def remove(key: A, elems: List[(A, B)]): List[(A, B)] = - if (elems.isEmpty) elems - else if (elems.head._1 == key) { siz -= 1; elems.tail } - else elems.head :: remove(key, elems.tail) + def += (kv: (A, B)) = { elems = remove(kv._1, elems, List()); elems = kv :: elems; siz += 1; this } + def -= (key: A) = { elems = remove(key, elems, List()); this } + + @tailrec + private def remove(key: A, elems: List[(A, B)], acc: List[(A, B)]): List[(A, B)] = { + if (elems.isEmpty) acc + else if (elems.head._1 == key) { siz -= 1; acc ::: elems.tail } + else remove(key, elems.tail, elems.head :: acc) + } + override def clear() = { elems = List(); siz = 0 } override def size: Int = siz diff --git a/src/library/scala/collection/mutable/PriorityQueue.scala b/src/library/scala/collection/mutable/PriorityQueue.scala index 84257c6e97..f59cbe878c 100644 --- a/src/library/scala/collection/mutable/PriorityQueue.scala +++ b/src/library/scala/collection/mutable/PriorityQueue.scala @@ -146,14 +146,6 @@ class PriorityQueue[A](implicit val ord: Ordering[A]) * * @return the element with the highest priority. */ - @deprecated("Use `head` instead.", "2.9.0") - def max: A = if (resarr.p_size0 > 1) toA(resarr.p_array(1)) else throw new NoSuchElementException("queue is empty") - - /** Returns the element with the highest priority in the queue, - * or throws an error if there is no element contained in the queue. - * - * @return the element with the highest priority. - */ override def head: A = if (resarr.p_size0 > 1) toA(resarr.p_array(1)) else throw new NoSuchElementException("queue is empty") /** Removes all elements from the queue. After this operation is completed, diff --git a/src/library/scala/collection/mutable/PriorityQueueProxy.scala b/src/library/scala/collection/mutable/PriorityQueueProxy.scala index 3bb5d32cf8..52a3755007 100644 --- a/src/library/scala/collection/mutable/PriorityQueueProxy.scala +++ b/src/library/scala/collection/mutable/PriorityQueueProxy.scala @@ -75,14 +75,6 @@ abstract class PriorityQueueProxy[A](implicit ord: Ordering[A]) extends Priority */ override def head: A = self.head - /** Returns the element with the highest priority in the queue, - * or throws an error if there is no element contained in the queue. - * - * @return the element with the highest priority. - */ - @deprecated("Use `head` instead.", "2.9.0") - override def max: A = self.max - /** Removes all elements from the queue. After this operation is completed, * the queue will be empty. */ diff --git a/src/library/scala/collection/parallel/ParIterableLike.scala b/src/library/scala/collection/parallel/ParIterableLike.scala index d77e5a6744..6eda29e6b0 100644 --- a/src/library/scala/collection/parallel/ParIterableLike.scala +++ b/src/library/scala/collection/parallel/ParIterableLike.scala @@ -454,7 +454,7 @@ self: ParIterableLike[T, Repr, Sequential] => def reduceRightOption[U >: T](op: (T, U) => U): Option[U] = seq.reduceRightOption(op) - /** Applies a function `f` to all the elements of $coll in a undefined order. + /** Applies a function `f` to all the elements of $coll in an undefined order. * * @tparam U the result type of the function applied to each element, which is always discarded * @param f function applied to each element diff --git a/src/library/scala/collection/parallel/Tasks.scala b/src/library/scala/collection/parallel/Tasks.scala index 12f8012a5b..4e350a2adf 100644 --- a/src/library/scala/collection/parallel/Tasks.scala +++ b/src/library/scala/collection/parallel/Tasks.scala @@ -346,60 +346,6 @@ object ThreadPoolTasks { ) } - -/** An implementation of tasks objects based on the Java thread pooling API and synchronization using futures. */ -@deprecated("This implementation is not used.", "2.10.0") -trait FutureThreadPoolTasks extends Tasks { - import java.util.concurrent._ - - trait WrappedTask[R, +Tp] extends Runnable with super.WrappedTask[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 newWrappedTask[R, Tp](b: Task[R, Tp]): WrappedTask[R, Tp] - - val environment: AnyRef = FutureThreadPoolTasks.defaultThreadPool - def executor = environment.asInstanceOf[ThreadPoolExecutor] - - def execute[R, Tp](task: Task[R, Tp]): () => R = { - val t = newWrappedTask(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 = newWrappedTask(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._ diff --git a/src/library/scala/collection/parallel/mutable/ParArray.scala b/src/library/scala/collection/parallel/mutable/ParArray.scala index db4a59f6ba..770599e9d3 100644 --- a/src/library/scala/collection/parallel/mutable/ParArray.scala +++ b/src/library/scala/collection/parallel/mutable/ParArray.scala @@ -470,7 +470,6 @@ self => Array.copy(arr, i, targetarr, 0, until - i) pac.buff.size = pac.buff.size + until - i pac.buff.lastPtr.size = until - i - pac } otherwise { copy2builder_quick(cb, arr, until, i) i = until @@ -532,7 +531,6 @@ self => val targetarr: Array[Any] = pac.lastbuff.internalArray.asInstanceOf[Array[Any]] reverse2combiner_quick(targetarr, arr, 0, i, until) pac.lastbuff.setInternalSize(sz) - pac } otherwise { cb.ifIs[UnrolledParArrayCombiner[T]] { pac => @@ -543,7 +541,6 @@ self => reverse2combiner_quick(targetarr, arr, 0, i, until) pac.buff.size = pac.buff.size + sz pac.buff.lastPtr.size = sz - pac } otherwise super.reverse2combiner(cb) } cb diff --git a/src/library/scala/collection/parallel/mutable/ParHashSet.scala b/src/library/scala/collection/parallel/mutable/ParHashSet.scala index 68a5f20cb5..e5de6182e6 100644 --- a/src/library/scala/collection/parallel/mutable/ParHashSet.scala +++ b/src/library/scala/collection/parallel/mutable/ParHashSet.scala @@ -85,7 +85,7 @@ extends ParSet[T] } private def readObject(in: java.io.ObjectInputStream) { - init(in, x => x) + init(in, x => ()) } import scala.collection.DebugUtils._ diff --git a/src/library/scala/concurrent/BatchingExecutor.scala b/src/library/scala/concurrent/BatchingExecutor.scala new file mode 100644 index 0000000000..a0d7aaea47 --- /dev/null +++ b/src/library/scala/concurrent/BatchingExecutor.scala @@ -0,0 +1,117 @@ +/* __ *\ +** ________ ___ / / ___ Scala API ** +** / __/ __// _ | / / / _ | (c) 2003-2013, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** +** /____/\___/_/ |_/____/_/ | | ** +** |/ ** +\* */ + +package scala.concurrent + +import java.util.concurrent.Executor +import scala.annotation.tailrec + +/** + * Mixin trait for an Executor + * which groups multiple nested `Runnable.run()` calls + * into a single Runnable passed to the original + * Executor. This can be a useful optimization + * because it bypasses the original context's task + * queue and keeps related (nested) code on a single + * thread which may improve CPU affinity. However, + * if tasks passed to the Executor are blocking + * or expensive, this optimization can prevent work-stealing + * and make performance worse. Also, some ExecutionContext + * may be fast enough natively that this optimization just + * adds overhead. + * The default ExecutionContext.global is already batching + * or fast enough not to benefit from it; while + * `fromExecutor` and `fromExecutorService` do NOT add + * this optimization since they don't know whether the underlying + * executor will benefit from it. + * A batching executor can create deadlocks if code does + * not use `scala.concurrent.blocking` when it should, + * because tasks created within other tasks will block + * on the outer task completing. + * This executor may run tasks in any order, including LIFO order. + * There are no ordering guarantees. + * + * WARNING: The underlying Executor's execute-method must not execute the submitted Runnable + * in the calling thread synchronously. It must enqueue/handoff the Runnable. + */ +private[concurrent] trait BatchingExecutor extends Executor { + + // invariant: if "_tasksLocal.get ne null" then we are inside BatchingRunnable.run; if it is null, we are outside + private val _tasksLocal = new ThreadLocal[List[Runnable]]() + + private class Batch(val initial: List[Runnable]) extends Runnable with BlockContext { + private var parentBlockContext: BlockContext = _ + // this method runs in the delegate ExecutionContext's thread + override def run(): Unit = { + require(_tasksLocal.get eq null) + + val prevBlockContext = BlockContext.current + BlockContext.withBlockContext(this) { + try { + parentBlockContext = prevBlockContext + + @tailrec def processBatch(batch: List[Runnable]): Unit = batch match { + case Nil => () + case head :: tail => + _tasksLocal set tail + try { + head.run() + } catch { + case t: Throwable => + // if one task throws, move the + // remaining tasks to another thread + // so we can throw the exception + // up to the invoking executor + val remaining = _tasksLocal.get + _tasksLocal set Nil + unbatchedExecute(new Batch(remaining)) //TODO what if this submission fails? + throw t // rethrow + } + processBatch(_tasksLocal.get) // since head.run() can add entries, always do _tasksLocal.get here + } + + processBatch(initial) + } finally { + _tasksLocal.remove() + parentBlockContext = null + } + } + } + + override def blockOn[T](thunk: => T)(implicit permission: CanAwait): T = { + // if we know there will be blocking, we don't want to keep tasks queued up because it could deadlock. + { + val tasks = _tasksLocal.get + _tasksLocal set Nil + if ((tasks ne null) && tasks.nonEmpty) + unbatchedExecute(new Batch(tasks)) + } + + // now delegate the blocking to the previous BC + require(parentBlockContext ne null) + parentBlockContext.blockOn(thunk) + } + } + + protected def unbatchedExecute(r: Runnable): Unit + + override def execute(runnable: Runnable): Unit = { + if (batchable(runnable)) { // If we can batch the runnable + _tasksLocal.get match { + case null => unbatchedExecute(new Batch(List(runnable))) // If we aren't in batching mode yet, enqueue batch + case some => _tasksLocal.set(runnable :: some) // If we are already in batching mode, add to batch + } + } else unbatchedExecute(runnable) // If not batchable, just delegate to underlying + } + + /** Override this to define which runnables will be batched. */ + def batchable(runnable: Runnable): Boolean = runnable match { + case _: OnCompleteRunnable => true + case _ => false + } +} diff --git a/src/library/scala/concurrent/Future.scala b/src/library/scala/concurrent/Future.scala index 4b9e74708d..36f3be341f 100644 --- a/src/library/scala/concurrent/Future.scala +++ b/src/library/scala/concurrent/Future.scala @@ -675,9 +675,9 @@ object Future { // by just not ever using it itself. scala.concurrent // doesn't need to create defaultExecutionContext as // a side effect. - private[concurrent] object InternalCallbackExecutor extends ExecutionContext { - override def execute(runnable: Runnable): Unit = - runnable.run() + private[concurrent] object InternalCallbackExecutor extends ExecutionContext with BatchingExecutor { + override protected def unbatchedExecute(r: Runnable): Unit = + r.run() override def reportFailure(t: Throwable): Unit = throw new IllegalStateException("problem in scala.concurrent internal callback", t) } diff --git a/src/library/scala/concurrent/JavaConversions.scala b/src/library/scala/concurrent/JavaConversions.scala index 573882ee34..3d0597ca22 100644 --- a/src/library/scala/concurrent/JavaConversions.scala +++ b/src/library/scala/concurrent/JavaConversions.scala @@ -18,34 +18,6 @@ import scala.language.implicitConversions */ object JavaConversions { - @deprecated("Use `asExecutionContext` instead.", "2.10.0") - implicit def asTaskRunner(exec: ExecutorService): FutureTaskRunner = - new ThreadPoolRunner { - override protected def executor = - exec - - def shutdown() = - exec.shutdown() - } - - @deprecated("Use `asExecutionContext` instead.", "2.10.0") - implicit def asTaskRunner(exec: Executor): TaskRunner = - new TaskRunner { - type Task[T] = Runnable - - implicit def functionAsTask[T](fun: () => T): Task[T] = new Runnable { - def run() { fun() } - } - - def execute[S](task: Task[S]) { - exec.execute(task) - } - - def shutdown() { - // do nothing - } - } - /** * Creates a new `ExecutionContext` which uses the provided `ExecutorService`. */ diff --git a/src/library/scala/concurrent/TaskRunners.scala b/src/library/scala/concurrent/TaskRunners.scala deleted file mode 100644 index e109a8abf9..0000000000 --- a/src/library/scala/concurrent/TaskRunners.scala +++ /dev/null @@ -1,36 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ Scala API ** -** / __/ __// _ | / / / _ | (c) 2003-2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** -** /____/\___/_/ |_/____/_/ | | ** -** |/ ** -\* */ - -package scala.concurrent - -import java.util.concurrent.{ThreadPoolExecutor, LinkedBlockingQueue, TimeUnit} - -/** The `TaskRunners` object... - * - * @author Philipp Haller - */ -@deprecated("Use `ExecutionContext` instead.", "2.10.0") -object TaskRunners { - - implicit val threadRunner: FutureTaskRunner = - new ThreadRunner - - implicit val threadPoolRunner: FutureTaskRunner = { - val numCores = Runtime.getRuntime().availableProcessors() - val keepAliveTime = 60000L - val workQueue = new LinkedBlockingQueue[Runnable] - val exec = new ThreadPoolExecutor(numCores, - numCores, - keepAliveTime, - TimeUnit.MILLISECONDS, - workQueue, - new ThreadPoolExecutor.CallerRunsPolicy) - JavaConversions.asTaskRunner(exec) - } - -} diff --git a/src/library/scala/concurrent/ThreadRunner.scala b/src/library/scala/concurrent/ThreadRunner.scala deleted file mode 100644 index cd92db9486..0000000000 --- a/src/library/scala/concurrent/ThreadRunner.scala +++ /dev/null @@ -1,60 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ Scala API ** -** / __/ __// _ | / / / _ | (c) 2003-2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** -** /____/\___/_/ |_/____/_/ | | ** -** |/ ** -\* */ - -package scala.concurrent - -import java.lang.Thread -import scala.language.implicitConversions - -/** The `ThreadRunner` trait... - * - * @author Philipp Haller - */ -@deprecated("Use `ExecutionContext` instead.", "2.10.0") -class ThreadRunner extends FutureTaskRunner { - - type Task[T] = () => T - type Future[T] = () => T - - implicit def functionAsTask[S](fun: () => S): Task[S] = fun - implicit def futureAsFunction[S](x: Future[S]): () => S = x - - /* If expression computed successfully return it in `Right`, - * otherwise return exception in `Left`. - */ - private def tryCatch[A](body: => A): Either[Exception, A] = - try Right(body) catch { - case ex: Exception => Left(ex) - } - - def execute[S](task: Task[S]) { - val runnable = new Runnable { - def run() { tryCatch(task()) } - } - (new Thread(runnable)).start() - } - - def submit[S](task: Task[S]): Future[S] = { - val result = new SyncVar[Either[Exception, S]] - val runnable = new Runnable { - def run() { result set tryCatch(task()) } - } - (new Thread(runnable)).start() - () => result.get.fold[S](throw _, identity _) - } - - @deprecated("Use `blocking` instead.", "2.10.0") - def managedBlock(blocker: ManagedBlocker) { - blocker.block() - } - - def shutdown() { - // do nothing - } - -} diff --git a/src/library/scala/concurrent/ops.scala b/src/library/scala/concurrent/ops.scala deleted file mode 100644 index 4c91e78dc7..0000000000 --- a/src/library/scala/concurrent/ops.scala +++ /dev/null @@ -1,73 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ Scala API ** -** / __/ __// _ | / / / _ | (c) 2003-2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** -** /____/\___/_/ |_/____/_/ | | ** -** |/ ** -\* */ - -package scala.concurrent - -import java.lang.Thread -import scala.util.control.Exception.allCatch - -/** The object `ops` ... - * - * @author Martin Odersky, Stepan Koltsov, Philipp Haller - */ -@deprecated("Use `Future` instead.", "2.10.0") -object ops -{ - val defaultRunner: FutureTaskRunner = TaskRunners.threadRunner - - /** - * If expression computed successfully return it in `Right`, - * otherwise return exception in `Left`. - */ - private def tryCatch[A](body: => A): Either[Throwable, A] = - allCatch[A] either body - - private def getOrThrow[T <: Throwable, A](x: Either[T, A]): A = - x.fold[A](throw _, identity _) - - /** Evaluates an expression asynchronously. - * - * @param p the expression to evaluate - */ - def spawn(p: => Unit)(implicit runner: TaskRunner = defaultRunner): Unit = { - runner execute runner.functionAsTask(() => p) - } - - /** 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)) - } - - /** 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)(implicit runner: TaskRunner = defaultRunner): (A, B) = { - val y = new SyncVar[Either[Throwable, B]] - spawn { y set tryCatch(yp) } - (xp, getOrThrow(y.get)) - } - -/* - def parMap[a,b](f: a => b, xs: Array[a]): Array[b] = { - val results = new Array[b](xs.length); - replicate(0, xs.length) { i => results(i) = f(xs(i)) } - results - } -*/ - -} diff --git a/src/library/scala/io/BytePickle.scala b/src/library/scala/io/BytePickle.scala deleted file mode 100644 index 2c4a0bd2da..0000000000 --- a/src/library/scala/io/BytePickle.scala +++ /dev/null @@ -1,318 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ Scala API ** -** / __/ __// _ | / / / _ | (c) 2003-2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** -** /____/\___/_/ |_/____/_/ | | ** -** |/ ** -\* */ - -package scala.io - -import scala.collection.mutable - -/** - * Pickler combinators. - * Based on a Haskell library by Andrew Kennedy, - * see <a href="http://research.microsoft.com/~akenn/fun/" - * target="_top">http://research.microsoft.com/~akenn/fun/</a>. - * - * @author Philipp Haller - * @version 1.1 - */ -@deprecated("This class will be removed.", "2.10.0") -object BytePickle { - abstract class SPU[T] { - def appP(a: T, state: PicklerState): PicklerState - def appU(state: UnPicklerState): (T, UnPicklerState) - } - - def pickle[T](p: SPU[T], a: T): Array[Byte] = - p.appP(a, new PicklerState(new Array[Byte](0), new PicklerEnv)).stream - - def unpickle[T](p: SPU[T], stream: Array[Byte]): T = - p.appU(new UnPicklerState(stream, new UnPicklerEnv))._1 - - abstract class PU[T] { - def appP(a: T, state: Array[Byte]): Array[Byte] - def appU(state: Array[Byte]): (T, Array[Byte]) - } - - def upickle[T](p: PU[T], a: T): Array[Byte] = - p.appP(a, new Array[Byte](0)) - - def uunpickle[T](p: PU[T], stream: Array[Byte]): T = - p.appU(stream)._1 - - class PicklerEnv extends mutable.HashMap[Any, Int] { - private var cnt: Int = 64 - def nextLoc() = { cnt += 1; cnt } - } - - class UnPicklerEnv extends mutable.HashMap[Int, Any] { - private var cnt: Int = 64 - def nextLoc() = { cnt += 1; cnt } - } - - class PicklerState(val stream: Array[Byte], val dict: PicklerEnv) - class UnPicklerState(val stream: Array[Byte], val dict: UnPicklerEnv) - - abstract class RefDef - case class Ref() extends RefDef - case class Def() extends RefDef - - def refDef: PU[RefDef] = new PU[RefDef] { - def appP(b: RefDef, s: Array[Byte]): Array[Byte] = - b match { - case Ref() => Array.concat(s, Array[Byte](0)) - case Def() => Array.concat(s, Array[Byte](1)) - }; - def appU(s: Array[Byte]): (RefDef, Array[Byte]) = - if (s(0) == (0: Byte)) (Ref(), s.slice(1, s.length)) - else (Def(), s.slice(1, s.length)); - } - - val REF = 0 - val DEF = 1 - - def unat: PU[Int] = new PU[Int] { - def appP(n: Int, s: Array[Byte]): Array[Byte] = - Array.concat(s, nat2Bytes(n)); - def appU(s: Array[Byte]): (Int, Array[Byte]) = { - var num = 0 - def readNat: Int = { - var b = 0; - var x = 0; - do { - b = s(num) - num += 1 - x = (x << 7) + (b & 0x7f); - } while ((b & 0x80) != 0); - x - } - (readNat, s.slice(num, s.length)) - } - } - - def share[a](pa: SPU[a]): SPU[a] = new SPU[a] { - def appP(v: a, state: PicklerState): PicklerState = { - /* - - is there some value equal to v associated with a location l in the pickle environment? - - yes: write REF-tag to outstream together with l - - no: - write DEF-tag to outstream - record current location l of outstream - --> serialize value - add entry to pickle environment, mapping v onto l - */ - val pe = state.dict - pe.get(v) match { - case None => - val sPrime = refDef.appP(Def(), state.stream) - val l = pe.nextLoc() - - val sPrimePrime = pa.appP(v, new PicklerState(sPrime, pe)) - - pe.update(v, l) - - return sPrimePrime - case Some(l) => - val sPrime = refDef.appP(Ref(), state.stream) - - return new PicklerState(unat.appP(l, sPrime), pe) - } - } - def appU(state: UnPicklerState): (a, UnPicklerState) = { - /* - - first, read tag (i.e. DEF or REF) - - if REF: - read location l - look up resulting value in unpickler environment - - if DEF: - record location l of input stream - --> deserialize value v with argument deserializer - add entry to unpickler environment, mapping l onto v - */ - val upe = state.dict - val res = refDef.appU(state.stream) - res._1 match { - case Def() => - val l = upe.nextLoc - val res2 = pa.appU(new UnPicklerState(res._2, upe)) - upe.update(l, res2._1) - return res2 - case Ref() => - val res2 = unat.appU(res._2) // read location - upe.get(res2._1) match { // lookup value in unpickler env - case None => throw new IllegalArgumentException("invalid unpickler environment") - case Some(v) => return (v.asInstanceOf[a], new UnPicklerState(res2._2, upe)) - } - } - } - } - - def ulift[t](x: t): PU[t] = new PU[t] { - def appP(a: t, state: Array[Byte]): Array[Byte] = - if (x != a) throw new IllegalArgumentException("value to be pickled (" + a + ") != " + x) - else state; - def appU(state: Array[Byte]) = (x, state) - } - - def lift[t](x: t): SPU[t] = new SPU[t] { - def appP(a: t, state: PicklerState): PicklerState = - if (x != a) { /*throw new IllegalArgumentException("value to be pickled (" + a + ") != " + x);*/ state } - else state; - def appU(state: UnPicklerState) = (x, state) - } - - def usequ[t,u](f: u => t, pa: PU[t], k: t => PU[u]): PU[u] = new PU[u] { - def appP(b: u, s: Array[Byte]): Array[Byte] = { - val a = f(b) - val sPrime = pa.appP(a, s) - val pb = k(a) - val sPrimePrime = pb.appP(b, sPrime) - sPrimePrime - } - def appU(s: Array[Byte]): (u, Array[Byte]) = { - val resPa = pa.appU(s) - val a = resPa._1 - val sPrime = resPa._2 - val pb = k(a) - pb.appU(sPrime) - } - } - - def sequ[t,u](f: u => t, pa: SPU[t], k: t => SPU[u]): SPU[u] = new SPU[u] { - def appP(b: u, s: PicklerState): PicklerState = { - val a = f(b) - val sPrime = pa.appP(a, s) - val pb = k(a) - pb.appP(b, sPrime) - } - def appU(s: UnPicklerState): (u, UnPicklerState) = { - val resPa = pa.appU(s) - val a = resPa._1 - val sPrime = resPa._2 - val pb = k(a) - pb.appU(sPrime) - } - } - - def upair[a,b](pa: PU[a], pb: PU[b]): PU[(a,b)] = { - def fst(p: (a,b)): a = p._1 - def snd(p: (a,b)): b = p._2 - usequ(fst, pa, (x: a) => usequ(snd, pb, (y: b) => ulift((x, y)))) - } - - def pair[a,b](pa: SPU[a], pb: SPU[b]): SPU[(a,b)] = { - def fst(p: (a,b)): a = p._1 - def snd(p: (a,b)): b = p._2 - sequ(fst, pa, (x: a) => sequ(snd, pb, (y: b) => lift((x, y)))) - } - - def triple[a,b,c](pa: SPU[a], pb: SPU[b], pc: SPU[c]): SPU[(a,b,c)] = { - def fst(p: (a,b,c)): a = p._1 - def snd(p: (a,b,c)): b = p._2 - def trd(p: (a,b,c)): c = p._3 - - sequ(fst, pa, - (x: a) => sequ(snd, pb, - (y: b) => sequ(trd, pc, - (z: c) => lift((x, y, z))))) - } - - def uwrap[a,b](i: a => b, j: b => a, pa: PU[a]): PU[b] = - usequ(j, pa, (x: a) => ulift(i(x))) - - def wrap[a,b](i: a => b, j: b => a, pa: SPU[a]): SPU[b] = - sequ(j, pa, (x: a) => lift(i(x))) - - def appendByte(a: Array[Byte], b: Int): Array[Byte] = - Array.concat(a, Array(b.toByte)) - - def nat2Bytes(x: Int): Array[Byte] = { - val buf = new mutable.ArrayBuffer[Byte] - def writeNatPrefix(x: Int) { - val y = x >>> 7; - if (y != 0) writeNatPrefix(y); - buf += ((x & 0x7f) | 0x80).asInstanceOf[Byte]; - } - val y = x >>> 7; - if (y != 0) writeNatPrefix(y); - buf += (x & 0x7f).asInstanceOf[Byte]; - buf.toArray - } - - def nat: SPU[Int] = new SPU[Int] { - def appP(n: Int, s: PicklerState): PicklerState = { - new PicklerState(Array.concat(s.stream, nat2Bytes(n)), s.dict); - } - def appU(s: UnPicklerState): (Int,UnPicklerState) = { - var num = 0 - def readNat: Int = { - var b = 0 - var x = 0 - do { - b = s.stream(num) - num += 1 - x = (x << 7) + (b & 0x7f); - } while ((b & 0x80) != 0); - x - } - (readNat, new UnPicklerState(s.stream.slice(num, s.stream.length), s.dict)) - } - } - - def byte: SPU[Byte] = new SPU[Byte] { - def appP(b: Byte, s: PicklerState): PicklerState = - new PicklerState(Array.concat(s.stream, Array(b)), s.dict) - def appU(s: UnPicklerState): (Byte, UnPicklerState) = - (s.stream(0), new UnPicklerState(s.stream.slice(1, s.stream.length), s.dict)); - } - - def string: SPU[String] = share(wrap( - (a: Array[Byte]) => (Codec fromUTF8 a).mkString, - (s: String) => Codec toUTF8 s, - bytearray - )) - - def bytearray: SPU[Array[Byte]] = { - wrap((l:List[Byte]) => l.toArray, (_.toList), list(byte)) - } - - def bool: SPU[Boolean] = { - def toEnum(b: Boolean) = if (b) 1 else 0 - def fromEnum(n: Int) = if (n == 0) false else true - wrap(fromEnum, toEnum, nat) - } - - def ufixedList[A](pa: PU[A])(n: Int): PU[List[A]] = { - def pairToList(p: (A, List[A])): List[A] = - p._1 :: p._2; - def listToPair(l: List[A]): (A, List[A]) = - (l: @unchecked) match { case x :: xs => (x, xs) } - - if (n == 0) ulift(Nil) - else - uwrap(pairToList, listToPair, upair(pa, ufixedList(pa)(n-1))) - } - - def fixedList[a](pa: SPU[a])(n: Int): SPU[List[a]] = { - def pairToList(p: (a,List[a])): List[a] = - p._1 :: p._2; - def listToPair(l: List[a]): (a,List[a]) = - (l: @unchecked) match { case x :: xs => (x, xs) } - - if (n == 0) lift(Nil) - else - wrap(pairToList, listToPair, pair(pa, fixedList(pa)(n-1))) - } - - def list[a](pa: SPU[a]): SPU[List[a]] = - sequ((l: List[a])=>l.length, nat, fixedList(pa)); - - def ulist[a](pa: PU[a]): PU[List[a]] = - usequ((l:List[a]) => l.length, unat, ufixedList(pa)); - - def data[a](tag: a => Int, ps: List[()=>SPU[a]]): SPU[a] = - sequ(tag, nat, (x: Int)=> ps.apply(x)()); -} diff --git a/src/library/scala/io/UTF8Codec.scala b/src/library/scala/io/UTF8Codec.scala deleted file mode 100644 index e4c2145153..0000000000 --- a/src/library/scala/io/UTF8Codec.scala +++ /dev/null @@ -1,32 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ Scala API ** -** / __/ __// _ | / / / _ | (c) 2003-2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** -** /____/\___/_/ |_/____/_/ | | ** -** |/ ** -\* */ - - -package scala.io - -/** - * @author Martin Odersky - * @version 1.0, 04/10/2004 - */ -@deprecated("This class will be removed.", "2.10.0") -object UTF8Codec { - final val UNI_REPLACEMENT_CHAR: Int = 0x0000FFFD - final val UNI_REPLACEMENT_BYTES = Array[Byte](-17, -65, -67) - - // Note, from http://unicode.org/faq/utf_bom.html#utf8-5 - // - // A different issue arises if an unpaired surrogate is encountered when converting - // ill-formed UTF-16 data. By represented such an unpaired surrogate on its own as a - // 3-byte sequence, the resulting UTF-8 data stream would become ill-formed. - // While it faithfully reflects the nature of the input, Unicode conformance - // requires that encoding form conversion always results in valid data stream. - // Therefore a converter must treat this as an error. - // - // Some useful locations: - // http://www.cl.cam.ac.uk/~mgk25/ucs/examples/UTF-8-test.txt -} diff --git a/src/library/scala/math/BigInt.scala b/src/library/scala/math/BigInt.scala index 0cddd71721..8f86fd5aa7 100644 --- a/src/library/scala/math/BigInt.scala +++ b/src/library/scala/math/BigInt.scala @@ -289,9 +289,6 @@ class BigInt(val bigInteger: BigInteger) extends ScalaNumber with ScalaNumericCo */ def signum: Int = this.bigInteger.signum() - @deprecated("Use ~bigInt (the unary_~ method) instead", "2.10.0") - def ~ : BigInt = ~this - /** Returns the bitwise complement of this BigInt */ def unary_~ : BigInt = new BigInt(this.bigInteger.not()) @@ -358,7 +355,7 @@ class BigInt(val bigInteger: BigInteger) extends ScalaNumber with ScalaNumericCo def charValue = intValue.toChar /** Converts this BigInt to an <tt>int</tt>. - * If the BigInt is too big to fit in a int, only the low-order 32 bits + * If the BigInt is too big to fit in an int, only the low-order 32 bits * are returned. Note that this conversion can lose information about the * overall magnitude of the BigInt value as well as return a result with * the opposite sign. diff --git a/src/library/scala/math/Ordering.scala b/src/library/scala/math/Ordering.scala index e9b92541c2..aea512a541 100644 --- a/src/library/scala/math/Ordering.scala +++ b/src/library/scala/math/Ordering.scala @@ -33,7 +33,7 @@ import scala.language.{implicitConversions, higherKinds} * }}} * * An Ordering[T] is implemented by specifying compare(a:T, b:T), which - * decides how to order to instances a and b. Instances of Ordering[T] can be + * decides how to order two instances a and b. Instances of Ordering[T] can be * used by things like scala.util.Sorting to sort collections like Array[T]. * * For example: diff --git a/src/library/scala/package.scala b/src/library/scala/package.scala index 15d6dce8a7..224112c11c 100644 --- a/src/library/scala/package.scala +++ b/src/library/scala/package.scala @@ -34,9 +34,6 @@ package object scala { override def toString = "object AnyRef" } - @deprecated("instead of `@cloneable class C`, use `class C extends Cloneable`", "2.10.0") - type cloneable = annotation.cloneable - type TraversableOnce[+A] = scala.collection.TraversableOnce[A] type Traversable[+A] = scala.collection.Traversable[A] @@ -121,7 +118,6 @@ package object scala { // Annotations which we might move to annotation.* /* type SerialVersionUID = annotation.SerialVersionUID - type cloneable = annotation.cloneable type deprecated = annotation.deprecated type deprecatedName = annotation.deprecatedName type inline = annotation.inline diff --git a/src/library/scala/parallel/Future.scala b/src/library/scala/parallel/Future.scala deleted file mode 100644 index e255a5772b..0000000000 --- a/src/library/scala/parallel/Future.scala +++ /dev/null @@ -1,39 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ Scala API ** -** / __/ __// _ | / / / _ | (c) 2005-2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** -** /____/\___/_/ |_/____/_/ | | ** -** |/ ** -\* */ - -package scala.parallel - - - -/** A future is a function without parameters that will block the caller if - * the parallel computation associated with the function is not completed. - * - * @tparam R the type of the result - * - * @since 2.9 - */ -@deprecated("Use `scala.concurrent.Future` instead.", "2.10.0") -trait Future[@specialized +R] extends (() => R) { - /** Returns a result once the parallel computation completes. If the - * computation produced an exception, an exception is forwarded. - * - * '''Note:''' creating a circular dependency between futures by calling - * this method will result in a deadlock. - * - * @return the result - * @throws the exception that was thrown during a parallel computation - */ - def apply(): R - - /** Returns `true` if the parallel computation is completed. - * - * @return `true` if the parallel computation is completed, `false` otherwise - */ - def isDone(): Boolean -} - diff --git a/src/library/scala/sys/process/ProcessBuilder.scala b/src/library/scala/sys/process/ProcessBuilder.scala index d0b2ecfe73..30fd4d83ff 100644 --- a/src/library/scala/sys/process/ProcessBuilder.scala +++ b/src/library/scala/sys/process/ProcessBuilder.scala @@ -23,7 +23,7 @@ import ProcessBuilder._ * based on these factories made available in the package object * [[scala.sys.process]]. Here are some examples: * {{{ - * import.scala.sys.process._ + * import scala.sys.process._ * * // Executes "ls" and sends output to stdout * "ls".! diff --git a/src/library/scala/testing/Benchmark.scala b/src/library/scala/testing/Benchmark.scala deleted file mode 100644 index 66d7d448eb..0000000000 --- a/src/library/scala/testing/Benchmark.scala +++ /dev/null @@ -1,114 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ Scala API ** -** / __/ __// _ | / / / _ | (c) 2003-2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** -** /____/\___/_/ |_/____/_/ | | ** -** |/ ** -\* */ - -package scala.testing - -import scala.compat.Platform - -/** `Benchmark` can be used to quickly turn an existing class into a - * benchmark. Here is a short example: - * {{{ - * object sort1 extends Sorter with Benchmark { - * def run = sort(List.range(1, 1000)) - * } - * }}} - * The `run` method has to be defined by the user, who will perform the - * timed operation there. Run the benchmark as follows: - * {{{ - * > scala sort1 5 - * }}} - * This will run the benchmark 5 times, forcing a garbage collection - * between runs, and printing the execution times to stdout. - * - * It is also possible to add a multiplier, so - * {{{ - * > scala sort1 5 10 - * }}} - * will run the entire benchmark 10 times, each time for 5 runs. - * - * @author Iulian Dragos, Burak Emir - */ -@deprecated("This class will be removed.", "2.10.0") -trait Benchmark { - - /** this method should be implemented by the concrete benchmark. - * This method is called by the benchmarking code for a number of times. - * The GC is called between "multiplier" calls to run, right after tear - * down. - * - * @see setUp - * @see tearDown - */ - def run() - - var multiplier = 1 - - /** Run the benchmark the specified number of times and return a list with - * the execution times in milliseconds in reverse order of the execution. - */ - def runBenchmark(noTimes: Int): List[Long] = - for (i <- List.range(1, noTimes + 1)) yield { - setUp - val startTime = Platform.currentTime - var i = 0; while (i < multiplier) { - run() - i += 1 - } - val stopTime = Platform.currentTime - tearDown - Platform.collectGarbage - - stopTime - startTime - } - - /** Prepare any data needed by the benchmark, but whose execution time - * should not be measured. This method is run before each call to the - * benchmark payload, 'run'. - */ - def setUp() {} - - /** Perform cleanup operations after each 'run'. For micro benchmarks, - * think about using the result of 'run' in a way that prevents the JVM - * to dead-code eliminate the whole 'run' method. For instance, print or - * write the results to a file. The execution time of this method is not - * measured. - */ - def tearDown() {} - - /** a string that is written at the beginning of the output line - * that contains the timings. By default, this is the class name. - */ - def prefix: String = getClass().getName() - - /** - * The entry point. It takes two arguments: - * - argument `n` is the number of consecutive runs - * - optional argument `mult` specifies that the `n` runs are repeated - * `mult` times. - */ - def main(args: Array[String]) { - if (args.length > 0) { - val logFile = new java.io.OutputStreamWriter(System.out) - if (args.length > 1) multiplier = args(1).toInt - logFile.write(prefix) - for (t <- runBenchmark(args(0).toInt)) - logFile.write("\t" + t) - - logFile.write(Platform.EOL) - logFile.flush() - } else { - println("Usage: scala benchmarks.program <runs> ") - println(" or: scala benchmarks.program <runs> <multiplier>") - println(""" - The benchmark is run <runs> times, forcing a garbage collection between runs. The optional - <multiplier> causes the benchmark to be repeated <multiplier> times, each time for <runs> - executions. - """) - } - } -} diff --git a/src/library/scala/testing/Show.scala b/src/library/scala/testing/Show.scala deleted file mode 100644 index 9376e26db4..0000000000 --- a/src/library/scala/testing/Show.scala +++ /dev/null @@ -1,75 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ Scala API ** -** / __/ __// _ | / / / _ | (c) 2003-2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** -** /____/\___/_/ |_/____/_/ | | ** -** |/ ** -\* */ - - - -package scala.testing - -/** Classes inheriting trait `Show` can test their member methods using the - * notation `meth(arg,,1,,, ..., arg,,n,,)`, where `meth` is the name of - * the method and `arg,,1,,,...,arg,,n,,` are the arguments. - * - * The only difference to a normal method call is the leading quote - * character (`'`). A quoted method call like the one above will produces - * a legible diagnostic to be printed on [[scala.Console]]. - * - * It is of the form - * - * `meth(arg,,1,,, ..., arg,,n,,)` gives `<result>` - * - * where `<result>` is the result of evaluating the call. - * - */ -@deprecated("This class will be removed.", "2.10.0") -trait Show { - - /** An implicit definition that adds an apply method to Symbol which forwards to `test`. - * Prints out diagnostics of method applications. - */ - implicit class SymApply(f: Symbol) { - def apply[A](args: A*) { - println(test(f, args: _*)) - } - } - - @deprecated("use SymApply instead", "2.10.0") - def symApply(sym: Symbol): SymApply = new SymApply(sym) - - /** Apply method with name of given symbol `f` to given arguments and return - * a result diagnostics. - */ - def test[A](f: Symbol, args: A*): String = { - val args1 = args map (_.asInstanceOf[AnyRef]) - def testMethod(meth: java.lang.reflect.Method): String = - f.name+"("+(args mkString ",")+") gives "+ - { - try { - meth.invoke(this, args1: _*) - } catch { - case ex: IllegalAccessException => ex - case ex: IllegalArgumentException => ex - case ex: java.lang.reflect.InvocationTargetException => ex - } - } - getClass.getMethods.toList filter (_.getName == f.name) match { - case List() => - f.name+" is not defined" - case List(m) => - testMethod(m) - case ms => // multiple methods, disambiguate by number of arguments - ms filter (_.getParameterTypes.length == args.length) match { - case List() => - testMethod(ms.head) // go ahead anyway, to get an exception - case List(m) => - testMethod(m) - case ms => - "cannot disambiguate between multiple implementations of "+f.name - } - } - } -} diff --git a/src/library/scala/throws.scala b/src/library/scala/throws.scala index 159f1f02f4..5a5dd9a1f5 100644 --- a/src/library/scala/throws.scala +++ b/src/library/scala/throws.scala @@ -24,5 +24,5 @@ package scala * @since 2.1 */ class throws[T <: Throwable](cause: String = "") extends scala.annotation.StaticAnnotation { - def this(clazz: Class[T]) = this() + def this(clazz: Class[T]) = this("") } diff --git a/src/library/scala/util/Either.scala b/src/library/scala/util/Either.scala index dba11ed73c..864d8953c4 100644 --- a/src/library/scala/util/Either.scala +++ b/src/library/scala/util/Either.scala @@ -221,8 +221,6 @@ object Either { case Right(a) => a } } - @deprecated("use MergeableEither instead", "2.10.0") - def either2mergeable[A](x: Either[A, A]): MergeableEither[A] = new MergeableEither(x) /** * Projects an `Either` into a `Left`. diff --git a/src/library/scala/util/Marshal.scala b/src/library/scala/util/Marshal.scala deleted file mode 100644 index b78ed2140e..0000000000 --- a/src/library/scala/util/Marshal.scala +++ /dev/null @@ -1,50 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ Scala API ** -** / __/ __// _ | / / / _ | (c) 2008-2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** -** /____/\___/_/ |_/____/_/ | | ** -** |/ ** -\* */ - - - -package scala.util - -/** - * Marshalling of Scala objects using Scala tags. - * - * @author Stephane Micheloud - * @version 1.0 - */ -@deprecated("This class will be removed", "2.10.0") -object Marshal { - import java.io._ - import scala.reflect.ClassTag - - def dump[A](o: A)(implicit t: ClassTag[A]): Array[Byte] = { - val ba = new ByteArrayOutputStream(512) - val out = new ObjectOutputStream(ba) - out.writeObject(t) - out.writeObject(o) - out.close() - ba.toByteArray() - } - - @throws(classOf[IOException]) - @throws(classOf[ClassCastException]) - @throws(classOf[ClassNotFoundException]) - def load[A](buffer: Array[Byte])(implicit expected: ClassTag[A]): A = { - val in = new ObjectInputStream(new ByteArrayInputStream(buffer)) - val found = in.readObject.asInstanceOf[ClassTag[_]] - try { - found.runtimeClass.asSubclass(expected.runtimeClass) - in.readObject.asInstanceOf[A] - } catch { - case _: ClassCastException => - in.close() - throw new ClassCastException("type mismatch;"+ - "\n found : "+found+ - "\n required: "+expected) - } - } -} diff --git a/src/library/scala/util/grammar/HedgeRHS.scala b/src/library/scala/util/grammar/HedgeRHS.scala deleted file mode 100644 index d1c11a2f99..0000000000 --- a/src/library/scala/util/grammar/HedgeRHS.scala +++ /dev/null @@ -1,26 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ Scala API ** -** / __/ __// _ | / / / _ | (c) 2003-2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** -** /____/\___/_/ |_/____/_/ | | ** -** |/ ** -\* */ - - - -package scala.util.grammar - -@deprecated("This class will be removed", "2.10.0") -abstract class HedgeRHS - -/** Right hand side of a hedge production, deriving a single tree. */ -@deprecated("This class will be removed", "2.10.0") -case class ConsRHS(tnt: Int, hnt: Int) extends HedgeRHS - -/** Right hand side of a hedge production, deriving any hedge. */ -@deprecated("This class will be removed", "2.10.0") -case object AnyHedgeRHS extends HedgeRHS - -/** Right hand side of a hedge production, deriving the empty hedge. */ -@deprecated("This class will be removed", "2.10.0") -case object EmptyHedgeRHS extends HedgeRHS diff --git a/src/library/scala/util/grammar/TreeRHS.scala b/src/library/scala/util/grammar/TreeRHS.scala deleted file mode 100644 index ee72ea982d..0000000000 --- a/src/library/scala/util/grammar/TreeRHS.scala +++ /dev/null @@ -1,22 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ Scala API ** -** / __/ __// _ | / / / _ | (c) 2003-2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** -** /____/\___/_/ |_/____/_/ | | ** -** |/ ** -\* */ - - - -package scala.util.grammar - -/** Right hand side of a tree production. */ -@deprecated("This class will be removed", "2.10.0") -abstract class TreeRHS - -/** Right hand side of a tree production, labelled with a letter from an alphabet. */ -@deprecated("This class will be removed", "2.10.0") -case class LabelledRHS[A](label: A, hnt: Int) extends TreeRHS - -@deprecated("This class will be removed", "2.10.0") -case object AnyTreeRHS extends TreeRHS diff --git a/src/library/scala/util/matching/Regex.scala b/src/library/scala/util/matching/Regex.scala index 830710432c..7af75173d3 100644 --- a/src/library/scala/util/matching/Regex.scala +++ b/src/library/scala/util/matching/Regex.scala @@ -204,16 +204,6 @@ class Regex private[matching](val pattern: Pattern, groupNames: String*) extends else if (m.matcher.pattern == this.pattern) Some(1 to m.groupCount map m.group) else unapplySeq(m.matched) - @deprecated("Extracting a match result from anything but a CharSequence or Match is deprecated", "2.10.0") - def unapplySeq(target: Any): Option[List[String]] = target match { - case s: CharSequence => - val m = pattern matcher s - if (runMatcher(m)) Some((1 to m.groupCount).toList map m.group) - else None - case m: Match => unapplySeq(m.matched) - case _ => None - } - // @see UnanchoredRegex protected def runMatcher(m: Matcher) = m.matches() diff --git a/src/library/scala/xml/NamespaceBinding.scala b/src/library/scala/xml/NamespaceBinding.scala index c7cd9e6b6c..3a63d47d4e 100644 --- a/src/library/scala/xml/NamespaceBinding.scala +++ b/src/library/scala/xml/NamespaceBinding.scala @@ -38,6 +38,22 @@ case class NamespaceBinding(prefix: String, uri: String, parent: NamespaceBindin override def toString(): String = sbToString(buildString(_, TopScope)) + private def shadowRedefined: NamespaceBinding = shadowRedefined(TopScope) + + private def shadowRedefined(stop: NamespaceBinding): NamespaceBinding = { + def prefixList(x: NamespaceBinding): List[String] = + if ((x == null) || (x eq stop)) Nil + else x.prefix :: prefixList(x.parent) + def fromPrefixList(l: List[String]): NamespaceBinding = l match { + case Nil => stop + case x :: xs => new NamespaceBinding(x, this.getURI(x), fromPrefixList(xs)) + } + val ps0 = prefixList(this).reverse + val ps = ps0.distinct + if (ps.size == ps0.size) this + else fromPrefixList(ps) + } + override def canEqual(other: Any) = other match { case _: NamespaceBinding => true case _ => false @@ -53,12 +69,16 @@ case class NamespaceBinding(prefix: String, uri: String, parent: NamespaceBindin def buildString(stop: NamespaceBinding): String = sbToString(buildString(_, stop)) def buildString(sb: StringBuilder, stop: NamespaceBinding) { - if (this eq stop) return // contains? + shadowRedefined(stop).doBuildString(sb, stop) + } + + private def doBuildString(sb: StringBuilder, stop: NamespaceBinding) { + if ((this == null) || (this eq stop)) return // contains? val s = " xmlns%s=\"%s\"".format( (if (prefix != null) ":" + prefix else ""), (if (uri != null) uri else "") ) - parent.buildString(sb append s, stop) // copy(ignore) + parent.doBuildString(sb append s, stop) // copy(ignore) } } diff --git a/src/library/scala/xml/dtd/ContentModel.scala b/src/library/scala/xml/dtd/ContentModel.scala index abc71f55bd..debdf37975 100644 --- a/src/library/scala/xml/dtd/ContentModel.scala +++ b/src/library/scala/xml/dtd/ContentModel.scala @@ -11,8 +11,7 @@ package scala.xml package dtd -import scala.util.regexp.WordExp -import scala.util.automata._ +import scala.xml.dtd.impl._ import scala.xml.Utility.sbToString import PartialFunction._ diff --git a/src/library/scala/xml/dtd/DocType.scala b/src/library/scala/xml/dtd/DocType.scala index ce067bee79..b2510baa18 100644 --- a/src/library/scala/xml/dtd/DocType.scala +++ b/src/library/scala/xml/dtd/DocType.scala @@ -18,8 +18,7 @@ package dtd * @param extID NoExternalID or the external ID of this doctype * @param intSubset sequence of internal subset declarations */ -case class DocType(name: String, extID: ExternalID, intSubset: Seq[dtd.Decl]) -{ +case class DocType(name: String, extID: ExternalID, intSubset: Seq[dtd.Decl]) { if (!Utility.isName(name)) throw new IllegalArgumentException(name+" must be an XML Name") @@ -33,8 +32,7 @@ case class DocType(name: String, extID: ExternalID, intSubset: Seq[dtd.Decl]) } } -object DocType -{ +object DocType { /** Creates a doctype with no external id, nor internal subset declarations. */ def apply(name: String): DocType = apply(name, NoExternalID, Nil) } diff --git a/src/library/scala/xml/dtd/ElementValidator.scala b/src/library/scala/xml/dtd/ElementValidator.scala index 66951bf390..e73e209daa 100644 --- a/src/library/scala/xml/dtd/ElementValidator.scala +++ b/src/library/scala/xml/dtd/ElementValidator.scala @@ -12,10 +12,12 @@ package scala.xml package dtd import PartialFunction._ +import scala.collection.mutable + import ContentModel.ElemName import MakeValidationException._ // @todo other exceptions -import scala.util.automata._ -import scala.collection.mutable + +import impl._ /** validate children and/or attributes of an element * exceptions are created but not thrown. diff --git a/src/library/scala/xml/dtd/ExternalID.scala b/src/library/scala/xml/dtd/ExternalID.scala index e346f89d0a..80ada0caaa 100644 --- a/src/library/scala/xml/dtd/ExternalID.scala +++ b/src/library/scala/xml/dtd/ExternalID.scala @@ -14,8 +14,7 @@ package dtd * * @author Burak Emir */ -abstract class ExternalID extends parsing.TokenTests -{ +abstract class ExternalID extends parsing.TokenTests { def quoted(s: String) = { val c = if (s contains '"') '\'' else '"' c + s + c diff --git a/src/library/scala/util/regexp/Base.scala b/src/library/scala/xml/dtd/impl/Base.scala index 7dbe60a34e..dd277779f6 100644 --- a/src/library/scala/util/regexp/Base.scala +++ b/src/library/scala/xml/dtd/impl/Base.scala @@ -8,7 +8,7 @@ -package scala.util.regexp +package scala.xml.dtd.impl /** Basic regular expressions. * @@ -17,7 +17,7 @@ package scala.util.regexp */ @deprecated("This class will be removed", "2.10.0") -abstract class Base { +private[dtd] abstract class Base { type _regexpT <: RegExp abstract class RegExp { diff --git a/src/library/scala/util/automata/BaseBerrySethi.scala b/src/library/scala/xml/dtd/impl/BaseBerrySethi.scala index 3f6f4507a9..99d5ab62e1 100644 --- a/src/library/scala/util/automata/BaseBerrySethi.scala +++ b/src/library/scala/xml/dtd/impl/BaseBerrySethi.scala @@ -6,9 +6,8 @@ ** |/ ** \* */ -package scala.util.automata +package scala.xml.dtd.impl -import scala.util.regexp.{ Base } import scala.collection.{ mutable, immutable } // todo: replace global variable pos with acc @@ -18,7 +17,7 @@ import scala.collection.{ mutable, immutable } * position automata construction (also called ''Berry-Sethi'' or ''Glushkov''). */ @deprecated("This class will be removed", "2.10.0") -abstract class BaseBerrySethi { +private[dtd] abstract class BaseBerrySethi { val lang: Base import lang.{ Alt, Eps, Meta, RegExp, Sequ, Star } diff --git a/src/library/scala/util/automata/DetWordAutom.scala b/src/library/scala/xml/dtd/impl/DetWordAutom.scala index 5d709106f8..5c1dcb7ff8 100644 --- a/src/library/scala/util/automata/DetWordAutom.scala +++ b/src/library/scala/xml/dtd/impl/DetWordAutom.scala @@ -6,7 +6,7 @@ ** |/ ** \* */ -package scala.util.automata +package scala.xml.dtd.impl import scala.collection.{ mutable, immutable } @@ -21,7 +21,7 @@ import scala.collection.{ mutable, immutable } * @version 1.0 */ @deprecated("This class will be removed", "2.10.0") -abstract class DetWordAutom[T <: AnyRef] { +private[dtd] abstract class DetWordAutom[T <: AnyRef] { val nstates: Int val finals: Array[Int] val delta: Array[mutable.Map[T, Int]] diff --git a/src/library/scala/util/automata/Inclusion.scala b/src/library/scala/xml/dtd/impl/Inclusion.scala index 91441bd3a8..0ae78519ca 100644 --- a/src/library/scala/util/automata/Inclusion.scala +++ b/src/library/scala/xml/dtd/impl/Inclusion.scala @@ -8,7 +8,7 @@ -package scala.util.automata +package scala.xml.dtd.impl /** A fast test of language inclusion between minimal automata. @@ -18,7 +18,7 @@ package scala.util.automata * @version 1.0 */ @deprecated("This class will be removed", "2.10.0") -trait Inclusion[A <: AnyRef] { +private[dtd] trait Inclusion[A <: AnyRef] { val labels: Seq[A] diff --git a/src/library/scala/util/automata/NondetWordAutom.scala b/src/library/scala/xml/dtd/impl/NondetWordAutom.scala index 24c6612d0f..8e0b5a3a4c 100644 --- a/src/library/scala/util/automata/NondetWordAutom.scala +++ b/src/library/scala/xml/dtd/impl/NondetWordAutom.scala @@ -6,7 +6,7 @@ ** |/ ** \* */ -package scala.util.automata +package scala.xml.dtd.impl import scala.collection.{ immutable, mutable } @@ -18,7 +18,7 @@ import scala.collection.{ immutable, mutable } * the partial function `finals` is defined. */ @deprecated("This class will be removed", "2.10.0") -abstract class NondetWordAutom[T <: AnyRef] { +private[dtd] abstract class NondetWordAutom[T <: AnyRef] { val nstates: Int val labels: Seq[T] val finals: Array[Int] // 0 means not final @@ -37,10 +37,10 @@ abstract class NondetWordAutom[T <: AnyRef] { /** @return true if there are no accepting states */ final def isEmpty = (0 until nstates) forall (x => !isFinal(x)) - /** @return a immutable.BitSet with the next states for given state and label */ + /** @return an immutable.BitSet with the next states for given state and label */ def next(q: Int, a: T): immutable.BitSet = delta(q).getOrElse(a, default(q)) - /** @return a immutable.BitSet with the next states for given state and label */ + /** @return an immutable.BitSet with the next states for given state and label */ def next(Q: immutable.BitSet, a: T): immutable.BitSet = next(Q, next(_, a)) def nextDefault(Q: immutable.BitSet): immutable.BitSet = next(Q, default) diff --git a/src/library/scala/util/regexp/PointedHedgeExp.scala b/src/library/scala/xml/dtd/impl/PointedHedgeExp.scala index 5c0379b6f8..0b5297510d 100644 --- a/src/library/scala/util/regexp/PointedHedgeExp.scala +++ b/src/library/scala/xml/dtd/impl/PointedHedgeExp.scala @@ -8,7 +8,7 @@ -package scala.util.regexp +package scala.xml.dtd.impl /** Pointed regular hedge expressions, a useful subclass of regular hedge expressions. * @@ -16,7 +16,7 @@ package scala.util.regexp * @version 1.0 */ @deprecated("This class will be removed", "2.10.0") -abstract class PointedHedgeExp extends Base { +private[dtd] abstract class PointedHedgeExp extends Base { type _regexpT <: RegExp type _labelT diff --git a/src/library/scala/util/automata/SubsetConstruction.scala b/src/library/scala/xml/dtd/impl/SubsetConstruction.scala index 0ee768587c..8e4b5cc0f0 100644 --- a/src/library/scala/util/automata/SubsetConstruction.scala +++ b/src/library/scala/xml/dtd/impl/SubsetConstruction.scala @@ -6,12 +6,12 @@ ** |/ ** \* */ -package scala.util.automata +package scala.xml.dtd.impl import scala.collection.{ mutable, immutable } @deprecated("This class will be removed", "2.10.0") -class SubsetConstruction[T <: AnyRef](val nfa: NondetWordAutom[T]) { +private[dtd] class SubsetConstruction[T <: AnyRef](val nfa: NondetWordAutom[T]) { import nfa.labels def selectTag(Q: immutable.BitSet, finals: Array[Int]) = diff --git a/src/library/scala/util/regexp/SyntaxError.scala b/src/library/scala/xml/dtd/impl/SyntaxError.scala index 1788fdfb84..b0e0b8b6cd 100644 --- a/src/library/scala/util/regexp/SyntaxError.scala +++ b/src/library/scala/xml/dtd/impl/SyntaxError.scala @@ -8,7 +8,7 @@ -package scala.util.regexp +package scala.xml.dtd.impl /** This runtime exception is thrown if an attempt to instantiate a * syntactically incorrect expression is detected. @@ -17,4 +17,4 @@ package scala.util.regexp * @version 1.0 */ @deprecated("This class will be removed", "2.10.0") -class SyntaxError(e: String) extends RuntimeException(e) +private[dtd] class SyntaxError(e: String) extends RuntimeException(e) diff --git a/src/library/scala/util/automata/WordBerrySethi.scala b/src/library/scala/xml/dtd/impl/WordBerrySethi.scala index 2f4625da44..90d7fe760a 100644 --- a/src/library/scala/util/automata/WordBerrySethi.scala +++ b/src/library/scala/xml/dtd/impl/WordBerrySethi.scala @@ -6,10 +6,9 @@ ** |/ ** \* */ -package scala.util.automata +package scala.xml.dtd.impl import scala.collection.{ immutable, mutable } -import scala.util.regexp.WordExp /** This class turns a regular expression into a [[scala.util.automata.NondetWordAutom]] * celebrated position automata construction (also called ''Berry-Sethi'' or ''Glushkov''). @@ -18,7 +17,7 @@ import scala.util.regexp.WordExp * @version 1.0 */ @deprecated("This class will be removed", "2.10.0") -abstract class WordBerrySethi extends BaseBerrySethi { +private[dtd] abstract class WordBerrySethi extends BaseBerrySethi { override val lang: WordExp import lang.{ Alt, Eps, Letter, RegExp, Sequ, Star, _labelT } diff --git a/src/library/scala/util/regexp/WordExp.scala b/src/library/scala/xml/dtd/impl/WordExp.scala index 3c0c2ec156..38f8aea697 100644 --- a/src/library/scala/util/regexp/WordExp.scala +++ b/src/library/scala/xml/dtd/impl/WordExp.scala @@ -8,7 +8,7 @@ -package scala.util.regexp +package scala.xml.dtd.impl /** * The class `WordExp` provides regular word expressions. @@ -39,7 +39,7 @@ package scala.util.regexp * @version 1.0 */ @deprecated("This class will be removed", "2.10.0") -abstract class WordExp extends Base { +private[dtd] abstract class WordExp extends Base { abstract class Label diff --git a/src/library/scala/xml/include/sax/Main.scala b/src/library/scala/xml/include/sax/Main.scala deleted file mode 100644 index 92d4d6ea73..0000000000 --- a/src/library/scala/xml/include/sax/Main.scala +++ /dev/null @@ -1,82 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ Scala API ** -** / __/ __// _ | / / / _ | (c) 2002-2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** -** /____/\___/_/ |_/____/_/ | | ** -** |/ ** -\* */ - - -package scala.xml -package include.sax - -import scala.util.control.Exception.{ catching, ignoring } -import org.xml.sax.XMLReader -import org.xml.sax.helpers.XMLReaderFactory - -@deprecated("Code example will be moved to documentation.", "2.10.0") -object Main { - private val namespacePrefixes = "http://xml.org/sax/features/namespace-prefixes" - private val lexicalHandler = "http://xml.org/sax/properties/lexical-handler" - - /** - * The driver method for xinc - * Output is written to System.out via Conolse - * </p> - * - * @param args contains the URLs and/or filenames - * of the documents to be processed. - */ - def main(args: Array[String]) { - def saxe[T](body: => T) = catching[T](classOf[SAXException]) opt body - def fail(msg: String) = System.err.println(msg) - - val parser: XMLReader = - saxe[XMLReader](XMLReaderFactory.createXMLReader()) getOrElse ( - saxe[XMLReader](XMLReaderFactory.createXMLReader(XercesClassName)) getOrElse ( - return fail("Could not find an XML parser") - ) - ) - - // Need better namespace handling - try parser.setFeature(namespacePrefixes, true) - catch { case e: SAXException => return System.err.println(e) } - - if (args.isEmpty) - return - - def dashR = args.size >= 2 && args(0) == "-r" - val args2 = if (dashR) args drop 2 else args - val resolver: Option[EntityResolver] = - if (dashR) None - else catching(classOf[Exception]) opt { - val r = Class.forName(args(1)).newInstance().asInstanceOf[EntityResolver] - parser setEntityResolver r - r - } orElse (return fail("Could not load requested EntityResolver")) - - for (arg <- args2) { - try { - val includer = new XIncludeFilter() - includer setParent parser - val s = new XIncluder(System.out, "UTF-8") - includer setContentHandler s - - resolver map (includer setEntityResolver _) - // SAXException here means will not support comments - ignoring(classOf[SAXException]) { - includer.setProperty(lexicalHandler, s) - s setFilter includer - } - includer parse arg - } - catch { - case e: SAXParseException => - fail(e.toString) - fail("Problem in %s at line %d".format(e.getSystemId, e.getLineNumber)) - case e: SAXException => - fail(e.toString) - } - } - } -} diff --git a/src/partest/scala/tools/partest/BytecodeTest.scala b/src/partest/scala/tools/partest/BytecodeTest.scala new file mode 100644 index 0000000000..93183c2095 --- /dev/null +++ b/src/partest/scala/tools/partest/BytecodeTest.scala @@ -0,0 +1,61 @@ +package scala.tools.partest + +import scala.tools.nsc.util.JavaClassPath +import scala.collection.JavaConverters._ +import scala.tools.asm +import asm.ClassReader +import asm.tree.{ClassNode, MethodNode, InsnList} +import java.io.InputStream + +/** + * Providies utilities for inspecting bytecode using ASM library. + * + * HOW TO USE + * 1. Create subdirectory in test/files/jvm for your test. Let's name it $TESTDIR. + * 2. Create $TESTDIR/BytecodeSrc_1.scala that contains Scala source file which you + * want to inspect the bytecode for. The '_1' suffix signals to partest that it + * should compile this file first. + * 3. Create $TESTDIR/Test.scala: + * import scala.tools.partest.BytecodeTest + * object Test extends BytecodeTest { + * def show { + * // your code that inspect ASM trees and prints values + * } + * } + * 4. Create corresponding check file. + * + * EXAMPLE + * See test/files/jvm/bytecode-test-example for an example of bytecode test. + * + */ +abstract class BytecodeTest { + + /** produce the output to be compared against a checkfile */ + protected def show(): Unit + + def main(args: Array[String]): Unit = show + + protected def getMethod(classNode: ClassNode, name: String): MethodNode = + classNode.methods.asScala.find(_.name == name) getOrElse + sys.error(s"Didn't find method '$name' in class '${classNode.name}'") + + protected def loadClassNode(name: String): ClassNode = { + val classBytes: InputStream = (for { + classRep <- classpath.findClass(name) + binary <- classRep.binary + } yield binary.input) getOrElse sys.error(s"failed to load class '$name'; classpath = $classpath") + + val cr = new ClassReader(classBytes) + val cn = new ClassNode() + cr.accept(cn, 0) + cn + } + + protected lazy val classpath: JavaClassPath = { + import scala.tools.nsc.util.ClassPath.DefaultJavaContext + import scala.tools.util.PathResolver.Defaults + // logic inspired by scala.tools.util.PathResolver implementation + val containers = DefaultJavaContext.classesInExpandedPath(Defaults.javaUserClassPath) + new JavaClassPath(containers, DefaultJavaContext) + } +} diff --git a/src/partest/scala/tools/partest/PartestTask.scala b/src/partest/scala/tools/partest/PartestTask.scala index d320f20616..13207b16fd 100644 --- a/src/partest/scala/tools/partest/PartestTask.scala +++ b/src/partest/scala/tools/partest/PartestTask.scala @@ -346,7 +346,7 @@ class PartestTask extends Task with CompilationPathProperty { javacmd foreach (x => antFileManager.JAVACMD = x.getAbsolutePath) javaccmd foreach (x => antFileManager.JAVAC_CMD = x.getAbsolutePath) - scalacArgsFlat foreach (antFileManager.SCALAC_OPTS = _) + scalacArgsFlat foreach (antFileManager.SCALAC_OPTS ++= _) timeout foreach (antFileManager.timeout = _) type TFSet = (Array[File], String, String) diff --git a/src/partest/scala/tools/partest/nest/SBTRunner.scala b/src/partest/scala/tools/partest/nest/SBTRunner.scala index b0ce6579ac..20f9c701d5 100644 --- a/src/partest/scala/tools/partest/nest/SBTRunner.scala +++ b/src/partest/scala/tools/partest/nest/SBTRunner.scala @@ -46,7 +46,7 @@ object SBTRunner extends DirectRunner { case x => sys.error("Unknown command line options: " + x) } val config = parseArgs(args, CommandLineOptions()) - fileManager.SCALAC_OPTS = config.scalacOptions + fileManager.SCALAC_OPTS ++= config.scalacOptions fileManager.CLASSPATH = config.classpath getOrElse sys.error("No classpath set") def findClasspath(jar: String, name: String): Option[String] = { diff --git a/src/reflect/scala/reflect/api/Names.scala b/src/reflect/scala/reflect/api/Names.scala index 8add98d815..6290b88d33 100644 --- a/src/reflect/scala/reflect/api/Names.scala +++ b/src/reflect/scala/reflect/api/Names.scala @@ -75,10 +75,10 @@ trait Names { * @group API */ abstract class NameApi { - /** Checks wether the name is a a term name */ + /** Checks wether the name is a term name */ def isTermName: Boolean - /** Checks wether the name is a a type name */ + /** Checks wether the name is a type name */ def isTypeName: Boolean /** Returns a term name that wraps the same string as `this` */ diff --git a/src/reflect/scala/reflect/internal/AnnotationCheckers.scala b/src/reflect/scala/reflect/internal/AnnotationCheckers.scala index 13346d9151..73cc7fbbd6 100644 --- a/src/reflect/scala/reflect/internal/AnnotationCheckers.scala +++ b/src/reflect/scala/reflect/internal/AnnotationCheckers.scala @@ -16,7 +16,15 @@ trait AnnotationCheckers { /** An additional checker for annotations on types. * Typically these are registered by compiler plugins * with the addAnnotationChecker method. */ - abstract class AnnotationChecker { + trait AnnotationChecker { + + /** + * Selectively activate this annotation checker. When using both an annotation checker + * and an analyzer plugin, it is common to run both of them only during selected + * compiler phases. See documentation in AnalyzerPlugin.isActive. + */ + def isActive(): Boolean = true + /** Check the annotations on two types conform. */ def annotationsConform(tpe1: Type, tpe2: Type): Boolean @@ -29,39 +37,51 @@ trait AnnotationCheckers { def annotationsGlb(tp: Type, ts: List[Type]): Type = tp /** Refine the bounds on type parameters to the given type arguments. */ - def adaptBoundsToAnnotations(bounds: List[TypeBounds], - tparams: List[Symbol], targs: List[Type]): List[TypeBounds] = bounds + def adaptBoundsToAnnotations(bounds: List[TypeBounds], tparams: List[Symbol], + targs: List[Type]): List[TypeBounds] = bounds - /** Modify the type that has thus far been inferred - * for a tree. All this should do is add annotations. */ + /** + * Modify the type that has thus far been inferred for a tree. All this should + * do is add annotations. + */ + @deprecated("Create an AnalyzerPlugin and use pluginsTyped", "2.10.1") def addAnnotations(tree: Tree, tpe: Type): Type = tpe - /** Decide whether this annotation checker can adapt a tree - * that has an annotated type to the given type tp, taking - * into account the given mode (see method adapt in trait Typers).*/ + /** + * Decide whether this analyzer plugin can adapt a tree that has an annotated type to the + * given type tp, taking into account the given mode (see method adapt in trait Typers). + */ + @deprecated("Create an AnalyzerPlugin and use canAdaptAnnotations", "2.10.1") def canAdaptAnnotations(tree: Tree, mode: Mode, pt: Type): Boolean = false - /** Adapt a tree that has an annotated type to the given type tp, - * taking into account the given mode (see method adapt in trait Typers). - * An implementation cannot rely on canAdaptAnnotations being called - * before. If the implementing class cannot do the adaptiong, it - * should return the tree unchanged.*/ + /** + * Adapt a tree that has an annotated type to the given type tp, taking into account the given + * mode (see method adapt in trait Typers). + * + * An implementation cannot rely on canAdaptAnnotations being called before. If the implementing + * class cannot do the adaptiong, it should return the tree unchanged. + */ + @deprecated("Create an AnalyzerPlugin and use adaptAnnotations", "2.10.1") def adaptAnnotations(tree: Tree, mode: Mode, pt: Type): Tree = tree - /** Adapt the type of a return expression. The decision of an annotation checker - * whether the type should be adapted is based on the type of the expression - * which is returned, as well as the result type of the method (pt). - * By default, this method simply returns the passed `default` type. + /** + * Adapt the type of a return expression. The decision of a typer plugin whether the type + * should be adapted is based on the type of the expression which is returned, as well as the + * result type of the method (pt). + * + * By default, this method simply returns the passed `default` type. */ + @deprecated("Create an AnalyzerPlugin and use pluginsTypedReturn. Note: the 'tree' argument here is\n"+ + "the 'expr' of a Return tree; 'pluginsTypedReturn' takes the Return tree itself as argument", "2.10.1") def adaptTypeOfReturn(tree: Tree, pt: Type, default: => Type): Type = default } // Syncnote: Annotation checkers inaccessible to reflection, so no sync in var necessary. + /** The list of annotation checkers that have been registered */ private var annotationCheckers: List[AnnotationChecker] = Nil - /** Register an annotation checker. Typically these - * are added by compiler plugins. */ + /** Register an annotation checker. Typically these are added by compiler plugins. */ def addAnnotationChecker(checker: AnnotationChecker) { if (!(annotationCheckers contains checker)) annotationCheckers = checker :: annotationCheckers @@ -72,76 +92,53 @@ trait AnnotationCheckers { annotationCheckers = Nil } - /** Check that the annotations on two types conform. To do - * so, consult all registered annotation checkers. */ - def annotationsConform(tp1: Type, tp2: Type): Boolean = { - /* Finish quickly if there are no annotations */ - if (tp1.annotations.isEmpty && tp2.annotations.isEmpty) - true - else - annotationCheckers.forall( - _.annotationsConform(tp1,tp2)) - } - - /** Refine the computed least upper bound of a list of types. - * All this should do is add annotations. */ - def annotationsLub(tpe: Type, ts: List[Type]): Type = { - annotationCheckers.foldLeft(tpe)((tpe, checker) => - checker.annotationsLub(tpe, ts)) - } - - /** Refine the computed greatest lower bound of a list of types. - * All this should do is add annotations. */ - def annotationsGlb(tpe: Type, ts: List[Type]): Type = { - annotationCheckers.foldLeft(tpe)((tpe, checker) => - checker.annotationsGlb(tpe, ts)) - } - - /** Refine the bounds on type parameters to the given type arguments. */ - def adaptBoundsToAnnotations(bounds: List[TypeBounds], - tparams: List[Symbol], targs: List[Type]): List[TypeBounds] = { - annotationCheckers.foldLeft(bounds)((bounds, checker) => - checker.adaptBoundsToAnnotations(bounds, tparams, targs)) - } - - /** Let all annotations checkers add extra annotations - * to this tree's type. */ - def addAnnotations(tree: Tree, tpe: Type): Type = { - annotationCheckers.foldLeft(tpe)((tpe, checker) => - checker.addAnnotations(tree, tpe)) - } - - /** Find out whether any annotation checker can adapt a tree - * to a given type. Called by Typers.adapt. */ - def canAdaptAnnotations(tree: Tree, mode: Mode, pt: Type): Boolean = { - annotationCheckers.exists(_.canAdaptAnnotations(tree, mode, pt)) - } - - /** Let registered annotation checkers adapt a tree - * to a given type (called by Typers.adapt). Annotation checkers - * that cannot do the adaption should pass the tree through - * unchanged. */ - def adaptAnnotations(tree: Tree, mode: Mode, pt: Type): Tree = { - annotationCheckers.foldLeft(tree)((tree, checker) => - checker.adaptAnnotations(tree, mode, pt)) - } - - /** Let a registered annotation checker adapt the type of a return expression. - * Annotation checkers that cannot do the adaptation should simply return - * the `default` argument. - * - * Note that the result is undefined if more than one annotation checker - * returns an adapted type which is not a subtype of `default`. - */ - def adaptTypeOfReturn(tree: Tree, pt: Type, default: => Type): Type = { - val adaptedTypes = annotationCheckers flatMap { checker => - val adapted = checker.adaptTypeOfReturn(tree, pt, default) - if (!(adapted <:< default)) List(adapted) - else List() - } - adaptedTypes match { - case fst :: _ => fst - case List() => default - } - } + /** @see AnnotationChecker.annotationsConform */ + def annotationsConform(tp1: Type, tp2: Type): Boolean = + if (annotationCheckers.isEmpty || (tp1.annotations.isEmpty && tp2.annotations.isEmpty)) true + else annotationCheckers.forall(checker => { + !checker.isActive() || checker.annotationsConform(tp1,tp2) + }) + + /** @see AnnotationChecker.annotationsLub */ + def annotationsLub(tpe: Type, ts: List[Type]): Type = + if (annotationCheckers.isEmpty) tpe + else annotationCheckers.foldLeft(tpe)((tpe, checker) => + if (!checker.isActive()) tpe else checker.annotationsLub(tpe, ts)) + + /** @see AnnotationChecker.annotationsGlb */ + def annotationsGlb(tpe: Type, ts: List[Type]): Type = + if (annotationCheckers.isEmpty) tpe + else annotationCheckers.foldLeft(tpe)((tpe, checker) => + if (!checker.isActive()) tpe else checker.annotationsGlb(tpe, ts)) + + /** @see AnnotationChecker.adaptBoundsToAnnotations */ + def adaptBoundsToAnnotations(bounds: List[TypeBounds], tparams: List[Symbol], + targs: List[Type]): List[TypeBounds] = + if (annotationCheckers.isEmpty) bounds + else annotationCheckers.foldLeft(bounds)((bounds, checker) => + if (!checker.isActive()) bounds else checker.adaptBoundsToAnnotations(bounds, tparams, targs)) + + + /* The following methods will be removed with the deprecated methods is AnnotationChecker. */ + + def addAnnotations(tree: Tree, tpe: Type): Type = + if (annotationCheckers.isEmpty) tpe + else annotationCheckers.foldLeft(tpe)((tpe, checker) => + if (!checker.isActive()) tpe else checker.addAnnotations(tree, tpe)) + + def canAdaptAnnotations(tree: Tree, mode: Mode, pt: Type): Boolean = + if (annotationCheckers.isEmpty) false + else annotationCheckers.exists(checker => { + checker.isActive() && checker.canAdaptAnnotations(tree, mode, pt) + }) + + def adaptAnnotations(tree: Tree, mode: Mode, pt: Type): Tree = + if (annotationCheckers.isEmpty) tree + else annotationCheckers.foldLeft(tree)((tree, checker) => + if (!checker.isActive()) tree else checker.adaptAnnotations(tree, mode, pt)) + + def adaptTypeOfReturn(tree: Tree, pt: Type, default: => Type): Type = + if (annotationCheckers.isEmpty) default + else annotationCheckers.foldLeft(default)((tpe, checker) => + if (!checker.isActive()) tpe else checker.adaptTypeOfReturn(tree, pt, tpe)) } diff --git a/src/reflect/scala/reflect/internal/AnnotationInfos.scala b/src/reflect/scala/reflect/internal/AnnotationInfos.scala index 7a972c3f1a..70b8bd9be5 100644 --- a/src/reflect/scala/reflect/internal/AnnotationInfos.scala +++ b/src/reflect/scala/reflect/internal/AnnotationInfos.scala @@ -12,7 +12,7 @@ import scala.collection.immutable.ListMap /** AnnotationInfo and its helpers */ trait AnnotationInfos extends api.Annotations { self: SymbolTable => - import definitions.{ ThrowsClass, StaticAnnotationClass, isMetaAnnotation } + import definitions.{ ThrowsClass, ThrowableClass, StaticAnnotationClass, isMetaAnnotation } // Common annotation code between Symbol and Type. // For methods altering the annotation list, on Symbol it mutates @@ -334,7 +334,7 @@ trait AnnotationInfos extends api.Annotations { self: SymbolTable => * as well as “new-stye” `@throws[Exception]("cause")` annotations. */ object ThrownException { - def unapply(ann: AnnotationInfo): Option[Symbol] = + def unapply(ann: AnnotationInfo): Option[Symbol] = { ann match { case AnnotationInfo(tpe, _, _) if tpe.typeSymbol != ThrowsClass => None @@ -342,8 +342,11 @@ trait AnnotationInfos extends api.Annotations { self: SymbolTable => case AnnotationInfo(_, List(Literal(Constant(tpe: Type))), _) => Some(tpe.typeSymbol) // new-style: @throws[Exception], @throws[Exception]("cause") - case AnnotationInfo(TypeRef(_, _, args), _, _) => - Some(args.head.typeSymbol) + case AnnotationInfo(TypeRef(_, _, arg :: _), _, _) => + Some(arg.typeSymbol) + case AnnotationInfo(TypeRef(_, _, Nil), _, _) => + Some(ThrowableClass) } + } } } diff --git a/src/reflect/scala/reflect/internal/Definitions.scala b/src/reflect/scala/reflect/internal/Definitions.scala index edd295aa65..8cca309d11 100644 --- a/src/reflect/scala/reflect/internal/Definitions.scala +++ b/src/reflect/scala/reflect/internal/Definitions.scala @@ -626,7 +626,7 @@ trait Definitions extends api.StandardDefinitions { len <= MaxTupleArity && sym == TupleClass(len) case _ => false } - def isTupleType(tp: Type) = isTupleTypeDirect(tp.normalize) + def isTupleType(tp: Type) = isTupleTypeDirect(tp.dealiasWiden) lazy val ProductRootClass: ClassSymbol = requiredClass[scala.Product] def Product_productArity = getMemberMethod(ProductRootClass, nme.productArity) @@ -648,16 +648,17 @@ trait Definitions extends api.StandardDefinitions { case _ => tp } - def unapplyUnwrap(tpe:Type) = tpe.finalResultType.normalize match { - case RefinedType(p :: _, _) => p.normalize + def unapplyUnwrap(tpe:Type) = tpe.finalResultType.dealiasWiden match { + case RefinedType(p :: _, _) => p.dealiasWiden case tp => tp } - def abstractFunctionForFunctionType(tp: Type) = - if (isFunctionType(tp)) abstractFunctionType(tp.typeArgs.init, tp.typeArgs.last) - else NoType + def abstractFunctionForFunctionType(tp: Type) = { + assert(isFunctionType(tp), tp) + abstractFunctionType(tp.typeArgs.init, tp.typeArgs.last) + } - def isFunctionType(tp: Type): Boolean = tp.normalize match { + def isFunctionType(tp: Type): Boolean = tp.dealiasWiden match { case TypeRef(_, sym, args) if args.nonEmpty => val arity = args.length - 1 // -1 is the return type arity <= MaxFunctionArity && sym == FunctionClass(arity) @@ -714,7 +715,10 @@ trait Definitions extends api.StandardDefinitions { * C[E1, ..., En] forSome { E1 >: LB1 <: UB1 ... en >: LBn <: UBn }. */ def classExistentialType(clazz: Symbol): Type = - newExistentialType(clazz.typeParams, clazz.tpe_*) + existentialAbstraction(clazz.typeParams, clazz.tpe_*) + + def unsafeClassExistentialType(clazz: Symbol): Type = + existentialAbstraction(clazz.unsafeTypeParams, clazz.tpe_*) // members of class scala.Any lazy val Any_== = enterNewMethod(AnyClass, nme.EQ, anyparam, booltype, FINAL) @@ -876,7 +880,6 @@ trait Definitions extends api.StandardDefinitions { lazy val BeanPropertyAttr = requiredClass[scala.beans.BeanProperty] lazy val BooleanBeanPropertyAttr = requiredClass[scala.beans.BooleanBeanProperty] - lazy val CloneableAttr = requiredClass[scala.annotation.cloneable] lazy val CompileTimeOnlyAttr = getClassIfDefined("scala.reflect.macros.compileTimeOnly") lazy val DeprecatedAttr = requiredClass[scala.deprecated] lazy val DeprecatedNameAttr = requiredClass[scala.deprecatedName] @@ -1140,10 +1143,10 @@ trait Definitions extends api.StandardDefinitions { } def flatNameString(sym: Symbol, separator: Char): String = if (sym == NoSymbol) "" // be more resistant to error conditions, e.g. neg/t3222.scala - else if (sym.owner.isPackageClass) sym.javaClassName + else if (sym.isTopLevel) sym.javaClassName else flatNameString(sym.owner, separator) + nme.NAME_JOIN_STRING + sym.simpleName def signature1(etp: Type): String = { - if (etp.typeSymbol == ArrayClass) "[" + signature1(erasure(etp.normalize.typeArgs.head)) + if (etp.typeSymbol == ArrayClass) "[" + signature1(erasure(etp.dealiasWiden.typeArgs.head)) else if (isPrimitiveValueClass(etp.typeSymbol)) abbrvTag(etp.typeSymbol).toString() else "L" + flatNameString(etp.typeSymbol, '/') + ";" } diff --git a/src/reflect/scala/reflect/internal/ExistentialsAndSkolems.scala b/src/reflect/scala/reflect/internal/ExistentialsAndSkolems.scala index 2a0fe9d19a..281a32caf6 100644 --- a/src/reflect/scala/reflect/internal/ExistentialsAndSkolems.scala +++ b/src/reflect/scala/reflect/internal/ExistentialsAndSkolems.scala @@ -31,19 +31,4 @@ trait ExistentialsAndSkolems { } (new Deskolemizer).typeSkolems } - - /** Convert to corresponding type parameters all skolems of method - * parameters which appear in `tparams`. - */ - def deskolemizeTypeParams(tparams: List[Symbol])(tp: Type): Type = { - class DeSkolemizeMap extends TypeMap { - def apply(tp: Type): Type = tp match { - case TypeRef(pre, sym, args) if sym.isTypeSkolem && (tparams contains sym.deSkolemize) => - mapOver(typeRef(NoPrefix, sym.deSkolemize, args)) - case _ => - mapOver(tp) - } - } - new DeSkolemizeMap mapOver tp - } } diff --git a/src/reflect/scala/reflect/internal/Symbols.scala b/src/reflect/scala/reflect/internal/Symbols.scala index 2d42d2df58..9b7b8bd683 100644 --- a/src/reflect/scala/reflect/internal/Symbols.scala +++ b/src/reflect/scala/reflect/internal/Symbols.scala @@ -591,7 +591,7 @@ trait Symbols extends api.Symbols { self: SymbolTable => /** Does this symbol denote a wrapper created by the repl? */ final def isInterpreterWrapper = ( (this hasFlag MODULE) - && owner.isPackageClass + && isTopLevel && nme.isReplWrapperName(name) ) final def getFlag(mask: Long): Long = { @@ -813,7 +813,7 @@ trait Symbols extends api.Symbols { self: SymbolTable => /** Is this symbol effectively final? I.e, it cannot be overridden */ final def isEffectivelyFinal: Boolean = ( (this hasFlag FINAL | PACKAGE) - || isModuleOrModuleClass && (owner.isPackageClass || !settings.overrideObjects.value) + || isModuleOrModuleClass && (isTopLevel || !settings.overrideObjects.value) || isTerm && ( isPrivate || isLocal @@ -821,6 +821,9 @@ trait Symbols extends api.Symbols { self: SymbolTable => ) ) + /** Is this symbol owned by a package? */ + final def isTopLevel = owner.isPackageClass + /** Is this symbol locally defined? I.e. not accessed from outside `this` instance */ final def isLocal: Boolean = owner.isTerm @@ -841,7 +844,7 @@ trait Symbols extends api.Symbols { self: SymbolTable => /** Is this class or type defined as a structural refinement type? */ final def isStructuralRefinement: Boolean = - (isClass || isType || isModule) && info.normalize/*.underlying*/.isStructuralRefinement + (isClass || isType || isModule) && info.dealiasWiden/*.underlying*/.isStructuralRefinement /** Is this a term symbol only defined in a refinement (so that it needs * to be accessed by reflection)? @@ -870,7 +873,7 @@ trait Symbols extends api.Symbols { self: SymbolTable => // Does not always work if the rawInfo is a SourcefileLoader, see comment // in "def coreClassesFirst" in Global. - def exists = !owner.isPackageClass || { rawInfo.load(this); rawInfo != NoType } + def exists = !isTopLevel || { rawInfo.load(this); rawInfo != NoType } final def isInitialized: Boolean = validTo != NoPeriod @@ -1177,6 +1180,10 @@ trait Symbols extends api.Symbols { self: SymbolTable => * Since tpe forwards to tpe_*, if you call it on a type symbol with unapplied * type parameters, the type returned will contain dummies types. These will * hide legitimate errors or create spurious ones if used as normal types. + * + * For type symbols, `tpe` is different than `info`. `tpe` returns a typeRef + * to the type symbol, `info` returns the type information of the type symbol, + * e.g. a ClassInfoType for classes or a TypeBounds for abstract types. */ final def tpe: Type = tpe_* @@ -1608,8 +1615,21 @@ trait Symbols extends api.Symbols { self: SymbolTable => setAnnotations(annot :: annotations) // Convenience for the overwhelmingly common case - def addAnnotation(sym: Symbol, args: Tree*): this.type = + def addAnnotation(sym: Symbol, args: Tree*): this.type = { + // The assertion below is meant to prevent from issues like SI-7009 but it's disabled + // due to problems with cycles while compiling Scala library. It's rather shocking that + // just checking if sym is monomorphic type introduces nasty cycles. We are definitively + // forcing too much because monomorphism is a local property of a type that can be checked + // syntactically + // assert(sym.initialize.isMonomorphicType, sym) addAnnotation(AnnotationInfo(sym.tpe, args.toList, Nil)) + } + + /** Use that variant if you want to pass (for example) an applied type */ + def addAnnotation(tp: Type, args: Tree*): this.type = { + assert(tp.typeParams.isEmpty, tp) + addAnnotation(AnnotationInfo(tp, args.toList, Nil)) + } // ------ comparisons ---------------------------------------------------------------- @@ -1687,6 +1707,8 @@ trait Symbols extends api.Symbols { self: SymbolTable => @inline final def map(f: Symbol => Symbol): Symbol = if (this eq NoSymbol) this else f(this) + final def toOption: Option[Symbol] = if (exists) Some(this) else None + // ------ cloneing ------------------------------------------------------------------- /** A clone of this symbol. */ @@ -1764,8 +1786,27 @@ trait Symbols extends api.Symbols { self: SymbolTable => /** For a case class, the symbols of the accessor methods, one for each * argument in the first parameter list of the primary constructor. * The empty list for all other classes. - */ - final def caseFieldAccessors: List[Symbol] = + * + * This list will be sorted to correspond to the declaration order + * in the constructor parameter + */ + final def caseFieldAccessors: List[Symbol] = { + // We can't rely on the ordering of the case field accessors within decls -- + // handling of non-public parameters seems to change the order (see SI-7035.) + // + // Luckily, the constrParamAccessors are still sorted properly, so sort the field-accessors using them + // (need to undo name-mangling, including the sneaky trailing whitespace) + // + // The slightly more principled approach of using the paramss of the + // primary constructor leads to cycles in, for example, pos/t5084.scala. + val primaryNames = constrParamAccessors.map(acc => nme.dropLocalSuffix(acc.name)) + caseFieldAccessorsUnsorted.sortBy { acc => + primaryNames indexWhere { orig => + (acc.name == orig) || (acc.name startsWith (orig append "$")) + } + } + } + private final def caseFieldAccessorsUnsorted: List[Symbol] = (info.decls filter (_.isCaseAccessorMethod)).toList final def constrParamAccessors: List[Symbol] = @@ -1916,7 +1957,7 @@ trait Symbols extends api.Symbols { self: SymbolTable => /** The top-level class containing this symbol. */ def enclosingTopLevelClass: Symbol = - if (owner.isPackageClass) { + if (isTopLevel) { if (isClass) this else moduleClass } else owner.enclosingTopLevelClass @@ -2889,7 +2930,7 @@ trait Symbols extends api.Symbols { self: SymbolTable => override def isAnonymousClass = name containsName tpnme.ANON_CLASS_NAME override def isConcreteClass = !(this hasFlag ABSTRACT | TRAIT) override def isJavaInterface = hasAllFlags(JAVA | TRAIT) - override def isNestedClass = !owner.isPackageClass + override def isNestedClass = !isTopLevel override def isNumericValueClass = definitions.isNumericValueClass(this) override def isNumeric = isNumericValueClass override def isPackageObjectClass = isModuleClass && (name == tpnme.PACKAGE) @@ -2915,7 +2956,7 @@ trait Symbols extends api.Symbols { self: SymbolTable => override def isLocalClass = ( isAnonOrRefinementClass || isLocal - || !owner.isPackageClass && owner.isLocalClass + || !isTopLevel && owner.isLocalClass ) override def enclClassChain = this :: owner.enclClassChain @@ -2944,7 +2985,7 @@ trait Symbols extends api.Symbols { self: SymbolTable => } override def associatedFile = ( - if (!owner.isPackageClass) super.associatedFile + if (!isTopLevel) super.associatedFile else if (_associatedFile eq null) NoAbstractFile // guarantee not null, but save cost of initializing the var else _associatedFile ) diff --git a/src/reflect/scala/reflect/internal/TreeGen.scala b/src/reflect/scala/reflect/internal/TreeGen.scala index 6a2006e56f..b2269e476f 100644 --- a/src/reflect/scala/reflect/internal/TreeGen.scala +++ b/src/reflect/scala/reflect/internal/TreeGen.scala @@ -212,7 +212,7 @@ abstract class TreeGen extends macros.TreeBuilder { mkTypeApply(mkAttributedSelect(target, method), targs map TypeTree) private def mkSingleTypeApply(value: Tree, tpe: Type, what: Symbol, wrapInApply: Boolean) = { - val tapp = mkAttributedTypeApply(value, what, tpe.normalize :: Nil) + val tapp = mkAttributedTypeApply(value, what, tpe.dealias :: Nil) if (wrapInApply) Apply(tapp, Nil) else tapp } private def typeTestSymbol(any: Boolean) = if (any) Any_isInstanceOf else Object_isInstanceOf @@ -271,6 +271,10 @@ abstract class TreeGen extends macros.TreeBuilder { case _ => Constant(null) } + /** Wrap an expression in a named argument. */ + def mkNamedArg(name: Name, tree: Tree): Tree = mkNamedArg(Ident(name), tree) + def mkNamedArg(lhs: Tree, rhs: Tree): Tree = atPos(rhs.pos)(AssignOrNamedArg(lhs, rhs)) + /** Builds a tuple */ def mkTuple(elems: List[Tree]): Tree = if (elems.isEmpty) Literal(Constant()) diff --git a/src/reflect/scala/reflect/internal/TreeInfo.scala b/src/reflect/scala/reflect/internal/TreeInfo.scala index 032a4aebef..9b8f86751e 100644 --- a/src/reflect/scala/reflect/internal/TreeInfo.scala +++ b/src/reflect/scala/reflect/internal/TreeInfo.scala @@ -65,6 +65,9 @@ abstract class TreeInfo { false } + // TODO SI-5304 tighten this up so we don't elide side effect in module loads + def isQualifierSafeToElide(tree: Tree): Boolean = isExprSafeToInline(tree) + /** Is tree an expression which can be inlined without affecting program semantics? * * Note that this is not called "isExprPure" since purity (lack of side-effects) @@ -250,22 +253,24 @@ abstract class TreeInfo { * in the position `for { <tree> <- expr }` based only * on information at the `parser` phase? To qualify, there * may be no subtree that will be interpreted as a - * Stable Identifier Pattern. + * Stable Identifier Pattern, nor any type tests, even + * on TupleN. See SI-6968. * * For instance: * * {{{ - * foo @ (bar, (baz, quux)) + * (foo @ (bar @ _)) = 0 * }}} * - * is a variable pattern; if the structure matches, - * then the remainder is inevitable. + * is a not a variable pattern; if only binds names. * * The following are not variable patterns. * * {{{ - * foo @ (bar, (`baz`, quux)) // back quoted ident, not at top level - * foo @ (bar, Quux) // UpperCase ident, not at top level + * `bar` + * Bar + * (a, b) + * _: T * }}} * * If the pattern is a simple identifier, it is always @@ -294,10 +299,6 @@ abstract class TreeInfo { tree match { case Bind(name, pat) => isVarPatternDeep0(pat) case Ident(name) => isVarPattern(tree) - case Apply(sel, args) => - ( isReferenceToScalaMember(sel, TupleClass(args.size).name.toTermName) - && (args forall isVarPatternDeep0) - ) case _ => false } } @@ -370,6 +371,14 @@ abstract class TreeInfo { case _ => false } + /** Translates an Assign(_, _) node to AssignOrNamedArg(_, _) if + * the lhs is a simple ident. Otherwise returns unchanged. + */ + def assignmentToMaybeNamedArg(tree: Tree) = tree match { + case t @ Assign(id: Ident, rhs) => atPos(t.pos)(AssignOrNamedArg(id, rhs)) + case t => t + } + /** Is name a left-associative operator? */ def isLeftAssoc(operator: Name) = operator.nonEmpty && (operator.endChar != ':') @@ -467,7 +476,7 @@ abstract class TreeInfo { tp match { case TypeRef(pre, sym, args) => - args.isEmpty && (sym.owner.isPackageClass || isSimple(pre)) + args.isEmpty && (sym.isTopLevel || isSimple(pre)) case NoPrefix => true case _ => @@ -605,6 +614,12 @@ abstract class TreeInfo { } loop(tree) } + + override def toString = { + val tstr = if (targs.isEmpty) "" else targs.mkString("[", ", ", "]") + val astr = argss map (args => args.mkString("(", ", ", ")")) mkString "" + s"$core$tstr$astr" + } } /** Returns a wrapper that knows how to destructure and analyze applications. diff --git a/src/reflect/scala/reflect/internal/Trees.scala b/src/reflect/scala/reflect/internal/Trees.scala index 3c2249bfb5..9b185c1c2d 100644 --- a/src/reflect/scala/reflect/internal/Trees.scala +++ b/src/reflect/scala/reflect/internal/Trees.scala @@ -1469,6 +1469,22 @@ trait Trees extends api.Trees { self: SymbolTable => if (tree.hasSymbolField) { subst(from, to) tree match { + case _: DefTree => + val newInfo = symSubst(tree.symbol.info) + if (!(newInfo =:= tree.symbol.info)) { + debuglog(sm""" + |TreeSymSubstituter: updated info of symbol ${tree.symbol} + | Old: ${showRaw(tree.symbol.info, printTypes = true, printIds = true)} + | New: ${showRaw(newInfo, printTypes = true, printIds = true)}""") + tree.symbol updateInfo newInfo + } + case _ => + // no special handling is required for Function or Import nodes here. + // as they don't have interesting infos attached to their symbols. + // Subsitution of the referenced symbol of Return nodes is handled + // in .ChangeOwnerTraverser + } + tree match { case Ident(name0) if tree.symbol != NoSymbol => treeCopy.Ident(tree, tree.symbol.name) case Select(qual, name0) if tree.symbol != NoSymbol => @@ -1526,6 +1542,14 @@ trait Trees extends api.Trees { self: SymbolTable => t1 } } + trait TreeStackTraverser extends Traverser { + import collection.mutable + val path: mutable.Stack[Tree] = mutable.Stack() + abstract override def traverse(t: Tree) = { + path push t + try super.traverse(t) finally path.pop() + } + } def duplicateAndKeepPositions(tree: Tree) = new Duplicator(focusPositions = false) transform tree diff --git a/src/reflect/scala/reflect/internal/Types.scala b/src/reflect/scala/reflect/internal/Types.scala index 1ef983c1c9..e34d695a61 100644 --- a/src/reflect/scala/reflect/internal/Types.scala +++ b/src/reflect/scala/reflect/internal/Types.scala @@ -153,7 +153,7 @@ trait Types extends api.Types { self: SymbolTable => } /** No sync necessary, because record should only - * be called from within a undo or undoUnless block, + * be called from within an undo or undoUnless block, * which is already synchronized. */ private[reflect] def record(tv: TypeVar) = { @@ -234,7 +234,14 @@ trait Types extends api.Types { self: SymbolTable => * forwarded here. Some operations are rewrapped again. */ trait RewrappingTypeProxy extends SimpleTypeProxy { - protected def maybeRewrap(newtp: Type) = if (newtp eq underlying) this else rewrap(newtp) + protected def maybeRewrap(newtp: Type) = ( + if (newtp eq underlying) this + // BoundedWildcardTypes reach here during erroneous compilation: neg/t6258 + // Higher-kinded exclusion is because [x]CC[x] compares =:= to CC: pos/t3800 + // Otherwise, if newtp =:= underlying, don't rewrap it. + else if (!newtp.isWildcard && !newtp.isHigherKinded && (newtp =:= underlying)) this + else rewrap(newtp) + ) protected def rewrap(newtp: Type): Type // the following are all operations in class Type that are overridden in some subclass @@ -557,6 +564,26 @@ trait Types extends api.Types { self: SymbolTable => * Example: (in the below, <List> is the type constructor of List) * TypeRef(pre, <List>, List()) is replaced by * PolyType(X, TypeRef(pre, <List>, List(X))) + * + * Discussion: normalize is NOT usually what you want to be calling. + * The (very real) danger with normalize is that it will force types + * which would not otherwise have been forced, leading to mysterious + * behavioral differences, cycles, and other elements of mysteries. + * Under most conditions the method you should be calling is `dealiasWiden` + * (see that method for more info.) + * + * Here are a few of the side-effect-trail-leaving methods called + * by various implementations of normalize: + * + * - sym.info + * - tpe.etaExpand + * - tpe.betaReduce + * - tpe.memberType + * - sym.nextOverriddenSymbol + * - constraint.inst + * + * If you've been around the compiler a while that list must fill + * your heart with fear. */ def normalize = this // @MAT @@ -566,6 +593,8 @@ trait Types extends api.Types { self: SymbolTable => /** Repeatedly apply widen and dealias until they have no effect. * This compensates for the fact that type aliases can hide beneath * singleton types and singleton types can hide inside type aliases. + * !!! - and yet it is still inadequate, because aliases and singletons + * might lurk in the upper bounds of an abstract type. See SI-7051. */ def dealiasWiden: Type = ( if (this ne widen) widen.dealiasWiden @@ -703,7 +732,7 @@ trait Types extends api.Types { self: SymbolTable => val trivial = ( this.isTrivial || phase.erasedTypes && pre.typeSymbol != ArrayClass - || pre.normalize.isTrivial && !isPossiblePrefix(clazz) + || skipPrefixOf(pre, clazz) ) if (trivial) this else { @@ -828,23 +857,27 @@ trait Types extends api.Types { self: SymbolTable => } /** Is this type a subtype of that type in a pattern context? - * Any type arguments on the right hand side are replaced with + * Dummy type arguments on the right hand side are replaced with * fresh existentials, except for Arrays. * * See bug1434.scala for an example of code which would fail * if only a <:< test were applied. */ - def matchesPattern(that: Type): Boolean = { - (this <:< that) || ((this, that) match { - case (TypeRef(_, ArrayClass, List(arg1)), TypeRef(_, ArrayClass, List(arg2))) if arg2.typeSymbol.typeParams.nonEmpty => - arg1 matchesPattern arg2 - case (_, TypeRef(_, _, args)) => - val newtp = existentialAbstraction(args map (_.typeSymbol), that) - !(that =:= newtp) && (this <:< newtp) - case _ => - false - }) - } + def matchesPattern(that: Type): Boolean = (this <:< that) || (that match { + case ArrayTypeRef(elem2) if elem2.typeConstructor.isHigherKinded => + this match { + case ArrayTypeRef(elem1) => elem1 matchesPattern elem2 + case _ => false + } + case TypeRef(_, sym, args) => + val that1 = existentialAbstraction(args map (_.typeSymbol), that) + (that ne that1) && (this <:< that1) && { + log(s"$this.matchesPattern($that) depended on discarding args and testing <:< $that1") + true + } + case _ => + false + }) def stat_<:<(that: Type): Boolean = { if (Statistics.canEnable) Statistics.incCounter(subtypeCount) @@ -2445,7 +2478,7 @@ trait Types extends api.Types { self: SymbolTable => case RepeatedParamClass => args.head + "*" case ByNameParamClass => "=> " + args.head case _ => - def targs = normalize.typeArgs + def targs = dealiasWiden.typeArgs if (isFunctionType(this)) { // Aesthetics: printing Function1 as T => R rather than (T) => R @@ -2454,7 +2487,9 @@ trait Types extends api.Types { self: SymbolTable => targs match { case in :: out :: Nil if !isTupleType(in) => // A => B => C should be (A => B) => C or A => (B => C) - val in_s = if (isFunctionType(in)) "(" + in + ")" else "" + in + // Also if A is byname, then we want (=> A) => B because => is right associative and => A => B + // would mean => (A => B) which is a different type + val in_s = if (isFunctionType(in) || isByNameParamType(in)) "(" + in + ")" else "" + in val out_s = if (isFunctionType(out)) "(" + out + ")" else "" + out in_s + " => " + out_s case xs => @@ -2858,6 +2893,13 @@ trait Types extends api.Types { self: SymbolTable => } } + object ArrayTypeRef { + def unapply(tp: Type) = tp match { + case TypeRef(_, ArrayClass, arg :: Nil) => Some(arg) + case _ => None + } + } + //@M // a TypeVar used to be a case class with only an origin and a constr // then, constr became mutable (to support UndoLog, I guess), @@ -2927,20 +2969,6 @@ trait Types extends api.Types { self: SymbolTable => createTypeVar(tparam.tpeHK, deriveConstraint(tparam), Nil, tparam.typeParams, untouchable) } - /** Repack existential types, otherwise they sometimes get unpacked in the - * wrong location (type inference comes up with an unexpected skolem) - */ - def repackExistential(tp: Type): Type = ( - if (tp == NoType) tp - else existentialAbstraction(existentialsInType(tp), tp) - ) - - def containsExistential(tpe: Type) = - tpe exists typeIsExistentiallyBound - - def existentialsInType(tpe: Type) = - tpe withFilter typeIsExistentiallyBound map (_.typeSymbol) - /** Precondition: params.nonEmpty. (args.nonEmpty enforced structurally.) */ class HKTypeVar( @@ -3726,17 +3754,14 @@ trait Types extends api.Types { self: SymbolTable => } /** Type with all top-level occurrences of abstract types replaced by their bounds */ - def abstractTypesToBounds(tp: Type): Type = tp match { // @M don't normalize here (compiler loops on pos/bug1090.scala ) - case TypeRef(_, sym, _) if sym.isAbstractType => - abstractTypesToBounds(tp.bounds.hi) - case TypeRef(_, sym, _) if sym.isAliasType => - abstractTypesToBounds(tp.normalize) - case rtp @ RefinedType(parents, decls) => - copyRefinedType(rtp, parents mapConserve abstractTypesToBounds, decls) - case AnnotatedType(_, underlying, _) => - abstractTypesToBounds(underlying) - case _ => - tp + object abstractTypesToBounds extends TypeMap { + def apply(tp: Type): Type = tp match { + case TypeRef(_, sym, _) if sym.isAliasType => apply(tp.dealias) + case TypeRef(_, sym, _) if sym.isAbstractType => apply(tp.bounds.hi) + case rtp @ RefinedType(parents, decls) => copyRefinedType(rtp, parents mapConserve this, decls) + case AnnotatedType(_, _, _) => mapOver(tp) + case _ => tp // no recursion - top level only + } } // Set to true for A* => Seq[A] @@ -3907,7 +3932,7 @@ trait Types extends api.Types { self: SymbolTable => } } class ClassUnwrapper(existential: Boolean) extends TypeUnwrapper(poly = true, existential, annotated = true, nullary = false) { - override def apply(tp: Type) = super.apply(tp.normalize) + override def apply(tp: Type) = super.apply(tp.normalize) // normalize is required here } object unwrapToClass extends ClassUnwrapper(existential = true) { } @@ -4154,6 +4179,26 @@ trait Types extends api.Types { self: SymbolTable => } } + /** Repack existential types, otherwise they sometimes get unpacked in the + * wrong location (type inference comes up with an unexpected skolem) + */ + def repackExistential(tp: Type): Type = ( + if (tp == NoType) tp + else existentialAbstraction(existentialsInType(tp), tp) + ) + + def containsExistential(tpe: Type) = tpe exists typeIsExistentiallyBound + def existentialsInType(tpe: Type) = tpe withFilter typeIsExistentiallyBound map (_.typeSymbol) + + private def isDummyOf(tpe: Type)(targ: Type) = { + val sym = targ.typeSymbol + sym.isTypeParameter && sym.owner == tpe.typeSymbol + } + def isDummyAppliedType(tp: Type) = tp.dealias match { + case tr @ TypeRef(_, _, args) => args exists isDummyOf(tr) + case _ => false + } + def typeParamsToExistentials(clazz: Symbol, tparams: List[Symbol]): List[Symbol] = { val eparams = mapWithIndex(tparams)((tparam, i) => clazz.newExistential(newTypeName("?"+i), clazz.pos) setInfo tparam.info.bounds) @@ -4163,19 +4208,21 @@ trait Types extends api.Types { self: SymbolTable => def typeParamsToExistentials(clazz: Symbol): List[Symbol] = typeParamsToExistentials(clazz, clazz.typeParams) + def isRawIfWithoutArgs(sym: Symbol) = sym.isClass && sym.typeParams.nonEmpty && sym.isJavaDefined + /** Is type tp a ''raw type''? */ // note: it's important to write the two tests in this order, // as only typeParams forces the classfile to be read. See #400 - private def isRawIfWithoutArgs(sym: Symbol) = - sym.isClass && sym.typeParams.nonEmpty && sym.isJavaDefined - - def isRaw(sym: Symbol, args: List[Type]) = - !phase.erasedTypes && isRawIfWithoutArgs(sym) && args.isEmpty + def isRawType(tp: Type) = !phase.erasedTypes && (tp match { + case TypeRef(_, sym, Nil) => isRawIfWithoutArgs(sym) + case _ => false + }) - /** Is type tp a ''raw type''? */ - def isRawType(tp: Type) = tp match { - case TypeRef(_, sym, args) => isRaw(sym, args) - case _ => false - } + @deprecated("Use isRawType", "2.10.1") // presently used by sbt + def isRaw(sym: Symbol, args: List[Type]) = ( + !phase.erasedTypes + && args.isEmpty + && isRawIfWithoutArgs(sym) + ) /** The raw to existential map converts a ''raw type'' to an existential type. * It is necessary because we might have read a raw type of a @@ -4294,14 +4341,15 @@ trait Types extends api.Types { self: SymbolTable => */ def isPossiblePrefix(clazz: Symbol) = clazz.isClass && !clazz.isPackageClass + private def skipPrefixOf(pre: Type, clazz: Symbol) = ( + (pre eq NoType) || (pre eq NoPrefix) || !isPossiblePrefix(clazz) + ) + /** A map to compute the asSeenFrom method */ class AsSeenFromMap(pre: Type, clazz: Symbol) extends TypeMap with KeepOnlyTypeConstraints { var capturedSkolems: List[Symbol] = List() var capturedParams: List[Symbol] = List() - private def skipPrefixOf(pre: Type, clazz: Symbol) = ( - (pre eq NoType) || (pre eq NoPrefix) || !isPossiblePrefix(clazz) - ) override def mapOver(tree: Tree, giveup: ()=>Nothing): Tree = { object annotationArgRewriter extends TypeMapTransformer { private def canRewriteThis(sym: Symbol) = ( @@ -4334,8 +4382,7 @@ trait Types extends api.Types { self: SymbolTable => } def apply(tp: Type): Type = - if (skipPrefixOf(pre, clazz)) tp - else tp match { + tp match { case ThisType(sym) => def toPrefix(pre: Type, clazz: Symbol): Type = if (skipPrefixOf(pre, clazz)) tp @@ -4539,23 +4586,13 @@ trait Types extends api.Types { self: SymbolTable => case idx => Some(to(idx)) } - override def transform(tree: Tree) = - tree match { - case tree@Ident(_) => - termMapsTo(tree.symbol) match { - case Some(tosym) => - if (tosym.info.bounds.hi.typeSymbol isSubClass SingletonClass) { - Ident(tosym.existentialToString) - .setSymbol(tosym) - .setPos(tosym.pos) - .setType(dropSingletonType(tosym.info.bounds.hi)) - } else { - giveup() - } - case none => super.transform(tree) - } - case tree => super.transform(tree) + override def transform(tree: Tree) = { + termMapsTo(tree.symbol) match { + case Some(tosym) => tree.symbol = tosym + case None => () } + super.transform(tree) + } } trans.transform(tree) } @@ -5608,7 +5645,13 @@ trait Types extends api.Types { self: SymbolTable => // for (tpFresh <- tpsFresh) tpFresh.setInfo(tpFresh.info.substSym(tparams1, tpsFresh)) } } && annotationsConform(tp1.normalize, tp2.normalize) - case (_, _) => false // @assume !tp1.isHigherKinded || !tp2.isHigherKinded + + case (PolyType(_, _), MethodType(params, _)) if params exists (_.tpe.isWildcard) => + false // don't warn on HasMethodMatching on right hand side + + case (ntp1, ntp2) => + devWarning(s"isHKSubType0($tp1, $tp2, _) is ${tp1.getClass}, ${tp2.getClass}: ($ntp1, $ntp2)") + false // @assume !tp1.isHigherKinded || !tp2.isHigherKinded // --> thus, cannot be subtypes (Any/Nothing has already been checked) })) @@ -5706,7 +5749,7 @@ trait Types extends api.Types { self: SymbolTable => case NotNullClass => tp1.isNotNull case SingletonClass => tp1.isStable || fourthTry case _: ClassSymbol => - if (isRaw(sym2, tp2.args)) + if (isRawType(tp2)) isSubType(tp1, rawToExistential(tp2), depth) else if (sym2.name == tpnme.REFINE_CLASS_NAME) isSubType(tp1, sym2.info, depth) @@ -5749,7 +5792,7 @@ trait Types extends api.Types { self: SymbolTable => (sameLength(params1, params2) && mt1.isImplicit == mt2.isImplicit && matchingParams(params1, params2, mt1.isJava, mt2.isJava) && - isSubType(res1, res2.substSym(params2, params1), depth)) + isSubType(res1.substSym(params1, params2), res2, depth)) // TODO: if mt1.params.isEmpty, consider NullaryMethodType? case _ => false @@ -5788,7 +5831,7 @@ trait Types extends api.Types { self: SymbolTable => isSingleType(tp2) && isSubType(tp1, tp2.widen, depth) } case _: ClassSymbol => - if (isRaw(sym1, tr1.args)) + if (isRawType(tp1)) isSubType(rawToExistential(tp1), tp2, depth) else if (sym1.isModuleClass) tp2 match { case SingleType(pre2, sym2) => equalSymsAndPrefixes(sym1.sourceModule, pre1, sym2, pre2) @@ -6279,7 +6322,7 @@ trait Types extends api.Types { self: SymbolTable => val ts0 = elimSub0(ts) if (ts0.isEmpty || ts0.tail.isEmpty) ts0 else { - val ts1 = ts0 mapConserve (t => elimAnonymousClass(t.underlying)) + val ts1 = ts0 mapConserve (t => elimAnonymousClass(t.dealiasWiden)) if (ts1 eq ts0) ts0 else elimSub(ts1, depth) } @@ -6409,6 +6452,8 @@ trait Types extends api.Types { self: SymbolTable => NullaryMethodType(lub0(matchingRestypes(ts, Nil))) case ts @ TypeBounds(_, _) :: rest => TypeBounds(glb(ts map (_.bounds.lo), depth), lub(ts map (_.bounds.hi), depth)) + case ts @ AnnotatedType(annots, tpe, _) :: rest => + annotationsLub(lub0(ts map (_.withoutAnnotations)), ts) case ts => lubResults get (depth, ts) match { case Some(lubType) => diff --git a/src/reflect/scala/reflect/internal/transform/Erasure.scala b/src/reflect/scala/reflect/internal/transform/Erasure.scala index 59bf51d638..abf380ac44 100644 --- a/src/reflect/scala/reflect/internal/transform/Erasure.scala +++ b/src/reflect/scala/reflect/internal/transform/Erasure.scala @@ -16,7 +16,7 @@ trait Erasure { /** Is `tp` an unbounded generic type (i.e. which could be instantiated * with primitive as well as class types)?. */ - private def genericCore(tp: Type): Type = tp.normalize match { + private def genericCore(tp: Type): Type = tp.dealiasWiden match { /* A Java Array<T> is erased to Array[Object] (T can only be a reference type), where as a Scala Array[T] is * erased to Object. However, there is only symbol for the Array class. So to make the distinction between * a Java and a Scala array, we check if the owner of T comes from a Java class. @@ -36,7 +36,7 @@ trait Erasure { * then Some((N, T)) where N is the number of Array constructors enclosing `T`, * otherwise None. Existentials on any level are ignored. */ - def unapply(tp: Type): Option[(Int, Type)] = tp.normalize match { + def unapply(tp: Type): Option[(Int, Type)] = tp.dealiasWiden match { case TypeRef(_, ArrayClass, List(arg)) => genericCore(arg) match { case NoType => @@ -101,7 +101,7 @@ trait Erasure { def valueClassIsParametric(clazz: Symbol): Boolean = { assert(!phase.erasedTypes) clazz.typeParams contains - clazz.derivedValueClassUnbox.tpe.resultType.normalize.typeSymbol + clazz.derivedValueClassUnbox.tpe.resultType.typeSymbol } abstract class ErasureMap extends TypeMap { @@ -214,9 +214,6 @@ trait Erasure { specialConstructorErasure(clazz, restpe) case ExistentialType(tparams, restpe) => specialConstructorErasure(clazz, restpe) - case RefinedType(parents, decls) => - specialConstructorErasure( - clazz, specialScalaErasure.mergeParents(parents)) case mt @ MethodType(params, restpe) => MethodType( cloneSymbolsAndModify(params, specialScalaErasure), @@ -225,15 +222,7 @@ trait Erasure { typeRef(pre, clazz, List()) case tp => if (!(clazz == ArrayClass || tp.isError)) - // See SI-6556. It seems in some cases the result constructor - // type of an anonymous class is a different version of the class. - // This has nothing to do with value classes per se. - // We simply used a less discriminating transform before, that - // did not look at the cases in detail. - // It seems there is a deeper problem here, which needs - // following up to. But we will not risk regressions - // in 2.10 because of it. - devWarning(s"unexpected constructor erasure $tp for $clazz") + assert(clazz == ArrayClass || tp.isError, s"!!! unexpected constructor erasure $tp for $clazz") specialScalaErasure(tp) } } diff --git a/src/reflect/scala/reflect/internal/transform/UnCurry.scala b/src/reflect/scala/reflect/internal/transform/UnCurry.scala index 6dc6a0f7b8..32d3171b26 100644 --- a/src/reflect/scala/reflect/internal/transform/UnCurry.scala +++ b/src/reflect/scala/reflect/internal/transform/UnCurry.scala @@ -10,6 +10,14 @@ trait UnCurry { import global._ import definitions._ + /** Note: changing tp.normalize to tp.dealias in this method leads to a single + * test failure: run/t5688.scala, where instead of the expected output + * Vector(ta, tb, tab) + * we instead get + * Vector(tab, tb, tab) + * I think that difference is not the product of sentience but of randomness. + * Let us figure out why it is and then change this method. + */ private def expandAlias(tp: Type): Type = if (!tp.isHigherKinded) tp.normalize else tp val uncurry: TypeMap = new TypeMap { @@ -60,4 +68,4 @@ trait UnCurry { */ def transformInfo(sym: Symbol, tp: Type): Type = if (sym.isType) uncurryType(tp) else uncurry(tp) -}
\ No newline at end of file +} diff --git a/src/reflect/scala/reflect/internal/util/Position.scala b/src/reflect/scala/reflect/internal/util/Position.scala index 1c29cabe24..f0185372c5 100644 --- a/src/reflect/scala/reflect/internal/util/Position.scala +++ b/src/reflect/scala/reflect/internal/util/Position.scala @@ -91,7 +91,7 @@ abstract class Position extends scala.reflect.api.Position { self => /** An optional value containing the source file referred to by this position, or * None if not defined. */ - def source: SourceFile = throw new UnsupportedOperationException("Position.source") + def source: SourceFile = throw new UnsupportedOperationException(s"Position.source on ${this.getClass}") /** Is this position neither a NoPosition nor a FakePosition? * If isDefined is true, offset and source are both defined. @@ -111,19 +111,19 @@ abstract class Position extends scala.reflect.api.Position { self => def makeTransparent: Position = this /** The start of the position's range, error if not a range position */ - def start: Int = throw new UnsupportedOperationException("Position.start") + def start: Int = throw new UnsupportedOperationException(s"Position.start on ${this.getClass}") /** The start of the position's range, or point if not a range position */ def startOrPoint: Int = point /** The point (where the ^ is) of the position */ - def point: Int = throw new UnsupportedOperationException("Position.point") + def point: Int = throw new UnsupportedOperationException(s"Position.point on ${this.getClass}") /** The point (where the ^ is) of the position, or else `default` if undefined */ def pointOrElse(default: Int): Int = default /** The end of the position's range, error if not a range position */ - def end: Int = throw new UnsupportedOperationException("Position.end") + def end: Int = throw new UnsupportedOperationException(s"Position.end on ${this.getClass}") /** The end of the position's range, or point if not a range position */ def endOrPoint: Int = point diff --git a/src/reflect/scala/reflect/macros/Attachments.scala b/src/reflect/scala/reflect/macros/Attachments.scala index a77cebf415..eeb87fafcc 100644 --- a/src/reflect/scala/reflect/macros/Attachments.scala +++ b/src/reflect/scala/reflect/macros/Attachments.scala @@ -44,17 +44,19 @@ abstract class Attachments { self => * Replaces an existing payload of the same type, if exists. */ def update[T: ClassTag](attachment: T): Attachments { type Pos = self.Pos } = - new NonemptyAttachments(this.pos, remove[T].all + attachment) + new NonemptyAttachments[Pos](this.pos, remove[T].all + attachment) /** Creates a copy of this attachment with the payload of the given class type `T` removed. */ def remove[T: ClassTag]: Attachments { type Pos = self.Pos } = { val newAll = all filterNot matchesTag[T] if (newAll.isEmpty) pos.asInstanceOf[Attachments { type Pos = self.Pos }] - else new NonemptyAttachments(this.pos, newAll) + else new NonemptyAttachments[Pos](this.pos, newAll) } +} - private class NonemptyAttachments(override val pos: Pos, override val all: Set[Any]) extends Attachments { - type Pos = self.Pos - def withPos(newPos: Pos) = new NonemptyAttachments(newPos, all) - } +// SI-7018: This used to be an inner class of `Attachments`, but that led to a memory leak in the +// IDE via $outer pointers. +private final class NonemptyAttachments[P >: Null](override val pos: P, override val all: Set[Any]) extends Attachments { + type Pos = P + def withPos(newPos: Pos) = new NonemptyAttachments(newPos, all) } diff --git a/src/reflect/scala/reflect/macros/Context.scala b/src/reflect/scala/reflect/macros/Context.scala index 1adc6928da..f4a4631e53 100644 --- a/src/reflect/scala/reflect/macros/Context.scala +++ b/src/reflect/scala/reflect/macros/Context.scala @@ -52,7 +52,7 @@ trait Context extends Aliases /** The prefix tree from which the macro is selected. * - * For a example, for a macro `filter` defined as an instance method on a collection `Coll`, + * For example, for a macro `filter` defined as an instance method on a collection `Coll`, * `prefix` represents an equivalent of `this` for normal instance methods: * * {{{ diff --git a/src/reflect/scala/reflect/runtime/JavaMirrors.scala b/src/reflect/scala/reflect/runtime/JavaMirrors.scala index cdb9e7159c..2bffe398f6 100644 --- a/src/reflect/scala/reflect/runtime/JavaMirrors.scala +++ b/src/reflect/scala/reflect/runtime/JavaMirrors.scala @@ -507,7 +507,7 @@ private[reflect] trait JavaMirrors extends internal.SymbolTable with api.JavaUni def erasure = symbol.moduleClass.asClass def isStatic = true def instance = { - if (symbol.owner.isPackageClass) + if (symbol.isTopLevel) staticSingletonInstance(classLoader, symbol.fullName) else if (outer == null) staticSingletonInstance(classToJava(symbol.moduleClass.asClass)) @@ -1156,11 +1156,11 @@ private[reflect] trait JavaMirrors extends internal.SymbolTable with api.JavaUni valueClassToJavaType(clazz) else if (clazz == ArrayClass) noClass - else if (clazz.owner.isPackageClass) + else if (clazz.isTopLevel) javaClass(clazz.javaClassName) else if (clazz.owner.isClass) { val childOfClass = !clazz.owner.isModuleClass - val childOfTopLevel = clazz.owner.owner.isPackageClass + val childOfTopLevel = clazz.owner.isTopLevel val childOfTopLevelObject = clazz.owner.isModuleClass && childOfTopLevel // suggested in https://issues.scala-lang.org/browse/SI-4023?focusedCommentId=54759#comment-54759 diff --git a/src/scalap/scala/tools/scalap/Main.scala b/src/scalap/scala/tools/scalap/Main.scala index 7c84279699..90f8cb8d71 100644 --- a/src/scalap/scala/tools/scalap/Main.scala +++ b/src/scalap/scala/tools/scalap/Main.scala @@ -184,7 +184,7 @@ object Main extends Main { val cparg = List("-classpath", "-cp") map (arguments getArgument _) reduceLeft (_ orElse _) val path = cparg match { case Some(cp) => new JavaClassPath(DefaultJavaContext.classesInExpandedPath(cp), DefaultJavaContext) - case _ => PathResolver.fromPathString("") + case _ => PathResolver.fromPathString(".") // include '.' in the default classpath SI-6669 } // print the classpath if output is verbose if (verbose) diff --git a/test/benchmarking/t6726-patmat-analysis.scala b/test/benchmarking/t6726-patmat-analysis.scala new file mode 100644 index 0000000000..bcb7f6c6b2 --- /dev/null +++ b/test/benchmarking/t6726-patmat-analysis.scala @@ -0,0 +1,4005 @@ +trait Foo{ +abstract class Base +case class Dummy0(x: Int) extends Base +case class Dummy1(x: Int) extends Base +case class Dummy2(x: Int) extends Base +case class Dummy3(x: Int) extends Base +case class Dummy4(x: Int) extends Base +case class Dummy5(x: Int) extends Base +case class Dummy6(x: Int) extends Base +case class Dummy7(x: Int) extends Base +case class Dummy8(x: Int) extends Base +case class Dummy9(x: Int) extends Base +case class Dummy10(x: Int) extends Base +case class Dummy11(x: Int) extends Base +case class Dummy12(x: Int) extends Base +case class Dummy13(x: Int) extends Base +case class Dummy14(x: Int) extends Base +case class Dummy15(x: Int) extends Base +case class Dummy16(x: Int) extends Base +case class Dummy17(x: Int) extends Base +case class Dummy18(x: Int) extends Base +case class Dummy19(x: Int) extends Base +case class Dummy20(x: Int) extends Base +case class Dummy21(x: Int) extends Base +case class Dummy22(x: Int) extends Base +case class Dummy23(x: Int) extends Base +case class Dummy24(x: Int) extends Base +case class Dummy25(x: Int) extends Base +case class Dummy26(x: Int) extends Base +case class Dummy27(x: Int) extends Base +case class Dummy28(x: Int) extends Base +case class Dummy29(x: Int) extends Base +case class Dummy30(x: Int) extends Base +case class Dummy31(x: Int) extends Base +case class Dummy32(x: Int) extends Base +case class Dummy33(x: Int) extends Base +case class Dummy34(x: Int) extends Base +case class Dummy35(x: Int) extends Base +case class Dummy36(x: Int) extends Base +case class Dummy37(x: Int) extends Base +case class Dummy38(x: Int) extends Base +case class Dummy39(x: Int) extends Base +case class Dummy40(x: Int) extends Base +case class Dummy41(x: Int) extends Base +case class Dummy42(x: Int) extends Base +case class Dummy43(x: Int) extends Base +case class Dummy44(x: Int) extends Base +case class Dummy45(x: Int) extends Base +case class Dummy46(x: Int) extends Base +case class Dummy47(x: Int) extends Base +case class Dummy48(x: Int) extends Base +case class Dummy49(x: Int) extends Base +case class Dummy50(x: Int) extends Base +case class Dummy51(x: Int) extends Base +case class Dummy52(x: Int) extends Base +case class Dummy53(x: Int) extends Base +case class Dummy54(x: Int) extends Base +case class Dummy55(x: Int) extends Base +case class Dummy56(x: Int) extends Base +case class Dummy57(x: Int) extends Base +case class Dummy58(x: Int) extends Base +case class Dummy59(x: Int) extends Base +case class Dummy60(x: Int) extends Base +case class Dummy61(x: Int) extends Base +case class Dummy62(x: Int) extends Base +case class Dummy63(x: Int) extends Base +case class Dummy64(x: Int) extends Base +case class Dummy65(x: Int) extends Base +case class Dummy66(x: Int) extends Base +case class Dummy67(x: Int) extends Base +case class Dummy68(x: Int) extends Base +case class Dummy69(x: Int) extends Base +case class Dummy70(x: Int) extends Base +case class Dummy71(x: Int) extends Base +case class Dummy72(x: Int) extends Base +case class Dummy73(x: Int) extends Base +case class Dummy74(x: Int) extends Base +case class Dummy75(x: Int) extends Base +case class Dummy76(x: Int) extends Base +case class Dummy77(x: Int) extends Base +case class Dummy78(x: Int) extends Base +case class Dummy79(x: Int) extends Base +case class Dummy80(x: Int) extends Base +case class Dummy81(x: Int) extends Base +case class Dummy82(x: Int) extends Base +case class Dummy83(x: Int) extends Base +case class Dummy84(x: Int) extends Base +case class Dummy85(x: Int) extends Base +case class Dummy86(x: Int) extends Base +case class Dummy87(x: Int) extends Base +case class Dummy88(x: Int) extends Base +case class Dummy89(x: Int) extends Base +case class Dummy90(x: Int) extends Base +case class Dummy91(x: Int) extends Base +case class Dummy92(x: Int) extends Base +case class Dummy93(x: Int) extends Base +case class Dummy94(x: Int) extends Base +case class Dummy95(x: Int) extends Base +case class Dummy96(x: Int) extends Base +case class Dummy97(x: Int) extends Base +case class Dummy98(x: Int) extends Base +case class Dummy99(x: Int) extends Base +case class Dummy100(x: Int) extends Base +case class Dummy101(x: Int) extends Base +case class Dummy102(x: Int) extends Base +case class Dummy103(x: Int) extends Base +case class Dummy104(x: Int) extends Base +case class Dummy105(x: Int) extends Base +case class Dummy106(x: Int) extends Base +case class Dummy107(x: Int) extends Base +case class Dummy108(x: Int) extends Base +case class Dummy109(x: Int) extends Base +case class Dummy110(x: Int) extends Base +case class Dummy111(x: Int) extends Base +case class Dummy112(x: Int) extends Base +case class Dummy113(x: Int) extends Base +case class Dummy114(x: Int) extends Base +case class Dummy115(x: Int) extends Base +case class Dummy116(x: Int) extends Base +case class Dummy117(x: Int) extends Base +case class Dummy118(x: Int) extends Base +case class Dummy119(x: Int) extends Base +case class Dummy120(x: Int) extends Base +case class Dummy121(x: Int) extends Base +case class Dummy122(x: Int) extends Base +case class Dummy123(x: Int) extends Base +case class Dummy124(x: Int) extends Base +case class Dummy125(x: Int) extends Base +case class Dummy126(x: Int) extends Base +case class Dummy127(x: Int) extends Base +case class Dummy128(x: Int) extends Base +case class Dummy129(x: Int) extends Base +case class Dummy130(x: Int) extends Base +case class Dummy131(x: Int) extends Base +case class Dummy132(x: Int) extends Base +case class Dummy133(x: Int) extends Base +case class Dummy134(x: Int) extends Base +case class Dummy135(x: Int) extends Base +case class Dummy136(x: Int) extends Base +case class Dummy137(x: Int) extends Base +case class Dummy138(x: Int) extends Base +case class Dummy139(x: Int) extends Base +case class Dummy140(x: Int) extends Base +case class Dummy141(x: Int) extends Base +case class Dummy142(x: Int) extends Base +case class Dummy143(x: Int) extends Base +case class Dummy144(x: Int) extends Base +case class Dummy145(x: Int) extends Base +case class Dummy146(x: Int) extends Base +case class Dummy147(x: Int) extends Base +case class Dummy148(x: Int) extends Base +case class Dummy149(x: Int) extends Base +case class Dummy150(x: Int) extends Base +case class Dummy151(x: Int) extends Base +case class Dummy152(x: Int) extends Base +case class Dummy153(x: Int) extends Base +case class Dummy154(x: Int) extends Base +case class Dummy155(x: Int) extends Base +case class Dummy156(x: Int) extends Base +case class Dummy157(x: Int) extends Base +case class Dummy158(x: Int) extends Base +case class Dummy159(x: Int) extends Base +case class Dummy160(x: Int) extends Base +case class Dummy161(x: Int) extends Base +case class Dummy162(x: Int) extends Base +case class Dummy163(x: Int) extends Base +case class Dummy164(x: Int) extends Base +case class Dummy165(x: Int) extends Base +case class Dummy166(x: Int) extends Base +case class Dummy167(x: Int) extends Base +case class Dummy168(x: Int) extends Base +case class Dummy169(x: Int) extends Base +case class Dummy170(x: Int) extends Base +case class Dummy171(x: Int) extends Base +case class Dummy172(x: Int) extends Base +case class Dummy173(x: Int) extends Base +case class Dummy174(x: Int) extends Base +case class Dummy175(x: Int) extends Base +case class Dummy176(x: Int) extends Base +case class Dummy177(x: Int) extends Base +case class Dummy178(x: Int) extends Base +case class Dummy179(x: Int) extends Base +case class Dummy180(x: Int) extends Base +case class Dummy181(x: Int) extends Base +case class Dummy182(x: Int) extends Base +case class Dummy183(x: Int) extends Base +case class Dummy184(x: Int) extends Base +case class Dummy185(x: Int) extends Base +case class Dummy186(x: Int) extends Base +case class Dummy187(x: Int) extends Base +case class Dummy188(x: Int) extends Base +case class Dummy189(x: Int) extends Base +case class Dummy190(x: Int) extends Base +case class Dummy191(x: Int) extends Base +case class Dummy192(x: Int) extends Base +case class Dummy193(x: Int) extends Base +case class Dummy194(x: Int) extends Base +case class Dummy195(x: Int) extends Base +case class Dummy196(x: Int) extends Base +case class Dummy197(x: Int) extends Base +case class Dummy198(x: Int) extends Base +case class Dummy199(x: Int) extends Base +case class Dummy200(x: Int) extends Base +case class Dummy201(x: Int) extends Base +case class Dummy202(x: Int) extends Base +case class Dummy203(x: Int) extends Base +case class Dummy204(x: Int) extends Base +case class Dummy205(x: Int) extends Base +case class Dummy206(x: Int) extends Base +case class Dummy207(x: Int) extends Base +case class Dummy208(x: Int) extends Base +case class Dummy209(x: Int) extends Base +case class Dummy210(x: Int) extends Base +case class Dummy211(x: Int) extends Base +case class Dummy212(x: Int) extends Base +case class Dummy213(x: Int) extends Base +case class Dummy214(x: Int) extends Base +case class Dummy215(x: Int) extends Base +case class Dummy216(x: Int) extends Base +case class Dummy217(x: Int) extends Base +case class Dummy218(x: Int) extends Base +case class Dummy219(x: Int) extends Base +case class Dummy220(x: Int) extends Base +case class Dummy221(x: Int) extends Base +case class Dummy222(x: Int) extends Base +case class Dummy223(x: Int) extends Base +case class Dummy224(x: Int) extends Base +case class Dummy225(x: Int) extends Base +case class Dummy226(x: Int) extends Base +case class Dummy227(x: Int) extends Base +case class Dummy228(x: Int) extends Base +case class Dummy229(x: Int) extends Base +case class Dummy230(x: Int) extends Base +case class Dummy231(x: Int) extends Base +case class Dummy232(x: Int) extends Base +case class Dummy233(x: Int) extends Base +case class Dummy234(x: Int) extends Base +case class Dummy235(x: Int) extends Base +case class Dummy236(x: Int) extends Base +case class Dummy237(x: Int) extends Base +case class Dummy238(x: Int) extends Base +case class Dummy239(x: Int) extends Base +case class Dummy240(x: Int) extends Base +case class Dummy241(x: Int) extends Base +case class Dummy242(x: Int) extends Base +case class Dummy243(x: Int) extends Base +case class Dummy244(x: Int) extends Base +case class Dummy245(x: Int) extends Base +case class Dummy246(x: Int) extends Base +case class Dummy247(x: Int) extends Base +case class Dummy248(x: Int) extends Base +case class Dummy249(x: Int) extends Base +case class Dummy250(x: Int) extends Base +case class Dummy251(x: Int) extends Base +case class Dummy252(x: Int) extends Base +case class Dummy253(x: Int) extends Base +case class Dummy254(x: Int) extends Base +case class Dummy255(x: Int) extends Base +case class Dummy256(x: Int) extends Base +case class Dummy257(x: Int) extends Base +case class Dummy258(x: Int) extends Base +case class Dummy259(x: Int) extends Base +case class Dummy260(x: Int) extends Base +case class Dummy261(x: Int) extends Base +case class Dummy262(x: Int) extends Base +case class Dummy263(x: Int) extends Base +case class Dummy264(x: Int) extends Base +case class Dummy265(x: Int) extends Base +case class Dummy266(x: Int) extends Base +case class Dummy267(x: Int) extends Base +case class Dummy268(x: Int) extends Base +case class Dummy269(x: Int) extends Base +case class Dummy270(x: Int) extends Base +case class Dummy271(x: Int) extends Base +case class Dummy272(x: Int) extends Base +case class Dummy273(x: Int) extends Base +case class Dummy274(x: Int) extends Base +case class Dummy275(x: Int) extends Base +case class Dummy276(x: Int) extends Base +case class Dummy277(x: Int) extends Base +case class Dummy278(x: Int) extends Base +case class Dummy279(x: Int) extends Base +case class Dummy280(x: Int) extends Base +case class Dummy281(x: Int) extends Base +case class Dummy282(x: Int) extends Base +case class Dummy283(x: Int) extends Base +case class Dummy284(x: Int) extends Base +case class Dummy285(x: Int) extends Base +case class Dummy286(x: Int) extends Base +case class Dummy287(x: Int) extends Base +case class Dummy288(x: Int) extends Base +case class Dummy289(x: Int) extends Base +case class Dummy290(x: Int) extends Base +case class Dummy291(x: Int) extends Base +case class Dummy292(x: Int) extends Base +case class Dummy293(x: Int) extends Base +case class Dummy294(x: Int) extends Base +case class Dummy295(x: Int) extends Base +case class Dummy296(x: Int) extends Base +case class Dummy297(x: Int) extends Base +case class Dummy298(x: Int) extends Base +case class Dummy299(x: Int) extends Base +case class Dummy300(x: Int) extends Base +case class Dummy301(x: Int) extends Base +case class Dummy302(x: Int) extends Base +case class Dummy303(x: Int) extends Base +case class Dummy304(x: Int) extends Base +case class Dummy305(x: Int) extends Base +case class Dummy306(x: Int) extends Base +case class Dummy307(x: Int) extends Base +case class Dummy308(x: Int) extends Base +case class Dummy309(x: Int) extends Base +case class Dummy310(x: Int) extends Base +case class Dummy311(x: Int) extends Base +case class Dummy312(x: Int) extends Base +case class Dummy313(x: Int) extends Base +case class Dummy314(x: Int) extends Base +case class Dummy315(x: Int) extends Base +case class Dummy316(x: Int) extends Base +case class Dummy317(x: Int) extends Base +case class Dummy318(x: Int) extends Base +case class Dummy319(x: Int) extends Base +case class Dummy320(x: Int) extends Base +case class Dummy321(x: Int) extends Base +case class Dummy322(x: Int) extends Base +case class Dummy323(x: Int) extends Base +case class Dummy324(x: Int) extends Base +case class Dummy325(x: Int) extends Base +case class Dummy326(x: Int) extends Base +case class Dummy327(x: Int) extends Base +case class Dummy328(x: Int) extends Base +case class Dummy329(x: Int) extends Base +case class Dummy330(x: Int) extends Base +case class Dummy331(x: Int) extends Base +case class Dummy332(x: Int) extends Base +case class Dummy333(x: Int) extends Base +case class Dummy334(x: Int) extends Base +case class Dummy335(x: Int) extends Base +case class Dummy336(x: Int) extends Base +case class Dummy337(x: Int) extends Base +case class Dummy338(x: Int) extends Base +case class Dummy339(x: Int) extends Base +case class Dummy340(x: Int) extends Base +case class Dummy341(x: Int) extends Base +case class Dummy342(x: Int) extends Base +case class Dummy343(x: Int) extends Base +case class Dummy344(x: Int) extends Base +case class Dummy345(x: Int) extends Base +case class Dummy346(x: Int) extends Base +case class Dummy347(x: Int) extends Base +case class Dummy348(x: Int) extends Base +case class Dummy349(x: Int) extends Base +case class Dummy350(x: Int) extends Base +case class Dummy351(x: Int) extends Base +case class Dummy352(x: Int) extends Base +case class Dummy353(x: Int) extends Base +case class Dummy354(x: Int) extends Base +case class Dummy355(x: Int) extends Base +case class Dummy356(x: Int) extends Base +case class Dummy357(x: Int) extends Base +case class Dummy358(x: Int) extends Base +case class Dummy359(x: Int) extends Base +case class Dummy360(x: Int) extends Base +case class Dummy361(x: Int) extends Base +case class Dummy362(x: Int) extends Base +case class Dummy363(x: Int) extends Base +case class Dummy364(x: Int) extends Base +case class Dummy365(x: Int) extends Base +case class Dummy366(x: Int) extends Base +case class Dummy367(x: Int) extends Base +case class Dummy368(x: Int) extends Base +case class Dummy369(x: Int) extends Base +case class Dummy370(x: Int) extends Base +case class Dummy371(x: Int) extends Base +case class Dummy372(x: Int) extends Base +case class Dummy373(x: Int) extends Base +case class Dummy374(x: Int) extends Base +case class Dummy375(x: Int) extends Base +case class Dummy376(x: Int) extends Base +case class Dummy377(x: Int) extends Base +case class Dummy378(x: Int) extends Base +case class Dummy379(x: Int) extends Base +case class Dummy380(x: Int) extends Base +case class Dummy381(x: Int) extends Base +case class Dummy382(x: Int) extends Base +case class Dummy383(x: Int) extends Base +case class Dummy384(x: Int) extends Base +case class Dummy385(x: Int) extends Base +case class Dummy386(x: Int) extends Base +case class Dummy387(x: Int) extends Base +case class Dummy388(x: Int) extends Base +case class Dummy389(x: Int) extends Base +case class Dummy390(x: Int) extends Base +case class Dummy391(x: Int) extends Base +case class Dummy392(x: Int) extends Base +case class Dummy393(x: Int) extends Base +case class Dummy394(x: Int) extends Base +case class Dummy395(x: Int) extends Base +case class Dummy396(x: Int) extends Base +case class Dummy397(x: Int) extends Base +case class Dummy398(x: Int) extends Base +case class Dummy399(x: Int) extends Base +case class Dummy400(x: Int) extends Base +case class Dummy401(x: Int) extends Base +case class Dummy402(x: Int) extends Base +case class Dummy403(x: Int) extends Base +case class Dummy404(x: Int) extends Base +case class Dummy405(x: Int) extends Base +case class Dummy406(x: Int) extends Base +case class Dummy407(x: Int) extends Base +case class Dummy408(x: Int) extends Base +case class Dummy409(x: Int) extends Base +case class Dummy410(x: Int) extends Base +case class Dummy411(x: Int) extends Base +case class Dummy412(x: Int) extends Base +case class Dummy413(x: Int) extends Base +case class Dummy414(x: Int) extends Base +case class Dummy415(x: Int) extends Base +case class Dummy416(x: Int) extends Base +case class Dummy417(x: Int) extends Base +case class Dummy418(x: Int) extends Base +case class Dummy419(x: Int) extends Base +case class Dummy420(x: Int) extends Base +case class Dummy421(x: Int) extends Base +case class Dummy422(x: Int) extends Base +case class Dummy423(x: Int) extends Base +case class Dummy424(x: Int) extends Base +case class Dummy425(x: Int) extends Base +case class Dummy426(x: Int) extends Base +case class Dummy427(x: Int) extends Base +case class Dummy428(x: Int) extends Base +case class Dummy429(x: Int) extends Base +case class Dummy430(x: Int) extends Base +case class Dummy431(x: Int) extends Base +case class Dummy432(x: Int) extends Base +case class Dummy433(x: Int) extends Base +case class Dummy434(x: Int) extends Base +case class Dummy435(x: Int) extends Base +case class Dummy436(x: Int) extends Base +case class Dummy437(x: Int) extends Base +case class Dummy438(x: Int) extends Base +case class Dummy439(x: Int) extends Base +case class Dummy440(x: Int) extends Base +case class Dummy441(x: Int) extends Base +case class Dummy442(x: Int) extends Base +case class Dummy443(x: Int) extends Base +case class Dummy444(x: Int) extends Base +case class Dummy445(x: Int) extends Base +case class Dummy446(x: Int) extends Base +case class Dummy447(x: Int) extends Base +case class Dummy448(x: Int) extends Base +case class Dummy449(x: Int) extends Base +case class Dummy450(x: Int) extends Base +case class Dummy451(x: Int) extends Base +case class Dummy452(x: Int) extends Base +case class Dummy453(x: Int) extends Base +case class Dummy454(x: Int) extends Base +case class Dummy455(x: Int) extends Base +case class Dummy456(x: Int) extends Base +case class Dummy457(x: Int) extends Base +case class Dummy458(x: Int) extends Base +case class Dummy459(x: Int) extends Base +case class Dummy460(x: Int) extends Base +case class Dummy461(x: Int) extends Base +case class Dummy462(x: Int) extends Base +case class Dummy463(x: Int) extends Base +case class Dummy464(x: Int) extends Base +case class Dummy465(x: Int) extends Base +case class Dummy466(x: Int) extends Base +case class Dummy467(x: Int) extends Base +case class Dummy468(x: Int) extends Base +case class Dummy469(x: Int) extends Base +case class Dummy470(x: Int) extends Base +case class Dummy471(x: Int) extends Base +case class Dummy472(x: Int) extends Base +case class Dummy473(x: Int) extends Base +case class Dummy474(x: Int) extends Base +case class Dummy475(x: Int) extends Base +case class Dummy476(x: Int) extends Base +case class Dummy477(x: Int) extends Base +case class Dummy478(x: Int) extends Base +case class Dummy479(x: Int) extends Base +case class Dummy480(x: Int) extends Base +case class Dummy481(x: Int) extends Base +case class Dummy482(x: Int) extends Base +case class Dummy483(x: Int) extends Base +case class Dummy484(x: Int) extends Base +case class Dummy485(x: Int) extends Base +case class Dummy486(x: Int) extends Base +case class Dummy487(x: Int) extends Base +case class Dummy488(x: Int) extends Base +case class Dummy489(x: Int) extends Base +case class Dummy490(x: Int) extends Base +case class Dummy491(x: Int) extends Base +case class Dummy492(x: Int) extends Base +case class Dummy493(x: Int) extends Base +case class Dummy494(x: Int) extends Base +case class Dummy495(x: Int) extends Base +case class Dummy496(x: Int) extends Base +case class Dummy497(x: Int) extends Base +case class Dummy498(x: Int) extends Base +case class Dummy499(x: Int) extends Base +case class Dummy500(x: Int) extends Base +case class Dummy501(x: Int) extends Base +case class Dummy502(x: Int) extends Base +case class Dummy503(x: Int) extends Base +case class Dummy504(x: Int) extends Base +case class Dummy505(x: Int) extends Base +case class Dummy506(x: Int) extends Base +case class Dummy507(x: Int) extends Base +case class Dummy508(x: Int) extends Base +case class Dummy509(x: Int) extends Base +case class Dummy510(x: Int) extends Base +case class Dummy511(x: Int) extends Base +case class Dummy512(x: Int) extends Base +case class Dummy513(x: Int) extends Base +case class Dummy514(x: Int) extends Base +case class Dummy515(x: Int) extends Base +case class Dummy516(x: Int) extends Base +case class Dummy517(x: Int) extends Base +case class Dummy518(x: Int) extends Base +case class Dummy519(x: Int) extends Base +case class Dummy520(x: Int) extends Base +case class Dummy521(x: Int) extends Base +case class Dummy522(x: Int) extends Base +case class Dummy523(x: Int) extends Base +case class Dummy524(x: Int) extends Base +case class Dummy525(x: Int) extends Base +case class Dummy526(x: Int) extends Base +case class Dummy527(x: Int) extends Base +case class Dummy528(x: Int) extends Base +case class Dummy529(x: Int) extends Base +case class Dummy530(x: Int) extends Base +case class Dummy531(x: Int) extends Base +case class Dummy532(x: Int) extends Base +case class Dummy533(x: Int) extends Base +case class Dummy534(x: Int) extends Base +case class Dummy535(x: Int) extends Base +case class Dummy536(x: Int) extends Base +case class Dummy537(x: Int) extends Base +case class Dummy538(x: Int) extends Base +case class Dummy539(x: Int) extends Base +case class Dummy540(x: Int) extends Base +case class Dummy541(x: Int) extends Base +case class Dummy542(x: Int) extends Base +case class Dummy543(x: Int) extends Base +case class Dummy544(x: Int) extends Base +case class Dummy545(x: Int) extends Base +case class Dummy546(x: Int) extends Base +case class Dummy547(x: Int) extends Base +case class Dummy548(x: Int) extends Base +case class Dummy549(x: Int) extends Base +case class Dummy550(x: Int) extends Base +case class Dummy551(x: Int) extends Base +case class Dummy552(x: Int) extends Base +case class Dummy553(x: Int) extends Base +case class Dummy554(x: Int) extends Base +case class Dummy555(x: Int) extends Base +case class Dummy556(x: Int) extends Base +case class Dummy557(x: Int) extends Base +case class Dummy558(x: Int) extends Base +case class Dummy559(x: Int) extends Base +case class Dummy560(x: Int) extends Base +case class Dummy561(x: Int) extends Base +case class Dummy562(x: Int) extends Base +case class Dummy563(x: Int) extends Base +case class Dummy564(x: Int) extends Base +case class Dummy565(x: Int) extends Base +case class Dummy566(x: Int) extends Base +case class Dummy567(x: Int) extends Base +case class Dummy568(x: Int) extends Base +case class Dummy569(x: Int) extends Base +case class Dummy570(x: Int) extends Base +case class Dummy571(x: Int) extends Base +case class Dummy572(x: Int) extends Base +case class Dummy573(x: Int) extends Base +case class Dummy574(x: Int) extends Base +case class Dummy575(x: Int) extends Base +case class Dummy576(x: Int) extends Base +case class Dummy577(x: Int) extends Base +case class Dummy578(x: Int) extends Base +case class Dummy579(x: Int) extends Base +case class Dummy580(x: Int) extends Base +case class Dummy581(x: Int) extends Base +case class Dummy582(x: Int) extends Base +case class Dummy583(x: Int) extends Base +case class Dummy584(x: Int) extends Base +case class Dummy585(x: Int) extends Base +case class Dummy586(x: Int) extends Base +case class Dummy587(x: Int) extends Base +case class Dummy588(x: Int) extends Base +case class Dummy589(x: Int) extends Base +case class Dummy590(x: Int) extends Base +case class Dummy591(x: Int) extends Base +case class Dummy592(x: Int) extends Base +case class Dummy593(x: Int) extends Base +case class Dummy594(x: Int) extends Base +case class Dummy595(x: Int) extends Base +case class Dummy596(x: Int) extends Base +case class Dummy597(x: Int) extends Base +case class Dummy598(x: Int) extends Base +case class Dummy599(x: Int) extends Base +case class Dummy600(x: Int) extends Base +case class Dummy601(x: Int) extends Base +case class Dummy602(x: Int) extends Base +case class Dummy603(x: Int) extends Base +case class Dummy604(x: Int) extends Base +case class Dummy605(x: Int) extends Base +case class Dummy606(x: Int) extends Base +case class Dummy607(x: Int) extends Base +case class Dummy608(x: Int) extends Base +case class Dummy609(x: Int) extends Base +case class Dummy610(x: Int) extends Base +case class Dummy611(x: Int) extends Base +case class Dummy612(x: Int) extends Base +case class Dummy613(x: Int) extends Base +case class Dummy614(x: Int) extends Base +case class Dummy615(x: Int) extends Base +case class Dummy616(x: Int) extends Base +case class Dummy617(x: Int) extends Base +case class Dummy618(x: Int) extends Base +case class Dummy619(x: Int) extends Base +case class Dummy620(x: Int) extends Base +case class Dummy621(x: Int) extends Base +case class Dummy622(x: Int) extends Base +case class Dummy623(x: Int) extends Base +case class Dummy624(x: Int) extends Base +case class Dummy625(x: Int) extends Base +case class Dummy626(x: Int) extends Base +case class Dummy627(x: Int) extends Base +case class Dummy628(x: Int) extends Base +case class Dummy629(x: Int) extends Base +case class Dummy630(x: Int) extends Base +case class Dummy631(x: Int) extends Base +case class Dummy632(x: Int) extends Base +case class Dummy633(x: Int) extends Base +case class Dummy634(x: Int) extends Base +case class Dummy635(x: Int) extends Base +case class Dummy636(x: Int) extends Base +case class Dummy637(x: Int) extends Base +case class Dummy638(x: Int) extends Base +case class Dummy639(x: Int) extends Base +case class Dummy640(x: Int) extends Base +case class Dummy641(x: Int) extends Base +case class Dummy642(x: Int) extends Base +case class Dummy643(x: Int) extends Base +case class Dummy644(x: Int) extends Base +case class Dummy645(x: Int) extends Base +case class Dummy646(x: Int) extends Base +case class Dummy647(x: Int) extends Base +case class Dummy648(x: Int) extends Base +case class Dummy649(x: Int) extends Base +case class Dummy650(x: Int) extends Base +case class Dummy651(x: Int) extends Base +case class Dummy652(x: Int) extends Base +case class Dummy653(x: Int) extends Base +case class Dummy654(x: Int) extends Base +case class Dummy655(x: Int) extends Base +case class Dummy656(x: Int) extends Base +case class Dummy657(x: Int) extends Base +case class Dummy658(x: Int) extends Base +case class Dummy659(x: Int) extends Base +case class Dummy660(x: Int) extends Base +case class Dummy661(x: Int) extends Base +case class Dummy662(x: Int) extends Base +case class Dummy663(x: Int) extends Base +case class Dummy664(x: Int) extends Base +case class Dummy665(x: Int) extends Base +case class Dummy666(x: Int) extends Base +case class Dummy667(x: Int) extends Base +case class Dummy668(x: Int) extends Base +case class Dummy669(x: Int) extends Base +case class Dummy670(x: Int) extends Base +case class Dummy671(x: Int) extends Base +case class Dummy672(x: Int) extends Base +case class Dummy673(x: Int) extends Base +case class Dummy674(x: Int) extends Base +case class Dummy675(x: Int) extends Base +case class Dummy676(x: Int) extends Base +case class Dummy677(x: Int) extends Base +case class Dummy678(x: Int) extends Base +case class Dummy679(x: Int) extends Base +case class Dummy680(x: Int) extends Base +case class Dummy681(x: Int) extends Base +case class Dummy682(x: Int) extends Base +case class Dummy683(x: Int) extends Base +case class Dummy684(x: Int) extends Base +case class Dummy685(x: Int) extends Base +case class Dummy686(x: Int) extends Base +case class Dummy687(x: Int) extends Base +case class Dummy688(x: Int) extends Base +case class Dummy689(x: Int) extends Base +case class Dummy690(x: Int) extends Base +case class Dummy691(x: Int) extends Base +case class Dummy692(x: Int) extends Base +case class Dummy693(x: Int) extends Base +case class Dummy694(x: Int) extends Base +case class Dummy695(x: Int) extends Base +case class Dummy696(x: Int) extends Base +case class Dummy697(x: Int) extends Base +case class Dummy698(x: Int) extends Base +case class Dummy699(x: Int) extends Base +case class Dummy700(x: Int) extends Base +case class Dummy701(x: Int) extends Base +case class Dummy702(x: Int) extends Base +case class Dummy703(x: Int) extends Base +case class Dummy704(x: Int) extends Base +case class Dummy705(x: Int) extends Base +case class Dummy706(x: Int) extends Base +case class Dummy707(x: Int) extends Base +case class Dummy708(x: Int) extends Base +case class Dummy709(x: Int) extends Base +case class Dummy710(x: Int) extends Base +case class Dummy711(x: Int) extends Base +case class Dummy712(x: Int) extends Base +case class Dummy713(x: Int) extends Base +case class Dummy714(x: Int) extends Base +case class Dummy715(x: Int) extends Base +case class Dummy716(x: Int) extends Base +case class Dummy717(x: Int) extends Base +case class Dummy718(x: Int) extends Base +case class Dummy719(x: Int) extends Base +case class Dummy720(x: Int) extends Base +case class Dummy721(x: Int) extends Base +case class Dummy722(x: Int) extends Base +case class Dummy723(x: Int) extends Base +case class Dummy724(x: Int) extends Base +case class Dummy725(x: Int) extends Base +case class Dummy726(x: Int) extends Base +case class Dummy727(x: Int) extends Base +case class Dummy728(x: Int) extends Base +case class Dummy729(x: Int) extends Base +case class Dummy730(x: Int) extends Base +case class Dummy731(x: Int) extends Base +case class Dummy732(x: Int) extends Base +case class Dummy733(x: Int) extends Base +case class Dummy734(x: Int) extends Base +case class Dummy735(x: Int) extends Base +case class Dummy736(x: Int) extends Base +case class Dummy737(x: Int) extends Base +case class Dummy738(x: Int) extends Base +case class Dummy739(x: Int) extends Base +case class Dummy740(x: Int) extends Base +case class Dummy741(x: Int) extends Base +case class Dummy742(x: Int) extends Base +case class Dummy743(x: Int) extends Base +case class Dummy744(x: Int) extends Base +case class Dummy745(x: Int) extends Base +case class Dummy746(x: Int) extends Base +case class Dummy747(x: Int) extends Base +case class Dummy748(x: Int) extends Base +case class Dummy749(x: Int) extends Base +case class Dummy750(x: Int) extends Base +case class Dummy751(x: Int) extends Base +case class Dummy752(x: Int) extends Base +case class Dummy753(x: Int) extends Base +case class Dummy754(x: Int) extends Base +case class Dummy755(x: Int) extends Base +case class Dummy756(x: Int) extends Base +case class Dummy757(x: Int) extends Base +case class Dummy758(x: Int) extends Base +case class Dummy759(x: Int) extends Base +case class Dummy760(x: Int) extends Base +case class Dummy761(x: Int) extends Base +case class Dummy762(x: Int) extends Base +case class Dummy763(x: Int) extends Base +case class Dummy764(x: Int) extends Base +case class Dummy765(x: Int) extends Base +case class Dummy766(x: Int) extends Base +case class Dummy767(x: Int) extends Base +case class Dummy768(x: Int) extends Base +case class Dummy769(x: Int) extends Base +case class Dummy770(x: Int) extends Base +case class Dummy771(x: Int) extends Base +case class Dummy772(x: Int) extends Base +case class Dummy773(x: Int) extends Base +case class Dummy774(x: Int) extends Base +case class Dummy775(x: Int) extends Base +case class Dummy776(x: Int) extends Base +case class Dummy777(x: Int) extends Base +case class Dummy778(x: Int) extends Base +case class Dummy779(x: Int) extends Base +case class Dummy780(x: Int) extends Base +case class Dummy781(x: Int) extends Base +case class Dummy782(x: Int) extends Base +case class Dummy783(x: Int) extends Base +case class Dummy784(x: Int) extends Base +case class Dummy785(x: Int) extends Base +case class Dummy786(x: Int) extends Base +case class Dummy787(x: Int) extends Base +case class Dummy788(x: Int) extends Base +case class Dummy789(x: Int) extends Base +case class Dummy790(x: Int) extends Base +case class Dummy791(x: Int) extends Base +case class Dummy792(x: Int) extends Base +case class Dummy793(x: Int) extends Base +case class Dummy794(x: Int) extends Base +case class Dummy795(x: Int) extends Base +case class Dummy796(x: Int) extends Base +case class Dummy797(x: Int) extends Base +case class Dummy798(x: Int) extends Base +case class Dummy799(x: Int) extends Base +case class Dummy800(x: Int) extends Base +case class Dummy801(x: Int) extends Base +case class Dummy802(x: Int) extends Base +case class Dummy803(x: Int) extends Base +case class Dummy804(x: Int) extends Base +case class Dummy805(x: Int) extends Base +case class Dummy806(x: Int) extends Base +case class Dummy807(x: Int) extends Base +case class Dummy808(x: Int) extends Base +case class Dummy809(x: Int) extends Base +case class Dummy810(x: Int) extends Base +case class Dummy811(x: Int) extends Base +case class Dummy812(x: Int) extends Base +case class Dummy813(x: Int) extends Base +case class Dummy814(x: Int) extends Base +case class Dummy815(x: Int) extends Base +case class Dummy816(x: Int) extends Base +case class Dummy817(x: Int) extends Base +case class Dummy818(x: Int) extends Base +case class Dummy819(x: Int) extends Base +case class Dummy820(x: Int) extends Base +case class Dummy821(x: Int) extends Base +case class Dummy822(x: Int) extends Base +case class Dummy823(x: Int) extends Base +case class Dummy824(x: Int) extends Base +case class Dummy825(x: Int) extends Base +case class Dummy826(x: Int) extends Base +case class Dummy827(x: Int) extends Base +case class Dummy828(x: Int) extends Base +case class Dummy829(x: Int) extends Base +case class Dummy830(x: Int) extends Base +case class Dummy831(x: Int) extends Base +case class Dummy832(x: Int) extends Base +case class Dummy833(x: Int) extends Base +case class Dummy834(x: Int) extends Base +case class Dummy835(x: Int) extends Base +case class Dummy836(x: Int) extends Base +case class Dummy837(x: Int) extends Base +case class Dummy838(x: Int) extends Base +case class Dummy839(x: Int) extends Base +case class Dummy840(x: Int) extends Base +case class Dummy841(x: Int) extends Base +case class Dummy842(x: Int) extends Base +case class Dummy843(x: Int) extends Base +case class Dummy844(x: Int) extends Base +case class Dummy845(x: Int) extends Base +case class Dummy846(x: Int) extends Base +case class Dummy847(x: Int) extends Base +case class Dummy848(x: Int) extends Base +case class Dummy849(x: Int) extends Base +case class Dummy850(x: Int) extends Base +case class Dummy851(x: Int) extends Base +case class Dummy852(x: Int) extends Base +case class Dummy853(x: Int) extends Base +case class Dummy854(x: Int) extends Base +case class Dummy855(x: Int) extends Base +case class Dummy856(x: Int) extends Base +case class Dummy857(x: Int) extends Base +case class Dummy858(x: Int) extends Base +case class Dummy859(x: Int) extends Base +case class Dummy860(x: Int) extends Base +case class Dummy861(x: Int) extends Base +case class Dummy862(x: Int) extends Base +case class Dummy863(x: Int) extends Base +case class Dummy864(x: Int) extends Base +case class Dummy865(x: Int) extends Base +case class Dummy866(x: Int) extends Base +case class Dummy867(x: Int) extends Base +case class Dummy868(x: Int) extends Base +case class Dummy869(x: Int) extends Base +case class Dummy870(x: Int) extends Base +case class Dummy871(x: Int) extends Base +case class Dummy872(x: Int) extends Base +case class Dummy873(x: Int) extends Base +case class Dummy874(x: Int) extends Base +case class Dummy875(x: Int) extends Base +case class Dummy876(x: Int) extends Base +case class Dummy877(x: Int) extends Base +case class Dummy878(x: Int) extends Base +case class Dummy879(x: Int) extends Base +case class Dummy880(x: Int) extends Base +case class Dummy881(x: Int) extends Base +case class Dummy882(x: Int) extends Base +case class Dummy883(x: Int) extends Base +case class Dummy884(x: Int) extends Base +case class Dummy885(x: Int) extends Base +case class Dummy886(x: Int) extends Base +case class Dummy887(x: Int) extends Base +case class Dummy888(x: Int) extends Base +case class Dummy889(x: Int) extends Base +case class Dummy890(x: Int) extends Base +case class Dummy891(x: Int) extends Base +case class Dummy892(x: Int) extends Base +case class Dummy893(x: Int) extends Base +case class Dummy894(x: Int) extends Base +case class Dummy895(x: Int) extends Base +case class Dummy896(x: Int) extends Base +case class Dummy897(x: Int) extends Base +case class Dummy898(x: Int) extends Base +case class Dummy899(x: Int) extends Base +case class Dummy900(x: Int) extends Base +case class Dummy901(x: Int) extends Base +case class Dummy902(x: Int) extends Base +case class Dummy903(x: Int) extends Base +case class Dummy904(x: Int) extends Base +case class Dummy905(x: Int) extends Base +case class Dummy906(x: Int) extends Base +case class Dummy907(x: Int) extends Base +case class Dummy908(x: Int) extends Base +case class Dummy909(x: Int) extends Base +case class Dummy910(x: Int) extends Base +case class Dummy911(x: Int) extends Base +case class Dummy912(x: Int) extends Base +case class Dummy913(x: Int) extends Base +case class Dummy914(x: Int) extends Base +case class Dummy915(x: Int) extends Base +case class Dummy916(x: Int) extends Base +case class Dummy917(x: Int) extends Base +case class Dummy918(x: Int) extends Base +case class Dummy919(x: Int) extends Base +case class Dummy920(x: Int) extends Base +case class Dummy921(x: Int) extends Base +case class Dummy922(x: Int) extends Base +case class Dummy923(x: Int) extends Base +case class Dummy924(x: Int) extends Base +case class Dummy925(x: Int) extends Base +case class Dummy926(x: Int) extends Base +case class Dummy927(x: Int) extends Base +case class Dummy928(x: Int) extends Base +case class Dummy929(x: Int) extends Base +case class Dummy930(x: Int) extends Base +case class Dummy931(x: Int) extends Base +case class Dummy932(x: Int) extends Base +case class Dummy933(x: Int) extends Base +case class Dummy934(x: Int) extends Base +case class Dummy935(x: Int) extends Base +case class Dummy936(x: Int) extends Base +case class Dummy937(x: Int) extends Base +case class Dummy938(x: Int) extends Base +case class Dummy939(x: Int) extends Base +case class Dummy940(x: Int) extends Base +case class Dummy941(x: Int) extends Base +case class Dummy942(x: Int) extends Base +case class Dummy943(x: Int) extends Base +case class Dummy944(x: Int) extends Base +case class Dummy945(x: Int) extends Base +case class Dummy946(x: Int) extends Base +case class Dummy947(x: Int) extends Base +case class Dummy948(x: Int) extends Base +case class Dummy949(x: Int) extends Base +case class Dummy950(x: Int) extends Base +case class Dummy951(x: Int) extends Base +case class Dummy952(x: Int) extends Base +case class Dummy953(x: Int) extends Base +case class Dummy954(x: Int) extends Base +case class Dummy955(x: Int) extends Base +case class Dummy956(x: Int) extends Base +case class Dummy957(x: Int) extends Base +case class Dummy958(x: Int) extends Base +case class Dummy959(x: Int) extends Base +case class Dummy960(x: Int) extends Base +case class Dummy961(x: Int) extends Base +case class Dummy962(x: Int) extends Base +case class Dummy963(x: Int) extends Base +case class Dummy964(x: Int) extends Base +case class Dummy965(x: Int) extends Base +case class Dummy966(x: Int) extends Base +case class Dummy967(x: Int) extends Base +case class Dummy968(x: Int) extends Base +case class Dummy969(x: Int) extends Base +case class Dummy970(x: Int) extends Base +case class Dummy971(x: Int) extends Base +case class Dummy972(x: Int) extends Base +case class Dummy973(x: Int) extends Base +case class Dummy974(x: Int) extends Base +case class Dummy975(x: Int) extends Base +case class Dummy976(x: Int) extends Base +case class Dummy977(x: Int) extends Base +case class Dummy978(x: Int) extends Base +case class Dummy979(x: Int) extends Base +case class Dummy980(x: Int) extends Base +case class Dummy981(x: Int) extends Base +case class Dummy982(x: Int) extends Base +case class Dummy983(x: Int) extends Base +case class Dummy984(x: Int) extends Base +case class Dummy985(x: Int) extends Base +case class Dummy986(x: Int) extends Base +case class Dummy987(x: Int) extends Base +case class Dummy988(x: Int) extends Base +case class Dummy989(x: Int) extends Base +case class Dummy990(x: Int) extends Base +case class Dummy991(x: Int) extends Base +case class Dummy992(x: Int) extends Base +case class Dummy993(x: Int) extends Base +case class Dummy994(x: Int) extends Base +case class Dummy995(x: Int) extends Base +case class Dummy996(x: Int) extends Base +case class Dummy997(x: Int) extends Base +case class Dummy998(x: Int) extends Base +case class Dummy999(x: Int) extends Base +case class Dummy1000(x: Int) extends Base +case class Dummy1001(x: Int) extends Base +case class Dummy1002(x: Int) extends Base +case class Dummy1003(x: Int) extends Base +case class Dummy1004(x: Int) extends Base +case class Dummy1005(x: Int) extends Base +case class Dummy1006(x: Int) extends Base +case class Dummy1007(x: Int) extends Base +case class Dummy1008(x: Int) extends Base +case class Dummy1009(x: Int) extends Base +case class Dummy1010(x: Int) extends Base +case class Dummy1011(x: Int) extends Base +case class Dummy1012(x: Int) extends Base +case class Dummy1013(x: Int) extends Base +case class Dummy1014(x: Int) extends Base +case class Dummy1015(x: Int) extends Base +case class Dummy1016(x: Int) extends Base +case class Dummy1017(x: Int) extends Base +case class Dummy1018(x: Int) extends Base +case class Dummy1019(x: Int) extends Base +case class Dummy1020(x: Int) extends Base +case class Dummy1021(x: Int) extends Base +case class Dummy1022(x: Int) extends Base +case class Dummy1023(x: Int) extends Base +case class Dummy1024(x: Int) extends Base +case class Dummy1025(x: Int) extends Base +case class Dummy1026(x: Int) extends Base +case class Dummy1027(x: Int) extends Base +case class Dummy1028(x: Int) extends Base +case class Dummy1029(x: Int) extends Base +case class Dummy1030(x: Int) extends Base +case class Dummy1031(x: Int) extends Base +case class Dummy1032(x: Int) extends Base +case class Dummy1033(x: Int) extends Base +case class Dummy1034(x: Int) extends Base +case class Dummy1035(x: Int) extends Base +case class Dummy1036(x: Int) extends Base +case class Dummy1037(x: Int) extends Base +case class Dummy1038(x: Int) extends Base +case class Dummy1039(x: Int) extends Base +case class Dummy1040(x: Int) extends Base +case class Dummy1041(x: Int) extends Base +case class Dummy1042(x: Int) extends Base +case class Dummy1043(x: Int) extends Base +case class Dummy1044(x: Int) extends Base +case class Dummy1045(x: Int) extends Base +case class Dummy1046(x: Int) extends Base +case class Dummy1047(x: Int) extends Base +case class Dummy1048(x: Int) extends Base +case class Dummy1049(x: Int) extends Base +case class Dummy1050(x: Int) extends Base +case class Dummy1051(x: Int) extends Base +case class Dummy1052(x: Int) extends Base +case class Dummy1053(x: Int) extends Base +case class Dummy1054(x: Int) extends Base +case class Dummy1055(x: Int) extends Base +case class Dummy1056(x: Int) extends Base +case class Dummy1057(x: Int) extends Base +case class Dummy1058(x: Int) extends Base +case class Dummy1059(x: Int) extends Base +case class Dummy1060(x: Int) extends Base +case class Dummy1061(x: Int) extends Base +case class Dummy1062(x: Int) extends Base +case class Dummy1063(x: Int) extends Base +case class Dummy1064(x: Int) extends Base +case class Dummy1065(x: Int) extends Base +case class Dummy1066(x: Int) extends Base +case class Dummy1067(x: Int) extends Base +case class Dummy1068(x: Int) extends Base +case class Dummy1069(x: Int) extends Base +case class Dummy1070(x: Int) extends Base +case class Dummy1071(x: Int) extends Base +case class Dummy1072(x: Int) extends Base +case class Dummy1073(x: Int) extends Base +case class Dummy1074(x: Int) extends Base +case class Dummy1075(x: Int) extends Base +case class Dummy1076(x: Int) extends Base +case class Dummy1077(x: Int) extends Base +case class Dummy1078(x: Int) extends Base +case class Dummy1079(x: Int) extends Base +case class Dummy1080(x: Int) extends Base +case class Dummy1081(x: Int) extends Base +case class Dummy1082(x: Int) extends Base +case class Dummy1083(x: Int) extends Base +case class Dummy1084(x: Int) extends Base +case class Dummy1085(x: Int) extends Base +case class Dummy1086(x: Int) extends Base +case class Dummy1087(x: Int) extends Base +case class Dummy1088(x: Int) extends Base +case class Dummy1089(x: Int) extends Base +case class Dummy1090(x: Int) extends Base +case class Dummy1091(x: Int) extends Base +case class Dummy1092(x: Int) extends Base +case class Dummy1093(x: Int) extends Base +case class Dummy1094(x: Int) extends Base +case class Dummy1095(x: Int) extends Base +case class Dummy1096(x: Int) extends Base +case class Dummy1097(x: Int) extends Base +case class Dummy1098(x: Int) extends Base +case class Dummy1099(x: Int) extends Base +case class Dummy1100(x: Int) extends Base +case class Dummy1101(x: Int) extends Base +case class Dummy1102(x: Int) extends Base +case class Dummy1103(x: Int) extends Base +case class Dummy1104(x: Int) extends Base +case class Dummy1105(x: Int) extends Base +case class Dummy1106(x: Int) extends Base +case class Dummy1107(x: Int) extends Base +case class Dummy1108(x: Int) extends Base +case class Dummy1109(x: Int) extends Base +case class Dummy1110(x: Int) extends Base +case class Dummy1111(x: Int) extends Base +case class Dummy1112(x: Int) extends Base +case class Dummy1113(x: Int) extends Base +case class Dummy1114(x: Int) extends Base +case class Dummy1115(x: Int) extends Base +case class Dummy1116(x: Int) extends Base +case class Dummy1117(x: Int) extends Base +case class Dummy1118(x: Int) extends Base +case class Dummy1119(x: Int) extends Base +case class Dummy1120(x: Int) extends Base +case class Dummy1121(x: Int) extends Base +case class Dummy1122(x: Int) extends Base +case class Dummy1123(x: Int) extends Base +case class Dummy1124(x: Int) extends Base +case class Dummy1125(x: Int) extends Base +case class Dummy1126(x: Int) extends Base +case class Dummy1127(x: Int) extends Base +case class Dummy1128(x: Int) extends Base +case class Dummy1129(x: Int) extends Base +case class Dummy1130(x: Int) extends Base +case class Dummy1131(x: Int) extends Base +case class Dummy1132(x: Int) extends Base +case class Dummy1133(x: Int) extends Base +case class Dummy1134(x: Int) extends Base +case class Dummy1135(x: Int) extends Base +case class Dummy1136(x: Int) extends Base +case class Dummy1137(x: Int) extends Base +case class Dummy1138(x: Int) extends Base +case class Dummy1139(x: Int) extends Base +case class Dummy1140(x: Int) extends Base +case class Dummy1141(x: Int) extends Base +case class Dummy1142(x: Int) extends Base +case class Dummy1143(x: Int) extends Base +case class Dummy1144(x: Int) extends Base +case class Dummy1145(x: Int) extends Base +case class Dummy1146(x: Int) extends Base +case class Dummy1147(x: Int) extends Base +case class Dummy1148(x: Int) extends Base +case class Dummy1149(x: Int) extends Base +case class Dummy1150(x: Int) extends Base +case class Dummy1151(x: Int) extends Base +case class Dummy1152(x: Int) extends Base +case class Dummy1153(x: Int) extends Base +case class Dummy1154(x: Int) extends Base +case class Dummy1155(x: Int) extends Base +case class Dummy1156(x: Int) extends Base +case class Dummy1157(x: Int) extends Base +case class Dummy1158(x: Int) extends Base +case class Dummy1159(x: Int) extends Base +case class Dummy1160(x: Int) extends Base +case class Dummy1161(x: Int) extends Base +case class Dummy1162(x: Int) extends Base +case class Dummy1163(x: Int) extends Base +case class Dummy1164(x: Int) extends Base +case class Dummy1165(x: Int) extends Base +case class Dummy1166(x: Int) extends Base +case class Dummy1167(x: Int) extends Base +case class Dummy1168(x: Int) extends Base +case class Dummy1169(x: Int) extends Base +case class Dummy1170(x: Int) extends Base +case class Dummy1171(x: Int) extends Base +case class Dummy1172(x: Int) extends Base +case class Dummy1173(x: Int) extends Base +case class Dummy1174(x: Int) extends Base +case class Dummy1175(x: Int) extends Base +case class Dummy1176(x: Int) extends Base +case class Dummy1177(x: Int) extends Base +case class Dummy1178(x: Int) extends Base +case class Dummy1179(x: Int) extends Base +case class Dummy1180(x: Int) extends Base +case class Dummy1181(x: Int) extends Base +case class Dummy1182(x: Int) extends Base +case class Dummy1183(x: Int) extends Base +case class Dummy1184(x: Int) extends Base +case class Dummy1185(x: Int) extends Base +case class Dummy1186(x: Int) extends Base +case class Dummy1187(x: Int) extends Base +case class Dummy1188(x: Int) extends Base +case class Dummy1189(x: Int) extends Base +case class Dummy1190(x: Int) extends Base +case class Dummy1191(x: Int) extends Base +case class Dummy1192(x: Int) extends Base +case class Dummy1193(x: Int) extends Base +case class Dummy1194(x: Int) extends Base +case class Dummy1195(x: Int) extends Base +case class Dummy1196(x: Int) extends Base +case class Dummy1197(x: Int) extends Base +case class Dummy1198(x: Int) extends Base +case class Dummy1199(x: Int) extends Base +case class Dummy1200(x: Int) extends Base +case class Dummy1201(x: Int) extends Base +case class Dummy1202(x: Int) extends Base +case class Dummy1203(x: Int) extends Base +case class Dummy1204(x: Int) extends Base +case class Dummy1205(x: Int) extends Base +case class Dummy1206(x: Int) extends Base +case class Dummy1207(x: Int) extends Base +case class Dummy1208(x: Int) extends Base +case class Dummy1209(x: Int) extends Base +case class Dummy1210(x: Int) extends Base +case class Dummy1211(x: Int) extends Base +case class Dummy1212(x: Int) extends Base +case class Dummy1213(x: Int) extends Base +case class Dummy1214(x: Int) extends Base +case class Dummy1215(x: Int) extends Base +case class Dummy1216(x: Int) extends Base +case class Dummy1217(x: Int) extends Base +case class Dummy1218(x: Int) extends Base +case class Dummy1219(x: Int) extends Base +case class Dummy1220(x: Int) extends Base +case class Dummy1221(x: Int) extends Base +case class Dummy1222(x: Int) extends Base +case class Dummy1223(x: Int) extends Base +case class Dummy1224(x: Int) extends Base +case class Dummy1225(x: Int) extends Base +case class Dummy1226(x: Int) extends Base +case class Dummy1227(x: Int) extends Base +case class Dummy1228(x: Int) extends Base +case class Dummy1229(x: Int) extends Base +case class Dummy1230(x: Int) extends Base +case class Dummy1231(x: Int) extends Base +case class Dummy1232(x: Int) extends Base +case class Dummy1233(x: Int) extends Base +case class Dummy1234(x: Int) extends Base +case class Dummy1235(x: Int) extends Base +case class Dummy1236(x: Int) extends Base +case class Dummy1237(x: Int) extends Base +case class Dummy1238(x: Int) extends Base +case class Dummy1239(x: Int) extends Base +case class Dummy1240(x: Int) extends Base +case class Dummy1241(x: Int) extends Base +case class Dummy1242(x: Int) extends Base +case class Dummy1243(x: Int) extends Base +case class Dummy1244(x: Int) extends Base +case class Dummy1245(x: Int) extends Base +case class Dummy1246(x: Int) extends Base +case class Dummy1247(x: Int) extends Base +case class Dummy1248(x: Int) extends Base +case class Dummy1249(x: Int) extends Base +case class Dummy1250(x: Int) extends Base +case class Dummy1251(x: Int) extends Base +case class Dummy1252(x: Int) extends Base +case class Dummy1253(x: Int) extends Base +case class Dummy1254(x: Int) extends Base +case class Dummy1255(x: Int) extends Base +case class Dummy1256(x: Int) extends Base +case class Dummy1257(x: Int) extends Base +case class Dummy1258(x: Int) extends Base +case class Dummy1259(x: Int) extends Base +case class Dummy1260(x: Int) extends Base +case class Dummy1261(x: Int) extends Base +case class Dummy1262(x: Int) extends Base +case class Dummy1263(x: Int) extends Base +case class Dummy1264(x: Int) extends Base +case class Dummy1265(x: Int) extends Base +case class Dummy1266(x: Int) extends Base +case class Dummy1267(x: Int) extends Base +case class Dummy1268(x: Int) extends Base +case class Dummy1269(x: Int) extends Base +case class Dummy1270(x: Int) extends Base +case class Dummy1271(x: Int) extends Base +case class Dummy1272(x: Int) extends Base +case class Dummy1273(x: Int) extends Base +case class Dummy1274(x: Int) extends Base +case class Dummy1275(x: Int) extends Base +case class Dummy1276(x: Int) extends Base +case class Dummy1277(x: Int) extends Base +case class Dummy1278(x: Int) extends Base +case class Dummy1279(x: Int) extends Base +case class Dummy1280(x: Int) extends Base +case class Dummy1281(x: Int) extends Base +case class Dummy1282(x: Int) extends Base +case class Dummy1283(x: Int) extends Base +case class Dummy1284(x: Int) extends Base +case class Dummy1285(x: Int) extends Base +case class Dummy1286(x: Int) extends Base +case class Dummy1287(x: Int) extends Base +case class Dummy1288(x: Int) extends Base +case class Dummy1289(x: Int) extends Base +case class Dummy1290(x: Int) extends Base +case class Dummy1291(x: Int) extends Base +case class Dummy1292(x: Int) extends Base +case class Dummy1293(x: Int) extends Base +case class Dummy1294(x: Int) extends Base +case class Dummy1295(x: Int) extends Base +case class Dummy1296(x: Int) extends Base +case class Dummy1297(x: Int) extends Base +case class Dummy1298(x: Int) extends Base +case class Dummy1299(x: Int) extends Base +case class Dummy1300(x: Int) extends Base +case class Dummy1301(x: Int) extends Base +case class Dummy1302(x: Int) extends Base +case class Dummy1303(x: Int) extends Base +case class Dummy1304(x: Int) extends Base +case class Dummy1305(x: Int) extends Base +case class Dummy1306(x: Int) extends Base +case class Dummy1307(x: Int) extends Base +case class Dummy1308(x: Int) extends Base +case class Dummy1309(x: Int) extends Base +case class Dummy1310(x: Int) extends Base +case class Dummy1311(x: Int) extends Base +case class Dummy1312(x: Int) extends Base +case class Dummy1313(x: Int) extends Base +case class Dummy1314(x: Int) extends Base +case class Dummy1315(x: Int) extends Base +case class Dummy1316(x: Int) extends Base +case class Dummy1317(x: Int) extends Base +case class Dummy1318(x: Int) extends Base +case class Dummy1319(x: Int) extends Base +case class Dummy1320(x: Int) extends Base +case class Dummy1321(x: Int) extends Base +case class Dummy1322(x: Int) extends Base +case class Dummy1323(x: Int) extends Base +case class Dummy1324(x: Int) extends Base +case class Dummy1325(x: Int) extends Base +case class Dummy1326(x: Int) extends Base +case class Dummy1327(x: Int) extends Base +case class Dummy1328(x: Int) extends Base +case class Dummy1329(x: Int) extends Base +case class Dummy1330(x: Int) extends Base +case class Dummy1331(x: Int) extends Base +case class Dummy1332(x: Int) extends Base +case class Dummy1333(x: Int) extends Base +case class Dummy1334(x: Int) extends Base +case class Dummy1335(x: Int) extends Base +case class Dummy1336(x: Int) extends Base +case class Dummy1337(x: Int) extends Base +case class Dummy1338(x: Int) extends Base +case class Dummy1339(x: Int) extends Base +case class Dummy1340(x: Int) extends Base +case class Dummy1341(x: Int) extends Base +case class Dummy1342(x: Int) extends Base +case class Dummy1343(x: Int) extends Base +case class Dummy1344(x: Int) extends Base +case class Dummy1345(x: Int) extends Base +case class Dummy1346(x: Int) extends Base +case class Dummy1347(x: Int) extends Base +case class Dummy1348(x: Int) extends Base +case class Dummy1349(x: Int) extends Base +case class Dummy1350(x: Int) extends Base +case class Dummy1351(x: Int) extends Base +case class Dummy1352(x: Int) extends Base +case class Dummy1353(x: Int) extends Base +case class Dummy1354(x: Int) extends Base +case class Dummy1355(x: Int) extends Base +case class Dummy1356(x: Int) extends Base +case class Dummy1357(x: Int) extends Base +case class Dummy1358(x: Int) extends Base +case class Dummy1359(x: Int) extends Base +case class Dummy1360(x: Int) extends Base +case class Dummy1361(x: Int) extends Base +case class Dummy1362(x: Int) extends Base +case class Dummy1363(x: Int) extends Base +case class Dummy1364(x: Int) extends Base +case class Dummy1365(x: Int) extends Base +case class Dummy1366(x: Int) extends Base +case class Dummy1367(x: Int) extends Base +case class Dummy1368(x: Int) extends Base +case class Dummy1369(x: Int) extends Base +case class Dummy1370(x: Int) extends Base +case class Dummy1371(x: Int) extends Base +case class Dummy1372(x: Int) extends Base +case class Dummy1373(x: Int) extends Base +case class Dummy1374(x: Int) extends Base +case class Dummy1375(x: Int) extends Base +case class Dummy1376(x: Int) extends Base +case class Dummy1377(x: Int) extends Base +case class Dummy1378(x: Int) extends Base +case class Dummy1379(x: Int) extends Base +case class Dummy1380(x: Int) extends Base +case class Dummy1381(x: Int) extends Base +case class Dummy1382(x: Int) extends Base +case class Dummy1383(x: Int) extends Base +case class Dummy1384(x: Int) extends Base +case class Dummy1385(x: Int) extends Base +case class Dummy1386(x: Int) extends Base +case class Dummy1387(x: Int) extends Base +case class Dummy1388(x: Int) extends Base +case class Dummy1389(x: Int) extends Base +case class Dummy1390(x: Int) extends Base +case class Dummy1391(x: Int) extends Base +case class Dummy1392(x: Int) extends Base +case class Dummy1393(x: Int) extends Base +case class Dummy1394(x: Int) extends Base +case class Dummy1395(x: Int) extends Base +case class Dummy1396(x: Int) extends Base +case class Dummy1397(x: Int) extends Base +case class Dummy1398(x: Int) extends Base +case class Dummy1399(x: Int) extends Base +case class Dummy1400(x: Int) extends Base +case class Dummy1401(x: Int) extends Base +case class Dummy1402(x: Int) extends Base +case class Dummy1403(x: Int) extends Base +case class Dummy1404(x: Int) extends Base +case class Dummy1405(x: Int) extends Base +case class Dummy1406(x: Int) extends Base +case class Dummy1407(x: Int) extends Base +case class Dummy1408(x: Int) extends Base +case class Dummy1409(x: Int) extends Base +case class Dummy1410(x: Int) extends Base +case class Dummy1411(x: Int) extends Base +case class Dummy1412(x: Int) extends Base +case class Dummy1413(x: Int) extends Base +case class Dummy1414(x: Int) extends Base +case class Dummy1415(x: Int) extends Base +case class Dummy1416(x: Int) extends Base +case class Dummy1417(x: Int) extends Base +case class Dummy1418(x: Int) extends Base +case class Dummy1419(x: Int) extends Base +case class Dummy1420(x: Int) extends Base +case class Dummy1421(x: Int) extends Base +case class Dummy1422(x: Int) extends Base +case class Dummy1423(x: Int) extends Base +case class Dummy1424(x: Int) extends Base +case class Dummy1425(x: Int) extends Base +case class Dummy1426(x: Int) extends Base +case class Dummy1427(x: Int) extends Base +case class Dummy1428(x: Int) extends Base +case class Dummy1429(x: Int) extends Base +case class Dummy1430(x: Int) extends Base +case class Dummy1431(x: Int) extends Base +case class Dummy1432(x: Int) extends Base +case class Dummy1433(x: Int) extends Base +case class Dummy1434(x: Int) extends Base +case class Dummy1435(x: Int) extends Base +case class Dummy1436(x: Int) extends Base +case class Dummy1437(x: Int) extends Base +case class Dummy1438(x: Int) extends Base +case class Dummy1439(x: Int) extends Base +case class Dummy1440(x: Int) extends Base +case class Dummy1441(x: Int) extends Base +case class Dummy1442(x: Int) extends Base +case class Dummy1443(x: Int) extends Base +case class Dummy1444(x: Int) extends Base +case class Dummy1445(x: Int) extends Base +case class Dummy1446(x: Int) extends Base +case class Dummy1447(x: Int) extends Base +case class Dummy1448(x: Int) extends Base +case class Dummy1449(x: Int) extends Base +case class Dummy1450(x: Int) extends Base +case class Dummy1451(x: Int) extends Base +case class Dummy1452(x: Int) extends Base +case class Dummy1453(x: Int) extends Base +case class Dummy1454(x: Int) extends Base +case class Dummy1455(x: Int) extends Base +case class Dummy1456(x: Int) extends Base +case class Dummy1457(x: Int) extends Base +case class Dummy1458(x: Int) extends Base +case class Dummy1459(x: Int) extends Base +case class Dummy1460(x: Int) extends Base +case class Dummy1461(x: Int) extends Base +case class Dummy1462(x: Int) extends Base +case class Dummy1463(x: Int) extends Base +case class Dummy1464(x: Int) extends Base +case class Dummy1465(x: Int) extends Base +case class Dummy1466(x: Int) extends Base +case class Dummy1467(x: Int) extends Base +case class Dummy1468(x: Int) extends Base +case class Dummy1469(x: Int) extends Base +case class Dummy1470(x: Int) extends Base +case class Dummy1471(x: Int) extends Base +case class Dummy1472(x: Int) extends Base +case class Dummy1473(x: Int) extends Base +case class Dummy1474(x: Int) extends Base +case class Dummy1475(x: Int) extends Base +case class Dummy1476(x: Int) extends Base +case class Dummy1477(x: Int) extends Base +case class Dummy1478(x: Int) extends Base +case class Dummy1479(x: Int) extends Base +case class Dummy1480(x: Int) extends Base +case class Dummy1481(x: Int) extends Base +case class Dummy1482(x: Int) extends Base +case class Dummy1483(x: Int) extends Base +case class Dummy1484(x: Int) extends Base +case class Dummy1485(x: Int) extends Base +case class Dummy1486(x: Int) extends Base +case class Dummy1487(x: Int) extends Base +case class Dummy1488(x: Int) extends Base +case class Dummy1489(x: Int) extends Base +case class Dummy1490(x: Int) extends Base +case class Dummy1491(x: Int) extends Base +case class Dummy1492(x: Int) extends Base +case class Dummy1493(x: Int) extends Base +case class Dummy1494(x: Int) extends Base +case class Dummy1495(x: Int) extends Base +case class Dummy1496(x: Int) extends Base +case class Dummy1497(x: Int) extends Base +case class Dummy1498(x: Int) extends Base +case class Dummy1499(x: Int) extends Base +case class Dummy1500(x: Int) extends Base +case class Dummy1501(x: Int) extends Base +case class Dummy1502(x: Int) extends Base +case class Dummy1503(x: Int) extends Base +case class Dummy1504(x: Int) extends Base +case class Dummy1505(x: Int) extends Base +case class Dummy1506(x: Int) extends Base +case class Dummy1507(x: Int) extends Base +case class Dummy1508(x: Int) extends Base +case class Dummy1509(x: Int) extends Base +case class Dummy1510(x: Int) extends Base +case class Dummy1511(x: Int) extends Base +case class Dummy1512(x: Int) extends Base +case class Dummy1513(x: Int) extends Base +case class Dummy1514(x: Int) extends Base +case class Dummy1515(x: Int) extends Base +case class Dummy1516(x: Int) extends Base +case class Dummy1517(x: Int) extends Base +case class Dummy1518(x: Int) extends Base +case class Dummy1519(x: Int) extends Base +case class Dummy1520(x: Int) extends Base +case class Dummy1521(x: Int) extends Base +case class Dummy1522(x: Int) extends Base +case class Dummy1523(x: Int) extends Base +case class Dummy1524(x: Int) extends Base +case class Dummy1525(x: Int) extends Base +case class Dummy1526(x: Int) extends Base +case class Dummy1527(x: Int) extends Base +case class Dummy1528(x: Int) extends Base +case class Dummy1529(x: Int) extends Base +case class Dummy1530(x: Int) extends Base +case class Dummy1531(x: Int) extends Base +case class Dummy1532(x: Int) extends Base +case class Dummy1533(x: Int) extends Base +case class Dummy1534(x: Int) extends Base +case class Dummy1535(x: Int) extends Base +case class Dummy1536(x: Int) extends Base +case class Dummy1537(x: Int) extends Base +case class Dummy1538(x: Int) extends Base +case class Dummy1539(x: Int) extends Base +case class Dummy1540(x: Int) extends Base +case class Dummy1541(x: Int) extends Base +case class Dummy1542(x: Int) extends Base +case class Dummy1543(x: Int) extends Base +case class Dummy1544(x: Int) extends Base +case class Dummy1545(x: Int) extends Base +case class Dummy1546(x: Int) extends Base +case class Dummy1547(x: Int) extends Base +case class Dummy1548(x: Int) extends Base +case class Dummy1549(x: Int) extends Base +case class Dummy1550(x: Int) extends Base +case class Dummy1551(x: Int) extends Base +case class Dummy1552(x: Int) extends Base +case class Dummy1553(x: Int) extends Base +case class Dummy1554(x: Int) extends Base +case class Dummy1555(x: Int) extends Base +case class Dummy1556(x: Int) extends Base +case class Dummy1557(x: Int) extends Base +case class Dummy1558(x: Int) extends Base +case class Dummy1559(x: Int) extends Base +case class Dummy1560(x: Int) extends Base +case class Dummy1561(x: Int) extends Base +case class Dummy1562(x: Int) extends Base +case class Dummy1563(x: Int) extends Base +case class Dummy1564(x: Int) extends Base +case class Dummy1565(x: Int) extends Base +case class Dummy1566(x: Int) extends Base +case class Dummy1567(x: Int) extends Base +case class Dummy1568(x: Int) extends Base +case class Dummy1569(x: Int) extends Base +case class Dummy1570(x: Int) extends Base +case class Dummy1571(x: Int) extends Base +case class Dummy1572(x: Int) extends Base +case class Dummy1573(x: Int) extends Base +case class Dummy1574(x: Int) extends Base +case class Dummy1575(x: Int) extends Base +case class Dummy1576(x: Int) extends Base +case class Dummy1577(x: Int) extends Base +case class Dummy1578(x: Int) extends Base +case class Dummy1579(x: Int) extends Base +case class Dummy1580(x: Int) extends Base +case class Dummy1581(x: Int) extends Base +case class Dummy1582(x: Int) extends Base +case class Dummy1583(x: Int) extends Base +case class Dummy1584(x: Int) extends Base +case class Dummy1585(x: Int) extends Base +case class Dummy1586(x: Int) extends Base +case class Dummy1587(x: Int) extends Base +case class Dummy1588(x: Int) extends Base +case class Dummy1589(x: Int) extends Base +case class Dummy1590(x: Int) extends Base +case class Dummy1591(x: Int) extends Base +case class Dummy1592(x: Int) extends Base +case class Dummy1593(x: Int) extends Base +case class Dummy1594(x: Int) extends Base +case class Dummy1595(x: Int) extends Base +case class Dummy1596(x: Int) extends Base +case class Dummy1597(x: Int) extends Base +case class Dummy1598(x: Int) extends Base +case class Dummy1599(x: Int) extends Base +case class Dummy1600(x: Int) extends Base +case class Dummy1601(x: Int) extends Base +case class Dummy1602(x: Int) extends Base +case class Dummy1603(x: Int) extends Base +case class Dummy1604(x: Int) extends Base +case class Dummy1605(x: Int) extends Base +case class Dummy1606(x: Int) extends Base +case class Dummy1607(x: Int) extends Base +case class Dummy1608(x: Int) extends Base +case class Dummy1609(x: Int) extends Base +case class Dummy1610(x: Int) extends Base +case class Dummy1611(x: Int) extends Base +case class Dummy1612(x: Int) extends Base +case class Dummy1613(x: Int) extends Base +case class Dummy1614(x: Int) extends Base +case class Dummy1615(x: Int) extends Base +case class Dummy1616(x: Int) extends Base +case class Dummy1617(x: Int) extends Base +case class Dummy1618(x: Int) extends Base +case class Dummy1619(x: Int) extends Base +case class Dummy1620(x: Int) extends Base +case class Dummy1621(x: Int) extends Base +case class Dummy1622(x: Int) extends Base +case class Dummy1623(x: Int) extends Base +case class Dummy1624(x: Int) extends Base +case class Dummy1625(x: Int) extends Base +case class Dummy1626(x: Int) extends Base +case class Dummy1627(x: Int) extends Base +case class Dummy1628(x: Int) extends Base +case class Dummy1629(x: Int) extends Base +case class Dummy1630(x: Int) extends Base +case class Dummy1631(x: Int) extends Base +case class Dummy1632(x: Int) extends Base +case class Dummy1633(x: Int) extends Base +case class Dummy1634(x: Int) extends Base +case class Dummy1635(x: Int) extends Base +case class Dummy1636(x: Int) extends Base +case class Dummy1637(x: Int) extends Base +case class Dummy1638(x: Int) extends Base +case class Dummy1639(x: Int) extends Base +case class Dummy1640(x: Int) extends Base +case class Dummy1641(x: Int) extends Base +case class Dummy1642(x: Int) extends Base +case class Dummy1643(x: Int) extends Base +case class Dummy1644(x: Int) extends Base +case class Dummy1645(x: Int) extends Base +case class Dummy1646(x: Int) extends Base +case class Dummy1647(x: Int) extends Base +case class Dummy1648(x: Int) extends Base +case class Dummy1649(x: Int) extends Base +case class Dummy1650(x: Int) extends Base +case class Dummy1651(x: Int) extends Base +case class Dummy1652(x: Int) extends Base +case class Dummy1653(x: Int) extends Base +case class Dummy1654(x: Int) extends Base +case class Dummy1655(x: Int) extends Base +case class Dummy1656(x: Int) extends Base +case class Dummy1657(x: Int) extends Base +case class Dummy1658(x: Int) extends Base +case class Dummy1659(x: Int) extends Base +case class Dummy1660(x: Int) extends Base +case class Dummy1661(x: Int) extends Base +case class Dummy1662(x: Int) extends Base +case class Dummy1663(x: Int) extends Base +case class Dummy1664(x: Int) extends Base +case class Dummy1665(x: Int) extends Base +case class Dummy1666(x: Int) extends Base +case class Dummy1667(x: Int) extends Base +case class Dummy1668(x: Int) extends Base +case class Dummy1669(x: Int) extends Base +case class Dummy1670(x: Int) extends Base +case class Dummy1671(x: Int) extends Base +case class Dummy1672(x: Int) extends Base +case class Dummy1673(x: Int) extends Base +case class Dummy1674(x: Int) extends Base +case class Dummy1675(x: Int) extends Base +case class Dummy1676(x: Int) extends Base +case class Dummy1677(x: Int) extends Base +case class Dummy1678(x: Int) extends Base +case class Dummy1679(x: Int) extends Base +case class Dummy1680(x: Int) extends Base +case class Dummy1681(x: Int) extends Base +case class Dummy1682(x: Int) extends Base +case class Dummy1683(x: Int) extends Base +case class Dummy1684(x: Int) extends Base +case class Dummy1685(x: Int) extends Base +case class Dummy1686(x: Int) extends Base +case class Dummy1687(x: Int) extends Base +case class Dummy1688(x: Int) extends Base +case class Dummy1689(x: Int) extends Base +case class Dummy1690(x: Int) extends Base +case class Dummy1691(x: Int) extends Base +case class Dummy1692(x: Int) extends Base +case class Dummy1693(x: Int) extends Base +case class Dummy1694(x: Int) extends Base +case class Dummy1695(x: Int) extends Base +case class Dummy1696(x: Int) extends Base +case class Dummy1697(x: Int) extends Base +case class Dummy1698(x: Int) extends Base +case class Dummy1699(x: Int) extends Base +case class Dummy1700(x: Int) extends Base +case class Dummy1701(x: Int) extends Base +case class Dummy1702(x: Int) extends Base +case class Dummy1703(x: Int) extends Base +case class Dummy1704(x: Int) extends Base +case class Dummy1705(x: Int) extends Base +case class Dummy1706(x: Int) extends Base +case class Dummy1707(x: Int) extends Base +case class Dummy1708(x: Int) extends Base +case class Dummy1709(x: Int) extends Base +case class Dummy1710(x: Int) extends Base +case class Dummy1711(x: Int) extends Base +case class Dummy1712(x: Int) extends Base +case class Dummy1713(x: Int) extends Base +case class Dummy1714(x: Int) extends Base +case class Dummy1715(x: Int) extends Base +case class Dummy1716(x: Int) extends Base +case class Dummy1717(x: Int) extends Base +case class Dummy1718(x: Int) extends Base +case class Dummy1719(x: Int) extends Base +case class Dummy1720(x: Int) extends Base +case class Dummy1721(x: Int) extends Base +case class Dummy1722(x: Int) extends Base +case class Dummy1723(x: Int) extends Base +case class Dummy1724(x: Int) extends Base +case class Dummy1725(x: Int) extends Base +case class Dummy1726(x: Int) extends Base +case class Dummy1727(x: Int) extends Base +case class Dummy1728(x: Int) extends Base +case class Dummy1729(x: Int) extends Base +case class Dummy1730(x: Int) extends Base +case class Dummy1731(x: Int) extends Base +case class Dummy1732(x: Int) extends Base +case class Dummy1733(x: Int) extends Base +case class Dummy1734(x: Int) extends Base +case class Dummy1735(x: Int) extends Base +case class Dummy1736(x: Int) extends Base +case class Dummy1737(x: Int) extends Base +case class Dummy1738(x: Int) extends Base +case class Dummy1739(x: Int) extends Base +case class Dummy1740(x: Int) extends Base +case class Dummy1741(x: Int) extends Base +case class Dummy1742(x: Int) extends Base +case class Dummy1743(x: Int) extends Base +case class Dummy1744(x: Int) extends Base +case class Dummy1745(x: Int) extends Base +case class Dummy1746(x: Int) extends Base +case class Dummy1747(x: Int) extends Base +case class Dummy1748(x: Int) extends Base +case class Dummy1749(x: Int) extends Base +case class Dummy1750(x: Int) extends Base +case class Dummy1751(x: Int) extends Base +case class Dummy1752(x: Int) extends Base +case class Dummy1753(x: Int) extends Base +case class Dummy1754(x: Int) extends Base +case class Dummy1755(x: Int) extends Base +case class Dummy1756(x: Int) extends Base +case class Dummy1757(x: Int) extends Base +case class Dummy1758(x: Int) extends Base +case class Dummy1759(x: Int) extends Base +case class Dummy1760(x: Int) extends Base +case class Dummy1761(x: Int) extends Base +case class Dummy1762(x: Int) extends Base +case class Dummy1763(x: Int) extends Base +case class Dummy1764(x: Int) extends Base +case class Dummy1765(x: Int) extends Base +case class Dummy1766(x: Int) extends Base +case class Dummy1767(x: Int) extends Base +case class Dummy1768(x: Int) extends Base +case class Dummy1769(x: Int) extends Base +case class Dummy1770(x: Int) extends Base +case class Dummy1771(x: Int) extends Base +case class Dummy1772(x: Int) extends Base +case class Dummy1773(x: Int) extends Base +case class Dummy1774(x: Int) extends Base +case class Dummy1775(x: Int) extends Base +case class Dummy1776(x: Int) extends Base +case class Dummy1777(x: Int) extends Base +case class Dummy1778(x: Int) extends Base +case class Dummy1779(x: Int) extends Base +case class Dummy1780(x: Int) extends Base +case class Dummy1781(x: Int) extends Base +case class Dummy1782(x: Int) extends Base +case class Dummy1783(x: Int) extends Base +case class Dummy1784(x: Int) extends Base +case class Dummy1785(x: Int) extends Base +case class Dummy1786(x: Int) extends Base +case class Dummy1787(x: Int) extends Base +case class Dummy1788(x: Int) extends Base +case class Dummy1789(x: Int) extends Base +case class Dummy1790(x: Int) extends Base +case class Dummy1791(x: Int) extends Base +case class Dummy1792(x: Int) extends Base +case class Dummy1793(x: Int) extends Base +case class Dummy1794(x: Int) extends Base +case class Dummy1795(x: Int) extends Base +case class Dummy1796(x: Int) extends Base +case class Dummy1797(x: Int) extends Base +case class Dummy1798(x: Int) extends Base +case class Dummy1799(x: Int) extends Base +case class Dummy1800(x: Int) extends Base +case class Dummy1801(x: Int) extends Base +case class Dummy1802(x: Int) extends Base +case class Dummy1803(x: Int) extends Base +case class Dummy1804(x: Int) extends Base +case class Dummy1805(x: Int) extends Base +case class Dummy1806(x: Int) extends Base +case class Dummy1807(x: Int) extends Base +case class Dummy1808(x: Int) extends Base +case class Dummy1809(x: Int) extends Base +case class Dummy1810(x: Int) extends Base +case class Dummy1811(x: Int) extends Base +case class Dummy1812(x: Int) extends Base +case class Dummy1813(x: Int) extends Base +case class Dummy1814(x: Int) extends Base +case class Dummy1815(x: Int) extends Base +case class Dummy1816(x: Int) extends Base +case class Dummy1817(x: Int) extends Base +case class Dummy1818(x: Int) extends Base +case class Dummy1819(x: Int) extends Base +case class Dummy1820(x: Int) extends Base +case class Dummy1821(x: Int) extends Base +case class Dummy1822(x: Int) extends Base +case class Dummy1823(x: Int) extends Base +case class Dummy1824(x: Int) extends Base +case class Dummy1825(x: Int) extends Base +case class Dummy1826(x: Int) extends Base +case class Dummy1827(x: Int) extends Base +case class Dummy1828(x: Int) extends Base +case class Dummy1829(x: Int) extends Base +case class Dummy1830(x: Int) extends Base +case class Dummy1831(x: Int) extends Base +case class Dummy1832(x: Int) extends Base +case class Dummy1833(x: Int) extends Base +case class Dummy1834(x: Int) extends Base +case class Dummy1835(x: Int) extends Base +case class Dummy1836(x: Int) extends Base +case class Dummy1837(x: Int) extends Base +case class Dummy1838(x: Int) extends Base +case class Dummy1839(x: Int) extends Base +case class Dummy1840(x: Int) extends Base +case class Dummy1841(x: Int) extends Base +case class Dummy1842(x: Int) extends Base +case class Dummy1843(x: Int) extends Base +case class Dummy1844(x: Int) extends Base +case class Dummy1845(x: Int) extends Base +case class Dummy1846(x: Int) extends Base +case class Dummy1847(x: Int) extends Base +case class Dummy1848(x: Int) extends Base +case class Dummy1849(x: Int) extends Base +case class Dummy1850(x: Int) extends Base +case class Dummy1851(x: Int) extends Base +case class Dummy1852(x: Int) extends Base +case class Dummy1853(x: Int) extends Base +case class Dummy1854(x: Int) extends Base +case class Dummy1855(x: Int) extends Base +case class Dummy1856(x: Int) extends Base +case class Dummy1857(x: Int) extends Base +case class Dummy1858(x: Int) extends Base +case class Dummy1859(x: Int) extends Base +case class Dummy1860(x: Int) extends Base +case class Dummy1861(x: Int) extends Base +case class Dummy1862(x: Int) extends Base +case class Dummy1863(x: Int) extends Base +case class Dummy1864(x: Int) extends Base +case class Dummy1865(x: Int) extends Base +case class Dummy1866(x: Int) extends Base +case class Dummy1867(x: Int) extends Base +case class Dummy1868(x: Int) extends Base +case class Dummy1869(x: Int) extends Base +case class Dummy1870(x: Int) extends Base +case class Dummy1871(x: Int) extends Base +case class Dummy1872(x: Int) extends Base +case class Dummy1873(x: Int) extends Base +case class Dummy1874(x: Int) extends Base +case class Dummy1875(x: Int) extends Base +case class Dummy1876(x: Int) extends Base +case class Dummy1877(x: Int) extends Base +case class Dummy1878(x: Int) extends Base +case class Dummy1879(x: Int) extends Base +case class Dummy1880(x: Int) extends Base +case class Dummy1881(x: Int) extends Base +case class Dummy1882(x: Int) extends Base +case class Dummy1883(x: Int) extends Base +case class Dummy1884(x: Int) extends Base +case class Dummy1885(x: Int) extends Base +case class Dummy1886(x: Int) extends Base +case class Dummy1887(x: Int) extends Base +case class Dummy1888(x: Int) extends Base +case class Dummy1889(x: Int) extends Base +case class Dummy1890(x: Int) extends Base +case class Dummy1891(x: Int) extends Base +case class Dummy1892(x: Int) extends Base +case class Dummy1893(x: Int) extends Base +case class Dummy1894(x: Int) extends Base +case class Dummy1895(x: Int) extends Base +case class Dummy1896(x: Int) extends Base +case class Dummy1897(x: Int) extends Base +case class Dummy1898(x: Int) extends Base +case class Dummy1899(x: Int) extends Base +case class Dummy1900(x: Int) extends Base +case class Dummy1901(x: Int) extends Base +case class Dummy1902(x: Int) extends Base +case class Dummy1903(x: Int) extends Base +case class Dummy1904(x: Int) extends Base +case class Dummy1905(x: Int) extends Base +case class Dummy1906(x: Int) extends Base +case class Dummy1907(x: Int) extends Base +case class Dummy1908(x: Int) extends Base +case class Dummy1909(x: Int) extends Base +case class Dummy1910(x: Int) extends Base +case class Dummy1911(x: Int) extends Base +case class Dummy1912(x: Int) extends Base +case class Dummy1913(x: Int) extends Base +case class Dummy1914(x: Int) extends Base +case class Dummy1915(x: Int) extends Base +case class Dummy1916(x: Int) extends Base +case class Dummy1917(x: Int) extends Base +case class Dummy1918(x: Int) extends Base +case class Dummy1919(x: Int) extends Base +case class Dummy1920(x: Int) extends Base +case class Dummy1921(x: Int) extends Base +case class Dummy1922(x: Int) extends Base +case class Dummy1923(x: Int) extends Base +case class Dummy1924(x: Int) extends Base +case class Dummy1925(x: Int) extends Base +case class Dummy1926(x: Int) extends Base +case class Dummy1927(x: Int) extends Base +case class Dummy1928(x: Int) extends Base +case class Dummy1929(x: Int) extends Base +case class Dummy1930(x: Int) extends Base +case class Dummy1931(x: Int) extends Base +case class Dummy1932(x: Int) extends Base +case class Dummy1933(x: Int) extends Base +case class Dummy1934(x: Int) extends Base +case class Dummy1935(x: Int) extends Base +case class Dummy1936(x: Int) extends Base +case class Dummy1937(x: Int) extends Base +case class Dummy1938(x: Int) extends Base +case class Dummy1939(x: Int) extends Base +case class Dummy1940(x: Int) extends Base +case class Dummy1941(x: Int) extends Base +case class Dummy1942(x: Int) extends Base +case class Dummy1943(x: Int) extends Base +case class Dummy1944(x: Int) extends Base +case class Dummy1945(x: Int) extends Base +case class Dummy1946(x: Int) extends Base +case class Dummy1947(x: Int) extends Base +case class Dummy1948(x: Int) extends Base +case class Dummy1949(x: Int) extends Base +case class Dummy1950(x: Int) extends Base +case class Dummy1951(x: Int) extends Base +case class Dummy1952(x: Int) extends Base +case class Dummy1953(x: Int) extends Base +case class Dummy1954(x: Int) extends Base +case class Dummy1955(x: Int) extends Base +case class Dummy1956(x: Int) extends Base +case class Dummy1957(x: Int) extends Base +case class Dummy1958(x: Int) extends Base +case class Dummy1959(x: Int) extends Base +case class Dummy1960(x: Int) extends Base +case class Dummy1961(x: Int) extends Base +case class Dummy1962(x: Int) extends Base +case class Dummy1963(x: Int) extends Base +case class Dummy1964(x: Int) extends Base +case class Dummy1965(x: Int) extends Base +case class Dummy1966(x: Int) extends Base +case class Dummy1967(x: Int) extends Base +case class Dummy1968(x: Int) extends Base +case class Dummy1969(x: Int) extends Base +case class Dummy1970(x: Int) extends Base +case class Dummy1971(x: Int) extends Base +case class Dummy1972(x: Int) extends Base +case class Dummy1973(x: Int) extends Base +case class Dummy1974(x: Int) extends Base +case class Dummy1975(x: Int) extends Base +case class Dummy1976(x: Int) extends Base +case class Dummy1977(x: Int) extends Base +case class Dummy1978(x: Int) extends Base +case class Dummy1979(x: Int) extends Base +case class Dummy1980(x: Int) extends Base +case class Dummy1981(x: Int) extends Base +case class Dummy1982(x: Int) extends Base +case class Dummy1983(x: Int) extends Base +case class Dummy1984(x: Int) extends Base +case class Dummy1985(x: Int) extends Base +case class Dummy1986(x: Int) extends Base +case class Dummy1987(x: Int) extends Base +case class Dummy1988(x: Int) extends Base +case class Dummy1989(x: Int) extends Base +case class Dummy1990(x: Int) extends Base +case class Dummy1991(x: Int) extends Base +case class Dummy1992(x: Int) extends Base +case class Dummy1993(x: Int) extends Base +case class Dummy1994(x: Int) extends Base +case class Dummy1995(x: Int) extends Base +case class Dummy1996(x: Int) extends Base +case class Dummy1997(x: Int) extends Base +case class Dummy1998(x: Int) extends Base +case class Dummy1999(x: Int) extends Base +def test(y: Base) = y match { + case Dummy0(p) => p + case Dummy1(p) => p + case Dummy2(p) => p + case Dummy3(p) => p + case Dummy4(p) => p + case Dummy5(p) => p + case Dummy6(p) => p + case Dummy7(p) => p + case Dummy8(p) => p + case Dummy9(p) => p + case Dummy10(p) => p + case Dummy11(p) => p + case Dummy12(p) => p + case Dummy13(p) => p + case Dummy14(p) => p + case Dummy15(p) => p + case Dummy16(p) => p + case Dummy17(p) => p + case Dummy18(p) => p + case Dummy19(p) => p + case Dummy20(p) => p + case Dummy21(p) => p + case Dummy22(p) => p + case Dummy23(p) => p + case Dummy24(p) => p + case Dummy25(p) => p + case Dummy26(p) => p + case Dummy27(p) => p + case Dummy28(p) => p + case Dummy29(p) => p + case Dummy30(p) => p + case Dummy31(p) => p + case Dummy32(p) => p + case Dummy33(p) => p + case Dummy34(p) => p + case Dummy35(p) => p + case Dummy36(p) => p + case Dummy37(p) => p + case Dummy38(p) => p + case Dummy39(p) => p + case Dummy40(p) => p + case Dummy41(p) => p + case Dummy42(p) => p + case Dummy43(p) => p + case Dummy44(p) => p + case Dummy45(p) => p + case Dummy46(p) => p + case Dummy47(p) => p + case Dummy48(p) => p + case Dummy49(p) => p + case Dummy50(p) => p + case Dummy51(p) => p + case Dummy52(p) => p + case Dummy53(p) => p + case Dummy54(p) => p + case Dummy55(p) => p + case Dummy56(p) => p + case Dummy57(p) => p + case Dummy58(p) => p + case Dummy59(p) => p + case Dummy60(p) => p + case Dummy61(p) => p + case Dummy62(p) => p + case Dummy63(p) => p + case Dummy64(p) => p + case Dummy65(p) => p + case Dummy66(p) => p + case Dummy67(p) => p + case Dummy68(p) => p + case Dummy69(p) => p + case Dummy70(p) => p + case Dummy71(p) => p + case Dummy72(p) => p + case Dummy73(p) => p + case Dummy74(p) => p + case Dummy75(p) => p + case Dummy76(p) => p + case Dummy77(p) => p + case Dummy78(p) => p + case Dummy79(p) => p + case Dummy80(p) => p + case Dummy81(p) => p + case Dummy82(p) => p + case Dummy83(p) => p + case Dummy84(p) => p + case Dummy85(p) => p + case Dummy86(p) => p + case Dummy87(p) => p + case Dummy88(p) => p + case Dummy89(p) => p + case Dummy90(p) => p + case Dummy91(p) => p + case Dummy92(p) => p + case Dummy93(p) => p + case Dummy94(p) => p + case Dummy95(p) => p + case Dummy96(p) => p + case Dummy97(p) => p + case Dummy98(p) => p + case Dummy99(p) => p + case Dummy100(p) => p + case Dummy101(p) => p + case Dummy102(p) => p + case Dummy103(p) => p + case Dummy104(p) => p + case Dummy105(p) => p + case Dummy106(p) => p + case Dummy107(p) => p + case Dummy108(p) => p + case Dummy109(p) => p + case Dummy110(p) => p + case Dummy111(p) => p + case Dummy112(p) => p + case Dummy113(p) => p + case Dummy114(p) => p + case Dummy115(p) => p + case Dummy116(p) => p + case Dummy117(p) => p + case Dummy118(p) => p + case Dummy119(p) => p + case Dummy120(p) => p + case Dummy121(p) => p + case Dummy122(p) => p + case Dummy123(p) => p + case Dummy124(p) => p + case Dummy125(p) => p + case Dummy126(p) => p + case Dummy127(p) => p + case Dummy128(p) => p + case Dummy129(p) => p + case Dummy130(p) => p + case Dummy131(p) => p + case Dummy132(p) => p + case Dummy133(p) => p + case Dummy134(p) => p + case Dummy135(p) => p + case Dummy136(p) => p + case Dummy137(p) => p + case Dummy138(p) => p + case Dummy139(p) => p + case Dummy140(p) => p + case Dummy141(p) => p + case Dummy142(p) => p + case Dummy143(p) => p + case Dummy144(p) => p + case Dummy145(p) => p + case Dummy146(p) => p + case Dummy147(p) => p + case Dummy148(p) => p + case Dummy149(p) => p + case Dummy150(p) => p + case Dummy151(p) => p + case Dummy152(p) => p + case Dummy153(p) => p + case Dummy154(p) => p + case Dummy155(p) => p + case Dummy156(p) => p + case Dummy157(p) => p + case Dummy158(p) => p + case Dummy159(p) => p + case Dummy160(p) => p + case Dummy161(p) => p + case Dummy162(p) => p + case Dummy163(p) => p + case Dummy164(p) => p + case Dummy165(p) => p + case Dummy166(p) => p + case Dummy167(p) => p + case Dummy168(p) => p + case Dummy169(p) => p + case Dummy170(p) => p + case Dummy171(p) => p + case Dummy172(p) => p + case Dummy173(p) => p + case Dummy174(p) => p + case Dummy175(p) => p + case Dummy176(p) => p + case Dummy177(p) => p + case Dummy178(p) => p + case Dummy179(p) => p + case Dummy180(p) => p + case Dummy181(p) => p + case Dummy182(p) => p + case Dummy183(p) => p + case Dummy184(p) => p + case Dummy185(p) => p + case Dummy186(p) => p + case Dummy187(p) => p + case Dummy188(p) => p + case Dummy189(p) => p + case Dummy190(p) => p + case Dummy191(p) => p + case Dummy192(p) => p + case Dummy193(p) => p + case Dummy194(p) => p + case Dummy195(p) => p + case Dummy196(p) => p + case Dummy197(p) => p + case Dummy198(p) => p + case Dummy199(p) => p + case Dummy200(p) => p + case Dummy201(p) => p + case Dummy202(p) => p + case Dummy203(p) => p + case Dummy204(p) => p + case Dummy205(p) => p + case Dummy206(p) => p + case Dummy207(p) => p + case Dummy208(p) => p + case Dummy209(p) => p + case Dummy210(p) => p + case Dummy211(p) => p + case Dummy212(p) => p + case Dummy213(p) => p + case Dummy214(p) => p + case Dummy215(p) => p + case Dummy216(p) => p + case Dummy217(p) => p + case Dummy218(p) => p + case Dummy219(p) => p + case Dummy220(p) => p + case Dummy221(p) => p + case Dummy222(p) => p + case Dummy223(p) => p + case Dummy224(p) => p + case Dummy225(p) => p + case Dummy226(p) => p + case Dummy227(p) => p + case Dummy228(p) => p + case Dummy229(p) => p + case Dummy230(p) => p + case Dummy231(p) => p + case Dummy232(p) => p + case Dummy233(p) => p + case Dummy234(p) => p + case Dummy235(p) => p + case Dummy236(p) => p + case Dummy237(p) => p + case Dummy238(p) => p + case Dummy239(p) => p + case Dummy240(p) => p + case Dummy241(p) => p + case Dummy242(p) => p + case Dummy243(p) => p + case Dummy244(p) => p + case Dummy245(p) => p + case Dummy246(p) => p + case Dummy247(p) => p + case Dummy248(p) => p + case Dummy249(p) => p + case Dummy250(p) => p + case Dummy251(p) => p + case Dummy252(p) => p + case Dummy253(p) => p + case Dummy254(p) => p + case Dummy255(p) => p + case Dummy256(p) => p + case Dummy257(p) => p + case Dummy258(p) => p + case Dummy259(p) => p + case Dummy260(p) => p + case Dummy261(p) => p + case Dummy262(p) => p + case Dummy263(p) => p + case Dummy264(p) => p + case Dummy265(p) => p + case Dummy266(p) => p + case Dummy267(p) => p + case Dummy268(p) => p + case Dummy269(p) => p + case Dummy270(p) => p + case Dummy271(p) => p + case Dummy272(p) => p + case Dummy273(p) => p + case Dummy274(p) => p + case Dummy275(p) => p + case Dummy276(p) => p + case Dummy277(p) => p + case Dummy278(p) => p + case Dummy279(p) => p + case Dummy280(p) => p + case Dummy281(p) => p + case Dummy282(p) => p + case Dummy283(p) => p + case Dummy284(p) => p + case Dummy285(p) => p + case Dummy286(p) => p + case Dummy287(p) => p + case Dummy288(p) => p + case Dummy289(p) => p + case Dummy290(p) => p + case Dummy291(p) => p + case Dummy292(p) => p + case Dummy293(p) => p + case Dummy294(p) => p + case Dummy295(p) => p + case Dummy296(p) => p + case Dummy297(p) => p + case Dummy298(p) => p + case Dummy299(p) => p + case Dummy300(p) => p + case Dummy301(p) => p + case Dummy302(p) => p + case Dummy303(p) => p + case Dummy304(p) => p + case Dummy305(p) => p + case Dummy306(p) => p + case Dummy307(p) => p + case Dummy308(p) => p + case Dummy309(p) => p + case Dummy310(p) => p + case Dummy311(p) => p + case Dummy312(p) => p + case Dummy313(p) => p + case Dummy314(p) => p + case Dummy315(p) => p + case Dummy316(p) => p + case Dummy317(p) => p + case Dummy318(p) => p + case Dummy319(p) => p + case Dummy320(p) => p + case Dummy321(p) => p + case Dummy322(p) => p + case Dummy323(p) => p + case Dummy324(p) => p + case Dummy325(p) => p + case Dummy326(p) => p + case Dummy327(p) => p + case Dummy328(p) => p + case Dummy329(p) => p + case Dummy330(p) => p + case Dummy331(p) => p + case Dummy332(p) => p + case Dummy333(p) => p + case Dummy334(p) => p + case Dummy335(p) => p + case Dummy336(p) => p + case Dummy337(p) => p + case Dummy338(p) => p + case Dummy339(p) => p + case Dummy340(p) => p + case Dummy341(p) => p + case Dummy342(p) => p + case Dummy343(p) => p + case Dummy344(p) => p + case Dummy345(p) => p + case Dummy346(p) => p + case Dummy347(p) => p + case Dummy348(p) => p + case Dummy349(p) => p + case Dummy350(p) => p + case Dummy351(p) => p + case Dummy352(p) => p + case Dummy353(p) => p + case Dummy354(p) => p + case Dummy355(p) => p + case Dummy356(p) => p + case Dummy357(p) => p + case Dummy358(p) => p + case Dummy359(p) => p + case Dummy360(p) => p + case Dummy361(p) => p + case Dummy362(p) => p + case Dummy363(p) => p + case Dummy364(p) => p + case Dummy365(p) => p + case Dummy366(p) => p + case Dummy367(p) => p + case Dummy368(p) => p + case Dummy369(p) => p + case Dummy370(p) => p + case Dummy371(p) => p + case Dummy372(p) => p + case Dummy373(p) => p + case Dummy374(p) => p + case Dummy375(p) => p + case Dummy376(p) => p + case Dummy377(p) => p + case Dummy378(p) => p + case Dummy379(p) => p + case Dummy380(p) => p + case Dummy381(p) => p + case Dummy382(p) => p + case Dummy383(p) => p + case Dummy384(p) => p + case Dummy385(p) => p + case Dummy386(p) => p + case Dummy387(p) => p + case Dummy388(p) => p + case Dummy389(p) => p + case Dummy390(p) => p + case Dummy391(p) => p + case Dummy392(p) => p + case Dummy393(p) => p + case Dummy394(p) => p + case Dummy395(p) => p + case Dummy396(p) => p + case Dummy397(p) => p + case Dummy398(p) => p + case Dummy399(p) => p + case Dummy400(p) => p + case Dummy401(p) => p + case Dummy402(p) => p + case Dummy403(p) => p + case Dummy404(p) => p + case Dummy405(p) => p + case Dummy406(p) => p + case Dummy407(p) => p + case Dummy408(p) => p + case Dummy409(p) => p + case Dummy410(p) => p + case Dummy411(p) => p + case Dummy412(p) => p + case Dummy413(p) => p + case Dummy414(p) => p + case Dummy415(p) => p + case Dummy416(p) => p + case Dummy417(p) => p + case Dummy418(p) => p + case Dummy419(p) => p + case Dummy420(p) => p + case Dummy421(p) => p + case Dummy422(p) => p + case Dummy423(p) => p + case Dummy424(p) => p + case Dummy425(p) => p + case Dummy426(p) => p + case Dummy427(p) => p + case Dummy428(p) => p + case Dummy429(p) => p + case Dummy430(p) => p + case Dummy431(p) => p + case Dummy432(p) => p + case Dummy433(p) => p + case Dummy434(p) => p + case Dummy435(p) => p + case Dummy436(p) => p + case Dummy437(p) => p + case Dummy438(p) => p + case Dummy439(p) => p + case Dummy440(p) => p + case Dummy441(p) => p + case Dummy442(p) => p + case Dummy443(p) => p + case Dummy444(p) => p + case Dummy445(p) => p + case Dummy446(p) => p + case Dummy447(p) => p + case Dummy448(p) => p + case Dummy449(p) => p + case Dummy450(p) => p + case Dummy451(p) => p + case Dummy452(p) => p + case Dummy453(p) => p + case Dummy454(p) => p + case Dummy455(p) => p + case Dummy456(p) => p + case Dummy457(p) => p + case Dummy458(p) => p + case Dummy459(p) => p + case Dummy460(p) => p + case Dummy461(p) => p + case Dummy462(p) => p + case Dummy463(p) => p + case Dummy464(p) => p + case Dummy465(p) => p + case Dummy466(p) => p + case Dummy467(p) => p + case Dummy468(p) => p + case Dummy469(p) => p + case Dummy470(p) => p + case Dummy471(p) => p + case Dummy472(p) => p + case Dummy473(p) => p + case Dummy474(p) => p + case Dummy475(p) => p + case Dummy476(p) => p + case Dummy477(p) => p + case Dummy478(p) => p + case Dummy479(p) => p + case Dummy480(p) => p + case Dummy481(p) => p + case Dummy482(p) => p + case Dummy483(p) => p + case Dummy484(p) => p + case Dummy485(p) => p + case Dummy486(p) => p + case Dummy487(p) => p + case Dummy488(p) => p + case Dummy489(p) => p + case Dummy490(p) => p + case Dummy491(p) => p + case Dummy492(p) => p + case Dummy493(p) => p + case Dummy494(p) => p + case Dummy495(p) => p + case Dummy496(p) => p + case Dummy497(p) => p + case Dummy498(p) => p + case Dummy499(p) => p + case Dummy500(p) => p + case Dummy501(p) => p + case Dummy502(p) => p + case Dummy503(p) => p + case Dummy504(p) => p + case Dummy505(p) => p + case Dummy506(p) => p + case Dummy507(p) => p + case Dummy508(p) => p + case Dummy509(p) => p + case Dummy510(p) => p + case Dummy511(p) => p + case Dummy512(p) => p + case Dummy513(p) => p + case Dummy514(p) => p + case Dummy515(p) => p + case Dummy516(p) => p + case Dummy517(p) => p + case Dummy518(p) => p + case Dummy519(p) => p + case Dummy520(p) => p + case Dummy521(p) => p + case Dummy522(p) => p + case Dummy523(p) => p + case Dummy524(p) => p + case Dummy525(p) => p + case Dummy526(p) => p + case Dummy527(p) => p + case Dummy528(p) => p + case Dummy529(p) => p + case Dummy530(p) => p + case Dummy531(p) => p + case Dummy532(p) => p + case Dummy533(p) => p + case Dummy534(p) => p + case Dummy535(p) => p + case Dummy536(p) => p + case Dummy537(p) => p + case Dummy538(p) => p + case Dummy539(p) => p + case Dummy540(p) => p + case Dummy541(p) => p + case Dummy542(p) => p + case Dummy543(p) => p + case Dummy544(p) => p + case Dummy545(p) => p + case Dummy546(p) => p + case Dummy547(p) => p + case Dummy548(p) => p + case Dummy549(p) => p + case Dummy550(p) => p + case Dummy551(p) => p + case Dummy552(p) => p + case Dummy553(p) => p + case Dummy554(p) => p + case Dummy555(p) => p + case Dummy556(p) => p + case Dummy557(p) => p + case Dummy558(p) => p + case Dummy559(p) => p + case Dummy560(p) => p + case Dummy561(p) => p + case Dummy562(p) => p + case Dummy563(p) => p + case Dummy564(p) => p + case Dummy565(p) => p + case Dummy566(p) => p + case Dummy567(p) => p + case Dummy568(p) => p + case Dummy569(p) => p + case Dummy570(p) => p + case Dummy571(p) => p + case Dummy572(p) => p + case Dummy573(p) => p + case Dummy574(p) => p + case Dummy575(p) => p + case Dummy576(p) => p + case Dummy577(p) => p + case Dummy578(p) => p + case Dummy579(p) => p + case Dummy580(p) => p + case Dummy581(p) => p + case Dummy582(p) => p + case Dummy583(p) => p + case Dummy584(p) => p + case Dummy585(p) => p + case Dummy586(p) => p + case Dummy587(p) => p + case Dummy588(p) => p + case Dummy589(p) => p + case Dummy590(p) => p + case Dummy591(p) => p + case Dummy592(p) => p + case Dummy593(p) => p + case Dummy594(p) => p + case Dummy595(p) => p + case Dummy596(p) => p + case Dummy597(p) => p + case Dummy598(p) => p + case Dummy599(p) => p + case Dummy600(p) => p + case Dummy601(p) => p + case Dummy602(p) => p + case Dummy603(p) => p + case Dummy604(p) => p + case Dummy605(p) => p + case Dummy606(p) => p + case Dummy607(p) => p + case Dummy608(p) => p + case Dummy609(p) => p + case Dummy610(p) => p + case Dummy611(p) => p + case Dummy612(p) => p + case Dummy613(p) => p + case Dummy614(p) => p + case Dummy615(p) => p + case Dummy616(p) => p + case Dummy617(p) => p + case Dummy618(p) => p + case Dummy619(p) => p + case Dummy620(p) => p + case Dummy621(p) => p + case Dummy622(p) => p + case Dummy623(p) => p + case Dummy624(p) => p + case Dummy625(p) => p + case Dummy626(p) => p + case Dummy627(p) => p + case Dummy628(p) => p + case Dummy629(p) => p + case Dummy630(p) => p + case Dummy631(p) => p + case Dummy632(p) => p + case Dummy633(p) => p + case Dummy634(p) => p + case Dummy635(p) => p + case Dummy636(p) => p + case Dummy637(p) => p + case Dummy638(p) => p + case Dummy639(p) => p + case Dummy640(p) => p + case Dummy641(p) => p + case Dummy642(p) => p + case Dummy643(p) => p + case Dummy644(p) => p + case Dummy645(p) => p + case Dummy646(p) => p + case Dummy647(p) => p + case Dummy648(p) => p + case Dummy649(p) => p + case Dummy650(p) => p + case Dummy651(p) => p + case Dummy652(p) => p + case Dummy653(p) => p + case Dummy654(p) => p + case Dummy655(p) => p + case Dummy656(p) => p + case Dummy657(p) => p + case Dummy658(p) => p + case Dummy659(p) => p + case Dummy660(p) => p + case Dummy661(p) => p + case Dummy662(p) => p + case Dummy663(p) => p + case Dummy664(p) => p + case Dummy665(p) => p + case Dummy666(p) => p + case Dummy667(p) => p + case Dummy668(p) => p + case Dummy669(p) => p + case Dummy670(p) => p + case Dummy671(p) => p + case Dummy672(p) => p + case Dummy673(p) => p + case Dummy674(p) => p + case Dummy675(p) => p + case Dummy676(p) => p + case Dummy677(p) => p + case Dummy678(p) => p + case Dummy679(p) => p + case Dummy680(p) => p + case Dummy681(p) => p + case Dummy682(p) => p + case Dummy683(p) => p + case Dummy684(p) => p + case Dummy685(p) => p + case Dummy686(p) => p + case Dummy687(p) => p + case Dummy688(p) => p + case Dummy689(p) => p + case Dummy690(p) => p + case Dummy691(p) => p + case Dummy692(p) => p + case Dummy693(p) => p + case Dummy694(p) => p + case Dummy695(p) => p + case Dummy696(p) => p + case Dummy697(p) => p + case Dummy698(p) => p + case Dummy699(p) => p + case Dummy700(p) => p + case Dummy701(p) => p + case Dummy702(p) => p + case Dummy703(p) => p + case Dummy704(p) => p + case Dummy705(p) => p + case Dummy706(p) => p + case Dummy707(p) => p + case Dummy708(p) => p + case Dummy709(p) => p + case Dummy710(p) => p + case Dummy711(p) => p + case Dummy712(p) => p + case Dummy713(p) => p + case Dummy714(p) => p + case Dummy715(p) => p + case Dummy716(p) => p + case Dummy717(p) => p + case Dummy718(p) => p + case Dummy719(p) => p + case Dummy720(p) => p + case Dummy721(p) => p + case Dummy722(p) => p + case Dummy723(p) => p + case Dummy724(p) => p + case Dummy725(p) => p + case Dummy726(p) => p + case Dummy727(p) => p + case Dummy728(p) => p + case Dummy729(p) => p + case Dummy730(p) => p + case Dummy731(p) => p + case Dummy732(p) => p + case Dummy733(p) => p + case Dummy734(p) => p + case Dummy735(p) => p + case Dummy736(p) => p + case Dummy737(p) => p + case Dummy738(p) => p + case Dummy739(p) => p + case Dummy740(p) => p + case Dummy741(p) => p + case Dummy742(p) => p + case Dummy743(p) => p + case Dummy744(p) => p + case Dummy745(p) => p + case Dummy746(p) => p + case Dummy747(p) => p + case Dummy748(p) => p + case Dummy749(p) => p + case Dummy750(p) => p + case Dummy751(p) => p + case Dummy752(p) => p + case Dummy753(p) => p + case Dummy754(p) => p + case Dummy755(p) => p + case Dummy756(p) => p + case Dummy757(p) => p + case Dummy758(p) => p + case Dummy759(p) => p + case Dummy760(p) => p + case Dummy761(p) => p + case Dummy762(p) => p + case Dummy763(p) => p + case Dummy764(p) => p + case Dummy765(p) => p + case Dummy766(p) => p + case Dummy767(p) => p + case Dummy768(p) => p + case Dummy769(p) => p + case Dummy770(p) => p + case Dummy771(p) => p + case Dummy772(p) => p + case Dummy773(p) => p + case Dummy774(p) => p + case Dummy775(p) => p + case Dummy776(p) => p + case Dummy777(p) => p + case Dummy778(p) => p + case Dummy779(p) => p + case Dummy780(p) => p + case Dummy781(p) => p + case Dummy782(p) => p + case Dummy783(p) => p + case Dummy784(p) => p + case Dummy785(p) => p + case Dummy786(p) => p + case Dummy787(p) => p + case Dummy788(p) => p + case Dummy789(p) => p + case Dummy790(p) => p + case Dummy791(p) => p + case Dummy792(p) => p + case Dummy793(p) => p + case Dummy794(p) => p + case Dummy795(p) => p + case Dummy796(p) => p + case Dummy797(p) => p + case Dummy798(p) => p + case Dummy799(p) => p + case Dummy800(p) => p + case Dummy801(p) => p + case Dummy802(p) => p + case Dummy803(p) => p + case Dummy804(p) => p + case Dummy805(p) => p + case Dummy806(p) => p + case Dummy807(p) => p + case Dummy808(p) => p + case Dummy809(p) => p + case Dummy810(p) => p + case Dummy811(p) => p + case Dummy812(p) => p + case Dummy813(p) => p + case Dummy814(p) => p + case Dummy815(p) => p + case Dummy816(p) => p + case Dummy817(p) => p + case Dummy818(p) => p + case Dummy819(p) => p + case Dummy820(p) => p + case Dummy821(p) => p + case Dummy822(p) => p + case Dummy823(p) => p + case Dummy824(p) => p + case Dummy825(p) => p + case Dummy826(p) => p + case Dummy827(p) => p + case Dummy828(p) => p + case Dummy829(p) => p + case Dummy830(p) => p + case Dummy831(p) => p + case Dummy832(p) => p + case Dummy833(p) => p + case Dummy834(p) => p + case Dummy835(p) => p + case Dummy836(p) => p + case Dummy837(p) => p + case Dummy838(p) => p + case Dummy839(p) => p + case Dummy840(p) => p + case Dummy841(p) => p + case Dummy842(p) => p + case Dummy843(p) => p + case Dummy844(p) => p + case Dummy845(p) => p + case Dummy846(p) => p + case Dummy847(p) => p + case Dummy848(p) => p + case Dummy849(p) => p + case Dummy850(p) => p + case Dummy851(p) => p + case Dummy852(p) => p + case Dummy853(p) => p + case Dummy854(p) => p + case Dummy855(p) => p + case Dummy856(p) => p + case Dummy857(p) => p + case Dummy858(p) => p + case Dummy859(p) => p + case Dummy860(p) => p + case Dummy861(p) => p + case Dummy862(p) => p + case Dummy863(p) => p + case Dummy864(p) => p + case Dummy865(p) => p + case Dummy866(p) => p + case Dummy867(p) => p + case Dummy868(p) => p + case Dummy869(p) => p + case Dummy870(p) => p + case Dummy871(p) => p + case Dummy872(p) => p + case Dummy873(p) => p + case Dummy874(p) => p + case Dummy875(p) => p + case Dummy876(p) => p + case Dummy877(p) => p + case Dummy878(p) => p + case Dummy879(p) => p + case Dummy880(p) => p + case Dummy881(p) => p + case Dummy882(p) => p + case Dummy883(p) => p + case Dummy884(p) => p + case Dummy885(p) => p + case Dummy886(p) => p + case Dummy887(p) => p + case Dummy888(p) => p + case Dummy889(p) => p + case Dummy890(p) => p + case Dummy891(p) => p + case Dummy892(p) => p + case Dummy893(p) => p + case Dummy894(p) => p + case Dummy895(p) => p + case Dummy896(p) => p + case Dummy897(p) => p + case Dummy898(p) => p + case Dummy899(p) => p + case Dummy900(p) => p + case Dummy901(p) => p + case Dummy902(p) => p + case Dummy903(p) => p + case Dummy904(p) => p + case Dummy905(p) => p + case Dummy906(p) => p + case Dummy907(p) => p + case Dummy908(p) => p + case Dummy909(p) => p + case Dummy910(p) => p + case Dummy911(p) => p + case Dummy912(p) => p + case Dummy913(p) => p + case Dummy914(p) => p + case Dummy915(p) => p + case Dummy916(p) => p + case Dummy917(p) => p + case Dummy918(p) => p + case Dummy919(p) => p + case Dummy920(p) => p + case Dummy921(p) => p + case Dummy922(p) => p + case Dummy923(p) => p + case Dummy924(p) => p + case Dummy925(p) => p + case Dummy926(p) => p + case Dummy927(p) => p + case Dummy928(p) => p + case Dummy929(p) => p + case Dummy930(p) => p + case Dummy931(p) => p + case Dummy932(p) => p + case Dummy933(p) => p + case Dummy934(p) => p + case Dummy935(p) => p + case Dummy936(p) => p + case Dummy937(p) => p + case Dummy938(p) => p + case Dummy939(p) => p + case Dummy940(p) => p + case Dummy941(p) => p + case Dummy942(p) => p + case Dummy943(p) => p + case Dummy944(p) => p + case Dummy945(p) => p + case Dummy946(p) => p + case Dummy947(p) => p + case Dummy948(p) => p + case Dummy949(p) => p + case Dummy950(p) => p + case Dummy951(p) => p + case Dummy952(p) => p + case Dummy953(p) => p + case Dummy954(p) => p + case Dummy955(p) => p + case Dummy956(p) => p + case Dummy957(p) => p + case Dummy958(p) => p + case Dummy959(p) => p + case Dummy960(p) => p + case Dummy961(p) => p + case Dummy962(p) => p + case Dummy963(p) => p + case Dummy964(p) => p + case Dummy965(p) => p + case Dummy966(p) => p + case Dummy967(p) => p + case Dummy968(p) => p + case Dummy969(p) => p + case Dummy970(p) => p + case Dummy971(p) => p + case Dummy972(p) => p + case Dummy973(p) => p + case Dummy974(p) => p + case Dummy975(p) => p + case Dummy976(p) => p + case Dummy977(p) => p + case Dummy978(p) => p + case Dummy979(p) => p + case Dummy980(p) => p + case Dummy981(p) => p + case Dummy982(p) => p + case Dummy983(p) => p + case Dummy984(p) => p + case Dummy985(p) => p + case Dummy986(p) => p + case Dummy987(p) => p + case Dummy988(p) => p + case Dummy989(p) => p + case Dummy990(p) => p + case Dummy991(p) => p + case Dummy992(p) => p + case Dummy993(p) => p + case Dummy994(p) => p + case Dummy995(p) => p + case Dummy996(p) => p + case Dummy997(p) => p + case Dummy998(p) => p + case Dummy999(p) => p + case Dummy1000(p) => p + case Dummy1001(p) => p + case Dummy1002(p) => p + case Dummy1003(p) => p + case Dummy1004(p) => p + case Dummy1005(p) => p + case Dummy1006(p) => p + case Dummy1007(p) => p + case Dummy1008(p) => p + case Dummy1009(p) => p + case Dummy1010(p) => p + case Dummy1011(p) => p + case Dummy1012(p) => p + case Dummy1013(p) => p + case Dummy1014(p) => p + case Dummy1015(p) => p + case Dummy1016(p) => p + case Dummy1017(p) => p + case Dummy1018(p) => p + case Dummy1019(p) => p + case Dummy1020(p) => p + case Dummy1021(p) => p + case Dummy1022(p) => p + case Dummy1023(p) => p + case Dummy1024(p) => p + case Dummy1025(p) => p + case Dummy1026(p) => p + case Dummy1027(p) => p + case Dummy1028(p) => p + case Dummy1029(p) => p + case Dummy1030(p) => p + case Dummy1031(p) => p + case Dummy1032(p) => p + case Dummy1033(p) => p + case Dummy1034(p) => p + case Dummy1035(p) => p + case Dummy1036(p) => p + case Dummy1037(p) => p + case Dummy1038(p) => p + case Dummy1039(p) => p + case Dummy1040(p) => p + case Dummy1041(p) => p + case Dummy1042(p) => p + case Dummy1043(p) => p + case Dummy1044(p) => p + case Dummy1045(p) => p + case Dummy1046(p) => p + case Dummy1047(p) => p + case Dummy1048(p) => p + case Dummy1049(p) => p + case Dummy1050(p) => p + case Dummy1051(p) => p + case Dummy1052(p) => p + case Dummy1053(p) => p + case Dummy1054(p) => p + case Dummy1055(p) => p + case Dummy1056(p) => p + case Dummy1057(p) => p + case Dummy1058(p) => p + case Dummy1059(p) => p + case Dummy1060(p) => p + case Dummy1061(p) => p + case Dummy1062(p) => p + case Dummy1063(p) => p + case Dummy1064(p) => p + case Dummy1065(p) => p + case Dummy1066(p) => p + case Dummy1067(p) => p + case Dummy1068(p) => p + case Dummy1069(p) => p + case Dummy1070(p) => p + case Dummy1071(p) => p + case Dummy1072(p) => p + case Dummy1073(p) => p + case Dummy1074(p) => p + case Dummy1075(p) => p + case Dummy1076(p) => p + case Dummy1077(p) => p + case Dummy1078(p) => p + case Dummy1079(p) => p + case Dummy1080(p) => p + case Dummy1081(p) => p + case Dummy1082(p) => p + case Dummy1083(p) => p + case Dummy1084(p) => p + case Dummy1085(p) => p + case Dummy1086(p) => p + case Dummy1087(p) => p + case Dummy1088(p) => p + case Dummy1089(p) => p + case Dummy1090(p) => p + case Dummy1091(p) => p + case Dummy1092(p) => p + case Dummy1093(p) => p + case Dummy1094(p) => p + case Dummy1095(p) => p + case Dummy1096(p) => p + case Dummy1097(p) => p + case Dummy1098(p) => p + case Dummy1099(p) => p + case Dummy1100(p) => p + case Dummy1101(p) => p + case Dummy1102(p) => p + case Dummy1103(p) => p + case Dummy1104(p) => p + case Dummy1105(p) => p + case Dummy1106(p) => p + case Dummy1107(p) => p + case Dummy1108(p) => p + case Dummy1109(p) => p + case Dummy1110(p) => p + case Dummy1111(p) => p + case Dummy1112(p) => p + case Dummy1113(p) => p + case Dummy1114(p) => p + case Dummy1115(p) => p + case Dummy1116(p) => p + case Dummy1117(p) => p + case Dummy1118(p) => p + case Dummy1119(p) => p + case Dummy1120(p) => p + case Dummy1121(p) => p + case Dummy1122(p) => p + case Dummy1123(p) => p + case Dummy1124(p) => p + case Dummy1125(p) => p + case Dummy1126(p) => p + case Dummy1127(p) => p + case Dummy1128(p) => p + case Dummy1129(p) => p + case Dummy1130(p) => p + case Dummy1131(p) => p + case Dummy1132(p) => p + case Dummy1133(p) => p + case Dummy1134(p) => p + case Dummy1135(p) => p + case Dummy1136(p) => p + case Dummy1137(p) => p + case Dummy1138(p) => p + case Dummy1139(p) => p + case Dummy1140(p) => p + case Dummy1141(p) => p + case Dummy1142(p) => p + case Dummy1143(p) => p + case Dummy1144(p) => p + case Dummy1145(p) => p + case Dummy1146(p) => p + case Dummy1147(p) => p + case Dummy1148(p) => p + case Dummy1149(p) => p + case Dummy1150(p) => p + case Dummy1151(p) => p + case Dummy1152(p) => p + case Dummy1153(p) => p + case Dummy1154(p) => p + case Dummy1155(p) => p + case Dummy1156(p) => p + case Dummy1157(p) => p + case Dummy1158(p) => p + case Dummy1159(p) => p + case Dummy1160(p) => p + case Dummy1161(p) => p + case Dummy1162(p) => p + case Dummy1163(p) => p + case Dummy1164(p) => p + case Dummy1165(p) => p + case Dummy1166(p) => p + case Dummy1167(p) => p + case Dummy1168(p) => p + case Dummy1169(p) => p + case Dummy1170(p) => p + case Dummy1171(p) => p + case Dummy1172(p) => p + case Dummy1173(p) => p + case Dummy1174(p) => p + case Dummy1175(p) => p + case Dummy1176(p) => p + case Dummy1177(p) => p + case Dummy1178(p) => p + case Dummy1179(p) => p + case Dummy1180(p) => p + case Dummy1181(p) => p + case Dummy1182(p) => p + case Dummy1183(p) => p + case Dummy1184(p) => p + case Dummy1185(p) => p + case Dummy1186(p) => p + case Dummy1187(p) => p + case Dummy1188(p) => p + case Dummy1189(p) => p + case Dummy1190(p) => p + case Dummy1191(p) => p + case Dummy1192(p) => p + case Dummy1193(p) => p + case Dummy1194(p) => p + case Dummy1195(p) => p + case Dummy1196(p) => p + case Dummy1197(p) => p + case Dummy1198(p) => p + case Dummy1199(p) => p + case Dummy1200(p) => p + case Dummy1201(p) => p + case Dummy1202(p) => p + case Dummy1203(p) => p + case Dummy1204(p) => p + case Dummy1205(p) => p + case Dummy1206(p) => p + case Dummy1207(p) => p + case Dummy1208(p) => p + case Dummy1209(p) => p + case Dummy1210(p) => p + case Dummy1211(p) => p + case Dummy1212(p) => p + case Dummy1213(p) => p + case Dummy1214(p) => p + case Dummy1215(p) => p + case Dummy1216(p) => p + case Dummy1217(p) => p + case Dummy1218(p) => p + case Dummy1219(p) => p + case Dummy1220(p) => p + case Dummy1221(p) => p + case Dummy1222(p) => p + case Dummy1223(p) => p + case Dummy1224(p) => p + case Dummy1225(p) => p + case Dummy1226(p) => p + case Dummy1227(p) => p + case Dummy1228(p) => p + case Dummy1229(p) => p + case Dummy1230(p) => p + case Dummy1231(p) => p + case Dummy1232(p) => p + case Dummy1233(p) => p + case Dummy1234(p) => p + case Dummy1235(p) => p + case Dummy1236(p) => p + case Dummy1237(p) => p + case Dummy1238(p) => p + case Dummy1239(p) => p + case Dummy1240(p) => p + case Dummy1241(p) => p + case Dummy1242(p) => p + case Dummy1243(p) => p + case Dummy1244(p) => p + case Dummy1245(p) => p + case Dummy1246(p) => p + case Dummy1247(p) => p + case Dummy1248(p) => p + case Dummy1249(p) => p + case Dummy1250(p) => p + case Dummy1251(p) => p + case Dummy1252(p) => p + case Dummy1253(p) => p + case Dummy1254(p) => p + case Dummy1255(p) => p + case Dummy1256(p) => p + case Dummy1257(p) => p + case Dummy1258(p) => p + case Dummy1259(p) => p + case Dummy1260(p) => p + case Dummy1261(p) => p + case Dummy1262(p) => p + case Dummy1263(p) => p + case Dummy1264(p) => p + case Dummy1265(p) => p + case Dummy1266(p) => p + case Dummy1267(p) => p + case Dummy1268(p) => p + case Dummy1269(p) => p + case Dummy1270(p) => p + case Dummy1271(p) => p + case Dummy1272(p) => p + case Dummy1273(p) => p + case Dummy1274(p) => p + case Dummy1275(p) => p + case Dummy1276(p) => p + case Dummy1277(p) => p + case Dummy1278(p) => p + case Dummy1279(p) => p + case Dummy1280(p) => p + case Dummy1281(p) => p + case Dummy1282(p) => p + case Dummy1283(p) => p + case Dummy1284(p) => p + case Dummy1285(p) => p + case Dummy1286(p) => p + case Dummy1287(p) => p + case Dummy1288(p) => p + case Dummy1289(p) => p + case Dummy1290(p) => p + case Dummy1291(p) => p + case Dummy1292(p) => p + case Dummy1293(p) => p + case Dummy1294(p) => p + case Dummy1295(p) => p + case Dummy1296(p) => p + case Dummy1297(p) => p + case Dummy1298(p) => p + case Dummy1299(p) => p + case Dummy1300(p) => p + case Dummy1301(p) => p + case Dummy1302(p) => p + case Dummy1303(p) => p + case Dummy1304(p) => p + case Dummy1305(p) => p + case Dummy1306(p) => p + case Dummy1307(p) => p + case Dummy1308(p) => p + case Dummy1309(p) => p + case Dummy1310(p) => p + case Dummy1311(p) => p + case Dummy1312(p) => p + case Dummy1313(p) => p + case Dummy1314(p) => p + case Dummy1315(p) => p + case Dummy1316(p) => p + case Dummy1317(p) => p + case Dummy1318(p) => p + case Dummy1319(p) => p + case Dummy1320(p) => p + case Dummy1321(p) => p + case Dummy1322(p) => p + case Dummy1323(p) => p + case Dummy1324(p) => p + case Dummy1325(p) => p + case Dummy1326(p) => p + case Dummy1327(p) => p + case Dummy1328(p) => p + case Dummy1329(p) => p + case Dummy1330(p) => p + case Dummy1331(p) => p + case Dummy1332(p) => p + case Dummy1333(p) => p + case Dummy1334(p) => p + case Dummy1335(p) => p + case Dummy1336(p) => p + case Dummy1337(p) => p + case Dummy1338(p) => p + case Dummy1339(p) => p + case Dummy1340(p) => p + case Dummy1341(p) => p + case Dummy1342(p) => p + case Dummy1343(p) => p + case Dummy1344(p) => p + case Dummy1345(p) => p + case Dummy1346(p) => p + case Dummy1347(p) => p + case Dummy1348(p) => p + case Dummy1349(p) => p + case Dummy1350(p) => p + case Dummy1351(p) => p + case Dummy1352(p) => p + case Dummy1353(p) => p + case Dummy1354(p) => p + case Dummy1355(p) => p + case Dummy1356(p) => p + case Dummy1357(p) => p + case Dummy1358(p) => p + case Dummy1359(p) => p + case Dummy1360(p) => p + case Dummy1361(p) => p + case Dummy1362(p) => p + case Dummy1363(p) => p + case Dummy1364(p) => p + case Dummy1365(p) => p + case Dummy1366(p) => p + case Dummy1367(p) => p + case Dummy1368(p) => p + case Dummy1369(p) => p + case Dummy1370(p) => p + case Dummy1371(p) => p + case Dummy1372(p) => p + case Dummy1373(p) => p + case Dummy1374(p) => p + case Dummy1375(p) => p + case Dummy1376(p) => p + case Dummy1377(p) => p + case Dummy1378(p) => p + case Dummy1379(p) => p + case Dummy1380(p) => p + case Dummy1381(p) => p + case Dummy1382(p) => p + case Dummy1383(p) => p + case Dummy1384(p) => p + case Dummy1385(p) => p + case Dummy1386(p) => p + case Dummy1387(p) => p + case Dummy1388(p) => p + case Dummy1389(p) => p + case Dummy1390(p) => p + case Dummy1391(p) => p + case Dummy1392(p) => p + case Dummy1393(p) => p + case Dummy1394(p) => p + case Dummy1395(p) => p + case Dummy1396(p) => p + case Dummy1397(p) => p + case Dummy1398(p) => p + case Dummy1399(p) => p + case Dummy1400(p) => p + case Dummy1401(p) => p + case Dummy1402(p) => p + case Dummy1403(p) => p + case Dummy1404(p) => p + case Dummy1405(p) => p + case Dummy1406(p) => p + case Dummy1407(p) => p + case Dummy1408(p) => p + case Dummy1409(p) => p + case Dummy1410(p) => p + case Dummy1411(p) => p + case Dummy1412(p) => p + case Dummy1413(p) => p + case Dummy1414(p) => p + case Dummy1415(p) => p + case Dummy1416(p) => p + case Dummy1417(p) => p + case Dummy1418(p) => p + case Dummy1419(p) => p + case Dummy1420(p) => p + case Dummy1421(p) => p + case Dummy1422(p) => p + case Dummy1423(p) => p + case Dummy1424(p) => p + case Dummy1425(p) => p + case Dummy1426(p) => p + case Dummy1427(p) => p + case Dummy1428(p) => p + case Dummy1429(p) => p + case Dummy1430(p) => p + case Dummy1431(p) => p + case Dummy1432(p) => p + case Dummy1433(p) => p + case Dummy1434(p) => p + case Dummy1435(p) => p + case Dummy1436(p) => p + case Dummy1437(p) => p + case Dummy1438(p) => p + case Dummy1439(p) => p + case Dummy1440(p) => p + case Dummy1441(p) => p + case Dummy1442(p) => p + case Dummy1443(p) => p + case Dummy1444(p) => p + case Dummy1445(p) => p + case Dummy1446(p) => p + case Dummy1447(p) => p + case Dummy1448(p) => p + case Dummy1449(p) => p + case Dummy1450(p) => p + case Dummy1451(p) => p + case Dummy1452(p) => p + case Dummy1453(p) => p + case Dummy1454(p) => p + case Dummy1455(p) => p + case Dummy1456(p) => p + case Dummy1457(p) => p + case Dummy1458(p) => p + case Dummy1459(p) => p + case Dummy1460(p) => p + case Dummy1461(p) => p + case Dummy1462(p) => p + case Dummy1463(p) => p + case Dummy1464(p) => p + case Dummy1465(p) => p + case Dummy1466(p) => p + case Dummy1467(p) => p + case Dummy1468(p) => p + case Dummy1469(p) => p + case Dummy1470(p) => p + case Dummy1471(p) => p + case Dummy1472(p) => p + case Dummy1473(p) => p + case Dummy1474(p) => p + case Dummy1475(p) => p + case Dummy1476(p) => p + case Dummy1477(p) => p + case Dummy1478(p) => p + case Dummy1479(p) => p + case Dummy1480(p) => p + case Dummy1481(p) => p + case Dummy1482(p) => p + case Dummy1483(p) => p + case Dummy1484(p) => p + case Dummy1485(p) => p + case Dummy1486(p) => p + case Dummy1487(p) => p + case Dummy1488(p) => p + case Dummy1489(p) => p + case Dummy1490(p) => p + case Dummy1491(p) => p + case Dummy1492(p) => p + case Dummy1493(p) => p + case Dummy1494(p) => p + case Dummy1495(p) => p + case Dummy1496(p) => p + case Dummy1497(p) => p + case Dummy1498(p) => p + case Dummy1499(p) => p + case Dummy1500(p) => p + case Dummy1501(p) => p + case Dummy1502(p) => p + case Dummy1503(p) => p + case Dummy1504(p) => p + case Dummy1505(p) => p + case Dummy1506(p) => p + case Dummy1507(p) => p + case Dummy1508(p) => p + case Dummy1509(p) => p + case Dummy1510(p) => p + case Dummy1511(p) => p + case Dummy1512(p) => p + case Dummy1513(p) => p + case Dummy1514(p) => p + case Dummy1515(p) => p + case Dummy1516(p) => p + case Dummy1517(p) => p + case Dummy1518(p) => p + case Dummy1519(p) => p + case Dummy1520(p) => p + case Dummy1521(p) => p + case Dummy1522(p) => p + case Dummy1523(p) => p + case Dummy1524(p) => p + case Dummy1525(p) => p + case Dummy1526(p) => p + case Dummy1527(p) => p + case Dummy1528(p) => p + case Dummy1529(p) => p + case Dummy1530(p) => p + case Dummy1531(p) => p + case Dummy1532(p) => p + case Dummy1533(p) => p + case Dummy1534(p) => p + case Dummy1535(p) => p + case Dummy1536(p) => p + case Dummy1537(p) => p + case Dummy1538(p) => p + case Dummy1539(p) => p + case Dummy1540(p) => p + case Dummy1541(p) => p + case Dummy1542(p) => p + case Dummy1543(p) => p + case Dummy1544(p) => p + case Dummy1545(p) => p + case Dummy1546(p) => p + case Dummy1547(p) => p + case Dummy1548(p) => p + case Dummy1549(p) => p + case Dummy1550(p) => p + case Dummy1551(p) => p + case Dummy1552(p) => p + case Dummy1553(p) => p + case Dummy1554(p) => p + case Dummy1555(p) => p + case Dummy1556(p) => p + case Dummy1557(p) => p + case Dummy1558(p) => p + case Dummy1559(p) => p + case Dummy1560(p) => p + case Dummy1561(p) => p + case Dummy1562(p) => p + case Dummy1563(p) => p + case Dummy1564(p) => p + case Dummy1565(p) => p + case Dummy1566(p) => p + case Dummy1567(p) => p + case Dummy1568(p) => p + case Dummy1569(p) => p + case Dummy1570(p) => p + case Dummy1571(p) => p + case Dummy1572(p) => p + case Dummy1573(p) => p + case Dummy1574(p) => p + case Dummy1575(p) => p + case Dummy1576(p) => p + case Dummy1577(p) => p + case Dummy1578(p) => p + case Dummy1579(p) => p + case Dummy1580(p) => p + case Dummy1581(p) => p + case Dummy1582(p) => p + case Dummy1583(p) => p + case Dummy1584(p) => p + case Dummy1585(p) => p + case Dummy1586(p) => p + case Dummy1587(p) => p + case Dummy1588(p) => p + case Dummy1589(p) => p + case Dummy1590(p) => p + case Dummy1591(p) => p + case Dummy1592(p) => p + case Dummy1593(p) => p + case Dummy1594(p) => p + case Dummy1595(p) => p + case Dummy1596(p) => p + case Dummy1597(p) => p + case Dummy1598(p) => p + case Dummy1599(p) => p + case Dummy1600(p) => p + case Dummy1601(p) => p + case Dummy1602(p) => p + case Dummy1603(p) => p + case Dummy1604(p) => p + case Dummy1605(p) => p + case Dummy1606(p) => p + case Dummy1607(p) => p + case Dummy1608(p) => p + case Dummy1609(p) => p + case Dummy1610(p) => p + case Dummy1611(p) => p + case Dummy1612(p) => p + case Dummy1613(p) => p + case Dummy1614(p) => p + case Dummy1615(p) => p + case Dummy1616(p) => p + case Dummy1617(p) => p + case Dummy1618(p) => p + case Dummy1619(p) => p + case Dummy1620(p) => p + case Dummy1621(p) => p + case Dummy1622(p) => p + case Dummy1623(p) => p + case Dummy1624(p) => p + case Dummy1625(p) => p + case Dummy1626(p) => p + case Dummy1627(p) => p + case Dummy1628(p) => p + case Dummy1629(p) => p + case Dummy1630(p) => p + case Dummy1631(p) => p + case Dummy1632(p) => p + case Dummy1633(p) => p + case Dummy1634(p) => p + case Dummy1635(p) => p + case Dummy1636(p) => p + case Dummy1637(p) => p + case Dummy1638(p) => p + case Dummy1639(p) => p + case Dummy1640(p) => p + case Dummy1641(p) => p + case Dummy1642(p) => p + case Dummy1643(p) => p + case Dummy1644(p) => p + case Dummy1645(p) => p + case Dummy1646(p) => p + case Dummy1647(p) => p + case Dummy1648(p) => p + case Dummy1649(p) => p + case Dummy1650(p) => p + case Dummy1651(p) => p + case Dummy1652(p) => p + case Dummy1653(p) => p + case Dummy1654(p) => p + case Dummy1655(p) => p + case Dummy1656(p) => p + case Dummy1657(p) => p + case Dummy1658(p) => p + case Dummy1659(p) => p + case Dummy1660(p) => p + case Dummy1661(p) => p + case Dummy1662(p) => p + case Dummy1663(p) => p + case Dummy1664(p) => p + case Dummy1665(p) => p + case Dummy1666(p) => p + case Dummy1667(p) => p + case Dummy1668(p) => p + case Dummy1669(p) => p + case Dummy1670(p) => p + case Dummy1671(p) => p + case Dummy1672(p) => p + case Dummy1673(p) => p + case Dummy1674(p) => p + case Dummy1675(p) => p + case Dummy1676(p) => p + case Dummy1677(p) => p + case Dummy1678(p) => p + case Dummy1679(p) => p + case Dummy1680(p) => p + case Dummy1681(p) => p + case Dummy1682(p) => p + case Dummy1683(p) => p + case Dummy1684(p) => p + case Dummy1685(p) => p + case Dummy1686(p) => p + case Dummy1687(p) => p + case Dummy1688(p) => p + case Dummy1689(p) => p + case Dummy1690(p) => p + case Dummy1691(p) => p + case Dummy1692(p) => p + case Dummy1693(p) => p + case Dummy1694(p) => p + case Dummy1695(p) => p + case Dummy1696(p) => p + case Dummy1697(p) => p + case Dummy1698(p) => p + case Dummy1699(p) => p + case Dummy1700(p) => p + case Dummy1701(p) => p + case Dummy1702(p) => p + case Dummy1703(p) => p + case Dummy1704(p) => p + case Dummy1705(p) => p + case Dummy1706(p) => p + case Dummy1707(p) => p + case Dummy1708(p) => p + case Dummy1709(p) => p + case Dummy1710(p) => p + case Dummy1711(p) => p + case Dummy1712(p) => p + case Dummy1713(p) => p + case Dummy1714(p) => p + case Dummy1715(p) => p + case Dummy1716(p) => p + case Dummy1717(p) => p + case Dummy1718(p) => p + case Dummy1719(p) => p + case Dummy1720(p) => p + case Dummy1721(p) => p + case Dummy1722(p) => p + case Dummy1723(p) => p + case Dummy1724(p) => p + case Dummy1725(p) => p + case Dummy1726(p) => p + case Dummy1727(p) => p + case Dummy1728(p) => p + case Dummy1729(p) => p + case Dummy1730(p) => p + case Dummy1731(p) => p + case Dummy1732(p) => p + case Dummy1733(p) => p + case Dummy1734(p) => p + case Dummy1735(p) => p + case Dummy1736(p) => p + case Dummy1737(p) => p + case Dummy1738(p) => p + case Dummy1739(p) => p + case Dummy1740(p) => p + case Dummy1741(p) => p + case Dummy1742(p) => p + case Dummy1743(p) => p + case Dummy1744(p) => p + case Dummy1745(p) => p + case Dummy1746(p) => p + case Dummy1747(p) => p + case Dummy1748(p) => p + case Dummy1749(p) => p + case Dummy1750(p) => p + case Dummy1751(p) => p + case Dummy1752(p) => p + case Dummy1753(p) => p + case Dummy1754(p) => p + case Dummy1755(p) => p + case Dummy1756(p) => p + case Dummy1757(p) => p + case Dummy1758(p) => p + case Dummy1759(p) => p + case Dummy1760(p) => p + case Dummy1761(p) => p + case Dummy1762(p) => p + case Dummy1763(p) => p + case Dummy1764(p) => p + case Dummy1765(p) => p + case Dummy1766(p) => p + case Dummy1767(p) => p + case Dummy1768(p) => p + case Dummy1769(p) => p + case Dummy1770(p) => p + case Dummy1771(p) => p + case Dummy1772(p) => p + case Dummy1773(p) => p + case Dummy1774(p) => p + case Dummy1775(p) => p + case Dummy1776(p) => p + case Dummy1777(p) => p + case Dummy1778(p) => p + case Dummy1779(p) => p + case Dummy1780(p) => p + case Dummy1781(p) => p + case Dummy1782(p) => p + case Dummy1783(p) => p + case Dummy1784(p) => p + case Dummy1785(p) => p + case Dummy1786(p) => p + case Dummy1787(p) => p + case Dummy1788(p) => p + case Dummy1789(p) => p + case Dummy1790(p) => p + case Dummy1791(p) => p + case Dummy1792(p) => p + case Dummy1793(p) => p + case Dummy1794(p) => p + case Dummy1795(p) => p + case Dummy1796(p) => p + case Dummy1797(p) => p + case Dummy1798(p) => p + case Dummy1799(p) => p + case Dummy1800(p) => p + case Dummy1801(p) => p + case Dummy1802(p) => p + case Dummy1803(p) => p + case Dummy1804(p) => p + case Dummy1805(p) => p + case Dummy1806(p) => p + case Dummy1807(p) => p + case Dummy1808(p) => p + case Dummy1809(p) => p + case Dummy1810(p) => p + case Dummy1811(p) => p + case Dummy1812(p) => p + case Dummy1813(p) => p + case Dummy1814(p) => p + case Dummy1815(p) => p + case Dummy1816(p) => p + case Dummy1817(p) => p + case Dummy1818(p) => p + case Dummy1819(p) => p + case Dummy1820(p) => p + case Dummy1821(p) => p + case Dummy1822(p) => p + case Dummy1823(p) => p + case Dummy1824(p) => p + case Dummy1825(p) => p + case Dummy1826(p) => p + case Dummy1827(p) => p + case Dummy1828(p) => p + case Dummy1829(p) => p + case Dummy1830(p) => p + case Dummy1831(p) => p + case Dummy1832(p) => p + case Dummy1833(p) => p + case Dummy1834(p) => p + case Dummy1835(p) => p + case Dummy1836(p) => p + case Dummy1837(p) => p + case Dummy1838(p) => p + case Dummy1839(p) => p + case Dummy1840(p) => p + case Dummy1841(p) => p + case Dummy1842(p) => p + case Dummy1843(p) => p + case Dummy1844(p) => p + case Dummy1845(p) => p + case Dummy1846(p) => p + case Dummy1847(p) => p + case Dummy1848(p) => p + case Dummy1849(p) => p + case Dummy1850(p) => p + case Dummy1851(p) => p + case Dummy1852(p) => p + case Dummy1853(p) => p + case Dummy1854(p) => p + case Dummy1855(p) => p + case Dummy1856(p) => p + case Dummy1857(p) => p + case Dummy1858(p) => p + case Dummy1859(p) => p + case Dummy1860(p) => p + case Dummy1861(p) => p + case Dummy1862(p) => p + case Dummy1863(p) => p + case Dummy1864(p) => p + case Dummy1865(p) => p + case Dummy1866(p) => p + case Dummy1867(p) => p + case Dummy1868(p) => p + case Dummy1869(p) => p + case Dummy1870(p) => p + case Dummy1871(p) => p + case Dummy1872(p) => p + case Dummy1873(p) => p + case Dummy1874(p) => p + case Dummy1875(p) => p + case Dummy1876(p) => p + case Dummy1877(p) => p + case Dummy1878(p) => p + case Dummy1879(p) => p + case Dummy1880(p) => p + case Dummy1881(p) => p + case Dummy1882(p) => p + case Dummy1883(p) => p + case Dummy1884(p) => p + case Dummy1885(p) => p + case Dummy1886(p) => p + case Dummy1887(p) => p + case Dummy1888(p) => p + case Dummy1889(p) => p + case Dummy1890(p) => p + case Dummy1891(p) => p + case Dummy1892(p) => p + case Dummy1893(p) => p + case Dummy1894(p) => p + case Dummy1895(p) => p + case Dummy1896(p) => p + case Dummy1897(p) => p + case Dummy1898(p) => p + case Dummy1899(p) => p + case Dummy1900(p) => p + case Dummy1901(p) => p + case Dummy1902(p) => p + case Dummy1903(p) => p + case Dummy1904(p) => p + case Dummy1905(p) => p + case Dummy1906(p) => p + case Dummy1907(p) => p + case Dummy1908(p) => p + case Dummy1909(p) => p + case Dummy1910(p) => p + case Dummy1911(p) => p + case Dummy1912(p) => p + case Dummy1913(p) => p + case Dummy1914(p) => p + case Dummy1915(p) => p + case Dummy1916(p) => p + case Dummy1917(p) => p + case Dummy1918(p) => p + case Dummy1919(p) => p + case Dummy1920(p) => p + case Dummy1921(p) => p + case Dummy1922(p) => p + case Dummy1923(p) => p + case Dummy1924(p) => p + case Dummy1925(p) => p + case Dummy1926(p) => p + case Dummy1927(p) => p + case Dummy1928(p) => p + case Dummy1929(p) => p + case Dummy1930(p) => p + case Dummy1931(p) => p + case Dummy1932(p) => p + case Dummy1933(p) => p + case Dummy1934(p) => p + case Dummy1935(p) => p + case Dummy1936(p) => p + case Dummy1937(p) => p + case Dummy1938(p) => p + case Dummy1939(p) => p + case Dummy1940(p) => p + case Dummy1941(p) => p + case Dummy1942(p) => p + case Dummy1943(p) => p + case Dummy1944(p) => p + case Dummy1945(p) => p + case Dummy1946(p) => p + case Dummy1947(p) => p + case Dummy1948(p) => p + case Dummy1949(p) => p + case Dummy1950(p) => p + case Dummy1951(p) => p + case Dummy1952(p) => p + case Dummy1953(p) => p + case Dummy1954(p) => p + case Dummy1955(p) => p + case Dummy1956(p) => p + case Dummy1957(p) => p + case Dummy1958(p) => p + case Dummy1959(p) => p + case Dummy1960(p) => p + case Dummy1961(p) => p + case Dummy1962(p) => p + case Dummy1963(p) => p + case Dummy1964(p) => p + case Dummy1965(p) => p + case Dummy1966(p) => p + case Dummy1967(p) => p + case Dummy1968(p) => p + case Dummy1969(p) => p + case Dummy1970(p) => p + case Dummy1971(p) => p + case Dummy1972(p) => p + case Dummy1973(p) => p + case Dummy1974(p) => p + case Dummy1975(p) => p + case Dummy1976(p) => p + case Dummy1977(p) => p + case Dummy1978(p) => p + case Dummy1979(p) => p + case Dummy1980(p) => p + case Dummy1981(p) => p + case Dummy1982(p) => p + case Dummy1983(p) => p + case Dummy1984(p) => p + case Dummy1985(p) => p + case Dummy1986(p) => p + case Dummy1987(p) => p + case Dummy1988(p) => p + case Dummy1989(p) => p + case Dummy1990(p) => p + case Dummy1991(p) => p + case Dummy1992(p) => p + case Dummy1993(p) => p + case Dummy1994(p) => p + case Dummy1995(p) => p + case Dummy1996(p) => p + case Dummy1997(p) => p + case Dummy1998(p) => p + case Dummy1999(p) => p +} +} diff --git a/test/disabled/presentation/akka/src/akka/dispatch/Dispatchers.scala b/test/disabled/presentation/akka/src/akka/dispatch/Dispatchers.scala index 7dd1bf6218..a567d0bcb0 100644 --- a/test/disabled/presentation/akka/src/akka/dispatch/Dispatchers.scala +++ b/test/disabled/presentation/akka/src/akka/dispatch/Dispatchers.scala @@ -89,7 +89,7 @@ object Dispatchers { new ThreadBasedDispatcher(actor, mailboxCapacity, pushTimeOut) /** - * Creates a executor-based event-driven dispatcher serving multiple (millions) of actors through a thread pool. + * Creates an executor-based event-driven dispatcher serving multiple (millions) of actors through a thread pool. * <p/> * Has a fluent builder interface for configuring its semantics. */ @@ -97,7 +97,7 @@ object Dispatchers { ThreadPoolConfigDispatcherBuilder(config => new ExecutorBasedEventDrivenDispatcher(name, config), ThreadPoolConfig()) /** - * Creates a executor-based event-driven dispatcher serving multiple (millions) of actors through a thread pool. + * Creates an executor-based event-driven dispatcher serving multiple (millions) of actors through a thread pool. * <p/> * Has a fluent builder interface for configuring its semantics. */ @@ -106,7 +106,7 @@ object Dispatchers { new ExecutorBasedEventDrivenDispatcher(name, throughput, THROUGHPUT_DEADLINE_TIME_MILLIS, mailboxType, config), ThreadPoolConfig()) /** - * Creates a executor-based event-driven dispatcher serving multiple (millions) of actors through a thread pool. + * Creates an executor-based event-driven dispatcher serving multiple (millions) of actors through a thread pool. * <p/> * Has a fluent builder interface for configuring its semantics. */ @@ -115,7 +115,7 @@ object Dispatchers { new ExecutorBasedEventDrivenDispatcher(name, throughput, throughputDeadlineMs, mailboxType, config), ThreadPoolConfig()) /** - * Creates a executor-based event-driven dispatcher, with work-stealing, serving multiple (millions) of actors through a thread pool. + * Creates an executor-based event-driven dispatcher, with work-stealing, serving multiple (millions) of actors through a thread pool. * <p/> * Has a fluent builder interface for configuring its semantics. */ @@ -123,7 +123,7 @@ object Dispatchers { ThreadPoolConfigDispatcherBuilder(config => new ExecutorBasedEventDrivenWorkStealingDispatcher(name, config), ThreadPoolConfig()) /** - * Creates a executor-based event-driven dispatcher, with work-stealing, serving multiple (millions) of actors through a thread pool. + * Creates an executor-based event-driven dispatcher, with work-stealing, serving multiple (millions) of actors through a thread pool. * <p/> * Has a fluent builder interface for configuring its semantics. */ @@ -132,7 +132,7 @@ object Dispatchers { new ExecutorBasedEventDrivenWorkStealingDispatcher(name, throughput, THROUGHPUT_DEADLINE_TIME_MILLIS, MAILBOX_TYPE, config), ThreadPoolConfig()) /** - * Creates a executor-based event-driven dispatcher, with work-stealing, serving multiple (millions) of actors through a thread pool. + * Creates an executor-based event-driven dispatcher, with work-stealing, serving multiple (millions) of actors through a thread pool. * <p/> * Has a fluent builder interface for configuring its semantics. */ @@ -141,7 +141,7 @@ object Dispatchers { new ExecutorBasedEventDrivenWorkStealingDispatcher(name, throughput, THROUGHPUT_DEADLINE_TIME_MILLIS, mailboxType, config), ThreadPoolConfig()) /** - * Creates a executor-based event-driven dispatcher, with work-stealing, serving multiple (millions) of actors through a thread pool. + * Creates an executor-based event-driven dispatcher, with work-stealing, serving multiple (millions) of actors through a thread pool. * <p/> * Has a fluent builder interface for configuring its semantics. */ @@ -224,4 +224,4 @@ class ExecutorBasedEventDrivenWorkStealingDispatcherConfigurator extends Message mailboxType(config), threadPoolConfig)).build } -}
\ No newline at end of file +} diff --git a/test/disabled/run/t6987.check b/test/disabled/run/t6987.check new file mode 100644 index 0000000000..86fc96c679 --- /dev/null +++ b/test/disabled/run/t6987.check @@ -0,0 +1 @@ +got successful verbose results! diff --git a/test/disabled/run/t6987.scala b/test/disabled/run/t6987.scala new file mode 100644 index 0000000000..37e91d61ae --- /dev/null +++ b/test/disabled/run/t6987.scala @@ -0,0 +1,43 @@ +import java.io._ +import tools.nsc.{CompileClient, CompileServer} +import java.util.concurrent.{CountDownLatch, TimeUnit} + +object Test extends App { + val startupLatch = new CountDownLatch(1) + // we have to explicitly launch our server because when the client launches a server it uses + // the "scala" shell command meaning whatever version of scala (and whatever version of libraries) + // happens to be in the path gets used + val t = new Thread(new Runnable { + def run() = { + CompileServer.execute(() => startupLatch.countDown(), Array[String]()) + } + }) + t setDaemon true + t.start() + if (!startupLatch.await(2, TimeUnit.MINUTES)) + sys error "Timeout waiting for server to start" + + val baos = new ByteArrayOutputStream() + val ps = new PrintStream(baos) + + val success = (scala.Console withOut ps) { + // shut down the server via the client using the verbose flag + CompileClient.process(Array("-shutdown", "-verbose")) + } + + // now make sure we got success and a verbose result + val msg = baos.toString() + + if (success) { + if (msg contains "Settings after normalizing paths") { + println("got successful verbose results!") + } else { + println("did not get the string expected, full results were:") + println(msg) + } + } else { + println("got a failure. Full results were:") + println(msg) + } + scala.Console.flush +} diff --git a/test/files/disabled/run/t4602.scala b/test/files/disabled/run/t4602.scala new file mode 100644 index 0000000000..73ba231ccf --- /dev/null +++ b/test/files/disabled/run/t4602.scala @@ -0,0 +1,57 @@ +import java.io.{File, FileOutputStream, BufferedOutputStream, FileWriter, ByteArrayOutputStream, PrintStream} +import tools.nsc.{CompileClient, CompileServer} +import java.util.concurrent.{CountDownLatch, TimeUnit} + +object Test extends App { + val startupLatch = new CountDownLatch(1) + // we have to explicitly launch our server because when the client launches a server it uses + // the "scala" shell command meaning whatever version of scala (and whatever version of libraries) + // happens to be in the path gets used + val t = new Thread(new Runnable { + def run() = { + CompileServer.execute(() => startupLatch.countDown(), Array[String]()) + } + }) + t setDaemon true + t.start() + if (!startupLatch.await(2, TimeUnit.MINUTES)) + sys error "Timeout waiting for server to start" + + val baos = new ByteArrayOutputStream() + val ps = new PrintStream(baos) + + val outdir = scala.reflect.io.Directory(sys.props("partest.output")) + + val dirNameAndPath = (1 to 2).toList map {number => + val name = s"Hello${number}" + val dir = outdir / number.toString + (dir, name, dir / s"${name}.scala") + } + + dirNameAndPath foreach {case (dir, name, path) => + dir.createDirectory() + val file = path.jfile + val out = new FileWriter(file) + try + out.write(s"object ${name}\n") + finally + out.close + } + + val success = (scala.Console withOut ps) { + dirNameAndPath foreach {case (path, name, _) => + CompileClient.process(Array("-verbose", "-current-dir", path.toString, s"${name}.scala")) + } + + CompileClient.process(Array("-shutdown")) + } + + // now make sure we got success and the correct normalized paths + val msg = baos.toString() + + assert(success, s"got a failure. Full results were: \n${msg}") + dirNameAndPath foreach {case (_, _, path) => + val expected = s"Input files after normalizing paths: ${path}" + assert(msg contains expected, s"could not find '${expected}' in output. Full results were: \n${msg}") + } +} diff --git a/test/files/jvm/bytecode-test-example.check b/test/files/jvm/bytecode-test-example.check new file mode 100644 index 0000000000..0cfbf08886 --- /dev/null +++ b/test/files/jvm/bytecode-test-example.check @@ -0,0 +1 @@ +2 diff --git a/test/files/jvm/bytecode-test-example/Foo_1.scala b/test/files/jvm/bytecode-test-example/Foo_1.scala new file mode 100644 index 0000000000..4f679d156f --- /dev/null +++ b/test/files/jvm/bytecode-test-example/Foo_1.scala @@ -0,0 +1,9 @@ +class Foo_1 { + def foo(x: AnyRef): Int = { + val bool = x == null + if (x != null) + 1 + else + 0 + } +} diff --git a/test/files/jvm/bytecode-test-example/Test.scala b/test/files/jvm/bytecode-test-example/Test.scala new file mode 100644 index 0000000000..d668059cb7 --- /dev/null +++ b/test/files/jvm/bytecode-test-example/Test.scala @@ -0,0 +1,32 @@ +import scala.tools.partest.BytecodeTest + +import scala.tools.nsc.util.JavaClassPath +import java.io.InputStream +import scala.tools.asm +import asm.ClassReader +import asm.tree.{ClassNode, InsnList} +import scala.collection.JavaConverters._ + +object Test extends BytecodeTest { + def show: Unit = { + val classNode = loadClassNode("Foo_1") + val methodNode = getMethod(classNode, "foo") + println(countNullChecks(methodNode.instructions)) + } + + def countNullChecks(insnList: InsnList): Int = { + /** Is given instruction a null check? + * NOTE + * This will detect direct null compparsion as in + * if (x == null) ... + * and not indirect as in + * val foo = null + * if (x == foo) ... + */ + def isNullCheck(node: asm.tree.AbstractInsnNode): Boolean = { + val opcode = node.getOpcode + (opcode == asm.Opcodes.IFNULL) || (opcode == asm.Opcodes.IFNONNULL) + } + insnList.iterator.asScala.count(isNullCheck) + } +} diff --git a/test/files/jvm/manifests-new.scala b/test/files/jvm/manifests-new.scala index f730be67bb..3937fdec69 100644 --- a/test/files/jvm/manifests-new.scala +++ b/test/files/jvm/manifests-new.scala @@ -56,7 +56,7 @@ object Test1 extends TestUtil { } object Test2 { - import scala.util.Marshal._ + import Marshal._ println("()="+load[Unit](dump(()))) println("true="+load[Boolean](dump(true))) println("a="+load[Char](dump('a'))) @@ -88,6 +88,38 @@ object Test2 { println() } +object Marshal { + import java.io._ + import scala.reflect.ClassTag + + def dump[A](o: A)(implicit t: ClassTag[A]): Array[Byte] = { + val ba = new ByteArrayOutputStream(512) + val out = new ObjectOutputStream(ba) + out.writeObject(t) + out.writeObject(o) + out.close() + ba.toByteArray() + } + + @throws(classOf[IOException]) + @throws(classOf[ClassCastException]) + @throws(classOf[ClassNotFoundException]) + def load[A](buffer: Array[Byte])(implicit expected: ClassTag[A]): A = { + val in = new ObjectInputStream(new ByteArrayInputStream(buffer)) + val found = in.readObject.asInstanceOf[ClassTag[_]] + try { + found.runtimeClass.asSubclass(expected.runtimeClass) + in.readObject.asInstanceOf[A] + } catch { + case _: ClassCastException => + in.close() + throw new ClassCastException("type mismatch;"+ + "\n found : "+found+ + "\n required: "+expected) + } + } +} + trait TestUtil { import java.io._ def write[A](o: A): Array[Byte] = { diff --git a/test/files/jvm/manifests-old.scala b/test/files/jvm/manifests-old.scala index 241966fd9d..bb1928f094 100644 --- a/test/files/jvm/manifests-old.scala +++ b/test/files/jvm/manifests-old.scala @@ -55,7 +55,7 @@ object Test1 extends TestUtil { } object Test2 { - import scala.util.Marshal._ + import Marshal._ println("()="+load[Unit](dump(()))) println("true="+load[Boolean](dump(true))) println("a="+load[Char](dump('a'))) @@ -87,6 +87,38 @@ object Test2 { println() } +object Marshal { + import java.io._ + import scala.reflect.ClassTag + + def dump[A](o: A)(implicit t: ClassTag[A]): Array[Byte] = { + val ba = new ByteArrayOutputStream(512) + val out = new ObjectOutputStream(ba) + out.writeObject(t) + out.writeObject(o) + out.close() + ba.toByteArray() + } + + @throws(classOf[IOException]) + @throws(classOf[ClassCastException]) + @throws(classOf[ClassNotFoundException]) + def load[A](buffer: Array[Byte])(implicit expected: ClassTag[A]): A = { + val in = new ObjectInputStream(new ByteArrayInputStream(buffer)) + val found = in.readObject.asInstanceOf[ClassTag[_]] + try { + found.runtimeClass.asSubclass(expected.runtimeClass) + in.readObject.asInstanceOf[A] + } catch { + case _: ClassCastException => + in.close() + throw new ClassCastException("type mismatch;"+ + "\n found : "+found+ + "\n required: "+expected) + } + } +} + trait TestUtil { import java.io._ def write[A](o: A): Array[Byte] = { diff --git a/test/files/jvm/scala-concurrent-tck.scala b/test/files/jvm/scala-concurrent-tck.scala index b529bca38a..b2b4183564 100644 --- a/test/files/jvm/scala-concurrent-tck.scala +++ b/test/files/jvm/scala-concurrent-tck.scala @@ -134,6 +134,12 @@ trait FutureCallbacks extends TestBase { assert(false) } } + + def testThatNestedCallbacksDoNotYieldStackOverflow(): Unit = { + val promise = Promise[Int] + (0 to 10000).map(Future(_)).foldLeft(promise.future)((f1, f2) => f2.flatMap(i => f1)) + promise.success(-1) + } testOnSuccess() testOnSuccessWhenCompleted() @@ -143,6 +149,7 @@ trait FutureCallbacks extends TestBase { // testOnFailureWhenSpecialThrowable(6, new scala.util.control.ControlThrowable { }) //TODO: this test is currently problematic, because NonFatal does not match InterruptedException //testOnFailureWhenSpecialThrowable(7, new InterruptedException) + testThatNestedCallbacksDoNotYieldStackOverflow() testOnFailureWhenTimeoutException() } diff --git a/test/files/jvm/throws-annot-from-java.check b/test/files/jvm/throws-annot-from-java.check new file mode 100644 index 0000000000..be3ba412f8 --- /dev/null +++ b/test/files/jvm/throws-annot-from-java.check @@ -0,0 +1,47 @@ +Type in expressions to have them evaluated. +Type :help for more information. + +scala> :power +** Power User mode enabled - BEEP WHIR GYVE ** +** :phase has been set to 'typer'. ** +** scala.tools.nsc._ has been imported ** +** global._, definitions._ also imported ** +** Try :help, :vals, power.<tab> ** + +scala> :paste +// Entering paste mode (ctrl-D to finish) + +{ + val clazz = rootMirror.getClassByName(newTermName("test.ThrowsDeclaration_2")); + { + val method = clazz.info.member(newTermName("foo")) + val throwsAnn = method.annotations.head + val atp = throwsAnn.atp + println("foo") + println("atp.typeParams.isEmpty: " + atp.typeParams.isEmpty) + println(throwsAnn) + } + println + + { + val method = clazz.info.member(newTermName("bar")) + val throwsAnn = method.annotations.head + val Literal(const) = throwsAnn.args.head + val tp = const.typeValue + println("bar") + println("tp.typeParams.isEmpty: " + tp.typeParams.isEmpty) + println(throwsAnn) + } +} + +// Exiting paste mode, now interpreting. + +foo +atp.typeParams.isEmpty: true +throws[IllegalStateException](classOf[java.lang.IllegalStateException]) + +bar +tp.typeParams.isEmpty: true +throws[test.PolymorphicException[_]](classOf[test.PolymorphicException]) + +scala> diff --git a/test/files/jvm/throws-annot-from-java/PolymorphicException_1.scala b/test/files/jvm/throws-annot-from-java/PolymorphicException_1.scala new file mode 100644 index 0000000000..58fa536f0b --- /dev/null +++ b/test/files/jvm/throws-annot-from-java/PolymorphicException_1.scala @@ -0,0 +1,3 @@ +package test + +class PolymorphicException[T] extends Exception diff --git a/test/files/jvm/throws-annot-from-java/Test_3.scala b/test/files/jvm/throws-annot-from-java/Test_3.scala new file mode 100644 index 0000000000..de1d984573 --- /dev/null +++ b/test/files/jvm/throws-annot-from-java/Test_3.scala @@ -0,0 +1,29 @@ +import scala.tools.partest.ReplTest + +object Test extends ReplTest { + def code = """:power +:paste +{ + val clazz = rootMirror.getClassByName(newTermName("test.ThrowsDeclaration_2")); + { + val method = clazz.info.member(newTermName("foo")) + val throwsAnn = method.annotations.head + val atp = throwsAnn.atp + println("foo") + println("atp.typeParams.isEmpty: " + atp.typeParams.isEmpty) + println(throwsAnn) + } + println + + { + val method = clazz.info.member(newTermName("bar")) + val throwsAnn = method.annotations.head + val Literal(const) = throwsAnn.args.head + val tp = const.typeValue + println("bar") + println("tp.typeParams.isEmpty: " + tp.typeParams.isEmpty) + println(throwsAnn) + } +} +""" +} diff --git a/test/files/jvm/throws-annot-from-java/ThrowsDeclaration_2.java b/test/files/jvm/throws-annot-from-java/ThrowsDeclaration_2.java new file mode 100644 index 0000000000..3708fe626b --- /dev/null +++ b/test/files/jvm/throws-annot-from-java/ThrowsDeclaration_2.java @@ -0,0 +1,6 @@ +package test; + +public class ThrowsDeclaration_2 { + public void foo() throws IllegalStateException {}; + public void bar() throws PolymorphicException {}; +} diff --git a/test/files/neg/annot-nonconst.check b/test/files/neg/annot-nonconst.check index b43e58a0ca..5b3da7a13c 100644 --- a/test/files/neg/annot-nonconst.check +++ b/test/files/neg/annot-nonconst.check @@ -8,7 +8,7 @@ make your annotation visible at runtime. If that is what you want, you must write the annotation class in Java. class Ann2(value: String) extends annotation.ClassfileAnnotation ^ -annot-nonconst.scala:6: error: annotation argument needs to be a constant; found: n +annot-nonconst.scala:6: error: annotation argument needs to be a constant; found: Test.this.n @Length(n) def foo = "foo" ^ annot-nonconst.scala:7: error: annotation argument cannot be null diff --git a/test/files/neg/catch-all.check b/test/files/neg/catch-all.check index 2d58dd99a8..aaf51480c3 100644 --- a/test/files/neg/catch-all.check +++ b/test/files/neg/catch-all.check @@ -1,13 +1,10 @@ -catch-all.scala:2: warning: This catches all Throwables, which often has undesirable consequences. -If intentional, use `case _ : Throwable` to clear this warning. +catch-all.scala:2: warning: This catches all Throwables. If this is really intended, use `case _ : Throwable` to clear this warning. try { "warn" } catch { case _ => } ^ -catch-all.scala:4: warning: This catches all Throwables, which often has undesirable consequences. -If intentional, use `case x : Throwable` to clear this warning. +catch-all.scala:4: warning: This catches all Throwables. If this is really intended, use `case x : Throwable` to clear this warning. try { "warn" } catch { case x => } ^ -catch-all.scala:6: warning: This catches all Throwables, which often has undesirable consequences. -If intentional, use `case x : Throwable` to clear this warning. +catch-all.scala:6: warning: This catches all Throwables. If this is really intended, use `case x : Throwable` to clear this warning. try { "warn" } catch { case _: RuntimeException => ; case x => } ^ error: No warnings can be incurred under -Xfatal-warnings. diff --git a/test/files/neg/javaConversions-2.10-ambiguity.check b/test/files/neg/javaConversions-2.10-ambiguity.check deleted file mode 100644 index c064a22964..0000000000 --- a/test/files/neg/javaConversions-2.10-ambiguity.check +++ /dev/null @@ -1,6 +0,0 @@ -javaConversions-2.10-ambiguity.scala:8: error: type mismatch; - found : scala.collection.concurrent.Map[String,String] - required: scala.collection.mutable.ConcurrentMap[String,String] - assertType[mutable.ConcurrentMap[String, String]](a) - ^ -one error found diff --git a/test/files/neg/names-defaults-neg.check b/test/files/neg/names-defaults-neg.check index 6f9dc7d127..f6bd703e1f 100644 --- a/test/files/neg/names-defaults-neg.check +++ b/test/files/neg/names-defaults-neg.check @@ -134,9 +134,17 @@ names-defaults-neg.scala:144: error: variable definition needs type because 'x' names-defaults-neg.scala:147: error: variable definition needs type because 'x' is used as a named argument in its body. object t6 { var x = t.f(x = 1) } ^ +names-defaults-neg.scala:147: warning: type-checking the invocation of method f checks if the named argument expression 'x = ...' is a valid assignment +in the current scope. The resulting type inference error (see above) can be fixed by providing an explicit type in the local definition for x. + object t6 { var x = t.f(x = 1) } + ^ names-defaults-neg.scala:150: error: variable definition needs type because 'x' is used as a named argument in its body. class t9 { var x = t.f(x = 1) } ^ +names-defaults-neg.scala:150: warning: type-checking the invocation of method f checks if the named argument expression 'x = ...' is a valid assignment +in the current scope. The resulting type inference error (see above) can be fixed by providing an explicit type in the local definition for x. + class t9 { var x = t.f(x = 1) } + ^ names-defaults-neg.scala:164: error: variable definition needs type because 'x' is used as a named argument in its body. def u3 { var x = u.f(x = 1) } ^ @@ -156,5 +164,5 @@ in the current scope. The resulting type inference error (see above) can be fixe names-defaults-neg.scala:180: error: reference to x is ambiguous; it is both a method parameter and a variable in scope. class u18 { var x: Int = u.f(x = 1) } ^ -two warnings found +four warnings found 41 errors found diff --git a/test/files/neg/nested-annotation.check b/test/files/neg/nested-annotation.check new file mode 100644 index 0000000000..ca263943fe --- /dev/null +++ b/test/files/neg/nested-annotation.check @@ -0,0 +1,10 @@ +nested-annotation.scala:3: warning: Implementation restriction: subclassing Classfile does not +make your annotation visible at runtime. If that is what +you want, you must write the annotation class in Java. +class ComplexAnnotation(val value: Annotation) extends ClassfileAnnotation + ^ +nested-annotation.scala:8: error: nested classfile annotations must be defined in java; found: inline + @ComplexAnnotation(new inline) def bippy(): Int = 1 + ^ +one warning found +one error found diff --git a/test/files/neg/nested-annotation.scala b/test/files/neg/nested-annotation.scala new file mode 100644 index 0000000000..35c0cd3b75 --- /dev/null +++ b/test/files/neg/nested-annotation.scala @@ -0,0 +1,9 @@ +import annotation._ + +class ComplexAnnotation(val value: Annotation) extends ClassfileAnnotation + +class A { + // It's hard to induce this error because @ComplexAnnotation(@inline) is a parse + // error so it never gets out of the parser, but: + @ComplexAnnotation(new inline) def bippy(): Int = 1 +} diff --git a/test/files/neg/nonlocal-warning.check b/test/files/neg/nonlocal-warning.check index 67b3b10095..5202df655a 100644 --- a/test/files/neg/nonlocal-warning.check +++ b/test/files/neg/nonlocal-warning.check @@ -1,5 +1,4 @@ -nonlocal-warning.scala:4: warning: This catches all Throwables, which often has undesirable consequences. -If intentional, use `case x : Throwable` to clear this warning. +nonlocal-warning.scala:4: warning: This catches all Throwables. If this is really intended, use `case x : Throwable` to clear this warning. catch { case x => 11 } ^ nonlocal-warning.scala:2: warning: catch block may intercept non-local return from method foo diff --git a/test/files/neg/t2641.check b/test/files/neg/t2641.check index 909f4f0cf3..a0a960f0ea 100644 --- a/test/files/neg/t2641.check +++ b/test/files/neg/t2641.check @@ -1,15 +1,7 @@ t2641.scala:18: error: wrong number of type arguments for ManagedSeq, should be 2 with TraversableViewLike[A, ManagedSeqStrict[A], ManagedSeq[A]] ^ -t2641.scala:16: error: illegal inheritance; - self-type ManagedSeq does not conform to ManagedSeqStrict[A]'s selftype ManagedSeqStrict[A] - extends ManagedSeqStrict[A] - ^ -t2641.scala:17: error: illegal inheritance; - self-type ManagedSeq does not conform to scala.collection.TraversableView[A,ManagedSeqStrict[A]]'s selftype scala.collection.TraversableView[A,ManagedSeqStrict[A]] - with TraversableView[A, ManagedSeqStrict[A]] - ^ -t2641.scala:27: error: value managedIterator is not a member of ManagedSeq +t2641.scala:27: error: value managedIterator is not a member of ManagedSeq[A,Coll] override def managedIterator = self.managedIterator slice (from, until) ^ -four errors found +two errors found diff --git a/test/files/neg/t4851.check b/test/files/neg/t4851.check index 0fd66b9efe..4f2919807e 100644 --- a/test/files/neg/t4851.check +++ b/test/files/neg/t4851.check @@ -40,6 +40,12 @@ S.scala:10: warning: Adapting argument list by inserting (): this is unlikely to after adaptation: new J2((): Unit) val z2 = new J2() ^ +S.scala:14: warning: Adapting argument list by creating a 3-tuple: this may not be what you want. + signature: Test.anyId(a: Any): Any + given arguments: 1, 2, 3 + after adaptation: Test.anyId((1, 2, 3): (Int, Int, Int)) + val w1 = anyId(1, 2 ,3) + ^ error: No warnings can be incurred under -Xfatal-warnings. -7 warnings found +8 warnings found one error found diff --git a/test/files/neg/t4851/S.scala b/test/files/neg/t4851/S.scala index 1550892967..0a442ac7a9 100644 --- a/test/files/neg/t4851/S.scala +++ b/test/files/neg/t4851/S.scala @@ -10,6 +10,9 @@ object Test { val z2 = new J2() val z3 = new J2(()) + def anyId(a: Any) = a + val w1 = anyId(1, 2 ,3) + def main(args: Array[String]): Unit = { println(x1) println(x2) @@ -19,5 +22,7 @@ object Test { println(z1) println(z2) println(z3) + + println(w1) } } diff --git a/test/files/neg/t5182.check b/test/files/neg/t5182.check new file mode 100644 index 0000000000..3161f92680 --- /dev/null +++ b/test/files/neg/t5182.check @@ -0,0 +1,7 @@ +t5182.scala:2: error: unknown annotation argument name: qwe + @java.lang.Deprecated(qwe = "wer") def ok(q:Int) = 1 + ^ +t5182.scala:3: error: classfile annotation arguments have to be supplied as named arguments + @java.lang.Deprecated("wer") def whereAmI(q:Int) = 1 + ^ +two errors found diff --git a/test/files/neg/t5182.flags b/test/files/neg/t5182.flags new file mode 100644 index 0000000000..85d8eb2ba2 --- /dev/null +++ b/test/files/neg/t5182.flags @@ -0,0 +1 @@ +-Xfatal-warnings diff --git a/test/files/neg/t5182.scala b/test/files/neg/t5182.scala new file mode 100644 index 0000000000..0687e99efb --- /dev/null +++ b/test/files/neg/t5182.scala @@ -0,0 +1,5 @@ +class test { + @java.lang.Deprecated(qwe = "wer") def ok(q:Int) = 1 + @java.lang.Deprecated("wer") def whereAmI(q:Int) = 1 + @java.lang.Deprecated() def bippy(q:Int) = 1 +} diff --git a/test/files/neg/t5543.check b/test/files/neg/t5543.check new file mode 100644 index 0000000000..b61de0f78b --- /dev/null +++ b/test/files/neg/t5543.check @@ -0,0 +1,10 @@ +t5543.scala:3: error: not found: type T + def this(x: T) { this() } + ^ +t5543.scala:11: error: not found: value x + def this(a: Int, b: Int = x) { + ^ +t5543.scala:18: error: not found: value x + def this(a: Int = x) { this() } + ^ +three errors found diff --git a/test/files/neg/t5543.scala b/test/files/neg/t5543.scala new file mode 100644 index 0000000000..4e03e6e114 --- /dev/null +++ b/test/files/neg/t5543.scala @@ -0,0 +1,19 @@ +class C1 { + type T + def this(x: T) { this() } +} + +class C1a[T] { + def this(x: T) { this() } // works, no error here +} + +class C2(x: Int) { + def this(a: Int, b: Int = x) { + this(b) + } +} + +class C3 { + val x = 0 + def this(a: Int = x) { this() } +} diff --git a/test/files/neg/t5753/Impls$class.class b/test/files/neg/t5753/Impls$class.class Binary files differdeleted file mode 100644 index 476329174e..0000000000 --- a/test/files/neg/t5753/Impls$class.class +++ /dev/null diff --git a/test/files/neg/t5753/Impls.class b/test/files/neg/t5753/Impls.class Binary files differdeleted file mode 100644 index dfcf89ed44..0000000000 --- a/test/files/neg/t5753/Impls.class +++ /dev/null diff --git a/test/files/neg/t6040.check b/test/files/neg/t6040.check index f6757f97e3..f91df0c46d 100644 --- a/test/files/neg/t6040.check +++ b/test/files/neg/t6040.check @@ -1,7 +1,9 @@ -error: extension of type scala.Dynamic needs to be enabled +t6040.scala:1: error: extension of type scala.Dynamic needs to be enabled by making the implicit value language.dynamics visible. This can be achieved by adding the import clause 'import scala.language.dynamics' or by setting the compiler option -language:dynamics. See the Scala docs for value scala.language.dynamics for a discussion why the feature needs to be explicitly enabled. +class X extends Dynamic + ^ one error found diff --git a/test/files/neg/t6083.check b/test/files/neg/t6083.check new file mode 100644 index 0000000000..c9b5ba05d3 --- /dev/null +++ b/test/files/neg/t6083.check @@ -0,0 +1,10 @@ +t6083.scala:6: warning: Implementation restriction: subclassing Classfile does not +make your annotation visible at runtime. If that is what +you want, you must write the annotation class in Java. +class annot(value: String) extends annotation.ClassfileAnnotation + ^ +t6083.scala:7: error: annotation argument needs to be a constant; found: conv.i2s(101) +@annot(101) class C + ^ +one warning found +one error found diff --git a/test/files/neg/t6083.scala b/test/files/neg/t6083.scala new file mode 100644 index 0000000000..1de18e6527 --- /dev/null +++ b/test/files/neg/t6083.scala @@ -0,0 +1,7 @@ +object conv { + implicit def i2s(i: Int): String = "" +} +import conv._ + +class annot(value: String) extends annotation.ClassfileAnnotation +@annot(101) class C diff --git a/test/files/neg/t6231.check b/test/files/neg/t6231.check new file mode 100644 index 0000000000..b27961d393 --- /dev/null +++ b/test/files/neg/t6231.check @@ -0,0 +1,6 @@ +t6231.scala:4: error: Implementation restriction: local trait Bug$X$1 is unable to automatically capture the +free variable value ev$1 on behalf of anonymous class anonfun$qux$1. You can manually assign it to a val inside the trait, +and refer that that val in anonymous class anonfun$qux$1. For more details, see SI-6231. + def qux = { () => ev } + ^ +one error found diff --git a/test/files/neg/t6231.scala b/test/files/neg/t6231.scala new file mode 100644 index 0000000000..1e5b4e0e1a --- /dev/null +++ b/test/files/neg/t6231.scala @@ -0,0 +1,15 @@ +object Bug { + def bar(ev: Any) = { + trait X { + def qux = { () => ev } + } + new X {}.qux() + + // workaround + trait Y { + val ev2 = ev // manually capture `ev` so that `ev2` is added to the trait interface. + def qux = { () => ev2 } + } + } +} + diff --git a/test/files/neg/t6406-regextract.check b/test/files/neg/t6406-regextract.check index 19425a68b0..4fea66f760 100644 --- a/test/files/neg/t6406-regextract.check +++ b/test/files/neg/t6406-regextract.check @@ -1,6 +1,7 @@ -t6406-regextract.scala:4: warning: method unapplySeq in class Regex is deprecated: Extracting a match result from anything but a CharSequence or Match is deprecated +t6406-regextract.scala:4: error: cannot resolve overloaded unapply List(1) collect { case r(i) => i } ^ -error: No warnings can be incurred under -Xfatal-warnings. -one warning found -one error found +t6406-regextract.scala:4: error: not found: value i + List(1) collect { case r(i) => i } + ^ +two errors found diff --git a/test/files/neg/t6443c.check b/test/files/neg/t6443c.check new file mode 100644 index 0000000000..7cf8d23f4b --- /dev/null +++ b/test/files/neg/t6443c.check @@ -0,0 +1,7 @@ +t6443c.scala:16: error: double definition: +method foo:(d: B.D)(a: Any)(d2: d.type)Unit and +method foo:(d: B.D)(a: Any, d2: d.type)Unit at line 11 +have same type after erasure: (d: B.D, a: Object, d2: B.D)Unit + def foo(d: D)(a: Any)(d2: d.type): Unit = () + ^ +one error found diff --git a/test/files/neg/t6443c.scala b/test/files/neg/t6443c.scala new file mode 100644 index 0000000000..817224e043 --- /dev/null +++ b/test/files/neg/t6443c.scala @@ -0,0 +1,21 @@ +trait A { + type D >: Null <: C + def foo(d: D)(a: Any, d2: d.type): Unit + trait C { + def bar: Unit = foo(null)(null, null) + } +} +object B extends A { + class D extends C + + def foo(d: D)(a: Any, d2: d.type): Unit = () // Bridge method required here! + + // No bridge method should be added, but we'll be happy enough if + // the "same type after erasure" error kicks in before the duplicated + // bridge causes a problem. + def foo(d: D)(a: Any)(d2: d.type): Unit = () +} + +object Test extends App { + new B.D().bar +} diff --git a/test/files/neg/t6666.check b/test/files/neg/t6666.check new file mode 100644 index 0000000000..d0378173ea --- /dev/null +++ b/test/files/neg/t6666.check @@ -0,0 +1,40 @@ +t6666.scala:23: error: Implementation restriction: access of method x$2 in object O1 from anonymous class 2, would require illegal premature access to object O1 + F.byname(x) + ^ +t6666.scala:30: error: Implementation restriction: access of value x$3 in object O2 from anonymous class 3, would require illegal premature access to object O2 + F.byname(x) + ^ +t6666.scala:37: error: Implementation restriction: access of method x$4 in object O3 from anonymous class 4, would require illegal premature access to object O3 + F.hof(() => x) + ^ +t6666.scala:50: error: Implementation restriction: access of method x$6 in class C1 from anonymous class 7, would require illegal premature access to the unconstructed `this` of class C1 + F.byname(x) + ^ +t6666.scala:54: error: Implementation restriction: access of value x$7 in class C2 from anonymous class 8, would require illegal premature access to the unconstructed `this` of class C2 + F.byname(x) + ^ +t6666.scala:58: error: Implementation restriction: access of method x$8 in class C3 from anonymous class 9, would require illegal premature access to the unconstructed `this` of class C3 + F.hof(() => x) + ^ +t6666.scala:62: error: Implementation restriction: access of method x$9 in class C4 from object Nested$5, would require illegal premature access to the unconstructed `this` of class C4 + object Nested { def xx = x} + ^ +t6666.scala:68: error: Implementation restriction: access of method x$10 in class C5 from object Nested$6, would require illegal premature access to the unconstructed `this` of class C5 + object Nested { def xx = x} + ^ +t6666.scala:83: error: Implementation restriction: access of method x$12 in class C11 from anonymous class 12, would require illegal premature access to the unconstructed `this` of class C11 + F.byname(x) + ^ +t6666.scala:102: error: Implementation restriction: access of method x$13 in class C13 from anonymous class 13, would require illegal premature access to the unconstructed `this` of class C13 + F.hof(() => x) + ^ +t6666.scala:111: error: Implementation restriction: access of method x$14 in class C14 from object Nested$7, would require illegal premature access to the unconstructed `this` of class C14 + object Nested { def xx = x} + ^ +t6666.scala:122: error: Implementation restriction: access of method x$15 in class C15 from object Nested$8, would require illegal premature access to the unconstructed `this` of class C15 + object Nested { def xx = x} + ^ +t6666.scala:131: error: Implementation restriction: access of method foo$1 in class COuter from class CInner$1, would require illegal premature access to the unconstructed `this` of class COuter + class CInner extends C({foo}) + ^ +13 errors found diff --git a/test/files/neg/t6666.scala b/test/files/neg/t6666.scala new file mode 100644 index 0000000000..d37ffaf141 --- /dev/null +++ b/test/files/neg/t6666.scala @@ -0,0 +1,132 @@ +class C(a: Any) +object F { + def byname(a: => Any) = println(a) + def hof(a: () => Any) = println(a()) +} + +class COkay extends C(0) { + def this(a: Any) { + this() + def x = "".toString + F.byname(x) + } +} + +// +// The thunk's apply method accesses the MODULE$ +// field before it is set. +// +// 0: getstatic #23; //Field O1$.MODULE$:LO1$; +// 3: invokevirtual #26; //Method O1$.O1$$x$1:()Ljava/lang/String; +object O1 extends C({ + def x = "".toString + F.byname(x) +}) + +// java.lang.NullPointerException +// at O2$$anonfun$$init$$1.apply(<console>:11) +object O2 extends C({ + lazy val x = "".toString + F.byname(x) +}) + +// java.lang.NullPointerException +// at O3$$anonfun$$init$$1.apply(<console>:11) +object O3 extends C({ + def x = "".toString + F.hof(() => x) +}) + +// Okay, the nested classes don't get an outer pointer passed, +// just an extra param for `x: String`. +object O6 extends C({ + val x = "".toString + F.byname(x); F.hof(() => x); (new { val xx = x }.xx) +}) + + +class C1 extends C({ + def x = "".toString + F.byname(x) +}) +class C2 extends C({ + lazy val x = "".toString + F.byname(x) +}) +class C3 extends C({ + def x = "".toString + F.hof(() => x) +}) +class C4 extends C({ + def x = "".toString + object Nested { def xx = x} + Nested.xx +}) +class C5 extends C({ + def x = "".toString + val y = { + object Nested { def xx = x} + Nested.xx + } +}) + +// okay, for same reason as O6 +class C6 extends C({ + val x = "".toString + F.byname(x); F.hof(() => x); (new { val xx = x }.xx) +}) + +class C11(a: Any) { + def this() = { + this({ + def x = "".toString + F.byname(x) + }) + } +} + +// Crashes earlier in lazyVals. +// class C12(a: Any) { +// def this() = { +// this({ +// lazy val x = "".toString +// F.byname(x) +// }) +// } +// } + +class C13(a: Any) { + def this() = { + this({ + def x = "".toString + F.hof(() => x) + }) + } +} + +class C14(a: Any) { + def this() = { + this({ + def x = "".toString + object Nested { def xx = x} + Nested.xx + }) + } +} + +class C15(a: Any) { + def this() = { + this({ + def x = "".toString + val y = { + object Nested { def xx = x} + Nested.xx + } + }) + } +} + +class COuter extends C({ + def foo = 0 + class CInner extends C({foo}) +})
\ No newline at end of file diff --git a/test/files/neg/t6728.check b/test/files/neg/t6728.check new file mode 100644 index 0000000000..d853d6f724 --- /dev/null +++ b/test/files/neg/t6728.check @@ -0,0 +1,4 @@ +t6728.scala:4: error: '(' expected but '}' found. + } + ^ +one error found diff --git a/test/files/neg/t6728.scala b/test/files/neg/t6728.scala new file mode 100644 index 0000000000..ba0b1a0fdf --- /dev/null +++ b/test/files/neg/t6728.scala @@ -0,0 +1,5 @@ +object X { + while(true) { + for + } +} diff --git a/test/files/neg/t6829.check b/test/files/neg/t6829.check index 8ee6d182eb..7c3c66e0f2 100644 --- a/test/files/neg/t6829.check +++ b/test/files/neg/t6829.check @@ -1,6 +1,6 @@ t6829.scala:35: error: type mismatch; found : AgentSimulation.this.state.type (with underlying type G#State) - required: _10.State + required: _9.State lazy val actions: Map[G#Agent,G#Action] = agents.map(a => a -> a.chooseAction(state)).toMap ^ t6829.scala:45: error: trait AgentSimulation takes type parameters @@ -17,12 +17,12 @@ t6829.scala:49: error: not found: value nextState ^ t6829.scala:50: error: type mismatch; found : s.type (with underlying type Any) - required: _54.State where val _54: G + required: _53.State where val _53: G val r = rewards(agent).r(s,a,s2) ^ t6829.scala:51: error: type mismatch; found : s.type (with underlying type Any) - required: _51.State + required: _50.State agent.learn(s,a,s2,r): G#Agent ^ t6829.scala:53: error: not found: value nextState diff --git a/test/files/neg/t6902.check b/test/files/neg/t6902.check new file mode 100644 index 0000000000..ed0ed75303 --- /dev/null +++ b/test/files/neg/t6902.check @@ -0,0 +1,12 @@ +t6902.scala:4: warning: unreachable code + case Some(b) => 3 // no warning was emitted + ^ +t6902.scala:9: warning: unreachable code + case Some(b) => 3 // no warning was emitted + ^ +t6902.scala:21: warning: unreachable code + case 1 => 3 // crash + ^ +error: No warnings can be incurred under -Xfatal-warnings. +three warnings found +one error found diff --git a/test/files/neg/t6902.flags b/test/files/neg/t6902.flags new file mode 100644 index 0000000000..e8fb65d50c --- /dev/null +++ b/test/files/neg/t6902.flags @@ -0,0 +1 @@ +-Xfatal-warnings
\ No newline at end of file diff --git a/test/files/neg/t6902.scala b/test/files/neg/t6902.scala new file mode 100644 index 0000000000..ce5ff8b6fb --- /dev/null +++ b/test/files/neg/t6902.scala @@ -0,0 +1,23 @@ +object Test { + Some(Some(1)) collect { + case Some(a) => 2 + case Some(b) => 3 // no warning was emitted + } + + (Some(1): @ unchecked) match { + case Some(a) => 2 + case Some(b) => 3 // no warning was emitted + } + + // A variation of SI-6011, which eluded the fix + // in 2.10.0. + // + // duplicate keys in SWITCH, can't pick arbitrarily one of them to evict, see SI-6011. + // at scala.reflect.internal.SymbolTable.abort(SymbolTable.scala:50) + // at scala.tools.nsc.Global.abort(Global.scala:249) + // at scala.tools.nsc.backend.jvm.GenASM$JPlainBuilder$jcode$.emitSWITCH(GenASM.scala:1850) + ((1: Byte): @unchecked @annotation.switch) match { + case 1 => 2 + case 1 => 3 // crash + } +} diff --git a/test/files/neg/t6952.check b/test/files/neg/t6952.check new file mode 100644 index 0000000000..f1e1881404 --- /dev/null +++ b/test/files/neg/t6952.check @@ -0,0 +1,13 @@ +t6952.scala:2: error: extension of type scala.Dynamic needs to be enabled +by making the implicit value language.dynamics visible. +This can be achieved by adding the import clause 'import scala.language.dynamics' +or by setting the compiler option -language:dynamics. +See the Scala docs for value scala.language.dynamics for a discussion +why the feature needs to be explicitly enabled. +trait B extends Dynamic + ^ +t6952.scala:3: error: extension of type scala.Dynamic needs to be enabled +by making the implicit value language.dynamics visible. +trait C extends A with Dynamic + ^ +two errors found diff --git a/test/files/neg/t6952.scala b/test/files/neg/t6952.scala new file mode 100644 index 0000000000..257ea3be68 --- /dev/null +++ b/test/files/neg/t6952.scala @@ -0,0 +1,4 @@ +trait A +trait B extends Dynamic +trait C extends A with Dynamic +trait D extends B diff --git a/test/files/neg/t6963.check b/test/files/neg/t6963.check deleted file mode 100644 index cc4a7a48fc..0000000000 --- a/test/files/neg/t6963.check +++ /dev/null @@ -1,4 +0,0 @@ -warning: -Xmigration is deprecated: This setting is no longer useful and will be removed. Please remove it from your build. -error: No warnings can be incurred under -Xfatal-warnings. -one warning found -one error found diff --git a/test/files/neg/t6963.flags b/test/files/neg/t6963.flags deleted file mode 100644 index 0b6d71496a..0000000000 --- a/test/files/neg/t6963.flags +++ /dev/null @@ -1 +0,0 @@ --Xmigration -deprecation -Xfatal-warnings
\ No newline at end of file diff --git a/test/files/neg/t6963.scala b/test/files/neg/t6963.scala deleted file mode 100644 index 4da52764f5..0000000000 --- a/test/files/neg/t6963.scala +++ /dev/null @@ -1,3 +0,0 @@ - -object test { -} diff --git a/test/files/neg/t6963a.check b/test/files/neg/t6963a.check new file mode 100644 index 0000000000..5858e7740a --- /dev/null +++ b/test/files/neg/t6963a.check @@ -0,0 +1,7 @@ +t6963a.scala:4: warning: method scanRight in trait TraversableLike has changed semantics in version 2.9.0: +The behavior of `scanRight` has changed. The previous behavior can be reproduced with scanRight.reverse. + List(1,2,3,4,5).scanRight(0)(_+_) + ^ +error: No warnings can be incurred under -Xfatal-warnings. +one warning found +one error found diff --git a/test/files/neg/t6963a.flags b/test/files/neg/t6963a.flags new file mode 100644 index 0000000000..4c61ed9430 --- /dev/null +++ b/test/files/neg/t6963a.flags @@ -0,0 +1 @@ +-Xfatal-warnings -Xmigration:2.7 diff --git a/test/files/neg/t6963a.scala b/test/files/neg/t6963a.scala new file mode 100644 index 0000000000..b3366b2557 --- /dev/null +++ b/test/files/neg/t6963a.scala @@ -0,0 +1,5 @@ +object Test { + import scala.collection.mutable._ + + List(1,2,3,4,5).scanRight(0)(_+_) +} diff --git a/test/files/pos/annotations.scala b/test/files/pos/annotations.scala index 501e2a6bd3..4832ce4ecd 100644 --- a/test/files/pos/annotations.scala +++ b/test/files/pos/annotations.scala @@ -2,7 +2,7 @@ class ann(i: Int) extends scala.annotation.Annotation class cfann(x: String) extends annotation.ClassfileAnnotation // annotations on abstract types -abstract class C1[@cloneable +T, U, V[_]] +abstract class C1[@annotation.elidable(0) +T, U, V[_]] abstract class C2[@deprecated @ann(1) T <: Number, V] diff --git a/test/files/pos/annotations2.scala b/test/files/pos/annotations2.scala new file mode 100644 index 0000000000..3bce7f8ac4 --- /dev/null +++ b/test/files/pos/annotations2.scala @@ -0,0 +1,31 @@ + +class B[T](x: (T, T)) { + def this(xx: (T, Any, Any)) = this((xx._1, xx._1)) +} +class BAnn[T](x: (T, T)) extends scala.annotation.StaticAnnotation { + def this(xx: (T, Any, Any)) = this((xx._1, xx._1)) +} +class CAnn[T](x: (T, T)) extends scala.annotation.StaticAnnotation { + def this(xx: Class[T]) = this((xx.newInstance(), xx.newInstance())) +} + +class A1 { + val b1 = new B((1, 2, 3)) + val b2 = new B((1, 2)) + val b3 = new B[Int]((1, 2, 3)) + val b4 = new B[Int]((1, 2)) +} + +class A2 { + @BAnn((1, 2, 3)) val b1 = null + @BAnn((1, 2)) val b2 = null + @BAnn[Int]((1, 2, 3)) val b3 = null + @BAnn[Int]((1, 2)) val b4 = null +} + +class A3 { + @CAnn(classOf[Int]) val b1 = null + @CAnn((1, 2)) val b2 = null + @CAnn[Int](classOf[Int]) val b3 = null + @CAnn[Int]((1, 2)) val b4 = null +} diff --git a/test/files/neg/javaConversions-2.10-ambiguity.scala b/test/files/pos/javaConversions-2.10-ambiguity.scala index e856846a29..c4aad6cbfc 100644 --- a/test/files/neg/javaConversions-2.10-ambiguity.scala +++ b/test/files/pos/javaConversions-2.10-ambiguity.scala @@ -5,6 +5,6 @@ import java.util.concurrent.{ConcurrentHashMap => CHM} object Bar { def assertType[T](t: T) = t val a = new CHM[String, String]() += (("", "")) - assertType[mutable.ConcurrentMap[String, String]](a) + assertType[concurrent.Map[String, String]](a) } // vim: set et: diff --git a/test/files/pos/javaConversions-2.10-regression.scala b/test/files/pos/javaConversions-2.10-regression.scala index e1b81015ba..7c7ff03b55 100644 --- a/test/files/pos/javaConversions-2.10-regression.scala +++ b/test/files/pos/javaConversions-2.10-regression.scala @@ -3,10 +3,10 @@ import JavaConversions._ import java.util.concurrent.{ConcurrentHashMap => CHM} object Foo { - def buildCache2_9_simple[K <: AnyRef, V <: AnyRef]: mutable.ConcurrentMap[K, V] = - asScalaConcurrentMap(new CHM()) + def buildCache2_9_simple[K <: AnyRef, V <: AnyRef]: concurrent.Map[K, V] = + mapAsScalaConcurrentMap(new CHM()) - def buildCache2_9_implicit[K <: AnyRef, V <: AnyRef]: mutable.ConcurrentMap[K, V] = + def buildCache2_9_implicit[K <: AnyRef, V <: AnyRef]: concurrent.Map[K, V] = new CHM[K, V]() } diff --git a/test/files/pos/kinds.scala b/test/files/pos/kinds.scala new file mode 100644 index 0000000000..6d6da0c8b6 --- /dev/null +++ b/test/files/pos/kinds.scala @@ -0,0 +1,13 @@ +trait IllKind1 { + def g(s: String): String = s + def f: String = ??? + def f[C](c: C): String = g(f) +} + +trait IllKind2 { + def b1: Char = ??? + def b2: Byte = ??? + + def f1 = "abc" contains b1 + def f2 = "abc" contains b2 +} diff --git a/test/files/pos/lubs.scala b/test/files/pos/lubs.scala new file mode 100644 index 0000000000..d7651f86b0 --- /dev/null +++ b/test/files/pos/lubs.scala @@ -0,0 +1,3 @@ +object Test { + List(new { def f = 1; def g = 1}, new { def f = 2}).map(_.f) +} diff --git a/test/files/pos/presuperContext.scala b/test/files/pos/presuperContext.scala new file mode 100644 index 0000000000..cc34263073 --- /dev/null +++ b/test/files/pos/presuperContext.scala @@ -0,0 +1,13 @@ +class A { + class C extends { val x: A = this } with AnyRef +} + +class B(x: Int) + +class D { + class C(x: Int) extends B({val test: D = this; x}) { + def this() { + this({val test: D = this; 1}) + } + } +} diff --git a/test/files/pos/spec-annotations.scala b/test/files/pos/spec-annotations.scala index 6c1f737470..b23abf48e8 100644 --- a/test/files/pos/spec-annotations.scala +++ b/test/files/pos/spec-annotations.scala @@ -1,7 +1,7 @@ class ann(i: Int) extends scala.annotation.Annotation // annotations on abstract types -abstract class C1[@cloneable +T, U, V[_]] +abstract class C1[@annotation.elidable(0) +T, U, V[_]] abstract class C2[@deprecated @ann(1) T <: Number, V] diff --git a/test/files/pos/spec-arrays.scala b/test/files/pos/spec-arrays.scala index 84f6eef071..7ae2cb1efb 100644 --- a/test/files/pos/spec-arrays.scala +++ b/test/files/pos/spec-arrays.scala @@ -177,38 +177,11 @@ class ScalaSpec3Test extends Test { } } -object TestJava extends scala.testing.Benchmark { - def run() { - (new JavaTest).run() - } -} - -object TestSpec extends scala.testing.Benchmark { - def run() { - (new ScalaSpecTest).run() - } -} - -object TestSpec2 extends scala.testing.Benchmark { - def run() { - (new ScalaSpec2Test).run() - } -} - -object TestGen extends scala.testing.Benchmark { - def run() { - (new ScalaGenTest).run() - } -} - -object TestWrap extends scala.testing.Benchmark { - def run() { - (new ScalaWrapTest).run() - } -} - -object TestSpec3 extends scala.testing.Benchmark { - def run() { - (new ScalaSpec3Test).run() - } +object TestRunner { + (new JavaTest).run() + (new ScalaSpecTest).run() + (new ScalaSpec2Test).run() + (new ScalaGenTest).run() + (new ScalaWrapTest).run() + (new ScalaSpec3Test).run() } diff --git a/test/files/pos/spec-funs.scala b/test/files/pos/spec-funs.scala index 611ec0ef62..b9acbe171a 100644 --- a/test/files/pos/spec-funs.scala +++ b/test/files/pos/spec-funs.scala @@ -54,10 +54,7 @@ final class ClosureTest { } } -object TestInt extends scala.testing.Benchmark { - def run() = (new IntTest).run() -} - -object TestClosure extends scala.testing.Benchmark { - def run() = (new ClosureTest).run() +object TestRunner { + (new IntTest).run() + (new ClosureTest).run() } diff --git a/test/files/pos/t0422.scala b/test/files/pos/t0422.scala index cb3ba279d4..2adfa392d2 100644 --- a/test/files/pos/t0422.scala +++ b/test/files/pos/t0422.scala @@ -1,5 +1,4 @@ -import scala.util.regexp.WordExp; -import scala.util.automata.WordBerrySethi; +package scala.xml.dtd.impl object BoolWordExp extends WordExp { type _labelT = MyLabels; diff --git a/test/files/pos/t1014.scala b/test/files/pos/t1014.scala index 1ac87b225b..3fc10d10dc 100644 --- a/test/files/pos/t1014.scala +++ b/test/files/pos/t1014.scala @@ -1,6 +1,8 @@ import scala.xml.{NodeSeq, Elem} -class EO extends App with Moo{ +class EO extends App with Moo { + // return type is Flog, inherited from overridden method. + // implicit conversions are applied because expected type `pt` is `Flog` when `computeType(rhs, pt)`. def cat = <cat>dog</cat> implicit def nodeSeqToFlog(in: Elem): Flog = new Flog(in) diff --git a/test/files/pos/t1803.flags b/test/files/pos/t1803.flags new file mode 100644 index 0000000000..d1a8244169 --- /dev/null +++ b/test/files/pos/t1803.flags @@ -0,0 +1 @@ +-Yinfer-argument-types
\ No newline at end of file diff --git a/test/files/pos/t1803.scala b/test/files/pos/t1803.scala new file mode 100644 index 0000000000..42f4e784a3 --- /dev/null +++ b/test/files/pos/t1803.scala @@ -0,0 +1,2 @@ +class A { def foo[A](a: A) = a } +class B extends A { override def foo[A](b) = b } diff --git a/test/files/pos/t2421b_pos.scala b/test/files/pos/t2421b_pos.scala index 8b848abb75..0df3461662 100644 --- a/test/files/pos/t2421b_pos.scala +++ b/test/files/pos/t2421b_pos.scala @@ -11,7 +11,7 @@ object Test { f } -/* bug: +/* bug: error: ambiguous implicit values: both method b in object Test1 of type [X <: Test1.B]Test1.F[X] and method a in object Test1 of type => Test1.F[Test1.A] diff --git a/test/files/pos/t2484.scala b/test/files/pos/t2484.scala index 7d1b7cb03c..29f798edf9 100755 --- a/test/files/pos/t2484.scala +++ b/test/files/pos/t2484.scala @@ -1,7 +1,9 @@ +import concurrent.ExecutionContext.Implicits.global + class Admin extends javax.swing.JApplet { val jScrollPane = new javax.swing.JScrollPane (null, 0, 0) def t2484: Unit = { - scala.concurrent.ops.spawn {jScrollPane.synchronized { + scala.concurrent.future {jScrollPane.synchronized { def someFunction () = {} //scala.concurrent.ops.spawn {someFunction ()} jScrollPane.addComponentListener (new java.awt.event.ComponentAdapter {override def componentShown (e: java.awt.event.ComponentEvent) = { diff --git a/test/files/pos/t2698.scala b/test/files/pos/t2698.scala index 0e2662de61..7de50a13d6 100644 --- a/test/files/pos/t2698.scala +++ b/test/files/pos/t2698.scala @@ -1,5 +1,6 @@ +package scala.xml.dtd.impl + import scala.collection._ -import scala.util.regexp._ abstract class S2 { val lang: WordExp diff --git a/test/files/pos/t342.scala b/test/files/pos/t342.scala deleted file mode 100644 index 752b24d2ba..0000000000 --- a/test/files/pos/t342.scala +++ /dev/null @@ -1,8 +0,0 @@ -object Main extends App { - - object Foo extends Enumeration(0, "Bar") { // 2 - val Bar = Value - } - import Foo._; - Console.println(Bar) -} diff --git a/test/files/pos/t3864/tuples_1.scala b/test/files/pos/t3864/tuples_1.scala index 1d19af6e41..5e97f8452b 100644 --- a/test/files/pos/t3864/tuples_1.scala +++ b/test/files/pos/t3864/tuples_1.scala @@ -1,11 +1,11 @@ -trait PimpedType[X] { +trait EnrichedType[X] { val value: X } trait Tuples { - -trait Tuple15W[A, B, C, D, E, F, G, H, I, J, K, L, M, N, O] extends PimpedType[Tuple15[A, B, C, D, E, F, G, H, I, J, K, L, M, N, O]] { + +trait Tuple15W[A, B, C, D, E, F, G, H, I, J, K, L, M, N, O] extends EnrichedType[Tuple15[A, B, C, D, E, F, G, H, I, J, K, L, M, N, O]] { def fold[Z](f: => (A, B, C, D, E, F, G, H, I, J, K, L, M, N, O) => Z): Z = {import value._; f(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15)} def toIndexedSeq[Z](implicit ev: value.type <:< Tuple15[Z, Z, Z, Z, Z, Z, Z, Z, Z, Z, Z, Z, Z, Z, Z]): IndexedSeq[Z] = {val zs = ev(value); import zs._; IndexedSeq(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15)} def mapElements[AA, BB, CC, DD, EE, FF, GG, HH, II, JJ, KK, LL, MM, NN, OO](_1: (A => AA) = identity[A] _, _2: (B => BB) = identity[B] _, _3: (C => CC) = identity[C] _, _4: (D => DD) = identity[D] _, _5: (E => EE) = identity[E] _, _6: (F => FF) = identity[F] _, _7: (G => GG) = identity[G] _, _8: (H => HH) = identity[H] _, _9: (I => II) = identity[I] _, _10: (J => JJ) = identity[J] _, _11: (K => KK) = identity[K] _, _12: (L => LL) = identity[L] _, _13: (M => MM) = identity[M] _, _14: (N => NN) = identity[N] _, _15: (O => OO) = identity[O] _): (AA, BB, CC, DD, EE, FF, GG, HH, II, JJ, KK, LL, MM, NN, OO) = (_1(value._1), _2(value._2), _3(value._3), _4(value._4), _5(value._5), _6(value._6), _7(value._7), _8(value._8), _9(value._9), _10(value._10), _11(value._11), _12(value._12), _13(value._13), _14(value._14), _15(value._15)) @@ -13,8 +13,8 @@ trait Tuple15W[A, B, C, D, E, F, G, H, I, J, K, L, M, N, O] extends PimpedType[T implicit def ToTuple15W[A, B, C, D, E, F, G, H, I, J, K, L, M, N, O](t: (A, B, C, D, E, F, G, H, I, J, K, L, M, N, O)): Tuple15W[A, B, C, D, E, F, G, H, I, J, K, L, M, N, O] = new { val value = t } with Tuple15W[A, B, C, D, E, F, G, H, I, J, K, L, M, N, O] - -trait Tuple16W[A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P] extends PimpedType[Tuple16[A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P]] { + +trait Tuple16W[A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P] extends EnrichedType[Tuple16[A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P]] { def fold[Z](f: => (A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P) => Z): Z = {import value._; f(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16)} def toIndexedSeq[Z](implicit ev: value.type <:< Tuple16[Z, Z, Z, Z, Z, Z, Z, Z, Z, Z, Z, Z, Z, Z, Z, Z]): IndexedSeq[Z] = {val zs = ev(value); import zs._; IndexedSeq(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16)} def mapElements[AA, BB, CC, DD, EE, FF, GG, HH, II, JJ, KK, LL, MM, NN, OO, PP](_1: (A => AA) = identity[A] _, _2: (B => BB) = identity[B] _, _3: (C => CC) = identity[C] _, _4: (D => DD) = identity[D] _, _5: (E => EE) = identity[E] _, _6: (F => FF) = identity[F] _, _7: (G => GG) = identity[G] _, _8: (H => HH) = identity[H] _, _9: (I => II) = identity[I] _, _10: (J => JJ) = identity[J] _, _11: (K => KK) = identity[K] _, _12: (L => LL) = identity[L] _, _13: (M => MM) = identity[M] _, _14: (N => NN) = identity[N] _, _15: (O => OO) = identity[O] _, _16: (P => PP) = identity[P] _): (AA, BB, CC, DD, EE, FF, GG, HH, II, JJ, KK, LL, MM, NN, OO, PP) = (_1(value._1), _2(value._2), _3(value._3), _4(value._4), _5(value._5), _6(value._6), _7(value._7), _8(value._8), _9(value._9), _10(value._10), _11(value._11), _12(value._12), _13(value._13), _14(value._14), _15(value._15), _16(value._16)) @@ -22,8 +22,8 @@ trait Tuple16W[A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P] extends PimpedTyp implicit def ToTuple16W[A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P](t: (A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P)): Tuple16W[A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P] = new { val value = t } with Tuple16W[A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P] - -trait Tuple17W[A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q] extends PimpedType[Tuple17[A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q]] { + +trait Tuple17W[A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q] extends EnrichedType[Tuple17[A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q]] { def fold[Z](f: => (A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q) => Z): Z = {import value._; f(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17)} def toIndexedSeq[Z](implicit ev: value.type <:< Tuple17[Z, Z, Z, Z, Z, Z, Z, Z, Z, Z, Z, Z, Z, Z, Z, Z, Z]): IndexedSeq[Z] = {val zs = ev(value); import zs._; IndexedSeq(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17)} def mapElements[AA, BB, CC, DD, EE, FF, GG, HH, II, JJ, KK, LL, MM, NN, OO, PP, QQ](_1: (A => AA) = identity[A] _, _2: (B => BB) = identity[B] _, _3: (C => CC) = identity[C] _, _4: (D => DD) = identity[D] _, _5: (E => EE) = identity[E] _, _6: (F => FF) = identity[F] _, _7: (G => GG) = identity[G] _, _8: (H => HH) = identity[H] _, _9: (I => II) = identity[I] _, _10: (J => JJ) = identity[J] _, _11: (K => KK) = identity[K] _, _12: (L => LL) = identity[L] _, _13: (M => MM) = identity[M] _, _14: (N => NN) = identity[N] _, _15: (O => OO) = identity[O] _, _16: (P => PP) = identity[P] _, _17: (Q => QQ) = identity[Q] _): (AA, BB, CC, DD, EE, FF, GG, HH, II, JJ, KK, LL, MM, NN, OO, PP, QQ) = (_1(value._1), _2(value._2), _3(value._3), _4(value._4), _5(value._5), _6(value._6), _7(value._7), _8(value._8), _9(value._9), _10(value._10), _11(value._11), _12(value._12), _13(value._13), _14(value._14), _15(value._15), _16(value._16), _17(value._17)) @@ -31,8 +31,8 @@ trait Tuple17W[A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q] extends Pimped implicit def ToTuple17W[A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q](t: (A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q)): Tuple17W[A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q] = new { val value = t } with Tuple17W[A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q] - -trait Tuple18W[A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R] extends PimpedType[Tuple18[A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R]] { + +trait Tuple18W[A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R] extends EnrichedType[Tuple18[A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R]] { def fold[Z](f: => (A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R) => Z): Z = {import value._; f(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18)} def toIndexedSeq[Z](implicit ev: value.type <:< Tuple18[Z, Z, Z, Z, Z, Z, Z, Z, Z, Z, Z, Z, Z, Z, Z, Z, Z, Z]): IndexedSeq[Z] = {val zs = ev(value); import zs._; IndexedSeq(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18)} def mapElements[AA, BB, CC, DD, EE, FF, GG, HH, II, JJ, KK, LL, MM, NN, OO, PP, QQ, RR](_1: (A => AA) = identity[A] _, _2: (B => BB) = identity[B] _, _3: (C => CC) = identity[C] _, _4: (D => DD) = identity[D] _, _5: (E => EE) = identity[E] _, _6: (F => FF) = identity[F] _, _7: (G => GG) = identity[G] _, _8: (H => HH) = identity[H] _, _9: (I => II) = identity[I] _, _10: (J => JJ) = identity[J] _, _11: (K => KK) = identity[K] _, _12: (L => LL) = identity[L] _, _13: (M => MM) = identity[M] _, _14: (N => NN) = identity[N] _, _15: (O => OO) = identity[O] _, _16: (P => PP) = identity[P] _, _17: (Q => QQ) = identity[Q] _, _18: (R => RR) = identity[R] _): (AA, BB, CC, DD, EE, FF, GG, HH, II, JJ, KK, LL, MM, NN, OO, PP, QQ, RR) = (_1(value._1), _2(value._2), _3(value._3), _4(value._4), _5(value._5), _6(value._6), _7(value._7), _8(value._8), _9(value._9), _10(value._10), _11(value._11), _12(value._12), _13(value._13), _14(value._14), _15(value._15), _16(value._16), _17(value._17), _18(value._18)) @@ -40,8 +40,8 @@ trait Tuple18W[A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R] extends Pim implicit def ToTuple18W[A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R](t: (A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R)): Tuple18W[A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R] = new { val value = t } with Tuple18W[A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R] - -trait Tuple19W[A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S] extends PimpedType[Tuple19[A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S]] { + +trait Tuple19W[A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S] extends EnrichedType[Tuple19[A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S]] { def fold[Z](f: => (A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S) => Z): Z = {import value._; f(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19)} def toIndexedSeq[Z](implicit ev: value.type <:< Tuple19[Z, Z, Z, Z, Z, Z, Z, Z, Z, Z, Z, Z, Z, Z, Z, Z, Z, Z, Z]): IndexedSeq[Z] = {val zs = ev(value); import zs._; IndexedSeq(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19)} def mapElements[AA, BB, CC, DD, EE, FF, GG, HH, II, JJ, KK, LL, MM, NN, OO, PP, QQ, RR, SS](_1: (A => AA) = identity[A] _, _2: (B => BB) = identity[B] _, _3: (C => CC) = identity[C] _, _4: (D => DD) = identity[D] _, _5: (E => EE) = identity[E] _, _6: (F => FF) = identity[F] _, _7: (G => GG) = identity[G] _, _8: (H => HH) = identity[H] _, _9: (I => II) = identity[I] _, _10: (J => JJ) = identity[J] _, _11: (K => KK) = identity[K] _, _12: (L => LL) = identity[L] _, _13: (M => MM) = identity[M] _, _14: (N => NN) = identity[N] _, _15: (O => OO) = identity[O] _, _16: (P => PP) = identity[P] _, _17: (Q => QQ) = identity[Q] _, _18: (R => RR) = identity[R] _, _19: (S => SS) = identity[S] _): (AA, BB, CC, DD, EE, FF, GG, HH, II, JJ, KK, LL, MM, NN, OO, PP, QQ, RR, SS) = (_1(value._1), _2(value._2), _3(value._3), _4(value._4), _5(value._5), _6(value._6), _7(value._7), _8(value._8), _9(value._9), _10(value._10), _11(value._11), _12(value._12), _13(value._13), _14(value._14), _15(value._15), _16(value._16), _17(value._17), _18(value._18), _19(value._19)) @@ -49,8 +49,8 @@ trait Tuple19W[A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S] extends implicit def ToTuple19W[A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S](t: (A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S)): Tuple19W[A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S] = new { val value = t } with Tuple19W[A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S] - -trait Tuple20W[A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T] extends PimpedType[Tuple20[A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T]] { + +trait Tuple20W[A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T] extends EnrichedType[Tuple20[A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T]] { def fold[Z](f: => (A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T) => Z): Z = {import value._; f(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20)} def toIndexedSeq[Z](implicit ev: value.type <:< Tuple20[Z, Z, Z, Z, Z, Z, Z, Z, Z, Z, Z, Z, Z, Z, Z, Z, Z, Z, Z, Z]): IndexedSeq[Z] = {val zs = ev(value); import zs._; IndexedSeq(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20)} def mapElements[AA, BB, CC, DD, EE, FF, GG, HH, II, JJ, KK, LL, MM, NN, OO, PP, QQ, RR, SS, TT](_1: (A => AA) = identity[A] _, _2: (B => BB) = identity[B] _, _3: (C => CC) = identity[C] _, _4: (D => DD) = identity[D] _, _5: (E => EE) = identity[E] _, _6: (F => FF) = identity[F] _, _7: (G => GG) = identity[G] _, _8: (H => HH) = identity[H] _, _9: (I => II) = identity[I] _, _10: (J => JJ) = identity[J] _, _11: (K => KK) = identity[K] _, _12: (L => LL) = identity[L] _, _13: (M => MM) = identity[M] _, _14: (N => NN) = identity[N] _, _15: (O => OO) = identity[O] _, _16: (P => PP) = identity[P] _, _17: (Q => QQ) = identity[Q] _, _18: (R => RR) = identity[R] _, _19: (S => SS) = identity[S] _, _20: (T => TT) = identity[T] _): (AA, BB, CC, DD, EE, FF, GG, HH, II, JJ, KK, LL, MM, NN, OO, PP, QQ, RR, SS, TT) = (_1(value._1), _2(value._2), _3(value._3), _4(value._4), _5(value._5), _6(value._6), _7(value._7), _8(value._8), _9(value._9), _10(value._10), _11(value._11), _12(value._12), _13(value._13), _14(value._14), _15(value._15), _16(value._16), _17(value._17), _18(value._18), _19(value._19), _20(value._20)) @@ -58,8 +58,8 @@ trait Tuple20W[A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T] exten implicit def ToTuple20W[A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T](t: (A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T)): Tuple20W[A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T] = new { val value = t } with Tuple20W[A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T] - -trait Tuple21W[A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U] extends PimpedType[Tuple21[A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U]] { + +trait Tuple21W[A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U] extends EnrichedType[Tuple21[A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U]] { def fold[Z](f: => (A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U) => Z): Z = {import value._; f(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21)} def toIndexedSeq[Z](implicit ev: value.type <:< Tuple21[Z, Z, Z, Z, Z, Z, Z, Z, Z, Z, Z, Z, Z, Z, Z, Z, Z, Z, Z, Z, Z]): IndexedSeq[Z] = {val zs = ev(value); import zs._; IndexedSeq(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21)} def mapElements[AA, BB, CC, DD, EE, FF, GG, HH, II, JJ, KK, LL, MM, NN, OO, PP, QQ, RR, SS, TT, UU](_1: (A => AA) = identity[A] _, _2: (B => BB) = identity[B] _, _3: (C => CC) = identity[C] _, _4: (D => DD) = identity[D] _, _5: (E => EE) = identity[E] _, _6: (F => FF) = identity[F] _, _7: (G => GG) = identity[G] _, _8: (H => HH) = identity[H] _, _9: (I => II) = identity[I] _, _10: (J => JJ) = identity[J] _, _11: (K => KK) = identity[K] _, _12: (L => LL) = identity[L] _, _13: (M => MM) = identity[M] _, _14: (N => NN) = identity[N] _, _15: (O => OO) = identity[O] _, _16: (P => PP) = identity[P] _, _17: (Q => QQ) = identity[Q] _, _18: (R => RR) = identity[R] _, _19: (S => SS) = identity[S] _, _20: (T => TT) = identity[T] _, _21: (U => UU) = identity[U] _): (AA, BB, CC, DD, EE, FF, GG, HH, II, JJ, KK, LL, MM, NN, OO, PP, QQ, RR, SS, TT, UU) = (_1(value._1), _2(value._2), _3(value._3), _4(value._4), _5(value._5), _6(value._6), _7(value._7), _8(value._8), _9(value._9), _10(value._10), _11(value._11), _12(value._12), _13(value._13), _14(value._14), _15(value._15), _16(value._16), _17(value._17), _18(value._18), _19(value._19), _20(value._20), _21(value._21)) @@ -67,12 +67,12 @@ trait Tuple21W[A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U] ex implicit def ToTuple21W[A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U](t: (A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U)): Tuple21W[A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U] = new { val value = t } with Tuple21W[A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U] - -trait Tuple22W[A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V] extends PimpedType[Tuple22[A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V]] { + +trait Tuple22W[A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V] extends EnrichedType[Tuple22[A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V]] { def fold[Z](f: => (A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V) => Z): Z = {import value._; f(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22)} def toIndexedSeq[Z](implicit ev: value.type <:< Tuple22[Z, Z, Z, Z, Z, Z, Z, Z, Z, Z, Z, Z, Z, Z, Z, Z, Z, Z, Z, Z, Z, Z]): IndexedSeq[Z] = {val zs = ev(value); import zs._; IndexedSeq(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22)} def mapElements[AA, BB, CC, DD, EE, FF, GG, HH, II, JJ, KK, LL, MM, NN, OO, PP, QQ, RR, SS, TT, UU, VV](_1: (A => AA) = identity[A] _, _2: (B => BB) = identity[B] _, _3: (C => CC) = identity[C] _, _4: (D => DD) = identity[D] _, _5: (E => EE) = identity[E] _, _6: (F => FF) = identity[F] _, _7: (G => GG) = identity[G] _, _8: (H => HH) = identity[H] _, _9: (I => II) = identity[I] _, _10: (J => JJ) = identity[J] _, _11: (K => KK) = identity[K] _, _12: (L => LL) = identity[L] _, _13: (M => MM) = identity[M] _, _14: (N => NN) = identity[N] _, _15: (O => OO) = identity[O] _, _16: (P => PP) = identity[P] _, _17: (Q => QQ) = identity[Q] _, _18: (R => RR) = identity[R] _, _19: (S => SS) = identity[S] _, _20: (T => TT) = identity[T] _, _21: (U => UU) = identity[U] _, _22: (V => VV) = identity[V] _): (AA, BB, CC, DD, EE, FF, GG, HH, II, JJ, KK, LL, MM, NN, OO, PP, QQ, RR, SS, TT, UU, VV) = (_1(value._1), _2(value._2), _3(value._3), _4(value._4), _5(value._5), _6(value._6), _7(value._7), _8(value._8), _9(value._9), _10(value._10), _11(value._11), _12(value._12), _13(value._13), _14(value._14), _15(value._15), _16(value._16), _17(value._17), _18(value._18), _19(value._19), _20(value._20), _21(value._21), _22(value._22)) } implicit def ToTuple22W[A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V](t: (A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V)): Tuple22W[A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V] = new { val value = t } with Tuple22W[A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V] -}
\ No newline at end of file +} diff --git a/test/files/pos/t422.scala b/test/files/pos/t422.scala deleted file mode 100644 index cb3ba279d4..0000000000 --- a/test/files/pos/t422.scala +++ /dev/null @@ -1,17 +0,0 @@ -import scala.util.regexp.WordExp; -import scala.util.automata.WordBerrySethi; - -object BoolWordExp extends WordExp { - type _labelT = MyLabels; - type _regexpT = RegExp; - abstract class MyLabels extends Label ; - case class MyLabel(c:Char) extends MyLabels; -} - -object MyTranslator extends WordBerrySethi { - override val lang = BoolWordExp; - import lang._; - override protected def seenLabel( r:RegExp, i:Int, label: _labelT ): Unit = { - super.seenLabel(r,i,label) - } -} diff --git a/test/pending/pos/t4859.scala b/test/files/pos/t4859.scala index ec5abd966d..284a39b7ab 100644 --- a/test/pending/pos/t4859.scala +++ b/test/files/pos/t4859.scala @@ -1,5 +1,7 @@ object O { + // error: C is not a legal prefix for a constructor C().CC() + // but this works. D().DD() } diff --git a/test/files/pos/t5223.scala b/test/files/pos/t5223.scala index 0b2528e367..d81daa9907 100644 --- a/test/files/pos/t5223.scala +++ b/test/files/pos/t5223.scala @@ -2,5 +2,5 @@ import scala.reflect.runtime.universe._ object Foo extends App { reify{def printf(format: String, args: Any*): String = null } - reify{def printf(format: String, args: Any*): String = ("abc": @cloneable)} + reify{def printf(format: String, args: Any*): String = ("abc": @deprecated)} }
\ No newline at end of file diff --git a/test/files/pos/t5809.scala b/test/files/pos/t5809.scala index 4bcd743faa..6101f546b3 100644 --- a/test/files/pos/t5809.scala +++ b/test/files/pos/t5809.scala @@ -1,5 +1,5 @@ package object foo { - implicit class PimpedInt(foo: Int) { + implicit class EnrichedInt(foo: Int) { def bar = ??? def bippy = foo } diff --git a/test/files/pos/t5877.scala b/test/files/pos/t5877.scala index c7827df99f..939013cd01 100644 --- a/test/files/pos/t5877.scala +++ b/test/files/pos/t5877.scala @@ -7,8 +7,8 @@ package foo { } package object foo { - // Crasher: No synthetics for method PimpedFoo2: synthetics contains - implicit class PimpedFoo2(value: Foo) { + // Crasher: No synthetics for method EnrichedFoo2: synthetics contains + implicit class EnrichedFoo2(value: Foo) { def huzzah = "" } } diff --git a/test/files/pos/t5877b.scala b/test/files/pos/t5877b.scala index 6b8cbd473e..43a2ea2f06 100644 --- a/test/files/pos/t5877b.scala +++ b/test/files/pos/t5877b.scala @@ -7,7 +7,7 @@ object Test { } object `package` { - implicit class PimpedFoo2(value: Foo) { + implicit class EnrichedFoo2(value: Foo) { def huzzah = "" } } diff --git a/test/files/pos/t6516.scala b/test/files/pos/t6516.scala new file mode 100644 index 0000000000..c004055de2 --- /dev/null +++ b/test/files/pos/t6516.scala @@ -0,0 +1,19 @@ +import scala.language.experimental.macros +import scala.reflect.macros.Context +import scala.collection.TraversableLike + +// This one compiles +object Test { + type Alias[T, CC[_]] = Context { type PrefixType = TraversableLike[T, CC[T]] } + def f() = macro f_impl + def f_impl(c: Alias[Int, List])() = ??? +} + +// This one doesn't +object Test2 { + type Ctx = scala.reflect.macros.Context + type Alias[T, CC[_]] = Ctx { type PrefixType = TraversableLike[T, CC[T]] } + + def f() = macro f_impl + def f_impl(c: Alias[Int, List])() = ??? +} diff --git a/test/files/pos/t6601/PrivateValueClass_1.scala b/test/files/pos/t6601/PrivateValueClass_1.scala new file mode 100644 index 0000000000..85c3687137 --- /dev/null +++ b/test/files/pos/t6601/PrivateValueClass_1.scala @@ -0,0 +1 @@ +class V private (val a: Any) extends AnyVal
\ No newline at end of file diff --git a/test/files/pos/t6601/UsePrivateValueClass_2.scala b/test/files/pos/t6601/UsePrivateValueClass_2.scala new file mode 100644 index 0000000000..461b8397b2 --- /dev/null +++ b/test/files/pos/t6601/UsePrivateValueClass_2.scala @@ -0,0 +1,10 @@ +object Test { + // After the first attempt to make seprately compiled value + // classes respect the privacy of constructors, we got: + // + // exception when typing v.a().==(v.a())/class scala.reflect.internal.Trees$Apply + // constructor V in class V cannot be accessed in object Test in file test/files/pos/t6601/UsePrivateValueClass_2.scala + // scala.reflect.internal.Types$TypeError: constructor V in class V cannot be accessed in object Test + def foo(v: V) = v.a == v.a + def bar(v: V) = v == v +} diff --git a/test/files/pos/t6651.scala b/test/files/pos/t6651.scala new file mode 100644 index 0000000000..55a3b74e4c --- /dev/null +++ b/test/files/pos/t6651.scala @@ -0,0 +1,33 @@ +class YouAreYourself[A <: AnyRef](val you: A) extends AnyVal { + def yourself: you.type = you +} + +object Test { + val s = "" + val s1: s.type = new YouAreYourself[s.type](s).yourself +} + +trait Path { + type Dep <: AnyRef +} + +final class ValueClass[P <: Path](val path: P) extends AnyVal { + import path.Dep + + def apply(dep: Dep)(d2: dep.type, foo: Int): (Dep, d2.type) = (d2, d2) + + // This generates dodgy code; note `ValueClass.this`: + // + // final def bounds$extension[D >: Nothing <: ValueClass.this.path.Dep, + // P >: Nothing <: Path] + // ($this: ValueClass[P]) + // (dep: D) + // (d2: dep.type, foo: Int): (D, d2.type) = scala.Tuple2.apply[D, d2.type](d2, d2); + // + // Nothing crashes down the line, but it certainly doesn't conform to best-practices. + // + // An better alternative would be to add a type parameter for the (singleton) type of + // the wrapped value. + def bounds[D <: Dep](dep: D)(d2: dep.type, foo: Int): (D, d2.type) = (d2, d2) +} + diff --git a/test/files/pos/t6891.flags b/test/files/pos/t6891.flags new file mode 100644 index 0000000000..fe048006aa --- /dev/null +++ b/test/files/pos/t6891.flags @@ -0,0 +1 @@ +-Ycheck:extmethods -Xfatal-warnings
\ No newline at end of file diff --git a/test/files/pos/t6891.scala b/test/files/pos/t6891.scala new file mode 100644 index 0000000000..bed2d0d777 --- /dev/null +++ b/test/files/pos/t6891.scala @@ -0,0 +1,26 @@ +object O { + implicit class Foo[A](val value: String) extends AnyVal { + def bippy() = { + @annotation.tailrec def loop(x: A): Unit = loop(x) + () + } + + def boppy() = { + @annotation.tailrec def loop(x: value.type): Unit = loop(x) + () + } + + def beppy[C](c: => C) = { + () => c + @annotation.tailrec def loop(x: value.type): Unit = loop(x) + () => c + () + } + } + // uncaught exception during compilation: Types$TypeError("type mismatch; + // found : A(in method bippy$extension) + // required: A(in class Foo)") @ scala.tools.nsc.typechecker.Contexts$Context.issueCommon(Contexts.scala:396) + // error: scala.reflect.internal.Types$TypeError: type mismatch; + // found : A(in method bippy$extension) + // required: A(in class Foo) +} diff --git a/test/files/pos/t6942.flags b/test/files/pos/t6942.flags new file mode 100644 index 0000000000..e8fb65d50c --- /dev/null +++ b/test/files/pos/t6942.flags @@ -0,0 +1 @@ +-Xfatal-warnings
\ No newline at end of file diff --git a/test/files/pos/t6942/Bar.java b/test/files/pos/t6942/Bar.java new file mode 100644 index 0000000000..592f62efb4 --- /dev/null +++ b/test/files/pos/t6942/Bar.java @@ -0,0 +1,235 @@ +package foo; + +public enum Bar { + ANGUILLA /*("US")*/, + ANTIGUA_AND_BARBUDA /*("US")*/, + ARGENTINA /*("US")*/, + ARUBA /*("US")*/, + BAHAMAS /*("US")*/, + BARBADOS /*("US")*/, + BELIZE /*("US")*/, + BERMUDA /*("US")*/, + BOLIVIA /*("US")*/, + BRAZIL /*("US")*/, + BRITISH_VIRGIN_ISLANDS /*("US")*/, + CANADA /*("US")*/, + CAYMAN_ISLANDS /*("US")*/, + CHILE /*("US")*/, + CHRISTMAS_ISLANDS /*("US")*/, + COCOS /*("US")*/, + COLOMBIA /*("US")*/, + COSTA_RICA /*("US")*/, + CUBA /*("US")*/, + DOMINICA /*("US")*/, + DOMINICAN_REPUBLIC /*("US")*/, + ECUADOR /*("US")*/, + EL_SALVADOR /*("US")*/, + FALKLAND_ISLANDS /*("US")*/, + GRENADA /*("US")*/, + GUADALOUPE /*("US")*/, + GUATEMALA /*("US")*/, + HAITI /*("US")*/, + HONDURAS /*("US")*/, + NETHERLANDS_ANTILLES /*("US")*/, + NICARAGUA /*("US")*/, + PANAMA /*("US")*/, + PARAGUAY /*("US")*/, + PERU /*("US")*/, + PUERTO_RICO /*("US")*/, + JAMAICA /*("US")*/, + MARTINIQUE /*("US")*/, + MEXICO /*("US")*/, + MONTSERRAT /*("US")*/, + ST_KITTS /*("US")*/, + ST_LUCIA /*("US")*/, + ST_VINCENT /*("US")*/, + SUPRA_NATIONAL /*("US")*/, + TRINIDAD /*("US")*/, + TURKS_AND_CAICOS /*("US")*/, + UNITED_STATES /*("US")*/, + URUGUAY /*("US")*/, + VENEZUELA /*("US")*/, + VIRGIN_ISLANDS /*("US")*/, + + AUSTRALIA /*("AP")*/, + BANGLADESH /*("AP")*/, + BHUTAN /*("AP")*/, + CAMBODIA /*("AP")*/, + CHINA /*("AP")*/, + COOK_ISLANDS /*("AP")*/, + EAST_TIMOR /*("AP")*/, + FIJI /*("AP")*/, + GUAM /*("AP")*/, + HONG_KONG /*("AP")*/, + INDIA /*("AP")*/, + INDONESIA /*("AP")*/, + JAPAN /*("AP")*/, + KIRIBATI /*("AP")*/, + LAOS /*("AP")*/, + MACAU /*("AP")*/, + MALAYSIA /*("AP")*/, + MICRONESIA /*("AP")*/, + MONGOLIA /*("AP")*/, + MYANMAR /*("AP")*/, + NEPAL /*("AP")*/, + NEW_CALEDONIA /*("AP")*/, + NEW_ZEALAND /*("AP")*/, + NORFOLK_ISLAND /*("AP")*/, + NORTH_KOREA /*("AP")*/, + PAKISTAN /*("AP")*/, + PALAU /*("AP")*/, + PAPUA_NEW_GUINEA /*("AP")*/, + PHILIPPINES /*("AP")*/, + PITCAIRN_ISLANDS /*("AP")*/, + SAMOA /*("AP")*/, + WEST_SAMOA /*("AP")*/, + SINGAPORE /*("AP")*/, + SOUTH_KOREA /*("AP")*/, + SRI_LANKA /*("AP")*/, + TAIWAN /*("AP")*/, + THAILAND /*("AP")*/, + TOKELAU /*("AP")*/, + TONGA /*("AP")*/, + TUVALU /*("AP")*/, + VANUATU /*("AP")*/, + VIETNAM /*("AP")*/, + + AFGHANISTAN /*("EU")*/, + ALBANIA /*("EU")*/, + ALGERIA /*("EU")*/, + ANDORRA /*("EU")*/, + ANGOLA /*("EU")*/, + ARMENIA /*("EU")*/, + AUSTRIA /*("EU")*/, + AZERBAIJAN /*("EU")*/, + BAHRAIN /*("EU")*/, + BELARUS /*("EU")*/, + BELGIUM /*("EU")*/, + BENIN /*("EU")*/, + BOSNIA_AND_HERZEGOVINA /*("EU")*/, + BOTSWANA /*("EU")*/, + BOUVET_ISLAND /*("EU")*/, + BRUNEI /*("EU")*/, + BULGARIA /*("EU")*/, + BURKINA_FASO /*("EU")*/, + BURUNDI /*("EU")*/, + CAMEROON /*("EU")*/, + CAPE_VERDE /*("EU")*/, + CHAD /*("EU")*/, + COMOROS /*("EU")*/, + CONGO /*("EU")*/, + CROATIA /*("EU")*/, + CYPRUS /*("EU")*/, + CZECH_REPUBLIC /*("EU")*/, + DR_CONGO /*("EU")*/, + DENMARK /*("EU")*/, + DJIBOUTI /*("EU")*/, + EGYPT /*("EU")*/, + EQUATORIAL_GUINEA /*("EU")*/, + ERITREA /*("EU")*/, + ESTONIA /*("EU")*/, + ETHIOPIA /*("EU")*/, + FAEROE_ISLANDS /*("EU")*/, + FINLAND /*("EU")*/, + FRANCE /*("EU")*/, + FRENCH_GUIANA /*("EU")*/, + GABON /*("EU")*/, + GAMBIA /*("EU")*/, + GEORGIA /*("EU")*/, + GERMANY /*("EU")*/, + GHANA /*("EU")*/, + GIBRALTAR /*("EU")*/, + GREAT_BRITAIN /*("EU")*/, + GREECE /*("EU")*/, + GREENLAND /*("EU")*/, + GUINEA /*("EU")*/, + GUINEA_BISSAU /*("EU")*/, + GUYANA /*("EU")*/, + HUNGARY /*("EU")*/, + ICELAND /*("EU")*/, + IRAN /*("EU")*/, + IRAQ /*("EU")*/, + IRELAND /*("EU")*/, + ISLE_OF_MAN /*("EU")*/, + ISRAEL /*("EU")*/, + ITALY /*("EU")*/, + IVORY_COAST /*("EU")*/, + JERSEY /*("EU")*/, + JORDAN /*("EU")*/, + KAZAKHSTAN /*("EU")*/, + KENYA /*("EU")*/, + KUWAIT /*("EU")*/, + KYRGYZSTAN /*("EU")*/, + LATVIA /*("EU")*/, + LEBANON /*("EU")*/, + LESOTHO /*("EU")*/, + LIBERIA /*("EU")*/, + LIBYA /*("EU")*/, + LIECHTENSTEIN /*("EU")*/, + LITHUANIA /*("EU")*/, + LUXEMBOURG /*("EU")*/, + MACEDONIA /*("EU")*/, + MADAGASCAR /*("EU")*/, + MALAWI /*("EU")*/, + MALDIVES /*("EU")*/, + MALI /*("EU")*/, + MALTA /*("EU")*/, + MARSHALL_ISLAND /*("EU")*/, + MAURITANIA /*("EU")*/, + MAURITIUS /*("EU")*/, + MAYOTTE /*("EU")*/, + MOLDOVA /*("EU")*/, + MONACO /*("EU")*/, + MOROCCO /*("EU")*/, + MOZAMBIQUE /*("EU")*/, + NAMIBIA /*("EU")*/, + NETHERLANDS /*("EU")*/, + NIGER_REPUBLIC /*("EU")*/, + NIGERIA /*("EU")*/, + NORWAY /*("EU")*/, + OMAN /*("EU")*/, + PALESTINE /*("EU")*/, + POLAND /*("EU")*/, + PORTUGAL /*("EU")*/, + QATAR /*("EU")*/, + REUNION /*("EU")*/, + ROMANIA /*("EU")*/, + RUSSIA /*("EU")*/, + RWANDA /*("EU")*/, + SAN_MARINO /*("EU")*/, + SAO_TOME /*("EU")*/, + SAUDI_ARABIA /*("EU")*/, + SENEGAL /*("EU")*/, + SERBIA /*("EU")*/, + SEYCHELLES /*("EU")*/, + SEIRRA_LEONE /*("EU")*/, + SLOVAKIA /*("EU")*/, + SLOVENIA /*("EU")*/, + SOMALIA /*("EU")*/, + SOUTH_AFRICA /*("EU")*/, + SPAIN /*("EU")*/, + ST_HELENA /*("EU")*/, + SUDAN /*("EU")*/, + SURINAME /*("EU")*/, + SVALBARD /*("EU")*/, + SWAZILAND /*("EU")*/, + SWEDEN /*("EU")*/, + SWITZERLAND /*("EU")*/, + SYRIA /*("EU")*/, + TAJIKSTAN /*("EU")*/, + TANZANIA /*("EU")*/, + TOGO /*("EU")*/, + TUNISIA /*("EU")*/, + TURKEY /*("EU")*/, + TURKMENISTAN /*("EU")*/, + UAE /*("EU")*/, + UGANDA /*("EU")*/, + UKRAINE /*("EU")*/, + UZBEKISTAN /*("EU")*/, + VATICAN_CITY /*("EU")*/, + WESTERN_SAHARA /*("EU")*/, + YEMEN /*("EU")*/, + ZAMBIA /*("EU")*/, + ZIMBABWE /*("EU")*/; + +}
\ No newline at end of file diff --git a/test/files/pos/t6942/t6942.scala b/test/files/pos/t6942/t6942.scala new file mode 100644 index 0000000000..77963d2634 --- /dev/null +++ b/test/files/pos/t6942/t6942.scala @@ -0,0 +1,64 @@ +// not a peep out of the pattern matcher's unreachability analysis +// its budget should suffice for these simple matches (they do have a large search space) +class Test { + import foo.Bar // a large enum + def exhaustUnreachabilitysStack_ENUM_STYLE = (null: Bar) match { + case Bar.BULGARIA => + case _ => + } + + // lots of strings + def exhaustUnreachabilitysStack_StringStyle = "foo" match { + case "a" => + case "b" => + case "c" => + case "d" => + case "e" => + case "f" => + case "aa" => + case "ba" => + case "ca" => + case "da" => + case "ea" => + case "f1a" => + case "a1a" => + case "b1a" => + case "c1a" => + case "d1a" => + case "e1a" => + case "f1a2" => + case "f1a0" => + case "a1a2" => + case "b1a2" => + case "c1a2" => + case "d1a2" => + case "e1a2" => + case "f1a3" => + case "_a" => + case "_b" => + case "_c" => + case "_d" => + case "_e" => + case "_f" => + case "_aa" => + case "_ba" => + case "_ca" => + case "_da" => + case "_ea" => + case "_f1a" => + case "_a1a" => + case "_b1a" => + case "_c1a" => + case "_d1a" => + case "_e1a" => + case "_f1a0" => + case "_f1a2" => + case "_a1a2" => + case "_b1a2" => + case "_c1a2" => + case "_d1a2" => + case "_e1a2" => + case "_f1a3" => + case _ => + } +} diff --git a/test/files/pos/t6963c.flags b/test/files/pos/t6963c.flags new file mode 100644 index 0000000000..4d6e04914f --- /dev/null +++ b/test/files/pos/t6963c.flags @@ -0,0 +1 @@ +-Xmigration:2.9 -Xfatal-warnings
\ No newline at end of file diff --git a/test/files/pos/t6963c.scala b/test/files/pos/t6963c.scala new file mode 100644 index 0000000000..0b6b5c757f --- /dev/null +++ b/test/files/pos/t6963c.scala @@ -0,0 +1,25 @@ +object Test { + def f1(x: Any) = x.isInstanceOf[Seq[_]] + def f2(x: Any) = x match { + case _: Seq[_] => true + case _ => false + } + + def f3(x: Any) = x match { + case _: Array[_] => true + case _ => false + } + + def f4(x: Any) = x.isInstanceOf[Traversable[_]] + + def f5(x1: Any, x2: Any, x3: AnyRef) = (x1, x2, x3) match { + case (Some(_: Seq[_]), Nil, _) => 1 + case (None, List(_: List[_], _), _) => 2 + case _ => 3 + } + + def f5: Unit = { + import scala.collection.mutable._ + List(1,2,3,4,5).scanRight(0)(_+_) + } +} diff --git a/test/files/pos/t6976/Exts_1.scala b/test/files/pos/t6976/Exts_1.scala new file mode 100644 index 0000000000..9b3a69edd9 --- /dev/null +++ b/test/files/pos/t6976/Exts_1.scala @@ -0,0 +1,10 @@ +object Exts { + implicit class AnyExts[T](val o: T) extends AnyVal { + def moo = "moo!" + } +} + +trait Exts { + import language.implicitConversions + implicit def AnyExts[T](o: T) = Exts.AnyExts(o) +} diff --git a/test/files/pos/t6976/ImplicitBug_1.scala b/test/files/pos/t6976/ImplicitBug_1.scala new file mode 100644 index 0000000000..c9031bab2e --- /dev/null +++ b/test/files/pos/t6976/ImplicitBug_1.scala @@ -0,0 +1,27 @@ +// This one is weird and nasty. Not sure if this is scalac or sbt +// (tried with 0.12 & 0.12.2-RC2) bug. +// +// A level of indirection is required to trigger this bug. +// Exts seems to need to be defined in separate file. +// +// Steps to reproduce: +// 1. sbt clean +// 2. sbt run (it works) +// 3. Comment A & uncomment B. +// 4. sbt run (it fails) +// 5. Switch it back & sbt run. It still fails. +// +// In this project sbt clean helps. However in a large project where this +// bug was found compiler crashed even after doing sbt clean. The only +// way to work around this was to reference Exts object explicitly (C) in +// the source file using its implicit classes. + +// Lets suppose this is a mega-trait combining all sorts of helper +// functionality. +trait Support extends Exts + +object ImplicitsBug extends App with Support { // A +// object ImplicitsBug extends App with Exts { // B + //Exts // C) this reference helped in the large project. + println(3.moo) +} diff --git a/test/files/pos/t6976/ImplicitBug_2.scala b/test/files/pos/t6976/ImplicitBug_2.scala new file mode 100644 index 0000000000..2fea5e2993 --- /dev/null +++ b/test/files/pos/t6976/ImplicitBug_2.scala @@ -0,0 +1,7 @@ +trait Support extends Exts + +// object ImplicitsBug extends App with Support { // A +object ImplicitsBug extends App with Exts { // B + //Exts // C) this reference helped in the large project. + println(3.moo) +} diff --git a/test/files/pos/t6994.flags b/test/files/pos/t6994.flags new file mode 100644 index 0000000000..e8fb65d50c --- /dev/null +++ b/test/files/pos/t6994.flags @@ -0,0 +1 @@ +-Xfatal-warnings
\ No newline at end of file diff --git a/test/files/pos/t6994.scala b/test/files/pos/t6994.scala new file mode 100644 index 0000000000..d707196423 --- /dev/null +++ b/test/files/pos/t6994.scala @@ -0,0 +1,8 @@ +object Test { + object NF { + def unapply(t: Throwable): Option[Throwable] = None + } + val x = (try { None } catch { case NF(ex) => None }) getOrElse 0 + // Was emitting a spurious warning post typer: + // "This catches all Throwables. If this is really intended, use `case ex6 : Throwable` to clear this warning." +} diff --git a/test/files/pos/t7011.flags b/test/files/pos/t7011.flags new file mode 100644 index 0000000000..a4c161553e --- /dev/null +++ b/test/files/pos/t7011.flags @@ -0,0 +1 @@ +-Ydebug -Xfatal-warnings
\ No newline at end of file diff --git a/test/files/pos/t7011.scala b/test/files/pos/t7011.scala new file mode 100644 index 0000000000..539f662bc0 --- /dev/null +++ b/test/files/pos/t7011.scala @@ -0,0 +1,7 @@ +object bar { + def foo { + lazy val x = 42 + + {()=>x} + } +}
\ No newline at end of file diff --git a/test/files/pos/t7035.scala b/test/files/pos/t7035.scala new file mode 100644 index 0000000000..f45bd0a878 --- /dev/null +++ b/test/files/pos/t7035.scala @@ -0,0 +1,15 @@ +case class Y(final var x: Int, final private var y: String, final val z1: Boolean, final private val z2: Any) { + + import Test.{y => someY} + List(someY.x: Int, someY.y: String, someY.z1: Boolean, someY.z2: Any) + someY.y = "" +} + +object Test { + val y = Y(0, "", true, new {}) + val unapp: Option[(Int, String, Boolean, Any)] = // was (Int, Boolean, String, Any) !! + Y.unapply(y) + + val Y(a, b, c, d) = y + List(a: Int, b: String, c: Boolean, d: Any) +} diff --git a/test/files/presentation/callcc-interpreter.check b/test/files/presentation/callcc-interpreter.check index 3a08e2a2ea..dd3ee68e45 100644 --- a/test/files/presentation/callcc-interpreter.check +++ b/test/files/presentation/callcc-interpreter.check @@ -3,7 +3,7 @@ reload: CallccInterpreter.scala askTypeCompletion at CallccInterpreter.scala(51,38) ================================================================================ [response] aksTypeCompletion at (51,38) -retrieved 64 members +retrieved 63 members [accessible: true] `class AddcallccInterpreter.Add` [accessible: true] `class AppcallccInterpreter.App` [accessible: true] `class CcccallccInterpreter.Ccc` @@ -50,7 +50,6 @@ retrieved 64 members [accessible: true] `method wait()Unit` [accessible: true] `method wait(x$1: Long)Unit` [accessible: true] `method wait(x$1: Long, x$2: Int)Unit` -[accessible: true] `method x=> callccInterpreter.type` [accessible: true] `method →[B](y: B)(callccInterpreter.type, B)` [accessible: true] `object WrongcallccInterpreter.Wrong.type` [accessible: true] `trait TermcallccInterpreter.Term` diff --git a/test/files/presentation/ide-bug-1000349.check b/test/files/presentation/ide-bug-1000349.check index 44a3207d75..7eeaddc054 100644 --- a/test/files/presentation/ide-bug-1000349.check +++ b/test/files/presentation/ide-bug-1000349.check @@ -3,7 +3,7 @@ reload: CompletionOnEmptyArgMethod.scala askTypeCompletion at CompletionOnEmptyArgMethod.scala(2,17) ================================================================================ [response] aksTypeCompletion at (2,17) -retrieved 37 members +retrieved 36 members [accessible: true] `method !=(x$1: Any)Boolean` [accessible: true] `method !=(x$1: AnyRef)Boolean` [accessible: true] `method ##()Int` @@ -32,7 +32,6 @@ retrieved 37 members [accessible: true] `method wait()Unit` [accessible: true] `method wait(x$1: Long)Unit` [accessible: true] `method wait(x$1: Long, x$2: Int)Unit` -[accessible: true] `method x=> Foo` [accessible: true] `method →[B](y: B)(Foo, B)` [accessible: true] `value __leftOfArrowFoo` [accessible: true] `value __resultOfEnsuringFoo` diff --git a/test/files/presentation/ide-bug-1000475.check b/test/files/presentation/ide-bug-1000475.check index 34c3b557d8..01de4608ca 100644 --- a/test/files/presentation/ide-bug-1000475.check +++ b/test/files/presentation/ide-bug-1000475.check @@ -3,7 +3,7 @@ reload: Foo.scala askTypeCompletion at Foo.scala(3,7) ================================================================================ [response] aksTypeCompletion at (3,7) -retrieved 36 members +retrieved 35 members [accessible: true] `method !=(x$1: Any)Boolean` [accessible: true] `method !=(x$1: AnyRef)Boolean` [accessible: true] `method ##()Int` @@ -29,7 +29,6 @@ retrieved 36 members [accessible: true] `method wait()Unit` [accessible: true] `method wait(x$1: Long)Unit` [accessible: true] `method wait(x$1: Long, x$2: Int)Unit` -[accessible: true] `method x=> Object` [accessible: true] `method →[B](y: B)(Object, B)` [accessible: true] `value __leftOfArrowObject` [accessible: true] `value __resultOfEnsuringObject` @@ -41,7 +40,7 @@ retrieved 36 members askTypeCompletion at Foo.scala(6,10) ================================================================================ [response] aksTypeCompletion at (6,10) -retrieved 36 members +retrieved 35 members [accessible: true] `method !=(x$1: Any)Boolean` [accessible: true] `method !=(x$1: AnyRef)Boolean` [accessible: true] `method ##()Int` @@ -67,7 +66,6 @@ retrieved 36 members [accessible: true] `method wait()Unit` [accessible: true] `method wait(x$1: Long)Unit` [accessible: true] `method wait(x$1: Long, x$2: Int)Unit` -[accessible: true] `method x=> Object` [accessible: true] `method →[B](y: B)(Object, B)` [accessible: true] `value __leftOfArrowObject` [accessible: true] `value __resultOfEnsuringObject` @@ -79,7 +77,7 @@ retrieved 36 members askTypeCompletion at Foo.scala(7,7) ================================================================================ [response] aksTypeCompletion at (7,7) -retrieved 36 members +retrieved 35 members [accessible: true] `method !=(x$1: Any)Boolean` [accessible: true] `method !=(x$1: AnyRef)Boolean` [accessible: true] `method ##()Int` @@ -105,7 +103,6 @@ retrieved 36 members [accessible: true] `method wait()Unit` [accessible: true] `method wait(x$1: Long)Unit` [accessible: true] `method wait(x$1: Long, x$2: Int)Unit` -[accessible: true] `method x=> Object` [accessible: true] `method →[B](y: B)(Object, B)` [accessible: true] `value __leftOfArrowObject` [accessible: true] `value __resultOfEnsuringObject` diff --git a/test/files/presentation/ide-bug-1000531.check b/test/files/presentation/ide-bug-1000531.check index 6c3892d272..7fa550179f 100644 --- a/test/files/presentation/ide-bug-1000531.check +++ b/test/files/presentation/ide-bug-1000531.check @@ -3,7 +3,7 @@ reload: CrashOnLoad.scala askTypeCompletion at CrashOnLoad.scala(6,12) ================================================================================ [response] aksTypeCompletion at (6,12) -retrieved 126 members +retrieved 124 members [accessible: true] `class GroupedIteratorIterator[B]#GroupedIterator` [accessible: true] `method !=(x$1: Any)Boolean` [accessible: true] `method !=(x$1: AnyRef)Boolean` @@ -12,7 +12,6 @@ retrieved 126 members [accessible: true] `method ++[B >: B](that: => scala.collection.GenTraversableOnce[B])Iterator[B]` [accessible: true] `method ->[B](y: B)(java.util.Iterator[B], B)` [accessible: true] `method /:[B](z: B)(op: (B, B) => B)B` -[accessible: true] `method /:\[A1 >: B](z: A1)(op: (A1, A1) => A1)A1` [accessible: true] `method :\[B](z: B)(op: (B, B) => B)B` [accessible: true] `method ==(x$1: Any)Boolean` [accessible: true] `method ==(x$1: AnyRef)Boolean` @@ -115,7 +114,6 @@ retrieved 126 members [accessible: true] `method wait(x$1: Long)Unit` [accessible: true] `method wait(x$1: Long, x$2: Int)Unit` [accessible: true] `method withFilter(p: B => Boolean)Iterator[B]` -[accessible: true] `method x=> java.util.Iterator[B]` [accessible: true] `method zipAll[B, A1 >: B, B1 >: B](that: Iterator[B], thisElem: A1, thatElem: B1)Iterator[(A1, B1)]` [accessible: true] `method zipWithIndex=> Iterator[(B, Int)]` [accessible: true] `method zip[B](that: Iterator[B])Iterator[(B, B)]` diff --git a/test/files/presentation/implicit-member.check b/test/files/presentation/implicit-member.check index 05d6f61699..7b4f792bf3 100644 --- a/test/files/presentation/implicit-member.check +++ b/test/files/presentation/implicit-member.check @@ -3,7 +3,7 @@ reload: ImplicitMember.scala askTypeCompletion at ImplicitMember.scala(7,7) ================================================================================ [response] aksTypeCompletion at (7,7) -retrieved 39 members +retrieved 38 members [accessible: true] `class AppliedImplicitImplicit.AppliedImplicit` [accessible: true] `method !=(x$1: Any)Boolean` [accessible: true] `method !=(x$1: AnyRef)Boolean` @@ -33,7 +33,6 @@ retrieved 39 members [accessible: true] `method wait()Unit` [accessible: true] `method wait(x$1: Long)Unit` [accessible: true] `method wait(x$1: Long, x$2: Int)Unit` -[accessible: true] `method x=> Implicit.type` [accessible: true] `method →[B](y: B)(Implicit.type, B)` [accessible: true] `value __leftOfArrowImplicit.type` [accessible: true] `value __resultOfEnsuringImplicit.type` diff --git a/test/files/presentation/ping-pong.check b/test/files/presentation/ping-pong.check index b666d51de5..c85f6cc21a 100644 --- a/test/files/presentation/ping-pong.check +++ b/test/files/presentation/ping-pong.check @@ -3,7 +3,7 @@ reload: PingPong.scala askTypeCompletion at PingPong.scala(10,23) ================================================================================ [response] aksTypeCompletion at (10,23) -retrieved 40 members +retrieved 39 members [accessible: true] `method !=(x$1: Any)Boolean` [accessible: true] `method !=(x$1: AnyRef)Boolean` [accessible: true] `method ##()Int` @@ -30,7 +30,6 @@ retrieved 40 members [accessible: true] `method wait()Unit` [accessible: true] `method wait(x$1: Long)Unit` [accessible: true] `method wait(x$1: Long, x$2: Int)Unit` -[accessible: true] `method x=> Pong` [accessible: true] `method →[B](y: B)(Pong, B)` [accessible: true] `value __leftOfArrowPong` [accessible: true] `value __resultOfEnsuringPong` @@ -44,7 +43,7 @@ retrieved 40 members askTypeCompletion at PingPong.scala(19,20) ================================================================================ [response] aksTypeCompletion at (19,20) -retrieved 40 members +retrieved 39 members [accessible: true] `method !=(x$1: Any)Boolean` [accessible: true] `method !=(x$1: AnyRef)Boolean` [accessible: true] `method ##()Int` @@ -73,7 +72,6 @@ retrieved 40 members [accessible: true] `method wait()Unit` [accessible: true] `method wait(x$1: Long)Unit` [accessible: true] `method wait(x$1: Long, x$2: Int)Unit` -[accessible: true] `method x=> Ping` [accessible: true] `method →[B](y: B)(Ping, B)` [accessible: true] `value __leftOfArrowPing` [accessible: true] `value __resultOfEnsuringPing` diff --git a/test/files/presentation/t5708.check b/test/files/presentation/t5708.check index c6d4762635..572f404cf4 100644 --- a/test/files/presentation/t5708.check +++ b/test/files/presentation/t5708.check @@ -3,7 +3,7 @@ reload: Completions.scala askTypeCompletion at Completions.scala(17,9) ================================================================================ [response] aksTypeCompletion at (17,9) -retrieved 44 members +retrieved 43 members [accessible: true] `lazy value fooInt` [accessible: true] `method !=(x$1: Any)Boolean` [accessible: true] `method !=(x$1: AnyRef)Boolean` @@ -31,7 +31,6 @@ retrieved 44 members [accessible: true] `method wait()Unit` [accessible: true] `method wait(x$1: Long)Unit` [accessible: true] `method wait(x$1: Long, x$2: Int)Unit` -[accessible: true] `method x=> test.Compat.type` [accessible: true] `method →[B](y: B)(test.Compat.type, B)` [accessible: true] `value CONST_STRINGString("constant")` [accessible: true] `value __leftOfArrowtest.Compat.type` diff --git a/test/files/presentation/visibility.check b/test/files/presentation/visibility.check index 3026e58f7e..87b4463bf7 100644 --- a/test/files/presentation/visibility.check +++ b/test/files/presentation/visibility.check @@ -3,7 +3,7 @@ reload: Completions.scala askTypeCompletion at Completions.scala(14,12) ================================================================================ [response] aksTypeCompletion at (14,12) -retrieved 42 members +retrieved 41 members [accessible: true] `method !=(x$1: Any)Boolean` [accessible: true] `method !=(x$1: AnyRef)Boolean` [accessible: true] `method ##()Int` @@ -36,7 +36,6 @@ retrieved 42 members [accessible: true] `method wait()Unit` [accessible: true] `method wait(x$1: Long)Unit` [accessible: true] `method wait(x$1: Long, x$2: Int)Unit` -[accessible: true] `method x=> accessibility.Foo` [accessible: true] `method →[B](y: B)(accessibility.Foo, B)` [accessible: true] `value __leftOfArrowaccessibility.Foo` [accessible: true] `value __resultOfEnsuringaccessibility.Foo` @@ -47,7 +46,7 @@ retrieved 42 members askTypeCompletion at Completions.scala(16,11) ================================================================================ [response] aksTypeCompletion at (16,11) -retrieved 42 members +retrieved 41 members [accessible: true] `method !=(x$1: Any)Boolean` [accessible: true] `method !=(x$1: AnyRef)Boolean` [accessible: true] `method ##()Int` @@ -81,7 +80,6 @@ retrieved 42 members [accessible: true] `method wait()Unit` [accessible: true] `method wait(x$1: Long)Unit` [accessible: true] `method wait(x$1: Long, x$2: Int)Unit` -[accessible: true] `method x=> accessibility.Foo` [accessible: true] `method →[B](y: B)(accessibility.Foo, B)` [accessible: true] `value __leftOfArrowaccessibility.Foo` [accessible: true] `value __resultOfEnsuringaccessibility.Foo` @@ -91,7 +89,7 @@ retrieved 42 members askTypeCompletion at Completions.scala(22,11) ================================================================================ [response] aksTypeCompletion at (22,11) -retrieved 42 members +retrieved 41 members [accessible: true] `method !=(x$1: Any)Boolean` [accessible: true] `method !=(x$1: AnyRef)Boolean` [accessible: true] `method ##()Int` @@ -124,7 +122,6 @@ retrieved 42 members [accessible: true] `method wait()Unit` [accessible: true] `method wait(x$1: Long)Unit` [accessible: true] `method wait(x$1: Long, x$2: Int)Unit` -[accessible: true] `method x=> accessibility.AccessibilityChecks` [accessible: true] `method →[B](y: B)(accessibility.AccessibilityChecks, B)` [accessible: true] `value __leftOfArrowaccessibility.AccessibilityChecks` [accessible: true] `value __resultOfEnsuringaccessibility.AccessibilityChecks` @@ -135,7 +132,7 @@ retrieved 42 members askTypeCompletion at Completions.scala(28,10) ================================================================================ [response] aksTypeCompletion at (28,10) -retrieved 42 members +retrieved 41 members [accessible: true] `method !=(x$1: Any)Boolean` [accessible: true] `method !=(x$1: AnyRef)Boolean` [accessible: true] `method ##()Int` @@ -164,7 +161,6 @@ retrieved 42 members [accessible: true] `method wait()Unit` [accessible: true] `method wait(x$1: Long)Unit` [accessible: true] `method wait(x$1: Long, x$2: Int)Unit` -[accessible: true] `method x=> accessibility.Foo` [accessible: true] `method →[B](y: B)(accessibility.Foo, B)` [accessible: true] `value __leftOfArrowaccessibility.Foo` [accessible: true] `value __resultOfEnsuringaccessibility.Foo` @@ -179,7 +175,7 @@ retrieved 42 members askTypeCompletion at Completions.scala(37,8) ================================================================================ [response] aksTypeCompletion at (37,8) -retrieved 42 members +retrieved 41 members [accessible: true] `method !=(x$1: Any)Boolean` [accessible: true] `method !=(x$1: AnyRef)Boolean` [accessible: true] `method ##()Int` @@ -207,7 +203,6 @@ retrieved 42 members [accessible: true] `method wait()Unit` [accessible: true] `method wait(x$1: Long)Unit` [accessible: true] `method wait(x$1: Long, x$2: Int)Unit` -[accessible: true] `method x=> accessibility.Foo` [accessible: true] `method →[B](y: B)(accessibility.Foo, B)` [accessible: true] `value __leftOfArrowaccessibility.Foo` [accessible: true] `value __resultOfEnsuringaccessibility.Foo` diff --git a/test/files/run/analyzerPlugins.check b/test/files/run/analyzerPlugins.check new file mode 100644 index 0000000000..0788086459 --- /dev/null +++ b/test/files/run/analyzerPlugins.check @@ -0,0 +1,197 @@ +adaptBoundsToAnnots(List( <: Int), List(type T), List(Int @testAnn)) [2] +annotationsConform(Boolean @testAnn, Boolean) [1] +annotationsConform(Boolean(false), Boolean @testAnn) [1] +annotationsConform(Int @testAnn, ?A) [1] +annotationsConform(Int @testAnn, Any) [1] +annotationsConform(Int @testAnn, Int) [2] +annotationsConform(Int(1) @testAnn, Int) [1] +annotationsConform(Int(1), Int @testAnn) [1] +annotationsConform(Nothing, Int @testAnn) [2] +annotationsConform(String @testAnn, String) [1] +canAdaptAnnotations(Trees$Ident, String) [1] +canAdaptAnnotations(Trees$Select, ?) [1] +canAdaptAnnotations(Trees$Select, Boolean @testAnn) [1] +canAdaptAnnotations(Trees$Select, Boolean) [1] +canAdaptAnnotations(Trees$Select, String @testAnn) [1] +canAdaptAnnotations(Trees$TypeTree, ?) [10] +canAdaptAnnotations(Trees$Typed, ?) [3] +canAdaptAnnotations(Trees$Typed, Any) [1] +canAdaptAnnotations(Trees$Typed, Int) [1] +lub(List(Int @testAnn, Int)) [1] +pluginsPt(?, Trees$Annotated) [7] +pluginsPt(?, Trees$Apply) [8] +pluginsPt(?, Trees$ApplyImplicitView) [2] +pluginsPt(?, Trees$Assign) [7] +pluginsPt(?, Trees$Block) [4] +pluginsPt(?, Trees$ClassDef) [2] +pluginsPt(?, Trees$DefDef) [14] +pluginsPt(?, Trees$Ident) [51] +pluginsPt(?, Trees$If) [2] +pluginsPt(?, Trees$Literal) [16] +pluginsPt(?, Trees$New) [5] +pluginsPt(?, Trees$PackageDef) [1] +pluginsPt(?, Trees$Return) [1] +pluginsPt(?, Trees$Select) [51] +pluginsPt(?, Trees$Super) [2] +pluginsPt(?, Trees$This) [20] +pluginsPt(?, Trees$TypeApply) [3] +pluginsPt(?, Trees$TypeBoundsTree) [2] +pluginsPt(?, Trees$TypeDef) [1] +pluginsPt(?, Trees$TypeTree) [38] +pluginsPt(?, Trees$Typed) [1] +pluginsPt(?, Trees$ValDef) [21] +pluginsPt(Any, Trees$Literal) [2] +pluginsPt(Any, Trees$Typed) [1] +pluginsPt(Array[Any], Trees$ArrayValue) [1] +pluginsPt(Boolean @testAnn, Trees$Literal) [1] +pluginsPt(Boolean @testAnn, Trees$Select) [1] +pluginsPt(Boolean, Trees$Apply) [1] +pluginsPt(Boolean, Trees$Ident) [1] +pluginsPt(Boolean, Trees$Literal) [1] +pluginsPt(Double, Trees$Select) [1] +pluginsPt(Int @testAnn, Trees$Literal) [1] +pluginsPt(Int, Trees$Apply) [1] +pluginsPt(Int, Trees$Ident) [2] +pluginsPt(Int, Trees$If) [1] +pluginsPt(Int, Trees$Literal) [5] +pluginsPt(Int, Trees$Select) [3] +pluginsPt(List, Trees$Apply) [1] +pluginsPt(List[Any], Trees$Select) [1] +pluginsPt(String @testAnn, Trees$Select) [1] +pluginsPt(String, Trees$Apply) [1] +pluginsPt(String, Trees$Block) [2] +pluginsPt(String, Trees$Ident) [4] +pluginsPt(String, Trees$Literal) [1] +pluginsPt(String, Trees$Select) [1] +pluginsPt(String, Trees$Typed) [1] +pluginsPt(Unit, Trees$Assign) [1] +pluginsPt(testAnn, Trees$Apply) [5] +pluginsTypeSig(<none>, Trees$Template) [2] +pluginsTypeSig(class A, Trees$ClassDef) [1] +pluginsTypeSig(class testAnn, Trees$ClassDef) [1] +pluginsTypeSig(constructor A, Trees$DefDef) [2] +pluginsTypeSig(constructor testAnn, Trees$DefDef) [1] +pluginsTypeSig(method foo, Trees$DefDef) [1] +pluginsTypeSig(method method, Trees$DefDef) [1] +pluginsTypeSig(method nested, Trees$DefDef) [1] +pluginsTypeSig(type T, Trees$TypeDef) [2] +pluginsTypeSig(value annotField, Trees$ValDef) [2] +pluginsTypeSig(value f, Trees$ValDef) [1] +pluginsTypeSig(value inferField, Trees$ValDef) [2] +pluginsTypeSig(value lub1, Trees$ValDef) [2] +pluginsTypeSig(value lub2, Trees$ValDef) [2] +pluginsTypeSig(value param, Trees$ValDef) [2] +pluginsTypeSig(value str, Trees$ValDef) [1] +pluginsTypeSig(value x, Trees$ValDef) [4] +pluginsTypeSig(value y, Trees$ValDef) [4] +pluginsTypeSig(variable count, Trees$ValDef) [3] +pluginsTypeSigAccessor(value annotField) [1] +pluginsTypeSigAccessor(value inferField) [1] +pluginsTypeSigAccessor(value lub1) [1] +pluginsTypeSigAccessor(value lub2) [1] +pluginsTypeSigAccessor(value x) [1] +pluginsTypeSigAccessor(value y) [1] +pluginsTypeSigAccessor(variable count) [2] +pluginsTyped( <: Int, Trees$TypeBoundsTree) [2] +pluginsTyped(()Object, Trees$Select) [1] +pluginsTyped(()String, Trees$Ident) [1] +pluginsTyped(()String, Trees$TypeApply) [1] +pluginsTyped(()scala.annotation.Annotation, Trees$Select) [1] +pluginsTyped(()testAnn, Trees$Select) [10] +pluginsTyped((str: String)A <and> (param: Double)A, Trees$Select) [1] +pluginsTyped((x$1: Any)Boolean <and> (x: Double)Boolean <and> (x: Float)Boolean <and> (x: Long)Boolean <and> (x: Int)Boolean <and> (x: Char)Boolean <and> (x: Short)Boolean <and> (x: Byte)Boolean, Trees$Select) [1] +pluginsTyped((x$1: Int)Unit, Trees$Select) [1] +pluginsTyped((x: Double)Double <and> (x: Float)Float <and> (x: Long)Long <and> (x: Int)Int <and> (x: Char)Int <and> (x: Short)Int <and> (x: Byte)Int <and> (x: String)String, Trees$Select) [1] +pluginsTyped((x: String)scala.collection.immutable.StringOps, Trees$Select) [2] +pluginsTyped((xs: Array[Any])scala.collection.mutable.WrappedArray[Any], Trees$TypeApply) [1] +pluginsTyped(<empty>.type, Trees$Ident) [1] +pluginsTyped(<error>, Trees$Select) [1] +pluginsTyped(<notype>, Trees$ClassDef) [2] +pluginsTyped(<notype>, Trees$DefDef) [14] +pluginsTyped(<notype>, Trees$PackageDef) [1] +pluginsTyped(<notype>, Trees$TypeDef) [1] +pluginsTyped(<notype>, Trees$ValDef) [21] +pluginsTyped(<root>, Trees$Ident) [1] +pluginsTyped(=> Boolean @testAnn, Trees$Select) [1] +pluginsTyped(=> Double, Trees$Select) [4] +pluginsTyped(=> Int, Trees$Select) [5] +pluginsTyped(=> Int, Trees$TypeApply) [1] +pluginsTyped(=> String @testAnn, Trees$Select) [1] +pluginsTyped(A, Trees$Apply) [1] +pluginsTyped(A, Trees$Ident) [2] +pluginsTyped(A, Trees$This) [8] +pluginsTyped(A, Trees$TypeTree) [4] +pluginsTyped(A.super.type, Trees$Super) [1] +pluginsTyped(A.this.type, Trees$This) [11] +pluginsTyped(Any, Trees$TypeTree) [1] +pluginsTyped(AnyRef, Trees$Select) [4] +pluginsTyped(Array[Any], Trees$ArrayValue) [1] +pluginsTyped(Boolean @testAnn, Trees$Select) [1] +pluginsTyped(Boolean @testAnn, Trees$TypeTree) [4] +pluginsTyped(Boolean(false), Trees$Literal) [2] +pluginsTyped(Boolean, Trees$Apply) [1] +pluginsTyped(Boolean, Trees$Select) [4] +pluginsTyped(Char('c'), Trees$Literal) [2] +pluginsTyped(Double, Trees$Select) [6] +pluginsTyped(Int @testAnn, Trees$TypeTree) [2] +pluginsTyped(Int @testAnn, Trees$Typed) [2] +pluginsTyped(Int(0), Trees$Literal) [3] +pluginsTyped(Int(1) @testAnn, Trees$Typed) [1] +pluginsTyped(Int(1), Trees$Literal) [8] +pluginsTyped(Int(2), Trees$Literal) [1] +pluginsTyped(Int, Trees$Apply) [1] +pluginsTyped(Int, Trees$Ident) [2] +pluginsTyped(Int, Trees$If) [2] +pluginsTyped(Int, Trees$Select) [15] +pluginsTyped(Int, Trees$TypeTree) [13] +pluginsTyped(List, Trees$Apply) [1] +pluginsTyped(List, Trees$Select) [1] +pluginsTyped(List[Any], Trees$Apply) [1] +pluginsTyped(List[Any], Trees$Select) [1] +pluginsTyped(List[Any], Trees$TypeTree) [3] +pluginsTyped(Nothing, Trees$Return) [1] +pluginsTyped(Nothing, Trees$Select) [2] +pluginsTyped(Object, Trees$Apply) [1] +pluginsTyped(String @testAnn, Trees$Ident) [1] +pluginsTyped(String @testAnn, Trees$Select) [1] +pluginsTyped(String @testAnn, Trees$TypeTree) [4] +pluginsTyped(String(""), Trees$Literal) [2] +pluginsTyped(String("huhu"), Trees$Literal) [1] +pluginsTyped(String("str") @testAnn, Trees$Typed) [1] +pluginsTyped(String("str"), Trees$Literal) [1] +pluginsTyped(String("str"), Trees$Typed) [1] +pluginsTyped(String("two"), Trees$Literal) [2] +pluginsTyped(String, Trees$Apply) [2] +pluginsTyped(String, Trees$Block) [2] +pluginsTyped(String, Trees$Ident) [1] +pluginsTyped(String, Trees$Select) [9] +pluginsTyped(String, Trees$TypeTree) [7] +pluginsTyped(Unit, Trees$Apply) [2] +pluginsTyped(Unit, Trees$Assign) [8] +pluginsTyped(Unit, Trees$Block) [4] +pluginsTyped(Unit, Trees$If) [1] +pluginsTyped(Unit, Trees$Literal) [5] +pluginsTyped(Unit, Trees$TypeTree) [1] +pluginsTyped([A](xs: A*)List[A], Trees$Select) [1] +pluginsTyped([T <: Int]=> Int, Trees$Select) [1] +pluginsTyped([T0]()T0, Trees$Select) [1] +pluginsTyped([T](xs: Array[T])scala.collection.mutable.WrappedArray[T], Trees$Select) [1] +pluginsTyped(annotation.type, Trees$Select) [4] +pluginsTyped(math.type, Trees$Select) [9] +pluginsTyped(scala.annotation.Annotation, Trees$Apply) [1] +pluginsTyped(scala.annotation.TypeConstraint, Trees$Select) [4] +pluginsTyped(scala.annotation.TypeConstraint, Trees$TypeTree) [2] +pluginsTyped(scala.collection.immutable.List.type, Trees$Select) [2] +pluginsTyped(scala.collection.immutable.StringOps, Trees$ApplyImplicitView) [2] +pluginsTyped(scala.collection.mutable.WrappedArray[Any], Trees$Apply) [1] +pluginsTyped(scala.type, Trees$Ident) [1] +pluginsTyped(scala.type, Trees$Select) [1] +pluginsTyped(str.type, Trees$Ident) [3] +pluginsTyped(testAnn, Trees$Apply) [5] +pluginsTyped(testAnn, Trees$Ident) [5] +pluginsTyped(testAnn, Trees$New) [5] +pluginsTyped(testAnn, Trees$This) [1] +pluginsTyped(testAnn, Trees$TypeTree) [2] +pluginsTyped(testAnn.super.type, Trees$Super) [1] +pluginsTyped(type, Trees$Select) [1] +pluginsTypedReturn(return f, String) [1] diff --git a/test/files/run/analyzerPlugins.scala b/test/files/run/analyzerPlugins.scala new file mode 100644 index 0000000000..b20a734fe6 --- /dev/null +++ b/test/files/run/analyzerPlugins.scala @@ -0,0 +1,121 @@ +import scala.tools.partest._ +import scala.tools.nsc._ + +object Test extends DirectTest { + + override def extraSettings: String = "-usejavacp" + + def code = """ + class testAnn extends annotation.TypeConstraint + + class A(param: Double) extends { val x: Int = 1; val y = "two"; type T = A } with AnyRef { + val inferField = ("str": @testAnn) + val annotField: Boolean @testAnn = false + + val lub1 = List('c', (1: Int @testAnn), "") + val lub2 = if (annotField) (1: @testAnn) else 2 + + def foo[T <: Int] = 0 + foo[Int @testAnn] + + var count = 0 + + math.random // some statement + + def method: String = { + math.random + val f = inferField + + def nested(): String = { + if(count == 1) + return f + "huhu" + } + nested() + } + + def this(str: String) { + this(str.toDouble) + math.random + count += 1 + } + } + """.trim + + + def show() { + val global = newCompiler() + import global._ + import analyzer._ + + val output = collection.mutable.ListBuffer[String]() + + object annotChecker extends AnnotationChecker { + def hasTestAnn(tps: Type*) = { + tps exists (_.annotations.map(_.toString) contains "testAnn") + } + + def annotationsConform(tpe1: Type, tpe2: Type): Boolean = { + if (hasTestAnn(tpe1, tpe2)) + output += s"annotationsConform($tpe1, $tpe2)" + true + } + + override def annotationsLub(tp: Type, ts: List[Type]): Type = { + if (hasTestAnn(ts: _*)) + output += s"lub($ts)" + tp + } + + override def adaptBoundsToAnnotations(bounds: List[TypeBounds], tparams: List[Symbol], targs: List[Type]): List[TypeBounds] = { + if (hasTestAnn(targs: _*)) + output += s"adaptBoundsToAnnots($bounds, $tparams, $targs)" + bounds + } + } + + object analyzerPlugin extends AnalyzerPlugin { + def treeClass(t: Tree) = t.getClass.toString.split('.').last + + override def pluginsPt(pt: Type, typer: Typer, tree: Tree, mode: Mode): Type = { + output += s"pluginsPt($pt, ${treeClass(tree)})" + pt + } + + override def pluginsTyped(tpe: Type, typer: Typer, tree: Tree, mode: Mode, pt: Type): Type = { + output += s"pluginsTyped($tpe, ${treeClass(tree)})" + tpe + } + + override def pluginsTypeSig(tpe: Type, typer: Typer, defTree: Tree, pt: Type): Type = { + output += s"pluginsTypeSig(${defTree.symbol}, ${treeClass(defTree)})" + tpe + } + + override def pluginsTypeSigAccessor(tpe: Type, typer: Typer, tree: ValDef, sym: Symbol): Type = { + output += s"pluginsTypeSigAccessor(${tree.symbol})" + tpe + } + + + override def canAdaptAnnotations(tree: Tree, typer: Typer, mode: Mode, pt: Type): Boolean = { + output += s"canAdaptAnnotations(${treeClass(tree)}, $pt)" + false + } + + override def pluginsTypedReturn(tpe: Type, typer: Typer, tree: Return, pt: Type): Type = { + output += s"pluginsTypedReturn($tree, $pt)" + tpe + } + + } + + addAnnotationChecker(annotChecker) + addAnalyzerPlugin(analyzerPlugin) + compileString(global)(code) + + val res = output.groupBy(identity).mapValues(_.size).map { case (k,v) => s"$k [$v]" }.toList.sorted + println(res.mkString("\n")) + } + +} diff --git a/test/files/run/bitsets.scala b/test/files/run/bitsets.scala index 27395683b4..bdeb1fd811 100644 --- a/test/files/run/bitsets.scala +++ b/test/files/run/bitsets.scala @@ -85,8 +85,8 @@ object TestImmutable { import scala.collection.immutable.BitSet val is0 = BitSet() - val is1 = BitSet.fromArray(Array()) - val is2 = BitSet.fromArray(Array(4)) + val is1 = BitSet.fromBitMask(Array()) + val is2 = BitSet.fromBitMask(Array(4)) val is3 = BitSet.empty Console.println("is0 = " + is0) diff --git a/test/files/run/ctries-new/iterator.scala b/test/files/run/ctries-new/iterator.scala index b953a40e00..bb1175e61b 100644 --- a/test/files/run/ctries-new/iterator.scala +++ b/test/files/run/ctries-new/iterator.scala @@ -1,144 +1,134 @@ - - - - import collection._ import collection.concurrent.TrieMap - - object IteratorSpec extends Spec { - + def test() { "work for an empty trie" in { val ct = new TrieMap val it = ct.iterator - + it.hasNext shouldEqual (false) evaluating { it.next() }.shouldProduce [NoSuchElementException] } - + def nonEmptyIteratorCheck(sz: Int) { val ct = new TrieMap[Wrap, Int] for (i <- 0 until sz) ct.put(new Wrap(i), i) - + val it = ct.iterator val tracker = mutable.Map[Wrap, Int]() for (i <- 0 until sz) { assert(it.hasNext == true) tracker += it.next } - + it.hasNext shouldEqual (false) evaluating { it.next() }.shouldProduce [NoSuchElementException] tracker.size shouldEqual (sz) tracker shouldEqual (ct) } - + "work for a 1 element trie" in { nonEmptyIteratorCheck(1) } - + "work for a 2 element trie" in { nonEmptyIteratorCheck(2) } - + "work for a 3 element trie" in { nonEmptyIteratorCheck(3) } - + "work for a 5 element trie" in { nonEmptyIteratorCheck(5) } - + "work for a 10 element trie" in { nonEmptyIteratorCheck(10) } - + "work for a 20 element trie" in { nonEmptyIteratorCheck(20) } - + "work for a 50 element trie" in { nonEmptyIteratorCheck(50) } - + "work for a 100 element trie" in { nonEmptyIteratorCheck(100) } - + "work for a 1k element trie" in { nonEmptyIteratorCheck(1000) } - + "work for a 5k element trie" in { nonEmptyIteratorCheck(5000) } - + "work for a 75k element trie" in { nonEmptyIteratorCheck(75000) } - + "work for a 250k element trie" in { nonEmptyIteratorCheck(500000) } - + def nonEmptyCollideCheck(sz: Int) { val ct = new TrieMap[DumbHash, Int] for (i <- 0 until sz) ct.put(new DumbHash(i), i) - + val it = ct.iterator val tracker = mutable.Map[DumbHash, Int]() for (i <- 0 until sz) { assert(it.hasNext == true) tracker += it.next } - + it.hasNext shouldEqual (false) evaluating { it.next() }.shouldProduce [NoSuchElementException] tracker.size shouldEqual (sz) tracker shouldEqual (ct) } - + "work for colliding hashcodes, 2 element trie" in { nonEmptyCollideCheck(2) } - + "work for colliding hashcodes, 3 element trie" in { nonEmptyCollideCheck(3) } - + "work for colliding hashcodes, 5 element trie" in { nonEmptyCollideCheck(5) } - + "work for colliding hashcodes, 10 element trie" in { nonEmptyCollideCheck(10) } - + "work for colliding hashcodes, 100 element trie" in { nonEmptyCollideCheck(100) } - + "work for colliding hashcodes, 500 element trie" in { nonEmptyCollideCheck(500) } - + "work for colliding hashcodes, 5k element trie" in { nonEmptyCollideCheck(5000) } - + def assertEqual(a: Map[Wrap, Int], b: Map[Wrap, Int]) { if (a != b) { println(a.size + " vs " + b.size) - // println(a) - // println(b) - // println(a.toSeq.sortBy((x: (Wrap, Int)) => x._1.i)) - // println(b.toSeq.sortBy((x: (Wrap, Int)) => x._1.i)) } assert(a == b) } - + "be consistent when taken with concurrent modifications" in { val sz = 25000 val W = 15 @@ -146,40 +136,40 @@ object IteratorSpec extends Spec { val checks = 5 val ct = new TrieMap[Wrap, Int] for (i <- 0 until sz) ct.put(new Wrap(i), i) - + class Modifier extends Thread { override def run() { for (i <- 0 until sz) ct.putIfAbsent(new Wrap(i), i) match { case Some(_) => ct.remove(new Wrap(i)) - case None => + case None => } } } - + def consistentIteration(ct: TrieMap[Wrap, Int], checks: Int) { class Iter extends Thread { override def run() { val snap = ct.readOnlySnapshot() val initial = mutable.Map[Wrap, Int]() for (kv <- snap) initial += kv - + for (i <- 0 until checks) { assertEqual(snap.iterator.toMap, initial) } } } - + val iter = new Iter iter.start() iter.join() } - + val threads = for (_ <- 0 until W) yield new Modifier threads.foreach(_.start()) for (_ <- 0 until S) consistentIteration(ct, checks) threads.foreach(_.join()) } - + "be consistent with a concurrent removal with a well defined order" in { val sz = 150000 val sgroupsize = 10 @@ -187,17 +177,16 @@ object IteratorSpec extends Spec { val removerslowdown = 50 val ct = new TrieMap[Wrap, Int] for (i <- 0 until sz) ct.put(new Wrap(i), i) - + class Remover extends Thread { override def run() { for (i <- 0 until sz) { assert(ct.remove(new Wrap(i)) == Some(i)) for (i <- 0 until removerslowdown) ct.get(new Wrap(i)) // slow down, mate } - //println("done removing") } } - + def consistentIteration(it: Iterator[(Wrap, Int)]) = { class Iter extends Thread { override def run() { @@ -210,7 +199,7 @@ object IteratorSpec extends Spec { } new Iter } - + val remover = new Remover remover.start() for (_ <- 0 until sgroupnum) { @@ -218,27 +207,25 @@ object IteratorSpec extends Spec { iters.foreach(_.start()) iters.foreach(_.join()) } - //println("done with iterators") remover.join() } - + "be consistent with a concurrent insertion with a well defined order" in { val sz = 150000 val sgroupsize = 10 val sgroupnum = 10 val inserterslowdown = 50 val ct = new TrieMap[Wrap, Int] - + class Inserter extends Thread { override def run() { for (i <- 0 until sz) { assert(ct.put(new Wrap(i), i) == None) for (i <- 0 until inserterslowdown) ct.get(new Wrap(i)) // slow down, mate } - //println("done inserting") } } - + def consistentIteration(it: Iterator[(Wrap, Int)]) = { class Iter extends Thread { override def run() { @@ -251,7 +238,7 @@ object IteratorSpec extends Spec { } new Iter } - + val inserter = new Inserter inserter.start() for (_ <- 0 until sgroupnum) { @@ -259,31 +246,30 @@ object IteratorSpec extends Spec { iters.foreach(_.start()) iters.foreach(_.join()) } - //println("done with iterators") inserter.join() } - + "work on a yet unevaluated snapshot" in { val sz = 50000 val ct = new TrieMap[Wrap, Int] for (i <- 0 until sz) ct.update(new Wrap(i), i) - + val snap = ct.snapshot() val it = snap.iterator - + while (it.hasNext) it.next() } - + "be duplicated" in { val sz = 50 val ct = collection.parallel.mutable.ParTrieMap((0 until sz) zip (0 until sz): _*) val it = ct.splitter for (_ <- 0 until (sz / 2)) it.next() val dupit = it.dup - + it.toList shouldEqual dupit.toList } - + } - + } diff --git a/test/files/run/enums.scala b/test/files/run/enums.scala index 9cdeed2691..3aad7ec320 100644 --- a/test/files/run/enums.scala +++ b/test/files/run/enums.scala @@ -36,8 +36,11 @@ object Test2 { object Test3 { - object Direction extends Enumeration("North", "South", "East", "West") { - val North, South, East, West = Value; + object Direction extends Enumeration { + val North = Value("North") + val South = Value("South") + val East = Value("East") + val West = Value("West") } def run: Int = { @@ -48,8 +51,11 @@ object Test3 { object Test4 { - object Direction extends Enumeration("North", "South", "East", "West") { - val North, South, East, West = Value; + object Direction extends Enumeration { + val North = Value("North") + val South = Value("South") + val East = Value("East") + val West = Value("West") } def run: Int = { diff --git a/test/files/run/existentials-in-compiler.check b/test/files/run/existentials-in-compiler.check index 0d7a9298b4..b0d852865d 100644 --- a/test/files/run/existentials-in-compiler.check +++ b/test/files/run/existentials-in-compiler.check @@ -8,22 +8,22 @@ abstract trait BippyLike[A <: AnyRef, B <: List[A], This <: extest.BippyLike[A,B extest.BippyLike[A,B,This] forSome { A <: AnyRef; B <: List[A]; This <: extest.BippyLike[A,B,This] with extest.Bippy[A,B] } abstract trait Contra[-A >: AnyRef, -B] extends AnyRef - extest.Contra[_ >: AnyRef, _] + extest.Contra[AnyRef, _] abstract trait ContraLike[-A >: AnyRef, -B >: List[A]] extends AnyRef extest.ContraLike[A,B] forSome { -A >: AnyRef; -B >: List[A] } abstract trait Cov01[+A <: AnyRef, +B] extends AnyRef - extest.Cov01[_ <: AnyRef, _] + extest.Cov01[AnyRef,Any] abstract trait Cov02[+A <: AnyRef, B] extends AnyRef - extest.Cov02[_ <: AnyRef, _] + extest.Cov02[AnyRef, _] abstract trait Cov03[+A <: AnyRef, -B] extends AnyRef - extest.Cov03[_ <: AnyRef, _] + extest.Cov03[AnyRef, _] abstract trait Cov04[A <: AnyRef, +B] extends AnyRef - extest.Cov04[_ <: AnyRef, _] + extest.Cov04[_ <: AnyRef, Any] abstract trait Cov05[A <: AnyRef, B] extends AnyRef extest.Cov05[_ <: AnyRef, _] @@ -32,7 +32,7 @@ abstract trait Cov06[A <: AnyRef, -B] extends AnyRef extest.Cov06[_ <: AnyRef, _] abstract trait Cov07[-A <: AnyRef, +B] extends AnyRef - extest.Cov07[_ <: AnyRef, _] + extest.Cov07[_ <: AnyRef, Any] abstract trait Cov08[-A <: AnyRef, B] extends AnyRef extest.Cov08[_ <: AnyRef, _] @@ -41,16 +41,16 @@ abstract trait Cov09[-A <: AnyRef, -B] extends AnyRef extest.Cov09[_ <: AnyRef, _] abstract trait Cov11[+A <: AnyRef, +B <: List[_]] extends AnyRef - extest.Cov11[_ <: AnyRef, _ <: List[_]] + extest.Cov11[AnyRef,List[_]] abstract trait Cov12[+A <: AnyRef, B <: List[_]] extends AnyRef - extest.Cov12[_ <: AnyRef, _ <: List[_]] + extest.Cov12[AnyRef, _ <: List[_]] abstract trait Cov13[+A <: AnyRef, -B <: List[_]] extends AnyRef - extest.Cov13[_ <: AnyRef, _ <: List[_]] + extest.Cov13[AnyRef, _ <: List[_]] abstract trait Cov14[A <: AnyRef, +B <: List[_]] extends AnyRef - extest.Cov14[_ <: AnyRef, _ <: List[_]] + extest.Cov14[_ <: AnyRef, List[_]] abstract trait Cov15[A <: AnyRef, B <: List[_]] extends AnyRef extest.Cov15[_ <: AnyRef, _ <: List[_]] @@ -59,7 +59,7 @@ abstract trait Cov16[A <: AnyRef, -B <: List[_]] extends AnyRef extest.Cov16[_ <: AnyRef, _ <: List[_]] abstract trait Cov17[-A <: AnyRef, +B <: List[_]] extends AnyRef - extest.Cov17[_ <: AnyRef, _ <: List[_]] + extest.Cov17[_ <: AnyRef, List[_]] abstract trait Cov18[-A <: AnyRef, B <: List[_]] extends AnyRef extest.Cov18[_ <: AnyRef, _ <: List[_]] @@ -68,16 +68,16 @@ abstract trait Cov19[-A <: AnyRef, -B <: List[_]] extends AnyRef extest.Cov19[_ <: AnyRef, _ <: List[_]] abstract trait Cov21[+A, +B] extends AnyRef - extest.Cov21[_, _] + extest.Cov21[Any,Any] abstract trait Cov22[+A, B] extends AnyRef - extest.Cov22[_, _] + extest.Cov22[Any, _] abstract trait Cov23[+A, -B] extends AnyRef - extest.Cov23[_, _] + extest.Cov23[Any, _] abstract trait Cov24[A, +B] extends AnyRef - extest.Cov24[_, _] + extest.Cov24[_, Any] abstract trait Cov25[A, B] extends AnyRef extest.Cov25[_, _] @@ -86,7 +86,7 @@ abstract trait Cov26[A, -B] extends AnyRef extest.Cov26[_, _] abstract trait Cov27[-A, +B] extends AnyRef - extest.Cov27[_, _] + extest.Cov27[_, Any] abstract trait Cov28[-A, B] extends AnyRef extest.Cov28[_, _] @@ -122,16 +122,16 @@ abstract trait Cov39[-A, -B, C <: Tuple2[_, _]] extends AnyRef extest.Cov39[_, _, _ <: Tuple2[_, _]] abstract trait Cov41[+A >: Null, +B] extends AnyRef - extest.Cov41[_ >: Null, _] + extest.Cov41[Any,Any] abstract trait Cov42[+A >: Null, B] extends AnyRef - extest.Cov42[_ >: Null, _] + extest.Cov42[Any, _] abstract trait Cov43[+A >: Null, -B] extends AnyRef - extest.Cov43[_ >: Null, _] + extest.Cov43[Any, _] abstract trait Cov44[A >: Null, +B] extends AnyRef - extest.Cov44[_ >: Null, _] + extest.Cov44[_ >: Null, Any] abstract trait Cov45[A >: Null, B] extends AnyRef extest.Cov45[_ >: Null, _] @@ -140,7 +140,7 @@ abstract trait Cov46[A >: Null, -B] extends AnyRef extest.Cov46[_ >: Null, _] abstract trait Cov47[-A >: Null, +B] extends AnyRef - extest.Cov47[_ >: Null, _] + extest.Cov47[_ >: Null, Any] abstract trait Cov48[-A >: Null, B] extends AnyRef extest.Cov48[_ >: Null, _] @@ -149,7 +149,7 @@ abstract trait Cov49[-A >: Null, -B] extends AnyRef extest.Cov49[_ >: Null, _] abstract trait Covariant[+A <: AnyRef, +B] extends AnyRef - extest.Covariant[_ <: AnyRef, _] + extest.Covariant[AnyRef,Any] abstract trait CovariantLike[+A <: AnyRef, +B <: List[A], +This <: extest.CovariantLike[A,B,This] with extest.Covariant[A,B]] extends AnyRef extest.CovariantLike[A,B,This] forSome { +A <: AnyRef; +B <: List[A]; +This <: extest.CovariantLike[A,B,This] with extest.Covariant[A,B] } diff --git a/test/files/run/idempotency-case-classes.check b/test/files/run/idempotency-case-classes.check index 700af3b81b..80d178cba3 100644 --- a/test/files/run/idempotency-case-classes.check +++ b/test/files/run/idempotency-case-classes.check @@ -42,7 +42,7 @@ C(2,3) C.super.<init>(); () }; - final override def toString(): String = "C"; + final override <synthetic> def toString(): String = "C"; case <synthetic> def apply(x: Int, y: Int): C = new C(x, y); case <synthetic> def unapply(x$0: C): Option[(Int, Int)] = if (x$0.==(null)) scala.this.None diff --git a/test/files/run/lazy-locals.scala b/test/files/run/lazy-locals.scala index aca15d0357..8d4c61be8c 100644 --- a/test/files/run/lazy-locals.scala +++ b/test/files/run/lazy-locals.scala @@ -120,7 +120,7 @@ object Test extends App { t } - /** test recursive method with lazy vals and a all vals forced */ + /** test recursive method with lazy vals and all vals forced */ def testLazyRecMany(n: Int): Int = { lazy val t = { println("forced lazy val t at n = " + n); 42 } if (n > 0) { diff --git a/test/files/run/map_java_conversions.scala b/test/files/run/map_java_conversions.scala index 7714b2cc74..751167c04d 100644 --- a/test/files/run/map_java_conversions.scala +++ b/test/files/run/map_java_conversions.scala @@ -19,7 +19,7 @@ object Test { val concMap = new java.util.concurrent.ConcurrentHashMap[String, String] test(concMap) - val cmap = asScalaConcurrentMap(concMap) + val cmap = mapAsScalaConcurrentMap(concMap) cmap.putIfAbsent("absentKey", "absentValue") cmap.put("somekey", "somevalue") assert(cmap.remove("somekey", "somevalue") == true) diff --git a/test/files/run/reify-staticXXX.scala b/test/files/run/reify-staticXXX.scala index dc861f843e..e80157dd8f 100644 --- a/test/files/run/reify-staticXXX.scala +++ b/test/files/run/reify-staticXXX.scala @@ -4,12 +4,12 @@ import scala.tools.reflect.Eval object B { override def toString = "object" } class C { override def toString = "class" } -package foo { +package foo1 { object B { override def toString = "package > object" } class C { override def toString = "package > class" } } -object foo { +object Foo2 { object B { override def toString = "object > object" } class C { override def toString = "object > class" } } @@ -20,14 +20,14 @@ object packageless { println(reify(B).eval) println(new C) println(reify(new C).eval) - println(foo.B) - println(reify(foo.B).eval) - println(new foo.C) - println(reify(new foo.C).eval) - println(_root_.foo.B) - println(reify(_root_.foo.B).eval) - println(new _root_.foo.C) - println(reify(new _root_.foo.C).eval) + println(Foo2.B) + println(reify(Foo2.B).eval) + println(new Foo2.C) + println(reify(new Foo2.C).eval) + println(_root_.foo1.B) + println(reify(_root_.foo1.B).eval) + println(new _root_.foo1.C) + println(reify(new _root_.foo1.C).eval) } } @@ -38,14 +38,14 @@ package packageful { println(reify(B).eval) println(new C) println(reify(new C).eval) - println(foo.B) - println(reify(foo.B).eval) - println(new foo.C) - println(reify(new foo.C).eval) - println(_root_.foo.B) - println(reify(_root_.foo.B).eval) - println(new _root_.foo.C) - println(reify(new _root_.foo.C).eval) + println(Foo2.B) + println(reify(Foo2.B).eval) + println(new Foo2.C) + println(reify(new Foo2.C).eval) + println(_root_.foo1.B) + println(reify(_root_.foo1.B).eval) + println(new _root_.foo1.C) + println(reify(new _root_.foo1.C).eval) } } } diff --git a/test/files/run/reify_magicsymbols.check b/test/files/run/reify_magicsymbols.check index e2aa46a364..c9d892d793 100644 --- a/test/files/run/reify_magicsymbols.check +++ b/test/files/run/reify_magicsymbols.check @@ -10,4 +10,4 @@ List[Null] List[Nothing] AnyRef{def foo(x: Int): Int} Int* => Unit -=> Int => Unit +(=> Int) => Unit diff --git a/test/files/run/repl-empty-package.check b/test/files/run/repl-empty-package.check new file mode 100644 index 0000000000..ecf79c2c6d --- /dev/null +++ b/test/files/run/repl-empty-package.check @@ -0,0 +1,7 @@ +Type in expressions to have them evaluated. +Type :help for more information. + +scala> println(Bippy.bippy) +bippy! + +scala> diff --git a/test/files/run/repl-empty-package/s_1.scala b/test/files/run/repl-empty-package/s_1.scala new file mode 100644 index 0000000000..b59d16b338 --- /dev/null +++ b/test/files/run/repl-empty-package/s_1.scala @@ -0,0 +1,3 @@ +object Bippy { + def bippy = "bippy!" +} diff --git a/test/files/run/repl-empty-package/s_2.scala b/test/files/run/repl-empty-package/s_2.scala new file mode 100644 index 0000000000..512e6dd382 --- /dev/null +++ b/test/files/run/repl-empty-package/s_2.scala @@ -0,0 +1,5 @@ +import scala.tools.partest.ReplTest + +object Test extends ReplTest { + def code = "println(Bippy.bippy)" +} diff --git a/test/files/run/t1505.scala b/test/files/run/t1505.scala index a246e8a35b..d7feb30ce3 100644 --- a/test/files/run/t1505.scala +++ b/test/files/run/t1505.scala @@ -1,5 +1,3 @@ -object P extends Enumeration(0, "A", "B", "C") { val A, B, C = Value } - object Q extends Enumeration { val A = Value("A") val B = Value("B") @@ -11,9 +9,14 @@ object R extends Enumeration { } object Test extends App { - assert(P(0) == P.withName("A")) - assert(P.C == P.withName("C")) - assert(Q(0) == Q.withName("A")) assert(Q.C == Q.withName("C")) + + assert(R(0) == R.withName("A")) + assert(R.C == R.withName("C")) + + var failed = false + try { Q.withName("x") } catch { case _: NoSuchElementException => failed = true } + assert(failed) + } diff --git a/test/files/run/t2577.check b/test/files/run/t2577.check new file mode 100644 index 0000000000..4a584e4989 --- /dev/null +++ b/test/files/run/t2577.check @@ -0,0 +1 @@ +Nothing diff --git a/test/files/run/t2577.scala b/test/files/run/t2577.scala new file mode 100644 index 0000000000..6d836a3996 --- /dev/null +++ b/test/files/run/t2577.scala @@ -0,0 +1,17 @@ +case class annot[T]() extends scala.annotation.StaticAnnotation + +// type inference should infer @annot[Nothing] instead of @annot[T] +// note the T is not in scope here! +class Foo[@annot U] + +object Test { + import scala.reflect.runtime.universe._ + val x = new Foo + + def main(args: Array[String]): Unit = { + val targ = typeOf[x.type].widen match { + case TypeRef(_, _, arg :: _) => arg + } + println(targ) + } +} diff --git a/test/files/run/t2818.check b/test/files/run/t2818.check new file mode 100644 index 0000000000..31286c990b --- /dev/null +++ b/test/files/run/t2818.check @@ -0,0 +1,4 @@ +105 +499999500000 +0 +1 diff --git a/test/files/run/t2818.scala b/test/files/run/t2818.scala new file mode 100644 index 0000000000..19b67cbc88 --- /dev/null +++ b/test/files/run/t2818.scala @@ -0,0 +1,6 @@ +object Test extends App { + println((List.range(1L, 15L) :\ 0L) (_ + _)) + println((List.range(1L, 1000000L) :\ 0L) (_ + _)) + println((List.fill(5)(1) :\ 1) (_ - _)) + println((List.fill(1000000)(1) :\ 1) (_ - _)) +} diff --git a/test/files/run/t2873.check b/test/files/run/t2873.check index 9198280f61..209b679c07 100644 --- a/test/files/run/t2873.check +++ b/test/files/run/t2873.check @@ -1 +1 @@ -scala.collection.immutable.RedBlack<A>.Empty$ +RedBlack<A>.Empty$ diff --git a/test/files/run/t2873.scala b/test/files/run/t2873.scala index 8d48a8dbb4..3a3cc59b46 100644 --- a/test/files/run/t2873.scala +++ b/test/files/run/t2873.scala @@ -1,5 +1,10 @@ +abstract class RedBlack[A] extends Serializable { + abstract class Tree[+B] extends Serializable + case object Empty extends Tree[Nothing] +} + object Test { def main(args: Array[String]): Unit = { - println(classOf[scala.collection.immutable.RedBlack[_]].getMethod("Empty").getGenericReturnType) + println(classOf[RedBlack[_]].getMethod("Empty").getGenericReturnType) } } diff --git a/test/files/run/t3353.check b/test/files/run/t3353.check new file mode 100644 index 0000000000..8b4ae1fe69 --- /dev/null +++ b/test/files/run/t3353.check @@ -0,0 +1 @@ +Got: foo and None diff --git a/test/files/run/t3353.scala b/test/files/run/t3353.scala new file mode 100644 index 0000000000..eeb63c1b05 --- /dev/null +++ b/test/files/run/t3353.scala @@ -0,0 +1,10 @@ +object Test extends App { + + "foo" match { + case Matcher(result) => println(result) + } + + object Matcher{ + def unapply(s: String)(implicit secondParam: Option[String] = None) = Some("Got: " + s + " and " + secondParam) + } +} diff --git a/test/files/run/t4729/S_2.scala b/test/files/run/t4729/S_2.scala index e34e3d34d4..a80afb0257 100644 --- a/test/files/run/t4729/S_2.scala +++ b/test/files/run/t4729/S_2.scala @@ -20,7 +20,7 @@ object Test { (new ScalaVarArgs).method("1", "2") (new ScalaVarArgs: J_1).method("1", "2") - //[4] Not Ok -- error when assigning anonymous class to a explictly typed val + //[4] Not Ok -- error when assigning anonymous class to an explictly typed val // Compiler error: object creation impossible, since method method in trait VarArgs of type (s: <repeated...>[java.lang.String])Unit is not defined val tagged: J_1 = new J_1 { def method(s: String*) { println(s) } diff --git a/test/files/run/t4859.check b/test/files/run/t4859.check new file mode 100644 index 0000000000..d329744ca0 --- /dev/null +++ b/test/files/run/t4859.check @@ -0,0 +1,8 @@ +Inner +Inner.i +About to reference Inner.i +Outer +Inner.i +About to reference O.N +About to reference O.N +About to reference O.N.apply() diff --git a/test/files/run/t4859.scala b/test/files/run/t4859.scala new file mode 100644 index 0000000000..3c20cea983 --- /dev/null +++ b/test/files/run/t4859.scala @@ -0,0 +1,29 @@ +object O { + case class N() + object P +} + +object Outer { + println("Outer") + object Inner { + println("Inner") + def i { + println("Inner.i") + } + } +} + +object Test { + def main(args: Array[String]) { + Outer.Inner.i // we still don't initialize Outer here (but should we?) + + {println("About to reference Inner.i"); Outer}.Inner.i // Outer will be initialized. + + {println("About to reference O.N" ); O}.N + + {println("About to reference O.N" ); O}.N + + {println("About to reference O.N.apply()"); O}.N.apply() + } +} + diff --git a/test/files/run/t5225_2.check b/test/files/run/t5225_2.check index 8ed54a14bb..477ea4eb6d 100644 --- a/test/files/run/t5225_2.check +++ b/test/files/run/t5225_2.check @@ -1,4 +1,4 @@ { - def foo(@new cloneable() x: Int) = ""; + def foo(@new elidable(0) x: Int) = ""; () } diff --git a/test/files/run/t5225_2.scala b/test/files/run/t5225_2.scala index d1b607499c..cf0f23a5c8 100644 --- a/test/files/run/t5225_2.scala +++ b/test/files/run/t5225_2.scala @@ -1,6 +1,6 @@ import scala.reflect.runtime.universe._ object Test extends App { - val tree = reify{def foo(@cloneable x: Int) = ""}.tree + val tree = reify{def foo(@annotation.elidable(0) x: Int) = ""}.tree println(tree.toString) }
\ No newline at end of file diff --git a/test/files/run/t5543.check b/test/files/run/t5543.check index 517038f4c7..2ef2d51ff4 100644 --- a/test/files/run/t5543.check +++ b/test/files/run/t5543.check @@ -1,3 +1,9 @@ Test, 7, 119 m, 3, 19 Test, 5, 85 +T +C +T +T +D +T diff --git a/test/files/run/t5543.scala b/test/files/run/t5543.scala index 651bc7f2b2..3684bf9690 100644 --- a/test/files/run/t5543.scala +++ b/test/files/run/t5543.scala @@ -22,5 +22,24 @@ object Test extends Function0[Int] { println(sut.toString) println(sut.m()) println(A.init()()) + + println((new T.C()).x) + println((new T.D(0,0)).x) + } +} + +object T { + override def toString = "T" + + // `this` refers to T + class C(val x: Any = {println(this); this}) { // prints T + println(this) // prints C + override def toString() = "C" + } + + class D(val x: Any) { + override def toString() = "D" + // `this` refers again to T + def this(a: Int, b: Int, c: Any = {println(this); this}) { this(c); println(this) } // prints T, then prints D } } diff --git a/test/files/run/t5568.check b/test/files/run/t5568.check new file mode 100644 index 0000000000..67aaf16e07 --- /dev/null +++ b/test/files/run/t5568.check @@ -0,0 +1,9 @@ +void +int +class scala.runtime.BoxedUnit +class scala.runtime.BoxedUnit +class java.lang.Integer +class java.lang.Integer +5 +5 +5 diff --git a/test/files/run/t5568.scala b/test/files/run/t5568.scala new file mode 100644 index 0000000000..14599d9ed2 --- /dev/null +++ b/test/files/run/t5568.scala @@ -0,0 +1,16 @@ +object Test { + def main(args: Array[String]): Unit = { + // these should give unboxed results + println(().getClass) + println(5.getClass) + // these should give boxed results + println(().asInstanceOf[AnyRef with Unit].getClass) + println(().asInstanceOf[Unit with AnyRef].getClass) + println(5.asInstanceOf[AnyRef with Int].getClass) + println(5.asInstanceOf[Int with AnyRef].getClass) + //make sure ## wasn't broken + println(5.##) + println((5.asInstanceOf[AnyRef]).##) + println((5:Any).##) + } +} diff --git a/test/files/run/t5879.check b/test/files/run/t5879.check index b6cbda35a7..4bdf3f5fcf 100644 --- a/test/files/run/t5879.check +++ b/test/files/run/t5879.check @@ -1,16 +1,8 @@ Map(1 -> 1) 1 -Map(1 -> 1) -1 -(1,1) -Map(1 -> 1) -1 (1,1) Map(1 -> 1) 1 (1,2) Map(1 -> 2) 2 -(1,2) -Map(1 -> 2) -2
\ No newline at end of file diff --git a/test/files/run/t5879.scala b/test/files/run/t5879.scala index e1c07fc4c2..18dd94289d 100644 --- a/test/files/run/t5879.scala +++ b/test/files/run/t5879.scala @@ -17,10 +17,6 @@ object Test { val r = a.merged(b)(null) println(r) println(r(1)) - - val rold = a.merge(b) - println(rold) - println(rold(1)) } def resolveFirst() { @@ -34,10 +30,6 @@ object Test { val r = a.merged(b) { collision } println(r) println(r(1)) - - val rold = a.merge(b, collision) - println(rold) - println(rold(1)) } def resolveSecond() { @@ -51,10 +43,6 @@ object Test { val r = a.merged(b) { collision } println(r) println(r(1)) - - val rold = a.merge(b, collision) - println(rold) - println(rold(1)) } def resolveMany() { @@ -66,9 +54,6 @@ object Test { val r = a.merged(b) { collision } for ((k, v) <- r) assert(v == 100 + 2 * k, (k, v)) - - val rold = a.merge(b, collision) - for ((k, v) <- r) assert(v == 100 + 2 * k, (k, v)) } } diff --git a/test/files/run/t6011c.scala b/test/files/run/t6011c.scala new file mode 100644 index 0000000000..0647e3f81a --- /dev/null +++ b/test/files/run/t6011c.scala @@ -0,0 +1,13 @@ +object Test extends App { + // A variation of SI-6011, which eluded the fix + // in 2.10.0. + // + // duplicate keys in SWITCH, can't pick arbitrarily one of them to evict, see SI-6011. + // at scala.reflect.internal.SymbolTable.abort(SymbolTable.scala:50) + // at scala.tools.nsc.Global.abort(Global.scala:249) + // at scala.tools.nsc.backend.jvm.GenASM$JPlainBuilder$jcode$.emitSWITCH(GenASM.scala:1850) + ((1: Byte): @unchecked @annotation.switch) match { + case 1 => 2 + case 1 => 3 // crash + } +} diff --git a/test/files/run/t6028.check b/test/files/run/t6028.check index 42921ae2f5..942f3d5f0c 100644 --- a/test/files/run/t6028.check +++ b/test/files/run/t6028.check @@ -15,7 +15,7 @@ package <empty> { } }; def bar(barParam: Int): Object = { - @volatile var MethodLocalObject$module: runtime.VolatileObjectRef = new runtime.VolatileObjectRef(<empty>); + @volatile var MethodLocalObject$module: runtime.VolatileObjectRef = new runtime.VolatileObjectRef(null); T.this.MethodLocalObject$1(barParam, MethodLocalObject$module) }; def tryy(tryyParam: Int): Function0 = { diff --git a/test/files/run/t6135.scala b/test/files/run/t6135.scala new file mode 100644 index 0000000000..c0f8f3fd1d --- /dev/null +++ b/test/files/run/t6135.scala @@ -0,0 +1,13 @@ +object Test extends App { + class A { class V } + + abstract class B[S] { + def foo(t: S, a: A)(v: a.V) + } + + val b1 = new B[String] { + def foo(t: String, a: A)(v: a.V) = () // Bridge method required here! + } + + b1.foo("", null)(null) +} diff --git a/test/files/run/t6329_repl.check b/test/files/run/t6329_repl.check index 8663184bde..55d689f2fb 100644 --- a/test/files/run/t6329_repl.check +++ b/test/files/run/t6329_repl.check @@ -3,11 +3,37 @@ Type :help for more information. scala> -scala> classManifest[List[_]] +scala> import scala.reflect.classTag +import scala.reflect.classTag + +scala> classManifest[scala.List[_]] warning: there were 1 deprecation warnings; re-run with -deprecation for details -res0: scala.reflect.ClassTag[List[_]] = scala.collection.immutable.List[Any] +res0: scala.reflect.ClassTag[List[_]] = scala.collection.immutable.List[<?>] -scala> scala.reflect.classTag[List[_]] +scala> classTag[scala.List[_]] res1: scala.reflect.ClassTag[List[_]] = scala.collection.immutable.List +scala> classManifest[scala.collection.immutable.List[_]] +warning: there were 1 deprecation warnings; re-run with -deprecation for details +res2: scala.reflect.ClassTag[List[_]] = scala.collection.immutable.List[<?>] + +scala> classTag[scala.collection.immutable.List[_]] +res3: scala.reflect.ClassTag[List[_]] = scala.collection.immutable.List + +scala> classManifest[Predef.Set[_]] +warning: there were 1 deprecation warnings; re-run with -deprecation for details +res4: scala.reflect.ClassTag[scala.collection.immutable.Set[_]] = scala.collection.immutable.Set[<?>] + +scala> classTag[Predef.Set[_]] +res5: scala.reflect.ClassTag[scala.collection.immutable.Set[_]] = scala.collection.immutable.Set + +scala> classManifest[scala.collection.immutable.Set[_]] +warning: there were 1 deprecation warnings; re-run with -deprecation for details +res6: scala.reflect.ClassTag[scala.collection.immutable.Set[_]] = scala.collection.immutable.Set[<?>] + +scala> classTag[scala.collection.immutable.Set[_]] +res7: scala.reflect.ClassTag[scala.collection.immutable.Set[_]] = scala.collection.immutable.Set + +scala> + scala> diff --git a/test/files/run/t6329_repl.scala b/test/files/run/t6329_repl.scala index add6d64962..f210d6512c 100644 --- a/test/files/run/t6329_repl.scala +++ b/test/files/run/t6329_repl.scala @@ -2,7 +2,14 @@ import scala.tools.partest.ReplTest object Test extends ReplTest { def code = """ - |classManifest[List[_]] - |scala.reflect.classTag[List[_]] - |""".stripMargin + |import scala.reflect.classTag + |classManifest[scala.List[_]] + |classTag[scala.List[_]] + |classManifest[scala.collection.immutable.List[_]] + |classTag[scala.collection.immutable.List[_]] + |classManifest[Predef.Set[_]] + |classTag[Predef.Set[_]] + |classManifest[scala.collection.immutable.Set[_]] + |classTag[scala.collection.immutable.Set[_]] + """.stripMargin } diff --git a/test/files/run/t6329_vanilla.check b/test/files/run/t6329_vanilla.check index 8282afaeba..ad8f4b5c77 100644 --- a/test/files/run/t6329_vanilla.check +++ b/test/files/run/t6329_vanilla.check @@ -1,2 +1,8 @@ -scala.collection.immutable.List[Any] +scala.collection.immutable.List[<?>] scala.collection.immutable.List +scala.collection.immutable.List[<?>] +scala.collection.immutable.List +scala.collection.immutable.Set[<?>] +scala.collection.immutable.Set +scala.collection.immutable.Set[<?>] +scala.collection.immutable.Set diff --git a/test/files/run/t6329_vanilla.scala b/test/files/run/t6329_vanilla.scala index a31cd5c72e..f2d843896d 100644 --- a/test/files/run/t6329_vanilla.scala +++ b/test/files/run/t6329_vanilla.scala @@ -1,4 +1,12 @@ +import scala.reflect.classTag + object Test extends App { - println(classManifest[List[_]]) - println(scala.reflect.classTag[List[_]]) -}
\ No newline at end of file + println(classManifest[scala.List[_]]) + println(classTag[scala.List[_]]) + println(classManifest[scala.collection.immutable.List[_]]) + println(classTag[scala.collection.immutable.List[_]]) + println(classManifest[Predef.Set[_]]) + println(classTag[Predef.Set[_]]) + println(classManifest[scala.collection.immutable.Set[_]]) + println(classTag[scala.collection.immutable.Set[_]]) +} diff --git a/test/files/run/t6434.check b/test/files/run/t6434.check new file mode 100644 index 0000000000..f898b6b781 --- /dev/null +++ b/test/files/run/t6434.check @@ -0,0 +1,10 @@ +Type in expressions to have them evaluated. +Type :help for more information. + +scala> def f(x: => Int): Int = x +f: (x: => Int)Int + +scala> f _ +res0: (=> Int) => Int = <function1> + +scala> diff --git a/test/files/run/t6434.scala b/test/files/run/t6434.scala new file mode 100644 index 0000000000..e4a4579613 --- /dev/null +++ b/test/files/run/t6434.scala @@ -0,0 +1,8 @@ +import scala.tools.partest.ReplTest + +object Test extends ReplTest { + def code = +"""def f(x: => Int): Int = x +f _ +""" +} diff --git a/test/files/run/t6439.check b/test/files/run/t6439.check new file mode 100644 index 0000000000..3f5f7dc8a4 --- /dev/null +++ b/test/files/run/t6439.check @@ -0,0 +1,77 @@ +Type in expressions to have them evaluated. +Type :help for more information. + +scala> + +scala> class A +defined class A + +scala> object A // warn +defined object A +warning: previously defined class A is not a companion to object A. +Companions must be defined together; you may wish to use :paste mode for this. + +scala> trait B +defined trait B + +scala> object B // warn +defined object B +warning: previously defined trait B is not a companion to object B. +Companions must be defined together; you may wish to use :paste mode for this. + +scala> object C +defined object C + +scala> object Bippy +defined object Bippy + +scala> class C // warn +defined class C +warning: previously defined object C is not a companion to class C. +Companions must be defined together; you may wish to use :paste mode for this. + +scala> class D +defined class D + +scala> def D = 0 // no warn +D: Int + +scala> val D = 0 // no warn +D: Int = 0 + +scala> object E +defined object E + +scala> var E = 0 // no warn +E: Int = 0 + +scala> object F +defined object F + +scala> type F = Int // no warn +defined type alias F + +scala> :power +** Power User mode enabled - BEEP WHIR GYVE ** +** :phase has been set to 'typer'. ** +** scala.tools.nsc._ has been imported ** +** global._, definitions._ also imported ** +** Try :help, :vals, power.<tab> ** + +scala> object lookup { + import intp._ + def apply(name: String): Symbol = types(name) orElse terms(name) + def types(name: String): Symbol = replScope lookup (name: TypeName) orElse getClassIfDefined(name) + def terms(name: String): Symbol = replScope lookup (name: TermName) orElse getModuleIfDefined(name) + def types[T: global.TypeTag] : Symbol = typeOf[T].typeSymbol + def terms[T: global.TypeTag] : Symbol = typeOf[T].termSymbol + def apply[T: global.TypeTag] : Symbol = typeOf[T].typeSymbol +} +defined object lookup + +scala> lookup("F") // this now works as a result of changing .typeSymbol to .typeSymbolDirect in IMain#Request#definedSymbols +res0: $r.intp.global.Symbol = type F + +scala> + +scala> diff --git a/test/files/run/t6439.scala b/test/files/run/t6439.scala new file mode 100644 index 0000000000..175a1d134f --- /dev/null +++ b/test/files/run/t6439.scala @@ -0,0 +1,32 @@ +import scala.tools.partest.ReplTest + +object Test extends ReplTest { + + def code = """ +class A +object A // warn +trait B +object B // warn +object C +object Bippy +class C // warn +class D +def D = 0 // no warn +val D = 0 // no warn +object E +var E = 0 // no warn +object F +type F = Int // no warn +:power +object lookup { + import intp._ + def apply(name: String): Symbol = types(name) orElse terms(name) + def types(name: String): Symbol = replScope lookup (name: TypeName) orElse getClassIfDefined(name) + def terms(name: String): Symbol = replScope lookup (name: TermName) orElse getModuleIfDefined(name) + def types[T: global.TypeTag] : Symbol = typeOf[T].typeSymbol + def terms[T: global.TypeTag] : Symbol = typeOf[T].termSymbol + def apply[T: global.TypeTag] : Symbol = typeOf[T].typeSymbol +} +lookup("F") // this now works as a result of changing .typeSymbol to .typeSymbolDirect in IMain#Request#definedSymbols + """ +} diff --git a/test/files/run/t6443-by-name.check b/test/files/run/t6443-by-name.check new file mode 100644 index 0000000000..6f98fa4a28 --- /dev/null +++ b/test/files/run/t6443-by-name.check @@ -0,0 +1,3 @@ +1 +foo +foo diff --git a/test/files/run/t6443-by-name.scala b/test/files/run/t6443-by-name.scala new file mode 100644 index 0000000000..bfd9bf9791 --- /dev/null +++ b/test/files/run/t6443-by-name.scala @@ -0,0 +1,18 @@ +object Test { + + def main(args: Array[String]) { + def foo = {println("foo"); 0} + lazyDep(X)(foo) + } + + trait T { + type U + } + object X extends T { type U = Int } + + def lazyDep(t: T)(u: => t.U) { + println("1") + u + u + } +} diff --git a/test/files/run/t6443-varargs.check b/test/files/run/t6443-varargs.check new file mode 100644 index 0000000000..257cc5642c --- /dev/null +++ b/test/files/run/t6443-varargs.check @@ -0,0 +1 @@ +foo diff --git a/test/files/run/t6443-varargs.scala b/test/files/run/t6443-varargs.scala new file mode 100644 index 0000000000..9cbae3e99c --- /dev/null +++ b/test/files/run/t6443-varargs.scala @@ -0,0 +1,16 @@ +object Test { + + def main(args: Array[String]) { + def foo = {println("foo"); 0} + lazyDep(X)(foo) + } + + trait T { + type U + } + object X extends T { type U = Int } + + def lazyDep(t: T)(us: t.U*) { + List(us: _*) + } +} diff --git a/test/files/run/t6443.scala b/test/files/run/t6443.scala new file mode 100644 index 0000000000..67fe2cab22 --- /dev/null +++ b/test/files/run/t6443.scala @@ -0,0 +1,15 @@ +class Base +class Derived extends Base + +trait A { + def foo(d: String)(d2: d.type): Base + val s = "" + def bar: Unit = foo(s)(s) +} +object B extends A { + def foo(d: String)(d2: d.type): D forSome { type D <: S; type S <: Derived } = {d2.isEmpty; null} // Bridge method required here! +} + +object Test extends App { + B.bar +} diff --git a/test/files/run/t6443b.scala b/test/files/run/t6443b.scala new file mode 100644 index 0000000000..9320b1dcfe --- /dev/null +++ b/test/files/run/t6443b.scala @@ -0,0 +1,16 @@ +trait A { + type D >: Null <: C + def foo(d: D)(d2: d.type): Unit + trait C { + def bar: Unit = foo(null)(null) + } +} +object B extends A { + class D extends C + + def foo(d: D)(d2: d.type): Unit = () // Bridge method required here! +} + +object Test extends App { + new B.D().bar +} diff --git a/test/files/run/t6669.scala b/test/files/run/t6669.scala new file mode 100644 index 0000000000..b55718b12b --- /dev/null +++ b/test/files/run/t6669.scala @@ -0,0 +1,26 @@ +import java.io.{ByteArrayOutputStream, PrintStream} + +object Test extends App { + val baos = new ByteArrayOutputStream() + val ps = new PrintStream(baos) + + // first test with the default classpath + (scala.Console withOut ps) { + scala.tools.scalap.Main.main(Array("-verbose", "java.lang.Object")) + } + + // now make sure we saw the '.' in the classpath + val msg1 = baos.toString() + assert(msg1 contains "directory classpath: .", s"Did not see '.' in the default class path. Full results were:\n$msg1") + + // then test again with a user specified classpath + baos.reset + + (scala.Console withOut ps) { + scala.tools.scalap.Main.main(Array("-verbose", "-cp", "whatever", "java.lang.Object")) + } + + // now make sure we did not see the '.' in the classpath + val msg2 = baos.toString() + assert(!(msg2 contains "directory classpath: ."), s"Did saw '.' in the user specified class path. Full results were:\n$msg2") +} diff --git a/test/files/run/t6853.scala b/test/files/run/t6853.scala new file mode 100644 index 0000000000..352375c99c --- /dev/null +++ b/test/files/run/t6853.scala @@ -0,0 +1,18 @@ +// Test cases: the only place we can cut and paste without crying +// ourself to sleep. +object Test { + + def main(args: Array[String]): Unit = { + // First testing the basic operations + val m = collection.mutable.ListMap[String, Int]() + var i = 0 + while(i < 2) { m += ("foo" + i) -> i; i = i+1} + assert(m == Map("foo1"->1,"foo0"->0)) + m-= "foo0" + assert(m == Map("foo1"->1)) + // Now checking if it scales as described in SI-6853 + i = 0 + while(i < 80000) { m += ("foo" + i) -> i; i = i+1} + assert(m.size == 80000) + } +} diff --git a/test/files/run/t6860.check b/test/files/run/t6860.check new file mode 100644 index 0000000000..c96331f540 --- /dev/null +++ b/test/files/run/t6860.check @@ -0,0 +1,4 @@ +Bippy[String] +Bippy[String] +throws[Nothing] +throws[RuntimeException] diff --git a/test/files/run/t6860.scala b/test/files/run/t6860.scala new file mode 100644 index 0000000000..2dcc2a67f7 --- /dev/null +++ b/test/files/run/t6860.scala @@ -0,0 +1,20 @@ +class Bippy[T](val value: T) extends annotation.StaticAnnotation + +class A { + @Bippy("hi") def f1: Int = 1 + @Bippy[String]("hi") def f2: Int = 2 + + @throws("what do I throw?") def f3 = throw new RuntimeException + @throws[RuntimeException]("that's good to know!") def f4 = throw new RuntimeException +} + +object Test { + import scala.reflect.runtime.universe._ + + def main(args: Array[String]): Unit = { + val members = typeOf[A].declarations.toList + val tpes = members flatMap (_.annotations) map (_.tpe) + + tpes.map(_.toString).sorted foreach println + } +} diff --git a/test/files/run/t6863.scala b/test/files/run/t6863.scala new file mode 100644 index 0000000000..d77adb6af4 --- /dev/null +++ b/test/files/run/t6863.scala @@ -0,0 +1,114 @@ +/** Make sure that when a variable is captured its initialization expression is handled properly */ +object Test { + def lazyVal() = { + // internally lazy vals become vars which are initialized with "_", so they need to be tested just like vars do + lazy val x = "42" + assert({ () => x }.apply == "42") + } + def ident() = { + val y = "42" + var x = y + assert({ () => x }.apply == "42") + } + def apply() = { + def y(x : Int) = x.toString + var x = y(42) + assert({ () => x }.apply == "42") + } + def literal() = { + var x = "42" + assert({ () => x }.apply == "42") + } + def `new`() = { + var x = new String("42") + assert({ () => x }.apply == "42") + } + def select() = { + object Foo{val bar = "42"} + var x = Foo.bar + assert({ () => x }.apply == "42") + } + def `throw`() = { + var x = if (true) "42" else throw new Exception("42") + assert({ () => x }.apply == "42") + } + def assign() = { + var y = 1 + var x = y = 42 + assert({ () => x}.apply == ()) + } + def valDef() = { + var x = {val y = 42} + assert({ () => x}.apply == ()) + } + def `return`(): String = { + var x = if (true) return "42" else () + assert({ () => x}.apply == ()) + "42" + } + def tryFinally() = { + var x = try { "42" } finally () + assert({ () => x }.apply == "42") + } + def tryCatch() = { + var x = try { "42" } catch { case _ => "43" } + assert({ () => x }.apply == "42") + } + def `if`() = { + var x = if (true) () + assert({ () => x }.apply == ()) + } + def ifElse() = { + var x = if(true) "42" else "43" + assert({ () => x }.apply == "42") + } + def matchCase() = { + var x = 100 match { + case 100 => "42" + case _ => "43" + } + assert({ () => x }.apply == "42") + } + def block() = { + var x = { + val y = 42 + "42" + } + assert({ () => x }.apply == "42") + } + def labelDef() = { + var x = 100 match { + case 100 => try "42" finally () + } + assert({ () => x }.apply == "42") + } + def nested() = { + var x = { + val y = 42 + if(true) try "42" catch {case _ => "43"} + else "44" + } + assert({ () => x }.apply == "42") + } + def main(args: Array[String]) { + lazyVal() + ident() + apply() + literal() + `new`() + select() + `throw`() + assign() + valDef() + `return`() + tryFinally() + tryCatch() + ifElse() + `if`() + matchCase() + block() + labelDef() + nested() + } +} + diff --git a/test/files/run/t6939.scala b/test/files/run/t6939.scala new file mode 100644 index 0000000000..9fe721555f --- /dev/null +++ b/test/files/run/t6939.scala @@ -0,0 +1,13 @@ +object Test extends App { + val foo = <x:foo xmlns:x="http://foo.com/"><x:bar xmlns:x="http://bar.com/"><x:baz/></x:bar></x:foo> + assert(foo.child.head.scope.toString == """ xmlns:x="http://bar.com/"""") + + val fooDefault = <foo xmlns="http://foo.com/"><bar xmlns="http://bar.com/"><baz/></bar></foo> + assert(fooDefault.child.head.scope.toString == """ xmlns="http://bar.com/"""") + + val foo2 = scala.xml.XML.loadString("""<x:foo xmlns:x="http://foo.com/"><x:bar xmlns:x="http://bar.com/"><x:baz/></x:bar></x:foo>""") + assert(foo2.child.head.scope.toString == """ xmlns:x="http://bar.com/"""") + + val foo2Default = scala.xml.XML.loadString("""<foo xmlns="http://foo.com/"><bar xmlns="http://bar.com/"><baz/></bar></foo>""") + assert(foo2Default.child.head.scope.toString == """ xmlns="http://bar.com/"""") +} diff --git a/test/files/run/t6956.check b/test/files/run/t6956.check new file mode 100644 index 0000000000..0cfbf08886 --- /dev/null +++ b/test/files/run/t6956.check @@ -0,0 +1 @@ +2 diff --git a/test/files/run/t6956.scala b/test/files/run/t6956.scala new file mode 100644 index 0000000000..4a6583ca45 --- /dev/null +++ b/test/files/run/t6956.scala @@ -0,0 +1,26 @@ +import scala.tools.partest.IcodeTest + +class Switches { + private[this] final val ONE = 1 + + def switchBad(i: Byte): Int = i match { + case ONE => 1 + case 2 => 2 + case 3 => 3 + case _ => 0 + } + + def switchOkay(i: Byte): Int = i match { + case 1 => 1 + case 2 => 2 + case 3 => 3 + case _ => 0 + } +} + +object Test extends IcodeTest { + // ensure we get two switches out of this -- ignore the rest of the output for robustness + // exclude the constant we emit for the "SWITCH ..." string below (we get the icode for all the code you see in this file) + override def show() = println(collectIcode("").filter(x => x.indexOf("SWITCH ...") >= 0 && x.indexOf("CONSTANT(") == -1).size) +} + diff --git a/test/files/run/t6968.check b/test/files/run/t6968.check new file mode 100644 index 0000000000..7a18941537 --- /dev/null +++ b/test/files/run/t6968.check @@ -0,0 +1 @@ +1, 3, 5 diff --git a/test/files/run/t6968.scala b/test/files/run/t6968.scala new file mode 100644 index 0000000000..b5cadfd9e1 --- /dev/null +++ b/test/files/run/t6968.scala @@ -0,0 +1,7 @@ +object Test { + def main(args: Array[String]) { + val mixedList = List(1,(1,2),4,(3,1),(5,4),6) + val as = for((a,b) <- mixedList) yield a + println(as.mkString(", ")) + } +} diff --git a/test/files/run/t6969.check b/test/files/run/t6969.check new file mode 100644 index 0000000000..78297812c9 --- /dev/null +++ b/test/files/run/t6969.check @@ -0,0 +1 @@ +All threads completed. diff --git a/test/files/run/t6969.scala b/test/files/run/t6969.scala new file mode 100644 index 0000000000..8cfc28c1e5 --- /dev/null +++ b/test/files/run/t6969.scala @@ -0,0 +1,28 @@ +object Test { + private type Clearable = { def clear(): Unit } + private def choke() = { + try new Array[Object]((Runtime.getRuntime().maxMemory min Int.MaxValue).toInt) + catch { + case _: OutOfMemoryError => // what do you mean, out of memory? + case t: Throwable => println(t) + } + } + private def f(x: Clearable) = x.clear() + class Choker(id: Int) extends Thread { + private def g(iteration: Int) = { + val map = scala.collection.mutable.Map[Int, Int](1 -> 2) + try f(map) catch { case t: NullPointerException => println(s"Failed at $id/$iteration") ; throw t } + choke() + } + override def run() { + 1 to 50 foreach g + } + } + + def main(args: Array[String]): Unit = { + val threads = 1 to 3 map (id => new Choker(id)) + threads foreach (_.start()) + threads foreach (_.join()) + println("All threads completed.") + } +} diff --git a/test/files/run/test-cpp.scala b/test/files/run/test-cpp.scala index 5b3bc7b746..f9fa85c4d0 100644 --- a/test/files/run/test-cpp.scala +++ b/test/files/run/test-cpp.scala @@ -3,7 +3,7 @@ * in the copy-propagation performed before ClosureElimination. * * In the general case, the local variable 'l' is connected through - * a alias chain with other local variables and at the end of the + * an alias chain with other local variables and at the end of the * alias chain there may be a Value, call it 'v'. * * If 'v' is cheaper to access (it is a Deref(This) or Const(_)), then diff --git a/test/files/scalacheck/parallel-collections/ParallelMapCheck1.scala b/test/files/scalacheck/parallel-collections/ParallelMapCheck1.scala index 05237bace8..b6af8f41bd 100644 --- a/test/files/scalacheck/parallel-collections/ParallelMapCheck1.scala +++ b/test/files/scalacheck/parallel-collections/ParallelMapCheck1.scala @@ -20,7 +20,7 @@ abstract class ParallelMapCheck[K, V](collname: String) extends ParallelIterable property("gets iterated keys") = forAll(collectionPairs) { case (t, coll) => val containsT = for ((k, v) <- t) yield (coll.get(k) == Some(v)) - val containsSelf = for ((k, v) <- coll) yield (coll.get(k) == Some(v)) + val containsSelf = coll.map { case (k, v) => coll.get(k) == Some(v) } ("Par contains elements of seq map" |: containsT.forall(_ == true)) && ("Par contains elements of itself" |: containsSelf.forall(_ == true)) } diff --git a/test/files/scalacheck/redblack.scala b/test/files/scalacheck/redblack.scala deleted file mode 100644 index bbc6504f58..0000000000 --- a/test/files/scalacheck/redblack.scala +++ /dev/null @@ -1,213 +0,0 @@ -import org.scalacheck._ -import Prop._ -import Gen._ - -/* -Properties of a Red & Black Tree: - -A node is either red or black. -The root is black. (This rule is used in some definitions and not others. Since the -root can always be changed from red to black but not necessarily vice-versa this -rule has little effect on analysis.) -All leaves are black. -Both children of every red node are black. -Every simple path from a given node to any of its descendant leaves contains the same number of black nodes. -*/ - -abstract class RedBlackTest extends Properties("RedBlack") { - def minimumSize = 0 - def maximumSize = 5 - - object RedBlackTest extends scala.collection.immutable.RedBlack[String] { - def isSmaller(x: String, y: String) = x < y - } - - import RedBlackTest._ - - def nodeAt[A](tree: Tree[A], n: Int): Option[(String, A)] = if (n < tree.iterator.size && n >= 0) - Some(tree.iterator.drop(n).next) - else - None - - def treeContains[A](tree: Tree[A], key: String) = tree.iterator.map(_._1) contains key - - def mkTree(level: Int, parentIsBlack: Boolean = false, label: String = ""): Gen[Tree[Int]] = - if (level == 0) { - value(Empty) - } else { - for { - oddOrEven <- choose(0, 2) - tryRed = oddOrEven.sample.get % 2 == 0 // work around arbitrary[Boolean] bug - isRed = parentIsBlack && tryRed - nextLevel = if (isRed) level else level - 1 - left <- mkTree(nextLevel, !isRed, label + "L") - right <- mkTree(nextLevel, !isRed, label + "R") - } yield { - if (isRed) - RedTree(label + "N", 0, left, right) - else - BlackTree(label + "N", 0, left, right) - } - } - - def genTree = for { - depth <- choose(minimumSize, maximumSize + 1) - tree <- mkTree(depth) - } yield tree - - type ModifyParm - def genParm(tree: Tree[Int]): Gen[ModifyParm] - def modify(tree: Tree[Int], parm: ModifyParm): Tree[Int] - - def genInput: Gen[(Tree[Int], ModifyParm, Tree[Int])] = for { - tree <- genTree - parm <- genParm(tree) - } yield (tree, parm, modify(tree, parm)) -} - -trait RedBlackInvariants { - self: RedBlackTest => - - import RedBlackTest._ - - def rootIsBlack[A](t: Tree[A]) = t.isBlack - - def areAllLeavesBlack[A](t: Tree[A]): Boolean = t match { - case Empty => t.isBlack - case ne: NonEmpty[_] => List(ne.left, ne.right) forall areAllLeavesBlack - } - - def areRedNodeChildrenBlack[A](t: Tree[A]): Boolean = t match { - case RedTree(_, _, left, right) => List(left, right) forall (t => t.isBlack && areRedNodeChildrenBlack(t)) - case BlackTree(_, _, left, right) => List(left, right) forall areRedNodeChildrenBlack - case Empty => true - } - - def blackNodesToLeaves[A](t: Tree[A]): List[Int] = t match { - case Empty => List(1) - case BlackTree(_, _, left, right) => List(left, right) flatMap blackNodesToLeaves map (_ + 1) - case RedTree(_, _, left, right) => List(left, right) flatMap blackNodesToLeaves - } - - def areBlackNodesToLeavesEqual[A](t: Tree[A]): Boolean = t match { - case Empty => true - case ne: NonEmpty[_] => - ( - blackNodesToLeaves(ne).distinct.size == 1 - && areBlackNodesToLeavesEqual(ne.left) - && areBlackNodesToLeavesEqual(ne.right) - ) - } - - def orderIsPreserved[A](t: Tree[A]): Boolean = - t.iterator zip t.iterator.drop(1) forall { case (x, y) => isSmaller(x._1, y._1) } - - def setup(invariant: Tree[Int] => Boolean) = forAll(genInput) { case (tree, parm, newTree) => - invariant(newTree) - } - - property("root is black") = setup(rootIsBlack) - property("all leaves are black") = setup(areAllLeavesBlack) - property("children of red nodes are black") = setup(areRedNodeChildrenBlack) - property("black nodes are balanced") = setup(areBlackNodesToLeavesEqual) - property("ordering of keys is preserved") = setup(orderIsPreserved) -} - -object TestInsert extends RedBlackTest with RedBlackInvariants { - import RedBlackTest._ - - override type ModifyParm = Int - override def genParm(tree: Tree[Int]): Gen[ModifyParm] = choose(0, tree.iterator.size + 1) - override def modify(tree: Tree[Int], parm: ModifyParm): Tree[Int] = tree update (generateKey(tree, parm), 0) - - def generateKey(tree: Tree[Int], parm: ModifyParm): String = nodeAt(tree, parm) match { - case Some((key, _)) => key.init.mkString + "MN" - case None => nodeAt(tree, parm - 1) match { - case Some((key, _)) => key.init.mkString + "RN" - case None => "N" - } - } - - property("update adds elements") = forAll(genInput) { case (tree, parm, newTree) => - treeContains(newTree, generateKey(tree, parm)) - } -} - -object TestModify extends RedBlackTest { - import RedBlackTest._ - - def newValue = 1 - override def minimumSize = 1 - override type ModifyParm = Int - override def genParm(tree: Tree[Int]): Gen[ModifyParm] = choose(0, tree.iterator.size) - override def modify(tree: Tree[Int], parm: ModifyParm): Tree[Int] = nodeAt(tree, parm) map { - case (key, _) => tree update (key, newValue) - } getOrElse tree - - property("update modifies values") = forAll(genInput) { case (tree, parm, newTree) => - nodeAt(tree,parm) forall { case (key, _) => - newTree.iterator contains (key, newValue) - } - } -} - -object TestDelete extends RedBlackTest with RedBlackInvariants { - import RedBlackTest._ - - override def minimumSize = 1 - override type ModifyParm = Int - override def genParm(tree: Tree[Int]): Gen[ModifyParm] = choose(0, tree.iterator.size) - override def modify(tree: Tree[Int], parm: ModifyParm): Tree[Int] = nodeAt(tree, parm) map { - case (key, _) => tree delete key - } getOrElse tree - - property("delete removes elements") = forAll(genInput) { case (tree, parm, newTree) => - nodeAt(tree, parm) forall { case (key, _) => - !treeContains(newTree, key) - } - } -} - -object TestRange extends RedBlackTest with RedBlackInvariants { - import RedBlackTest._ - - override type ModifyParm = (Option[Int], Option[Int]) - override def genParm(tree: Tree[Int]): Gen[ModifyParm] = for { - from <- choose(0, tree.iterator.size) - to <- choose(0, tree.iterator.size) suchThat (from <=) - optionalFrom <- oneOf(Some(from), None, Some(from)) // Double Some(n) to get around a bug - optionalTo <- oneOf(Some(to), None, Some(to)) // Double Some(n) to get around a bug - } yield (optionalFrom, optionalTo) - - override def modify(tree: Tree[Int], parm: ModifyParm): Tree[Int] = { - val from = parm._1 flatMap (nodeAt(tree, _) map (_._1)) - val to = parm._2 flatMap (nodeAt(tree, _) map (_._1)) - tree range (from, to) - } - - property("range boundaries respected") = forAll(genInput) { case (tree, parm, newTree) => - val from = parm._1 flatMap (nodeAt(tree, _) map (_._1)) - val to = parm._2 flatMap (nodeAt(tree, _) map (_._1)) - ("lower boundary" |: (from forall ( key => newTree.iterator.map(_._1) forall (key <=)))) && - ("upper boundary" |: (to forall ( key => newTree.iterator.map(_._1) forall (key >)))) - } - - property("range returns all elements") = forAll(genInput) { case (tree, parm, newTree) => - val from = parm._1 flatMap (nodeAt(tree, _) map (_._1)) - val to = parm._2 flatMap (nodeAt(tree, _) map (_._1)) - val filteredTree = (tree.iterator - .map(_._1) - .filter(key => from forall (key >=)) - .filter(key => to forall (key <)) - .toList) - filteredTree == newTree.iterator.map(_._1).toList - } -} - -object Test extends Properties("RedBlack") { - include(TestInsert) - include(TestModify) - include(TestDelete) - include(TestRange) -} - diff --git a/test/partest b/test/partest index 391cc52fe0..9b0ab02fdc 100755 --- a/test/partest +++ b/test/partest @@ -82,8 +82,13 @@ fi # last arg wins, so if JAVA_OPTS already contains -Xmx or -Xms the # supplied argument will be used. -JAVA_OPTS="-Xmx1024M -Xms64M $JAVA_OPTS" -[ -n "$SCALAC_OPTS" ] || SCALAC_OPTS="-deprecation" +# At this writing it is reported test/partest --all requires 108m permgen. +JAVA_OPTS="-Xmx1024M -Xms64M -XX:MaxPermSize=128M $JAVA_OPTS" + +# the ant task doesn't supply any options by default, +# so don't to that here either -- note that you may want to pass -optimise +# to mimic what happens during nightlies +# [ -n "$SCALAC_OPTS" ] || SCALAC_OPTS="-deprecation" partestDebugStr="" if [ ! -z "${PARTEST_DEBUG}" ] ; then diff --git a/test/files/neg/t5589neg.check b/test/pending/neg/t5589neg.check index f1dad94df3..f1dad94df3 100644 --- a/test/files/neg/t5589neg.check +++ b/test/pending/neg/t5589neg.check diff --git a/test/files/neg/t5589neg.scala b/test/pending/neg/t5589neg.scala index 31ff2c3693..31ff2c3693 100644 --- a/test/files/neg/t5589neg.scala +++ b/test/pending/neg/t5589neg.scala diff --git a/test/files/neg/t5589neg2.scala b/test/pending/neg/t5589neg2.scala index b7c7ab7218..b7c7ab7218 100644 --- a/test/files/neg/t5589neg2.scala +++ b/test/pending/neg/t5589neg2.scala diff --git a/test/files/pos/t1336.scala b/test/pending/pos/t1336.scala index 63967985c7..63967985c7 100644 --- a/test/files/pos/t1336.scala +++ b/test/pending/pos/t1336.scala diff --git a/test/pending/pos/t5459.scala b/test/pending/pos/t5459.scala new file mode 100644 index 0000000000..971e6f896d --- /dev/null +++ b/test/pending/pos/t5459.scala @@ -0,0 +1,48 @@ +trait A1 +trait A2 +trait A3 +trait L1 extends A1 with A2 with A3 + +object Test { + trait T1[-A <: A1] + trait T2[-A >: L1] + trait T3[ A <: A1] + trait T4[ A >: L1] + trait T5[+A <: A1] + trait T6[+A >: L1] + + def f1(x: T1[_]) = x + def f2(x: T2[_]) = x + def f3(x: T3[_]) = x + def f4(x: T4[_]) = x + def f5(x: T5[_]) = x + def f6(x: T6[_]) = x + // a.scala:22: error: type arguments [Any] do not conform to trait T5's type parameter bounds [+A <: A1] + // def f5(x: T5[_]) = x + // ^ + + def g1(x: T1[_ <: A1]) = x + def g2(x: T2[_ >: L1]) = x + def g3(x: T3[_ <: A1]) = x + def g4(x: T4[_ >: L1]) = x + def g5(x: T5[_ <: A1]) = x + def g6(x: T6[_ >: L1]) = x + + def q1(x: T1[_ >: L1]) = x + def q2(x: T2[_ <: A1]) = x + def q3(x: T3[_ >: L1]) = x + def q4(x: T4[_ <: A1]) = x + def q5(x: T5[_ >: L1]) = x + def q6(x: T6[_ <: A1]) = x + // a.scala:41: error: type arguments [Any] do not conform to trait T5's type parameter bounds [+A <: A1] + // def q5(x: T5[_ >: L1]) = x + // ^ + // two errors found + + def h1(x: T1[_ >: L1 <: A1]) = x + def h2(x: T2[_ >: L1 <: A1]) = x + def h3(x: T3[_ >: L1 <: A1]) = x + def h4(x: T4[_ >: L1 <: A1]) = x + def h5(x: T5[_ >: L1 <: A1]) = x + def h6(x: T6[_ >: L1 <: A1]) = x +} diff --git a/test/files/pos/t5589.scala b/test/pending/pos/t5589.scala index 69cbb20391..69cbb20391 100644 --- a/test/files/pos/t5589.scala +++ b/test/pending/pos/t5589.scala diff --git a/test/pending/pos/those-kinds-are-high.scala b/test/pending/pos/those-kinds-are-high.scala index 434e64cefb..78367cb746 100644 --- a/test/pending/pos/those-kinds-are-high.scala +++ b/test/pending/pos/those-kinds-are-high.scala @@ -4,18 +4,18 @@ class A { class C1[T] extends Template[C1] with Container[T] class C2[T] extends Template[C2] with Container[T] - + /** Target expression: * List(new C1[String], new C2[String]) */ - + // Here's what would ideally be inferred. // // scala> :type List[Template[Container] with Container[String]](new C1[String], new C2[String]) // List[Template[Container] with Container[java.lang.String]] // // Here's what it does infer. - // + // // scala> :type List(new C1[String], new C2[String]) // <console>:8: error: type mismatch; // found : C1[String] @@ -43,11 +43,54 @@ class A { // def fFail = List(new C1[String], new C2[String]) // ^ // two errors found - + /** Working version explicitly typed. */ def fExplicit = List[Template[Container] with Container[String]](new C1[String], new C2[String]) - + // nope def fFail = List(new C1[String], new C2[String]) } + + +trait Other { + trait GenBar[+A] + trait Bar[+A] extends GenBar[A] + trait Templ[+A, +CC[X] <: GenBar[X]] + + abstract class CC1[+A] extends Templ[A, CC1] with Bar[A] + abstract class CC2[+A] extends Templ[A, CC2] with Bar[A] + + // Compiles + class A1 { + abstract class BarFactory[CC[X] <: Bar[X]] + + def f(x: Boolean) = if (x) (null: BarFactory[CC1]) else (null: BarFactory[CC2]) + } + + // Fails - only difference is CC covariant. + class A2 { + abstract class BarFactory[+CC[X] <: Bar[X]] + + def f(x: Boolean) = if (x) (null: BarFactory[CC1]) else (null: BarFactory[CC2]) + // c.scala:23: error: kinds of the type arguments (Bar with Templ[Any,Bar]) do not conform to the expected kinds of the type parameters (type CC) in class BarFactory. + // Bar with Templ[Any,Bar]'s type parameters do not match type CC's expected parameters: + // <empty> has no type parameters, but type CC has one + // def f(x: Boolean) = if (x) (null: BarFactory[CC1]) else (null: BarFactory[CC2]) + // ^ + // one error found + } + + // Compiles - CC contravariant. + class A3 { + abstract class BarFactory[-CC[X] <: Bar[X]] // with Templ[X, CC]] + + def f(x: Boolean) = if (x) (null: BarFactory[CC1]) else (null: BarFactory[CC2]) + // c.scala:23: error: kinds of the type arguments (Bar with Templ[Any,Bar]) do not conform to the expected kinds of the type parameters (type CC) in class BarFactory. + // Bar with Templ[Any,Bar]'s type parameters do not match type CC's expected parameters: + // <empty> has no type parameters, but type CC has one + // def f(x: Boolean) = if (x) (null: BarFactory[CC1]) else (null: BarFactory[CC2]) + // ^ + // one error found + } +} diff --git a/test/files/run/t4574.scala b/test/pending/run/t4574.scala index 1dde496aca..1dde496aca 100644 --- a/test/files/run/t4574.scala +++ b/test/pending/run/t4574.scala diff --git a/test/scaladoc/resources/implicits-base-res.scala b/test/scaladoc/resources/implicits-base-res.scala index d6c0332c10..1d17e9a6d3 100644 --- a/test/scaladoc/resources/implicits-base-res.scala +++ b/test/scaladoc/resources/implicits-base-res.scala @@ -11,21 +11,21 @@ trait MyNumeric[R] * - tests the complete type inference * - the following inherited methods should appear: * {{{ - * def convToGtColonDoubleA(x: Double) // pimpA3: with a constraint that T <: Double - * def convToIntA(x: Int) // pimpA2: with a constraint that T = Int - * def convToManifestA(x: T) // pimpA7: with 2 constraints: T: Manifest and T <: Double - * def convToMyNumericA(x: T) // pimpA6: with a constraint that there is x: MyNumeric[T] implicit in scope - * def convToNumericA(x: T) // pimpA1: with a constraint that there is x: Numeric[T] implicit in scope - * def convToPimpedA(x: Bar[Foo[T]]) // pimpA5: no constraints, SHADOWED - * def convToPimpedA(x: S) // pimpA4: with 3 constraints: T = Foo[Bar[S]], S: Foo and S: Bar, SHADOWED - * def convToPimpedA(x: T) // pimpA0: with no constraints, SHADOWED - * def convToTraversableOps(x: T) // pimpA7: with 2 constraints: T: Manifest and T <: Double + * def convToGtColonDoubleA(x: Double) // enrichA3: with a constraint that T <: Double + * def convToIntA(x: Int) // enrichA2: with a constraint that T = Int + * def convToManifestA(x: T) // enrichA7: with 2 constraints: T: Manifest and T <: Double + * def convToMyNumericA(x: T) // enrichA6: with a constraint that there is x: MyNumeric[T] implicit in scope + * def convToNumericA(x: T) // enrichA1: with a constraint that there is x: Numeric[T] implicit in scope + * def convToEnrichedA(x: Bar[Foo[T]]) // enrichA5: no constraints, SHADOWED + * def convToEnrichedA(x: S) // enrichA4: with 3 constraints: T = Foo[Bar[S]], S: Foo and S: Bar, SHADOWED + * def convToEnrichedA(x: T) // enrichA0: with no constraints, SHADOWED + * def convToTraversableOps(x: T) // enrichA7: with 2 constraints: T: Manifest and T <: Double * // should not be abstract! * }}} */ class A[T] { - /** This should prevent the implicitly inherited `def convToPimpedA: T` from `pimpA0` from showing up */ - def convToPimpedA(x: T): T = sys.error("Let's check it out!") + /** This should prevent the implicitly inherited `def convToEnrichedA: T` from `enrichA0` from showing up */ + def convToEnrichedA(x: T): T = sys.error("Let's check it out!") /** This should check implicit member elimination in the case of subtyping */ def foo(a: T, b: AnyRef): T } @@ -33,15 +33,15 @@ class A[T] { object A { import language.implicitConversions // according to SIP18 - implicit def pimpA0[V](a: A[V]) = new PimpedA(a) - implicit def pimpA1[ZBUR: Numeric](a: A[ZBUR]) = new NumericA[ZBUR](a) - implicit def pimpA2(a: A[Int]) = new IntA(a) - implicit def pimpA3(a: A[T] forSome { type T <: Double }) = new GtColonDoubleA(a) - implicit def pimpA4[S](a: A[Foo[Bar[S]]])(implicit foo: Foo[S], bar: Bar[S]): PimpedA[S] = sys.error("not implemented") - implicit def pimpA5[Z](a: A[Z]): PimpedA[Bar[Foo[Z]]] = sys.error("not implemented") - implicit def pimpA6[Z: MyNumeric](a: A[Z]) = new MyNumericA[Z](a) + implicit def enrichA0[V](a: A[V]) = new EnrichedA(a) + implicit def enrichA1[ZBUR: Numeric](a: A[ZBUR]) = new NumericA[ZBUR](a) + implicit def enrichA2(a: A[Int]) = new IntA(a) + implicit def enrichA3(a: A[T] forSome { type T <: Double }) = new GtColonDoubleA(a) + implicit def enrichA4[S](a: A[Foo[Bar[S]]])(implicit foo: Foo[S], bar: Bar[S]): EnrichedA[S] = sys.error("not implemented") + implicit def enrichA5[Z](a: A[Z]): EnrichedA[Bar[Foo[Z]]] = sys.error("not implemented") + implicit def enrichA6[Z: MyNumeric](a: A[Z]) = new MyNumericA[Z](a) // TODO: Add H <: Double and see why it crashes for C and D -- context bounds, need to check! - implicit def pimpA7[H <: Double : Manifest](a: A[H]) = new ManifestA[H](a) with MyTraversableOps[H] { def convToTraversableOps(x: H): H = sys.error("no") } + implicit def enrichA7[H <: Double : Manifest](a: A[H]) = new ManifestA[H](a) with MyTraversableOps[H] { def convToTraversableOps(x: H): H = sys.error("no") } } @@ -49,14 +49,14 @@ object A { * - tests the existential type solving * - the following inherited methods should appear: * {{{ - * def convToGtColonDoubleA(x: Double) // pimpA3: no constraints - * def convToManifestA(x: Double) // pimpA7: no constraints - * def convToMyNumericA(x: Double) // pimpA6: (if showAll is set) with a constraint that there is x: MyNumeric[Double] implicit in scope - * def convToNumericA(x: Double) // pimpA1: no constraintsd - * def convToPimpedA(x: Bar[Foo[Double]]) // pimpA5: no constraints, SHADOWED - * def convToPimpedA(x: Double) // pimpA0: no constraints, SHADOWED - * def convToTraversableOps(x: Double) // pimpA7: no constraints - * // should not be abstract! + * def convToGtColonDoubleA(x: Double) // enrichA3: no constraints + * def convToManifestA(x: Double) // enrichA7: no constraints + * def convToMyNumericA(x: Double) // enrichA6: (if showAll is set) with a constraint that there is x: MyNumeric[Double] implicit in scope + * def convToNumericA(x: Double) // enrichA1: no constraintsd + * def convToEnrichedA(x: Bar[Foo[Double]]) // enrichA5: no constraints, SHADOWED + * def convToEnrichedA(x: Double) // enrichA0: no constraints, SHADOWED + * def convToTraversableOps(x: Double) // enrichA7: no constraints + * // should not be abstract! * }}} */ class B extends A[Double] @@ -67,11 +67,11 @@ object B extends A * - tests asSeenFrom * - the following inherited methods should appear: * {{{ - * def convToIntA(x: Int) // pimpA2: no constraints - * def convToMyNumericA(x: Int) // pimpA6: (if showAll is set) with a constraint that there is x: MyNumeric[Int] implicit in scope - * def convToNumericA(x: Int) // pimpA1: no constraints - * def convToPimpedA(x: Int) // pimpA0: no constraints, SHADOWED - * def convToPimpedA(x: Bar[Foo[Int]]) // pimpA5: no constraints, SHADOWED + * def convToIntA(x: Int) // enrichA2: no constraints + * def convToMyNumericA(x: Int) // enrichA6: (if showAll is set) with a constraint that there is x: MyNumeric[Int] implicit in scope + * def convToNumericA(x: Int) // enrichA1: no constraints + * def convToEnrichedA(x: Int) // enrichA0: no constraints, SHADOWED + * def convToEnrichedA(x: Bar[Foo[Int]]) // enrichA5: no constraints, SHADOWED * }}} */ class C extends A[Int] @@ -82,10 +82,10 @@ object C extends A * - tests implicit elimination * - the following inherited methods should appear: * {{{ - * def convToMyNumericA(x: String) // pimpA6: (if showAll is set) with a constraint that there is x: MyNumeric[String] implicit in scope - * def convToNumericA(x: String) // pimpA1: (if showAll is set) with a constraint that there is x: Numeric[String] implicit in scope - * def convToPimpedA(x: Bar[Foo[String]]) // pimpA5: no constraints, SHADOWED - * def convToPimpedA(x: String) // pimpA0: no constraints, SHADOWED + * def convToMyNumericA(x: String) // enrichA6: (if showAll is set) with a constraint that there is x: MyNumeric[String] implicit in scope + * def convToNumericA(x: String) // enrichA1: (if showAll is set) with a constraint that there is x: Numeric[String] implicit in scope + * def convToEnrichedA(x: Bar[Foo[String]]) // enrichA5: no constraints, SHADOWED + * def convToEnrichedA(x: String) // enrichA0: no constraints, SHADOWED * }}} */ class D extends A[String] @@ -93,12 +93,12 @@ class D extends A[String] object D extends A -/** PimpedA class <br/> +/** EnrichedA class <br/> * - tests simple inheritance and asSeenFrom * - A, B and C should be implicitly converted to this */ -class PimpedA[V](a: A[V]) { - /** The convToPimpedA: V documentation... */ - def convToPimpedA(x: V): V = sys.error("Not implemented") +class EnrichedA[V](a: A[V]) { + /** The convToEnrichedA: V documentation... */ + def convToEnrichedA(x: V): V = sys.error("Not implemented") } /** NumericA class <br/> diff --git a/test/scaladoc/run/SI-6017.check b/test/scaladoc/run/SI-6017.check new file mode 100644 index 0000000000..619c56180b --- /dev/null +++ b/test/scaladoc/run/SI-6017.check @@ -0,0 +1 @@ +Done. diff --git a/test/scaladoc/run/SI-6017.scala b/test/scaladoc/run/SI-6017.scala new file mode 100644 index 0000000000..a4950e48d8 --- /dev/null +++ b/test/scaladoc/run/SI-6017.scala @@ -0,0 +1,23 @@ +import scala.tools.nsc.doc +import scala.tools.nsc.doc.model._ +import scala.tools.nsc.doc.html.page.{Index, ReferenceIndex} +import scala.tools.partest.ScaladocModelTest + +object Test extends ScaladocModelTest { + override def scaladocSettings = "" + override def code = """ + class STAR + class Star + """ + + def testModel(rootPackage: Package) { + model match { + case Some(universe) => { + val index = IndexModelFactory.makeIndex(universe) + // Because "STAR" and "Star" are different + assert(index.firstLetterIndex('s').keys.toSeq.length == 2) + } + case _ => assert(false) + } + } +} diff --git a/test/scaladoc/run/SI-6812.check b/test/scaladoc/run/SI-6812.check new file mode 100644 index 0000000000..619c56180b --- /dev/null +++ b/test/scaladoc/run/SI-6812.check @@ -0,0 +1 @@ +Done. diff --git a/test/scaladoc/run/implicits-base.scala b/test/scaladoc/run/implicits-base.scala index 3d57306f5d..8f8652cdb3 100644 --- a/test/scaladoc/run/implicits-base.scala +++ b/test/scaladoc/run/implicits-base.scala @@ -25,54 +25,54 @@ object Test extends ScaladocModelTest { val A = base._class("A") - // def convToPimpedA(x: T) // pimpA0: with no constraints, SHADOWED - conv = A._conversion(A.qualifiedName + ".pimpA0") + // def convToEnrichedA(x: T) // enrichA0: with no constraints, SHADOWED + conv = A._conversion(A.qualifiedName + ".enrichA0") assert(conv.members.length == 1) assert(conv.constraints.length == 0) - assert(isShadowed(conv._member("convToPimpedA"))) - assert(conv._member("convToPimpedA").resultType.name == "T") + assert(isShadowed(conv._member("convToEnrichedA"))) + assert(conv._member("convToEnrichedA").resultType.name == "T") - // def convToNumericA: T // pimpA1: with a constraint that there is x: Numeric[T] implicit in scope - conv = A._conversion(A.qualifiedName + ".pimpA1") + // def convToNumericA: T // enrichA1: with a constraint that there is x: Numeric[T] implicit in scope + conv = A._conversion(A.qualifiedName + ".enrichA1") assert(conv.members.length == 1) assert(conv.constraints.length == 1) assert(conv._member("convToNumericA").resultType.name == "T") - // def convToIntA: Int // pimpA2: with a constraint that T = Int - conv = A._conversion(A.qualifiedName + ".pimpA2") + // def convToIntA: Int // enrichA2: with a constraint that T = Int + conv = A._conversion(A.qualifiedName + ".enrichA2") assert(conv.members.length == 1) assert(conv.constraints.length == 1) assert(conv._member("convToIntA").resultType.name == "Int") - // def convToGtColonDoubleA: Double // pimpA3: with a constraint that T <: Double - conv = A._conversion(A.qualifiedName + ".pimpA3") + // def convToGtColonDoubleA: Double // enrichA3: with a constraint that T <: Double + conv = A._conversion(A.qualifiedName + ".enrichA3") assert(conv.members.length == 1) assert(conv.constraints.length == 1) assert(conv._member("convToGtColonDoubleA").resultType.name == "Double") - // def convToPimpedA: S // pimpA4: with 3 constraints: T = Foo[Bar[S]], S: Foo and S: Bar - conv = A._conversion(A.qualifiedName + ".pimpA4") + // def convToEnrichedA: S // enrichA4: with 3 constraints: T = Foo[Bar[S]], S: Foo and S: Bar + conv = A._conversion(A.qualifiedName + ".enrichA4") assert(conv.members.length == 1) assert(conv.constraints.length == 3) - assert(conv._member("convToPimpedA").resultType.name == "S") + assert(conv._member("convToEnrichedA").resultType.name == "S") - // def convToPimpedA: Bar[Foo[T]] // pimpA5: no constraints - conv = A._conversion(A.qualifiedName + ".pimpA5") + // def convToEnrichedA: Bar[Foo[T]] // enrichA5: no constraints + conv = A._conversion(A.qualifiedName + ".enrichA5") assert(conv.members.length == 1) assert(conv.constraints.length == 0) - assert(isShadowed(conv._member("convToPimpedA"))) - assert(conv._member("convToPimpedA").resultType.name == "Bar[Foo[T]]") + assert(isShadowed(conv._member("convToEnrichedA"))) + assert(conv._member("convToEnrichedA").resultType.name == "Bar[Foo[T]]") - // def convToMyNumericA: T // pimpA6: with a constraint that there is x: MyNumeric[T] implicit in scope - conv = A._conversion(A.qualifiedName + ".pimpA6") + // def convToMyNumericA: T // enrichA6: with a constraint that there is x: MyNumeric[T] implicit in scope + conv = A._conversion(A.qualifiedName + ".enrichA6") assert(conv.members.length == 1) assert(conv.constraints.length == 1) assert(conv._member("convToMyNumericA").resultType.name == "T") - // def convToManifestA: T // pimpA7: with 2 constraints: T: Manifest and T <: Double - // def convToTraversableOps: T // pimpA7: with 2 constraints: T: Manifest and T <: Double + // def convToManifestA: T // enrichA7: with 2 constraints: T: Manifest and T <: Double + // def convToTraversableOps: T // enrichA7: with 2 constraints: T: Manifest and T <: Double // should not be abstract! - conv = A._conversion(A.qualifiedName + ".pimpA7") + conv = A._conversion(A.qualifiedName + ".enrichA7") assert(conv.members.length == 2) assert(conv.constraints.length == 2) assert(conv._member("convToManifestA").resultType.name == "T") @@ -84,45 +84,45 @@ object Test extends ScaladocModelTest { val B = base._class("B") // these conversions should not affect B - assert(B._conversions(A.qualifiedName + ".pimpA2").isEmpty) - assert(B._conversions(A.qualifiedName + ".pimpA4").isEmpty) + assert(B._conversions(A.qualifiedName + ".enrichA2").isEmpty) + assert(B._conversions(A.qualifiedName + ".enrichA4").isEmpty) - // def convToPimpedA(x: Double) // pimpA0: no constraints, SHADOWED - conv = B._conversion(A.qualifiedName + ".pimpA0") + // def convToEnrichedA(x: Double) // enrichA0: no constraints, SHADOWED + conv = B._conversion(A.qualifiedName + ".enrichA0") assert(conv.members.length == 1) assert(conv.constraints.length == 0) - assert(isShadowed(conv._member("convToPimpedA"))) - assert(conv._member("convToPimpedA").resultType.name == "Double") + assert(isShadowed(conv._member("convToEnrichedA"))) + assert(conv._member("convToEnrichedA").resultType.name == "Double") - // def convToNumericA: Double // pimpA1: no constraintsd - conv = B._conversion(A.qualifiedName + ".pimpA1") + // def convToNumericA: Double // enrichA1: no constraintsd + conv = B._conversion(A.qualifiedName + ".enrichA1") assert(conv.members.length == 1) assert(conv.constraints.length == 0) assert(conv._member("convToNumericA").resultType.name == "Double") - // def convToGtColonDoubleA: Double // pimpA3: no constraints - conv = B._conversion(A.qualifiedName + ".pimpA3") + // def convToGtColonDoubleA: Double // enrichA3: no constraints + conv = B._conversion(A.qualifiedName + ".enrichA3") assert(conv.members.length == 1) assert(conv.constraints.length == 0) assert(conv._member("convToGtColonDoubleA").resultType.name == "Double") - // def convToPimpedA: Bar[Foo[Double]] // pimpA5: no constraints - conv = B._conversion(A.qualifiedName + ".pimpA5") + // def convToEnrichedA: Bar[Foo[Double]] // enrichA5: no constraints + conv = B._conversion(A.qualifiedName + ".enrichA5") assert(conv.members.length == 1) assert(conv.constraints.length == 0) - assert(isShadowed(conv._member("convToPimpedA"))) - assert(conv._member("convToPimpedA").resultType.name == "Bar[Foo[Double]]") + assert(isShadowed(conv._member("convToEnrichedA"))) + assert(conv._member("convToEnrichedA").resultType.name == "Bar[Foo[Double]]") - // def convToMyNumericA: Double // pimpA6: (if showAll is set) with a constraint that there is x: MyNumeric[Double] implicit in scope - conv = B._conversion(A.qualifiedName + ".pimpA6") + // def convToMyNumericA: Double // enrichA6: (if showAll is set) with a constraint that there is x: MyNumeric[Double] implicit in scope + conv = B._conversion(A.qualifiedName + ".enrichA6") assert(conv.members.length == 1) assert(conv.constraints.length == 1) assert(conv._member("convToMyNumericA").resultType.name == "Double") - // def convToManifestA: Double // pimpA7: no constraints - // def convToTraversableOps: Double // pimpA7: no constraints + // def convToManifestA: Double // enrichA7: no constraints + // def convToTraversableOps: Double // enrichA7: no constraints // // should not be abstract! - conv = B._conversion(A.qualifiedName + ".pimpA7") + conv = B._conversion(A.qualifiedName + ".enrichA7") assert(conv.members.length == 2) assert(conv.constraints.length == 0) assert(conv._member("convToManifestA").resultType.name == "Double") @@ -134,38 +134,38 @@ object Test extends ScaladocModelTest { val C = base._class("C") // these conversions should not affect C - assert(C._conversions(A.qualifiedName + ".pimpA3").isEmpty) - assert(C._conversions(A.qualifiedName + ".pimpA4").isEmpty) - assert(C._conversions(A.qualifiedName + ".pimpA7").isEmpty) + assert(C._conversions(A.qualifiedName + ".enrichA3").isEmpty) + assert(C._conversions(A.qualifiedName + ".enrichA4").isEmpty) + assert(C._conversions(A.qualifiedName + ".enrichA7").isEmpty) - // def convToPimpedA(x: Int) // pimpA0: no constraints, SHADOWED - conv = C._conversion(A.qualifiedName + ".pimpA0") + // def convToEnrichedA(x: Int) // enrichA0: no constraints, SHADOWED + conv = C._conversion(A.qualifiedName + ".enrichA0") assert(conv.members.length == 1) assert(conv.constraints.length == 0) - assert(isShadowed(conv._member("convToPimpedA"))) - assert(conv._member("convToPimpedA").resultType.name == "Int") + assert(isShadowed(conv._member("convToEnrichedA"))) + assert(conv._member("convToEnrichedA").resultType.name == "Int") - // def convToNumericA: Int // pimpA1: no constraints - conv = C._conversion(A.qualifiedName + ".pimpA1") + // def convToNumericA: Int // enrichA1: no constraints + conv = C._conversion(A.qualifiedName + ".enrichA1") assert(conv.members.length == 1) assert(conv.constraints.length == 0) assert(conv._member("convToNumericA").resultType.name == "Int") - // def convToIntA: Int // pimpA2: no constraints - conv = C._conversion(A.qualifiedName + ".pimpA2") + // def convToIntA: Int // enrichA2: no constraints + conv = C._conversion(A.qualifiedName + ".enrichA2") assert(conv.members.length == 1) assert(conv.constraints.length == 0) assert(conv._member("convToIntA").resultType.name == "Int") - // def convToPimpedA: Bar[Foo[Int]] // pimpA5: no constraints - conv = C._conversion(A.qualifiedName + ".pimpA5") + // def convToEnrichedA: Bar[Foo[Int]] // enrichA5: no constraints + conv = C._conversion(A.qualifiedName + ".enrichA5") assert(conv.members.length == 1) assert(conv.constraints.length == 0) - assert(isShadowed(conv._member("convToPimpedA"))) - assert(conv._member("convToPimpedA").resultType.name == "Bar[Foo[Int]]") + assert(isShadowed(conv._member("convToEnrichedA"))) + assert(conv._member("convToEnrichedA").resultType.name == "Bar[Foo[Int]]") - // def convToMyNumericA: Int // pimpA6: (if showAll is set) with a constraint that there is x: MyNumeric[Int] implicit in scope - conv = C._conversion(A.qualifiedName + ".pimpA6") + // def convToMyNumericA: Int // enrichA6: (if showAll is set) with a constraint that there is x: MyNumeric[Int] implicit in scope + conv = C._conversion(A.qualifiedName + ".enrichA6") assert(conv.members.length == 1) assert(conv.constraints.length == 1) assert(conv._member("convToMyNumericA").resultType.name == "Int") @@ -175,33 +175,33 @@ object Test extends ScaladocModelTest { val D = base._class("D") // these conversions should not affect D - assert(D._conversions(A.qualifiedName + ".pimpA2").isEmpty) - assert(D._conversions(A.qualifiedName + ".pimpA3").isEmpty) - assert(D._conversions(A.qualifiedName + ".pimpA4").isEmpty) - assert(D._conversions(A.qualifiedName + ".pimpA7").isEmpty) + assert(D._conversions(A.qualifiedName + ".enrichA2").isEmpty) + assert(D._conversions(A.qualifiedName + ".enrichA3").isEmpty) + assert(D._conversions(A.qualifiedName + ".enrichA4").isEmpty) + assert(D._conversions(A.qualifiedName + ".enrichA7").isEmpty) - // def convToPimpedA(x: String) // pimpA0: no constraints, SHADOWED - conv = D._conversion(A.qualifiedName + ".pimpA0") + // def convToEnrichedA(x: String) // enrichA0: no constraints, SHADOWED + conv = D._conversion(A.qualifiedName + ".enrichA0") assert(conv.members.length == 1) assert(conv.constraints.length == 0) - assert(isShadowed(conv._member("convToPimpedA"))) - assert(conv._member("convToPimpedA").resultType.name == "String") + assert(isShadowed(conv._member("convToEnrichedA"))) + assert(conv._member("convToEnrichedA").resultType.name == "String") - // def convToNumericA: String // pimpA1: (if showAll is set) with a constraint that there is x: Numeric[String] implicit in scope - conv = D._conversion(A.qualifiedName + ".pimpA1") + // def convToNumericA: String // enrichA1: (if showAll is set) with a constraint that there is x: Numeric[String] implicit in scope + conv = D._conversion(A.qualifiedName + ".enrichA1") assert(conv.members.length == 1) assert(conv.constraints.length == 1) assert(conv._member("convToNumericA").resultType.name == "String") - // def convToPimpedA: Bar[Foo[String]] // pimpA5: no constraints - conv = D._conversion(A.qualifiedName + ".pimpA5") + // def convToEnrichedA: Bar[Foo[String]] // enrichA5: no constraints + conv = D._conversion(A.qualifiedName + ".enrichA5") assert(conv.members.length == 1) assert(conv.constraints.length == 0) - assert(isShadowed(conv._member("convToPimpedA"))) - assert(conv._member("convToPimpedA").resultType.name == "Bar[Foo[String]]") + assert(isShadowed(conv._member("convToEnrichedA"))) + assert(conv._member("convToEnrichedA").resultType.name == "Bar[Foo[String]]") - // def convToMyNumericA: String // pimpA6: (if showAll is set) with a constraint that there is x: MyNumeric[String] implicit in scope - conv = D._conversion(A.qualifiedName + ".pimpA6") + // def convToMyNumericA: String // enrichA6: (if showAll is set) with a constraint that there is x: MyNumeric[String] implicit in scope + conv = D._conversion(A.qualifiedName + ".enrichA6") assert(conv.members.length == 1) assert(conv.constraints.length == 1) assert(conv._member("convToMyNumericA").resultType.name == "String") diff --git a/tools/partest-ack b/tools/partest-ack index 0c8244257b..f7d5063292 100755 --- a/tools/partest-ack +++ b/tools/partest-ack @@ -2,36 +2,18 @@ # # wrapper around partest for fine-grained test selection via ack -args="$@" - -pathMatches () { - ack --noenv --text --files-with-matches "$@" test/files - - for p in $(find test/files/* -print); do - [[ $p =~ $1 ]] && echo "$p" - done -} - -testIds () { - pathMatches "$@" | \ - perl -pe 's#^(test/files/[^/]+/[^/.]+).*$#$1#' | \ - sort -u -} -testPaths () { - for id in "$@"; do - if [[ -d $id ]]; then - echo $id - elif [[ -f ${id}.scala ]]; then - echo "${id}.scala" - else - echo >&2 "No test corresponds to $id" - fi - done -} +declare quiet failed update partest_debug file_regex partest_args ack_args cotouched [[ $# -gt 0 ]] || { cat <<EOM -Usage: $0 <regex> [ack options] +Usage: $0 <regex> [-dfquvp] [ack options] + + -d pass --debug to partest + -f pass --failed to partest + -q DON'T pass --show-log and --show-diff to partest + -u pass --update-check to partest + -v pass --verbose to partest + -p <path> select tests appearing in commits where <path> was also modified Given a regular expression (and optionally, any arguments accepted by ack) runs all the tests for which any associated file matches the regex. Associated @@ -42,30 +24,118 @@ You must have ack installed: http://betterthangrep.com/ack-standalone Examples: - % tools/partest-ack monad - Found 4 tests matching 'ack monad' + > tools/partest-ack monad + % tests-with-matching-paths ... 2 + % tests-with-matching-code ... 2 + # 4 tests to run. - Testing individual files - testing: [...]/files/pos/tcpoly_boundedmonad.scala [ OK ] - testing: [...]/files/pos/tcpoly_ticket2096.scala [ OK ] - testing: [...]/files/run/tcpoly_monads.scala [ OK ] - testing: [...]/files/presentation/callcc-interpreter [ OK ] + > tools/partest-ack -p src/library/scala/Enumeration.scala + % tests-modified-in-same-commit ... 84 + # 84 tests to run. - % tools/partest-ack monad -i # -i == ignore case - Found 12 tests matching 'ack monad -i' - - Testing individual files - [etc] + > tools/partest-ack -f + % tests-which-failed ... 42 + # 42 tests to run. EOM exit 0 } -paths=$(testPaths $(testIds "$@")) -if [[ -z $paths ]]; then +# The leading : in :achs suppresses some errors. Each letter is a valid +# option. If an option takes an argument, a colon follows it, e.g. +# it would be :ach:s if -h took an argument. +while getopts :fuvdp: opt; do + case $opt in + d) partest_debug=true && partest_args="$partest_args --debug" ;; + f) failed=true && partest_args="$partest_args --failed" ;; + p) cotouched="$cotouched $OPTARG" ;; + q) quiet=true ;; + u) partest_args="$partest_args --update-check" ;; + v) partest_args="$partest_args --verbose" ;; + :) echo "Option -$OPTARG requires an argument." >&2 ;; # this case is called for a missing option argument + *) echo "Unrecognized argument $OPTARG" ;; # this is the catch-all implying an unknown option + esac +done + +shift $((OPTIND-1)) +file_regex="$1" +ack_args="$*" + +tests () { + find test/files -mindepth 2 -maxdepth 2 -name '*.scala' -o -type d +} + +pathsToTests () { + for path in $(perl -pe 's#^(test/files/[^/]+/[^/.]+).*$#$1#'); do + if [[ -d "$path" ]]; then + echo "$path" + elif [[ -f "$path.scala" ]]; then + echo "$path.scala" + fi + done | sort -u +} + +tests-with-matching-paths() { + local re="$1" + for p in $(find test/files -type f); do + [[ $p =~ $re ]] && echo "$p" + done +} + +tests-which-failed () { + for f in $(find test/files -name '*.log'); do + echo ${f%-*} + done +} + +tests-modified-in-same-commit() { + [[ $# -gt 0 ]] && \ + for rev in $(git rev-list HEAD -- "$@"); do + git --no-pager show --pretty="format:" --name-only "$rev" -- test/files + done +} + +tests-with-matching-code() { + ack --noenv --text --files-with-matches "$@" -- test/files +} + +countStdout () { + local -i count=0 + while read line; do + printf "$line\n" + count+=1 + done + + printf >&2 " $count\n" +} + +testRun () { + printf >&2 "%% %-30s ... " "$1" + "$@" | pathsToTests | countStdout +} + +allMatches() { + [[ -n $file_regex ]] && testRun tests-with-matching-paths $file_regex + [[ -n $cotouched ]] && testRun tests-modified-in-same-commit $cotouched + [[ -n $ack_args ]] && testRun tests-with-matching-code $ack_args + [[ -n $failed ]] && testRun tests-which-failed +} + +paths=$(allMatches | sort -u) +[[ -n $quiet ]] || partest_args="--show-diff --show-log $partest_args" + +if [[ -z $paths ]] && [[ -z $failed ]]; then echo >&2 "No matching tests." else count=$(echo $(echo "$paths" | wc -w)) - echo "Found $count tests matching 'ack $@'" - test/partest $paths + + # Output a command line which will re-run these same tests. + echo "# $count tests to run." + printf "%-52s %s\n" "test/partest $partest_args" "\\" + for path in $paths; do + printf " %-50s %s\n" "$path" "\\" + done + echo ' ""' + + test/partest $partest_args $paths fi |