From 7a8ba54c1c2273cbece53a5141679adb724573b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Wed, 19 Aug 2020 10:51:15 +0200 Subject: [PATCH 1/5] Scala.js: Handle SAMs for js.ThisFunction's. --- .../dotty/tools/backend/sjs/JSCodeGen.scala | 38 +++++++++++++------ .../dotty/tools/dotc/config/SJSPlatform.scala | 5 ++- project/Build.scala | 9 +---- 3 files changed, 31 insertions(+), 21 deletions(-) diff --git a/compiler/src/dotty/tools/backend/sjs/JSCodeGen.scala b/compiler/src/dotty/tools/backend/sjs/JSCodeGen.scala index 75f2451374f3..7ffc4c654fb8 100644 --- a/compiler/src/dotty/tools/backend/sjs/JSCodeGen.scala +++ b/compiler/src/dotty/tools/backend/sjs/JSCodeGen.scala @@ -2472,20 +2472,34 @@ class JSCodeGen()(using genCtx: Context) { box(call, sym.info.finalResultType) } - val closure = js.Closure(arrow = true, formalCaptures, formalParams, genBody, actualCaptures) - report.debuglog(closure.toString) - val funInterfaceSym = functionalInterface.tpe.widenDealias.typeSymbol - if (jsdefn.isJSFunctionClass(funInterfaceSym)) { - closure + + if (jsdefn.isJSThisFunctionClass(funInterfaceSym)) { + val thisParam :: otherParams = formalParams + js.Closure( + arrow = false, + formalCaptures, + otherParams, + js.Block( + js.VarDef(thisParam.name, thisParam.originalName, + thisParam.ptpe, mutable = false, + js.This()(thisParam.ptpe)(thisParam.pos))(thisParam.pos), + genBody), + actualCaptures) } else { - 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)) + val closure = js.Closure(arrow = true, formalCaptures, formalParams, genBody, actualCaptures) + + if (jsdefn.isJSFunctionClass(funInterfaceSym)) { + closure + } else { + 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)) + } } } diff --git a/compiler/src/dotty/tools/dotc/config/SJSPlatform.scala b/compiler/src/dotty/tools/dotc/config/SJSPlatform.scala index 5987df22d432..8b69817224a1 100644 --- a/compiler/src/dotty/tools/dotc/config/SJSPlatform.scala +++ b/compiler/src/dotty/tools/dotc/config/SJSPlatform.scala @@ -13,6 +13,7 @@ class SJSPlatform()(using Context) extends JavaPlatform { /** Is the SAMType `cls` also a SAM under the rules of the Scala.js back-end? */ override def isSam(cls: ClassSymbol)(using Context): Boolean = - defn.isFunctionClass(cls) || jsDefinitions.isJSFunctionClass(cls) + defn.isFunctionClass(cls) + || jsDefinitions.isJSFunctionClass(cls) + || jsDefinitions.isJSThisFunctionClass(cls) } - diff --git a/project/Build.scala b/project/Build.scala index e31b8a23c08d..07664dfc2f62 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -1093,9 +1093,8 @@ object Build { -- "NestedJSClassTest.scala" // non-native JS classes -- "NonNativeJSTypeTest.scala" // non-native JS classes -- "PromiseMock.scala" // non-native JS classes - -- "SpecialTest.scala" // assertion error in ExpandSAMs + -- "SpecialTest.scala" // not yet implemented JS-specific primitive -- "SymbolTest.scala" // IR checking errors - -- "ThisFunctionTest.scala" // assertion error in ExpandSAMs -- "UndefOrTest.scala" // StackOverflow in the compiler )).get @@ -1117,11 +1116,7 @@ object Build { ++ (dir / "js/src/test/scala/org/scalajs/testsuite/niobuffer" ** "*.scala").get ++ (dir / "js/src/test/scala/org/scalajs/testsuite/scalalib" ** "*.scala").get - - ++ (dir / "js/src/test/scala/org/scalajs/testsuite/typedarray" ** (("*.scala": FileFilter) - -- "TypedArrayTest.scala" // assertion error in ExpandSAMs - )).get - + ++ (dir / "js/src/test/scala/org/scalajs/testsuite/typedarray" ** "*.scala").get ++ (dir / "js/src/test/scala/org/scalajs/testsuite/utils" ** "*.scala").get ++ (dir / "js/src/test/require-2.12" ** (("*.scala": FileFilter) From 9581eb1acd589a5a7c68568408dce4b0bde1f75a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Wed, 19 Aug 2020 11:25:04 +0200 Subject: [PATCH 2/5] Scala.js: Consider js.| as a JS type. --- compiler/src/dotty/tools/backend/sjs/JSDefinitions.scala | 3 +++ compiler/src/dotty/tools/backend/sjs/JSInterop.scala | 3 +-- project/Build.scala | 9 +-------- 3 files changed, 5 insertions(+), 10 deletions(-) diff --git a/compiler/src/dotty/tools/backend/sjs/JSDefinitions.scala b/compiler/src/dotty/tools/backend/sjs/JSDefinitions.scala index 6c15c7c72976..abd2d3d62ee6 100644 --- a/compiler/src/dotty/tools/backend/sjs/JSDefinitions.scala +++ b/compiler/src/dotty/tools/backend/sjs/JSDefinitions.scala @@ -47,6 +47,9 @@ final class JSDefinitions()(using Context) { @threadUnsafe lazy val JSBaseThisFunctionType: TypeRef = requiredClassRef("scala.scalajs.js.ThisFunction") def JSBaseThisFunctionClass(using Context) = JSBaseThisFunctionType.symbol.asClass + @threadUnsafe lazy val PseudoUnionType: TypeRef = requiredClassRef("scala.scalajs.js.|") + def PseudoUnionClass(using Context) = PseudoUnionType.symbol.asClass + @threadUnsafe lazy val JSArrayType: TypeRef = requiredClassRef("scala.scalajs.js.Array") def JSArrayClass(using Context) = JSArrayType.symbol.asClass diff --git a/compiler/src/dotty/tools/backend/sjs/JSInterop.scala b/compiler/src/dotty/tools/backend/sjs/JSInterop.scala index 3b1420c2d44e..d9b5aaef3856 100644 --- a/compiler/src/dotty/tools/backend/sjs/JSInterop.scala +++ b/compiler/src/dotty/tools/backend/sjs/JSInterop.scala @@ -16,9 +16,8 @@ object JSInterop { /** Is this symbol a JavaScript type? */ def isJSType(sym: Symbol)(using Context): Boolean = { - //sym.hasAnnotation(jsdefn.RawJSTypeAnnot) atPhase(erasurePhase) { - sym.derivesFrom(jsdefn.JSAnyClass) + sym.derivesFrom(jsdefn.JSAnyClass) || sym == jsdefn.PseudoUnionClass } } diff --git a/project/Build.scala b/project/Build.scala index 07664dfc2f62..1faea07236d4 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -1074,7 +1074,6 @@ object Build { ++ (dir / "js/src/test/scala/org/scalajs/testsuite/javalib" ** (("*.scala": FileFilter) -- "FormatterJSTest.scala" // compile error with the f"" interpolator -- "ObjectJSTest.scala" // non-native JS classes - -- "StringBufferJSTest.scala" // IR checking errors -- "ThrowableJSTest.scala" // test fails ("java.lang.Error: stub") )).get @@ -1082,7 +1081,6 @@ object Build { -- "AsyncTest.scala" // needs PromiseMock.scala -- "DynamicTest.scala" // one test requires JS exports, all other tests pass -- "ExportsTest.scala" // JS exports - -- "FunctionTest.scala" // IR checking errors -- "IterableTest.scala" // non-native JS classes -- "JSExportStaticTest.scala" // JS exports -- "JSNativeInPackage.scala" // IR checking errors @@ -1094,8 +1092,6 @@ object Build { -- "NonNativeJSTypeTest.scala" // non-native JS classes -- "PromiseMock.scala" // non-native JS classes -- "SpecialTest.scala" // not yet implemented JS-specific primitive - -- "SymbolTest.scala" // IR checking errors - -- "UndefOrTest.scala" // StackOverflow in the compiler )).get ++ (dir / "js/src/test/scala/org/scalajs/testsuite/junit" ** (("*.scala": FileFilter) @@ -1111,7 +1107,6 @@ object Build { -- "ObjectTest.scala" // compile errors -- "StackTraceTest.scala" // would require `npm install source-map-support` -- "UnionTypeTest.scala" // requires a Scala 2 macro + StackOverflow in the compiler - -- "WrappedDictionaryTest.scala" // IR checking errors )).get ++ (dir / "js/src/test/scala/org/scalajs/testsuite/niobuffer" ** "*.scala").get @@ -1127,9 +1122,7 @@ object Build { -- "SAMJSTest.scala" // non-native JS classes )).get - ++ (dir / "js/src/test/scala-new-collections" ** (("*.scala": FileFilter) - -- "WrappedDictionaryToTest.scala" // IR checking errors - )).get + ++ (dir / "js/src/test/scala-new-collections" ** "*.scala").get ) } ) From 66bc9ca7445a8183f32cb2445fb40d1367e57892 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Wed, 19 Aug 2020 11:43:23 +0200 Subject: [PATCH 3/5] Scala.js: Update the status of two tests. They do not cause a StackOverflow error anymore, but they still do not pass due to other reasons. --- project/Build.scala | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/project/Build.scala b/project/Build.scala index 1faea07236d4..78830808bd97 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -1103,10 +1103,10 @@ object Build { )).get ++ (dir / "js/src/test/scala/org/scalajs/testsuite/library" ** (("*.scala": FileFilter) - -- "BigIntTest.scala" // StackOverflow in the compiler + -- "BigIntTest.scala" // Ambiguous reference because of new non-shadowing rule in Scala 3, pending update upstream -- "ObjectTest.scala" // compile errors -- "StackTraceTest.scala" // would require `npm install source-map-support` - -- "UnionTypeTest.scala" // requires a Scala 2 macro + StackOverflow in the compiler + -- "UnionTypeTest.scala" // requires a Scala 2 macro )).get ++ (dir / "js/src/test/scala/org/scalajs/testsuite/niobuffer" ** "*.scala").get From fe5f7a4294ade6146c6ac77d6c4010efd0ec2be0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Wed, 19 Aug 2020 13:57:28 +0200 Subject: [PATCH 4/5] Scala.js: Implement the primitive `js.special.strictEquals`. --- compiler/src/dotty/tools/backend/sjs/JSCodeGen.scala | 5 +++++ .../src/dotty/tools/backend/sjs/JSDefinitions.scala | 2 ++ .../src/dotty/tools/backend/sjs/JSPrimitives.scala | 12 +++++++----- project/Build.scala | 4 ++-- 4 files changed, 16 insertions(+), 7 deletions(-) diff --git a/compiler/src/dotty/tools/backend/sjs/JSCodeGen.scala b/compiler/src/dotty/tools/backend/sjs/JSCodeGen.scala index 7ffc4c654fb8..cf010de61a8c 100644 --- a/compiler/src/dotty/tools/backend/sjs/JSCodeGen.scala +++ b/compiler/src/dotty/tools/backend/sjs/JSCodeGen.scala @@ -2812,6 +2812,11 @@ class JSCodeGen()(using genCtx: Context) { val arg = genArgs1 genAsInstanceOf(js.JSUnaryOp(js.JSUnaryOp.typeof, arg), defn.StringType) + case STRICT_EQ => + // js.special.strictEquals(arg1, arg2) + val (arg1, arg2) = genArgs2 + js.JSBinaryOp(js.JSBinaryOp.===, arg1, arg2) + case IN => // js.special.in(arg1, arg2) val (arg1, arg2) = genArgs2 diff --git a/compiler/src/dotty/tools/backend/sjs/JSDefinitions.scala b/compiler/src/dotty/tools/backend/sjs/JSDefinitions.scala index abd2d3d62ee6..d38baf096568 100644 --- a/compiler/src/dotty/tools/backend/sjs/JSDefinitions.scala +++ b/compiler/src/dotty/tools/backend/sjs/JSDefinitions.scala @@ -154,6 +154,8 @@ final class JSDefinitions()(using Context) { def Special_in(using Context) = Special_inR.symbol @threadUnsafe lazy val Special_instanceofR = SpecialPackageClass.requiredMethodRef("instanceof") def Special_instanceof(using Context) = Special_instanceofR.symbol + @threadUnsafe lazy val Special_strictEqualsR = SpecialPackageClass.requiredMethodRef("strictEquals") + def Special_strictEquals(using Context) = Special_strictEqualsR.symbol @threadUnsafe lazy val WrappedArrayType: TypeRef = requiredClassRef("scala.scalajs.js.WrappedArray") def WrappedArrayClass(using Context) = WrappedArrayType.symbol.asClass diff --git a/compiler/src/dotty/tools/backend/sjs/JSPrimitives.scala b/compiler/src/dotty/tools/backend/sjs/JSPrimitives.scala index 5169628b5d55..382b8b9d9a14 100644 --- a/compiler/src/dotty/tools/backend/sjs/JSPrimitives.scala +++ b/compiler/src/dotty/tools/backend/sjs/JSPrimitives.scala @@ -32,11 +32,12 @@ object JSPrimitives { final val WITH_CONTEXTUAL_JS_CLASS_VALUE = CREATE_LOCAL_JS_CLASS + 1 // runtime.withContextualJSClassValue final val LINKING_INFO = WITH_CONTEXTUAL_JS_CLASS_VALUE + 1 // runtime.linkingInfo - final val IN = LINKING_INFO + 1 // js.special.in - final val INSTANCEOF = IN + 1 // js.special.instanceof - final val DELETE = INSTANCEOF + 1 // js.special.delete - final val FORIN = DELETE + 1 // js.special.forin - final val DEBUGGER = FORIN + 1 // js.special.debugger + final val STRICT_EQ = LINKING_INFO + 1 // js.special.strictEquals + final val IN = STRICT_EQ + 1 // js.special.in + final val INSTANCEOF = IN + 1 // js.special.instanceof + final val DELETE = INSTANCEOF + 1 // js.special.delete + final val FORIN = DELETE + 1 // js.special.forin + final val DEBUGGER = FORIN + 1 // js.special.debugger final val THROW = DEBUGGER + 1 @@ -107,6 +108,7 @@ class JSPrimitives(ictx: Context) extends DottyPrimitives(ictx) { addPrimitive(jsdefn.Runtime_withContextualJSClassValue, WITH_CONTEXTUAL_JS_CLASS_VALUE)*/ addPrimitive(jsdefn.Runtime_linkingInfo, LINKING_INFO) + addPrimitive(jsdefn.Special_strictEquals, STRICT_EQ) addPrimitive(jsdefn.Special_in, IN) addPrimitive(jsdefn.Special_instanceof, INSTANCEOF) addPrimitive(jsdefn.Special_delete, DELETE) diff --git a/project/Build.scala b/project/Build.scala index 78830808bd97..3b4166007791 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -1074,7 +1074,7 @@ object Build { ++ (dir / "js/src/test/scala/org/scalajs/testsuite/javalib" ** (("*.scala": FileFilter) -- "FormatterJSTest.scala" // compile error with the f"" interpolator -- "ObjectJSTest.scala" // non-native JS classes - -- "ThrowableJSTest.scala" // test fails ("java.lang.Error: stub") + -- "ThrowableJSTest.scala" // test fails ("java.lang.Error: stub") because it uses js.constructorOf )).get ++ (dir / "js/src/test/scala/org/scalajs/testsuite/jsinterop" ** (("*.scala": FileFilter) @@ -1091,7 +1091,7 @@ object Build { -- "NestedJSClassTest.scala" // non-native JS classes -- "NonNativeJSTypeTest.scala" // non-native JS classes -- "PromiseMock.scala" // non-native JS classes - -- "SpecialTest.scala" // not yet implemented JS-specific primitive + -- "SpecialTest.scala" // test fails ("java.lang.Error: stub") because it uses js.constructorOf )).get ++ (dir / "js/src/test/scala/org/scalajs/testsuite/junit" ** (("*.scala": FileFilter) From d6fe8b989022bbc1a49584a4beb4b5c5f43656f0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Thu, 20 Aug 2020 13:18:14 +0200 Subject: [PATCH 5/5] Scala.js: Add support for js.constructorOf[T]. To do this, we add a new mini-phase that rewrites calls of the form scala.scalajs.js.constructor[T] to scala.scalajs.runtime.constructorOf(classOf[T]) The back-end already knew how to compile calls to `runtime.constructorOf`, so there were no changes needed there. The new mini-phase will also serve in the future for handling inner and local JS classes. --- compiler/src/dotty/tools/dotc/Compiler.scala | 1 + .../dotc/transform/ExplicitJSClasses.scala | 64 +++++++++++++++++++ project/Build.scala | 12 ++-- 3 files changed, 70 insertions(+), 7 deletions(-) create mode 100644 compiler/src/dotty/tools/dotc/transform/ExplicitJSClasses.scala diff --git a/compiler/src/dotty/tools/dotc/Compiler.scala b/compiler/src/dotty/tools/dotc/Compiler.scala index ecbda7e157ca..48290ac3fb2f 100644 --- a/compiler/src/dotty/tools/dotc/Compiler.scala +++ b/compiler/src/dotty/tools/dotc/Compiler.scala @@ -72,6 +72,7 @@ class Compiler { List(new ElimOpaque, // Turn opaque into normal aliases new TryCatchPatterns, // Compile cases in try/catch new PatternMatcher, // Compile pattern matches + new ExplicitJSClasses, // Make all JS classes explicit (Scala.js only) new ExplicitOuter, // Add accessors to outer classes from nested ones. new ExplicitSelf, // Make references to non-trivial self types explicit as casts new StringInterpolatorOpt, // Optimizes raw and s string interpolators by rewriting them to string concatentations diff --git a/compiler/src/dotty/tools/dotc/transform/ExplicitJSClasses.scala b/compiler/src/dotty/tools/dotc/transform/ExplicitJSClasses.scala new file mode 100644 index 000000000000..8458edc9fa2c --- /dev/null +++ b/compiler/src/dotty/tools/dotc/transform/ExplicitJSClasses.scala @@ -0,0 +1,64 @@ +package dotty.tools +package dotc +package transform + +import MegaPhase._ +import core.DenotTransformers._ +import core.Symbols._ +import core.Contexts._ +import core.Phases._ +import core.Types._ +import core.Flags._ +import core.Decorators._ +import core.StdNames.nme +import core.Names._ +import core.NameOps._ +import ast.Trees._ +import SymUtils._ +import dotty.tools.dotc.ast.tpd + +import dotty.tools.backend.sjs.JSDefinitions.jsdefn + +/** This phase makes all JS classes explicit (their definitions and references to them). + * + * Ultimately, this will be the equivalent of the two phases `ExplicitInnerJS` + * and `ExplicitLocalJS` from Scala 2. Currently, this phase only performs the + * following transformations: + * + * - Rewrite `js.constructorOf[T]` into `scala.scalajs.runtime.constructorOf(classOf[T])`, + * where the `classOf[T]` is represented as a `Literal`. + */ +class ExplicitJSClasses extends MiniPhase with InfoTransformer { thisPhase => + import ExplicitJSClasses._ + import ast.tpd._ + + override def phaseName: String = ExplicitJSClasses.name + + override def isEnabled(using Context): Boolean = + ctx.settings.scalajs.value + + override def runsAfter: Set[String] = Set(PatternMatcher.name, HoistSuperArgs.name) + + override def changesMembers: Boolean = true // the phase adds fields for inner JS classes + + override def transformInfo(tp: Type, sym: Symbol)(using Context): Type = { + // Currently we don't do anything here. Eventually we'll add fields for inner JS classes. + tp + } + + override def infoMayChange(sym: Symbol)(using Context): Boolean = + sym.isClass && !sym.is(JavaDefined) + + override def transformTypeApply(tree: TypeApply)(using Context): tpd.Tree = { + tree match { + case TypeApply(fun, tpt :: Nil) if fun.symbol == jsdefn.JSPackage_constructorOf => + ref(jsdefn.Runtime_constructorOf).appliedTo(clsOf(tpt.tpe)) + case _ => + tree + } + } +} + +object ExplicitJSClasses { + val name: String = "explicitJSClasses" +} diff --git a/project/Build.scala b/project/Build.scala index 3b4166007791..492eca561153 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -1064,9 +1064,9 @@ object Build { ++ (dir / "shared/src/test/require-jdk7/org/scalajs/testsuite/javalib/util" ** "*.scala").get ++ (dir / "js/src/test/scala/org/scalajs/testsuite/compiler" ** (("*.scala": FileFilter) - -- "InteroperabilityTest.scala" // various compile errors - -- "OptimizerTest.scala" // compile errors: false + string and () + string - -- "ReflectionTest.scala" // tests fail + -- "InteroperabilityTest.scala" // various compile errors, pending update upstream + -- "OptimizerTest.scala" // compile errors: false + string and () + string, pending update upstream + -- "ReflectionTest.scala" // tests fail (wrong load spec for JS globals) -- "RegressionJSTest.scala" // non-native JS classes -- "RuntimeTypesTest.scala" // compile errors: no ClassTag for Null and Nothing )).get @@ -1074,7 +1074,6 @@ object Build { ++ (dir / "js/src/test/scala/org/scalajs/testsuite/javalib" ** (("*.scala": FileFilter) -- "FormatterJSTest.scala" // compile error with the f"" interpolator -- "ObjectJSTest.scala" // non-native JS classes - -- "ThrowableJSTest.scala" // test fails ("java.lang.Error: stub") because it uses js.constructorOf )).get ++ (dir / "js/src/test/scala/org/scalajs/testsuite/jsinterop" ** (("*.scala": FileFilter) @@ -1083,7 +1082,7 @@ object Build { -- "ExportsTest.scala" // JS exports -- "IterableTest.scala" // non-native JS classes -- "JSExportStaticTest.scala" // JS exports - -- "JSNativeInPackage.scala" // IR checking errors + -- "JSNativeInPackage.scala" // tests fail (wrong load spec for JS globals) -- "JSOptionalTest.scala" // non-native JS classes -- "JSSymbolTest.scala" // non-native JS classes -- "MiscInteropTest.scala" // non-native JS classes @@ -1091,7 +1090,6 @@ object Build { -- "NestedJSClassTest.scala" // non-native JS classes -- "NonNativeJSTypeTest.scala" // non-native JS classes -- "PromiseMock.scala" // non-native JS classes - -- "SpecialTest.scala" // test fails ("java.lang.Error: stub") because it uses js.constructorOf )).get ++ (dir / "js/src/test/scala/org/scalajs/testsuite/junit" ** (("*.scala": FileFilter) @@ -1104,7 +1102,7 @@ object Build { ++ (dir / "js/src/test/scala/org/scalajs/testsuite/library" ** (("*.scala": FileFilter) -- "BigIntTest.scala" // Ambiguous reference because of new non-shadowing rule in Scala 3, pending update upstream - -- "ObjectTest.scala" // compile errors + -- "ObjectTest.scala" // compile errors caused by #9588 -- "StackTraceTest.scala" // would require `npm install source-map-support` -- "UnionTypeTest.scala" // requires a Scala 2 macro )).get