summaryrefslogtreecommitdiff
path: root/src/compiler
diff options
context:
space:
mode:
authorAdriaan Moors <adriaan.moors@epfl.ch>2012-03-23 12:39:46 +0100
committerAdriaan Moors <adriaan.moors@epfl.ch>2012-03-23 18:27:57 +0100
commite33950ccaa3dd7597c46956a29c1e2a859bb32be (patch)
tree0b8e2c90e48d9558d6a24a89aa7ece07d73005b9 /src/compiler
parent33a79fbc43dce40cdea93de37976f1d228440a9c (diff)
downloadscala-e33950ccaa3dd7597c46956a29c1e2a859bb32be.tar.gz
scala-e33950ccaa3dd7597c46956a29c1e2a859bb32be.tar.bz2
scala-e33950ccaa3dd7597c46956a29c1e2a859bb32be.zip
[vpm] be more careful about swatches
type-switch-based catches must not contain type tests on traits for some reason, so fall back to full-blown pattern match TODO: can we improve this? this simply mimics the old pattern matcher's behavior
Diffstat (limited to 'src/compiler')
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/PatMatVirtualiser.scala8
1 files changed, 5 insertions, 3 deletions
diff --git a/src/compiler/scala/tools/nsc/typechecker/PatMatVirtualiser.scala b/src/compiler/scala/tools/nsc/typechecker/PatMatVirtualiser.scala
index 2b67f7f44b..5452d13ef0 100644
--- a/src/compiler/scala/tools/nsc/typechecker/PatMatVirtualiser.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/PatMatVirtualiser.scala
@@ -149,7 +149,7 @@ trait PatMatVirtualiser extends ast.TreeDSL { self: Analyzer =>
// if they're already simple enough to be handled by the back-end, we're done
if (caseDefs forall treeInfo.isCatchCase) caseDefs
else {
- val switch = {
+ val swatches = { // switch-catches
val bindersAndCases = caseDefs map { caseDef =>
// generate a fresh symbol for each case, hoping we'll end up emitting a type-switch (we don't have a global scrut there)
// if we fail to emit a fine-grained switch, have to do translateCase again with a single scrutSym (TODO: uniformize substitution on treemakers so we can avoid this)
@@ -157,10 +157,12 @@ trait PatMatVirtualiser extends ast.TreeDSL { self: Analyzer =>
(caseScrutSym, propagateSubstitution(translateCase(caseScrutSym, pt)(caseDef), EmptySubstitution))
}
- (emitTypeSwitch(bindersAndCases, pt) map (_.map(fixerUpper(matchOwner, pos).apply(_).asInstanceOf[CaseDef])))
+ for(cases <- emitTypeSwitch(bindersAndCases, pt) toList;
+ if cases forall treeInfo.isCatchCase; // must check again, since it's not guaranteed -- TODO: can we eliminate this? e.g., a type test could test for a trait or a non-trivial prefix, which are not handled by the back-end
+ cse <- cases) yield fixerUpper(matchOwner, pos)(cse).asInstanceOf[CaseDef]
}
- val catches = switch getOrElse {
+ val catches = if (swatches nonEmpty) swatches else {
val scrutSym = freshSym(pos, pureType(ThrowableClass.tpe))
val casesNoSubstOnly = caseDefs map { caseDef => (propagateSubstitution(translateCase(scrutSym, pt)(caseDef), EmptySubstitution))}