diff options
author | Adriaan Moors <adriaan.moors@epfl.ch> | 2012-06-26 11:05:25 +0200 |
---|---|---|
committer | Adriaan Moors <adriaan.moors@epfl.ch> | 2012-06-26 20:17:57 +0200 |
commit | 966c9bbebec78b90a79f72c73b55d9de6db34798 (patch) | |
tree | 9b9b8060cbe0250ddb65ceb2d9e2652ef5973f0f | |
parent | 3601b34fb7bbd60f6f25d3bf44edc653aa7ba45b (diff) | |
download | scala-966c9bbebec78b90a79f72c73b55d9de6db34798.tar.gz scala-966c9bbebec78b90a79f72c73b55d9de6db34798.tar.bz2 scala-966c9bbebec78b90a79f72c73b55d9de6db34798.zip |
SI-5899 exhaustiveness for non-class types
-rw-r--r-- | src/compiler/scala/tools/nsc/typechecker/PatternMatching.scala | 22 | ||||
-rw-r--r-- | test/files/pos/t5899.flags | 1 | ||||
-rw-r--r-- | test/files/pos/t5899.scala | 19 |
3 files changed, 37 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 diff --git a/test/files/pos/t5899.flags b/test/files/pos/t5899.flags new file mode 100644 index 0000000000..e8fb65d50c --- /dev/null +++ b/test/files/pos/t5899.flags @@ -0,0 +1 @@ +-Xfatal-warnings
\ No newline at end of file diff --git a/test/files/pos/t5899.scala b/test/files/pos/t5899.scala new file mode 100644 index 0000000000..b16f1f84fe --- /dev/null +++ b/test/files/pos/t5899.scala @@ -0,0 +1,19 @@ +import scala.tools.nsc._ + +trait Foo { + val global: Global + import global.{Name, Symbol, nme} + + case class Bippy(name: Name) + + def f(x: Bippy, sym: Symbol): Int = { + // no warning (!) for + // val Stable = sym.name.toTermName + + val Stable = sym.name + Bippy(Stable) match { + case Bippy(nme.WILDCARD) => 1 + case Bippy(Stable) => 2 // should not be considered unreachable + } + } +}
\ No newline at end of file |