Skip to content

Commit fef1110

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 66b6dff commit fef1110

File tree

5 files changed

+11
-15
lines changed

5 files changed

+11
-15
lines changed

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1504,7 +1504,7 @@ object desugar {
15041504
DefDef(nme.ANON_FUN, paramss, if (tpt == null) TypeTree() else tpt, body)
15051505
.withSpan(span)
15061506
.withMods(synthetic | Artifact),
1507-
Closure(Nil, Ident(nme.ANON_FUN), EmptyTree))
1507+
Closure(Nil, Ident(nme.ANON_FUN), EmptyTree).withSpan(span.toSynthetic))
15081508

15091509
/** If `nparams` == 1, expand partial function
15101510
*

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

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5552,8 +5552,7 @@ object Types {
55525552
if (absMems.size == 1)
55535553
absMems.head.info match {
55545554
case mt: MethodType if !mt.isParamDependent &&
5555-
mt.resultType.isValueTypeOrWildcard &&
5556-
!defn.isContextFunctionType(mt.resultType) =>
5555+
mt.resultType.isValueTypeOrWildcard =>
55575556
val cls = tp.classSymbol
55585557

55595558
// 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
@@ -1686,6 +1686,12 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
16861686
pt.findFunctionType match {
16871687
case pt @ SAMType(sam)
16881688
if !defn.isFunctionType(pt) && mt <:< sam =>
1689+
if defn.isContextFunctionType(mt.resultType) then
1690+
report.error(
1691+
em"""Implementation restriction: cannot convert this expression to `$pt`
1692+
|because its result type `${mt.resultType}` is a contextual function type.""",
1693+
tree.srcPos)
1694+
16891695
// SAMs of the form C[?] where C is a class cannot be conversion targets.
16901696
// The resulting class `class $anon extends C[?] {...}` would be illegal,
16911697
// since type arguments to `C`'s super constructor cannot be constructed.

tests/neg/i15741.scala

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

3-
def pf2: PartialFunction[String, Int ?=> String] = {
4-
case "hoge" => get // error
3+
def pf2: PartialFunction[String, Int ?=> String] = { // error
4+
case "hoge" => get
55
case "huga" => get
66
}
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
1313
}
1414

0 commit comments

Comments
 (0)