summaryrefslogtreecommitdiff
path: root/src/compiler/scala/tools/nsc/transform/UnCurry.scala
diff options
context:
space:
mode:
authorAdriaan Moors <adriaan.moors@epfl.ch>2012-03-14 11:47:59 +0100
committerAdriaan Moors <adriaan.moors@epfl.ch>2012-03-20 19:54:03 +0100
commitb046a6e3316df8b27ac31e71da1a139c800ccce7 (patch)
treedfbed2ea5620d100a62bbdf39b93488628e8cbb3 /src/compiler/scala/tools/nsc/transform/UnCurry.scala
parent2d3b309a36757545901b99da1b77698749fcc0c5 (diff)
downloadscala-b046a6e3316df8b27ac31e71da1a139c800ccce7.tar.gz
scala-b046a6e3316df8b27ac31e71da1a139c800ccce7.tar.bz2
scala-b046a6e3316df8b27ac31e71da1a139c800ccce7.zip
[vpm] typer synths Function{} for empty-sel match
typedMatchAnonFun is called from typedFunction when the function's body is a match this is work-in-progres: the compiler currently won't bootstrap under -Yvirtpatmat see also the pending test make sure to use the right context in typeFunction when the body is a Match when typer is set up for type checking a Function, the current owner is the symbol for the function, but we'll type check a Block(List(ClassDef(cd)), New(cd)) when the function is a match, and the function symbol is nowhere to be found, so go to outer context in patmatvirt: - simplified default case gen (no need for a Casegen instance) - using CASE | SYNTHETIC to detect generated matches (for switches) and avoid typing them endlessly more uniform, and necessary for new-style anon Function class instance gen for matches
Diffstat (limited to 'src/compiler/scala/tools/nsc/transform/UnCurry.scala')
-rw-r--r--src/compiler/scala/tools/nsc/transform/UnCurry.scala86
1 files changed, 45 insertions, 41 deletions
diff --git a/src/compiler/scala/tools/nsc/transform/UnCurry.scala b/src/compiler/scala/tools/nsc/transform/UnCurry.scala
index ee565530b7..03bef83a90 100644
--- a/src/compiler/scala/tools/nsc/transform/UnCurry.scala
+++ b/src/compiler/scala/tools/nsc/transform/UnCurry.scala
@@ -237,8 +237,10 @@ abstract class UnCurry extends InfoTransform
def targs = fun.tpe.typeArgs
def isPartial = fun.tpe.typeSymbol == PartialFunctionClass
+ // if the function was eta-expanded, it's not a match without a selector
if (fun1 ne fun) fun1
else {
+ assert(!(opt.virtPatmat && isPartial)) // empty-selector matches have already been translated into instantiations of anonymous (partial) functions
val (formals, restpe) = (targs.init, targs.last)
val anonClass = owner.newAnonymousFunctionClass(fun.pos, inConstructorFlag)
def parents =
@@ -286,52 +288,54 @@ abstract class UnCurry extends InfoTransform
def defaultCase = CaseDef(Ident(nme.WILDCARD), EmptyTree, Literal(Constant(false)))
- val casesNoSynthCatchAll = dropSyntheticCatchAll(cases)
+// val casesNoSynthCatchAll = dropSyntheticCatchAll(cases)
gen.mkUncheckedMatch(
- if (casesNoSynthCatchAll exists treeInfo.isDefaultCase) Literal(Constant(true))
- else substTree(wrap(Match(selector, (casesNoSynthCatchAll map transformCase) :+ defaultCase)).duplicate)
+ if (cases exists treeInfo.isDefaultCase) Literal(Constant(true))
+ else substTree(wrap(Match(selector, (cases map transformCase) :+ defaultCase)).duplicate)
)
}
- override def caseVirtualizedMatch(orig: Tree, _match: Tree, targs: List[Tree], scrut: Tree, matcher: Tree): Tree = {
- object noOne extends Transformer {
- override val treeCopy = newStrictTreeCopier // must duplicate everything
- val one = _match.tpe member newTermName("one")
- override def transform(tree: Tree): Tree = tree match {
- case Apply(fun, List(a)) if fun.symbol == one =>
- // blow one's argument away since all we want to know is whether the match succeeds or not
- // (the alternative, making `one` CBN, would entail moving away from Option)
- Apply(fun.duplicate, List(gen.mkZeroContravariantAfterTyper(a.tpe)))
- case _ =>
- super.transform(tree)
- }
- }
- substTree(Apply(Apply(TypeApply(Select(_match.duplicate, _match.tpe.member(newTermName("isSuccess"))), targs map (_.duplicate)), List(scrut.duplicate)), List(noOne.transform(matcher))))
- }
-
- override def caseVirtualizedMatchOpt(orig: Tree, zero: ValDef, x: ValDef, matchRes: ValDef, keepGoing: ValDef, stats: List[Tree], epilogue: Tree, wrap: Tree => Tree) = {
- object dropMatchResAssign extends Transformer {
- // override val treeCopy = newStrictTreeCopier // will duplicate below
- override def transform(tree: Tree): Tree = tree match {
- // don't compute the result of the match -- remove the block for the RHS (emitted by pmgen.one), except for the assignment to keepGoing
- case gen.VirtualCaseDef(assignKeepGoing, matchRes, zero) if assignKeepGoing.lhs.symbol eq keepGoing.symbol =>
- Block(List(assignKeepGoing), zero)
- case _ =>
- super.transform(tree)
- }
- }
- val statsNoMatchRes: List[Tree] = stats map (dropMatchResAssign.transform) toList
- val idaBlock = wrap(Block(
- zero ::
- x ::
- /* drop matchRes def */
- keepGoing ::
- statsNoMatchRes,
- NOT(REF(keepGoing.symbol)) // replace `if (keepGoing) throw new MatchError(...) else matchRes` epilogue by `!keepGoing`
- ))
- substTree(idaBlock.duplicate) // duplicate on block as a whole to ensure valdefs are properly cloned and substed
- }
+ override def caseVirtualizedMatch(orig: Tree, _match: Tree, targs: List[Tree], scrut: Tree, matcher: Tree): Tree = {assert(false); orig}
+ // {
+ // object noOne extends Transformer {
+ // override val treeCopy = newStrictTreeCopier // must duplicate everything
+ // val one = _match.tpe member newTermName("one")
+ // override def transform(tree: Tree): Tree = tree match {
+ // case Apply(fun, List(a)) if fun.symbol == one =>
+ // // blow one's argument away since all we want to know is whether the match succeeds or not
+ // // (the alternative, making `one` CBN, would entail moving away from Option)
+ // Apply(fun.duplicate, List(gen.mkZeroContravariantAfterTyper(a.tpe)))
+ // case _ =>
+ // super.transform(tree)
+ // }
+ // }
+ // substTree(Apply(Apply(TypeApply(Select(_match.duplicate, _match.tpe.member(newTermName("isSuccess"))), targs map (_.duplicate)), List(scrut.duplicate)), List(noOne.transform(matcher))))
+ // }
+
+ override def caseVirtualizedMatchOpt(orig: Tree, zero: ValDef, x: ValDef, matchRes: ValDef, keepGoing: ValDef, stats: List[Tree], epilogue: Tree, wrap: Tree => Tree) = {assert(false); orig}
+ // {
+ // object dropMatchResAssign extends Transformer {
+ // // override val treeCopy = newStrictTreeCopier // will duplicate below
+ // override def transform(tree: Tree): Tree = tree match {
+ // // don't compute the result of the match -- remove the block for the RHS (emitted by pmgen.one), except for the assignment to keepGoing
+ // case gen.VirtualCaseDef(assignKeepGoing, matchRes, zero) if assignKeepGoing.lhs.symbol eq keepGoing.symbol =>
+ // Block(List(assignKeepGoing), zero)
+ // case _ =>
+ // super.transform(tree)
+ // }
+ // }
+ // val statsNoMatchRes: List[Tree] = stats map (dropMatchResAssign.transform) toList
+ // val idaBlock = wrap(Block(
+ // zero ::
+ // x ::
+ // /* drop matchRes def */
+ // keepGoing ::
+ // statsNoMatchRes,
+ // NOT(REF(keepGoing.symbol)) // replace `if (keepGoing) throw new MatchError(...) else matchRes` epilogue by `!keepGoing`
+ // ))
+ // substTree(idaBlock.duplicate) // duplicate on block as a whole to ensure valdefs are properly cloned and substed
+ // }
}
DefDef(m, isDefinedAtTransformer(fun.body))