Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

scalajs: compiler crash when overriding Promise.then #12572

Closed
rssh opened this issue May 23, 2021 · 3 comments
Closed

scalajs: compiler crash when overriding Promise.then #12572

rssh opened this issue May 23, 2021 · 3 comments

Comments

@rssh
Copy link
Contributor

rssh commented May 23, 2021

Compiler version

3.0.0

Minimized code

package x

import scalajs.*

class MyPromise[T]() extends js.Promise[T]( (resolve, reject) => ???) {

    override def `then`[S](
      onFulfilled: js.Function1[T, S | js.Thenable[S]],
      onRejected: js.UndefOr[js.Function1[scala.Any, S | js.Thenable[S]]] = js.undefined): js.Promise[S] =
        js.Promise( (resolve, reject) => ??? )

    override def `then`[S >: T](
      onFulfilled: Unit,
      onRejected: js.UndefOr[js.Function1[scala.Any, S | js.Thenable[S]]]): js.Promise[S] =
        `then`[S]( x => x , onRejected)

    override def `catch`[S >: T](
      onRejected: js.UndefOr[js.Function1[scala.Any, S | js.Thenable[S]]] = js.undefined): js.Promise[S] =
        `then`[S]( x => x , onRejected )

}

Output (click arrow to expand)

[info] welcome to sbt 1.5.2 (N/A Java 15.0.2)
[info] loading global plugins from /Users/rssh/.sbt/1.0/plugins
[info] loading settings for project scalajs-then-override-build from plugins.sbt ...
[info] loading project definition from /Users/rssh/tests/dotty/scalajs-then-override/project
[info] loading settings for project root from build.sbt ...
[info] set current project to test (in build file:/Users/rssh/tests/dotty/scalajs-then-override/)
[info] Executing in batch mode. For better performance use sbt's shell
[info] compiling 1 Scala source to /Users/rssh/tests/dotty/scalajs-then-override/target/scala-3.0.0/classes ...
[info] exception occurred while compiling /Users/rssh/tests/dotty/scalajs-then-override/src/main/scala/x/X.scala
java.lang.AssertionError: assertion failed: found overloaded default getter def then$default$2(): scala.scalajs.js.| <and> 
  def then$default$2(): scala.runtime.BoxedUnit while compiling /Users/rssh/tests/dotty/scalajs-then-override/src/main/scala/x/X.scala
