From 901479c0f624e56d14702e4fd4493ef98ee7901c Mon Sep 17 00:00:00 2001 From: odersky Date: Mon, 25 Jul 2022 14:35:43 +0200 Subject: [PATCH 1/2] Implementation restriction: No partial functions with CFT results Fixes #15741 I tried for a while to make this work, but it is just too gnarly. --- .../dotty/tools/dotc/transform/ExpandSAMs.scala | 9 +++++++++ tests/neg/i15741.scala | 15 +++++++++++++++ 2 files changed, 24 insertions(+) create mode 100644 tests/neg/i15741.scala diff --git a/compiler/src/dotty/tools/dotc/transform/ExpandSAMs.scala b/compiler/src/dotty/tools/dotc/transform/ExpandSAMs.scala index ac29275b2210..c3311d6495c9 100644 --- a/compiler/src/dotty/tools/dotc/transform/ExpandSAMs.scala +++ b/compiler/src/dotty/tools/dotc/transform/ExpandSAMs.scala @@ -66,6 +66,13 @@ class ExpandSAMs extends MiniPhase: tree } + private def checkNoContextFunction(tpt: Tree)(using Context): Unit = + if defn.isContextFunctionType(tpt.tpe) then + report.error( + em"""Implementation restriction: cannot convert this expression to + |partial function with context function result type $tpt""", + tpt.srcPos) + /** A partial function literal: * * ``` @@ -108,6 +115,8 @@ class ExpandSAMs extends MiniPhase: private def toPartialFunction(tree: Block, tpe: Type)(using Context): Tree = { val closureDef(anon @ DefDef(_, List(List(param)), _, _)) = tree: @unchecked + checkNoContextFunction(anon.tpt) + // The right hand side from which to construct the partial function. This is always a Match. // If the original rhs is already a Match (possibly in braces), return that. // Otherwise construct a match `x match case _ => rhs` where `x` is the parameter of the closure. diff --git a/tests/neg/i15741.scala b/tests/neg/i15741.scala new file mode 100644 index 000000000000..45d6c3bed16d --- /dev/null +++ b/tests/neg/i15741.scala @@ -0,0 +1,15 @@ + def get(using Int): String = summon[Int].toString + + def pf2: PartialFunction[String, Int ?=> String] = { // error + case "hoge" => get + case "huga" => get + } + + type IS = Int ?=> String + + def pf3: PartialFunction[String, IS] = { // error + case "hoge" => get + case "huga" => get + } + + From 7996022a6b4b3ce6a7f4ca7f994a311dbc16405a Mon Sep 17 00:00:00 2001 From: odersky Date: Mon, 25 Jul 2022 16:07:32 +0200 Subject: [PATCH 2/2] Fix test --- tests/neg/i15741.scala | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/neg/i15741.scala b/tests/neg/i15741.scala index 45d6c3bed16d..b5304f83d8b3 100644 --- a/tests/neg/i15741.scala +++ b/tests/neg/i15741.scala @@ -1,14 +1,14 @@ def get(using Int): String = summon[Int].toString - def pf2: PartialFunction[String, Int ?=> String] = { // error - case "hoge" => get + def pf2: PartialFunction[String, Int ?=> String] = { + case "hoge" => get // error case "huga" => get } type IS = Int ?=> String - def pf3: PartialFunction[String, IS] = { // error - case "hoge" => get + def pf3: PartialFunction[String, IS] = { + case "hoge" => get // error case "huga" => get }