Skip to content

Commit ede1261

Browse files
authored
Pretty-print lambdas (#21846)
Before: ```scala [[syntax trees at end of typer]] // tests/printing/lambdas.scala package <empty> { final lazy module val Main: Main = new Main() final module class Main() extends Object() { this: Main.type => val f1: Int => Int = { def $anonfun(x: Int): Int = x.+(1) closure($anonfun) } val f2: (Int, Int) => Int = { def $anonfun(x: Int, y: Int): Int = x.+(y) closure($anonfun) } val f3: Int => Int => Int = { def $anonfun(x: Int): Int => Int = { def $anonfun(y: Int): Int = x.+(y) closure($anonfun) } closure($anonfun) } val f4: [T] => (x: Int) => Int = { def $anonfun[T >: Nothing <: Any](x: Int): Int = x.+(1) closure($anonfun) } val f5: [T] => (x: Int) => Int => Int = { def $anonfun[T >: Nothing <: Any](x: Int): Int => Int = { def $anonfun(y: Int): Int = x.+(y) closure($anonfun) } closure($anonfun) } val f6: Int => Int = { def $anonfun(x: Int): Int = { val x2: Int = x.+(1) x2.+(1) } closure($anonfun) } def f7(x: Int): Int = x.+(1) val f8: Int => Int = { def $anonfun(x: Int): Int = Main.f7(x) closure($anonfun) } val l: List[Int] = List.apply[Int]([1,2,3 : Int]*) Main.l.map[Int]( { def $anonfun(_$1: Int): Int = _$1.+(1) closure($anonfun) } ) Main.l.map[Int]( { def $anonfun(x: Int): Int = x.+(1) closure($anonfun) } ) Main.l.map[Int]( { def $anonfun(x: Int): Int = { val x2: Int = x.+(1) x2.+(1) } closure($anonfun) } ) Main.l.map[Int]( { def $anonfun(x: Int): Int = Main.f7(x) closure($anonfun) } ) } } ``` After: ```scala [[syntax trees at end of typer]] // tests/printing/lambdas.scala package <empty> { final lazy module val Main: Main = new Main() final module class Main() extends Object() { this: Main.type => val f1: Int => Int = (x: Int) => x.+(1) val f2: (Int, Int) => Int = (x: Int, y: Int) => x.+(y) val f3: Int => Int => Int = (x: Int) => (y: Int) => x.+(y) val f4: [T] => (x: Int) => Int = [T >: Nothing <: Any] => (x: Int) => x.+(1) val f5: [T] => (x: Int) => Int => Int = [T >: Nothing <: Any] => (x: Int) => (y: Int) => x.+(y) val f6: Int => Int = (x: Int) => { val x2: Int = x.+(1) x2.+(1) } def f7(x: Int): Int = x.+(1) val f8: Int => Int = (x: Int) => Main.f7(x) val l: List[Int] = List.apply[Int]([1,2,3 : Int]*) Main.l.map[Int]((_$1: Int) => _$1.+(1)) Main.l.map[Int]((x: Int) => x.+(1)) Main.l.map[Int]((x: Int) => { val x2: Int = x.+(1) x2.+(1) } ) Main.l.map[Int]((x: Int) => Main.f7(x)) } } ``` The ugly thing can still be displayed with `-Yprint-debug`.
2 parents f95d4b2 + eb12bfe commit ede1261

File tree

4 files changed

+50
-16
lines changed

4 files changed

+50
-16
lines changed

Diff for: compiler/src/dotty/tools/dotc/printing/RefinedPrinter.scala

+4
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import Denotations.*
1717
import SymDenotations.*
1818
import StdNames.{nme, tpnme}
1919
import ast.{Trees, tpd, untpd}
20+
import tpd.closureDef
2021
import typer.{Implicits, Namer, Applications}
2122
import typer.ProtoTypes.*
2223
import Trees.*
@@ -510,6 +511,9 @@ class RefinedPrinter(_ctx: Context) extends PlainPrinter(_ctx) {
510511
toText(name) ~ (if name.isTermName && arg.isType then " : " else " = ") ~ toText(arg)
511512
case Assign(lhs, rhs) =>
512513
changePrec(GlobalPrec) { toTextLocal(lhs) ~ " = " ~ toText(rhs) }
514+
case closureDef(meth) if !printDebug =>
515+
withEnclosingDef(meth):
516+
meth.paramss.map(paramsText).foldRight(toText(meth.rhs))(_ ~ " => " ~ _)
513517
case block: Block =>
514518
blockToText(block)
515519
case If(cond, thenp, elsep) =>

Diff for: tests/printing/annot-19846b.check

+2-16
Original file line numberDiff line numberDiff line change
@@ -7,27 +7,13 @@ package <empty> {
77
final lazy module val Test: Test = new Test()
88
final module class Test() extends Object() { this: Test.type =>
99
val y: Int = ???
10-
val z:
11-
Int @lambdaAnnot(
12-
{
13-
def $anonfun(): Int = Test.y
14-
closure($anonfun)
15-
}
16-
)
17-
= f(Test.y)
10+
val z: Int @lambdaAnnot(() => Test.y) = f(Test.y)
1811
}
1912
final lazy module val annot-19846b$package: annot-19846b$package =
2013
new annot-19846b$package()
2114
final module class annot-19846b$package() extends Object() {
2215
this: annot-19846b$package.type =>
23-
def f(x: Int):
24-
Int @lambdaAnnot(
25-
{
26-
def $anonfun(): Int = x
27-
closure($anonfun)
28-
}
29-
)
30-
= x
16+
def f(x: Int): Int @lambdaAnnot(() => x) = x
3117
}
3218
}
3319

Diff for: tests/printing/lambdas.check

+30
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
[[syntax trees at end of typer]] // tests/printing/lambdas.scala
2+
package <empty> {
3+
final lazy module val Main: Main = new Main()
4+
final module class Main() extends Object() { this: Main.type =>
5+
val f1: Int => Int = (x: Int) => x.+(1)
6+
val f2: (Int, Int) => Int = (x: Int, y: Int) => x.+(y)
7+
val f3: Int => Int => Int = (x: Int) => (y: Int) => x.+(y)
8+
val f4: [T] => (x: Int) => Int = [T >: Nothing <: Any] => (x: Int) => x.+(1)
9+
val f5: [T] => (x: Int) => Int => Int = [T >: Nothing <: Any] => (x: Int)
10+
=> (y: Int) => x.+(y)
11+
val f6: Int => Int = (x: Int) =>
12+
{
13+
val x2: Int = x.+(1)
14+
x2.+(1)
15+
}
16+
def f7(x: Int): Int = x.+(1)
17+
val f8: Int => Int = (x: Int) => Main.f7(x)
18+
val l: List[Int] = List.apply[Int]([1,2,3 : Int]*)
19+
Main.l.map[Int]((_$1: Int) => _$1.+(1))
20+
Main.l.map[Int]((x: Int) => x.+(1))
21+
Main.l.map[Int]((x: Int) =>
22+
{
23+
val x2: Int = x.+(1)
24+
x2.+(1)
25+
}
26+
)
27+
Main.l.map[Int]((x: Int) => Main.f7(x))
28+
}
29+
}
30+

Diff for: tests/printing/lambdas.scala

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
object Main:
2+
val f1 = (x: Int) => x + 1
3+
val f2 = (x: Int, y: Int) => x + y
4+
val f3 = (x: Int) => (y: Int) => x + y
5+
val f4 = [T] => (x: Int) => x + 1
6+
val f5 = [T] => (x: Int) => (y: Int) => x + y
7+
val f6 = (x: Int) => { val x2 = x + 1; x2 + 1 }
8+
def f7(x: Int) = x + 1
9+
val f8 = f7
10+
val l = List(1,2,3)
11+
l.map(_ + 1)
12+
l.map(x => x + 1)
13+
l.map(x => { val x2 = x + 1; x2 + 1 })
14+
l.map(f7)

0 commit comments

Comments
 (0)