Skip to content

Commit 4290946

Browse files
committed
Refine condition when to generate a partial function
A partial function should be generated if - the argument is a Match - at least one formal is a partial function.
1 parent 5f73f6b commit 4290946

File tree

2 files changed

+16
-8
lines changed

2 files changed

+16
-8
lines changed

compiler/src/dotty/tools/dotc/ast/TreeInfo.scala

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -273,19 +273,24 @@ trait UntypedTreeInfo extends TreeInfo[Untyped] { self: Trees.Instance[Untyped]
273273
case _ => false
274274
}
275275

276-
def isFunctionWithUnknownParamType(tree: Tree): Boolean = tree match {
276+
def functionWithUnknownParamType(tree: Tree): Option[Tree] = tree match {
277277
case Function(args, _) =>
278-
args.exists {
278+
if (args.exists {
279279
case ValDef(_, tpt, _) => tpt.isEmpty
280280
case _ => false
281-
}
281+
}) Some(tree)
282+
else None
282283
case Match(EmptyTree, _) =>
283-
true
284+
Some(tree)
284285
case Block(Nil, expr) =>
285-
isFunctionWithUnknownParamType(expr)
286-
case _ => false
286+
functionWithUnknownParamType(expr)
287+
case _ =>
288+
None
287289
}
288290

291+
def isFunctionWithUnknownParamType(tree: Tree): Boolean =
292+
functionWithUnknownParamType(tree).isDefined
293+
289294
/** Is `tree` an implicit function or closure, possibly nested in a block? */
290295
def isImplicitClosure(tree: Tree)(implicit ctx: Context): Boolean = unsplice(tree) match {
291296
case Function((param: untpd.ValDef) :: _, _) => param.mods.is(Implicit)

compiler/src/dotty/tools/dotc/typer/Applications.scala

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1402,7 +1402,8 @@ trait Applications extends Compatibility { self: Typer with Dynamic =>
14021402
case ValDef(_, tpt, _) => tpt.isEmpty
14031403
case _ => false
14041404
}
1405-
if (untpd.isFunctionWithUnknownParamType(arg)) {
1405+
val fn = untpd.functionWithUnknownParamType(arg)
1406+
if (fn.isDefined) {
14061407
def isUniform[T](xs: List[T])(p: (T, T) => Boolean) = xs.forall(p(_, xs.head))
14071408
val formalsForArg: List[Type] = altFormals.map(_.head)
14081409
def argTypesOfFormal(formal: Type): List[Type] =
@@ -1422,7 +1423,9 @@ trait Applications extends Compatibility { self: Typer with Dynamic =>
14221423
// type of the i'th parameter of the closure.
14231424
if (isUniform(ps)(ctx.typeComparer.isSameTypeWhenFrozen(_, _))) ps.head
14241425
else WildcardType)
1425-
def isPartial = formalsForArg.forall(_.isRef(defn.PartialFunctionClass))
1426+
def isPartial = // we should generate a partial function for the arg
1427+
fn.get.isInstanceOf[untpd.Match] &&
1428+
formalsForArg.exists(_.isRef(defn.PartialFunctionClass))
14261429
val commonFormal =
14271430
if (isPartial) defn.PartialFunctionOf(commonParamTypes.head, newTypeVar(TypeBounds.empty))
14281431
else defn.FunctionOf(commonParamTypes, WildcardType)

0 commit comments

Comments
 (0)