diff options
3 files changed, 35 insertions, 20 deletions
diff --git a/src/compiler/scala/tools/nsc/matching/ParallelMatching.scala b/src/compiler/scala/tools/nsc/matching/ParallelMatching.scala index 1dcff85f71..0fabca1c15 100644 --- a/src/compiler/scala/tools/nsc/matching/ParallelMatching.scala +++ b/src/compiler/scala/tools/nsc/matching/ParallelMatching.scala @@ -38,6 +38,16 @@ trait ParallelMatching { import Types._ import Code.{ fn, Const } + /** + * Encapsulates a symbol being matched on. + * + * sym match { ... } + * + * results in Scrutinee(sym). + * + * Note that we only ever match on Symbols, not Trees: A temporary variable is created for any + * expressions being matched on. + */ case class Scrutinee(val sym: Symbol) { import definitions._ @@ -78,7 +88,9 @@ trait ParallelMatching { case _ => tpe } - // true if this pattern allows for a simple switch statement to be generated + /** + * Can this pattern be part of a switch statement? + */ lazy val isSimpleSwitchCandidate = stripped.tree match { case Literal(const : Constant) if isNumeric(const.tag) => const.tag match { @@ -165,6 +177,10 @@ trait ParallelMatching { } } + /** + * Class encapsulating a guard expression in a pattern match: + * case ... if(tree) => ... + */ case class Guard(tree: Tree) { def isEmpty = tree eq EmptyTree def duplicate = Guard(tree.duplicate) @@ -204,7 +220,7 @@ trait ParallelMatching { final def tree(implicit theOwner: Symbol, failTree: Tree): Tree = { val body = typer.typed { rep.requestBody(bx, subst) } lazy val vdefs = subst.targetParams - lazy val typedElse = repToTree(guardedRest) + lazy val typedElse = guardedRest.toTree lazy val typedIf = typer.typed(guard.mkIf(body, typedElse)) if (guard.isEmpty) body @@ -275,9 +291,9 @@ trait ParallelMatching { val (branches, defaultV, defaultRep) = this.getTransition // tag body pairs val cases = for ((tag, r) <- branches) yield { val r2 = rep.make(r.temp, r.row.map(x => x.rebind(bindVars(tag, x.subst)))) - CaseDef(Literal(tag), EmptyTree, repToTree(r2)) + CaseDef(Literal(tag), EmptyTree, r2.toTree) } - lazy val ndefault = defaultRep.map(repToTree) getOrElse failTree + lazy val ndefault = defaultRep.map(_.toTree) getOrElse failTree lazy val casesWithDefault = cases ::: List(CaseDef(mk_(definitions.IntClass.tpe), EmptyTree, ndefault)) cases match { @@ -359,8 +375,8 @@ trait ParallelMatching { final def tree(implicit theOwner: Symbol, failTree: Tree) = { val (uacall, vdefs, srep, frep) = this.getTransition - val succ = repToTree(srep) - val fail = frep.map(repToTree) getOrElse failTree + val succ = srep.toTree + val fail = frep.map(_.toTree) getOrElse failTree val cond = if (uacall.symbol.tpe.isBoolean) typer.typed(mkIdent(uacall.symbol)) else nonEmptinessCheck(uacall.symbol) @@ -434,8 +450,8 @@ trait ParallelMatching { final def tree(implicit theOwner: Symbol, failTree: Tree) = { val (cx,srep,frep) = this.getTransition - val succ = repToTree(srep) - val fail = repToTree(frep) + val succ = srep.toTree + val fail = frep.toTree cx(succ)(fail) } } @@ -494,10 +510,10 @@ trait ParallelMatching { final def tree(implicit theOwner: Symbol, failTree: Tree) = { val (cond, srep, fLabel, frep) = this.getTransition val cond2 = typer.typed( rep.handleOuter(cond) ) - val fail = typer.typed( repToTree(frep) ) + val fail = typer.typed( frep.toTree) fLabel setInfo MethodType(Nil, fail.tpe) - typer.typed( If(cond2, repToTree(srep), LabelDef(fLabel, Nil, fail)) ) + typer.typed( If(cond2, srep.toTree, LabelDef(fLabel, Nil, fail)) ) } } @@ -584,8 +600,8 @@ trait ParallelMatching { final def tree(implicit theOwner: Symbol, failTree: Tree): Tree = { val (casted, srep, frep) = this.getTransition val cond = condition(casted.tpe, scrut) - val succ = repToTree(srep) - val fail = frep.map(repToTree) getOrElse failTree + val succ = srep.toTree + val fail = frep.map(_.toTree) getOrElse failTree // dig out case field accessors that were buried in (***) val cfa = if (!pats.isCaseHead) Nil else casted.accessors @@ -604,11 +620,6 @@ trait ParallelMatching { } } - /** converts given rep to a tree - performs recursive call to translation in the process to get sub reps - */ - final def repToTree(r: Rep)(implicit theOwner: Symbol, failTree: Tree, rep: RepFactory): Tree = - r.applyRule.tree - case class Row(pat: List[Tree], subst: Bindings, guard: Guard, bx: Int) { def insert(h: Tree) = Row(h :: pat, subst, guard, bx) def insert(hs: List[Tree]) = Row(hs ::: pat, subst, guard, bx) // prepends supplied tree @@ -655,8 +666,6 @@ trait ParallelMatching { if (indexOfAlternative == -1) List(replace(pats)) else alternativeBranches } } - case class Columns(cols: Column*) - case class Column(pat: Tree, index: Int) class RepFactory(val handleOuter: Tree => Tree)(implicit val typer : Typer) { var vss: List[List[Symbol]] = _ @@ -832,6 +841,11 @@ trait ParallelMatching { } case class Rep(val temp: List[Symbol], val row: List[Row]) { + /** converts this to a tree - performs recursive call to translation in the process to get sub reps + */ + final def toTree(implicit theOwner: Symbol, failTree: Tree, rep: RepFactory): Tree = + this.applyRule.tree + private def setsToCombine: List[(Int, immutable.Set[Symbol])] = for { (sym, i) <- temp.zipWithIndex if sym hasFlag Flags.MUTABLE // indicates that have not yet checked exhaustivity diff --git a/src/compiler/scala/tools/nsc/matching/PatternNodes.scala b/src/compiler/scala/tools/nsc/matching/PatternNodes.scala index c0e256523c..53dcdc1bb6 100644 --- a/src/compiler/scala/tools/nsc/matching/PatternNodes.scala +++ b/src/compiler/scala/tools/nsc/matching/PatternNodes.scala @@ -154,6 +154,7 @@ trait PatternNodes { // me - if this isn't working maybe other unapply objects aren't working right either. The big // problem with using unapply and type matching is that if something's amiss, it will simply fail // silently, with the bug most likely manifesting at some unknown later point. + // DRM: This problem is almost certainly an instance of bug 1697 object Ident_Or_Empty { def unapply(x: Any) = x match { case Ident(nme.WILDCARD) | EmptyTree | _: Typed | _: Literal => true diff --git a/src/compiler/scala/tools/nsc/matching/TransMatcher.scala b/src/compiler/scala/tools/nsc/matching/TransMatcher.scala index f6f77ee47a..ba35cc79c9 100644 --- a/src/compiler/scala/tools/nsc/matching/TransMatcher.scala +++ b/src/compiler/scala/tools/nsc/matching/TransMatcher.scala @@ -79,7 +79,7 @@ trait TransMatcher { self: transform.ExplicitOuter with PatternNodes with Parall implicit val fail: Tree = theFailTree val irep = initRep(tmps, cases, rep) - val mch = typer.typed(repToTree(irep)) + val mch = typer.typed(irep.toTree) var dfatree = typer.typed(Block(vds, mch)) // cannot use squeezedBlock because of side-effects, see t275 |