From 2ff112526c3ea669ddc717c7b90f653ff06eda64 Mon Sep 17 00:00:00 2001 From: Guillaume Martres Date: Fri, 21 Jun 2019 23:40:37 +0200 Subject: [PATCH] Fix #6725: Parsing of poly function with parenthesized body --- .../src/dotty/tools/dotc/ast/Desugar.scala | 4 ++- .../dotty/tools/dotc/parsing/Parsers.scala | 26 ++++++++++++------- tests/run/polymorphic-functions.scala | 4 +++ 3 files changed, 23 insertions(+), 11 deletions(-) diff --git a/compiler/src/dotty/tools/dotc/ast/Desugar.scala b/compiler/src/dotty/tools/dotc/ast/Desugar.scala index 6521deaa1f70..3b710ec34f5f 100644 --- a/compiler/src/dotty/tools/dotc/ast/Desugar.scala +++ b/compiler/src/dotty/tools/dotc/ast/Desugar.scala @@ -1410,7 +1410,9 @@ object desugar { } def makePolyFunction(targs: List[Tree], body: Tree): Tree = body match { - case Function(vargs, res) => + case Parens(body1) => + makePolyFunction(targs, body1) + case Function(vargs, res) => // TODO: Figure out if we need a `PolyFunctionWithMods` instead. val mods = body match { case body: FunctionWithMods => body.mods diff --git a/compiler/src/dotty/tools/dotc/parsing/Parsers.scala b/compiler/src/dotty/tools/dotc/parsing/Parsers.scala index ab8a111192f5..11bd30a35e4d 100644 --- a/compiler/src/dotty/tools/dotc/parsing/Parsers.scala +++ b/compiler/src/dotty/tools/dotc/parsing/Parsers.scala @@ -864,6 +864,12 @@ object Parsers { */ def toplevelTyp(): Tree = rejectWildcardType(typ()) + private def isFunction(tree: Tree): Boolean = tree match { + case Parens(tree1) => isFunction(tree1) + case _: Function => true + case _ => false + } + /** Type ::= FunType * | HkTypeParamClause ‘=>>’ Type * | MatchType @@ -946,11 +952,11 @@ object Parsers { val arrowOffset = in.skipToken() val body = toplevelTyp() atSpan(start, arrowOffset) { - body match { - case _: Function => PolyFunction(tparams, body) - case _ => - syntaxError("Implementation restriction: polymorphic function types must have a value parameter", arrowOffset) - Ident(nme.ERROR.toTypeName) + if (isFunction(body)) + PolyFunction(tparams, body) + else { + syntaxError("Implementation restriction: polymorphic function types must have a value parameter", arrowOffset) + Ident(nme.ERROR.toTypeName) } } } else { accept(TLARROW); typ() } @@ -1381,11 +1387,11 @@ object Parsers { val arrowOffset = accept(ARROW) val body = expr() atSpan(start, arrowOffset) { - body match { - case _: Function => PolyFunction(tparams, body) - case _ => - syntaxError("Implementation restriction: polymorphic function literals must have a value parameter", arrowOffset) - errorTermTree + if (isFunction(body)) + PolyFunction(tparams, body) + else { + syntaxError("Implementation restriction: polymorphic function literals must have a value parameter", arrowOffset) + errorTermTree } } case _ => diff --git a/tests/run/polymorphic-functions.scala b/tests/run/polymorphic-functions.scala index 5167eab1580a..6dece7392017 100644 --- a/tests/run/polymorphic-functions.scala +++ b/tests/run/polymorphic-functions.scala @@ -90,4 +90,8 @@ object Test extends App { } val s = [T] => (t: T) => given (st: Show[T]) => st.show(t) assert(s(23) == "23") + + // Parens handling + val tt1: [T] => (T => T) = [T] => (x: T) => x + val tt2: [T] => T => T = [T] => ((x: T) => x) }