Skip to content

Commit

Permalink
Fix rewrite logic for old <function> _ syntax (#21715)
Browse files Browse the repository at this point in the history
A rewrite would previously produce uncompilable
code if the access path to the eta-expanded
function goes through at least one `def`.

Fixes #21394
  • Loading branch information
bracevac authored Oct 7, 2024
2 parents 6fa81cf + e42d883 commit 9344b1e
Show file tree
Hide file tree
Showing 4 changed files with 41 additions and 3 deletions.
9 changes: 6 additions & 3 deletions compiler/src/dotty/tools/dotc/typer/Migrations.scala
Original file line number Diff line number Diff line change
Expand Up @@ -71,10 +71,13 @@ trait Migrations:
}
nestedCtx.typerState.commit()

def functionPrefixSuffix(arity: Int) = if (arity > 0) ("", "") else ("(() => ", "())")

lazy val (prefix, suffix) = res match {
case Block(mdef @ DefDef(_, vparams :: Nil, _, _) :: Nil, _: Closure) =>
val arity = vparams.length
if (arity > 0) ("", "") else ("(() => ", "())")
case Block(DefDef(_, vparams :: Nil, _, _) :: Nil, _: Closure) =>
functionPrefixSuffix(vparams.length)
case Block(ValDef(_, _, _) :: Nil, Block(DefDef(_, vparams :: Nil, _, _) :: Nil, _: Closure)) =>
functionPrefixSuffix(vparams.length)
case _ =>
("(() => ", ")")
}
Expand Down
1 change: 1 addition & 0 deletions compiler/test/dotty/tools/dotc/CompilationTests.scala
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ class CompilationTests {
compileFile("tests/rewrites/rewrites.scala", defaultOptions.and("-source", "3.0-migration").and("-rewrite", "-indent")),
compileFile("tests/rewrites/rewrites3x.scala", defaultOptions.and("-rewrite", "-source", "future-migration")),
compileFile("tests/rewrites/rewrites3x-fatal-warnings.scala", defaultOptions.and("-rewrite", "-source", "future-migration", "-Xfatal-warnings")),
compileFile("tests/rewrites/i21394.scala", defaultOptions.and("-rewrite", "-source", "future-migration")),
compileFile("tests/rewrites/uninitialized-var.scala", defaultOptions.and("-rewrite", "-source", "future-migration")),
compileFile("tests/rewrites/with-type-operator.scala", defaultOptions.and("-rewrite", "-source", "future-migration")),
compileFile("tests/rewrites/private-this.scala", defaultOptions.and("-rewrite", "-source", "future-migration")),
Expand Down
17 changes: 17 additions & 0 deletions tests/rewrites/i21394.check
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
trait Container:
def loopDef: Container
val loopVal: Container
def fun(x: Int)(y: Int): Int

def test(c: Container): Int =
use(c.fun)
+ use(c.loopDef.fun)
+ use(c.loopVal.fun)
+ use(c.loopDef.loopDef.fun)
+ use(c.loopVal.loopVal.fun)
+ use(c.loopVal.loopDef.fun)
+ use(c.loopDef.loopVal.fun)
+ use(c.loopVal.loopDef.loopVal.fun)
+ use(c.loopVal.loopDef.loopVal.loopDef.fun)

def use(f: Int => Int => Int): Int = ???
17 changes: 17 additions & 0 deletions tests/rewrites/i21394.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
trait Container:
def loopDef: Container
val loopVal: Container
def fun(x: Int)(y: Int): Int

def test(c: Container): Int =
use(c.fun _)
+ use(c.loopDef.fun _)
+ use(c.loopVal.fun _)
+ use(c.loopDef.loopDef.fun _)
+ use(c.loopVal.loopVal.fun _)
+ use(c.loopVal.loopDef.fun _)
+ use(c.loopDef.loopVal.fun _)
+ use(c.loopVal.loopDef.loopVal.fun _)
+ use(c.loopVal.loopDef.loopVal.loopDef.fun _)

def use(f: Int => Int => Int): Int = ???

0 comments on commit 9344b1e

Please sign in to comment.