diff options
author | Paul Phillips <paulp@improving.org> | 2012-01-06 14:48:28 -0800 |
---|---|---|
committer | Paul Phillips <paulp@improving.org> | 2012-01-06 15:33:13 -0800 |
commit | f39537a369e3b137f5b1bef21cc8f5d86bc9d9d8 (patch) | |
tree | c655fb315741d30c59594b0f6a4758898ec89d70 | |
parent | dd14b6a9b8b3355fae847f7fc8c1fc7d41babaa5 (diff) | |
download | scala-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.scala | 13 | ||||
-rw-r--r-- | test/files/pos/t4070.scala | 37 | ||||
-rw-r--r-- | test/files/pos/t4070b.scala | 35 |
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 |