summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Phillips <paulp@improving.org>2012-01-06 14:48:28 -0800
committerPaul Phillips <paulp@improving.org>2012-01-06 15:33:13 -0800
commitf39537a369e3b137f5b1bef21cc8f5d86bc9d9d8 (patch)
treec655fb315741d30c59594b0f6a4758898ec89d70
parentdd14b6a9b8b3355fae847f7fc8c1fc7d41babaa5 (diff)
downloadscala-f39537a369e3b137f5b1bef21cc8f5d86bc9d9d8.tar.gz
scala-f39537a369e3b137f5b1bef21cc8f5d86bc9d9d8.tar.bz2
scala-f39537a369e3b137f5b1bef21cc8f5d86bc9d9d8.zip
Fix for crasher during type inference.
Well, "fix" is pretty generous, how about "workaround". It does seem to do the job. Closes SI-4070, review by @moors.
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Infer.scala13
-rw-r--r--test/files/pos/t4070.scala37
-rw-r--r--test/files/pos/t4070b.scala35
3 files changed, 83 insertions, 2 deletions
diff --git a/src/compiler/scala/tools/nsc/typechecker/Infer.scala b/src/compiler/scala/tools/nsc/typechecker/Infer.scala
index 2bd307e31a..295b66b17f 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Infer.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Infer.scala
@@ -1447,8 +1447,17 @@ trait Infer {
/** A traverser to collect type parameters referred to in a type
*/
object freeTypeParamsOfTerms extends SymCollector {
- protected def includeCondition(sym: Symbol): Boolean =
- sym.isAbstractType && sym.owner.isTerm
+ // An inferred type which corresponds to an unknown type
+ // constructor creates a file/declaration order-dependent crasher
+ // situation, the behavior of which depends on the state at the
+ // time the typevar is created. Until we can deal with these
+ // properly, we can avoid it by ignoring type parameters which
+ // have type constructors amongst their bounds. See SI-4070.
+ protected def includeCondition(sym: Symbol) = (
+ sym.isAbstractType
+ && sym.owner.isTerm
+ && !sym.info.bounds.exists(_.typeParams.nonEmpty)
+ )
}
/** A traverser to collect type parameters referred to in a type
diff --git a/test/files/pos/t4070.scala b/test/files/pos/t4070.scala
new file mode 100644
index 0000000000..29c8d16e30
--- /dev/null
+++ b/test/files/pos/t4070.scala
@@ -0,0 +1,37 @@
+package a {
+ // method before classes
+ trait Foo {
+ def crash(x: Dingus[_]): Unit = x match { case m: Bippy[tv] => () }
+
+ class Dingus[T]
+ class Bippy[CC[X] <: Seq[X]]() extends Dingus[CC[Int]]
+ }
+}
+
+package b {
+ // classes before method
+ trait Foo {
+ class Dingus[T]
+ class Bippy[CC[X] <: Seq[X]]() extends Dingus[CC[Int]]
+
+ def crash(x: Dingus[_]): Unit = x match { case m: Bippy[tv] => () }
+ }
+}
+
+
+/*
+// With crash below the clasess:
+% scalac -Dscalac.debug.tvar ./a.scala
+[ create] ?_$1 ( In Foo#crash )
+[ setInst] tv[Int] ( In Foo#crash, _$1=tv[Int] )
+[ create] tv[Int] ( In Foo#crash )
+[ clone] tv[Int] ( Foo#crash )
+
+// With crash above the classes:
+% scalac -Dscalac.debug.tvar ./a.scala
+[ create] ?tv ( In Foo#crash )
+./a.scala:2: error: Invalid type application in TypeVar: List(), List(Int)
+ def crash(x: Dingus[_]): Unit = x match { case m: Bippy[tv] => () }
+ ^
+one error found
+*/
diff --git a/test/files/pos/t4070b.scala b/test/files/pos/t4070b.scala
new file mode 100644
index 0000000000..36d03de80c
--- /dev/null
+++ b/test/files/pos/t4070b.scala
@@ -0,0 +1,35 @@
+package a {
+ abstract class DeliteOp[B]
+ abstract class DeliteCollection[A]
+ abstract class Exp[T] { def Type: T }
+
+ trait DeliteOpMap[A,B,C[X] <: DeliteCollection[X]] extends DeliteOp[C[B]] {
+ val in: Exp[C[A]]
+ val func: Exp[B]
+ val alloc: Exp[C[B]]
+ }
+
+ object Test {
+ def f(x: DeliteOp[_]) = x match {
+ case map: DeliteOpMap[_,_,_] => map.alloc.Type
+ }
+ }
+}
+
+package b {
+ object Test {
+ def f(x: DeliteOp[_]) = x match {
+ case map: DeliteOpMap[_,_,_] => map.alloc.Type
+ }
+ }
+
+ abstract class DeliteOp[B]
+ abstract class DeliteCollection[A]
+ abstract class Exp[T] { def Type: T }
+
+ trait DeliteOpMap[A,B,C[X] <: DeliteCollection[X]] extends DeliteOp[C[B]] {
+ val in: Exp[C[A]]
+ val func: Exp[B]
+ val alloc: Exp[C[B]]
+ }
+} \ No newline at end of file