diff options
-rw-r--r-- | src/compiler/scala/tools/nsc/typechecker/Contexts.scala | 9 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/typechecker/TreeCheckers.scala | 3 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/typechecker/TypeDiagnostics.scala | 17 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/typechecker/Typers.scala | 6 | ||||
-rw-r--r-- | src/library/scala/collection/immutable/ListMap.scala | 8 | ||||
-rw-r--r-- | src/library/scala/runtime/BoxedUnit.java | 2 | ||||
-rw-r--r-- | src/partest/scala/tools/partest/nest/RunnerManager.scala | 2 | ||||
-rw-r--r-- | test/files/pos/t6225.scala | 20 | ||||
-rw-r--r-- | test/files/pos/t6514.scala | 11 | ||||
-rw-r--r-- | test/files/run/t6370.scala | 12 | ||||
-rw-r--r-- | test/files/run/t6935.scala | 14 |
11 files changed, 92 insertions, 12 deletions
diff --git a/src/compiler/scala/tools/nsc/typechecker/Contexts.scala b/src/compiler/scala/tools/nsc/typechecker/Contexts.scala index 620665126e..f2a2ef4d61 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Contexts.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Contexts.scala @@ -644,7 +644,14 @@ trait Contexts { self: Analyzer => new ImplicitInfo(sym.name, pre, sym) private def collectImplicitImports(imp: ImportInfo): List[ImplicitInfo] = { - val pre = imp.qual.tpe + val qual = imp.qual + + val pre = + if (qual.tpe.typeSymbol.isPackageClass) + // SI-6225 important if the imported symbol is inherited by the the package object. + singleType(qual.tpe, qual.tpe member nme.PACKAGE) + else + qual.tpe def collect(sels: List[ImportSelector]): List[ImplicitInfo] = sels match { case List() => List() diff --git a/src/compiler/scala/tools/nsc/typechecker/TreeCheckers.scala b/src/compiler/scala/tools/nsc/typechecker/TreeCheckers.scala index c5c3c560ea..88d10f1d72 100644 --- a/src/compiler/scala/tools/nsc/typechecker/TreeCheckers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/TreeCheckers.scala @@ -313,6 +313,9 @@ abstract class TreeCheckers extends Analyzer { } for { sym <- referencedSymbols + // Accessors are known to steal the type of the underlying field without cloning existential symbols at the new owner. + // This happens in Namer#accessorTypeCompleter. We just look the other way here. + if !tree.symbol.isAccessor 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(", ")}") } diff --git a/src/compiler/scala/tools/nsc/typechecker/TypeDiagnostics.scala b/src/compiler/scala/tools/nsc/typechecker/TypeDiagnostics.scala index 4233bde770..8c21479f73 100644 --- a/src/compiler/scala/tools/nsc/typechecker/TypeDiagnostics.scala +++ b/src/compiler/scala/tools/nsc/typechecker/TypeDiagnostics.scala @@ -427,17 +427,24 @@ trait TypeDiagnostics { contextWarning(pos, "imported `%s' is permanently hidden by definition of %s".format(hidden, defn.fullLocationString)) object checkDead { - private var expr: Symbol = NoSymbol + private val exprStack: mutable.Stack[Symbol] = mutable.Stack(NoSymbol) + // The method being applied to `tree` when `apply` is called. + private def expr = exprStack.top private def exprOK = (expr != Object_synchronized) && !(expr.isLabel && treeInfo.isSynthCaseSymbol(expr)) // it's okay to jump to matchEnd (or another case) with an argument of type nothing - private def treeOK(tree: Tree) = tree.tpe != null && tree.tpe.typeSymbol == NothingClass + private def treeOK(tree: Tree) = { + val isLabelDef = tree match { case _: LabelDef => true; case _ => false} + tree.tpe != null && tree.tpe.typeSymbol == NothingClass && !isLabelDef + } - def updateExpr(fn: Tree) = { - if (fn.symbol != null && fn.symbol.isMethod && !fn.symbol.isConstructor) - checkDead.expr = fn.symbol + @inline def updateExpr[A](fn: Tree)(f: => A) = { + if (fn.symbol != null && fn.symbol.isMethod && !fn.symbol.isConstructor) { + exprStack push fn.symbol + try f finally exprStack.pop() + } else f } def apply(tree: Tree): Tree = { // Error suppression will squash some of these warnings unless we circumvent it. diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala index 478312116a..f97582f45c 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala @@ -3305,8 +3305,6 @@ trait Typers extends Modes with Adaptations with Tags { // but behaves as if it were (=> T) => T) we need to know what is the actual // target of a call. Since this information is no longer available from // typedArg, it is recorded here. - checkDead.updateExpr(fun) - val args1 = // no expected type when jumping to a match label -- anything goes (this is ok since we're typing the translation of well-typed code) // ... except during erasure: we must take the expected type into account as it drives the insertion of casts! @@ -3361,7 +3359,9 @@ trait Typers extends Modes with Adaptations with Tags { else constfold(treeCopy.Apply(tree, fun, args1) setType ifPatternSkipFormals(restpe)) } - handleMonomorphicCall + checkDead.updateExpr(fun) { + handleMonomorphicCall + } } else if (needsInstantiation(tparams, formals, args)) { //println("needs inst "+fun+" "+tparams+"/"+(tparams map (_.info))) inferExprInstance(fun, tparams) diff --git a/src/library/scala/collection/immutable/ListMap.scala b/src/library/scala/collection/immutable/ListMap.scala index 670540187e..75817350e5 100644 --- a/src/library/scala/collection/immutable/ListMap.scala +++ b/src/library/scala/collection/immutable/ListMap.scala @@ -156,8 +156,12 @@ extends AbstractMap[A, B] * @return the value associated with the given key. */ override def apply(k: A): B1 = apply0(this, k) - - @tailrec private def apply0(cur: ListMap[A, B1], k: A): B1 = if (k == cur.key) cur.value else apply0(cur.tail, k) + + + @tailrec private def apply0(cur: ListMap[A, B1], k: A): B1 = + if (cur.isEmpty) throw new NoSuchElementException("key not found: "+k) + else if (k == cur.key) cur.value + else apply0(cur.tail, k) /** Checks if this map maps `key` to a value and return the * value if it exists. diff --git a/src/library/scala/runtime/BoxedUnit.java b/src/library/scala/runtime/BoxedUnit.java index 035c05d12a..f436b7c209 100644 --- a/src/library/scala/runtime/BoxedUnit.java +++ b/src/library/scala/runtime/BoxedUnit.java @@ -17,6 +17,8 @@ public final class BoxedUnit implements java.io.Serializable { public final static BoxedUnit UNIT = new BoxedUnit(); public final static Class<Void> TYPE = java.lang.Void.TYPE; + + private Object readResolve() { return UNIT; } private BoxedUnit() { } diff --git a/src/partest/scala/tools/partest/nest/RunnerManager.scala b/src/partest/scala/tools/partest/nest/RunnerManager.scala index c5e944fbc0..0d979d2692 100644 --- a/src/partest/scala/tools/partest/nest/RunnerManager.scala +++ b/src/partest/scala/tools/partest/nest/RunnerManager.scala @@ -817,7 +817,7 @@ class RunnerManager(kind: String, val fileManager: FileManager, params: TestRunP if (passed exists (x => !x)) { if (fileManager.showDiff || isPartestDebug) NestUI.normal(testDiff) - else if (fileManager.showLog) + if (fileManager.showLog) showLog(logFile) } } diff --git a/test/files/pos/t6225.scala b/test/files/pos/t6225.scala new file mode 100644 index 0000000000..d3d30d9e16 --- /dev/null +++ b/test/files/pos/t6225.scala @@ -0,0 +1,20 @@ + +package library.x { + class X { + class Foo + implicit val foo: Foo = new Foo + } +} +package library { + package object y extends library.x.X +} + +object ko { + import library.y.{Foo, foo} + implicitly[Foo] +} + +object ko2 { + import library.y._ + implicitly[Foo] +} diff --git a/test/files/pos/t6514.scala b/test/files/pos/t6514.scala new file mode 100644 index 0000000000..7c58605d39 --- /dev/null +++ b/test/files/pos/t6514.scala @@ -0,0 +1,11 @@ +object Test { + def e(msg: String) = new Exception(msg) + + // this code ain't dead. + def a(b: Boolean) = { + b match { + case true => throw e("true") + case false => throw e("false") + } + } +} diff --git a/test/files/run/t6370.scala b/test/files/run/t6370.scala new file mode 100644 index 0000000000..c86b87dc8a --- /dev/null +++ b/test/files/run/t6370.scala @@ -0,0 +1,12 @@ +object Test { + + def main(args: Array[String]): Unit = { + val m = collection.immutable.ListMap( "x" -> 1 ) + try { + m("y") + } catch { + case e : NoSuchElementException => assert(e.getMessage() == "key not found: y") + } + + } +} diff --git a/test/files/run/t6935.scala b/test/files/run/t6935.scala new file mode 100644 index 0000000000..dea2d7f2e2 --- /dev/null +++ b/test/files/run/t6935.scala @@ -0,0 +1,14 @@ +object Test { + + def main(args: Array[String]): Unit = { + import java.io._ + val bytes = new ByteArrayOutputStream() + val out = new ObjectOutputStream(bytes) + out.writeObject(()) + out.close() + val buf = bytes.toByteArray + val in = new ObjectInputStream(new ByteArrayInputStream(buf)) + val unit = in.readObject() + assert(unit == ()) + } +} |