From c83ff66d9510bf16a701b81b12ec08fd02a778e9 Mon Sep 17 00:00:00 2001 From: Kacper Korban Date: Mon, 30 Sep 2024 10:13:46 +0200 Subject: [PATCH] fix: Check if a PolyFunction TypeTree has no ByName parameters --- .../dotty/tools/dotc/reporting/messages.scala | 5 ++--- .../src/dotty/tools/dotc/typer/Typer.scala | 19 +++++++++++++++++-- tests/neg/21538.check | 4 ++-- tests/neg/i21652.check | 4 ++++ tests/neg/i21652.scala | 2 ++ 5 files changed, 27 insertions(+), 7 deletions(-) create mode 100644 tests/neg/i21652.check create mode 100644 tests/neg/i21652.scala diff --git a/compiler/src/dotty/tools/dotc/reporting/messages.scala b/compiler/src/dotty/tools/dotc/reporting/messages.scala index cb730efbfe89..d65f9a9857e2 100644 --- a/compiler/src/dotty/tools/dotc/reporting/messages.scala +++ b/compiler/src/dotty/tools/dotc/reporting/messages.scala @@ -1829,12 +1829,11 @@ class NotAPath(tp: Type, usage: String)(using Context) extends TypeMsg(NotAPathI if sym.isAllOf(Flags.InlineParam) then i""" |Inline parameters are not considered immutable paths and cannot be used as - |singleton types. - | + |singleton types. + | |Hint: Removing the `inline` qualifier from the `${sym.name}` parameter |may help resolve this issue.""" else "" - class WrongNumberOfParameters(tree: untpd.Tree, foundCount: Int, pt: Type, expectedCount: Int)(using Context) extends SyntaxMsg(WrongNumberOfParametersID) { diff --git a/compiler/src/dotty/tools/dotc/typer/Typer.scala b/compiler/src/dotty/tools/dotc/typer/Typer.scala index 159ce8354a30..2900a702a5d5 100644 --- a/compiler/src/dotty/tools/dotc/typer/Typer.scala +++ b/compiler/src/dotty/tools/dotc/typer/Typer.scala @@ -1914,11 +1914,26 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer .showing(i"desugared fun $tree --> $desugared with pt = $pt", typr) } + /** Check that the PolyFunction doesn't have by-name parameters. + * Return the unchanged tree if it's valid, or EmptyTree otherwise. + */ + private def checkPolyTypeTree(tree: untpd.Tree)(using Context): untpd.Tree = + val untpd.PolyFunction(tparams: List[untpd.TypeDef] @unchecked, fun @ untpd.Function(vparamTypes, res)) = tree: @unchecked + var tree1 = tree + vparamTypes.foreach: + case t: ByNameTypeTree => + report.error("By-name parameters are not supported in Polymorphic Functions", t.srcPos) + tree1 = untpd.EmptyTree + case _ => + tree1 def typedPolyFunction(tree: untpd.PolyFunction, pt: Type)(using Context): Tree = val tree1 = desugar.normalizePolyFunction(tree) - if (ctx.mode is Mode.Type) typed(desugar.makePolyFunctionType(tree1), pt) - else typedPolyFunctionValue(tree1, pt) + checkPolyTypeTree(tree1) match + case tree2: untpd.PolyFunction => + if (ctx.mode is Mode.Type) typed(desugar.makePolyFunctionType(tree2), pt) + else typedPolyFunctionValue(tree2, pt) + case untpd.EmptyTree => TypeTree(NoType) def typedPolyFunctionValue(tree: untpd.PolyFunction, pt: Type)(using Context): Tree = val untpd.PolyFunction(tparams: List[untpd.TypeDef] @unchecked, fun) = tree: @unchecked diff --git a/tests/neg/21538.check b/tests/neg/21538.check index 0e799bef3611..e0bcb43f9356 100644 --- a/tests/neg/21538.check +++ b/tests/neg/21538.check @@ -3,8 +3,8 @@ | ^^^^^^^^^^ | (value : V) is not a valid singleton type, since it is not an immutable path | Inline parameters are not considered immutable paths and cannot be used as - | singleton types. - | + | singleton types. + | | Hint: Removing the `inline` qualifier from the `value` parameter | may help resolve this issue. | diff --git a/tests/neg/i21652.check b/tests/neg/i21652.check new file mode 100644 index 000000000000..14ca8e2dc9db --- /dev/null +++ b/tests/neg/i21652.check @@ -0,0 +1,4 @@ +-- Error: tests/neg/i21652.scala:1:15 ---------------------------------------------------------------------------------- +1 |def k: [A] => (=> A) => A = // error + | ^^^^ + | By-name parameters are not supported in Polymorphic Functions diff --git a/tests/neg/i21652.scala b/tests/neg/i21652.scala new file mode 100644 index 000000000000..a49d7f0eb1ce --- /dev/null +++ b/tests/neg/i21652.scala @@ -0,0 +1,2 @@ +def k: [A] => (=> A) => A = // error + [A] => a => a