|
| 1 | +--- |
| 2 | +layout: post |
| 3 | +title: Announcing Scala.js 1.18.0 |
| 4 | +category: news |
| 5 | +tags: [releases] |
| 6 | +permalink: /news/2025/01/07/announcing-scalajs-1.18.0/ |
| 7 | +--- |
| 8 | + |
| 9 | + |
| 10 | +We are pleased to announce the release of Scala.js 1.18.0! |
| 11 | + |
| 12 | +This release drops support for Scala 2.12.{2-5} and 2.13.{0-2}. |
| 13 | +Other than that, it is mostly a bugfix release. |
| 14 | + |
| 15 | +This release also contains a number of internal changes to the intermediate representation and linker. |
| 16 | +These are not externally visible, except for users who directly manipulate the IR and/or linker. |
| 17 | +They pave the way for upcoming changes that are still ongoing work. |
| 18 | + |
| 19 | +Read on for more details. |
| 20 | + |
| 21 | +<!--more--> |
| 22 | + |
| 23 | +## Getting started |
| 24 | + |
| 25 | +If you are new to Scala.js, head over to [the tutorial]({{ BASE_PATH }}/tutorial/). |
| 26 | + |
| 27 | +If you need help with anything related to Scala.js, you may find our community [in `#scala-js` on Discord](https://discord.com/invite/scala) and [on Stack Overflow](https://stackoverflow.com/questions/tagged/scala.js). |
| 28 | + |
| 29 | +Bug reports can be filed [on GitHub](https://github.com/scala-js/scala-js/issues). |
| 30 | + |
| 31 | +## Release notes |
| 32 | + |
| 33 | +If upgrading from Scala.js 0.6.x, make sure to read [the release notes of Scala.js 1.0.0]({{ BASE_PATH }}/news/2020/02/25/announcing-scalajs-1.0.0/) first, as they contain a host of important information, including breaking changes. |
| 34 | + |
| 35 | +This is a **minor** release: |
| 36 | + |
| 37 | +* It is backward binary compatible with all earlier versions in the 1.x series: libraries compiled with 1.0.x through 1.17.x can be used with 1.18.0 without change. |
| 38 | +* It is *not* forward binary compatible with 1.17.x: libraries compiled with 1.18.0 cannot be used with 1.17.x or earlier. |
| 39 | +* It is *not* entirely backward source compatible: it is not guaranteed that a codebase will compile *as is* when upgrading from 1.17.x (in particular in the presence of `-Xfatal-warnings`). |
| 40 | + |
| 41 | +As a reminder, libraries compiled with 0.6.x cannot be used with Scala.js 1.x; they must be republished with 1.x first. |
| 42 | + |
| 43 | +## Changes with compatibility concerns |
| 44 | + |
| 45 | +### Enforce stricter rules on the use of `this` in the IR of constructors |
| 46 | + |
| 47 | +Exceptionally, **this is theoretically a binary-breaking change**. |
| 48 | +It is possible for previously valid IR (Intermediate Representation, as published in binaries on Maven Central) to be rejected by Scala.js 1.18.0. |
| 49 | + |
| 50 | +We now enforce, during IR checking (by default, only enabled in `fullLink` builds), that constructors abide by stricter rules. |
| 51 | +Before calling their `super` constructor (or delegate `this()` constructor), they may not refer to the `this` instance. |
| 52 | +The only exception is to *assign* a field, as in `this.foo = bar`. |
| 53 | +This restriction is in line with a similar rule in JVM bytecode. |
| 54 | + |
| 55 | +Unfortunately, our compiler plugin for Scala 2.x was previously generating IR that is invalid according to the new rule in one corner case situation. |
| 56 | +If there is a `try..catch` expression inside an argument to the `super` constructor, the compiler may lift it to a separate method. |
| 57 | +We compiled that method as an *instance* method, using the `this` value, instead of compiling it as a *static* method. |
| 58 | + |
| 59 | +Here is an example: |
| 60 | + |
| 61 | +{% highlight scala %} |
| 62 | +import scala.util.control.Breaks._ |
| 63 | + |
| 64 | +class Parent(val i: Int) { |
| 65 | + def this(p: Parent) = this(p.i) |
| 66 | + if (i > 40) throw new IllegalArgumentException |
| 67 | +} |
| 68 | +class Child extends Parent({ |
| 69 | + val p = try new Parent(42) catch { case _: IllegalArgumentException => break() } |
| 70 | + p |
| 71 | +}) |
| 72 | + |
| 73 | +object Test extends App { |
| 74 | + breakable(new Child) |
| 75 | +} |
| 76 | +{% endhighlight %} |
| 77 | + |
| 78 | +If your application depends on a library that contained such a code shape, you may hit the following IR checking error at link time in Scala.js 1.18.0. |
| 79 | + |
| 80 | +{% highlight none %} |
| 81 | +Restricted use of `this` before the super constructor call |
| 82 | +{% endhighlight %} |
| 83 | + |
| 84 | +If that is the case, the library needs to be recompiled with Scala.js 1.18.0 or later to be usable again. |
| 85 | +Make sure to [tell us on the relevant PR](https://github.com/scala-js/scala-js/pull/5019) if that happens. |
| 86 | + |
| 87 | +In order to mitigate the impact of this change, we conducted an audit of (the latest version of) all Scala.js libraries published to Maven Central. |
| 88 | +We did not find any library that violated the new rule. |
| 89 | +You may still run into the issue if you depend on a private library. |
| 90 | + |
| 91 | +### Drop support for Scala 2.12.2 to 2.12.5 and 2.13.0 to 2.13.2 |
| 92 | + |
| 93 | +In order to reduce our maintenance burden and ease further development, Scala.js 1.18.0 drops support for Scala 2.12.2 to 2.12.5 and 2.13.0 to 2.13.2. |
| 94 | +Scala 2.12.6+ and 2.13.3+ are still supported. |
| 95 | + |
| 96 | +We still had a number of dedicated code paths, special cases and exceptions for these versions in our codebase. |
| 97 | +Moreover, we occasionally hit compiler bugs in early 2.12.x versions, which imposed constraints on how we wrote our code. |
| 98 | + |
| 99 | +### The Wasm backend now requires full support of `try_table` (notably Node.js 23) |
| 100 | + |
| 101 | +If you are using the WebAssembly backend, you now need at least Node.js 23 to run and test. |
| 102 | + |
| 103 | +In Scala.js 1.17.0, the WebAssembly backend worked around some issues in Wasm engines regarding the `try_table` instruction. |
| 104 | +Our main blocker was the version of V8 shipped with Node.js 22. |
| 105 | +Now that Node.js 23 has been released with the correct behavior, we removed the workaround. |
| 106 | + |
| 107 | +### Changes to the IR and linker APIs |
| 108 | + |
| 109 | +For tooling authors who directly manipulate the IR and linker APIs, there have been some breaking changes in that area. |
| 110 | +This is in line with our versioning policy for the linker APIs. |
| 111 | + |
| 112 | +The changes you are most likely to hit are: |
| 113 | + |
| 114 | +* We renamed `NoType` to `VoidType`, which represents the IR type `void`. |
| 115 | + `void` is now generally handled more regularly, as any other type of the type system. |
| 116 | +* `VarRef` now directly contains a `LocalName`, rather than a `LocalIdent` itself containing a `LocalName`. |
| 117 | +* `This` is not a separate IR node anymore; instead it is a `VarRef` with the special name `LocalName.This`. |
| 118 | +* `ArrayLength`, `Throw`, and a number of more obscure IR nodes have been merged into `UnaryOp`. |
| 119 | +* `Transformers` does not make the distinction between "statement" and "expression" anymore. |
| 120 | + This follows from handling `void` more uniformly. |
| 121 | + |
| 122 | +## Miscellaneous |
| 123 | + |
| 124 | +### New JDK APIs |
| 125 | + |
| 126 | +This release adds shell definitions for the following JDK 21 interfaces, but without any method: |
| 127 | + |
| 128 | +* `java.util.SequencedCollection`, `SequencedMap` and `SequencedSet` |
| 129 | + |
| 130 | +## Bug fixes |
| 131 | + |
| 132 | +Among others, the following bugs have been fixed in 1.18.0: |
| 133 | + |
| 134 | +* [#5085](https://github.com/scala-js/scala-js/issues/5085) `java.math.BigDecimal.valueOf(0, 9).stripTrailingZeros.scale` returns 9 instead of 0. |
| 135 | +* [#5069](https://github.com/scala-js/scala-js/issues/5069) Linking errors with `java.util.SequencedCollection` on JDK 21+ (considered a bug because they surfaced even in code that did not mention that new interface). |
| 136 | +* [#5048](https://github.com/scala-js/scala-js/issues/5048) Wasm backend fails when no modules are defined. |
| 137 | +* [#4947](https://github.com/scala-js/scala-js/issues/4947) Wrong optimization of `@inline` classes with several private fields of the same name in the class hierarchy. |
| 138 | + |
| 139 | +You can find the full list [on GitHub](https://github.com/scala-js/scala-js/issues?q=is%3Aissue+milestone%3Av1.18.0+is%3Aclosed). |
0 commit comments