summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorPaul Phillips <paulp@improving.org>2013-08-17 07:39:06 -0700
committerPaul Phillips <paulp@improving.org>2013-08-17 08:22:53 -0700
commitd351a1f79b5bd5f3be7d5e292f046495a9a0e629 (patch)
treefd7071d59ac786ea4db7987ae86162921b8566d9 /src
parent0be0b99414ae54f1f4fbc7c7bc0e36e3ada20289 (diff)
downloadscala-d351a1f79b5bd5f3be7d5e292f046495a9a0e629.tar.gz
scala-d351a1f79b5bd5f3be7d5e292f046495a9a0e629.tar.bz2
scala-d351a1f79b5bd5f3be7d5e292f046495a9a0e629.zip
Segreated CPS hacks in pattern matcher.
Diffstat (limited to 'src')
-rw-r--r--src/compiler/scala/tools/nsc/transform/patmat/MatchTranslation.scala55
1 files changed, 34 insertions, 21 deletions
diff --git a/src/compiler/scala/tools/nsc/transform/patmat/MatchTranslation.scala b/src/compiler/scala/tools/nsc/transform/patmat/MatchTranslation.scala
index fcee142932..2de9dac54f 100644
--- a/src/compiler/scala/tools/nsc/transform/patmat/MatchTranslation.scala
+++ b/src/compiler/scala/tools/nsc/transform/patmat/MatchTranslation.scala
@@ -10,9 +10,40 @@ import scala.language.postfixOps
import scala.collection.mutable
import scala.reflect.internal.util.Statistics
+
+/** Segregating this super hacky code. */
+trait CpsPatternHacks {
+ self: PatternMatching =>
+
+ import global._
+
+ // duplicated from CPSUtils (avoid dependency from compiler -> cps plugin...)
+ private object CpsSymbols {
+ val MarkerCPSAdaptPlus = rootMirror.getClassIfDefined("scala.util.continuations.cpsPlus")
+ val MarkerCPSAdaptMinus = rootMirror.getClassIfDefined("scala.util.continuations.cpsMinus")
+ val MarkerCPSSynth = rootMirror.getClassIfDefined("scala.util.continuations.cpsSynth")
+ val MarkerCPSTypes = rootMirror.getClassIfDefined("scala.util.continuations.cpsParam")
+ val stripTriggerCPSAnns = Set[Symbol](MarkerCPSSynth, MarkerCPSAdaptMinus, MarkerCPSAdaptPlus)
+ val strippedCPSAnns = stripTriggerCPSAnns + MarkerCPSTypes
+
+ // when one of the internal cps-type-state annotations is present, strip all CPS annotations
+ // a cps-type-state-annotated type makes no sense as an expected type (matchX.tpe is used as pt in translateMatch)
+ // (only test availability of MarkerCPSAdaptPlus assuming they are either all available or none of them are)
+ def removeCPSFromPt(pt: Type): Type = (
+ if (MarkerCPSAdaptPlus.exists && (stripTriggerCPSAnns exists pt.hasAnnotation))
+ pt filterAnnotations (ann => !(strippedCPSAnns exists ann.matches))
+ else
+ pt
+ )
+ }
+ def removeCPSFromPt(pt: Type): Type = CpsSymbols removeCPSFromPt pt
+}
+
/** Translate typed Trees that represent pattern matches into the patternmatching IR, defined by TreeMakers.
*/
-trait MatchTranslation { self: PatternMatching =>
+trait MatchTranslation extends CpsPatternHacks {
+ self: PatternMatching =>
+
import PatternMatchingStats._
import global._
import definitions._
@@ -84,15 +115,6 @@ trait MatchTranslation { self: PatternMatching =>
}
}
- // duplicated from CPSUtils (avoid dependency from compiler -> cps plugin...)
- private lazy val MarkerCPSAdaptPlus = rootMirror.getClassIfDefined("scala.util.continuations.cpsPlus")
- private lazy val MarkerCPSAdaptMinus = rootMirror.getClassIfDefined("scala.util.continuations.cpsMinus")
- private lazy val MarkerCPSSynth = rootMirror.getClassIfDefined("scala.util.continuations.cpsSynth")
- private lazy val stripTriggerCPSAnns = List(MarkerCPSSynth, MarkerCPSAdaptMinus, MarkerCPSAdaptPlus)
- private lazy val MarkerCPSTypes = rootMirror.getClassIfDefined("scala.util.continuations.cpsParam")
- private lazy val strippedCPSAnns = MarkerCPSTypes :: stripTriggerCPSAnns
- private def removeCPSAdaptAnnotations(tp: Type) = tp filterAnnotations (ann => !(strippedCPSAnns exists (ann matches _)))
-
/** Implement a pattern match by turning its cases (including the implicit failure case)
* into the corresponding (monadic) extractors, and combining them with the `orElse` combinator.
*
@@ -127,18 +149,11 @@ trait MatchTranslation { self: PatternMatching =>
val selectorTp = repeatedToSeq(elimAnonymousClass(selector.tpe.widen.withoutAnnotations))
- val origPt = match_.tpe
// when one of the internal cps-type-state annotations is present, strip all CPS annotations
- // a cps-type-state-annotated type makes no sense as an expected type (matchX.tpe is used as pt in translateMatch)
- // (only test availability of MarkerCPSAdaptPlus assuming they are either all available or none of them are)
- val ptUnCPS =
- if (MarkerCPSAdaptPlus != NoSymbol && (stripTriggerCPSAnns exists origPt.hasAnnotation))
- removeCPSAdaptAnnotations(origPt)
- else origPt
-
+ val origPt = removeCPSFromPt(match_.tpe)
// relevant test cases: pos/existentials-harmful.scala, pos/gadt-gilles.scala, pos/t2683.scala, pos/virtpatmat_exist4.scala
// pt is the skolemized version
- val pt = repeatedToSeq(ptUnCPS)
+ val pt = repeatedToSeq(origPt)
// val packedPt = repeatedToSeq(typer.packedType(match_, context.owner))
val selectorSym = freshSym(selector.pos, pureType(selectorTp)) setFlag treeInfo.SYNTH_CASE_FLAGS
@@ -191,8 +206,6 @@ trait MatchTranslation { self: PatternMatching =>
typer.typedCases(catches, ThrowableTpe, WildcardType)
}
-
-
/** The translation of `pat if guard => body` has two aspects:
* 1) the substitution due to the variables bound by patterns
* 2) the combination of the extractor calls using `flatMap`.