Skip to content

Commit f68b617

Browse files
committed
Refactor detection of illegal result types in SAMs
Previously there were two separate checks for contextual function types as result types: one in SAMType for non-PartialFunctions and one in ExpandSAM for PartialFunctions. This is replaced by a single check (with a detailed error message like we already had for PartialFunctions). [Cherry-picked 18f90d9][modified]
1 parent bfe8fab commit f68b617

File tree

4 files changed

+11
-14
lines changed

4 files changed

+11
-14
lines changed

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5544,7 +5544,7 @@ object Types {
55445544
if (absMems.size == 1)
55455545
absMems.head.info match {
55465546
case mt: MethodType if !mt.isParamDependent &&
5547-
!defn.isContextFunctionType(mt.resultType) =>
5547+
mt.resultType.isValueTypeOrWildcard =>
55485548
val cls = tp.classSymbol
55495549

55505550
// Given a SAM type such as:

compiler/src/dotty/tools/dotc/transform/ExpandSAMs.scala

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -66,13 +66,6 @@ class ExpandSAMs extends MiniPhase:
6666
tree
6767
}
6868

69-
private def checkNoContextFunction(tpt: Tree)(using Context): Unit =
70-
if defn.isContextFunctionType(tpt.tpe) then
71-
report.error(
72-
em"""Implementation restriction: cannot convert this expression to
73-
|partial function with context function result type $tpt""",
74-
tpt.srcPos)
75-
7669
/** A partial function literal:
7770
*
7871
* ```
@@ -115,8 +108,6 @@ class ExpandSAMs extends MiniPhase:
115108
private def toPartialFunction(tree: Block, tpe: Type)(using Context): Tree = {
116109
val closureDef(anon @ DefDef(_, List(List(param)), _, _)) = tree: @unchecked
117110

118-
checkNoContextFunction(anon.tpt)
119-
120111
// The right hand side from which to construct the partial function. This is always a Match.
121112
// If the original rhs is already a Match (possibly in braces), return that.
122113
// Otherwise construct a match `x match case _ => rhs` where `x` is the parameter of the closure.

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1638,6 +1638,12 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
16381638
pt.findFunctionType match {
16391639
case pt @ SAMType(sam)
16401640
if !defn.isFunctionNType(pt) && mt <:< sam =>
1641+
if defn.isContextFunctionType(mt.resultType) then
1642+
report.error(
1643+
em"""Implementation restriction: cannot convert this expression to `$pt`
1644+
|because its result type `${mt.resultType}` is a contextual function type.""",
1645+
tree.srcPos)
1646+
16411647
// SAMs of the form C[?] where C is a class cannot be conversion targets.
16421648
// The resulting class `class $anon extends C[?] {...}` would be illegal,
16431649
// since type arguments to `C`'s super constructor cannot be constructed.

tests/neg/i15741.scala

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
11
def get(using Int): String = summon[Int].toString
22

33
def pf2: PartialFunction[String, Int ?=> String] = {
4-
case "hoge" => get // error
4+
case "hoge" => get
55
case "huga" => get
6-
}
6+
} // error
77

88
type IS = Int ?=> String
99

1010
def pf3: PartialFunction[String, IS] = {
11-
case "hoge" => get // error
11+
case "hoge" => get
1212
case "huga" => get
13-
}
13+
} // error
1414

1515

0 commit comments

Comments
 (0)