summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAdriaan Moors <adriaan.moors@epfl.ch>2012-06-26 11:05:25 +0200
committerAdriaan Moors <adriaan.moors@epfl.ch>2012-06-26 20:17:57 +0200
commit966c9bbebec78b90a79f72c73b55d9de6db34798 (patch)
tree9b9b8060cbe0250ddb65ceb2d9e2652ef5973f0f /src
parent3601b34fb7bbd60f6f25d3bf44edc653aa7ba45b (diff)
downloadscala-966c9bbebec78b90a79f72c73b55d9de6db34798.tar.gz
scala-966c9bbebec78b90a79f72c73b55d9de6db34798.tar.bz2
scala-966c9bbebec78b90a79f72c73b55d9de6db34798.zip
SI-5899 exhaustiveness for non-class types
Diffstat (limited to 'src')
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/PatternMatching.scala22
1 files changed, 17 insertions, 5 deletions
diff --git a/src/compiler/scala/tools/nsc/typechecker/PatternMatching.scala b/src/compiler/scala/tools/nsc/typechecker/PatternMatching.scala
index 2ee3570905..c466206192 100644
--- a/src/compiler/scala/tools/nsc/typechecker/PatternMatching.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/PatternMatching.scala
@@ -2153,6 +2153,21 @@ trait PatternMatching extends Transform with TypingTransformers with ast.TreeDSL
// the equals inherited from AnyRef does just this
}
+ // find most precise super-type of tp that is a class
+ // we skip non-class types (singleton types, abstract types) so that we can
+ // correctly compute how types relate in terms of the values they rule out
+ // 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
+ }
object TypeConst {
def apply(tp: Type) = {
@@ -2168,7 +2183,7 @@ trait PatternMatching extends Transform with TypingTransformers with ast.TreeDSL
assert(!(tp =:= NullTp))
private[this] val id: Int = Const.nextTypeId
- val wideTp = tp.widen
+ val wideTp = widenToClass(tp)
override def toString = tp.toString //+"#"+ id
}
@@ -2187,10 +2202,7 @@ trait PatternMatching extends Transform with TypingTransformers with ast.TreeDSL
val tp = p.tpe.normalize
if (tp =:= NullTp) NullConst
else {
- val wideTp = {
- if (p.hasSymbol && p.symbol.isStable) tp.asSeenFrom(tp.prefix, p.symbol.owner).widen
- else tp.widen
- }
+ val wideTp = widenToClass(tp)
val narrowTp =
if (tp.isInstanceOf[SingletonType]) tp