diff options
author | Jason Zaugg <jzaugg@gmail.com> | 2014-05-28 15:20:01 +0200 |
---|---|---|
committer | Jason Zaugg <jzaugg@gmail.com> | 2014-06-10 17:00:19 +0200 |
commit | ad9d87b1faad22c1a2e05351757c0a940e2a0ef2 (patch) | |
tree | e2cf3962e0b6e772fbc73923a8c14af620825ecf /src/compiler/scala/tools/nsc/transform/patmat/MatchAnalysis.scala | |
parent | ddb29a8105bc3b692bc129cbd8ed111baae7076d (diff) | |
download | scala-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.scala | 10 |
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 |