[error] ## Exception when compiling 1 sources to /Users/rssh/tests/dotty/scalajs-then-override/target/scala-3.0.0/classes
[error] java.lang.AssertionError: assertion failed: found overloaded default getter def then$default$2(): scala.scalajs.js.| <and> 
[error]   def then$default$2(): scala.runtime.BoxedUnit
[error] scala.runtime.Scala3RunTime$.assertFailed(Scala3RunTime.scala:8)
[error] dotty.tools.backend.sjs.JSExportsGen.genCallDefaultGetter(JSExportsGen.scala:744)
[error] dotty.tools.backend.sjs.JSExportsGen.genPrepareArgs$$anonfun$2(JSExportsGen.scala:718)
[error] scala.collection.Iterator$$anon$9.next(Iterator.scala:575)
[error] scala.collection.mutable.Growable.addAll(Growable.scala:62)
[error] scala.collection.mutable.Growable.addAll$(Growable.scala:57)
[error] scala.collection.immutable.VectorBuilder.addAll(Vector.scala:1565)
[error] scala.collection.immutable.Vector$.from(Vector.scala:1349)
[error] scala.collection.immutable.Vector$.from(Vector.scala:34)
[error] scala.collection.IterableOps$WithFilter.map(Iterable.scala:884)
[error] dotty.tools.backend.sjs.JSExportsGen.genPrepareArgs(JSExportsGen.scala:731)
[error] dotty.tools.backend.sjs.JSExportsGen.genApplyForSingleExportedNonJSSuperCall(JSExportsGen.scala:681)
[error] dotty.tools.backend.sjs.JSExportsGen.genApplyForSingleExported(JSExportsGen.scala:636)
[error] dotty.tools.backend.sjs.JSExportsGen.genExportSameArgcRec(JSExportsGen.scala:540)
[error] dotty.tools.backend.sjs.JSExportsGen.genExportSameArgc(JSExportsGen.scala:516)
[error] dotty.tools.backend.sjs.JSExportsGen.$anonfun$28(JSExportsGen.scala:472)
[error] scala.collection.Iterator$$anon$9.next(Iterator.scala:575)
[error] scala.collection.immutable.List.prependedAll(List.scala:153)
[error] scala.collection.immutable.List$.from(List.scala:651)
[error] scala.collection.immutable.List$.from(List.scala:648)
[error] scala.collection.IterableOps$WithFilter.map(Iterable.scala:884)
[error] dotty.tools.backend.sjs.JSExportsGen.genExportMethodMultiAlts(JSExportsGen.scala:474)
[error] dotty.tools.backend.sjs.JSExportsGen.genExportMethod(JSExportsGen.scala:441)
[error] dotty.tools.backend.sjs.JSExportsGen.genMemberExportOrDispatcher$$anonfun$1(JSExportsGen.scala:333)
[error] dotty.tools.backend.sjs.JSCodeGen.withNewLocalNameScope$$anonfun$1(JSCodeGen.scala:117)
[error] dotty.tools.backend.sjs.ScopedVar$.withScopedVars(ScopedVar.scala:35)
[error] dotty.tools.backend.sjs.JSCodeGen.withNewLocalNameScope(JSCodeGen.scala:118)
[error] dotty.tools.backend.sjs.JSExportsGen.genMemberExportOrDispatcher(JSExportsGen.scala:334)
[error] dotty.tools.backend.sjs.JSExportsGen.genJSClassDispatcher(JSExportsGen.scala:323)
[error] dotty.tools.backend.sjs.JSExportsGen.genJSClassDispatchers$$anonfun$1(JSExportsGen.scala:295)
[error] scala.collection.immutable.List.map(List.scala:246)
[error] dotty.tools.backend.sjs.JSExportsGen.genJSClassDispatchers(JSExportsGen.scala:295)
[error] dotty.tools.backend.sjs.JSCodeGen.genNonNativeJSClass(JSCodeGen.scala:537)
[error] dotty.tools.backend.sjs.JSCodeGen.genCompilationUnit$$anonfun$6$$anonfun$1(JSCodeGen.scala:211)
[error] dotty.tools.backend.sjs.ScopedVar$.withScopedVars(ScopedVar.scala:35)
[error] dotty.tools.backend.sjs.JSCodeGen.genCompilationUnit$$anonfun$2(JSCodeGen.scala:221)
[error] scala.runtime.function.JProcedure1.apply(JProcedure1.java:15)
[error] scala.runtime.function.JProcedure1.apply(JProcedure1.java:10)
[error] scala.collection.immutable.List.foreach(List.scala:333)
[error] dotty.tools.backend.sjs.JSCodeGen.genCompilationUnit(JSCodeGen.scala:223)
[error] dotty.tools.backend.sjs.JSCodeGen.run(JSCodeGen.scala:152)
[error] dotty.tools.backend.sjs.GenSJSIR.run(GenSJSIR.scala:15)
[error] dotty.tools.dotc.core.Phases$Phase.runOn$$anonfun$1(Phases.scala:303)
[error] scala.collection.immutable.List.map(List.scala:246)
[error] dotty.tools.dotc.core.Phases$Phase.runOn(Phases.scala:304)
[error] dotty.tools.dotc.Run.runPhases$4$$anonfun$4(Run.scala:205)
[error] scala.runtime.function.JProcedure1.apply(JProcedure1.java:15)
[error] scala.runtime.function.JProcedure1.apply(JProcedure1.java:10)
[error] scala.collection.ArrayOps$.foreach$extension(ArrayOps.scala:1323)
[error] dotty.tools.dotc.Run.runPhases$5(Run.scala:215)
[error] dotty.tools.dotc.Run.compileUnits$$anonfun$1(Run.scala:223)
[error] scala.runtime.java8.JFunction0$mcV$sp.apply(JFunction0$mcV$sp.scala:18)
[error] dotty.tools.dotc.util.Stats$.maybeMonitored(Stats.scala:67)
[error] dotty.tools.dotc.Run.compileUnits(Run.scala:230)
[error] dotty.tools.dotc.Run.compileSources(Run.scala:166)
[error] dotty.tools.dotc.Run.compile(Run.scala:150)
[error] dotty.tools.dotc.Driver.doCompile(Driver.scala:39)
[error] dotty.tools.xsbt.CompilerBridgeDriver.run(CompilerBridgeDriver.java:88)
[error] dotty.tools.xsbt.CompilerBridge.run(CompilerBridge.java:22)
[error] sbt.internal.inc.AnalyzingCompiler.compile(AnalyzingCompiler.scala:91)
[error] sbt.internal.inc.MixedAnalyzingCompiler.$anonfun$compile$7(MixedAnalyzingCompiler.scala:186)
@sjrd
Copy link
Member

sjrd commented May 31, 2021

This happens because Scala 3 uses the inferred type of a parameter default value as the result type of the default accessor. This has always been a terrible idea wrt. binary compatibility, but that battle was lost. Now it's biting us because it creates bridges for param accessors in subclasses, and Scala.js handles default accessors in a very special way. We'll need to get rid of those bridges for default accessors in non-native JS classes.

@smarter
Copy link
Member

smarter commented May 31, 2021

This happens because Scala 3 uses the inferred type of a parameter default value as the result type of the default accessor.

As of 6fde5c1 this should only happen when the type of the method parameter cannot be used (e.g. def foo[T](x: T = 1)), I don't see what else we could do here.

@sjrd
Copy link
Member

sjrd commented Jun 1, 2021

Hum, then I don't know what causes the bridge to be generated. But the fact is that there is a bridge in this case, and ignoring default getter bridges in JS classes fixes this issue (see PR #12657).

smarter added a commit that referenced this issue Jun 22, 2021
…idges-in-non-native-js-classes

Fix #12572: Ignore default accessor bridges in non-native JS classes.
changvvb pushed a commit to changvvb/dotty that referenced this issue Jun 23, 2021
…sses.

They are not emitted, and they are excluded when looking up the
default getter to call.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants