diff options
author | Adriaan Moors <adriaan.moors@epfl.ch> | 2012-03-23 12:39:46 +0100 |
---|---|---|
committer | Adriaan Moors <adriaan.moors@epfl.ch> | 2012-03-23 12:39:46 +0100 |
commit | 20426fb137ac9dfc2fb87adaaedb0646c0413320 (patch) | |
tree | 0b8e2c90e48d9558d6a24a89aa7ece07d73005b9 /src | |
parent | 09eda4ef92168685ef3d301439bb8b6df76f982e (diff) | |
download | scala-20426fb137ac9dfc2fb87adaaedb0646c0413320.tar.gz scala-20426fb137ac9dfc2fb87adaaedb0646c0413320.tar.bz2 scala-20426fb137ac9dfc2fb87adaaedb0646c0413320.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')
-rw-r--r-- | src/compiler/scala/tools/nsc/typechecker/PatMatVirtualiser.scala | 8 |
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))} |