From 783f5e778b66554ed8de32d8b06fc2fa2b3a2e62 Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Wed, 25 Nov 2020 09:53:21 +0100 Subject: [PATCH 1/5] Switch back to ?=> for context function closures The old syntax was awkward since everywhere else after a `using` it's the _name of the paramater_ that's optional, not the type. --- .../dotty/tools/dotc/parsing/Parsers.scala | 27 ++++++------ .../contextual/context-functions-spec.md | 4 +- .../reference/contextual/context-functions.md | 16 +++---- .../src/scala/quoted/staging/staging.scala | 4 +- .../tupled-function-extension-method.scala | 8 ++-- tests/neg/i2514a.scala | 5 +-- tests/pos/i6862/lib_1.scala | 2 +- .../lambda-serialization-others.scala | 6 +-- .../quote-function-applied-to.scala | 44 +++++++++---------- tests/run-staging/quote-nested-2.scala | 2 +- tests/run-staging/quote-nested-5.scala | 4 +- tests/run/implicitFunctionXXL.scala | 4 +- 12 files changed, 63 insertions(+), 63 deletions(-) diff --git a/compiler/src/dotty/tools/dotc/parsing/Parsers.scala b/compiler/src/dotty/tools/dotc/parsing/Parsers.scala index bb96c372f909..49f53fa7cf22 100644 --- a/compiler/src/dotty/tools/dotc/parsing/Parsers.scala +++ b/compiler/src/dotty/tools/dotc/parsing/Parsers.scala @@ -443,11 +443,11 @@ object Parsers { /** Convert tree to formal parameter list */ - def convertToParams(tree: Tree): List[ValDef] = tree match { + def convertToParams(tree: Tree, mods: Modifiers): List[ValDef] = tree match { case Parens(t) => - convertToParam(t) :: Nil + convertToParam(t, mods) :: Nil case Tuple(ts) => - ts.map(convertToParam(_)) + ts.map(convertToParam(_, mods)) case t: Typed => report.errorOrMigrationWarning( em"parentheses are required around the parameter of a lambda${rewriteNotice()}", @@ -455,23 +455,23 @@ object Parsers { if migrateTo3 then patch(source, t.span.startPos, "(") patch(source, t.span.endPos, ")") - convertToParam(t) :: Nil + convertToParam(t, mods) :: Nil case t => - convertToParam(t) :: Nil + convertToParam(t, mods) :: Nil } /** Convert tree to formal parameter */ - def convertToParam(tree: Tree, expected: String = "formal parameter"): ValDef = tree match { + def convertToParam(tree: Tree, mods: Modifiers, expected: String = "formal parameter"): ValDef = tree match { case id @ Ident(name) => - makeParameter(name.asTermName, TypeTree(), EmptyModifiers, isBackquoted = isBackquoted(id)).withSpan(tree.span) + makeParameter(name.asTermName, TypeTree(), mods, isBackquoted = isBackquoted(id)).withSpan(tree.span) case Typed(id @ Ident(name), tpt) => - makeParameter(name.asTermName, tpt, EmptyModifiers, isBackquoted = isBackquoted(id)).withSpan(tree.span) + makeParameter(name.asTermName, tpt, mods, isBackquoted = isBackquoted(id)).withSpan(tree.span) case Typed(Splice(Ident(name)), tpt) => - makeParameter(("$" + name).toTermName, tpt, EmptyModifiers).withSpan(tree.span) + makeParameter(("$" + name).toTermName, tpt, mods).withSpan(tree.span) case _ => syntaxError(s"not a legal $expected", tree.span) - makeParameter(nme.ERROR, tree, EmptyModifiers) + makeParameter(nme.ERROR, tree, mods) } /** Convert (qual)ident to type identifier @@ -1920,9 +1920,10 @@ object Parsers { finally placeholderParams = saved val t = expr1(location) - if (in.token == ARROW) { + if (in.token == ARROW || in.token == CTXARROW) { placeholderParams = Nil // don't interpret `_' to the left of `=>` as placeholder - wrapPlaceholders(closureRest(start, location, convertToParams(t))) + val paramMods = if in.token == CTXARROW then Modifiers(Given) else EmptyModifiers + wrapPlaceholders(closureRest(start, location, convertToParams(t, paramMods))) } else if (isWildcard(t)) { placeholderParams = placeholderParams ::: saved @@ -2124,7 +2125,7 @@ object Parsers { /** FunParams ::= Bindings * | id * | `_' - * Bindings ::= `(' [[‘using’] [‘erased’] Binding {`,' Binding}] `)' + * Bindings ::= `(' [[‘erased’] Binding {`,' Binding}] `)' */ def funParams(mods: Modifiers, location: Location): List[Tree] = if in.token == LPAREN then diff --git a/docs/docs/reference/contextual/context-functions-spec.md b/docs/docs/reference/contextual/context-functions-spec.md index 39006116907c..fa5156bc4baf 100644 --- a/docs/docs/reference/contextual/context-functions-spec.md +++ b/docs/docs/reference/contextual/context-functions-spec.md @@ -28,7 +28,7 @@ trait ContextFunctionN[-T1 , ... , -TN, +R] { Context function types erase to normal function types, so these classes are generated on the fly for typechecking, but not realized in actual code. -Context function literals `(using x1: T1, ..., xn: Tn) => e` map +Context function literals `(x1: T1, ..., xn: Tn) ?=> e` map context parameters `xi` of types `Ti` to the result of evaluating the expression `e`. The scope of each context parameter `xi` is `e`. The parameters must have pairwise distinct names. @@ -54,7 +54,7 @@ Note: The closing paragraph of the [Anonymous Functions section](https://www.scala-lang.org/files/archive/spec/2.12/06-expressions.html#anonymous-functions) of Scala 2.12 is subsumed by context function types and should be removed. -Context function literals `(using x1: T1, ..., xn: Tn) => e` are +Context function literals `(x1: T1, ..., xn: Tn) ?=> e` are automatically created for any expression `e` whose expected type is `scala.ContextFunctionN[T1, ..., Tn, R]`, unless `e` is itself a context function literal. This is analogous to the automatic diff --git a/docs/docs/reference/contextual/context-functions.md b/docs/docs/reference/contextual/context-functions.md index 21e2dcf39fa3..279d2ad13356 100644 --- a/docs/docs/reference/contextual/context-functions.md +++ b/docs/docs/reference/contextual/context-functions.md @@ -27,7 +27,7 @@ Conversely, if the expected type of an expression `E` is a context function type `(T_1, ..., T_n) ?=> U` and `E` is not already an context function literal, `E` is converted to a context function literal by rewriting it to ```scala - (using x_1: T1, ..., x_n: Tn) => E + (x_1: T1, ..., x_n: Tn) ?=> E ``` where the names `x_1`, ..., `x_n` are arbitrary. This expansion is performed before the expression `E` is typechecked, which means that `x_1`, ..., `x_n` @@ -39,12 +39,12 @@ For example, continuing with the previous definitions, ```scala def g(arg: Executable[Int]) = ... - g(22) // is expanded to g((using ev: ExecutionContext) => 22) + g(22) // is expanded to g((ev: ExecutionContext) ?=> 22) - g(f(2)) // is expanded to g((using ev: ExecutionContext) => f(2)(using ev)) + g(f(2)) // is expanded to g((ev: ExecutionContext) ?=> f(2)(using ev)) - g(ExecutionContext ?=> f(3)) // is expanded to g((using ev: ExecutionContext) => f(3)(using ev)) - g((using ctx: ExecutionContext) => f(22)(using ctx)) // is left as it is + g((ctx: ExecutionContext) ?=> f(3)) // is expanded to g((ctx: ExecutionContext) ?=> f(3)(using ctx)) + g((ctx: ExecutionContext) ?=> f(3)(using ctx)) // is left as it is ``` ### Example: Builder Pattern @@ -102,14 +102,14 @@ that would otherwise be necessary. ``` With that setup, the table construction code above compiles and expands to: ```scala - table { (using $t: Table) => + table { ($t: Table) ?=> - row { (using $r: Row) => + row { ($r: Row) ?=> cell("top left")(using $r) cell("top right")(using $r) }(using $t) - row { (using $r: Row) => + row { ($r: Row) ?=> cell("bottom left")(using $r) cell("bottom right")(using $r) }(using $t) diff --git a/staging/src/scala/quoted/staging/staging.scala b/staging/src/scala/quoted/staging/staging.scala index ef3bcc832397..6af9184170f3 100644 --- a/staging/src/scala/quoted/staging/staging.scala +++ b/staging/src/scala/quoted/staging/staging.scala @@ -7,7 +7,7 @@ package object staging: * * Usage: * ``` - * val e: T = run { // (using Quotes) => + * val e: T = run { // (quotes: Quotes) ?=> * expr * } * ``` @@ -23,7 +23,7 @@ package object staging: * * Usage: * ``` - * val e: T = withQuotes { // (using Quotes) => + * val e: T = withQuotes { // (quotes: Quotes) ?=> * thunk * } * ``` diff --git a/tests/disabled/run/tupled-function-extension-method.scala b/tests/disabled/run/tupled-function-extension-method.scala index fc4f8191b644..751b05027c1e 100644 --- a/tests/disabled/run/tupled-function-extension-method.scala +++ b/tests/disabled/run/tupled-function-extension-method.scala @@ -17,11 +17,11 @@ object Test { println(f3(1, 2, 3)) println(f25(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25)) - val if1 = new Expr((using i: Int) => Tuple1(i)) - val if2 = new Expr((using i: Int, j: Int) => (i, i + j)) - val if3 = new Expr((using i: Int, j: Int, k: Int) => (i, i + j, i + j + k)) + val if1 = new Expr((i: Int) ?=> Tuple1(i)) + val if2 = new Expr((i: Int, j: Int) ?=> (i, i + j)) + val if3 = new Expr((i: Int, j: Int, k: Int) ?=> (i, i + j, i + j + k)) val if25 = new Expr( - (using x1: Int, x2: Int, x3: Int, x4: Int, x5: Int, x6: Int, x7: Int, x8: Int, x9: Int, x10: Int, x11: Int, x12: Int, x13: Int, x14: Int, x15: Int, x16: Int, x17: Int, x18: Int, x19: Int, x20: Int, x21: Int, x22: Int, x23: Int, x24: Int, x25: Int) => + (x1: Int, x2: Int, x3: Int, x4: Int, x5: Int, x6: Int, x7: Int, x8: Int, x9: Int, x10: Int, x11: Int, x12: Int, x13: Int, x14: Int, x15: Int, x16: Int, x17: Int, x18: Int, x19: Int, x20: Int, x21: Int, x22: Int, x23: Int, x24: Int, x25: Int) ?=> (x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18, x19, x20, x21, x22, x23, x24, x25) ) diff --git a/tests/neg/i2514a.scala b/tests/neg/i2514a.scala index bf96ce275405..5b88b22d9aba 100644 --- a/tests/neg/i2514a.scala +++ b/tests/neg/i2514a.scala @@ -1,11 +1,10 @@ object Foo { def foo(): Int = { - val f: Int ?=> Int = (using x: Int) => 2 * x + val f: Int ?=> Int = (x: Int) ?=> 2 * x f(using 2) } val f = implicit (x: Int) => x - ((using x: Int) => x): (Int ?=> Int) // error: no implicit argument found + ((x: Int) ?=> x): (Int ?=> Int) // error: no implicit argument found } - diff --git a/tests/pos/i6862/lib_1.scala b/tests/pos/i6862/lib_1.scala index fd90c74857fa..e00546a3163b 100644 --- a/tests/pos/i6862/lib_1.scala +++ b/tests/pos/i6862/lib_1.scala @@ -1,3 +1,3 @@ trait Ctx -inline def foo(): Unit = (using x: Ctx) => () +inline def foo(): Unit = (x: Ctx) ?=> () def bar[T](b: Ctx ?=> Unit): Unit = ??? diff --git a/tests/run-custom-args/lambda-serialization-others.scala b/tests/run-custom-args/lambda-serialization-others.scala index 1379a3b627de..59a9612010f6 100644 --- a/tests/run-custom-args/lambda-serialization-others.scala +++ b/tests/run-custom-args/lambda-serialization-others.scala @@ -36,11 +36,11 @@ class C1 { class C2 extends Serializable /* Needed because of #5866 */ { - val impfun: Int ?=> Int = (using x1) => x1 + val impfun: Int ?=> Int = x1 ?=> x1 - val impdepfun: (x1: Int) ?=> List[x1.type] = (using x1) => List(x1) + val impdepfun: (x1: Int) ?=> List[x1.type] = x1 ?=> List(x1) - val erasedimpfun: (erased Int) ?=> Int = (using erased x1) => 0 + val erasedimpfun: (erased Int) ?=> Int = (erased x1) ?=> 0 } object Test { diff --git a/tests/run-staging/quote-function-applied-to.scala b/tests/run-staging/quote-function-applied-to.scala index 805294c4e17c..839698fac195 100644 --- a/tests/run-staging/quote-function-applied-to.scala +++ b/tests/run-staging/quote-function-applied-to.scala @@ -29,28 +29,28 @@ object Test { println(show(Expr.betaReduce('{ ((x1: Int, x2: Int, x3: Int, x4: Int, x5: Int, x6: Int, x7: Int, x8: Int, x9: Int, x10: Int, x11: Int, x12: Int, x13: Int, x14: Int, x15: Int, x16: Int, x17: Int, x18: Int, x19: Int, x20: Int, x21: Int) => x1 + x2 + x3 + x4 + x5 + x6 + x7 + x8 + x9 + x10 + x11 + x12 + x13 + x14 + x15 + x16 + x17 + x18 + x19 + x20 + x21)(x(1), x(2), x(3), x(4), x(5), x(6), x(7), x(8), x(9), x(10), x(11), x(12), x(13), x(14), x(15), x(16), x(17), x(18), x(19), x(20), x(21)) }))) println(show(Expr.betaReduce('{ ((x1: Int, x2: Int, x3: Int, x4: Int, x5: Int, x6: Int, x7: Int, x8: Int, x9: Int, x10: Int, x11: Int, x12: Int, x13: Int, x14: Int, x15: Int, x16: Int, x17: Int, x18: Int, x19: Int, x20: Int, x21: Int, x22: Int) => x1 + x2 + x3 + x4 + x5 + x6 + x7 + x8 + x9 + x10 + x11 + x12 + x13 + x14 + x15 + x16 + x17 + x18 + x19 + x20 + x21 + x22)(x(1), x(2), x(3), x(4), x(5), x(6), x(7), x(8), x(9), x(10), x(11), x(12), x(13), x(14), x(15), x(16), x(17), x(18), x(19), x(20), x(21), x(22)) }))) - println(show(Expr.betaReduce('{ ((using x1: Int) => x1)(using x(1)) }))) - println(show(Expr.betaReduce('{ ((using x1: Int, x2: Int) => x1 + x2)(using x(1), x(2)) }))) - println(show(Expr.betaReduce('{ ((using x1: Int, x2: Int, x3: Int) => x1 + x2 + x3)(using x(1), x(2), x(3)) }))) - println(show(Expr.betaReduce('{ ((using x1: Int, x2: Int, x3: Int, x4: Int) => x1 + x2 + x3 + x4)(using x(1) , x(2), x(3), x(4)) }))) - println(show(Expr.betaReduce('{ ((using x1: Int, x2: Int, x3: Int, x4: Int, x5: Int) => x1 + x2 + x3 + x4 + x5)(using x(1) , x(2), x(3), x(4), x(5)) }))) - println(show(Expr.betaReduce('{ ((using x1: Int, x2: Int, x3: Int, x4: Int, x5: Int, x6: Int) => x1 + x2 + x3 + x4 + x5 + x6)(using x(1) , x(2), x(3), x(4), x(5), x(6)) }))) - println(show(Expr.betaReduce('{ ((using x1: Int, x2: Int, x3: Int, x4: Int, x5: Int, x6: Int, x7: Int) => x1 + x2 + x3 + x4 + x5 + x6 + x7)(using x(1) , x(2), x(3), x(4), x(5), x(6), x(7)) }))) - println(show(Expr.betaReduce('{ ((using x1: Int, x2: Int, x3: Int, x4: Int, x5: Int, x6: Int, x7: Int, x8: Int) => x1 + x2 + x3 + x4 + x5 + x6 + x7 + x8)(using x(1) , x(2), x(3), x(4), x(5), x(6), x(7), x(8)) }))) - println(show(Expr.betaReduce('{ ((using x1: Int, x2: Int, x3: Int, x4: Int, x5: Int, x6: Int, x7: Int, x8: Int, x9: Int) => x1 + x2 + x3 + x4 + x5 + x6 + x7 + x8 + x9)(using x(1) , x(2), x(3), x(4), x(5), x(6), x(7), x(8), x(9)) }))) - println(show(Expr.betaReduce('{ ((using x1: Int, x2: Int, x3: Int, x4: Int, x5: Int, x6: Int, x7: Int, x8: Int, x9: Int, x10: Int) => x1 + x2 + x3 + x4 + x5 + x6 + x7 + x8 + x9 + x10)(using x(1) , x(2), x(3), x(4), x(5), x(6), x(7), x(8), x(9), x(10)) }))) - println(show(Expr.betaReduce('{ ((using x1: Int, x2: Int, x3: Int, x4: Int, x5: Int, x6: Int, x7: Int, x8: Int, x9: Int, x10: Int, x11: Int) => x1 + x2 + x3 + x4 + x5 + x6 + x7 + x8 + x9 + x10 + x11)(using x(1) , x(2), x(3), x(4), x(5), x(6), x(7), x(8), x(9), x(10), x(11)) }))) - println(show(Expr.betaReduce('{ ((using x1: Int, x2: Int, x3: Int, x4: Int, x5: Int, x6: Int, x7: Int, x8: Int, x9: Int, x10: Int, x11: Int, x12: Int) => x1 + x2 + x3 + x4 + x5 + x6 + x7 + x8 + x9 + x10 + x11 + x12)(using x(1) , x(2), x(3), x(4), x(5), x(6), x(7), x(8), x(9), x(10), x(11), x(12)) }))) - println(show(Expr.betaReduce('{ ((using x1: Int, x2: Int, x3: Int, x4: Int, x5: Int, x6: Int, x7: Int, x8: Int, x9: Int, x10: Int, x11: Int, x12: Int, x13: Int) => x1 + x2 + x3 + x4 + x5 + x6 + x7 + x8 + x9 + x10 + x11 + x12 + x13)(using x(1) , x(2), x(3), x(4), x(5), x(6), x(7), x(8), x(9), x(10), x(11), x(12), x(13)) }))) - println(show(Expr.betaReduce('{ ((using x1: Int, x2: Int, x3: Int, x4: Int, x5: Int, x6: Int, x7: Int, x8: Int, x9: Int, x10: Int, x11: Int, x12: Int, x13: Int, x14: Int) => x1 + x2 + x3 + x4 + x5 + x6 + x7 + x8 + x9 + x10 + x11 + x12 + x13 + x14)(using x(1) , x(2), x(3), x(4), x(5), x(6), x(7), x(8), x(9), x(10), x(11), x(12), x(13), x(14)) }))) - println(show(Expr.betaReduce('{ ((using x1: Int, x2: Int, x3: Int, x4: Int, x5: Int, x6: Int, x7: Int, x8: Int, x9: Int, x10: Int, x11: Int, x12: Int, x13: Int, x14: Int, x15: Int) => x1 + x2 + x3 + x4 + x5 + x6 + x7 + x8 + x9 + x10 + x11 + x12 + x13 + x14 + x15)(using x(1) , x(2), x(3), x(4), x(5), x(6), x(7), x(8), x(9), x(10), x(11), x(12), x(13), x(14), x(15)) }))) - println(show(Expr.betaReduce('{ ((using x1: Int, x2: Int, x3: Int, x4: Int, x5: Int, x6: Int, x7: Int, x8: Int, x9: Int, x10: Int, x11: Int, x12: Int, x13: Int, x14: Int, x15: Int, x16: Int) => x1 + x2 + x3 + x4 + x5 + x6 + x7 + x8 + x9 + x10 + x11 + x12 + x13 + x14 + x15 + x16)(using x(1) , x(2), x(3), x(4), x(5), x(6), x(7), x(8), x(9), x(10), x(11), x(12), x(13), x(14), x(15), x(16)) }))) - println(show(Expr.betaReduce('{ ((using x1: Int, x2: Int, x3: Int, x4: Int, x5: Int, x6: Int, x7: Int, x8: Int, x9: Int, x10: Int, x11: Int, x12: Int, x13: Int, x14: Int, x15: Int, x16: Int, x17: Int) => x1 + x2 + x3 + x4 + x5 + x6 + x7 + x8 + x9 + x10 + x11 + x12 + x13 + x14 + x15 + x16 + x17)(using x(1) , x(2), x(3), x(4), x(5), x(6), x(7), x(8), x(9), x(10), x(11), x(12), x(13), x(14), x(15), x(16), x(17)) }))) - println(show(Expr.betaReduce('{ ((using x1: Int, x2: Int, x3: Int, x4: Int, x5: Int, x6: Int, x7: Int, x8: Int, x9: Int, x10: Int, x11: Int, x12: Int, x13: Int, x14: Int, x15: Int, x16: Int, x17: Int, x18: Int) => x1 + x2 + x3 + x4 + x5 + x6 + x7 + x8 + x9 + x10 + x11 + x12 + x13 + x14 + x15 + x16 + x17 + x18)(using x(1) , x(2), x(3), x(4), x(5), x(6), x(7), x(8), x(9), x(10), x(11), x(12), x(13), x(14), x(15), x(16), x(17), x(18)) }))) - println(show(Expr.betaReduce('{ ((using x1: Int, x2: Int, x3: Int, x4: Int, x5: Int, x6: Int, x7: Int, x8: Int, x9: Int, x10: Int, x11: Int, x12: Int, x13: Int, x14: Int, x15: Int, x16: Int, x17: Int, x18: Int, x19: Int) => x1 + x2 + x3 + x4 + x5 + x6 + x7 + x8 + x9 + x10 + x11 + x12 + x13 + x14 + x15 + x16 + x17 + x18 + x19)(using x(1) , x(2), x(3), x(4), x(5), x(6), x(7), x(8), x(9), x(10), x(11), x(12), x(13), x(14), x(15), x(16), x(17), x(18), x(19)) }))) - println(show(Expr.betaReduce('{ ((using x1: Int, x2: Int, x3: Int, x4: Int, x5: Int, x6: Int, x7: Int, x8: Int, x9: Int, x10: Int, x11: Int, x12: Int, x13: Int, x14: Int, x15: Int, x16: Int, x17: Int, x18: Int, x19: Int, x20: Int) => x1 + x2 + x3 + x4 + x5 + x6 + x7 + x8 + x9 + x10 + x11 + x12 + x13 + x14 + x15 + x16 + x17 + x18 + x19 + x20)(using x(1) , x(2), x(3), x(4), x(5), x(6), x(7), x(8), x(9), x(10), x(11), x(12), x(13), x(14), x(15), x(16), x(17), x(18), x(19), x(20)) }))) - println(show(Expr.betaReduce('{ ((using x1: Int, x2: Int, x3: Int, x4: Int, x5: Int, x6: Int, x7: Int, x8: Int, x9: Int, x10: Int, x11: Int, x12: Int, x13: Int, x14: Int, x15: Int, x16: Int, x17: Int, x18: Int, x19: Int, x20: Int, x21: Int) => x1 + x2 + x3 + x4 + x5 + x6 + x7 + x8 + x9 + x10 + x11 + x12 + x13 + x14 + x15 + x16 + x17 + x18 + x19 + x20 + x21)(using x(1) , x(2), x(3), x(4), x(5), x(6), x(7), x(8), x(9), x(10), x(11), x(12), x(13), x(14), x(15), x(16), x(17), x(18), x(19), x(20), x(21)) }))) - println(show(Expr.betaReduce('{ ((using x1: Int, x2: Int, x3: Int, x4: Int, x5: Int, x6: Int, x7: Int, x8: Int, x9: Int, x10: Int, x11: Int, x12: Int, x13: Int, x14: Int, x15: Int, x16: Int, x17: Int, x18: Int, x19: Int, x20: Int, x21: Int, x22: Int) => x1 + x2 + x3 + x4 + x5 + x6 + x7 + x8 + x9 + x10 + x11 + x12 + x13 + x14 + x15 + x16 + x17 + x18 + x19 + x20 + x21 + x22)(using x(1) , x(2), x(3), x(4), x(5), x(6), x(7), x(8), x(9), x(10), x(11), x(12), x(13), x(14), x(15), x(16), x(17), x(18), x(19), x(20), x(21), x(22)) }))) + println(show(Expr.betaReduce('{ ((x1: Int) ?=> x1)(using x(1)) }))) + println(show(Expr.betaReduce('{ ((x1: Int, x2: Int) ?=> x1 + x2)(using x(1), x(2)) }))) + println(show(Expr.betaReduce('{ ((x1: Int, x2: Int, x3: Int) ?=> x1 + x2 + x3)(using x(1), x(2), x(3)) }))) + println(show(Expr.betaReduce('{ ((x1: Int, x2: Int, x3: Int, x4: Int) ?=> x1 + x2 + x3 + x4)(using x(1) , x(2), x(3), x(4)) }))) + println(show(Expr.betaReduce('{ ((x1: Int, x2: Int, x3: Int, x4: Int, x5: Int) ?=> x1 + x2 + x3 + x4 + x5)(using x(1) , x(2), x(3), x(4), x(5)) }))) + println(show(Expr.betaReduce('{ ((x1: Int, x2: Int, x3: Int, x4: Int, x5: Int, x6: Int) ?=> x1 + x2 + x3 + x4 + x5 + x6)(using x(1) , x(2), x(3), x(4), x(5), x(6)) }))) + println(show(Expr.betaReduce('{ ((x1: Int, x2: Int, x3: Int, x4: Int, x5: Int, x6: Int, x7: Int) ?=> x1 + x2 + x3 + x4 + x5 + x6 + x7)(using x(1) , x(2), x(3), x(4), x(5), x(6), x(7)) }))) + println(show(Expr.betaReduce('{ ((x1: Int, x2: Int, x3: Int, x4: Int, x5: Int, x6: Int, x7: Int, x8: Int) ?=> x1 + x2 + x3 + x4 + x5 + x6 + x7 + x8)(using x(1) , x(2), x(3), x(4), x(5), x(6), x(7), x(8)) }))) + println(show(Expr.betaReduce('{ ((x1: Int, x2: Int, x3: Int, x4: Int, x5: Int, x6: Int, x7: Int, x8: Int, x9: Int) ?=> x1 + x2 + x3 + x4 + x5 + x6 + x7 + x8 + x9)(using x(1) , x(2), x(3), x(4), x(5), x(6), x(7), x(8), x(9)) }))) + println(show(Expr.betaReduce('{ ((x1: Int, x2: Int, x3: Int, x4: Int, x5: Int, x6: Int, x7: Int, x8: Int, x9: Int, x10: Int) ?=> x1 + x2 + x3 + x4 + x5 + x6 + x7 + x8 + x9 + x10)(using x(1) , x(2), x(3), x(4), x(5), x(6), x(7), x(8), x(9), x(10)) }))) + println(show(Expr.betaReduce('{ ((x1: Int, x2: Int, x3: Int, x4: Int, x5: Int, x6: Int, x7: Int, x8: Int, x9: Int, x10: Int, x11: Int) ?=> x1 + x2 + x3 + x4 + x5 + x6 + x7 + x8 + x9 + x10 + x11)(using x(1) , x(2), x(3), x(4), x(5), x(6), x(7), x(8), x(9), x(10), x(11)) }))) + println(show(Expr.betaReduce('{ ((x1: Int, x2: Int, x3: Int, x4: Int, x5: Int, x6: Int, x7: Int, x8: Int, x9: Int, x10: Int, x11: Int, x12: Int) ?=> x1 + x2 + x3 + x4 + x5 + x6 + x7 + x8 + x9 + x10 + x11 + x12)(using x(1) , x(2), x(3), x(4), x(5), x(6), x(7), x(8), x(9), x(10), x(11), x(12)) }))) + println(show(Expr.betaReduce('{ ((x1: Int, x2: Int, x3: Int, x4: Int, x5: Int, x6: Int, x7: Int, x8: Int, x9: Int, x10: Int, x11: Int, x12: Int, x13: Int) ?=> x1 + x2 + x3 + x4 + x5 + x6 + x7 + x8 + x9 + x10 + x11 + x12 + x13)(using x(1) , x(2), x(3), x(4), x(5), x(6), x(7), x(8), x(9), x(10), x(11), x(12), x(13)) }))) + println(show(Expr.betaReduce('{ ((x1: Int, x2: Int, x3: Int, x4: Int, x5: Int, x6: Int, x7: Int, x8: Int, x9: Int, x10: Int, x11: Int, x12: Int, x13: Int, x14: Int) ?=> x1 + x2 + x3 + x4 + x5 + x6 + x7 + x8 + x9 + x10 + x11 + x12 + x13 + x14)(using x(1) , x(2), x(3), x(4), x(5), x(6), x(7), x(8), x(9), x(10), x(11), x(12), x(13), x(14)) }))) + println(show(Expr.betaReduce('{ ((x1: Int, x2: Int, x3: Int, x4: Int, x5: Int, x6: Int, x7: Int, x8: Int, x9: Int, x10: Int, x11: Int, x12: Int, x13: Int, x14: Int, x15: Int) ?=> x1 + x2 + x3 + x4 + x5 + x6 + x7 + x8 + x9 + x10 + x11 + x12 + x13 + x14 + x15)(using x(1) , x(2), x(3), x(4), x(5), x(6), x(7), x(8), x(9), x(10), x(11), x(12), x(13), x(14), x(15)) }))) + println(show(Expr.betaReduce('{ ((x1: Int, x2: Int, x3: Int, x4: Int, x5: Int, x6: Int, x7: Int, x8: Int, x9: Int, x10: Int, x11: Int, x12: Int, x13: Int, x14: Int, x15: Int, x16: Int) ?=> x1 + x2 + x3 + x4 + x5 + x6 + x7 + x8 + x9 + x10 + x11 + x12 + x13 + x14 + x15 + x16)(using x(1) , x(2), x(3), x(4), x(5), x(6), x(7), x(8), x(9), x(10), x(11), x(12), x(13), x(14), x(15), x(16)) }))) + println(show(Expr.betaReduce('{ ((x1: Int, x2: Int, x3: Int, x4: Int, x5: Int, x6: Int, x7: Int, x8: Int, x9: Int, x10: Int, x11: Int, x12: Int, x13: Int, x14: Int, x15: Int, x16: Int, x17: Int) ?=> x1 + x2 + x3 + x4 + x5 + x6 + x7 + x8 + x9 + x10 + x11 + x12 + x13 + x14 + x15 + x16 + x17)(using x(1) , x(2), x(3), x(4), x(5), x(6), x(7), x(8), x(9), x(10), x(11), x(12), x(13), x(14), x(15), x(16), x(17)) }))) + println(show(Expr.betaReduce('{ ((x1: Int, x2: Int, x3: Int, x4: Int, x5: Int, x6: Int, x7: Int, x8: Int, x9: Int, x10: Int, x11: Int, x12: Int, x13: Int, x14: Int, x15: Int, x16: Int, x17: Int, x18: Int) ?=> x1 + x2 + x3 + x4 + x5 + x6 + x7 + x8 + x9 + x10 + x11 + x12 + x13 + x14 + x15 + x16 + x17 + x18)(using x(1) , x(2), x(3), x(4), x(5), x(6), x(7), x(8), x(9), x(10), x(11), x(12), x(13), x(14), x(15), x(16), x(17), x(18)) }))) + println(show(Expr.betaReduce('{ ((x1: Int, x2: Int, x3: Int, x4: Int, x5: Int, x6: Int, x7: Int, x8: Int, x9: Int, x10: Int, x11: Int, x12: Int, x13: Int, x14: Int, x15: Int, x16: Int, x17: Int, x18: Int, x19: Int) ?=> x1 + x2 + x3 + x4 + x5 + x6 + x7 + x8 + x9 + x10 + x11 + x12 + x13 + x14 + x15 + x16 + x17 + x18 + x19)(using x(1) , x(2), x(3), x(4), x(5), x(6), x(7), x(8), x(9), x(10), x(11), x(12), x(13), x(14), x(15), x(16), x(17), x(18), x(19)) }))) + println(show(Expr.betaReduce('{ ((x1: Int, x2: Int, x3: Int, x4: Int, x5: Int, x6: Int, x7: Int, x8: Int, x9: Int, x10: Int, x11: Int, x12: Int, x13: Int, x14: Int, x15: Int, x16: Int, x17: Int, x18: Int, x19: Int, x20: Int) ?=> x1 + x2 + x3 + x4 + x5 + x6 + x7 + x8 + x9 + x10 + x11 + x12 + x13 + x14 + x15 + x16 + x17 + x18 + x19 + x20)(using x(1) , x(2), x(3), x(4), x(5), x(6), x(7), x(8), x(9), x(10), x(11), x(12), x(13), x(14), x(15), x(16), x(17), x(18), x(19), x(20)) }))) + println(show(Expr.betaReduce('{ ((x1: Int, x2: Int, x3: Int, x4: Int, x5: Int, x6: Int, x7: Int, x8: Int, x9: Int, x10: Int, x11: Int, x12: Int, x13: Int, x14: Int, x15: Int, x16: Int, x17: Int, x18: Int, x19: Int, x20: Int, x21: Int) ?=> x1 + x2 + x3 + x4 + x5 + x6 + x7 + x8 + x9 + x10 + x11 + x12 + x13 + x14 + x15 + x16 + x17 + x18 + x19 + x20 + x21)(using x(1) , x(2), x(3), x(4), x(5), x(6), x(7), x(8), x(9), x(10), x(11), x(12), x(13), x(14), x(15), x(16), x(17), x(18), x(19), x(20), x(21)) }))) + println(show(Expr.betaReduce('{ ((x1: Int, x2: Int, x3: Int, x4: Int, x5: Int, x6: Int, x7: Int, x8: Int, x9: Int, x10: Int, x11: Int, x12: Int, x13: Int, x14: Int, x15: Int, x16: Int, x17: Int, x18: Int, x19: Int, x20: Int, x21: Int, x22: Int) ?=> x1 + x2 + x3 + x4 + x5 + x6 + x7 + x8 + x9 + x10 + x11 + x12 + x13 + x14 + x15 + x16 + x17 + x18 + x19 + x20 + x21 + x22)(using x(1) , x(2), x(3), x(4), x(5), x(6), x(7), x(8), x(9), x(10), x(11), x(12), x(13), x(14), x(15), x(16), x(17), x(18), x(19), x(20), x(21), x(22)) }))) } def x(i: Int): Int = i diff --git a/tests/run-staging/quote-nested-2.scala b/tests/run-staging/quote-nested-2.scala index 5b3588e2dcd2..f8277f849613 100644 --- a/tests/run-staging/quote-nested-2.scala +++ b/tests/run-staging/quote-nested-2.scala @@ -5,7 +5,7 @@ object Test { given Toolbox = Toolbox.make(getClass.getClassLoader) def main(args: Array[String]): Unit = withQuotes { - val q = '{(using q: Quotes) => + val q = '{(q: Quotes) ?=> val a = '{4} '{${a}} } diff --git a/tests/run-staging/quote-nested-5.scala b/tests/run-staging/quote-nested-5.scala index 0b8c82baa9dd..2c6152154535 100644 --- a/tests/run-staging/quote-nested-5.scala +++ b/tests/run-staging/quote-nested-5.scala @@ -5,9 +5,9 @@ object Test { given Toolbox = Toolbox.make(getClass.getClassLoader) def main(args: Array[String]): Unit = withQuotes { - val q = '{(using q: Quotes) => + val q = '{(q: Quotes) ?=> val a = '{4} - ${'{(using q2: Quotes) => + ${'{(q2: Quotes) ?=> '{${a}} }} diff --git a/tests/run/implicitFunctionXXL.scala b/tests/run/implicitFunctionXXL.scala index 993764f695ff..b4131080577d 100644 --- a/tests/run/implicitFunctionXXL.scala +++ b/tests/run/implicitFunctionXXL.scala @@ -5,7 +5,7 @@ object Test { implicit val intWorld: Int = 42 implicit val strWorld: String = "Hello " - val i1 = ((using x1: Int, + val i1 = (( x1: Int, x2: String, x3: Int, x4: Int, @@ -30,7 +30,7 @@ object Test { x23: Int, x24: Int, x25: Int, - x26: Int) => x2 + x1) + x26: Int) ?=> x2 + x1) println(i1) } From db39f61da52bae695f4d687d433c6808b4e6ead0 Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Wed, 25 Nov 2020 09:56:33 +0100 Subject: [PATCH 2/5] Revert "Fix tests" This reverts commit 1bbb2558755119686eaab306e9bbca2bf1361f64. # Conflicts: # library/src-bootstrapped/scala/internal/quoted/Expr.scala # tests/run-macros/i9812b/Macro_1.scala # tests/run-staging/quote-nested-1.scala --- tests/neg/i2006.scala | 4 ++-- tests/neg/i2146.scala | 2 +- tests/neg/i4668.scala | 2 +- tests/neg/scoped-quoted-expr-proto.scala | 4 ++-- tests/pos/case-getters.scala | 2 +- tests/pos/i5966.scala | 2 +- tests/pos/i6863/lib_1.scala | 2 +- tests/pos/ift-assign.scala | 2 +- tests/pos/inline-apply.scala | 2 +- tests/pos/reference/delegates.scala | 6 +++--- tests/pos/tasty-tags-obscure.scala | 2 +- tests/run-macros/i9812b/Macro_1.scala | 2 +- tests/run-staging/quote-nested-1.scala | 2 +- tests/run/i2146.scala | 2 +- tests/run/i3448.scala | 2 +- tests/run/implicitFuns.scala | 8 ++++---- tests/run/polymorphic-functions.scala | 2 +- 17 files changed, 24 insertions(+), 24 deletions(-) diff --git a/tests/neg/i2006.scala b/tests/neg/i2006.scala index 469bf358bb82..850c2588ba12 100644 --- a/tests/neg/i2006.scala +++ b/tests/neg/i2006.scala @@ -4,7 +4,7 @@ object Test { inline def bar(f: Int ?=> Int) = f // error def main(args: Array[String]) = { - foo((using thisTransaction) => 43) - bar((using thisTransaction) => 44) + foo(thisTransaction ?=> 43) + bar(thisTransaction ?=> 44) } } diff --git a/tests/neg/i2146.scala b/tests/neg/i2146.scala index 606304ba7352..015805dfd4e7 100644 --- a/tests/neg/i2146.scala +++ b/tests/neg/i2146.scala @@ -1,5 +1,5 @@ class Test { - def foo[A, B]: A ?=> B ?=> Int = { (using b: B) => // error: found Int, required: A ?=> B ?=> Int + def foo[A, B]: A ?=> B ?=> Int = { (b: B) ?=> // error: found Int, required: A ?=> B ?=> Int 42 } } diff --git a/tests/neg/i4668.scala b/tests/neg/i4668.scala index 685c83fd1109..6ea702f47f09 100644 --- a/tests/neg/i4668.scala +++ b/tests/neg/i4668.scala @@ -8,4 +8,4 @@ trait Functor[F[_]] { def map[A,B](x: F[A])(f: A => B): F[B] } object Functor { implicit object listFun extends Functor[List] { def map[A,B](ls: List[A])(f: A => B) = ls.map(f) } } val map: (A:Type,B:Type,F:Type1) ?=> (Functor[F.T]) ?=> (F.T[A.T]) => (A.T => B.T) => F.T[B.T] = - (using fun) => (using x) => f => fun.map(x)(f) // error \ No newline at end of file + fun ?=> x => f => fun.map(x)(f) // error \ No newline at end of file diff --git a/tests/neg/scoped-quoted-expr-proto.scala b/tests/neg/scoped-quoted-expr-proto.scala index c8d0f3bb8363..840542e8fb67 100644 --- a/tests/neg/scoped-quoted-expr-proto.scala +++ b/tests/neg/scoped-quoted-expr-proto.scala @@ -69,7 +69,7 @@ package b { } } - r { (using qctx) => + r { qctx ?=> var escaped: qctx.Expr[Double] = ??? q{ (x: Double) => s{ @@ -127,7 +127,7 @@ package c { } } - r { (using qctx) => + r { qctx ?=> var escaped: qctx.Expr[Double] = ??? q{ (x: Double) => s{ diff --git a/tests/pos/case-getters.scala b/tests/pos/case-getters.scala index df2862a333ca..391700aafb71 100644 --- a/tests/pos/case-getters.scala +++ b/tests/pos/case-getters.scala @@ -1,6 +1,6 @@ case class Foo(x: 1, y: Int ?=> Int) object Test { - val f = Foo(1, (using i: Int) => i) + val f = Foo(1, (i: Int) ?=> i) val fx1: 1 = f.x val fx2: 1 = f._1 val fy1: Int = f.y(using 1) diff --git a/tests/pos/i5966.scala b/tests/pos/i5966.scala index 05142f28d442..88a0c9a9beb5 100644 --- a/tests/pos/i5966.scala +++ b/tests/pos/i5966.scala @@ -1,5 +1,5 @@ object Test { - def foo = (using v: Int) => (x: Int) => v + x + def foo = (v: Int) ?=> (x: Int) => v + x given myInt as Int = 4 foo.apply(1) diff --git a/tests/pos/i6863/lib_1.scala b/tests/pos/i6863/lib_1.scala index b43393ae68bc..cde38c97220a 100644 --- a/tests/pos/i6863/lib_1.scala +++ b/tests/pos/i6863/lib_1.scala @@ -1,2 +1,2 @@ trait Ctx -inline def foo(): Unit = (using x: Ctx) => () +inline def foo(): Unit = (x: Ctx) ?=> () diff --git a/tests/pos/ift-assign.scala b/tests/pos/ift-assign.scala index 07def0f68d8a..7e9243760245 100644 --- a/tests/pos/ift-assign.scala +++ b/tests/pos/ift-assign.scala @@ -1,7 +1,7 @@ class Context object Test { - var f: Context ?=> String = ((using _) => "") + var f: Context ?=> String = (_ ?=> "") f = f diff --git a/tests/pos/inline-apply.scala b/tests/pos/inline-apply.scala index d1cca29ac65f..f70975d609b2 100644 --- a/tests/pos/inline-apply.scala +++ b/tests/pos/inline-apply.scala @@ -5,7 +5,7 @@ object Test { def transform()(implicit ctx: Context) = { inline def withLocalOwner[T](op: Context ?=> T) = op(using ctx) - withLocalOwner { (using ctx) => } + withLocalOwner { ctx ?=> } } } diff --git a/tests/pos/reference/delegates.scala b/tests/pos/reference/delegates.scala index 44be54d0684d..56b29c008924 100644 --- a/tests/pos/reference/delegates.scala +++ b/tests/pos/reference/delegates.scala @@ -78,12 +78,12 @@ object Instances extends Common: println(minimum(xs)) case class Context(value: String) - val c0: Context ?=> String = (using ctx) => ctx.value - val c1: Context ?=> String = (using ctx: Context) => ctx.value + val c0: Context ?=> String = ctx ?=> ctx.value + val c1: Context ?=> String = (ctx: Context) ?=> ctx.value class A class B - val ab: (x: A, y: B) ?=> Int = (using a: A, b: B) => 22 + val ab: (x: A, y: B) ?=> Int = (a: A, b: B) ?=> 22 trait TastyAPI: type Symbol diff --git a/tests/pos/tasty-tags-obscure.scala b/tests/pos/tasty-tags-obscure.scala index 315703915ba5..cd883ee0aeba 100644 --- a/tests/pos/tasty-tags-obscure.scala +++ b/tests/pos/tasty-tags-obscure.scala @@ -1,7 +1,7 @@ object ObscureTasty: def foo(f: [t] => List[t] ?=> Unit) = ??? - def test1 = foo([t] => (using a: List[t]) => ()) // POLYtype => GIVENMETHODType + def test1 = foo([t] => (a: List[t]) ?=> ()) // POLYtype => GIVENMETHODType def bar(f: [t] => List[t] => Unit) = ??? def test2 = bar([t] => (a: List[t]) => ()) // POLYtype => METHODType diff --git a/tests/run-macros/i9812b/Macro_1.scala b/tests/run-macros/i9812b/Macro_1.scala index f2128f6b1307..b9ba7b6acbad 100644 --- a/tests/run-macros/i9812b/Macro_1.scala +++ b/tests/run-macros/i9812b/Macro_1.scala @@ -27,7 +27,7 @@ final case class CONS[+T](head: T, tail: Lst[T]) extends Lst[T] case object NIL extends Lst[Nothing] given IntLiftable[T <: Int] as Liftable[T]: - def toExpr(x: T): Quotes ?=> Expr[T] = (using qctx) => { + def toExpr(x: T): Quotes ?=> Expr[T] = qctx ?=> { import quotes.reflect._ Literal(Constant.Int(x)).asExpr.asInstanceOf[Expr[T]] } diff --git a/tests/run-staging/quote-nested-1.scala b/tests/run-staging/quote-nested-1.scala index 2c00a4e79105..00985deebf0f 100644 --- a/tests/run-staging/quote-nested-1.scala +++ b/tests/run-staging/quote-nested-1.scala @@ -4,7 +4,7 @@ import scala.quoted.staging._ object Test { given Toolbox = Toolbox.make(getClass.getClassLoader) def main(args: Array[String]): Unit = withQuotes { - val q = '{ (using q: Quotes) => '{3} } + val q = '{ (q: Quotes) ?=> '{3} } println(q.show) } } diff --git a/tests/run/i2146.scala b/tests/run/i2146.scala index 7efbf30f73fb..4805ebfb8d74 100644 --- a/tests/run/i2146.scala +++ b/tests/run/i2146.scala @@ -7,7 +7,7 @@ object Test { def foo[A, B]: A ?=> B ?=> (A, B) = (implicitly[A], implicitly[B]) - def bar[A, B]: A ?=> B ?=> (A, B) = {(using a: A) => + def bar[A, B]: A ?=> B ?=> (A, B) = {(a: A) ?=> (implicitly[A], implicitly[B]) } diff --git a/tests/run/i3448.scala b/tests/run/i3448.scala index 42ee42be4e1e..4acd986573a1 100644 --- a/tests/run/i3448.scala +++ b/tests/run/i3448.scala @@ -5,7 +5,7 @@ object Test extends App { val x: IF[Int] = implicitly[C].x - val xs0: List[IF[Int]] = List((using _) => x) + val xs0: List[IF[Int]] = List(_ ?=> x) val xs: List[IF[Int]] = List(x) val ys: IF[List[Int]] = xs.map(x => x) val zs = ys(using C(22)) diff --git a/tests/run/implicitFuns.scala b/tests/run/implicitFuns.scala index f240a13fb999..d505eeea0d7a 100644 --- a/tests/run/implicitFuns.scala +++ b/tests/run/implicitFuns.scala @@ -3,15 +3,15 @@ object Test { implicit val world: String = "world!" - val i1 = ((using s: String) => s.length > 2) - val i2 = {(using s: String) => s.length > 2} + val i1 = ((s: String) ?=> s.length > 2) + val i2 = {(s: String) ?=> s.length > 2} assert(i1) assert(i2) - val x: String ?=> Boolean = { (using s: String) => s.length > 2 } + val x: String ?=> Boolean = { (s: String) ?=> s.length > 2 } - val xx: (String, Int) ?=> Int = (using x: String, y: Int) => x.length + y + val xx: (String, Int) ?=> Int = (x: String, y: Int) ?=> x.length + y val y: String => Boolean = x(using _) diff --git a/tests/run/polymorphic-functions.scala b/tests/run/polymorphic-functions.scala index 1b35e1d8c44e..e723fa34cf79 100644 --- a/tests/run/polymorphic-functions.scala +++ b/tests/run/polymorphic-functions.scala @@ -89,7 +89,7 @@ object Test extends App { new Show[Int] { def show(t: Int): String = t.toString } - val s = [T] => (t: T) => (using st: Show[T]) => st.show(t) + val s = [T] => (t: T) => (st: Show[T]) ?=> st.show(t) assert(s(23) == "23") // Parens handling From 9379c53375d5b215dedd61705ca00c1ff817531c Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Wed, 25 Nov 2020 09:57:08 +0100 Subject: [PATCH 3/5] Revert "Fix #10056: Drop old context function closure syntax" This reverts commit e75f7ccfbf205d105cad0949f3cc06da4cd784c3. --- compiler/src/dotty/tools/dotc/parsing/Parsers.scala | 10 +++++----- docs/docs/internals/syntax.md | 4 ++-- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/compiler/src/dotty/tools/dotc/parsing/Parsers.scala b/compiler/src/dotty/tools/dotc/parsing/Parsers.scala index 49f53fa7cf22..686dc5d3f5d0 100644 --- a/compiler/src/dotty/tools/dotc/parsing/Parsers.scala +++ b/compiler/src/dotty/tools/dotc/parsing/Parsers.scala @@ -1502,7 +1502,7 @@ object Parsers { def typedFunParam(start: Offset, name: TermName, mods: Modifiers = EmptyModifiers): ValDef = atSpan(start) { accept(COLON) - makeParameter(name, typ(), mods) + makeParameter(name, typ(), mods | Param) } /** FunParamClause ::= ‘(’ TypedFunParam {‘,’ TypedFunParam } ‘)’ @@ -1864,14 +1864,14 @@ object Parsers { accept(altToken) t - /** Expr ::= [`implicit'] FunParams ‘=>’ Expr + /** Expr ::= [`implicit'] FunParams (‘=>’ | ‘?=>’) Expr * | Expr1 * FunParams ::= Bindings * | id * | `_' * ExprInParens ::= PostfixExpr `:' Type * | Expr - * BlockResult ::= [‘implicit’] FunParams ‘=>’ Block + * BlockResult ::= [‘implicit’] FunParams (‘=>’ | ‘?=>’) Block * | Expr1 * Expr1 ::= [‘inline’] `if' `(' Expr `)' {nl} Expr [[semi] else Expr] * | [‘inline’] `if' Expr `then' Expr [[semi] else Expr] @@ -2186,7 +2186,7 @@ object Parsers { def closureRest(start: Int, location: Location, params: List[Tree]): Tree = atSpan(start, in.offset) { - accept(ARROW) + if in.token == CTXARROW then in.nextToken() else accept(ARROW) Function(params, if (location == Location.InBlock) block() else expr()) } @@ -3773,7 +3773,7 @@ object Parsers { case Typed(tree @ This(EmptyTypeIdent), tpt) => self = makeSelfDef(nme.WILDCARD, tpt).withSpan(first.span) case _ => - val ValDef(name, tpt, _) = convertToParam(first, "self type clause") + val ValDef(name, tpt, _) = convertToParam(first, EmptyModifiers, "self type clause") if (name != nme.ERROR) self = makeSelfDef(name, tpt).withSpan(first.span) } diff --git a/docs/docs/internals/syntax.md b/docs/docs/internals/syntax.md index aa1d5b182b29..6f4822be2f00 100644 --- a/docs/docs/internals/syntax.md +++ b/docs/docs/internals/syntax.md @@ -185,9 +185,9 @@ Types ::= Type {‘,’ Type} ### Expressions ```ebnf -Expr ::= FunParams ‘=>’ Expr Function(args, expr), Function(ValDef([implicit], id, TypeTree(), EmptyTree), expr) +Expr ::= FunParams (‘=>’ | ‘?=>’) Expr Function(args, expr), Function(ValDef([implicit], id, TypeTree(), EmptyTree), expr) | Expr1 -BlockResult ::= FunParams ‘=>’ Block +BlockResult ::= FunParams (‘=>’ | ‘?=>’) Block | Expr1 FunParams ::= Bindings | id From dbbf5882890dfb7b6f28ac7e38271705b05cce6a Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Wed, 25 Nov 2020 10:00:15 +0100 Subject: [PATCH 4/5] Small fixes --- compiler/src/dotty/tools/dotc/parsing/Parsers.scala | 2 +- docs/docs/internals/syntax.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/compiler/src/dotty/tools/dotc/parsing/Parsers.scala b/compiler/src/dotty/tools/dotc/parsing/Parsers.scala index 686dc5d3f5d0..5f99bfd22e9f 100644 --- a/compiler/src/dotty/tools/dotc/parsing/Parsers.scala +++ b/compiler/src/dotty/tools/dotc/parsing/Parsers.scala @@ -1502,7 +1502,7 @@ object Parsers { def typedFunParam(start: Offset, name: TermName, mods: Modifiers = EmptyModifiers): ValDef = atSpan(start) { accept(COLON) - makeParameter(name, typ(), mods | Param) + makeParameter(name, typ(), mods) } /** FunParamClause ::= ‘(’ TypedFunParam {‘,’ TypedFunParam } ‘)’ diff --git a/docs/docs/internals/syntax.md b/docs/docs/internals/syntax.md index 6f4822be2f00..7d2f3d18ef4e 100644 --- a/docs/docs/internals/syntax.md +++ b/docs/docs/internals/syntax.md @@ -322,7 +322,7 @@ ClosureMods ::= { ‘implicit’ | ‘given’} ### Bindings and Imports ```ebnf -Bindings ::= ‘(’ [[‘using’] Binding {‘,’ Binding}] ‘)’ +Bindings ::= ‘(’ [Binding {‘,’ Binding}] ‘)’ Binding ::= (id | ‘_’) [‘:’ Type] ValDef(_, id, tpe, EmptyTree) Modifier ::= LocalModifier From 1ec425aac877af040197ffd4b9f0adbebc043145 Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Wed, 25 Nov 2020 12:17:26 +0100 Subject: [PATCH 5/5] Drop with in front of template syntax This was no longer supported but still recognized by the parser --- .../dotty/tools/dotc/parsing/Parsers.scala | 21 +++++++------------ 1 file changed, 7 insertions(+), 14 deletions(-) diff --git a/compiler/src/dotty/tools/dotc/parsing/Parsers.scala b/compiler/src/dotty/tools/dotc/parsing/Parsers.scala index 5f99bfd22e9f..fe6c8b7ba9dd 100644 --- a/compiler/src/dotty/tools/dotc/parsing/Parsers.scala +++ b/compiler/src/dotty/tools/dotc/parsing/Parsers.scala @@ -2310,7 +2310,7 @@ object Parsers { possibleTemplateStart() val parents = if in.isNestedStart then Nil - else constrApps(commaOK = false, templateCanFollow = true) + else constrApps(commaOK = false) colonAtEOLOpt() possibleTemplateStart(isNew = true) parents match { @@ -3493,7 +3493,7 @@ object Parsers { val parents = if (in.token == EXTENDS) { in.nextToken() - constrApps(commaOK = true, templateCanFollow = false) + constrApps(commaOK = true) } else Nil Template(constr, parents, Nil, EmptyValDef, Nil) @@ -3537,7 +3537,7 @@ object Parsers { val noParams = tparams.isEmpty && vparamss.isEmpty if !(name.isEmpty && noParams) then accept(nme.as) - val parents = constrApps(commaOK = true, templateCanFollow = true) + val parents = constrApps(commaOK = true) if in.token == EQUALS && parents.length == 1 && parents.head.isType then accept(EQUALS) mods1 |= Final @@ -3617,19 +3617,12 @@ object Parsers { /** ConstrApps ::= ConstrApp {(‘,’ | ‘with’) ConstrApp} */ - def constrApps(commaOK: Boolean, templateCanFollow: Boolean): List[Tree] = + def constrApps(commaOK: Boolean): List[Tree] = val t = constrApp() val ts = - if in.token == WITH then + if in.token == WITH || commaOK && in.token == COMMA then in.nextToken() - newLineOptWhenFollowedBy(LBRACE) - if templateCanFollow && (in.token == LBRACE || in.token == INDENT) then - Nil - else - constrApps(commaOK, templateCanFollow) - else if commaOK && in.token == COMMA then - in.nextToken() - constrApps(commaOK, templateCanFollow) + constrApps(commaOK) else Nil t :: ts @@ -3646,7 +3639,7 @@ object Parsers { in.sourcePos()) Nil } - else constrApps(commaOK = true, templateCanFollow = true) + else constrApps(commaOK = true) } else Nil newLinesOptWhenFollowedBy(nme.derives)