diff options
36 files changed, 435 insertions, 115 deletions
diff --git a/project/Build.scala b/project/Build.scala index ea0e84f0cc..d3be8cd810 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -156,6 +156,8 @@ object ScalaBuild extends Build with Layers { def settingOverrides: Seq[Setting[_]] = publishSettings ++ Seq( crossPaths := false, autoScalaLibrary := false, + // Work around a bug where scala-library (and forkjoin) is put on classpath for analysis. + classpathOptions := ClasspathOptions.manual, publishArtifact in packageDoc := false, publishArtifact in packageSrc := false, target <<= (baseDirectory, name) apply (_ / "target" / _), @@ -168,8 +170,8 @@ object ScalaBuild extends Build with Layers { // Most libs in the compiler use this order to build. compileOrder in Compile := CompileOrder.JavaThenScala, lockFile <<= target(_ / "compile.lock"), - skip in Compile <<= lockFile.map(_ exists), - lock <<= lockFile map { f => IO.touch(f) }, + skip in Compile <<= lockFile map (_.exists), + lock <<= lockFile map (f => IO.touch(f)), unlock <<= lockFile map IO.delete ) diff --git a/src/compiler/scala/tools/nsc/backend/icode/Members.scala b/src/compiler/scala/tools/nsc/backend/icode/Members.scala index 71795a02aa..019e887c4e 100644 --- a/src/compiler/scala/tools/nsc/backend/icode/Members.scala +++ b/src/compiler/scala/tools/nsc/backend/icode/Members.scala @@ -257,11 +257,23 @@ trait Members { var succ = bb do { succ = nextBlock(succ); - bb.removeLastInstruction - succ.toList foreach { i => bb.emit(i, i.pos) } - code.removeBlock(succ) + val lastInstr = bb.lastInstruction + /* Ticket SI-5672 + * Besides removing the control-flow instruction at the end of `bb` (usually a JUMP), we have to pop any values it pushes. + * Examples: + * `SWITCH` consisting of just the default case, or + * `CJUMP(targetBlock, targetBlock, _, _)` ie where success and failure targets coincide (this one consumes two stack values). + */ + val oldTKs = lastInstr.consumedTypes + assert(lastInstr.consumed == oldTKs.size, "Someone forgot to override consumedTypes() in " + lastInstr) + + bb.removeLastInstruction + for(tk <- oldTKs.reverse) { bb.emit(DROP(tk), lastInstr.pos) } + succ.toList foreach { i => bb.emit(i, i.pos) } + code.removeBlock(succ) + exh foreach { e => e.covered = e.covered - succ } + nextBlock -= bb - exh foreach { e => e.covered = e.covered - succ } } while (nextBlock.isDefinedAt(succ)) bb.close } else diff --git a/src/compiler/scala/tools/nsc/backend/icode/Opcodes.scala b/src/compiler/scala/tools/nsc/backend/icode/Opcodes.scala index 576cc72f82..3179fc5c56 100644 --- a/src/compiler/scala/tools/nsc/backend/icode/Opcodes.scala +++ b/src/compiler/scala/tools/nsc/backend/icode/Opcodes.scala @@ -436,6 +436,8 @@ trait Opcodes { self: ICodes => override def consumed = 1 override def produced = 0 + override val consumedTypes = List(INT) + def flatTagsCount: Int = { var acc = 0; var rest = tags; while(rest.nonEmpty) { acc += rest.head.length; rest = rest.tail }; acc } // a one-liner } @@ -470,6 +472,8 @@ trait Opcodes { self: ICodes => override def consumed = 2 override def produced = 0 + + override val consumedTypes = List(kind, kind) } /** This class represents a CZJUMP instruction @@ -489,6 +493,8 @@ trait Opcodes { self: ICodes => override def consumed = 1 override def produced = 0 + + override val consumedTypes = List(kind) } @@ -499,6 +505,8 @@ trait Opcodes { self: ICodes => case class RETURN(kind: TypeKind) extends Instruction { override def consumed = if (kind == UNIT) 0 else 1 override def produced = 0 + + // TODO override val consumedTypes = List(kind) } /** This class represents a THROW instruction diff --git a/src/compiler/scala/tools/nsc/doc/html/page/Index.scala b/src/compiler/scala/tools/nsc/doc/html/page/Index.scala index f8fffdc726..8ed13e0da2 100644 --- a/src/compiler/scala/tools/nsc/doc/html/page/Index.scala +++ b/src/compiler/scala/tools/nsc/doc/html/page/Index.scala @@ -44,7 +44,7 @@ class Index(universe: doc.Universe, index: doc.Index) extends HtmlPage { </div> { browser } <div id="content" class="ui-layout-center"> - <iframe id="template" src={ relativeLinkTo{List("package.html")} }/> + <iframe id="template" name="template" src={ relativeLinkTo{List("package.html")} }/> </div> </body> diff --git a/src/compiler/scala/tools/nsc/transform/UnCurry.scala b/src/compiler/scala/tools/nsc/transform/UnCurry.scala index f01cbade18..8af12f3f10 100644 --- a/src/compiler/scala/tools/nsc/transform/UnCurry.scala +++ b/src/compiler/scala/tools/nsc/transform/UnCurry.scala @@ -77,9 +77,17 @@ abstract class UnCurry extends InfoTransform private var inConstructorFlag = 0L private val byNameArgs = mutable.HashSet[Tree]() private val noApply = mutable.HashSet[Tree]() - private val newMembers = mutable.ArrayBuffer[Tree]() + private val newMembers = mutable.Map[Symbol, mutable.Buffer[Tree]]() private val repeatedParams = mutable.Map[Symbol, List[ValDef]]() + /** Add a new synthetic member for `currentOwner` */ + private def addNewMember(t: Tree): Unit = + newMembers.getOrElseUpdate(currentOwner, mutable.Buffer()) += t + + /** Process synthetic members for `owner`. They are removed form the `newMembers` as a side-effect. */ + @inline private def useNewMembers[T](owner: Symbol)(f: List[Tree] => T): T = + f(newMembers.remove(owner).getOrElse(Nil).toList) + @inline private def withInPattern[T](value: Boolean)(body: => T): T = { inPattern = value try body @@ -573,7 +581,7 @@ abstract class UnCurry extends InfoTransform val vparamssNoRhs = dd.vparamss mapConserve (_ mapConserve {p => treeCopy.ValDef(p, p.mods, p.name, p.tpt, EmptyTree) }) - + if (dd.symbol hasAnnotation VarargsClass) saveRepeatedParams(dd) withNeedLift(false) { @@ -680,9 +688,8 @@ abstract class UnCurry extends InfoTransform tree match { /* Some uncurry post transformations add members to templates. - * When inside a template, the following sequence is available: - * - newMembers - * Any entry in this sequence will be added into the template + * + * Members registered by `addMembers` for the current template are added * once the template transformation has finished. * * In particular, this case will add: @@ -690,8 +697,10 @@ abstract class UnCurry extends InfoTransform */ case Template(_, _, _) => localTyper = typer.atOwner(tree, currentClass) - try deriveTemplate(tree)(transformTrees(newMembers.toList) ::: _) - finally newMembers.clear() + useNewMembers(currentClass) { + newMembers => + deriveTemplate(tree)(transformTrees(newMembers) ::: _) + } case dd @ DefDef(_, _, _, vparamss0, _, rhs0) => val flatdd = copyDefDef(dd)( @@ -763,7 +772,7 @@ abstract class UnCurry extends InfoTransform /* Called during post transform, after the method argument lists have been flattened. * It looks for the method in the `repeatedParams` map, and generates a Java-style - * varargs forwarder. It then adds the forwarder to the `newMembers` sequence. + * varargs forwarder. */ private def addJavaVarargsForwarders(dd: DefDef, flatdd: DefDef): DefDef = { if (!dd.symbol.hasAnnotation(VarargsClass) || !repeatedParams.contains(dd.symbol)) @@ -840,8 +849,7 @@ abstract class UnCurry extends InfoTransform case None => // enter symbol into scope currentClass.info.decls enter forwsym - // add the method to `newMembers` - newMembers += forwtree + addNewMember(forwtree) } flatdd diff --git a/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala b/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala index cb01faf619..eb3a1ffb5b 100644 --- a/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala +++ b/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala @@ -874,8 +874,12 @@ 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" + " %s package object %s".format(inOrOut, ""+prevSym.effectiveOwner.name) + } else "" - issueSymbolTypeError(currentSym, prevSym.name + " is already defined as " + s2 + s3) + issueSymbolTypeError(currentSym, prevSym.name + " is already defined as " + s2 + s3 + where) } def MaxParametersCaseClassError(tree: Tree) = diff --git a/src/compiler/scala/tools/nsc/typechecker/Contexts.scala b/src/compiler/scala/tools/nsc/typechecker/Contexts.scala index 0924789948..f4f081252f 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Contexts.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Contexts.scala @@ -438,8 +438,8 @@ trait Contexts { self: Analyzer => def enclosingContextChain: List[Context] = this :: outer.enclosingContextChain - override def toString = "Context(%s@%s unit=%s scope=%s errors=%b)".format( - owner.fullName, tree.shortClass, unit, scope.##, hasErrors + override def toString = "Context(%s@%s unit=%s scope=%s errors=%b, reportErrors=%b, throwErrors=%b)".format( + owner.fullName, tree.shortClass, unit, scope.##, hasErrors, reportErrors, throwErrors ) /** Is `sub` a subclass of `base` or a companion object of such a subclass? */ @@ -598,16 +598,16 @@ trait Contexts { self: Analyzer => * it is accessible, and if it is imported there is not already a local symbol * with the same names. Local symbols override imported ones. This fixes #2866. */ - private def isQualifyingImplicit(sym: Symbol, pre: Type, imported: Boolean) = + private def isQualifyingImplicit(name: Name, sym: Symbol, pre: Type, imported: Boolean) = sym.isImplicit && isAccessible(sym, pre) && !(imported && { - val e = scope.lookupEntry(sym.name) + val e = scope.lookupEntry(name) (e ne null) && (e.owner == scope) }) private def collectImplicits(syms: List[Symbol], pre: Type, imported: Boolean = false): List[ImplicitInfo] = - for (sym <- syms if isQualifyingImplicit(sym, pre, imported)) yield + for (sym <- syms if isQualifyingImplicit(sym.name, sym, pre, imported)) yield new ImplicitInfo(sym.name, pre, sym) private def collectImplicitImports(imp: ImportInfo): List[ImplicitInfo] = { @@ -621,7 +621,7 @@ trait Contexts { self: Analyzer => var impls = collect(sels1) filter (info => info.name != from) if (to != nme.WILDCARD) { for (sym <- imp.importedSymbol(to).alternatives) - if (isQualifyingImplicit(sym, pre, imported = true)) + if (isQualifyingImplicit(to, sym, pre, imported = true)) impls = new ImplicitInfo(to, pre, sym) :: impls } impls diff --git a/src/compiler/scala/tools/nsc/typechecker/Duplicators.scala b/src/compiler/scala/tools/nsc/typechecker/Duplicators.scala index 2574a1d241..b7a6ea677e 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Duplicators.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Duplicators.scala @@ -143,8 +143,8 @@ abstract class Duplicators extends Analyzer { else sym - private def invalidate(tree: Tree) { - debuglog("attempting to invalidate " + tree.symbol + ", owner - " + (if (tree.symbol ne null) tree.symbol.owner else "<NULL>")) + private def invalidate(tree: Tree, owner: Symbol = NoSymbol) { + debuglog("attempting to invalidate " + tree.symbol) if (tree.isDef && tree.symbol != NoSymbol) { debuglog("invalid " + tree.symbol) invalidSyms(tree.symbol) = tree @@ -158,18 +158,20 @@ abstract class Duplicators extends Analyzer { newsym.setInfo(fixType(ldef.symbol.info)) ldef.symbol = newsym debuglog("newsym: " + newsym + " info: " + newsym.info) - + case vdef @ ValDef(mods, name, _, rhs) if mods.hasFlag(Flags.LAZY) => debuglog("ValDef " + name + " sym.info: " + vdef.symbol.info) invalidSyms(vdef.symbol) = vdef - val newsym = vdef.symbol.cloneSymbol(context.owner) + val newowner = if (owner != NoSymbol) owner else context.owner + val newsym = vdef.symbol.cloneSymbol(newowner) newsym.setInfo(fixType(vdef.symbol.info)) vdef.symbol = newsym - debuglog("newsym: " + newsym + " info: " + newsym.info) - + debuglog("newsym: " + newsym + " info: " + newsym.info + ", owner: " + newsym.owner + ", " + newsym.owner.isClass) + if (newsym.owner.isClass) newsym.owner.info.decls enter newsym + case DefDef(_, name, tparams, vparamss, _, rhs) => // invalidate parameters - invalidate(tparams ::: vparamss.flatten) + invalidateAll(tparams ::: vparamss.flatten) tree.symbol = NoSymbol case _ => @@ -178,14 +180,14 @@ abstract class Duplicators extends Analyzer { } } - private def invalidate(stats: List[Tree]) { - stats foreach invalidate + private def invalidateAll(stats: List[Tree], owner: Symbol = NoSymbol) { + stats.foreach(invalidate(_, owner)) } def retypedMethod(ddef: DefDef, oldThis: Symbol, newThis: Symbol): Tree = { oldClassOwner = oldThis newClassOwner = newThis - invalidate(ddef.tparams) + invalidateAll(ddef.tparams) mforeach(ddef.vparamss) { vdef => invalidate(vdef) vdef.tpe = null @@ -239,15 +241,15 @@ abstract class Duplicators extends Analyzer { case Block(stats, res) => debuglog("invalidating block") - invalidate(stats) + invalidateAll(stats) invalidate(res) tree.tpe = null super.typed(tree, mode, pt) case ClassDef(_, _, _, tmpl @ Template(parents, _, stats)) => - // log("invalidating classdef " + tree.tpe) + // log("invalidating classdef " + tree) tmpl.symbol = tree.symbol.newLocalDummy(tree.pos) - invalidate(stats) + invalidateAll(stats, tree.symbol) tree.tpe = null super.typed(tree, mode, pt) diff --git a/src/compiler/scala/tools/nsc/typechecker/Implicits.scala b/src/compiler/scala/tools/nsc/typechecker/Implicits.scala index 9d33f3d828..a671b8d6b5 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Implicits.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Implicits.scala @@ -554,7 +554,11 @@ trait Implicits { val itree = atPos(pos.focus) { if (info.pre == NoPrefix) Ident(info.name) - else Select(gen.mkAttributedQualifier(info.pre), info.name) + else { + // SI-2405 Not info.name, which might be an aliased import + val implicitMemberName = info.sym.name + Select(gen.mkAttributedQualifier(info.pre), implicitMemberName) + } } printTyping("typedImplicit1 %s, pt=%s, from implicit %s:%s".format( typeDebug.ptTree(itree), wildPt, info.name, info.tpe) diff --git a/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala b/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala index 88e464a1f4..d1f319311e 100644 --- a/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala +++ b/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala @@ -482,6 +482,10 @@ trait NamesDefaults { self: Analyzer => try typer.silent { tpr => val res = tpr.typed(arg, subst(paramtpe)) // better warning for SI-5044: if `silent` was not actually silent give a hint to the user + // [H]: the reason why `silent` is not silent is because the cyclic reference exception is + // thrown in a context completely different from `context` here. The exception happens while + // completing the type, and TypeCompleter is created/run with a non-silent Namer `context` + // and there is at the moment no way to connect the two unless we go through some global state. if (errsBefore < reporter.ERROR.count) WarnAfterNonSilentRecursiveInference(param, arg)(context) res diff --git a/src/compiler/scala/tools/nsc/typechecker/PatternMatching.scala b/src/compiler/scala/tools/nsc/typechecker/PatternMatching.scala index 61e02edaff..c48c81ea7a 100644 --- a/src/compiler/scala/tools/nsc/typechecker/PatternMatching.scala +++ b/src/compiler/scala/tools/nsc/typechecker/PatternMatching.scala @@ -1646,7 +1646,7 @@ trait PatternMatching extends Transform with TypingTransformers with ast.TreeDSL // TODO: if patterns allow switch but the type of the scrutinee doesn't, cast (type-test) the scrutinee to the corresponding switchable type and switch on the result if (regularSwitchMaker.switchableTpe(scrutSym.tpe)) { val caseDefsWithDefault = regularSwitchMaker(cases map {c => (scrutSym, c)}, pt) - if (caseDefsWithDefault.length <= 2) None // not worth emitting a switch... also, the optimizer has trouble digesting tiny switches, apparently, so let's be nice and not generate them + if (caseDefsWithDefault isEmpty) None // not worth emitting a switch. else { // match on scrutSym -- converted to an int if necessary -- not on scrut directly (to avoid duplicating scrut) val scrutToInt: Tree = diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala index e40a567f1d..b1698ccb36 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala @@ -2510,10 +2510,7 @@ trait Typers extends Modes with Adaptations with Taggings { namer.enterSyms(stats) // need to delay rest of typedRefinement to avoid cyclic reference errors unit.toCheck += { () => - // go to next outer context which is not silent, see #3614 - var c = context - while (c.bufferErrors) c = c.outer - val stats1 = newTyper(c).typedStats(stats, NoSymbol) + val stats1 = typedStats(stats, NoSymbol) for (stat <- stats1 if stat.isDef) { val member = stat.symbol if (!(context.owner.ancestors forall diff --git a/src/library/scala/collection/mutable/FlatHashTable.scala b/src/library/scala/collection/mutable/FlatHashTable.scala index ee6d4d1d22..4070174902 100644 --- a/src/library/scala/collection/mutable/FlatHashTable.scala +++ b/src/library/scala/collection/mutable/FlatHashTable.scala @@ -50,6 +50,10 @@ trait FlatHashTable[A] extends FlatHashTable.HashUtils[A] { protected def capacity(expectedSize: Int) = if (expectedSize == 0) 1 else powerOfTwo(expectedSize) + /** The initial size of the hash table. + */ + def initialSize: Int = 32 + private def initialCapacity = capacity(initialSize) protected def randomSeed = seedGenerator.get.nextInt() @@ -361,10 +365,6 @@ private[collection] object FlatHashTable { def defaultLoadFactor: Int = 450 final def loadFactorDenum = 1000 - /** The initial size of the hash table. - */ - def initialSize: Int = 32 - def sizeForThreshold(size: Int, _loadFactor: Int) = math.max(32, (size.toLong * loadFactorDenum / _loadFactor).toInt) def newThreshold(_loadFactor: Int, size: Int) = { diff --git a/src/library/scala/collection/mutable/HashTable.scala b/src/library/scala/collection/mutable/HashTable.scala index a2f78dbde9..c307e6dcab 100644 --- a/src/library/scala/collection/mutable/HashTable.scala +++ b/src/library/scala/collection/mutable/HashTable.scala @@ -56,7 +56,15 @@ trait HashTable[A, Entry >: Null <: HashEntry[A, Entry]] extends HashTable.HashU protected def tableSizeSeed = Integer.bitCount(table.length - 1) - protected def initialSize: Int = HashTable.initialSize + /** The initial size of the hash table. + */ + protected def initialSize: Int = 16 + + /** The initial threshold. + */ + private def initialThreshold(_loadFactor: Int): Int = newThreshold(_loadFactor, initialCapacity) + + private def initialCapacity = capacity(initialSize) private def lastPopulatedIndex = { var idx = table.length - 1 @@ -354,16 +362,6 @@ private[collection] object HashTable { private[collection] final def defaultLoadFactor: Int = 750 // corresponds to 75% private[collection] final def loadFactorDenum = 1000; - /** The initial size of the hash table. - */ - private[collection] final def initialSize: Int = 16 - - /** The initial threshold. - */ - private[collection] final def initialThreshold(_loadFactor: Int): Int = newThreshold(_loadFactor, initialCapacity) - - private[collection] final def initialCapacity = capacity(initialSize) - private[collection] final def newThreshold(_loadFactor: Int, size: Int) = ((size.toLong * _loadFactor) / loadFactorDenum).toInt private[collection] final def sizeForThreshold(_loadFactor: Int, thr: Int) = ((thr.toLong * loadFactorDenum) / _loadFactor).toInt diff --git a/test/files/neg/t2405.check b/test/files/neg/t2405.check new file mode 100644 index 0000000000..78360bcc21 --- /dev/null +++ b/test/files/neg/t2405.check @@ -0,0 +1,8 @@ +t2405.scala:6: warning: imported `y' is permanently hidden by definition of method y + import A.{x => y} + ^ +t2405.scala:8: error: could not find implicit value for parameter e: Int + implicitly[Int] + ^ +one warning found +one error found diff --git a/test/files/neg/t2405.scala b/test/files/neg/t2405.scala new file mode 100644 index 0000000000..6982285b98 --- /dev/null +++ b/test/files/neg/t2405.scala @@ -0,0 +1,10 @@ +object A { implicit val x: Int = 1 } + +// Expecting shadowing #1 +object Test2 { + { + import A.{x => y} + def y: Int = 0 + implicitly[Int] + } +} diff --git a/test/files/neg/t3614.check b/test/files/neg/t3614.check new file mode 100644 index 0000000000..5fdb5cbf1f --- /dev/null +++ b/test/files/neg/t3614.check @@ -0,0 +1,4 @@ +t3614.scala:2: error: class type required but AnyRef{def a: <?>} found + def v = new ({ def a=0 }) + ^ +one error found
\ No newline at end of file diff --git a/test/files/neg/t3614.scala b/test/files/neg/t3614.scala new file mode 100644 index 0000000000..5b02cdf2b2 --- /dev/null +++ b/test/files/neg/t3614.scala @@ -0,0 +1,3 @@ +object t3614 { + def v = new ({ def a=0 }) +}
\ No newline at end of file diff --git a/test/files/neg/t5760-pkgobj-warn.check b/test/files/neg/t5760-pkgobj-warn.check new file mode 100644 index 0000000000..a89398c3f7 --- /dev/null +++ b/test/files/neg/t5760-pkgobj-warn.check @@ -0,0 +1,4 @@ +stalepkg_2.scala:6: error: Foo is already defined as class Foo in package object stalepkg + class Foo + ^ +one error found diff --git a/test/files/neg/t5760-pkgobj-warn/stalepkg_1.scala b/test/files/neg/t5760-pkgobj-warn/stalepkg_1.scala new file mode 100644 index 0000000000..ed4b731bb0 --- /dev/null +++ b/test/files/neg/t5760-pkgobj-warn/stalepkg_1.scala @@ -0,0 +1,11 @@ + +package object stalepkg { + class Foo +} + +package stalepkg { + object Test { + def main(args: Array[String]) { + } + } +} diff --git a/test/files/neg/t5760-pkgobj-warn/stalepkg_2.scala b/test/files/neg/t5760-pkgobj-warn/stalepkg_2.scala new file mode 100644 index 0000000000..9abcdbab17 --- /dev/null +++ b/test/files/neg/t5760-pkgobj-warn/stalepkg_2.scala @@ -0,0 +1,11 @@ + +package object stalepkg { +} + +package stalepkg { + class Foo + object Test { + def main(args: Array[String]) { + } + } +} diff --git a/test/files/pos/t2405.scala b/test/files/pos/t2405.scala new file mode 100644 index 0000000000..224b2ce83b --- /dev/null +++ b/test/files/pos/t2405.scala @@ -0,0 +1,23 @@ +object A { implicit val x: Int = 1 } + +// Problem as stated in the ticket. +object Test1 { + import A.{x => y} + implicitly[Int] +} + +// Testing for the absense of shadowing #1. +object Test2 { + import A.{x => y} + val x = 2 + implicitly[Int] +} + +// Testing for the absense of shadowing #2. +object Test3 { + { + import A.{x => y} + def x: Int = 0 + implicitly[Int] + } +} diff --git a/test/files/pos/t3856.scala b/test/files/pos/t3856.scala index fd253a56a8..5ea4b84e2c 100644 --- a/test/files/pos/t3856.scala +++ b/test/files/pos/t3856.scala @@ -2,6 +2,7 @@ case class C[T](x: T) case class CS(xs: C[_]*) +// t3856 object Test { val x = CS(C(5), C("abc")) match { case CS(C(5), xs @ _*) => xs } println(x) diff --git a/test/files/pos/t3880.scala b/test/files/pos/t3880.scala new file mode 100644 index 0000000000..b6f06c43a3 --- /dev/null +++ b/test/files/pos/t3880.scala @@ -0,0 +1,16 @@ +abstract class Bar[+B] { +} +abstract class C1[+B] extends Bar[B] { + private[this] def g(x: C1[B]): Unit = () + + // this method is fine: notice that it allows the call to g, + // which requires C1[B], even though we matched on C1[_]. + // (That is good news.) + private[this] def f1(x: Bar[B]): Unit = x match { + case x: C1[_] => g(x) + } + // this one crashes. + private[this] def f2(x: Bar[B]): Unit = x match { + case x: C1[_] => f2(x) + } +}
\ No newline at end of file diff --git a/test/files/pos/t4717.scala b/test/files/pos/t4717.scala new file mode 100644 index 0000000000..4acfe489cc --- /dev/null +++ b/test/files/pos/t4717.scala @@ -0,0 +1,35 @@ + + + + + + + +trait Bug1[@specialized(Boolean) A] extends TraversableOnce[A] { + + def ++[B >: A](that: TraversableOnce[B]): Iterator[B] = new Iterator[B] { + lazy val it = that.toIterator + def hasNext = it.hasNext + def next = it.next + } + +} + + + +trait WorksFine[@specialized(Boolean) A] { + class SubBounds[B >: A] extends Bounds[B] { + lazy val it = ??? + } + def x[B >: A]: Unit = new SubBounds[B] +} + + +trait Bounds[@specialized(Boolean) A] { + // okay without `>: A` + def x[B >: A]: Unit = new Bounds[B] { + lazy val it = ??? // def or val okay + } +} + + diff --git a/test/files/pos/t5305.scala b/test/files/pos/t5305.scala new file mode 100644 index 0000000000..4c32cd7c6d --- /dev/null +++ b/test/files/pos/t5305.scala @@ -0,0 +1,13 @@ +object t5305 { + def in(a: Any) = {} + + object O { + type F = Int + val v = "" + } + + in { + import O.{F, v} + type x = {type l = (F, v.type)} // not found: type F + } +} diff --git a/test/files/run/inline-ex-handlers.check b/test/files/run/inline-ex-handlers.check index a5d7e93334..708fcc6985 100644 --- a/test/files/run/inline-ex-handlers.check +++ b/test/files/run/inline-ex-handlers.check @@ -1,27 +1,23 @@ 172c172 -< locals: value x$1, value x1, value x2, value x +< locals: value x$1, value x1 --- -> locals: value x$1, value x1, value x2, value x, variable boxed1 +> locals: value x$1, value x1, variable boxed1 174c174 -< blocks: [1,2,3,5,6,7] +< blocks: [1,2,3,4] --- -> blocks: [1,3,5,6] -180,182d179 +> blocks: [1,3,4] +186a187,188 +> 92 STORE_LOCAL(variable boxed1) +> 92 LOAD_LOCAL(variable boxed1) +195,197d196 < 92 JUMP 2 < < 2: -194,196d190 -< 92 JUMP 7 -< -< 7: -204a199,200 -> 92 STORE_LOCAL(variable boxed1) -> 92 LOAD_LOCAL(variable boxed1) -395c391 +385c384 < blocks: [1,2,3,4,5,8,11,13,14,16] --- > blocks: [1,2,3,5,8,11,13,14,16,17] -419c415,424 +409c408,417 < 103 THROW(MyException) --- > ? STORE_LOCAL(value ex5) @@ -34,15 +30,15 @@ > 106 LOAD_LOCAL(value x3) > 106 IS_INSTANCE REF(class MyException) > 106 CZJUMP (BOOL)NE ? 5 : 11 -432,434d436 +422,424d429 < 101 JUMP 4 < < 4: -522c524 +512c517 < blocks: [1,2,3,4,6,7,8,9,10] --- > blocks: [1,2,3,4,6,7,8,9,10,11,12,13] -551c553,558 +541c546,551 < 306 THROW(MyException) --- > ? JUMP 11 @@ -51,7 +47,7 @@ > ? LOAD_LOCAL(variable monitor4) > 305 MONITOR_EXIT > ? JUMP 12 -557c564,570 +547c557,563 < ? THROW(Throwable) --- > ? JUMP 12 @@ -61,7 +57,7 @@ > 304 MONITOR_EXIT > ? STORE_LOCAL(value t) > ? JUMP 13 -563c576,589 +553c569,582 < ? THROW(Throwable) --- > ? STORE_LOCAL(value t) @@ -78,30 +74,29 @@ > 310 CALL_PRIMITIVE(EndConcat) > 310 CALL_METHOD scala.Predef.println (dynamic) > 310 JUMP 2 -587c613 +577c606 < catch (Throwable) in ArrayBuffer(7, 8, 9, 10) starting at: 6 --- > catch (Throwable) in ArrayBuffer(7, 8, 9, 10, 11) starting at: 6 -590c616 +580c609 < catch (Throwable) in ArrayBuffer(4, 6, 7, 8, 9, 10) starting at: 3 --- > catch (Throwable) in ArrayBuffer(4, 6, 7, 8, 9, 10, 11, 12) starting at: 3 -622c648 +612c641 < blocks: [1,2,3,4,5,6,7,9,10] --- > blocks: [1,2,3,4,5,6,7,9,10,11,12] -646c672,673 +636c665,671 < 78 THROW(IllegalArgumentException) --- > ? STORE_LOCAL(value e) > ? JUMP 11 -647a675,679 +> > 11: > 81 LOAD_LOCAL(value e) > ? STORE_LOCAL(variable exc1) > ? JUMP 12 -> -675c707,721 +665c700,714 < 81 THROW(Exception) --- > ? STORE_LOCAL(variable exc1) @@ -119,15 +114,15 @@ > 84 STORE_LOCAL(variable result) > 84 LOAD_LOCAL(variable exc1) > 84 THROW(Throwable) -697c743 +687c736 < catch (<none>) in ArrayBuffer(4, 6, 7, 9) starting at: 3 --- > catch (<none>) in ArrayBuffer(4, 6, 7, 9, 11) starting at: 3 -723c769 +713c762 < blocks: [1,2,3,4,5,6,9,12,14,17,18,19,22,25,27,28,30,31] --- > blocks: [1,2,3,4,5,6,9,12,14,17,18,19,22,25,27,28,30,31,32,33,34] -747c793,800 +737c786,793 < 172 THROW(MyException) --- > ? STORE_LOCAL(value ex5) @@ -138,12 +133,12 @@ > 170 STORE_LOCAL(value x3) > 170 SCOPE_ENTER value x3 > 170 JUMP 18 -803c856,857 +793c849,850 < 177 THROW(MyException) --- > ? STORE_LOCAL(value ex5) > ? JUMP 33 -807c861,868 +797c854,861 < 170 THROW(Throwable) --- > ? STORE_LOCAL(value ex5) @@ -154,17 +149,17 @@ > 169 STORE_LOCAL(value x3) > 169 SCOPE_ENTER value x3 > 169 JUMP 5 -840c901,902 +830c894,895 < 182 THROW(MyException) --- > ? STORE_LOCAL(variable exc2) > ? JUMP 34 -844c906,907 +834c899,900 < 169 THROW(Throwable) --- > ? STORE_LOCAL(variable exc2) > ? JUMP 34 -845a909,921 +835a902,914 > 34: > 184 LOAD_MODULE object Predef > 184 CONSTANT("finally") @@ -178,19 +173,19 @@ > 185 LOAD_LOCAL(variable exc2) > 185 THROW(Throwable) > -866c942 +856c935 < catch (Throwable) in ArrayBuffer(17, 18, 19, 22, 25, 27, 28, 30) starting at: 4 --- > catch (Throwable) in ArrayBuffer(17, 18, 19, 22, 25, 27, 28, 30, 32) starting at: 4 -869c945 +859c938 < catch (<none>) in ArrayBuffer(4, 5, 6, 9, 12, 17, 18, 19, 22, 25, 27, 28, 30) starting at: 3 --- > catch (<none>) in ArrayBuffer(4, 5, 6, 9, 12, 17, 18, 19, 22, 25, 27, 28, 30, 32, 33) starting at: 3 -895c971 +885c964 < blocks: [1,2,3,6,7,8,11,14,16,17,19] --- > blocks: [1,2,3,6,7,8,11,14,16,17,19,20] -919c995,1002 +909c988,995 < 124 THROW(MyException) --- > ? STORE_LOCAL(value ex5) @@ -201,15 +196,15 @@ > 122 STORE_LOCAL(value x3) > 122 SCOPE_ENTER value x3 > 122 JUMP 7 -979c1062 +969c1055 < catch (IllegalArgumentException) in ArrayBuffer(6, 7, 8, 11, 14, 16, 17, 19) starting at: 3 --- > catch (IllegalArgumentException) in ArrayBuffer(6, 7, 8, 11, 14, 16, 17, 19, 20) starting at: 3 -1005c1088 +995c1081 < blocks: [1,2,3,4,5,8,11,15,16,17,19] --- > blocks: [1,2,3,5,8,11,15,16,17,19,20] -1029c1112,1121 +1019c1105,1114 < 148 THROW(MyException) --- > ? STORE_LOCAL(value ex5) @@ -222,15 +217,15 @@ > 154 LOAD_LOCAL(value x3) > 154 IS_INSTANCE REF(class MyException) > 154 CZJUMP (BOOL)NE ? 5 : 11 -1050,1052d1141 +1040,1042d1134 < 145 JUMP 4 < < 4: -1285c1374 +1275c1367 < blocks: [1,2,3,4,5,7] --- > blocks: [1,2,3,4,5,7,8] -1309c1398,1405 +1299c1391,1398 < 38 THROW(IllegalArgumentException) --- > ? STORE_LOCAL(value e) @@ -241,16 +236,16 @@ > 42 CONSTANT("IllegalArgumentException") > 42 CALL_METHOD scala.Predef.println (dynamic) > 42 JUMP 2 -1358c1454 +1348c1447 < blocks: [1,2,3,4,5,8,11,13,14,16,17,19] --- > blocks: [1,2,3,5,8,11,13,14,16,17,19,20] -1382c1478,1479 +1372c1471,1472 < 203 THROW(MyException) --- > ? STORE_LOCAL(value ex5) > ? JUMP 20 -1402c1499,1508 +1392c1492,1501 < 209 THROW(MyException) --- > ? STORE_LOCAL(value ex5) @@ -263,15 +258,15 @@ > 212 LOAD_LOCAL(value x3) > 212 IS_INSTANCE REF(class MyException) > 212 CZJUMP (BOOL)NE ? 5 : 11 -1415,1417d1520 +1405,1407d1513 < 200 JUMP 4 < < 4: -1477c1580 +1467c1573 < blocks: [1,2,3,4,5,7] --- > blocks: [1,2,3,4,5,7,8] -1501c1604,1611 +1491c1597,1604 < 58 THROW(IllegalArgumentException) --- > ? STORE_LOCAL(value e) @@ -282,11 +277,11 @@ > 62 CONSTANT("RuntimeException") > 62 CALL_METHOD scala.Predef.println (dynamic) > 62 JUMP 2 -1550c1660 +1540c1653 < blocks: [1,2,3,4] --- > blocks: [1,2,3,4,5] -1570c1680,1685 +1560c1673,1678 < 229 THROW(MyException) --- > ? JUMP 5 @@ -295,19 +290,19 @@ > ? LOAD_LOCAL(variable monitor1) > 228 MONITOR_EXIT > 228 THROW(Throwable) -1576c1691 +1566c1684 < ? THROW(Throwable) --- > 228 THROW(Throwable) -1604c1719 +1594c1712 < locals: value args, variable result, variable monitor2, variable monitorResult1 --- > locals: value exception$1, value args, variable result, variable monitor2, variable monitorResult1 -1606c1721 +1596c1714 < blocks: [1,2,3,4] --- > blocks: [1,2,3,4,5] -1629c1744,1752 +1619c1737,1745 < 245 THROW(MyException) --- > ? STORE_LOCAL(value exception$1) @@ -319,7 +314,7 @@ > ? LOAD_LOCAL(variable monitor2) > 244 MONITOR_EXIT > 244 THROW(Throwable) -1635c1758 +1625c1751 < ? THROW(Throwable) --- > 244 THROW(Throwable) diff --git a/test/files/run/t5125.check b/test/files/run/t5125.check new file mode 100644 index 0000000000..d8a0565005 --- /dev/null +++ b/test/files/run/t5125.check @@ -0,0 +1,4 @@ +public void O1$.f(java.lang.String[]) +public void O1$.f(scala.collection.Seq) +public void O2$.f(java.lang.String[]) +public void O2$.f(scala.collection.Seq) diff --git a/test/files/run/t5125.scala b/test/files/run/t5125.scala new file mode 100644 index 0000000000..7ec2b929d9 --- /dev/null +++ b/test/files/run/t5125.scala @@ -0,0 +1,24 @@ +object O1 { + def instance = this + @scala.annotation.varargs + def f(values:String*) = println("Calling O1.f(): " + values) +} + +object O2 { + def instance = this + @scala.annotation.varargs + def f(values:String*) = println("Calling O2.f(): " + values) + // uncommenting g() results in errors in A.java + def g(): String => Int = s => s.hashCode +} + +object Test extends App { + def check(c: Class[_]) { + val methodName = "f" + val methods = c.getDeclaredMethods.filter(_.getName == methodName) + println(methods.map(_.toString).sorted.mkString("\n")) + } + + check(O1.getClass) + check(O2.getClass) +}
\ No newline at end of file diff --git a/test/files/run/t5125b.check b/test/files/run/t5125b.check new file mode 100644 index 0000000000..ddbf908f04 --- /dev/null +++ b/test/files/run/t5125b.check @@ -0,0 +1,7 @@ +public void C1.f(java.lang.String[]) +public void C1.f(scala.collection.Seq) +public void C2.f(java.lang.String[]) +public void C2.f(scala.collection.Seq) +public void C2$C3.f(java.lang.String[]) +public void C2$C3.f(scala.collection.Seq) +public void C4.f(scala.collection.Seq) diff --git a/test/files/run/t5125b.scala b/test/files/run/t5125b.scala new file mode 100644 index 0000000000..29c08fee4c --- /dev/null +++ b/test/files/run/t5125b.scala @@ -0,0 +1,37 @@ +class C1 { + @scala.annotation.varargs + def f(values:String*) = println("Calling C1.f(): " + values) +} + +class C2 { + @scala.annotation.varargs + def f(values:String*) = println("Calling C2.f(): " + values) + def g(): String => Int = s => s.hashCode + + class C3 { + @scala.annotation.varargs + def f(values:String*) = println("Calling C3.f(): " + values) + } +} + +class C4 { + def f(values: String*) = println("Calling C4.f(): " + values) + + locally { + @scala.annotation.varargs + def f(values: String*) = println("Calling C4.<locally>.f(): " + values) + } +} + +object Test extends App { + def check(c: Class[_]) { + val methodName = "f" + val methods = c.getDeclaredMethods.filter(_.getName == methodName) + println(methods.map(_.toString).sorted.mkString("\n")) + } + + check(classOf[C1]) + check(classOf[C2]) + check(classOf[C2#C3]) + check(classOf[C4]) +} diff --git a/test/files/run/t5804.check b/test/files/run/t5804.check new file mode 100644 index 0000000000..3ccc1c24d3 --- /dev/null +++ b/test/files/run/t5804.check @@ -0,0 +1,4 @@ +128 +16 +128 +32
\ No newline at end of file diff --git a/test/files/run/t5804.scala b/test/files/run/t5804.scala new file mode 100644 index 0000000000..b96a736035 --- /dev/null +++ b/test/files/run/t5804.scala @@ -0,0 +1,32 @@ + + +import collection.mutable._ + + +object Test { + + def main(args: Array[String]) { + class CustomHashMap extends HashMap[Int, Int] { + override def initialSize = 65 + + println(table.length) + } + + new CustomHashMap + new HashMap { + println(table.length) + } + + class CustomHashSet extends HashSet[Int] { + override def initialSize = 96 + + println(table.length) + } + + new CustomHashSet + new HashSet { + println(table.length) + } + } + +} diff --git a/test/pending/run/t3899.check b/test/pending/run/t3899.check new file mode 100644 index 0000000000..c317608eab --- /dev/null +++ b/test/pending/run/t3899.check @@ -0,0 +1,4 @@ +a,b +a,b +a,b +a,b diff --git a/test/pending/run/t3899/Base_1.java b/test/pending/run/t3899/Base_1.java new file mode 100644 index 0000000000..114cc0b7a6 --- /dev/null +++ b/test/pending/run/t3899/Base_1.java @@ -0,0 +1,5 @@ +public class Base_1 { + public String[] varargs1(String... as) { + return as; + } +} diff --git a/test/pending/run/t3899/Derived_2.scala b/test/pending/run/t3899/Derived_2.scala new file mode 100644 index 0000000000..bb4e53784d --- /dev/null +++ b/test/pending/run/t3899/Derived_2.scala @@ -0,0 +1,30 @@ +trait T extends Base_1 { + def t1(as: String*): Array[String] = { + varargs1(as: _*) + } + def t2(as: String*): Array[String] = { + // This is the bug reported in the ticket. + super.varargs1(as: _*) + } +} + +class C extends Base_1 { + def c1(as: String*): Array[String] = { + varargs1(as: _*) + } + def c2(as: String*): Array[String] = { + super.varargs1(as: _*) + } +} + + +object Test extends App { + val t = new T {} + println(t.t1("a", "b").mkString(",")) + println(t.t2("a", "b").mkString(",")) + + val c = new C {} + println(c.c1("a", "b").mkString(",")) + println(c.c2("a", "b").mkString(",")) + +} |