Skip to content

Commit 9880cea

Browse files
committed
Avoid SAM with param-dependent result crashing
1 parent 8812638 commit 9880cea

File tree

5 files changed

+40
-7
lines changed

5 files changed

+40
-7
lines changed

compiler/src/dotty/tools/dotc/core/Types.scala

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5568,6 +5568,17 @@ object Types {
55685568
else None
55695569
}
55705570
else None
5571+
5572+
object WithFunctionType:
5573+
def unapply(tp: Type)(using Context): Option[(MethodType, Type)] = tp match
5574+
case SAMType(mt) if !isParamDependentRec(mt) =>
5575+
Some((mt, mt.toFunctionType(isJava = tp.classSymbol.is(JavaDefined))))
5576+
case _ => None
5577+
5578+
private def isParamDependentRec(mt: MethodType)(using Context): Boolean =
5579+
mt.isParamDependent || mt.resultType.match
5580+
case mt: MethodType => isParamDependentRec(mt)
5581+
case _ => false
55715582
}
55725583

55735584
// ----- TypeMaps --------------------------------------------------------------------

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -696,7 +696,7 @@ trait Applications extends Compatibility {
696696

697697
def SAMargOK =
698698
defn.isFunctionType(argtpe1) && formal.match
699-
case SAMType(sam) => argtpe <:< sam.toFunctionType(isJava = formal.classSymbol.is(JavaDefined))
699+
case SAMType.WithFunctionType(_, fntpe) => argtpe <:< fntpe
700700
case _ => false
701701

702702
isCompatible(argtpe, formal)

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

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1335,10 +1335,7 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
13351335
case RefinedType(parent, nme.apply, mt @ MethodTpe(_, formals, restpe))
13361336
if (defn.isNonRefinedFunction(parent) || defn.isErasedFunctionType(parent)) && formals.length == defaultArity =>
13371337
(formals, untpd.DependentTypeTree(syms => restpe.substParams(mt, syms.map(_.termRef))))
1338-
case pt1 @ SAMType(mt @ MethodTpe(_, formals, methResType)) =>
1339-
val restpe = methResType match
1340-
case mt: MethodType if !mt.isParamDependent => mt.toFunctionType(isJava = pt1.classSymbol.is(JavaDefined))
1341-
case tp => tp
1338+
case SAMType.WithFunctionType(mt @ MethodTpe(_, formals, _), defn.FunctionOf(_, restpe, _)) =>
13421339
(formals,
13431340
if (mt.isResultDependent)
13441341
untpd.DependentTypeTree(syms => restpe.substParams(mt, syms.map(_.termRef)))
@@ -4131,8 +4128,8 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
41314128
case closure(Nil, id @ Ident(nme.ANON_FUN), _)
41324129
if defn.isFunctionType(wtp) && !defn.isFunctionType(pt) =>
41334130
pt match {
4134-
case SAMType(sam)
4135-
if wtp <:< sam.toFunctionType(isJava = pt.classSymbol.is(JavaDefined)) =>
4131+
case SAMType.WithFunctionType(_, fntpe)
4132+
if wtp <:< fntpe =>
41364133
// was ... && isFullyDefined(pt, ForceDegree.flipBottom)
41374134
// but this prevents case blocks from implementing polymorphic partial functions,
41384135
// since we do not know the result parameter a priori. Have to wait until the

tests/neg/i17183.check

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
-- [E081] Type Error: tests/neg/i17183.scala:11:24 ---------------------------------------------------------------------
2+
11 |def test = Context(f = (_, _) => ???) // error // error
3+
| ^
4+
| Missing parameter type
5+
|
6+
| I could not infer the type of the parameter _$1 of expanded function:
7+
| (_$1, _$2) => ???.
8+
-- [E081] Type Error: tests/neg/i17183.scala:11:27 ---------------------------------------------------------------------
9+
11 |def test = Context(f = (_, _) => ???) // error // error
10+
| ^
11+
| Missing parameter type
12+
|
13+
| I could not infer the type of the parameter _$2 of expanded function:
14+
| (_$1, _$2) => ???.

tests/neg/i17183.scala

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
trait Dependency {
2+
trait More
3+
}
4+
5+
trait MyFunc {
6+
def apply(a: Int, b: String)(using dep: Dependency, more: dep.More): String
7+
}
8+
9+
case class Context(f: MyFunc)
10+
11+
def test = Context(f = (_, _) => ???) // error // error

0 commit comments

Comments
 (0)