Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 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
1 change: 1 addition & 0 deletions compiler/src/dotty/tools/dotc/Compiler.scala
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ class Compiler {
new FunctionXXLForwarders, // Add forwarders for FunctionXXL apply method
new ParamForwarding, // Add forwarders for aliases of superclass parameters
new TupleOptimizations, // Optimize generic operations on tuples
new LetOverApply, // Lift blocks from receivers of applications
new ArrayConstructors) :: // Intercept creation of (non-generic) arrays and intrinsify.
List(new Erasure) :: // Rewrite types to JVM model, erasing all type parameters, abstract types and refinements.
List(new ElimErasedValueType, // Expand erased value types to their underlying implmementation types
Expand Down
5 changes: 2 additions & 3 deletions compiler/src/dotty/tools/dotc/transform/Erasure.scala
Original file line number Diff line number Diff line change
Expand Up @@ -749,14 +749,13 @@ object Erasure {
val origFunType = origFun.tpe.widen(using preErasureCtx)
val ownArgs = if origFunType.isErasedMethod then Nil else args
val fun1 = typedExpr(fun, AnyFunctionProto)
val fun1core = stripBlock(fun1)
fun1.tpe.widen match
case mt: MethodType =>
val (xmt, // A method type like `mt` but with bunched arguments expanded to individual ones
bunchArgs, // whether arguments are bunched
outers) = // the outer reference parameter(s)
if fun1core.isInstanceOf[Apply] then
(mt, fun1core.removeAttachment(BunchedArgs).isDefined, Nil)
if fun1.isInstanceOf[Apply] then
(mt, fun1.removeAttachment(BunchedArgs).isDefined, Nil)
else
val xmt = expandedMethodType(mt, origFun)
(xmt, xmt ne mt, outer.args(origFun))
Expand Down
31 changes: 31 additions & 0 deletions compiler/src/dotty/tools/dotc/transform/LetOverApply.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package dotty.tools
package dotc
package transform

import core._
import Contexts.Context, Symbols._, Decorators._
import MegaPhase._
import ast.Trees._

/** Rewrite `{ stats; expr}.f(args) }` to `{ stats; expr.f(args) }` before
* proceeding, but leave closures alone. This is necessary to be able to
* collapse applies of IFTs (this is done in Erasure).
*/
class LetOverApply extends MiniPhase:
import ast.tpd._

override def phaseName: String = "letOverApply"

override def transformApply(tree: Apply)(using Context): Tree =
tree.fun match
case Select(blk @ Block(stats, expr), name) if !expr.isInstanceOf[Closure] =>
cpy.Block(blk)(stats,
cpy.Apply(tree)(
cpy.Select(tree.fun)(expr, name), tree.args))
case Block(stats, expr) =>
cpy.Block(tree.fun)(stats,
cpy.Apply(tree)(expr, tree.args))
case _ =>
tree

end LetOverApply
5 changes: 5 additions & 0 deletions tests/pos/i8881.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
object Crash {
def f(a: String, b: String, c: Int = 0): Int ?=> String = ""
given Int = ???
f(b = "b", a = "a")
}