Skip to content

Commit 18f90d9

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).
1 parent ca29cdc commit 18f90d9

File tree

4 files changed

+11
-15
lines changed

4 files changed

+11
-15
lines changed

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

+1-2
Original file line numberDiff line numberDiff line change
@@ -5567,8 +5567,7 @@ object Types {
55675567
if (absMems.size == 1)
55685568
absMems.head.info match {
55695569
case mt: MethodType if !mt.isParamDependent &&
5570-
mt.resultType.isValueTypeOrWildcard &&
5571-
!defn.isContextFunctionType(mt.resultType) =>
5570+
mt.resultType.isValueTypeOrWildcard =>
55725571
val cls = tp.classSymbol
55735572

55745573
// Given a SAM type such as:

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

-9
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

+6
Original file line numberDiff line numberDiff line change
@@ -1688,6 +1688,12 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
16881688
pt.findFunctionType match {
16891689
case pt @ SAMType(sam)
16901690
if !defn.isFunctionNType(pt) && mt <:< sam =>
1691+
if defn.isContextFunctionType(mt.resultType) then
1692+
report.error(
1693+
em"""Implementation restriction: cannot convert this expression to `$pt`
1694+
|because its result type `${mt.resultType}` is a contextual function type.""",
1695+
tree.srcPos)
1696+
16911697
// SAMs of the form C[?] where C is a class cannot be conversion targets.
16921698
// The resulting class `class $anon extends C[?] {...}` would be illegal,
16931699
// since type arguments to `C`'s super constructor cannot be constructed.

tests/neg/i15741.scala

+4-4
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)