Skip to content

Commit b80b179

Browse files
committed
Also handle SAM functions when adaptiing arity of case lambdas.
1 parent 9fbb9c9 commit b80b179

File tree

2 files changed

+19
-14
lines changed

2 files changed

+19
-14
lines changed

src/dotty/tools/dotc/typer/Typer.scala

Lines changed: 13 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -502,22 +502,24 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
502502
assignType(cpy.If(tree)(cond1, thenp2, elsep2), thenp2, elsep2)
503503
}
504504

505+
private def decomposeProtoFunction(pt: Type, defaultArity: Int)(implicit ctx: Context): (List[Type], Type) = pt match {
506+
case _ if defn.isFunctionType(pt) =>
507+
(pt.dealias.argInfos.init, pt.dealias.argInfos.last)
508+
case SAMType(meth) =>
509+
val mt @ MethodType(_, paramTypes) = meth.info
510+
(paramTypes, mt.resultType)
511+
case _ =>
512+
(List.range(0, defaultArity) map alwaysWildcardType, WildcardType)
513+
}
514+
505515
def typedFunction(tree: untpd.Function, pt: Type)(implicit ctx: Context) = track("typedFunction") {
506516
val untpd.Function(args, body) = tree
507517
if (ctx.mode is Mode.Type)
508518
typed(cpy.AppliedTypeTree(tree)(
509519
untpd.TypeTree(defn.FunctionClass(args.length).typeRef), args :+ body), pt)
510520
else {
511521
val params = args.asInstanceOf[List[untpd.ValDef]]
512-
val (protoFormals, protoResult): (List[Type], Type) = pt match {
513-
case _ if defn.isFunctionType(pt) =>
514-
(pt.dealias.argInfos.init, pt.dealias.argInfos.last)
515-
case SAMType(meth) =>
516-
val mt @ MethodType(_, paramTypes) = meth.info
517-
(paramTypes, mt.resultType)
518-
case _ =>
519-
(params map alwaysWildcardType, WildcardType)
520-
}
522+
val (protoFormals, protoResult) = decomposeProtoFunction(pt, params.length)
521523

522524
def refersTo(arg: untpd.Tree, param: untpd.ValDef): Boolean = arg match {
523525
case Ident(name) => name == param.name
@@ -629,11 +631,8 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
629631
def typedMatch(tree: untpd.Match, pt: Type)(implicit ctx: Context) = track("typedMatch") {
630632
tree.selector match {
631633
case EmptyTree =>
632-
val arity = pt match {
633-
case defn.FunctionType(args, _) => args.length
634-
case _ => 1
635-
}
636-
typed(desugar.makeCaseLambda(tree.cases, arity) withPos tree.pos, pt)
634+
val (protoFormals, _) = decomposeProtoFunction(pt, 1)
635+
typed(desugar.makeCaseLambda(tree.cases, protoFormals.length) withPos tree.pos, pt)
637636
case _ =>
638637
val sel1 = typedExpr(tree.selector)
639638
val selType = widenForMatchSelector(

tests/pos/i873.scala

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,10 @@
11
object Test {
22
def call(k: (Int, Int) => Unit): Unit = ???
33
def test = call({ case (x, y) => ()})
4+
5+
trait X extends Function1[Int, String]
6+
implicit def f2x(f: Function1[Int, String]): X = ???
7+
({case _ if "".isEmpty => ""} : X) // allowed, implicit view used to adapt
8+
9+
// ({case _ if "".isEmpty => 0} : X) // expected String, found Int
410
}

0 commit comments

Comments
 (0)