Skip to content

Commit e2d0659

Browse files
committed
Fix #8881: Lift lets over applications
This is needed to correctly deal with bunched arguments arisign from IFTs. It's necessary in particular for let-bindings introduced by the compiler, e.g. when passing default araguments. User-defined blocks are not the problem since they get already eta expanded in typer.
1 parent 7a17422 commit e2d0659

File tree

3 files changed

+43
-0
lines changed

3 files changed

+43
-0
lines changed

compiler/src/dotty/tools/dotc/Compiler.scala

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@ class Compiler {
9393
new FunctionXXLForwarders, // Add forwarders for FunctionXXL apply method
9494
new ParamForwarding, // Add forwarders for aliases of superclass parameters
9595
new TupleOptimizations, // Optimize generic operations on tuples
96+
new LetOverApply, // Lift blocks from receivers of applications
9697
new ArrayConstructors) :: // Intercept creation of (non-generic) arrays and intrinsify.
9798
List(new Erasure) :: // Rewrite types to JVM model, erasing all type parameters, abstract types and refinements.
9899
List(new ElimErasedValueType, // Expand erased value types to their underlying implmementation types
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
package dotty.tools
2+
package dotc
3+
package transform
4+
5+
import core._
6+
import MegaPhase._
7+
import Contexts.Context
8+
import Symbols._, Decorators._, Types._
9+
import ast.Trees._
10+
import dotty.tools.dotc.ast.tpd
11+
12+
13+
import scala.collection.immutable.::
14+
15+
16+
/** Rewrite `{ stats; expr}.f(args) }` to `{ stats; expr.f(args) }` before
17+
* proceeding, but leave closures alone. This is necessary to be able to
18+
* collapse applies of IFTs.
19+
*/
20+
class LetOverApply extends MiniPhase:
21+
import ast.tpd._
22+
23+
override def phaseName: String = "letOverApply"
24+
25+
override def transformApply(tree: tpd.Apply)(using Context): tpd.Tree =
26+
tree.fun match
27+
case Select(blk @ Block(stats, expr), name) if !expr.isInstanceOf[Closure] =>
28+
cpy.Block(blk)(stats,
29+
cpy.Apply(tree)(
30+
cpy.Select(tree.fun)(expr, name), tree.args))
31+
case Block(stats, expr) =>
32+
cpy.Block(tree.fun)(stats,
33+
cpy.Apply(tree)(expr, tree.args))
34+
case _ =>
35+
tree
36+
37+
end LetOverApply

tests/pos/i8881.scala

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
object Crash {
2+
def f(a: String, b: String, c: Int = 0): Int ?=> String = ""
3+
given Int = ???
4+
f(b = "b", a = "a")
5+
}

0 commit comments

Comments
 (0)