Skip to content

Commit 37c9584

Browse files
authored
Merge pull request #12657 from dotty-staging/sjs-default-accessors-bridges-in-non-native-js-classes
Fix #12572: Ignore default accessor bridges in non-native JS classes.
2 parents 0d1d47a + dc89ac4 commit 37c9584

File tree

3 files changed

+33
-1
lines changed

3 files changed

+33
-1
lines changed

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

+9
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import Decorators._
1818
import Flags._
1919
import dotty.tools.dotc.ast.Trees._
2020
import Names._
21+
import NameKinds.DefaultGetterName
2122
import Types._
2223
import Symbols._
2324
import Denotations._
@@ -1069,6 +1070,14 @@ class JSCodeGen()(using genCtx: Context) {
10691070
} else if (sym.isJSNativeCtorDefaultParam) {
10701071
// #11592
10711072
None
1073+
} else if (sym.is(Bridge) && sym.name.is(DefaultGetterName) && currentClassSym.isNonNativeJSClass) {
1074+
/* #12572 Bridges for default accessors in non-native JS classes must not be emitted,
1075+
* because they call another default accessor, making their entire body an
1076+
* <undefined-param> that cannot be eliminated.
1077+
* Such methods are never called anyway, because they are filtered out in
1078+
* JSExportsGen.defaultGetterDenot().
1079+
*/
1080+
None
10721081
} else /*if (sym.isClassConstructor && isHijackedBoxedClass(sym.owner)) {
10731082
None
10741083
} else*/ {

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

+1-1
Original file line numberDiff line numberDiff line change
@@ -774,7 +774,7 @@ final class JSExportsGen(jsCodeGen: JSCodeGen)(using Context) {
774774
else sym.owner
775775

776776
private def defaultGetterDenot(targetSym: Symbol, sym: Symbol, paramIndex: Int): Denotation =
777-
targetSym.info.member(DefaultGetterName(sym.name.asTermName, paramIndex))
777+
targetSym.info.memberBasedOnFlags(DefaultGetterName(sym.name.asTermName, paramIndex), excluded = Bridge)
778778

779779
private def defaultGetterDenot(sym: Symbol, paramIndex: Int): Denotation =
780780
defaultGetterDenot(targetSymForDefaultGetter(sym), sym, paramIndex)

tests/sjs-junit/test/org/scalajs/testsuite/compiler/RegressionTestScala3.scala

+23
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,10 @@ class RegressionTestScala3 {
3535

3636
assertEquals(5, foo(5)(4))
3737
}
38+
39+
@Test def defaultAccessorBridgesIssue12572(): Unit = {
40+
new MyPromiseIssue12572[Int](5)
41+
}
3842
}
3943

4044
object RegressionTestScala3 {
@@ -53,6 +57,25 @@ object RegressionTestScala3 {
5357
class RangeErrorIssue11592(msg: String = js.native) extends js.Object {
5458
val message: String = js.native
5559
}
60+
61+
class MyPromiseIssue12572[T](t: T) extends js.Promise[T]((resolve, reject) => resolve(t)) {
62+
override def `then`[S](
63+
onFulfilled: js.Function1[T, S | js.Thenable[S]],
64+
onRejected: js.UndefOr[js.Function1[scala.Any, S | js.Thenable[S]]] = js.undefined): js.Promise[S] = {
65+
???
66+
}
67+
68+
override def `then`[S >: T](
69+
onFulfilled: Unit,
70+
onRejected: js.UndefOr[js.Function1[scala.Any, S | js.Thenable[S]]]): js.Promise[S] = {
71+
???
72+
}
73+
74+
override def `catch`[S >: T](
75+
onRejected: js.UndefOr[js.Function1[scala.Any, S | js.Thenable[S]]] = js.undefined): js.Promise[S] = {
76+
???
77+
}
78+
}
5679
}
5780

5881
// This class needs to be at the top-level, not in an object, to reproduce the issue

0 commit comments

Comments
 (0)