diff options
29 files changed, 302 insertions, 131 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/reflect/internal/Definitions.scala b/src/compiler/scala/reflect/internal/Definitions.scala index 6e07e6b04b..0cdef9e79a 100644 --- a/src/compiler/scala/reflect/internal/Definitions.scala +++ b/src/compiler/scala/reflect/internal/Definitions.scala @@ -404,6 +404,7 @@ trait Definitions extends reflect.api.StandardDefinitions { lazy val JavaSerializableClass = requiredClass[java.io.Serializable] modifyInfo fixupAsAnyTrait lazy val ComparableClass = requiredClass[java.lang.Comparable[_]] modifyInfo fixupAsAnyTrait lazy val JavaCloneableClass = requiredClass[java.lang.Cloneable] + lazy val JavaNumberClass = requiredClass[java.lang.Number] lazy val RemoteInterfaceClass = requiredClass[java.rmi.Remote] lazy val RemoteExceptionClass = requiredClass[java.rmi.RemoteException] 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/typechecker/ContextErrors.scala b/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala index eb3a1ffb5b..affa9cd63b 100644 --- a/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala +++ b/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala @@ -690,34 +690,44 @@ trait ContextErrors { setError(tree) } - def NoBestMethodAlternativeError(tree: Tree, argtpes: List[Type], pt: Type) = { + // side-effect on the tree, break the overloaded type cycle in infer + @inline + private def setErrorOnLastTry(lastTry: Boolean, tree: Tree) = if (lastTry) setError(tree) + + def NoBestMethodAlternativeError(tree: Tree, argtpes: List[Type], pt: Type, lastTry: Boolean) = { issueNormalTypeError(tree, applyErrorMsg(tree, " cannot be applied to ", argtpes, pt)) // since inferMethodAlternative modifies the state of the tree // we have to set the type of tree to ErrorType only in the very last - // fallback action that is done in the inference (tracking it manually is error prone). + // fallback action that is done in the inference. // This avoids entering infinite loop in doTypeApply. - if (implicitly[Context].reportErrors) setError(tree) + setErrorOnLastTry(lastTry, tree) } def AmbiguousMethodAlternativeError(tree: Tree, pre: Type, best: Symbol, - firstCompeting: Symbol, argtpes: List[Type], pt: Type) = { - val msg0 = - "argument types " + argtpes.mkString("(", ",", ")") + - (if (pt == WildcardType) "" else " and expected result type " + pt) - val (pos, msg) = ambiguousErrorMsgPos(tree.pos, pre, best, firstCompeting, msg0) - // discover last attempt in a similar way as for NoBestMethodAlternativeError - if (implicitly[Context].ambiguousErrors) setError(tree) - issueAmbiguousTypeError(pre, best, firstCompeting, AmbiguousTypeError(tree, pos, msg)) + firstCompeting: Symbol, argtpes: List[Type], pt: Type, lastTry: Boolean) = { + + if (!(argtpes exists (_.isErroneous)) && !pt.isErroneous) { + val msg0 = + "argument types " + argtpes.mkString("(", ",", ")") + + (if (pt == WildcardType) "" else " and expected result type " + pt) + val (pos, msg) = ambiguousErrorMsgPos(tree.pos, pre, best, firstCompeting, msg0) + issueAmbiguousTypeError(pre, best, firstCompeting, AmbiguousTypeError(tree, pos, msg)) + setErrorOnLastTry(lastTry, tree) + } else setError(tree) // do not even try further attempts because they should all fail + // even if this is not the last attempt (because of the SO's possibility on the horizon) + } - def NoBestExprAlternativeError(tree: Tree, pt: Type) = + def NoBestExprAlternativeError(tree: Tree, pt: Type, lastTry: Boolean) = { issueNormalTypeError(tree, withAddendum(tree.pos)(typeErrorMsg(tree.symbol.tpe, pt, isPossiblyMissingArgs(tree.symbol.tpe, pt)))) + setErrorOnLastTry(lastTry, tree) + } - def AmbiguousExprAlternativeError(tree: Tree, pre: Type, best: Symbol, firstCompeting: Symbol, pt: Type) = { + def AmbiguousExprAlternativeError(tree: Tree, pre: Type, best: Symbol, firstCompeting: Symbol, pt: Type, lastTry: Boolean) = { val (pos, msg) = ambiguousErrorMsgPos(tree.pos, pre, best, firstCompeting, "expected type " + pt) - setError(tree) issueAmbiguousTypeError(pre, best, firstCompeting, AmbiguousTypeError(tree, pos, msg)) + setErrorOnLastTry(lastTry, tree) } // checkBounds 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/Implicits.scala b/src/compiler/scala/tools/nsc/typechecker/Implicits.scala index 8f025336bb..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) @@ -929,7 +933,7 @@ trait Implicits { } case None => if (pre.isStable) { - val companion = sym.companionModule + val companion = companionSymbolOf(sym, context) companion.moduleClass match { case mc: ModuleClassSymbol => val infos = diff --git a/src/compiler/scala/tools/nsc/typechecker/Infer.scala b/src/compiler/scala/tools/nsc/typechecker/Infer.scala index 1c1adee343..839cdee301 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Infer.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Infer.scala @@ -1449,10 +1449,10 @@ trait Infer { * If no alternative matches `pt`, take the parameterless one anyway. */ def inferExprAlternative(tree: Tree, pt: Type) = tree.tpe match { - case OverloadedType(pre, alts) => tryTwice { - val alts0 = alts filter (alt => isWeaklyCompatible(pre.memberType(alt), pt)) - val secondTry = alts0.isEmpty - val alts1 = if (secondTry) alts else alts0 + case OverloadedType(pre, alts) => tryTwice { isSecondTry => + val alts0 = alts filter (alt => isWeaklyCompatible(pre.memberType(alt), pt)) + val noAlternatives = alts0.isEmpty + val alts1 = if (noAlternatives) alts else alts0 //println("trying "+alts1+(alts1 map (_.tpe))+(alts1 map (_.locationString))+" for "+pt) def improves(sym1: Symbol, sym2: Symbol): Boolean = @@ -1480,10 +1480,10 @@ trait Infer { } } // todo: missing test case - NoBestExprAlternativeError(tree, pt) + NoBestExprAlternativeError(tree, pt, isSecondTry) } else if (!competing.isEmpty) { - if (secondTry) { NoBestExprAlternativeError(tree, pt); setError(tree) } - else if (!pt.isErroneous) AmbiguousExprAlternativeError(tree, pre, best, competing.head, pt) + if (noAlternatives) NoBestExprAlternativeError(tree, pt, isSecondTry) + else if (!pt.isErroneous) AmbiguousExprAlternativeError(tree, pre, best, competing.head, pt, isSecondTry) } else { // val applicable = alts1 filter (alt => // global.typer.infer.isWeaklyCompatible(pre.memberType(alt), pt)) @@ -1562,10 +1562,10 @@ trait Infer { * assignment expression. */ def inferMethodAlternative(tree: Tree, undetparams: List[Symbol], - argtpes: List[Type], pt0: Type, varArgsOnly: Boolean = false): Unit = tree.tpe match { + argtpes: List[Type], pt0: Type, varArgsOnly: Boolean = false, lastInferAttempt: Boolean = true): Unit = tree.tpe match { case OverloadedType(pre, alts) => val pt = if (pt0.typeSymbol == UnitClass) WildcardType else pt0 - tryTwice { + tryTwice { isSecondTry => debuglog("infer method alt "+ tree.symbol +" with alternatives "+ (alts map pre.memberType) +", argtpes = "+ argtpes +", pt = "+ pt) @@ -1587,13 +1587,10 @@ trait Infer { if (improves(alt, best)) alt else best) val competing = applicable.dropWhile(alt => best == alt || improves(best, alt)) if (best == NoSymbol) { - if (pt == WildcardType) NoBestMethodAlternativeError(tree, argtpes, pt) - else inferMethodAlternative(tree, undetparams, argtpes, WildcardType) + if (pt == WildcardType) NoBestMethodAlternativeError(tree, argtpes, pt, isSecondTry && lastInferAttempt) + else inferMethodAlternative(tree, undetparams, argtpes, WildcardType, lastInferAttempt = isSecondTry) } else if (!competing.isEmpty) { - if (!(argtpes exists (_.isErroneous)) && !pt.isErroneous) - AmbiguousMethodAlternativeError(tree, pre, best, competing.head, argtpes, pt) - else setError(tree) - () + AmbiguousMethodAlternativeError(tree, pre, best, competing.head, argtpes, pt, isSecondTry && lastInferAttempt) } else { // checkNotShadowed(tree.pos, pre, best, applicable) tree.setSymbol(best).setType(pre.memberType(best)) @@ -1607,29 +1604,28 @@ trait Infer { * * @param infer ... */ - def tryTwice(infer: => Unit): Unit = { + def tryTwice(infer: Boolean => Unit): Unit = { if (context.implicitsEnabled) { val saved = context.state var fallback = false context.setBufferErrors() - val res = try { - context.withImplicitsDisabled(infer) + try { + context.withImplicitsDisabled(infer(false)) if (context.hasErrors) { fallback = true context.restoreState(saved) context.flushBuffer() - infer + infer(true) } } catch { case ex: CyclicReference => throw ex case ex: TypeError => // recoverable cyclic references context.restoreState(saved) - if (!fallback) infer else () + if (!fallback) infer(true) else () } context.restoreState(saved) - res } - else infer + else infer(true) } /** Assign <code>tree</code> the type of all polymorphic alternatives 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 18529a061b..80d40011ad 100644 --- a/src/compiler/scala/tools/nsc/typechecker/PatternMatching.scala +++ b/src/compiler/scala/tools/nsc/typechecker/PatternMatching.scala @@ -2516,7 +2516,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/RefChecks.scala b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala index 4e578e3f0d..3373878beb 100644 --- a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala +++ b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala @@ -1084,8 +1084,16 @@ abstract class RefChecks extends InfoTransform with reflect.internal.transform.R def isEitherNullable = (NullClass.tpe <:< receiver.info) || (NullClass.tpe <:< actual.info) def isBoolean(s: Symbol) = unboxedValueClass(s) == BooleanClass def isUnit(s: Symbol) = unboxedValueClass(s) == UnitClass - def isNumeric(s: Symbol) = isNumericValueClass(unboxedValueClass(s)) || (s isSubClass ScalaNumberClass) - def isSpecial(s: Symbol) = isPrimitiveValueClass(unboxedValueClass(s)) || (s isSubClass ScalaNumberClass) || isMaybeValue(s) + def isNumeric(s: Symbol) = isNumericValueClass(unboxedValueClass(s)) || isAnyNumber(s) + def isScalaNumber(s: Symbol) = s isSubClass ScalaNumberClass + // test is behind a platform guard + def isJavaNumber(s: Symbol) = !forMSIL && (s isSubClass JavaNumberClass) + // includes java.lang.Number if appropriate [SI-5779] + def isAnyNumber(s: Symbol) = isScalaNumber(s) || isJavaNumber(s) + def isMaybeAnyValue(s: Symbol) = isPrimitiveValueClass(unboxedValueClass(s)) || isMaybeValue(s) + // used to short-circuit unrelatedTypes check if both sides are special + def isSpecial(s: Symbol) = isMaybeAnyValue(s) || isAnyNumber(s) + // unused def possibleNumericCount = onSyms(_ filter (x => isNumeric(x) || isMaybeValue(x)) size) val nullCount = onSyms(_ filter (_ == NullClass) size) @@ -1155,7 +1163,7 @@ abstract class RefChecks extends InfoTransform with reflect.internal.transform.R if (isCaseEquals) { def thisCase = receiver.info.member(nme.equals_).owner actual.info.baseClasses.find(_.isCase) match { - case Some(p) if (p != thisCase) => nonSensible("case class ", false) + case Some(p) if p != thisCase => nonSensible("case class ", false) case None => // stronger message on (Some(1) == None) //if (receiver.isCase && receiver.isEffectivelyFinal && !(receiver isSubClass actual)) nonSensiblyNeq() diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala index 2ad9cba935..349bd1912b 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/t5735.check b/test/files/neg/t5735.check new file mode 100644 index 0000000000..f6e0028044 --- /dev/null +++ b/test/files/neg/t5735.check @@ -0,0 +1,6 @@ +t5735.scala:6: error: type mismatch; + found : (x: Int)Int <and> => String + required: Int + val z: Int = a + ^ +one error found diff --git a/test/files/neg/t5735.scala b/test/files/neg/t5735.scala new file mode 100644 index 0000000000..fde71ff962 --- /dev/null +++ b/test/files/neg/t5735.scala @@ -0,0 +1,7 @@ +abstract class Base { + def a: String = "one" +} +class Clazz extends Base { + def a(x: Int): Int = 2 + val z: Int = a +} 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/t4975.scala b/test/files/pos/t4975.scala new file mode 100644 index 0000000000..12d889c0d5 --- /dev/null +++ b/test/files/pos/t4975.scala @@ -0,0 +1,12 @@ +object ImplicitScope { + class A[T] + + def foo { + trait B + object B { + implicit def ab = new A[B] + } + + implicitly[A[B]] // Error + } +} 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/pos/t5779-numeq-warn.scala b/test/files/pos/t5779-numeq-warn.scala new file mode 100644 index 0000000000..76ef2970fd --- /dev/null +++ b/test/files/pos/t5779-numeq-warn.scala @@ -0,0 +1,13 @@ + +object Test { + def main(args: Array[String]) { + val d: Double = (BigInt(1) << 64).toDouble + val f: Float = d.toFloat + val n: java.lang.Number = d.toFloat + assert (d == f) // ok + assert (d == n) // was: comparing values of types Double and Number using `==' will always yield false + assert (n == d) // was: Number and Double are unrelated: they will most likely never compare equal + assert (f == n) + assert (n == 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/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) + } + } + +} |