summaryrefslogtreecommitdiff
path: root/src/compiler/scala/tools/nsc/transform/patmat
diff options
context:
space:
mode:
authorJason Zaugg <jzaugg@gmail.com>2014-06-11 09:25:50 +0200
committerJason Zaugg <jzaugg@gmail.com>2014-06-11 09:25:50 +0200
commitb664a488acca9d89c600f5b87ba9a9ca77aace59 (patch)
treea912905d3d00c7488ab11524918c715742e77765 /src/compiler/scala/tools/nsc/transform/patmat
parenta7046785e98db823a25eaaa975e571baed89690a (diff)
parent78caf290f86b965cc0d750d55a62ebea567d613d (diff)
downloadscala-b664a488acca9d89c600f5b87ba9a9ca77aace59.tar.gz
scala-b664a488acca9d89c600f5b87ba9a9ca77aace59.tar.bz2
scala-b664a488acca9d89c600f5b87ba9a9ca77aace59.zip
Merge pull request #3797 from retronym/topic/exhaust-compound
SI-8631 Treat `A with Sealed` as enumerable for pattern matching
Diffstat (limited to 'src/compiler/scala/tools/nsc/transform/patmat')
-rw-r--r--src/compiler/scala/tools/nsc/transform/patmat/MatchAnalysis.scala18
1 files changed, 14 insertions, 4 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..e1a663ea41 100644
--- a/src/compiler/scala/tools/nsc/transform/patmat/MatchAnalysis.scala
+++ b/src/compiler/scala/tools/nsc/transform/patmat/MatchAnalysis.scala
@@ -104,11 +104,18 @@ trait TreeAndTypeAnalysis extends Debugging {
// TODO case _ if tp.isTupleType => // recurse into component types
case modSym: ModuleClassSymbol =>
Some(List(tp))
+ 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
// make sure it's not a primitive, else (5: Byte) match { case 5 => ... } sees no Byte
- case sym if !sym.isSealed || isPrimitiveValueClass(sym) =>
- debug.patmat("enum unsealed "+ ((tp, sym, sym.isSealed, isPrimitiveValueClass(sym))))
- None
- case sym =>
+ case sym if sym.isSealed =>
val subclasses = debug.patmatResult(s"enum $sym sealed, subclasses")(
// symbols which are both sealed and abstract need not be covered themselves, because
// all of their children must be and they cannot otherwise be created.
@@ -136,6 +143,9 @@ trait TreeAndTypeAnalysis extends Debugging {
else None
}
})
+ case sym =>
+ debug.patmat("enum unsealed "+ ((tp, sym, sym.isSealed, isPrimitiveValueClass(sym))))
+ None
}
// approximate a type to the static type that is fully checkable at run time,