Skip to content

Fix #10056: Drop old context function closure syntax #10088

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Oct 27, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 17 additions & 18 deletions compiler/src/dotty/tools/dotc/parsing/Parsers.scala
Original file line number Diff line number Diff line change
Expand Up @@ -443,35 +443,35 @@ object Parsers {

/** Convert tree to formal parameter list
*/
def convertToParams(tree: Tree, mods: Modifiers): List[ValDef] = tree match {
def convertToParams(tree: Tree): List[ValDef] = tree match {
case Parens(t) =>
convertToParam(t, mods) :: Nil
convertToParam(t) :: Nil
case Tuple(ts) =>
ts.map(convertToParam(_, mods))
ts.map(convertToParam(_))
case t: Typed =>
report.errorOrMigrationWarning(
em"parentheses are required around the parameter of a lambda${rewriteNotice()}",
in.sourcePos())
if migrateTo3 then
patch(source, t.span.startPos, "(")
patch(source, t.span.endPos, ")")
convertToParam(t, mods) :: Nil
convertToParam(t) :: Nil
case t =>
convertToParam(t, mods) :: Nil
convertToParam(t) :: Nil
}

/** Convert tree to formal parameter
*/
def convertToParam(tree: Tree, mods: Modifiers, expected: String = "formal parameter"): ValDef = tree match {
def convertToParam(tree: Tree, expected: String = "formal parameter"): ValDef = tree match {
case id @ Ident(name) =>
makeParameter(name.asTermName, TypeTree(), mods, isBackquoted = isBackquoted(id)).withSpan(tree.span)
makeParameter(name.asTermName, TypeTree(), EmptyModifiers, isBackquoted = isBackquoted(id)).withSpan(tree.span)
case Typed(id @ Ident(name), tpt) =>
makeParameter(name.asTermName, tpt, mods, isBackquoted = isBackquoted(id)).withSpan(tree.span)
makeParameter(name.asTermName, tpt, EmptyModifiers, isBackquoted = isBackquoted(id)).withSpan(tree.span)
case Typed(Splice(Ident(name)), tpt) =>
makeParameter(("$" + name).toTermName, tpt, mods).withSpan(tree.span)
makeParameter(("$" + name).toTermName, tpt, EmptyModifiers).withSpan(tree.span)
case _ =>
syntaxError(s"not a legal $expected", tree.span)
makeParameter(nme.ERROR, tree, mods)
makeParameter(nme.ERROR, tree, EmptyModifiers)
}

/** Convert (qual)ident to type identifier
Expand Down Expand Up @@ -1500,7 +1500,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 } ‘)’
Expand Down Expand Up @@ -1854,14 +1854,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]
Expand Down Expand Up @@ -1910,10 +1910,9 @@ object Parsers {
finally placeholderParams = saved

val t = expr1(location)
if (in.token == ARROW || in.token == CTXARROW) {
if (in.token == ARROW) {
placeholderParams = Nil // don't interpret `_' to the left of `=>` as placeholder
val paramMods = if in.token == CTXARROW then Modifiers(Given) else EmptyModifiers
wrapPlaceholders(closureRest(start, location, convertToParams(t, paramMods)))
wrapPlaceholders(closureRest(start, location, convertToParams(t)))
}
else if (isWildcard(t)) {
placeholderParams = placeholderParams ::: saved
Expand Down Expand Up @@ -2176,7 +2175,7 @@ object Parsers {

def closureRest(start: Int, location: Location, params: List[Tree]): Tree =
atSpan(start, in.offset) {
if in.token == CTXARROW then in.nextToken() else accept(ARROW)
accept(ARROW)
Function(params, if (location == Location.InBlock) block() else expr())
}

Expand Down Expand Up @@ -3778,7 +3777,7 @@ object Parsers {
case Typed(tree @ This(EmptyTypeIdent), tpt) =>
self = makeSelfDef(nme.WILDCARD, tpt).withSpan(first.span)
case _ =>
val ValDef(name, tpt, _) = convertToParam(first, EmptyModifiers, "self type clause")
val ValDef(name, tpt, _) = convertToParam(first, "self type clause")
if (name != nme.ERROR)
self = makeSelfDef(name, tpt).withSpan(first.span)
}
Expand Down
4 changes: 2 additions & 2 deletions docs/docs/internals/syntax.md
Original file line number Diff line number Diff line change
Expand Up @@ -188,9 +188,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
Expand Down
4 changes: 2 additions & 2 deletions library/src-bootstrapped/scala/internal/quoted/Expr.scala
Original file line number Diff line number Diff line change
Expand Up @@ -58,13 +58,13 @@ object Expr {
}

/** Returns a null expresssion equivalent to `'{null}` */
def `null`: QuoteContext ?=> quoted.Expr[Null] = qctx ?=> {
def `null`: QuoteContext ?=> quoted.Expr[Null] = (using qctx) => {
import qctx.reflect._
Literal(Constant.Null()).seal.asInstanceOf[quoted.Expr[Null]]
}

/** Returns a unit expresssion equivalent to `'{}` or `'{()}` */
def Unit: QuoteContext ?=> quoted.Expr[Unit] = qctx ?=> {
def Unit: QuoteContext ?=> quoted.Expr[Unit] = (using qctx) => {
import qctx.reflect._
Literal(Constant.Unit()).seal.asInstanceOf[quoted.Expr[Unit]]
}
Expand Down
4 changes: 2 additions & 2 deletions tests/neg/i2006.scala
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ object Test {
inline def bar(f: Int ?=> Int) = f // error

def main(args: Array[String]) = {
foo(thisTransaction ?=> 43)
bar(thisTransaction ?=> 44)
foo((using thisTransaction) => 43)
bar((using thisTransaction) => 44)
}
}
2 changes: 1 addition & 1 deletion tests/neg/i2146.scala
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
class Test {
def foo[A, B]: A ?=> B ?=> Int = { (b: B) ?=> // error: found Int, required: A ?=> B ?=> Int
def foo[A, B]: A ?=> B ?=> Int = { (using b: B) => // error: found Int, required: A ?=> B ?=> Int
42
}
}
2 changes: 1 addition & 1 deletion tests/neg/i4668.scala
Original file line number Diff line number Diff line change
Expand Up @@ -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] =
fun ?=> x => f => fun.map(x)(f) // error
(using fun) => (using x) => f => fun.map(x)(f) // error
4 changes: 2 additions & 2 deletions tests/neg/scoped-quoted-expr-proto.scala
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ package b {
}
}

r { qctx ?=>
r { (using qctx) =>
var escaped: qctx.Expr[Double] = ???
q{ (x: Double) =>
s{
Expand Down Expand Up @@ -127,7 +127,7 @@ package c {
}
}

r { qctx ?=>
r { (using qctx) =>
var escaped: qctx.Expr[Double] = ???
q{ (x: Double) =>
s{
Expand Down
2 changes: 1 addition & 1 deletion tests/pos/case-getters.scala
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
case class Foo(x: 1, y: Int ?=> Int)
object Test {
val f = Foo(1, (i: Int) ?=> i)
val f = Foo(1, (using i: Int) => i)
val fx1: 1 = f.x
val fx2: 1 = f._1
val fy1: Int = f.y(using 1)
Expand Down
2 changes: 1 addition & 1 deletion tests/pos/i5966.scala
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
object Test {
def foo = (v: Int) ?=> (x: Int) => v + x
def foo = (using v: Int) => (x: Int) => v + x
given myInt as Int = 4

foo.apply(1)
Expand Down
2 changes: 1 addition & 1 deletion tests/pos/i6863/lib_1.scala
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
trait Ctx
inline def foo(): Unit = (x: Ctx) ?=> ()
inline def foo(): Unit = (using x: Ctx) => ()
2 changes: 1 addition & 1 deletion tests/pos/ift-assign.scala
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
class Context

object Test {
var f: Context ?=> String = (_ ?=> "")
var f: Context ?=> String = ((using _) => "")

f = f

Expand Down
2 changes: 1 addition & 1 deletion tests/pos/inline-apply.scala
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ object Test {
def transform()(implicit ctx: Context) = {
inline def withLocalOwner[T](op: Context ?=> T) = op(using ctx)

withLocalOwner { ctx ?=> }
withLocalOwner { (using ctx) => }

}
}
6 changes: 3 additions & 3 deletions tests/pos/reference/delegates.scala
Original file line number Diff line number Diff line change
Expand Up @@ -78,12 +78,12 @@ object Instances extends Common:
println(minimum(xs))

case class Context(value: String)
val c0: Context ?=> String = ctx ?=> ctx.value
val c1: Context ?=> String = (ctx: Context) ?=> ctx.value
val c0: Context ?=> String = (using ctx) => ctx.value
val c1: Context ?=> String = (using ctx: Context) => ctx.value

class A
class B
val ab: (x: A, y: B) ?=> Int = (a: A, b: B) ?=> 22
val ab: (x: A, y: B) ?=> Int = (using a: A, b: B) => 22

trait TastyAPI:
type Symbol
Expand Down
2 changes: 1 addition & 1 deletion tests/pos/tasty-tags-obscure.scala
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
object ObscureTasty:

def foo(f: [t] => List[t] ?=> Unit) = ???
def test1 = foo([t] => (a: List[t]) ?=> ()) // POLYtype => GIVENMETHODType
def test1 = foo([t] => (using a: List[t]) => ()) // POLYtype => GIVENMETHODType
def bar(f: [t] => List[t] => Unit) = ???
def test2 = bar([t] => (a: List[t]) => ()) // POLYtype => METHODType

Expand Down
2 changes: 1 addition & 1 deletion tests/run-macros/i9812b/Macro_1.scala
Original file line number Diff line number Diff line change
Expand Up @@ -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): QuoteContext ?=> Expr[T] = qctx ?=> {
def toExpr(x: T): QuoteContext ?=> Expr[T] = (using qctx) => {
import qctx.reflect._
Literal(Constant.Int(x)).seal.asInstanceOf[Expr[T]]
}
Expand Down
2 changes: 1 addition & 1 deletion tests/run-staging/quote-nested-1.scala
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import scala.quoted.staging._
object Test {
given Toolbox = Toolbox.make(getClass.getClassLoader)
def main(args: Array[String]): Unit = withQuoteContext {
val q = '{ (qctx: QuoteContext) ?=> '{3} }
val q = '{ (using qctx: QuoteContext) => '{3} }
println(q.show)
}
}
2 changes: 1 addition & 1 deletion tests/run/i2146.scala
Original file line number Diff line number Diff line change
Expand Up @@ -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) = {(a: A) ?=>
def bar[A, B]: A ?=> B ?=> (A, B) = {(using a: A) =>
(implicitly[A], implicitly[B])
}

Expand Down
2 changes: 1 addition & 1 deletion tests/run/i3448.scala
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ object Test extends App {

val x: IF[Int] = implicitly[C].x

val xs0: List[IF[Int]] = List(_ ?=> x)
val xs0: List[IF[Int]] = List((using _) => x)
val xs: List[IF[Int]] = List(x)
val ys: IF[List[Int]] = xs.map(x => x)
val zs = ys(using C(22))
Expand Down
8 changes: 4 additions & 4 deletions tests/run/implicitFuns.scala
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,15 @@ object Test {

implicit val world: String = "world!"

val i1 = ((s: String) ?=> s.length > 2)
val i2 = {(s: String) ?=> s.length > 2}
val i1 = ((using s: String) => s.length > 2)
val i2 = {(using s: String) => s.length > 2}

assert(i1)
assert(i2)

val x: String ?=> Boolean = { (s: String) ?=> s.length > 2 }
val x: String ?=> Boolean = { (using s: String) => s.length > 2 }

val xx: (String, Int) ?=> Int = (x: String, y: Int) ?=> x.length + y
val xx: (String, Int) ?=> Int = (using x: String, y: Int) => x.length + y

val y: String => Boolean = x(using _)

Expand Down
2 changes: 1 addition & 1 deletion tests/run/polymorphic-functions.scala
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ object Test extends App {
new Show[Int] {
def show(t: Int): String = t.toString
}
val s = [T] => (t: T) => (st: Show[T]) ?=> st.show(t)
val s = [T] => (t: T) => (using st: Show[T]) => st.show(t)
assert(s(23) == "23")

// Parens handling
Expand Down