Skip to content

Commit 2980c47

Browse files
smarterbishabosha
authored andcommitted
Fix typing of PartialFunction argument to overloaded method
Applications#preTypeArgs can type arguments with an expected type like `PartialFunction[Int, WildcardType]`, before this commit this was rejected by `typedClosure` because it requires the expected type to be fully-defined. Fixed by replacing the underdefined expected type by a new one where the argument types come from the closure method type. This is useful in particular to type `Map#collect` in 2.13 which is overloaded.
1 parent b72eb76 commit 2980c47

File tree

2 files changed

+14
-6
lines changed

2 files changed

+14
-6
lines changed

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

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -991,13 +991,22 @@ class Typer extends Namer
991991
pt match {
992992
case SAMType(sam)
993993
if !defn.isFunctionType(pt) && mt <:< sam =>
994-
if (!isFullyDefined(pt, ForceDegree.all))
995-
ctx.error(ex"result type of lambda is an underspecified SAM type $pt", tree.sourcePos)
996-
else if (pt.classSymbol.isOneOf(FinalOrSealed)) {
994+
val targetTpe =
995+
if (!isFullyDefined(pt, ForceDegree.all)) {
996+
if (pt.isRef(defn.PartialFunctionClass))
997+
// Replace the underspecified expected type by one based on the closure method type
998+
defn.PartialFunctionOf(mt.firstParamTypes.head, mt.resultType)
999+
else {
1000+
ctx.error(ex"result type of lambda is an underspecified SAM type $pt", tree.sourcePos)
1001+
pt
1002+
}
1003+
}
1004+
else pt
1005+
if (pt.classSymbol.isOneOf(FinalOrSealed)) {
9971006
val offendingFlag = pt.classSymbol.flags & FinalOrSealed
9981007
ctx.error(ex"lambda cannot implement $offendingFlag ${pt.classSymbol}", tree.sourcePos)
9991008
}
1000-
TypeTree(pt)
1009+
TypeTree(targetTpe)
10011010
case _ =>
10021011
if (mt.isParamDependent) {
10031012
throw new java.lang.Error(

compiler/test/dotty/tools/repl/ReplCompilerTests.scala

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -115,10 +115,9 @@ class ReplCompilerTests extends ReplTest {
115115
}
116116

117117
@Test def i4051 = fromInitialState { implicit state =>
118-
// FIXME: shouldn't have to pass a type parameter to collect.
119118
val source =
120119
"""val x: PartialFunction[Int, Int] = { case x => x }
121-
|val y = Map(("A", 1), ("B", 2), ("X", 3)).collect[Int] { case (k, v) => v }.toList""".stripMargin
120+
|val y = Map(("A", 1), ("B", 2), ("X", 3)).collect { case (k, v) => v }.toList""".stripMargin
122121

123122
val expected = List(
124123
"val x: PartialFunction[Int, Int] = <function1>",

0 commit comments

Comments
 (0)