Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 5f1d5cf

Browse files
committed
Scala.js: Remove spurious js.AsInstanceOf around js.LinkTimeIf.
When B <: A and C <: A, `linkTimeIf[A](cond) { B }{ C }` would generate an `.asInstanceOf[A]` that casts the resulting value to a supertype. However, this cast is redundant, as the linker will prune one branch at link time, and the remaining expression is already known to be a compatible type. This commit eliminates the surrounding `.asInstanceOf` around the `linkTimeIf[T]` when both `thenp` and `elsep` are known to be subtypes of `T`. The optimizer already routinely performs this optimization. However, that comes too late for the module instance field alias analysis performed by `IncOptimizer`. In that case, while the desugarer removes the `LinkTimeIf`, the extra `AsInstanceOf` prevents aliasing the field. Removing the cast ahead of time in the compiler allows field aliases to be recognized in the presence of `LinkTimeIf`s. This commit is a forward port of the Scala.js commit scala-js/scala-js@9bb267c
1 parent 33aa948 commit 5f1d5cf

File tree

1 file changed

+23
-1
lines changed

1 file changed

+23
-1
lines changed

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

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3321,7 +3321,29 @@ class JSCodeGen()(using genCtx: Context) {
33213321
val genReceiver = genExpr(receiver)
33223322

33233323
if (sym == defn.Any_asInstanceOf) {
3324-
genAsInstanceOf(genReceiver, to)
3324+
receiver match {
3325+
/* This is an optimization for `linkTimeIf(cond)(thenp)(elsep).asInstanceOf[T]`.
3326+
* If both `thenp` and `elsep` are subtypes of `T`, the `asInstanceOf`
3327+
* is redundant and can be removed. The optimizer already routinely performs
3328+
* this optimization. However, that comes too late for the module instance
3329+
* field alias analysis performed by `IncOptimizer`. In that case, while the
3330+
* desugarer removes the `LinkTimeIf`, the extra `AsInstanceOf` prevents
3331+
* aliasing the field. Removing the cast ahead of time in the compiler allows
3332+
* field aliases to be recognized in the presence of `LinkTimeIf`s.
3333+
*/
3334+
case Apply(innerFun, List(cond, thenp, elsep))
3335+
if innerFun.symbol == jsdefn.LinkingInfo_linkTimeIf &&
3336+
thenp.tpe <:< to && elsep.tpe <:< to =>
3337+
val genReceiver1 = genReceiver match {
3338+
case genReceiver: js.LinkTimeIf =>
3339+
genReceiver
3340+
case _ =>
3341+
throw FatalError(s"Unexpected tree $genReceiver is generated for $innerFun at: ${tree.sourcePos}")
3342+
}
3343+
js.LinkTimeIf(genReceiver1.cond, genReceiver1.thenp, genReceiver1.elsep)(toIRType(to))(using genReceiver1.pos)
3344+
case _ =>
3345+
genAsInstanceOf(genReceiver, to)
3346+
}
33253347
} else if (sym == defn.Any_isInstanceOf) {
33263348
genIsInstanceOf(genReceiver, to)
33273349
} else {

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /