Skip to content

Commit b27f55b

Browse files
authored
Upgrade to Scala.js 1.19.0. (#23026)
With minimal changes to preserve the status quo. These are forward ports of compiler, library and build changes from the following upstream commits: * scala-js/scala-js@b38201c Drop support for non-strict floats. * scala-js/scala-js@82910a0 Move well-known names to a new object `WellKnownNames`. * scala-js/scala-js@53dc4fe Introduce `NewLambda` to synthesize instances of SAM types. * scala-js/scala-js@9481522 Rewrite old IR with `AnonFunctionN` references to use `NewLambda`. From the `NewLambda` commit, we only adapt the way we compile Scala function lambdas. We do not use `NewLambda` for arbitrary SAM types yet. This is left for a future, independent commit, as it is not required for correctness. --- These are the minimal changes that have to go in 3.7.0 if we want to add support for `async/await` and JSPI in the 3.7.x line. I tried going further and actually port that as well. However I need to forward-port scala-js/scala-js@0d16b42 first. And that proves difficult because Scala 3 does not have a reliable `isDelambdafyTarget` test. Too much of Closures gets transformed away before the JS backend. I will need more time to figure this out (I'll try again tomorrow). But AFAICT we could do that in patch releases, unlike the initial upgrade to 1.19.0 that this PR does. /cc @WojciechMazur for consideration to be included as a last-minute change to 3.7.0. The idea is that we would like to get the [JSPI improvements of Scala.js 1.19.0](https://www.scala-js.org/news/2025/04/21/announcing-scalajs-1.19.0/#orphan-awaits-in-webassembly) rather sooner than later. It's a game changer for "direct style" libraries such as Ox and Gears.
2 parents 51adb13 + 12ca458 commit b27f55b

File tree

9 files changed

+97
-51
lines changed

9 files changed

+97
-51
lines changed

compiler/src/dotty/tools/backend/sjs/JSCodeGen.scala

+49-32
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ import dotty.tools.dotc.util.SourcePosition
2626
import dotty.tools.dotc.report
2727

2828
import dotty.tools.sjs.ir
29-
import dotty.tools.sjs.ir.{ClassKind, Position, Names => jsNames, Trees => js, Types => jstpe}
29+
import dotty.tools.sjs.ir.{ClassKind, Position, Trees => js, Types => jstpe, WellKnownNames => jswkn}
3030
import dotty.tools.sjs.ir.Names.{ClassName, LocalName, MethodName, SimpleMethodName}
3131
import dotty.tools.sjs.ir.OriginalName
3232
import dotty.tools.sjs.ir.OriginalName.NoOriginalName
@@ -133,7 +133,7 @@ class JSCodeGen()(using genCtx: Context) {
133133
def currentThisType: jstpe.Type = {
134134
currentThisTypeNullable match {
135135
case tpe @ jstpe.ClassType(cls, _) =>
136-
jstpe.BoxedClassToPrimType.getOrElse(cls, tpe.toNonNullable)
136+
jswkn.BoxedClassToPrimType.getOrElse(cls, tpe.toNonNullable)
137137
case tpe @ jstpe.AnyType =>
138138
// We are in a JS class, in which even `this` is nullable
139139
tpe
@@ -424,7 +424,7 @@ class JSCodeGen()(using genCtx: Context) {
424424

425425
val staticInitializerStats = reflectInit ::: staticModuleInit
426426
if (staticInitializerStats.nonEmpty)
427-
List(genStaticConstructorWithStats(ir.Names.StaticInitializerName, js.Block(staticInitializerStats)))
427+
List(genStaticConstructorWithStats(jswkn.StaticInitializerName, js.Block(staticInitializerStats)))
428428
else
429429
Nil
430430
}
@@ -453,7 +453,7 @@ class JSCodeGen()(using genCtx: Context) {
453453
originalName,
454454
ClassKind.Class,
455455
None,
456-
Some(js.ClassIdent(ir.Names.ObjectClass)),
456+
Some(js.ClassIdent(jswkn.ObjectClass)),
457457
Nil,
458458
None,
459459
None,
@@ -574,7 +574,7 @@ class JSCodeGen()(using genCtx: Context) {
574574

575575
if (staticFields.nonEmpty) {
576576
generatedMethods +=
577-
genStaticConstructorWithStats(ir.Names.ClassInitializerName, genLoadModule(companionModuleClass))
577+
genStaticConstructorWithStats(jswkn.ClassInitializerName, genLoadModule(companionModuleClass))
578578
}
579579

580580
(staticFields, staticExports)
@@ -1000,7 +1000,7 @@ class JSCodeGen()(using genCtx: Context) {
10001000
val fqcnArg = js.StringLiteral(sym.fullName.toString)
10011001
val runtimeClassArg = js.ClassOf(toTypeRef(sym.info))
10021002
val loadModuleFunArg =
1003-
js.Closure(arrow = true, Nil, Nil, None, genLoadModule(sym), Nil)
1003+
js.Closure(js.ClosureFlags.arrow, Nil, Nil, None, jstpe.AnyType, genLoadModule(sym), Nil)
10041004

10051005
val stat = genApplyMethod(
10061006
genLoadModule(jsdefn.ReflectModule),
@@ -1035,7 +1035,7 @@ class JSCodeGen()(using genCtx: Context) {
10351035

10361036
val paramTypesArray = js.JSArrayConstr(parameterTypes)
10371037

1038-
val newInstanceFun = js.Closure(arrow = true, Nil, formalParams, None, {
1038+
val newInstanceFun = js.Closure(js.ClosureFlags.arrow, Nil, formalParams, None, jstpe.AnyType, {
10391039
js.New(encodeClassName(sym), encodeMethodSym(ctor), actualParams)
10401040
}, Nil)
10411041

@@ -2389,7 +2389,7 @@ class JSCodeGen()(using genCtx: Context) {
23892389
// Make new class def with static members
23902390
val newClassDef = {
23912391
implicit val pos = originalClassDef.pos
2392-
val parent = js.ClassIdent(jsNames.ObjectClass)
2392+
val parent = js.ClassIdent(jswkn.ObjectClass)
23932393
js.ClassDef(originalClassDef.name, originalClassDef.originalName,
23942394
ClassKind.AbstractJSType, None, Some(parent), interfaces = Nil,
23952395
jsSuperClass = None, jsNativeLoadSpec = None, fields = Nil,
@@ -2427,7 +2427,7 @@ class JSCodeGen()(using genCtx: Context) {
24272427
js.VarRef(selfIdent.name)(jstpe.AnyType)
24282428

24292429
def memberLambda(params: List[js.ParamDef], restParam: Option[js.ParamDef], body: js.Tree)(implicit pos: ir.Position): js.Closure =
2430-
js.Closure(arrow = false, captureParams = Nil, params, restParam, body, captureValues = Nil)
2430+
js.Closure(js.ClosureFlags.function, captureParams = Nil, params, restParam, jstpe.AnyType, body, captureValues = Nil)
24312431

24322432
val fieldDefinitions = jsFieldDefs.toList.map { fdef =>
24332433
implicit val pos = fdef.pos
@@ -2539,7 +2539,8 @@ class JSCodeGen()(using genCtx: Context) {
25392539
beforeSuper ::: superCall ::: afterSuper
25402540
}
25412541

2542-
val closure = js.Closure(arrow = true, jsClassCaptures, Nil, None,
2542+
// Wrap everything in a lambda, for namespacing
2543+
val closure = js.Closure(js.ClosureFlags.arrow, jsClassCaptures, Nil, None, jstpe.AnyType,
25432544
js.Block(inlinedCtorStats, selfRef), jsSuperClassValue :: args)
25442545
js.JSFunctionApply(closure, Nil)
25452546
}
@@ -3350,7 +3351,7 @@ class JSCodeGen()(using genCtx: Context) {
33503351

33513352
// Sanity check: we can handle Ints and Strings (including `null`s), but nothing else
33523353
genSelector.tpe match {
3353-
case jstpe.IntType | jstpe.ClassType(jsNames.BoxedStringClass, _) | jstpe.NullType | jstpe.NothingType =>
3354+
case jstpe.IntType | jstpe.ClassType(jswkn.BoxedStringClass, _) | jstpe.NullType | jstpe.NothingType =>
33543355
// ok
33553356
case _ =>
33563357
abortMatch(s"Invalid selector type ${genSelector.tpe}")
@@ -3514,6 +3515,8 @@ class JSCodeGen()(using genCtx: Context) {
35143515
atPhase(elimRepeatedPhase)(samMethod.info.paramInfoss.flatten.exists(_.isRepeatedParam))
35153516
}
35163517
}
3518+
val isFunctionXXL =
3519+
funInterfaceSym.name == tpnme.FunctionXXL && funInterfaceSym.owner == defn.ScalaRuntimePackageClass
35173520

35183521
val formalParamNames = sym.info.paramNamess.flatten.drop(envSize)
35193522
val formalParamTypes = sym.info.paramInfoss.flatten.drop(envSize)
@@ -3523,8 +3526,11 @@ class JSCodeGen()(using genCtx: Context) {
35233526

35243527
val formalAndActualParams = formalParamNames.lazyZip(formalParamTypes).lazyZip(formalParamRepeateds).map {
35253528
(name, tpe, repeated) =>
3529+
val formalTpe =
3530+
if (isFunctionXXL) jstpe.ArrayType(ObjectArrayTypeRef, nullable = true)
3531+
else jstpe.AnyType
35263532
val formalParam = js.ParamDef(freshLocalIdent(name),
3527-
OriginalName(name.toString), jstpe.AnyType, mutable = false)
3533+
OriginalName(name.toString), formalTpe, mutable = false)
35283534
val actualParam =
35293535
if (repeated) genJSArrayToVarArgs(formalParam.ref)(tree.sourcePos)
35303536
else unbox(formalParam.ref, tpe)
@@ -3559,34 +3565,44 @@ class JSCodeGen()(using genCtx: Context) {
35593565
if (isThisFunction) {
35603566
val thisParam :: otherParams = formalParams: @unchecked
35613567
js.Closure(
3562-
arrow = false,
3568+
js.ClosureFlags.function,
35633569
formalCaptures,
35643570
otherParams,
35653571
restParam,
3572+
jstpe.AnyType,
35663573
js.Block(
35673574
js.VarDef(thisParam.name, thisParam.originalName,
35683575
thisParam.ptpe, mutable = false,
35693576
js.This()(thisParam.ptpe)(thisParam.pos))(thisParam.pos),
35703577
genBody),
35713578
actualCaptures)
35723579
} else {
3573-
val closure = js.Closure(arrow = true, formalCaptures, formalParams, restParam, genBody, actualCaptures)
3580+
val closure = js.Closure(js.ClosureFlags.typed, formalCaptures,
3581+
formalParams, restParam, jstpe.AnyType, genBody, actualCaptures)
35743582

35753583
if (!funInterfaceSym.exists || defn.isFunctionClass(funInterfaceSym)) {
35763584
val formalCount = formalParams.size
3577-
val cls = ClassName("scala.scalajs.runtime.AnonFunction" + formalCount)
3578-
val ctorName = MethodName.constructor(
3579-
jstpe.ClassRef(ClassName("scala.scalajs.js.Function" + formalCount)) :: Nil)
3580-
js.New(cls, js.MethodIdent(ctorName), List(closure))
3581-
} else if (funInterfaceSym.name == tpnme.FunctionXXL && funInterfaceSym.owner == defn.ScalaRuntimePackageClass) {
3582-
val cls = ClassName("scala.scalajs.runtime.AnonFunctionXXL")
3583-
val ctorName = MethodName.constructor(
3584-
jstpe.ClassRef(ClassName("scala.scalajs.js.Function1")) :: Nil)
3585-
js.New(cls, js.MethodIdent(ctorName), List(closure))
3585+
val descriptor = js.NewLambda.Descriptor(
3586+
superClass = encodeClassName(defn.AbstractFunctionClass(formalCount)),
3587+
interfaces = Nil,
3588+
methodName = MethodName(applySimpleMethodName, List.fill(formalCount)(jswkn.ObjectRef), jswkn.ObjectRef),
3589+
paramTypes = List.fill(formalCount)(jstpe.AnyType),
3590+
resultType = jstpe.AnyType
3591+
)
3592+
js.NewLambda(descriptor, closure)(encodeClassType(defn.FunctionSymbol(formalCount)).toNonNullable)
3593+
} else if (isFunctionXXL) {
3594+
val descriptor = js.NewLambda.Descriptor(
3595+
superClass = jswkn.ObjectClass,
3596+
interfaces = List(encodeClassName(defn.FunctionXXLClass)),
3597+
methodName = MethodName(applySimpleMethodName, List(ObjectArrayTypeRef), jswkn.ObjectRef),
3598+
paramTypes = List(jstpe.ArrayType(ObjectArrayTypeRef, nullable = true)),
3599+
resultType = jstpe.AnyType
3600+
)
3601+
js.NewLambda(descriptor, closure)(encodeClassType(funInterfaceSym).toNonNullable)
35863602
} else {
35873603
assert(funInterfaceSym.isJSType,
35883604
s"Invalid functional interface $funInterfaceSym reached the back-end")
3589-
closure
3605+
closure.copy(flags = js.ClosureFlags.arrow)
35903606
}
35913607
}
35923608
}
@@ -3699,8 +3715,8 @@ class JSCodeGen()(using genCtx: Context) {
36993715
}
37003716

37013717
private def genThrowClassCastException()(implicit pos: Position): js.Tree = {
3702-
js.UnaryOp(js.UnaryOp.Throw, js.New(jsNames.ClassCastExceptionClass,
3703-
js.MethodIdent(jsNames.NoArgConstructorName), Nil))
3718+
js.UnaryOp(js.UnaryOp.Throw, js.New(jswkn.ClassCastExceptionClass,
3719+
js.MethodIdent(jswkn.NoArgConstructorName), Nil))
37043720
}
37053721

37063722
/** Gen JS code for an isInstanceOf test (for reference types only) */
@@ -3987,7 +4003,7 @@ class JSCodeGen()(using genCtx: Context) {
39874003
case arg: js.JSGlobalRef => js.JSTypeOfGlobalRef(arg)
39884004
case _ => js.JSUnaryOp(js.JSUnaryOp.typeof, arg)
39894005
}
3990-
js.AsInstanceOf(typeofExpr, jstpe.ClassType(jsNames.BoxedStringClass, nullable = true))
4006+
js.AsInstanceOf(typeofExpr, jstpe.ClassType(jswkn.BoxedStringClass, nullable = true))
39914007

39924008
case STRICT_EQ =>
39934009
// js.special.strictEquals(arg1, arg2)
@@ -4235,7 +4251,7 @@ class JSCodeGen()(using genCtx: Context) {
42354251
"literal classOf[T] expressions (typically compiler-generated). " +
42364252
"Other uses are not supported in Scala.js.",
42374253
otherTree.sourcePos)
4238-
(jstpe.AnyType, jstpe.ClassRef(jsNames.ObjectClass))
4254+
(jstpe.AnyType, jstpe.ClassRef(jswkn.ObjectClass))
42394255
}
42404256

42414257
// Gen the actual args, downcasting them to the formal param types
@@ -4870,16 +4886,17 @@ object JSCodeGen {
48704886
private val JSObjectClassName = ClassName("scala.scalajs.js.Object")
48714887
private val JavaScriptExceptionClassName = ClassName("scala.scalajs.js.JavaScriptException")
48724888

4873-
private val ObjectClassRef = jstpe.ClassRef(ir.Names.ObjectClass)
4889+
private val ObjectArrayTypeRef = jstpe.ArrayTypeRef(jswkn.ObjectRef, 1)
48744890

4891+
private val applySimpleMethodName = SimpleMethodName("apply")
48754892
private val newSimpleMethodName = SimpleMethodName("new")
48764893

4877-
private val selectedValueMethodName = MethodName("selectedValue", Nil, ObjectClassRef)
4894+
private val selectedValueMethodName = MethodName("selectedValue", Nil, jswkn.ObjectRef)
48784895

48794896
private val JLRArrayNewInstanceMethodName =
4880-
MethodName("newInstance", List(jstpe.ClassRef(jsNames.ClassClass), jstpe.ArrayTypeRef(jstpe.IntRef, 1)), ObjectClassRef)
4897+
MethodName("newInstance", List(jstpe.ClassRef(jswkn.ClassClass), jstpe.ArrayTypeRef(jstpe.IntRef, 1)), jswkn.ObjectRef)
48814898

4882-
private val ObjectArgConstructorName = MethodName.constructor(List(ObjectClassRef))
4899+
private val ObjectArgConstructorName = MethodName.constructor(List(jswkn.ObjectRef))
48834900

48844901
private val thisOriginalName = OriginalName("this")
48854902

compiler/src/dotty/tools/backend/sjs/JSEncoding.scala

+7-4
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ import StdNames.*
1616
import dotty.tools.dotc.transform.sjs.JSSymUtils.*
1717

1818
import dotty.tools.sjs.ir
19-
import dotty.tools.sjs.ir.{Trees => js, Types => jstpe}
19+
import dotty.tools.sjs.ir.{Trees => js, Types => jstpe, WellKnownNames => jswkn}
2020
import dotty.tools.sjs.ir.Names.{LocalName, LabelName, SimpleFieldName, FieldName, SimpleMethodName, MethodName, ClassName}
2121
import dotty.tools.sjs.ir.OriginalName
2222
import dotty.tools.sjs.ir.OriginalName.NoOriginalName
@@ -235,7 +235,7 @@ object JSEncoding {
235235

236236
def encodeDynamicImportForwarderIdent(params: List[Symbol])(using Context, ir.Position): js.MethodIdent = {
237237
val paramTypeRefs = params.map(sym => paramOrResultTypeRef(sym.info))
238-
val resultTypeRef = jstpe.ClassRef(ir.Names.ObjectClass)
238+
val resultTypeRef = jstpe.ClassRef(jswkn.ObjectClass)
239239
val methodName = MethodName(dynamicImportForwarderSimpleName, paramTypeRefs, resultTypeRef)
240240
js.MethodIdent(methodName)
241241
}
@@ -282,7 +282,7 @@ object JSEncoding {
282282
* - scala.Null to scala.runtime.Null$.
283283
*/
284284
if (sym1 == defn.BoxedUnitClass)
285-
ir.Names.BoxedUnitClass
285+
jswkn.BoxedUnitClass
286286
else if (sym1 == defn.NothingClass)
287287
ScalaRuntimeNothingClassName
288288
else if (sym1 == defn.NullClass)
@@ -326,6 +326,9 @@ object JSEncoding {
326326

327327
case typeRef: jstpe.ArrayTypeRef =>
328328
jstpe.ArrayType(typeRef, nullable = true)
329+
330+
case typeRef: jstpe.TransientTypeRef =>
331+
throw AssertionError(s"Unexpected transient type ref $typeRef for ${typeRefInternal._2}")
329332
}
330333
}
331334

@@ -359,7 +362,7 @@ object JSEncoding {
359362
*/
360363
def nonClassTypeRefToTypeRef(sym: Symbol): (jstpe.TypeRef, Symbol) = {
361364
//assert(sym.isType && isCompilingArray, sym)
362-
(jstpe.ClassRef(ir.Names.ObjectClass), defn.ObjectClass)
365+
(jstpe.ClassRef(jswkn.ObjectClass), defn.ObjectClass)
363366
}
364367

365368
tp.widenDealias match {

compiler/src/dotty/tools/backend/sjs/JSExportsGen.scala

+4-5
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,7 @@ import TypeErasure.ErasedValueType
2222
import dotty.tools.dotc.util.{SourcePosition, SrcPos}
2323
import dotty.tools.dotc.report
2424

25-
import dotty.tools.sjs.ir.{Position, Names => jsNames, Trees => js, Types => jstpe}
26-
import dotty.tools.sjs.ir.Names.DefaultModuleID
25+
import dotty.tools.sjs.ir.{Position, Names => jsNames, Trees => js, Types => jstpe, WellKnownNames => jswkn}
2726
import dotty.tools.sjs.ir.OriginalName.NoOriginalName
2827
import dotty.tools.sjs.ir.Position.NoPosition
2928
import dotty.tools.sjs.ir.Trees.OptimizerHints
@@ -87,7 +86,7 @@ final class JSExportsGen(jsCodeGen: JSCodeGen)(using Context) {
8786
symForAnnot.annotations.collect {
8887
case annot if annot.symbol == jsdefn.JSExportTopLevelAnnot =>
8988
val jsName = annot.argumentConstantString(0).get
90-
val moduleID = annot.argumentConstantString(1).getOrElse(DefaultModuleID)
89+
val moduleID = annot.argumentConstantString(1).getOrElse(jswkn.DefaultModuleID)
9190
TopLevelExportInfo(moduleID, jsName)(annot.tree.sourcePos)
9291
}
9392
}
@@ -947,8 +946,8 @@ final class JSExportsGen(jsCodeGen: JSCodeGen)(using Context) {
947946
case jstpe.FloatType => PrimitiveTypeTest(jstpe.FloatType, 7)
948947
case jstpe.DoubleType => PrimitiveTypeTest(jstpe.DoubleType, 8)
949948

950-
case jstpe.ClassType(Names.BoxedUnitClass, _) => PrimitiveTypeTest(jstpe.UndefType, 0)
951-
case jstpe.ClassType(Names.BoxedStringClass, _) => PrimitiveTypeTest(jstpe.StringType, 9)
949+
case jstpe.ClassType(jswkn.BoxedUnitClass, _) => PrimitiveTypeTest(jstpe.UndefType, 0)
950+
case jstpe.ClassType(jswkn.BoxedStringClass, _) => PrimitiveTypeTest(jstpe.StringType, 9)
952951
case jstpe.ClassType(_, _) => InstanceOfTypeTest(tpe)
953952

954953
case jstpe.ArrayType(_, _) => InstanceOfTypeTest(tpe)

compiler/src/dotty/tools/dotc/transform/sjs/PrepJSExports.scala

+1-1
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ import dotty.tools.backend.sjs.JSDefinitions.jsdefn
2121
import JSExportUtils.*
2222
import JSSymUtils.*
2323

24-
import dotty.tools.sjs.ir.Names.DefaultModuleID
24+
import dotty.tools.sjs.ir.WellKnownNames.DefaultModuleID
2525
import dotty.tools.sjs.ir.Trees.TopLevelExportDef.isValidTopLevelExportName
2626

2727
object PrepJSExports {
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,25 @@
11
package scala.scalajs.runtime
22

3-
import scala.scalajs.js
4-
5-
@inline
6-
final class AnonFunctionXXL(f: js.Function1[IArray[Object], Object]) extends scala.runtime.FunctionXXL {
7-
override def apply(xs: IArray[Object]): Object = f(xs)
8-
}
3+
/* Before Scala.js 1.19, this class was concrete. It had a 1-argument
4+
* constructor taking a js.Function[Array[Object], Object], and its `apply()`
5+
* method called that function. This was similar to the `AnonFunctionN` classes
6+
* of the Scala.js library (shared between Scala 2 and 3).
7+
*
8+
* In Scala.js 1.19, we introduced `NewLambda` nodes, which superseded these
9+
* specialized classes with a compilation mode that is more efficient on Wasm.
10+
* However, libraries compiled with earlier versions still contain references
11+
* to `AnonFunctionXXL`.
12+
*
13+
* The IR deserializer patches allocations of the form
14+
* New(AnonFunctionXXL, ctor, closure :: Nil)
15+
* into
16+
* NewLambda(AnonFunctionXXL, ..., (xs: Array[Object]) => closure(xs))
17+
*
18+
* When the `closure` is directly a JS `Closure` with the right signature
19+
* (which is supposed to be always, as far as our codegens were concerned),
20+
* it rewrites that as
21+
* NewLambda(AnonFunctionXXL, ..., (closureParam: Array[Object]) => closureBody)
22+
* which provides the best performance for old code.
23+
*/
24+
@deprecated("used by the codegen before Scala.js 1.19", since = "3.7.0")
25+
sealed abstract class AnonFunctionXXL extends scala.runtime.FunctionXXL

project/Build.scala

-1
Original file line numberDiff line numberDiff line change
@@ -1685,7 +1685,6 @@ object Build {
16851685
"compliantNullPointers" -> (sems.nullPointers == CheckedBehavior.Compliant),
16861686
"compliantStringIndexOutOfBounds" -> (sems.stringIndexOutOfBounds == CheckedBehavior.Compliant),
16871687
"compliantModuleInit" -> (sems.moduleInit == CheckedBehavior.Compliant),
1688-
"strictFloats" -> sems.strictFloats,
16891688
"productionMode" -> sems.productionMode,
16901689
"esVersion" -> linkerConfig.esFeatures.esVersion.edition,
16911690
"useECMAScript2015Semantics" -> linkerConfig.esFeatures.useECMAScript2015Semantics,

project/MiMaFilters.scala

+11
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,10 @@ object MiMaFilters {
99
// Additions that require a new minor version of the library
1010
Build.mimaPreviousDottyVersion -> Seq(
1111
ProblemFilters.exclude[MissingClassProblem]("scala.annotation.internal.readOnlyCapability"),
12+
13+
// Scala.js-only class
14+
ProblemFilters.exclude[FinalClassProblem]("scala.scalajs.runtime.AnonFunctionXXL"),
15+
ProblemFilters.exclude[DirectMissingMethodProblem]("scala.scalajs.runtime.AnonFunctionXXL.this"),
1216
),
1317

1418
// Additions since last LTS
@@ -97,6 +101,13 @@ object MiMaFilters {
97101
// Breaking changes since last reference version
98102
Build.mimaPreviousDottyVersion -> // Seq.empty, // We should never break backwards compatibility
99103
Seq(
104+
// Scala.js-only class, which is subject to IR deserializatiation hacks to preserve bincompat.
105+
// It's OK. Scala.js did the same:
106+
// https://github.com/scala-js/scala-js/blob/v1.19.0/project/BinaryIncompatibilities.scala#L66-L71
107+
ProblemFilters.exclude[AbstractClassProblem]("scala.scalajs.runtime.AnonFunctionXXL"),
108+
ProblemFilters.exclude[DirectMissingMethodProblem]("scala.scalajs.runtime.AnonFunctionXXL.this"),
109+
ProblemFilters.exclude[DirectMissingMethodProblem]("scala.scalajs.runtime.AnonFunctionXXL.apply"),
110+
100111
// `ReversedMissingMethodProblem`s are acceptable. See comment in `Breaking changes since last LTS`.
101112
ProblemFilters.exclude[ReversedMissingMethodProblem]("scala.quoted.Quotes#reflectModule.FlexibleType"),
102113
ProblemFilters.exclude[ReversedMissingMethodProblem]("scala.quoted.Quotes#reflectModule.FlexibleTypeTypeTest"),

project/plugins.sbt

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
libraryDependencySchemes +=
77
"org.scala-lang.modules" %% "scala-xml" % VersionScheme.Always
88

9-
addSbtPlugin("org.scala-js" % "sbt-scalajs" % "1.18.1")
9+
addSbtPlugin("org.scala-js" % "sbt-scalajs" % "1.19.0")
1010

1111
addSbtPlugin("org.xerial.sbt" % "sbt-sonatype" % "3.9.21")
1212

0 commit comments

Comments
 (0)