diff options
author | Adriaan Moors <adriaan.moors@epfl.ch> | 2012-03-14 11:47:59 +0100 |
---|---|---|
committer | Adriaan Moors <adriaan.moors@epfl.ch> | 2012-03-20 19:54:03 +0100 |
commit | b046a6e3316df8b27ac31e71da1a139c800ccce7 (patch) | |
tree | dfbed2ea5620d100a62bbdf39b93488628e8cbb3 /src/compiler/scala/tools/nsc/transform/UnCurry.scala | |
parent | 2d3b309a36757545901b99da1b77698749fcc0c5 (diff) | |
download | scala-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.scala | 86 |
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)) |