summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdriaan Moors <adriaan.moors@epfl.ch>2012-08-08 19:05:49 +0200
committerAdriaan Moors <adriaan.moors@epfl.ch>2012-08-09 09:40:08 +0200
commitd97f7d95436d88e2c6a1e2ed3599f4847ca8662c (patch)
tree3ad819c6fc84663e9c0f6d5ed833510f4bf65dde
parent5fc4057c7706ec1efa13a5f892a6d40de61ab970 (diff)
downloadscala-d97f7d95436d88e2c6a1e2ed3599f4847ca8662c.tar.gz
scala-d97f7d95436d88e2c6a1e2ed3599f4847ca8662c.tar.bz2
scala-d97f7d95436d88e2c6a1e2ed3599f4847ca8662c.zip
SI-6184 don't introduce dummies in checkableType
this should fix the crash in asSeenFrom that resulted from calling baseTypeSeq on a type that had an unbound type parameter in it also, simplify widenToClass
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/PatternMatching.scala33
-rw-r--r--test/files/pos/t6184.scala7
2 files changed, 22 insertions, 18 deletions
diff --git a/src/compiler/scala/tools/nsc/typechecker/PatternMatching.scala b/src/compiler/scala/tools/nsc/typechecker/PatternMatching.scala
index 1b502025c2..53f2a686f4 100644
--- a/src/compiler/scala/tools/nsc/typechecker/PatternMatching.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/PatternMatching.scala
@@ -2396,15 +2396,9 @@ trait PatternMatching extends Transform with TypingTransformers with ast.TreeDSL
// e.g., when we know some value must be of type T, can it still be of type S? (this is the positive formulation of what `excludes` on Const computes)
// since we're talking values, there must have been a class involved in creating it, so rephrase our types in terms of classes
// (At least conceptually: `true` is an instance of class `Boolean`)
- private def widenToClass(tp: Type) = {
- // getOrElse to err on the safe side -- all BTS should end in Any, right?
- val wideTp = tp.widen
- val clsTp =
- if (wideTp.typeSymbol.isClass) wideTp
- else wideTp.baseTypeSeq.toList.find(_.typeSymbol.isClass).getOrElse(AnyClass.tpe)
- // patmatDebug("Widening to class: "+ (tp, clsTp, tp.widen, tp.widen.baseTypeSeq, tp.widen.baseTypeSeq.toList.find(_.typeSymbol.isClass)))
- clsTp
- }
+ private def widenToClass(tp: Type): Type =
+ if (tp.typeSymbol.isClass) tp
+ else tp.baseType(tp.baseClasses.head)
object TypeConst extends TypeConstExtractor {
def apply(tp: Type) = {
@@ -2623,17 +2617,20 @@ trait PatternMatching extends Transform with TypingTransformers with ast.TreeDSL
// TODO: this is subject to the availability of TypeTags (since an abstract type with a type tag is checkable at run time)
def checkableType(tp: Type): Type = {
// TODO: this is extremely rough...
- object toCheckable extends TypeMap {
- def apply(tp: Type) = tp match {
- case TypeRef(pre, sym, a :: as) if sym ne ArrayClass =>
- // replace type args by existentials, since they can't be checked
- // TODO: when type tags are available, we will check -- when this is implemented, can we take that into account here?
- // TODO: don't reuse sym.typeParams, they have bounds (and those must not be considered)
- newExistentialType(sym.typeParams, sym.tpe).asSeenFrom(pre, sym.owner)
- case _ => mapOver(tp)
+ // replace type args by wildcards, since they can't be checked (don't use existentials: overkill)
+ // TODO: when type tags are available, we will check -- when this is implemented, can we take that into account here?
+ // similar to typer.infer.approximateAbstracts
+ object typeArgsToWildcardsExceptArray extends TypeMap {
+ def apply(tp: Type): Type = tp match {
+ case TypeRef(pre, sym, as) if as.nonEmpty && (sym ne ArrayClass) =>
+ val wildArgs = List.fill(as.length)(WildcardType)
+ TypeRef(pre, sym, wildArgs)
+ case _ =>
+ mapOver(tp)
}
}
- val res = toCheckable(tp)
+
+ val res = typeArgsToWildcardsExceptArray(tp)
patmatDebug("checkable "+(tp, res))
res
}
diff --git a/test/files/pos/t6184.scala b/test/files/pos/t6184.scala
new file mode 100644
index 0000000000..83a1306aca
--- /dev/null
+++ b/test/files/pos/t6184.scala
@@ -0,0 +1,7 @@
+trait Foo[TroubleSome] {
+ type T <: Foo[TroubleSome]
+
+ this match {
+ case e: Foo[_]#T => ???
+ }
+} \ No newline at end of file