aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorodersky <odersky@gmail.com>2015-11-02 14:48:16 +0100
committerodersky <odersky@gmail.com>2015-11-02 14:48:16 +0100
commitf58acd171105487984a1d8df2646246aab43e5e1 (patch)
treef271a3ece981ef0df425d21a98bdc913adaee876 /src
parent21f6711d0ba034238f780614368d9d270192a22a (diff)
parentb80b179d6fbb92c8f6ff3616cec1f3aab5106799 (diff)
downloaddotty-f58acd171105487984a1d8df2646246aab43e5e1.tar.gz
dotty-f58acd171105487984a1d8df2646246aab43e5e1.tar.bz2
dotty-f58acd171105487984a1d8df2646246aab43e5e1.zip
Merge pull request #887 from dotty-staging/fix-#873
Allow pattern matching anonymous functions of arity > 1
Diffstat (limited to 'src')
-rw-r--r--src/dotty/tools/dotc/ast/Desugar.scala16
-rw-r--r--src/dotty/tools/dotc/typer/Typer.scala23
2 files changed, 24 insertions, 15 deletions
diff --git a/src/dotty/tools/dotc/ast/Desugar.scala b/src/dotty/tools/dotc/ast/Desugar.scala
index d1f101283..1ef883bf2 100644
--- a/src/dotty/tools/dotc/ast/Desugar.scala
+++ b/src/dotty/tools/dotc/ast/Desugar.scala
@@ -556,14 +556,20 @@ object desugar {
DefDef(nme.ANON_FUN, Nil, params :: Nil, tpt, body).withMods(synthetic),
Closure(Nil, Ident(nme.ANON_FUN), EmptyTree))
- /** Expand partial function
+ /** If `nparams` == 1, expand partial function
+ *
* { cases }
* ==>
- * x$0 => x$0 match { cases }
+ * x$1 => x$1 match { cases }
+ *
+ * If `nparams` != 1, expand instead to
+ *
+ * (x$1, ..., x$n) => (x$0, ..., x${n-1}) match { cases }
*/
- def makeCaseLambda(cases: List[CaseDef])(implicit ctx: Context) = {
- val param = makeSyntheticParameter()
- Function(param :: Nil, Match(Ident(param.name), cases))
+ def makeCaseLambda(cases: List[CaseDef], nparams: Int = 1)(implicit ctx: Context) = {
+ val params = (1 to nparams).toList.map(makeSyntheticParameter(_))
+ val selector = makeTuple(params.map(p => Ident(p.name)))
+ Function(params, Match(selector, cases))
}
/** Add annotation with class `cls` to tree:
diff --git a/src/dotty/tools/dotc/typer/Typer.scala b/src/dotty/tools/dotc/typer/Typer.scala
index 569e4f7d5..4637eed51 100644
--- a/src/dotty/tools/dotc/typer/Typer.scala
+++ b/src/dotty/tools/dotc/typer/Typer.scala
@@ -502,6 +502,16 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
assignType(cpy.If(tree)(cond1, thenp2, elsep2), thenp2, elsep2)
}
+ private def decomposeProtoFunction(pt: Type, defaultArity: Int)(implicit ctx: Context): (List[Type], Type) = pt match {
+ case _ if defn.isFunctionType(pt) =>
+ (pt.dealias.argInfos.init, pt.dealias.argInfos.last)
+ case SAMType(meth) =>
+ val mt @ MethodType(_, paramTypes) = meth.info
+ (paramTypes, mt.resultType)
+ case _ =>
+ (List.range(0, defaultArity) map alwaysWildcardType, WildcardType)
+ }
+
def typedFunction(tree: untpd.Function, pt: Type)(implicit ctx: Context) = track("typedFunction") {
val untpd.Function(args, body) = tree
if (ctx.mode is Mode.Type)
@@ -509,15 +519,7 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
untpd.TypeTree(defn.FunctionClass(args.length).typeRef), args :+ body), pt)
else {
val params = args.asInstanceOf[List[untpd.ValDef]]
- val (protoFormals, protoResult): (List[Type], Type) = pt match {
- case _ if defn.isFunctionType(pt) =>
- (pt.dealias.argInfos.init, pt.dealias.argInfos.last)
- case SAMType(meth) =>
- val mt @ MethodType(_, paramTypes) = meth.info
- (paramTypes, mt.resultType)
- case _ =>
- (params map alwaysWildcardType, WildcardType)
- }
+ val (protoFormals, protoResult) = decomposeProtoFunction(pt, params.length)
def refersTo(arg: untpd.Tree, param: untpd.ValDef): Boolean = arg match {
case Ident(name) => name == param.name
@@ -629,7 +631,8 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
def typedMatch(tree: untpd.Match, pt: Type)(implicit ctx: Context) = track("typedMatch") {
tree.selector match {
case EmptyTree =>
- typed(desugar.makeCaseLambda(tree.cases) withPos tree.pos, pt)
+ val (protoFormals, _) = decomposeProtoFunction(pt, 1)
+ typed(desugar.makeCaseLambda(tree.cases, protoFormals.length) withPos tree.pos, pt)
case _ =>
val sel1 = typedExpr(tree.selector)
val selType = widenForMatchSelector(