Skip to content

Commit

Permalink
Fix scala#16801: Scala.js: Handle Closure's of s.r.FunctionXXL.
Browse files Browse the repository at this point in the history
  • Loading branch information
sjrd committed Feb 2, 2023
1 parent e751f51 commit 85a1edf
Show file tree
Hide file tree
Showing 11 changed files with 24 additions and 22 deletions.
7 changes: 5 additions & 2 deletions compiler/src/dotty/tools/backend/sjs/JSCodeGen.scala
Original file line number Diff line number Diff line change
Expand Up @@ -3532,13 +3532,16 @@ class JSCodeGen()(using genCtx: Context) {
val closure = js.Closure(arrow = true, formalCaptures, formalParams, restParam, genBody, actualCaptures)

if (!funInterfaceSym.exists || defn.isFunctionClass(funInterfaceSym)) {
assert(!funInterfaceSym.exists || defn.isFunctionClass(funInterfaceSym),
s"Invalid functional interface $funInterfaceSym reached the back-end")
val formalCount = formalParams.size
val cls = ClassName("scala.scalajs.runtime.AnonFunction" + formalCount)
val ctorName = MethodName.constructor(
jstpe.ClassRef(ClassName("scala.scalajs.js.Function" + formalCount)) :: Nil)
js.New(cls, js.MethodIdent(ctorName), List(closure))
} else if (funInterfaceSym.name == tpnme.FunctionXXL && funInterfaceSym.owner == defn.ScalaRuntimePackageClass) {
val cls = ClassName("scala.scalajs.runtime.AnonFunctionXXL")
val ctorName = MethodName.constructor(
jstpe.ClassRef(ClassName("scala.scalajs.js.Function1")) :: Nil)
js.New(cls, js.MethodIdent(ctorName), List(closure))
} else {
assert(funInterfaceSym.isJSType,
s"Invalid functional interface $funInterfaceSym reached the back-end")
Expand Down
8 changes: 8 additions & 0 deletions library-js/src/scala/scalajs/runtime/AnonFunctionXXL.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package scala.scalajs.runtime

import scala.scalajs.js

@inline
final class AnonFunctionXXL(f: js.Function1[IArray[Object], Object]) extends scala.runtime.FunctionXXL {
override def apply(xs: IArray[Object]): Object = f(xs)
}
5 changes: 4 additions & 1 deletion project/MiMaFilters.scala
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,10 @@ object MiMaFilters {
ProblemFilters.exclude[MissingClassProblem]("scala.util.boundary"),
ProblemFilters.exclude[MissingClassProblem]("scala.util.boundary$"),
ProblemFilters.exclude[MissingClassProblem]("scala.util.boundary$Break"),
ProblemFilters.exclude[MissingClassProblem]("scala.util.boundary$Label")
ProblemFilters.exclude[MissingClassProblem]("scala.util.boundary$Label"),

// Scala.js only: new runtime support class in 3.2.3; not available to users
ProblemFilters.exclude[MissingClassProblem]("scala.scalajs.runtime.AnonFunctionXXL"),
)
val TastyCore: Seq[ProblemFilter] = Seq(
ProblemFilters.exclude[DirectMissingMethodProblem]("dotty.tools.tasty.TastyBuffer.reset"),
Expand Down
2 changes: 0 additions & 2 deletions tests/run/functionXXL.scala
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
// scalajs: --skip --pending

object Test {

val f = (x1: Int,
Expand Down
2 changes: 0 additions & 2 deletions tests/run/i2004.scala
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
// scalajs: --skip --pending

object Test {
def main(args: Array[String]) = {

Expand Down
2 changes: 0 additions & 2 deletions tests/run/implicitFunctionXXL.scala
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
// scalajs: --skip --pending

object Test {

def main(args: Array[String]): Unit = {
Expand Down
2 changes: 0 additions & 2 deletions tests/run/tupled-function-andThen.scala
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
// scalajs: --skip --pending

import scala.util.TupledFunction

object Test {
Expand Down
4 changes: 1 addition & 3 deletions tests/run/tupled-function-apply.scala
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
// scalajs: --skip --pending

import scala.util.TupledFunction

object Test {
Expand Down Expand Up @@ -119,4 +117,4 @@ object Test {
*/
extension [F, Args <: Tuple, R](f: F) def apply (args: Args)(using tf: TupledFunction[F, Args => R]): R =
tf.tupled(f)(args)
}
}
2 changes: 0 additions & 2 deletions tests/run/tupled-function-compose.scala
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
// scalajs: --skip --pending

import scala.util.TupledFunction
object Test {
def main(args: Array[String]): Unit = {
Expand Down
10 changes: 6 additions & 4 deletions tests/run/tupled-function-extension-method.scala
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
// scalajs: --skip --pending

import scala.util.TupledFunction
object Test {
def main(args: Array[String]): Unit = {
Expand All @@ -13,7 +11,7 @@ object Test {
(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18, x19, x20, x21, x22, x23, x24, x25)
)

println(f0())
portablePrintln(f0())
println(f1(1))
println(f2(1, 2))
println(f3(1, 2, 3))
Expand All @@ -34,6 +32,10 @@ object Test {

}

def portablePrintln(x: Any): Unit =
if x == () then println("()")
else println(x)

class Expr[T](val x: T)

// Specialized only for arity 0 and one as auto tupling will not provide the disired effect
Expand All @@ -50,4 +52,4 @@ object Test {
extension [F, Args <: Tuple, R](e: Expr[F]) def applyGiven (args: Args)(using tf: TupledFunction[F, Args ?=> R]): R =
tf.tupled(e.x)(using args)

}
}
2 changes: 0 additions & 2 deletions tests/run/tupled-function-tupled.scala
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
// scalajs: --skip --pending

import scala.util.TupledFunction

object Test {
Expand Down

0 comments on commit 85a1edf

Please sign in to comment.