Skip to content

Require (...) around parameters of a lambda #7156

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 4 commits into from
Sep 3, 2019
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
18 changes: 14 additions & 4 deletions compiler/src/dotty/tools/dotc/parsing/Parsers.scala
Original file line number Diff line number Diff line change
Expand Up @@ -423,9 +423,19 @@ object Parsers {
/** Convert tree to formal parameter list
*/
def convertToParams(tree: Tree): List[ValDef] = tree match {
case Parens(t) => convertToParam(t) :: Nil
case Tuple(ts) => ts map (convertToParam(_))
case t => convertToParam(t) :: Nil
case Parens(t) =>
convertToParam(t) :: Nil
case Tuple(ts) =>
ts.map(convertToParam(_))
case t: Typed =>
in.errorOrMigrationWarning(
em"parentheses are required around the parameter of a lambda${rewriteNotice("-language:Scala2")}",
t.span)
patch(source, t.span.startPos, "(")
patch(source, t.span.endPos, ")")
convertToParam(t) :: Nil
case t =>
convertToParam(t) :: Nil
}

/** Convert tree to formal parameter
Expand Down Expand Up @@ -2915,7 +2925,7 @@ object Parsers {
else from
}

val handleImport: Tree => Tree = { tree: Tree =>
val handleImport: Tree => Tree = { (tree: Tree) =>
if (in.token == USCORE) mkTree(importGiven, tree, wildcardIdent() :: Nil)
else if (in.token == LBRACE) mkTree(importGiven, tree, inBraces(importSelectors()))
else tree
Expand Down
2 changes: 1 addition & 1 deletion compiler/test-resources/repl/toplevelTry
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
scala> try { 0 } catch { _: Throwable => 1 }
scala> try { 0 } catch { (_: Throwable) => 1 }
val res0: Int = 0
10 changes: 5 additions & 5 deletions tests/neg/i5592.scala
Original file line number Diff line number Diff line change
Expand Up @@ -11,19 +11,19 @@ object Test {
}

// these are both fine
val eqReflexive1: (x: Obj) => (EQ[x.type, x.type]) = { x: Obj => implicitly }
val eqReflexive2: Forall[[x] =>> EQ[x, x]] = { x: Obj => implicitly }
val eqReflexive1: (x: Obj) => (EQ[x.type, x.type]) = { (x: Obj) => implicitly }
val eqReflexive2: Forall[[x] =>> EQ[x, x]] = { (x: Obj) => implicitly }

// this compiles
val eqSymmetric1: (x: Obj) => (y: Obj) => EQ[x.type, y.type] => EQ[y.type, x.type] = {
{ x: Obj => { y: Obj => { xEqy: EQ[x.type, y.type] => xEqy.commute } } }
{ (x: Obj) => { (y: Obj) => { (xEqy: EQ[x.type, y.type]) => xEqy.commute } } }
}

val eqSymmetric2: Forall[[x] =>> (y: Obj) => (EQ[x, y.type]) => (EQ[y.type, x])] = {
{ x: Obj => { y: Obj => { xEqy: EQ[x.type, y.type] => xEqy.commute } } } // error
{ (x: Obj) => { (y: Obj) => { (xEqy: EQ[x.type, y.type]) => xEqy.commute } } } // error
}

val eqSymmetric3: Forall[[x] =>> Forall[[y] =>> EQ[x, y] => EQ[y, x]]] = {
{ x: Obj => { y: Obj => { xEqy: EQ[x.type, y.type] => xEqy.commute } } } // error
{ (x: Obj) => { (y: Obj) => { (xEqy: EQ[x.type, y.type]) => xEqy.commute } } } // error
}
}
2 changes: 1 addition & 1 deletion tests/new/patterns.scala
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,6 @@ object test {
trait John[A,B] {
def filter(x:Any) = x match {
case (x::xs, _) => "ga"
case _ => {x:String => "foobar"}
case _ => { (x:String) => "foobar"}
}
}
4 changes: 2 additions & 2 deletions tests/pos/depmet_implicit_norm_ret.scala
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@ object Test{
// bug: inferred return type = (Stream[A]) => java.lang.Object with Test.ZipWith[B]{type T = Stream[B]}#T
// this seems incompatible with vvvvvvvvvvvvvvvvvvvvvv -- #3731
def map1[A,B](f : A => B) = ZipWith(f)(SuccZipWith) // this typechecks but fails in -Ycheck:first
val tst1: Stream[Int] = map1[String, Int]{x: String => x.length}.apply(Stream("a"))
val tst1: Stream[Int] = map1[String, Int]{(x: String) => x.length}.apply(Stream("a"))

def map2[A,B](f : A => B) = ZipWith(f) // this finds ZeroZipWith where scalac finds SuccZipWith and fails typechecking in the next line.
val tst2: Stream[Int] = map2{x: String => x.length}.apply(Stream("a"))
val tst2: Stream[Int] = map2{(x: String) => x.length}.apply(Stream("a"))
}
2 changes: 1 addition & 1 deletion tests/pos/gadt-TypeSafeLambda.scala
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ object TypeSafeLambda {
val interped: (Env) => String =
interp[Term, Exp, Prod, Arr, Env, String] (c, exp)

interped((((), 1), { i: Int => i.toString })) : String // "1"
interped((((), 1), { (i: Int) => i.toString })) : String // "1"
}

}
6 changes: 3 additions & 3 deletions tests/pos/i94-nada.scala
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ trait Test1 {
case class Left[A,B](x: A) extends Either[A,B] with Monad[A]
case class Right[A,B](x: B) extends Either[A,B] with Monad[B]
def flatMap[X,Y,M[X]<:Monad[X]](m: M[X], f: X => M[Y]): M[Y] = f(m.x)
println(flatMap(Right(1), {x: Int => Right(x)}))
println(flatMap(Right(1), {(x: Int) => Right(x)}))
}
trait Test2 {
trait Monad[X] {
Expand All @@ -35,9 +35,9 @@ trait Test2 {
case class Left[A,B](x: A) extends Either[A,B] with Monad[A]
case class Right[A,B](x: B) extends Either[A,B] with Monad[B]
def flatMap[X,Y,M[X]](m: M[X], f: X => M[Y]): M[Y]
println(flatMap(Left(1), {x: Int => Left(x)}))
println(flatMap(Left(1), {(x: Int) => Left(x)}))
}
trait Test3 {
def flatMap[X,Y,M[X]](m: M[X], f: X => M[Y]): M[Y]
println(flatMap(Some(1), {x: Int => Some(x)}))
println(flatMap(Some(1), {(x: Int) => Some(x)}))
}
2 changes: 1 addition & 1 deletion tests/pos/pat_gilles.scala
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
abstract class Table2 {


val x: Any => Unit = { zz:Any =>
val x: Any => Unit = { (zz:Any) =>
zz match {
case Table2.CellUpdated(row, column) =>
val foo = Table2.CellUpdated(2,2)
Expand Down
2 changes: 1 addition & 1 deletion tests/pos/t0438.scala
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
class Foo {
implicit def pair2fun2[A, B, C](f: (A, B) => C): ((A, B)) => C =
{p: (A, B) => f(p._1, p._2) }
{(p: (A, B)) => f(p._1, p._2) }

def foo(f: ((Int, Int)) => Int) = f
def bar(x: Int, y: Int) = x + y
Expand Down
4 changes: 2 additions & 2 deletions tests/pos/t3672.scala
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
object Test {
def foo(f: Int => Int) = () ; foo { implicit x : Int => x + 1 }
def bar(f: Int => Int) = () ; foo { x : Int => x + 1 }
def foo(f: Int => Int) = () ; foo { implicit (x : Int) => x + 1 }
def bar(f: Int => Int) = () ; foo { (x : Int) => x + 1 }
}
2 changes: 1 addition & 1 deletion tests/pos/tcpoly_typesub.scala
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ trait TypeSub {
def castSub[f[+x]](fl : f[l]) : f[u]
def castSuper[f[-x]](fu : f[u]) : f[l] = {
type c[+y] = f[y] => f[l]
castSub[c]{ fl : f[l] => fl }(fu)
castSub[c]{ (fl : f[l]) => fl }(fu)
}
def castValue[t](lt : l with t) : u with t = {
type c[+y] = y with t
Expand Down
4 changes: 2 additions & 2 deletions tests/run-custom-args/no-useless-forwarders.scala
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@ trait B {

object Test extends A with B{
def main(args: Array[String]) = {
assert(!this.getClass.getDeclaredMethods.exists{x: java.lang.reflect.Method => x.getName == "foo"},
assert(!this.getClass.getDeclaredMethods.exists{(x: java.lang.reflect.Method) => x.getName == "foo"},
"no forwarder is needed here")
assert(!this.getClass.getDeclaredMethods.exists{x: java.lang.reflect.Method => x.getName == "bar"},
assert(!this.getClass.getDeclaredMethods.exists{(x: java.lang.reflect.Method) => x.getName == "bar"},
"no forwarder is needed here")
}
}
2 changes: 1 addition & 1 deletion tests/run-staging/staged-streams_1.scala
Original file line number Diff line number Diff line change
Expand Up @@ -437,7 +437,7 @@ object Test {
})
case Many => producer.init(st => '{
val oldnadv: Unit => Unit = ${nadv.get}
val adv1: Unit => Unit = { _: Unit => {
val adv1: Unit => Unit = { (_: Unit) => {
if(${producer.hasNext(st)}) {
${producer.step(st, k)}
}
Expand Down
14 changes: 7 additions & 7 deletions tests/run/Course-2002-02.scala
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ object M4 {
def sumInts = sum(x => x)
def sumCubes = sum(x => x * x * x)
def sumReciprocals = sum(1.0/_)
def sumPi = { n: Int => 4 + sum(x => 4.0/(4*x+1) - 4.0/(4*x-1))(1, n) }
def sumPi = { (n: Int) => 4 + sum(x => 4.0/(4*x+1) - 4.0/(4*x-1))(1, n) }

Console.println(sumInts(1,4))
Console.println(sumCubes(1,4))
Expand All @@ -122,7 +122,7 @@ object M5 {
def sumInts = sum(x => x)
def sumCubes = sum(x => x * x * x)
def sumReciprocals = sum(x => 1.0/x)
def sumPi = { n: Int => 4 + sum(x => 4.0/(4*x+1) - 4.0/(4*x-1))(1, n) }
def sumPi = { (n: Int) => 4 + sum(x => 4.0/(4*x+1) - 4.0/(4*x-1))(1, n) }

Console.println(sumInts(1,4))
Console.println(sumCubes(1,4))
Expand All @@ -142,7 +142,7 @@ object M6 {
def sumInts = sum(x => x)_
def sumCubes = sum(x => x * x * x)_
def sumReciprocals = sum(x => 1.0/x)_
def sumPi = { n: Int => 4 + sum(x => 4.0/(4*x+1) - 4.0/(4*x-1))(1, n) }
def sumPi = { (n: Int) => 4 + sum(x => 4.0/(4*x+1) - 4.0/(4*x-1))(1, n) }

Console.println(sumInts(1,4))
Console.println(sumCubes(1,4))
Expand All @@ -165,7 +165,7 @@ object M7 {
def sumInts = sum(x => x)_
def sumCubes = sum(x => x * x * x)_
def sumReciprocals = sum(x => 1.0/x)_
def sumPi = { n: Int => 4 + sum(x => 4.0/(4*x+1) - 4.0/(4*x-1))(1, n) }
def sumPi = { (n: Int) => 4 + sum(x => 4.0/(4*x+1) - 4.0/(4*x-1))(1, n) }

Console.println(sumInts(1,4))
Console.println(sumCubes(1,4))
Expand All @@ -182,7 +182,7 @@ object M8 {
if (a > b) 1
else f(a) * product(f)(a + step, step, b);

def productPi = { n: Int => product(x=>4.0*x*x/(2*x-1)/(2*x-1))(1,1,n)/n }
def productPi = { (n: Int) => product(x=>4.0*x*x/(2*x-1)/(2*x-1))(1,1,n)/n }

val pi = 2 * product(x => x * x)(2, 2, 40) / product(x => x * x)(1, 2,40)/40;

Expand Down Expand Up @@ -210,9 +210,9 @@ object M9 {
def sumInts = sum(x => x)
def sumCubes = sum(x => x * x * x)
def sumReciprocals = sum(x => 1.0 / x)
def sumPi = { n: Int => 4 + sum(x => 4.0/(4*x+1) - 4.0/(4*x-1))(1, n) }
def sumPi = { (n: Int) => 4 + sum(x => 4.0/(4*x+1) - 4.0/(4*x-1))(1, n) }

def productPi = { n: Int => product(x=>4.0*x*x/(2*x-1)/(2*x-1))(1,n)/n }
def productPi = { (n: Int) => product(x=>4.0*x*x/(2*x-1)/(2*x-1))(1,n)/n }

val pi = 2*product(x => 2*x*2*x)(1,20)/product(x =>(2*x-1)*(2*x-1))(1,20)/40

Expand Down
4 changes: 2 additions & 2 deletions tests/run/Course-2002-05.scala
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ object M0 {
xs
else {
val pivot = xs.head;
val sub = partition(xs.tail, { elem : a => less(elem, pivot) });
val sub = partition(xs.tail, { (elem : a) => less(elem, pivot) });
quicksort(less)(sub._1) ::: List(pivot) ::: quicksort(less)(sub._2)
}
}
Expand Down Expand Up @@ -96,7 +96,7 @@ object M2 {
else {
val x = s.head;
val withoutX = powerset(s.tail);
withoutX ::: withoutX.map { s1 : List[a] => x::s1 }
withoutX ::: withoutX.map { (s1 : List[a]) => x::s1 }
}
}

Expand Down
6 changes: 3 additions & 3 deletions tests/run/Course-2002-06.scala
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@ object M0 {
* changing the appearance of the painter
*/
def transformPainter(origin: Vector, newX: Vector, newY: Vector)(painter: Painter): Painter = {
frame: Frame => {
(frame: Frame) => {
val newOrigin = frame.coordMap(origin);
val newFrame = new Frame(newOrigin,
frame.coordMap(newX) - newOrigin,
Expand All @@ -182,7 +182,7 @@ object M0 {
/** Compose a painter that draws p1 on the left of p2
*/
def beside(p1: Painter, p2: Painter) : Painter = {
frame: Frame => {
(frame: Frame) => {
transformPainter(new Vector(0.0, 0.0),
new Vector(0.5, 0.0),
new Vector(0.0, 1.0))(p1)(frame);
Expand All @@ -195,7 +195,7 @@ object M0 {
/** Compose a painter that draws p1 below p2
*/
def below(p1: Painter, p2: Painter): Painter = {
frame: Frame => {
(frame: Frame) => {
transformPainter(new Vector(0.0, 0.0),
new Vector(1.0, 0.0),
new Vector(0.0, 0.5))(p1)(frame);
Expand Down
6 changes: 3 additions & 3 deletions tests/run/Course-2002-10.scala
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ object M0 {
object M1 {

def scale(x: Double, s: LazyList[Double]): LazyList[Double] =
s map { e: Double => e*x }
s map { (e: Double) => e*x }

def partialSums(s: LazyList[Double]): LazyList[Double] =
LazyList.cons(s.head, partialSums(s.tail) map (x => x + s.head));
Expand All @@ -45,14 +45,14 @@ object M1 {
better(s, transform) map (x => x.head);

def lnSummands(n: Double): LazyList[Double] =
LazyList.cons(1.0 / n, lnSummands(n + 1.0) map { x: Double => -x })
LazyList.cons(1.0 / n, lnSummands(n + 1.0) map { (x: Double) => -x })

var ln0 = partialSums(lnSummands(1.0));
var ln1 = euler(ln0);
var ln2 = veryGood(ln0, euler);

def piSummands(n: Double): LazyList[Double] =
LazyList.cons(1.0 / n, piSummands(n + 2.0) map { x: Double => -x })
LazyList.cons(1.0 / n, piSummands(n + 2.0) map { (x: Double) => -x })

var pi0 = scale(4.0, partialSums(piSummands(1.0)));
var pi1 = euler(pi0);
Expand Down
8 changes: 4 additions & 4 deletions tests/run/implicitFuns.scala
Original file line number Diff line number Diff line change
Expand Up @@ -191,17 +191,17 @@ object TransactionalExpansion {
trans.commit()
}

def thisTransaction = $t: Transaction => $t
def thisTransaction = ($t: Transaction) => $t

def f1(x: Int) = { $t: Transaction =>
def f1(x: Int) = { ($t: Transaction) =>
thisTransaction.apply($t).println(s"first step: $x")
f2(x + 1).apply($t)
}
def f2(x: Int) = { $t: Transaction =>
def f2(x: Int) = { ($t: Transaction) =>
thisTransaction.apply($t).println(s"second step: $x")
f3(x * x).apply($t)
}
def f3(x: Int) = { $t: Transaction =>
def f3(x: Int) = { ($t: Transaction) =>
thisTransaction.apply($t).println(s"third step: $x")
if (x % 2 != 0) thisTransaction.apply($t).abort()
x
Expand Down
4 changes: 2 additions & 2 deletions tests/run/iterators.scala
Original file line number Diff line number Diff line change
Expand Up @@ -95,8 +95,8 @@ object Test {
}

def check_findIndexOf: String = {
val i = List(1, 2, 3, 4, 5).indexWhere { x: Int => x >= 4 }
val j = List(1, 2, 3, 4, 5).indexWhere { x: Int => x >= 16 }
val i = List(1, 2, 3, 4, 5).indexWhere { (x: Int) => x >= 4 }
val j = List(1, 2, 3, 4, 5).indexWhere { (x: Int) => x >= 16 }
"" + i + "x" + j
}

Expand Down
4 changes: 2 additions & 2 deletions tests/run/mapConserve.scala
Original file line number Diff line number Diff line change
Expand Up @@ -28,12 +28,12 @@ object Test {
}

var callCount = 0
val lastHexDigit: Function1[BigInt, AnyRef] = { x: BigInt => callCount+=1; if (x < 16) x else x % 16 }
val lastHexDigit: Function1[BigInt, AnyRef] = { (x: BigInt) => callCount+=1; if (x < 16) x else x % 16 }

def main(args: Array[String]): Unit = {
for (length <- 0 to maxListLength;
bitmap <- 0 until (1 << length);
data = List.range(0, length) map { x: Int =>
data = List.range(0, length) map { (x: Int) =>
if ((bitmap & (1 << x)) != 0) BigInt(x+16)
else BigInt(x)
})
Expand Down
2 changes: 1 addition & 1 deletion tests/run/serialization-new.scala
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ object Test1_scala {
println()

// Function
val f1 = { x: Int => 2 * x }
val f1 = { (x: Int) => 2 * x }
val _f1: Function[Int, Int] = read(write(f1))
println("f1 = <na>")
println("_f1 = <na>")
Expand Down
2 changes: 1 addition & 1 deletion tests/run/t216.scala
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
object Test extends App {
object m {
val f = { x: Unit => () }
val f = { (x: Unit) => () }
Console.println("OK")
}
m;
Expand Down
2 changes: 1 addition & 1 deletion tests/run/t5629b.scala
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ object Test extends App {
trait MySmartPF[@specialized(Int) -A] extends MyPF[A] {
def apply(x: A): Unit = {
println("MySmartPF.apply entered...")
applyOrElse(x, { default: Any => throw new MatchError(default) })
applyOrElse(x, { (default: Any) => throw new MatchError(default) })
}
}

Expand Down
2 changes: 1 addition & 1 deletion tests/run/t5665.scala
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ object O {
trait T {
private[this] val c: Int = 42
def f =
{ x: Int => c }
{ (x: Int) => c }
}
}

Expand Down
4 changes: 2 additions & 2 deletions tests/run/tuple-ops.scala
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,13 @@ val r5: Unit = a.zip(d)
// Map
case class Foo[X](x: X)

val r6: (Int, Int, Int) = a.map[[t] =>> Int]([t] => x: t => x match {
val r6: (Int, Int, Int) = a.map[[t] =>> Int]([t] => (x: t) => x match {
case x: Int => x * x
case _ => ???
})

val r7: ((1, Foo[1]), (2, Foo[2]), (3, Foo[3])) =
a.map[[t] =>> (t, Foo[t])]( [t] => x: t => (x, Foo(x)) )
a.map[[t] =>> (t, Foo[t])]( [t] => (x: t) => (x, Foo(x)) )

// More Zip
val t1: Int *: Long *: Tuple = (1, 2l, 100, 200)
Expand Down