summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Contexts.scala9
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/TreeCheckers.scala3
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/TypeDiagnostics.scala17
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Typers.scala6
-rw-r--r--src/library/scala/collection/immutable/ListMap.scala8
-rw-r--r--src/library/scala/runtime/BoxedUnit.java2
-rw-r--r--src/partest/scala/tools/partest/nest/RunnerManager.scala2
-rw-r--r--test/files/pos/t6225.scala20
-rw-r--r--test/files/pos/t6514.scala11
-rw-r--r--test/files/run/t6370.scala12
-rw-r--r--test/files/run/t6935.scala14
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 == ())
+ }
+}