summaryrefslogtreecommitdiff
path: root/src/compiler/scala/tools/nsc/transform/patmat/MatchAnalysis.scala
diff options
context:
space:
mode:
authorJason Zaugg <jzaugg@gmail.com>2014-05-28 15:20:01 +0200
committerJason Zaugg <jzaugg@gmail.com>2014-06-10 17:00:19 +0200
commitad9d87b1faad22c1a2e05351757c0a940e2a0ef2 (patch)
treee2cf3962e0b6e772fbc73923a8c14af620825ecf /src/compiler/scala/tools/nsc/transform/patmat/MatchAnalysis.scala
parentddb29a8105bc3b692bc129cbd8ed111baae7076d (diff)
downloadscala-ad9d87b1faad22c1a2e05351757c0a940e2a0ef2.tar.gz
scala-ad9d87b1faad22c1a2e05351757c0a940e2a0ef2.tar.bz2
scala-ad9d87b1faad22c1a2e05351757c0a940e2a0ef2.zip
SI-8631 Treat `A with Sealed` as enumerable for pattern matching
Enumerate the subtypes of sealed parent types of refinement types, and filter those that conform to the refinement type. Such types can crop up easily when LUB-bing case classes which add `Product with Serializable` to the mix.
Diffstat (limited to 'src/compiler/scala/tools/nsc/transform/patmat/MatchAnalysis.scala')
-rw-r--r--src/compiler/scala/tools/nsc/transform/patmat/MatchAnalysis.scala10
1 files changed, 10 insertions, 0 deletions
diff --git a/src/compiler/scala/tools/nsc/transform/patmat/MatchAnalysis.scala b/src/compiler/scala/tools/nsc/transform/patmat/MatchAnalysis.scala
index 894f959319..3ef9b8c0b4 100644
--- a/src/compiler/scala/tools/nsc/transform/patmat/MatchAnalysis.scala
+++ b/src/compiler/scala/tools/nsc/transform/patmat/MatchAnalysis.scala
@@ -105,6 +105,16 @@ trait TreeAndTypeAnalysis extends Debugging {
case modSym: ModuleClassSymbol =>
Some(List(tp))
// make sure it's not a primitive, else (5: Byte) match { case 5 => ... } sees no Byte
+ case sym: RefinementClassSymbol =>
+ val parentSubtypes: List[Option[List[Type]]] = tp.parents.map(parent => enumerateSubtypes(parent))
+ if (parentSubtypes exists (_.isDefined))
+ // If any of the parents is enumerable, then the refinement type is enumerable.
+ Some(
+ // We must only include subtypes of the parents that conform to `tp`.
+ // See neg/virtpatmat_exhaust_compound.scala for an example.
+ parentSubtypes flatMap (_.getOrElse(Nil)) filter (_ <:< tp)
+ )
+ else None
case sym if !sym.isSealed || isPrimitiveValueClass(sym) =>
debug.patmat("enum unsealed "+ ((tp, sym, sym.isSealed, isPrimitiveValueClass(sym))))
None