<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <id>https://www.scala-lang.org/</id>
  <title type="text" xml:lang="en">The Scala Programming Language</title>
  <link type="application/atom+xml" href="https://www.scala-lang.org/feed/index.xml" rel="self"/>
  <link type="text/html" href="https://www.scala-lang.org/news/" rel="alternate"/>

  <updated>2026-06-09T02:45:05+02:00</updated>
  <author>
    <name>École Polytechnique Fédérale de Lausanne</name>
  </author>
  <rights>Copyright (c) 2002-2026 École Polytechnique Fédérale de Lausanne (EPFL), Lausanne, Switzerland</rights>

  
  <entry>
    <title>Scala 3.8.4 is now available!</title>
    <link href="https://www.scala-lang.org/news/3.8.4/"/>
    <updated>2026-06-05T00:00:00+02:00</updated>
    <id>https://www.scala-lang.org/news/release-notes-3.8.4</id>
    <content type="html">&lt;h2 id=&quot;release-highlights&quot;&gt;Release highlights&lt;/h2&gt;

&lt;h3 id=&quot;security-audit-fixes&quot;&gt;Security audit fixes&lt;/h3&gt;

&lt;p&gt;Scala 3.8.4 includes improvements and fixes for issues discovered during the &lt;a href=&quot;https://scala-lang.org/blog/2026/06/01/first-part-security-audit.html&quot;&gt;Scala codebase security audit&lt;/a&gt; carried out in collaboration with the Open Source Technology Improvement Fund and Quarkslab. Notable fixes in this release include:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Hardened TASTy parsing to prevent infinite loops on maliciously crafted files (&lt;a href=&quot;https://github.com/scala/scala3/pull/25676&quot;&gt;#25676&lt;/a&gt;)&lt;/li&gt;
  &lt;li&gt;Fixed a stored XSS vulnerability in Scaladoc (&lt;a href=&quot;https://github.com/scala/scala3/pull/25681&quot;&gt;#25681&lt;/a&gt;)&lt;/li&gt;
  &lt;li&gt;Improved error handling in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;scala.sys.process.Parser.tokenize&lt;/code&gt; (&lt;a href=&quot;https://github.com/scala/scala3/pull/25675&quot;&gt;#25675&lt;/a&gt;)&lt;/li&gt;
  &lt;li&gt;Fixed TastyPrinter’s JAR-walking logic to include subdirectories (&lt;a href=&quot;https://github.com/scala/scala3/pull/25678&quot;&gt;#25678&lt;/a&gt;)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;help-syntax-for-all-compiler-settings-26052&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;:help&lt;/code&gt; syntax for all compiler settings (&lt;a href=&quot;https://github.com/scala/scala3/pull/26052&quot;&gt;#26052&lt;/a&gt;)&lt;/h3&gt;

&lt;p&gt;You can now append &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;:help&lt;/code&gt; to any compiler setting to see its documentation — not just a fixed subset as before. This works wherever you pass compiler options, making it easier to discover available flags without leaving your workflow.&lt;/p&gt;

&lt;p&gt;With the Scala runner, add &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;:help&lt;/code&gt; to a flag on the command line when running a script or project:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&amp;gt; scala test.scala -Xkind-projector:help
-Xkind-projector  Allow `*` as type lambda placeholder to be compatible with
                  kind projector. When invoked as -Xkind-projector:underscores
                  will repurpose `_` to be a type parameter placeholder, this
                  will disable usage of underscore as a wildcard.
                  Default disable
                  Choices: disable, , underscores
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;In the REPL, pass the same flag through &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;:settings&lt;/code&gt;:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;scala&amp;gt; :settings -Wunused:help
-Wunused  Enable or disable specific `unused` warnings
          Choices:
          - nowarn,
          - all,
          - imports :
                Warn if an import selector is not referenced.,
          - privates :
                Warn if a private member is unused,
          - locals :
                Warn if a local definition is unused,
          - explicits :
                Warn if an explicit parameter is unused,
          - implicits :
                Warn if an implicit parameter is unused,
          - params :
                Enable -Wunused:explicits,implicits,
          - patvars :
                Warn if a variable bound in a pattern is unused,
          - linted :
                Enable -Wunused:imports,privates,locals,implicits
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;upgrade-to-scala-cli-1140&quot;&gt;Upgrade to Scala CLI 1.14.0&lt;/h3&gt;

&lt;p&gt;The bundled Scala CLI has been upgraded from 1.11.x through 1.12.5, 1.13.0, to &lt;strong&gt;1.14.0&lt;/strong&gt;. Notable additions across these versions include:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;v1.12.5:&lt;/strong&gt; experimental &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;--cross&lt;/code&gt; support for &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;run&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;package&lt;/code&gt;, and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;doc&lt;/code&gt;; global &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;--offline&lt;/code&gt; config key; experimental local &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.m2&lt;/code&gt; in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;publish local&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;v1.13.0:&lt;/strong&gt; Scala.js 1.21.0 support; Ammonite REPL deprecated and scheduled for removal; &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;java-test-runner&lt;/code&gt; for pure Java tests; GraalVM native-image packaging via &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;packaging.graalvmJvmId&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;packaging.graalvmArgs&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;v1.14.0:&lt;/strong&gt; support for &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.test.java&lt;/code&gt; files; a toggle to turn auto-IDE-setup off&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;See the &lt;a href=&quot;https://github.com/VirtusLab/scala-cli/releases/tag/v1.14.0&quot;&gt;Scala CLI release notes&lt;/a&gt; for full details.&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;For the complete list of changes and contributor credits, see the &lt;a href=&quot;https://github.com/scala/scala3/releases/tag/3.8.4&quot;&gt;release notes on GitHub&lt;/a&gt;.&lt;/p&gt;
</content>
  </entry>
  
  <entry>
    <title>Scala Codebase Security Audit Complete</title>
    <link href="https://www.scala-lang.org/blog/2026/06/01/first-part-security-audit.html"/>
    <updated>2026-06-01T00:00:00+02:00</updated>
    <id>https://www.scala-lang.org/blog/2026/06/01/first-part-security-audit</id>
    <content type="html">&lt;blockquote&gt;
  &lt;p&gt;This post covers work done under the &lt;a href=&quot;https://www.scala-lang.org/blog/2026/01/27/sta-invests-in-scala.html&quot;&gt;Sovereign Tech Fund investment&lt;/a&gt; umbrella: &lt;a href=&quot;https://contributors.scala-lang.org/t/standard-library-now-open-for-improvements-and-suggestions/7337&quot;&gt;Maintenance of the Standard Library/Core Library Modules and APIs&lt;/a&gt;. The work is coordinated by the &lt;a href=&quot;https://scala.epfl.ch/&quot;&gt;Scala Center&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The Scala Center is proud to share the first results of the security audit of Scala carried out in collaboration with &lt;a href=&quot;https://ostif.org/&quot;&gt;Open Source Technology Improvement Fund&lt;/a&gt; and the security researchers at &lt;a href=&quot;https://github.com/scala/scala-lang/blob/ddfc6996a8a1c66cc891261f57684a41ec5268b6/blog/_posts/2026-06-01-first-part-security-audit.md&quot;&gt;Quarkslab&lt;/a&gt;. The audit was divided into two major parts: an assessment of the Scala 3 compiler and Scala standard library codebases, and a separate review of Scala’s supply-chain security.&lt;/p&gt;

&lt;p&gt;This &lt;a href=&quot;https://ostif.org/wp-content/uploads/2026/05/26-01-2527-REP-scala-security-audit-V1.0.pdf&quot;&gt;first publication&lt;/a&gt; focuses on the compiler and standard library audit. Since many reported security issues in Scala ecosystems involve the standard library, the audit aimed to strengthen the security and robustness of Scala’s core components through a combination of manual code review and automated tooling, including fuzzing and Java deserialization gadget finders.&lt;/p&gt;

&lt;h2 id=&quot;results&quot;&gt;Results&lt;/h2&gt;

&lt;p&gt;Read the full report &lt;a href=&quot;https://ostif.org/wp-content/uploads/2026/05/26-01-2527-REP-scala-security-audit-V1.0.pdf&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;No critical or major security issues were identified during the audit. However, the review uncovered 5 medium severity issues, 1 low severity issue, and 2 informational findings, all of which have since been addressed by the Scala maintainers. All of these issues are fixed as of the date of this blog post, both for the 3.3 LTS branch and for the main 3.8 branch.&lt;/p&gt;

&lt;p&gt;Importantly, these issues do not affect typical users compiling Scala code locally or through continuous integration pipelines. Most findings were only relevant in scenarios where the Scala compiler is exposed as a service and processes untrusted input, where they could potentially lead to denial-of-service-type behavior.&lt;/p&gt;

&lt;h2 id=&quot;fixes&quot;&gt;Fixes&lt;/h2&gt;

&lt;p&gt;All reported issues were present in 3.8-RC1 and fixed before the publication of this blog post, both in the Scala 3.3 LTS branch and in the main Scala 3.8 development branch.&lt;/p&gt;

&lt;p&gt;One example was a medium severity issue in &lt;a href=&quot;https://github.com/scala/scala3/pull/25676&quot;&gt;the compiler’s handling of TASTy files&lt;/a&gt;. The compiler did not validate that certain offsets were nonnegative, which could lead to an infinite loop when processing a maliciously crafted TASTy file containing unexpected negative offsets. The fix introduced additional validation not only for this specific case, but more generally for parsing variable-length TASTy integers, helping prevent similar classes of issues in the future.&lt;/p&gt;

&lt;h2 id=&quot;summary&quot;&gt;Summary&lt;/h2&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th style=&quot;text-align: left&quot;&gt;Severity&lt;/th&gt;
      &lt;th style=&quot;text-align: left&quot;&gt;Description&lt;/th&gt;
      &lt;th style=&quot;text-align: left&quot;&gt;Perimeter&lt;/th&gt;
      &lt;th style=&quot;text-align: left&quot;&gt;Fixes&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;Medium&lt;/td&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;scala.sys.Process.ProcessBuilderImpl.AbstractFunction0&lt;/code&gt; may be used as a deserialization gadget&lt;/td&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;Standard library&lt;/td&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;&lt;a href=&quot;https://github.com/scala/scala3/pull/25679&quot;&gt;Issue 25679&lt;/a&gt;&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;Medium&lt;/td&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;Stored XSS vulnerability&lt;/td&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;Scaladoc (Scala 3.8-RC1)&lt;/td&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;&lt;a href=&quot;https://github.com/scala/scala3/pull/25681&quot;&gt;Issue 25681&lt;/a&gt;&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;Medium&lt;/td&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;Unexpected return value in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;scala.collection.SeqOps.indexOfSlice&lt;/code&gt; on empty sequences&lt;/td&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;Standard library&lt;/td&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;Invalid, Scala behaves the same as other languages here.&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;Medium&lt;/td&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;Uncaught &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ParseException&lt;/code&gt; in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;scala.sys.process.Parser.tokenize&lt;/code&gt; on unmatched quotes&lt;/td&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;Standard library&lt;/td&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;&lt;a href=&quot;https://github.com/scala/scala3/pull/25675&quot;&gt;Issue 25675&lt;/a&gt;&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;Medium&lt;/td&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;Infinite loop during section loading in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;dotty.tools.dotc.core.tasty.TastyUnpickler&lt;/code&gt;&lt;/td&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;Compiler&lt;/td&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;&lt;a href=&quot;https://github.com/scala/scala3/pull/25676&quot;&gt;Issue 25676&lt;/a&gt;&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;Low&lt;/td&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;Potential command injection in GitHub Action CI/CD scripts&lt;/td&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;GitHub Action workflows&lt;/td&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;&lt;a href=&quot;https://github.com/scala/scala3/pull/25677&quot;&gt;Issue 25677&lt;/a&gt;&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;Low&lt;/td&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;Scala JVM bytecode could lead to conflicts between generated and user-defined methods&lt;/td&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;Compiler&lt;/td&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;Acceptable, no evidence it leads to any security issue.&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;Info&lt;/td&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;Use of a non-cryptographically secure random number generator&lt;/td&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;Compiler&lt;/td&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;&lt;a href=&quot;https://github.com/scala/scala3/pull/25660&quot;&gt;Issue 25660&lt;/a&gt;&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;Info&lt;/td&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;TastyPrinter&lt;/code&gt; silently skips &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.tasty&lt;/code&gt; files in subdirectories of a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.jar&lt;/code&gt;&lt;/td&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;scalac -print-tasty&lt;/code&gt;&lt;/td&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;&lt;a href=&quot;https://github.com/scala/scala3/pull/26082&quot;&gt;Issue 26082&lt;/a&gt;&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;h2 id=&quot;how-to-report-future-security-issues&quot;&gt;How to report future security issues&lt;/h2&gt;

&lt;p&gt;Please let us know as soon as you discover a security issue as per &lt;a href=&quot;https://scala-lang.org/security/&quot;&gt;https://scala-lang.org/security/&lt;/a&gt;&lt;/p&gt;

&lt;h2 id=&quot;thank-you&quot;&gt;Thank you&lt;/h2&gt;

&lt;p&gt;We first began discussions with the team at Open Source Technology Improvement Fund in July 2024. Between defining the scope of the audit, securing funding, assembling the teams, and carrying out the work itself, nearly two years passed before reaching this milestone.&lt;/p&gt;

&lt;p&gt;Projects like this are a reminder that open source work takes time, collaboration and coordination, patience and persistence, and countless contributions along the way.&lt;/p&gt;

&lt;p&gt;And so, we extend our gratitude to every person and organization involved in making this effort possible, including the Sovereign Tech Agency, the Open Source Technology Improvement Fund, Quarkslab, and the many Scala teams and maintainers who contributed along the way. We also look forward to sharing the final part of the audit, focused on Scala’s supply-chain security.&lt;/p&gt;

&lt;h2 id=&quot;participation&quot;&gt;Participation&lt;/h2&gt;

&lt;p&gt;The Scala Center has been entrusted with coordinating the commissioned Scala work for the Sovereign Tech Fund. The Scala Center is an independent, not-for-profit center sponsored by &lt;a href=&quot;/blog/2023/09/11/scala-center-fundraising.html&quot;&gt;corporate members and individual backers like you&lt;/a&gt; to promote and facilitate Scala. If you would like to participate and/or see more of these types of efforts, please reach out to your manager to see if your company can donate engineering time or membership to the Scala Center.&lt;/p&gt;

&lt;p&gt;See &lt;a href=&quot;/blog/2023/09/11/scala-center-fundraising.html&quot;&gt;The Scala Center Fundraising Campaign&lt;/a&gt; for more details.&lt;/p&gt;

</content>
  </entry>
  
  <entry>
    <title>Scala Days 2026: Call for proposals open</title>
    <link href="https://www.scala-lang.org/blog/2026/04/30/scala-days-2026-cfp.html"/>
    <updated>2026-04-30T00:00:00+02:00</updated>
    <id>https://www.scala-lang.org/blog/2026/04/30/scala-days-2026-cfp</id>
    <content type="html">&lt;h2 id=&quot;scala-days-2026-call-for-proposals-open&quot;&gt;&lt;strong&gt;Scala Days 2026: Call for proposals open&lt;/strong&gt;&lt;/h2&gt;

&lt;p&gt;Submit your talk &lt;a href=&quot;https://cfp.scaladays.org/scala26/cfp&quot;&gt;https://cfp.scaladays.org/scala26/cfp&lt;/a&gt; and be part of Scala Days 2026!&lt;/p&gt;

&lt;p&gt;The Call for Proposals is now open and will close on May 31, 2026, at 23:59 CEST.&lt;/p&gt;

&lt;p&gt;The &lt;a href=&quot;https://scaladays.org/program-committee&quot;&gt;Program Committee&lt;/a&gt; is looking for talks, labs, and workshops that showcase how Scala is evolving and delivering value in today’s fast-changing technology landscape.&lt;/p&gt;

&lt;p&gt;In particular, we’re excited to hear practical insights, real-world experience reports, and forward-looking ideas.&lt;/p&gt;

&lt;p&gt;See the topics below for inspiration.&lt;/p&gt;

&lt;p&gt;Kind reminder: Super Early Bird tickets are available only until the end of the day on April 30, 2026.&lt;/p&gt;

&lt;h2 id=&quot;formats&quot;&gt;&lt;strong&gt;Formats&lt;/strong&gt;&lt;/h2&gt;

&lt;p&gt;This year’s program includes three submission formats. &lt;strong&gt;Talks&lt;/strong&gt; and &lt;strong&gt;Interactive labs&lt;/strong&gt; are part of the main conference program, while &lt;strong&gt;Workshops&lt;/strong&gt; take place after the conference and require a separate ticket.&lt;/p&gt;

&lt;h3 id=&quot;talks-30-minutes&quot;&gt;&lt;strong&gt;Talks (30 minutes)&lt;/strong&gt;&lt;/h3&gt;

&lt;p&gt;Classic conference talks for sharing ideas, lessons learned, technical deep-dives, and real-world experience.&lt;/p&gt;

&lt;p&gt;We’re looking for talks that bring real value to the community: practical insights, innovative approaches, hard-earned lessons, or fresh perspectives on Scala and its ecosystem.&lt;/p&gt;

&lt;p&gt;We will select up to 48 talks, organized across 3 parallel tracks as part of the main conference program.&lt;/p&gt;

&lt;h3 id=&quot;interactive-labs-2-hours&quot;&gt;&lt;strong&gt;Interactive Labs (2 hours)&lt;/strong&gt;&lt;/h3&gt;

&lt;p&gt;Interactive labs are a new format at Scala Days 2026: small-group, highly interactive sessions built around live demos, guided exploration, and practical experimentation during the conference.&lt;/p&gt;

&lt;p&gt;This format is ideal for showcasing tools, libraries, frameworks, and new ideas in action. The goal is for participants to explore, experiment, and leave with practical experience they can immediately apply.&lt;/p&gt;

&lt;p&gt;Because sessions are limited to 2 hours total, proposals should be designed to get participants engaged quickly, with minimal setup time and a clear path into the core experience.&lt;/p&gt;

&lt;p&gt;Interactive labs are also a great fit for open-source maintainers who want to introduce their projects, onboard new users, and grow their contributor community.&lt;/p&gt;

&lt;p&gt;We will host up to 16 Interactive labs, organized into two dedicated conference time slots, across both days.&lt;/p&gt;

&lt;p&gt;Each session is limited to 10 participants, with seats allocated on a first-come, first-served basis.&lt;/p&gt;

&lt;h3 id=&quot;workshops-2-days&quot;&gt;&lt;strong&gt;Workshops (2 days)&lt;/strong&gt;&lt;/h3&gt;

&lt;p&gt;Workshops are in-depth training sessions held after the main conference, on October 14–15.&lt;/p&gt;

&lt;p&gt;Unlike Talks and Interactive labs, Workshops require a separate ticket and provide dedicated time for deeper exploration of a topic through practical exercises, discussion, and guided learning.&lt;/p&gt;

&lt;p&gt;They are designed to equip participants with substantial knowledge and practical experience over the course of two full days.&lt;/p&gt;

&lt;h2 id=&quot;topics&quot;&gt;&lt;strong&gt;Topics&lt;/strong&gt;&lt;/h2&gt;

&lt;p&gt;These topics are intended as guidance, not limits. If your proposal is relevant to the Scala ecosystem, we want to hear it.&lt;/p&gt;

&lt;h3 id=&quot;experience--industry&quot;&gt;&lt;strong&gt;Experience &amp;amp; Industry&lt;/strong&gt;&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;Experience reports&lt;/li&gt;
  &lt;li&gt;Industrial adoption&lt;/li&gt;
  &lt;li&gt;Libraries and applications&lt;/li&gt;
  &lt;li&gt;Distributed systems&lt;/li&gt;
  &lt;li&gt;Scala-based contracts&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;data--ai&quot;&gt;&lt;strong&gt;Data &amp;amp; AI&lt;/strong&gt;&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;Machine learning in Scala&lt;/li&gt;
  &lt;li&gt;Big data&lt;/li&gt;
  &lt;li&gt;Scala in AI/ML pipelines&lt;/li&gt;
  &lt;li&gt;Integrating Scala with LLM-based systems&lt;/li&gt;
  &lt;li&gt;Scala’s role in data-centric and AI-driven architectures&lt;/li&gt;
  &lt;li&gt;Scala safety features for agentic systems&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;development&quot;&gt;&lt;strong&gt;Development&lt;/strong&gt;&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;Web development&lt;/li&gt;
  &lt;li&gt;Scala.js showcases&lt;/li&gt;
  &lt;li&gt;Game development&lt;/li&gt;
  &lt;li&gt;Native applications&lt;/li&gt;
  &lt;li&gt;Workflow and programming methodologies&lt;/li&gt;
  &lt;li&gt;Cloud and deployment&lt;/li&gt;
  &lt;li&gt;DevOps&lt;/li&gt;
  &lt;li&gt;Security&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;tooling&quot;&gt;&lt;strong&gt;Tooling&lt;/strong&gt;&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;Compilers and virtual machines&lt;/li&gt;
  &lt;li&gt;IDEs&lt;/li&gt;
  &lt;li&gt;Testing frameworks&lt;/li&gt;
  &lt;li&gt;Build tools&lt;/li&gt;
  &lt;li&gt;LLM-assisted development&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;foundations&quot;&gt;&lt;strong&gt;Foundations&lt;/strong&gt;&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;Functional programming&lt;/li&gt;
  &lt;li&gt;Type systems&lt;/li&gt;
  &lt;li&gt;Concurrency and parallelism&lt;/li&gt;
  &lt;li&gt;Algorithms and performance&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;community&quot;&gt;&lt;strong&gt;Community&lt;/strong&gt;&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;Open source&lt;/li&gt;
  &lt;li&gt;Teaching and mentoring&lt;/li&gt;
  &lt;li&gt;Community building&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;other-areas&quot;&gt;&lt;strong&gt;Other Areas&lt;/strong&gt;&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;Hardware&lt;/li&gt;
  &lt;li&gt;Networking&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;strategic--forward-looking-topics&quot;&gt;&lt;strong&gt;Strategic &amp;amp; Forward-Looking Topics&lt;/strong&gt;&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;Scala’s place in modern software ecosystems&lt;/li&gt;
  &lt;li&gt;How companies are using Scala in AI-driven environments&lt;/li&gt;
  &lt;li&gt;Adapting Scala to new architectural paradigms (data platforms, cloud-native, AI-first systems)&lt;/li&gt;
  &lt;li&gt;Real-world lessons from integrating Scala with emerging technologies&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;get-inspired&quot;&gt;&lt;strong&gt;Get inspired&lt;/strong&gt;&lt;/h2&gt;

&lt;p&gt;Need inspiration? Explore talks from previous editions of Scala Days on the &lt;a href=&quot;https://www.youtube.com/@ScalaDaysConferences&quot;&gt;YouTube channel&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;If you have questions or need help with your submission, contact us at &lt;strong&gt;info@scaladays.org&lt;/strong&gt;.&lt;/p&gt;

</content>
  </entry>
  
  <entry>
    <title>Last mile towards sbt 2</title>
    <link href="https://www.scala-lang.org/blog/2026/04/14/last-mile-towards-sbt2.html"/>
    <updated>2026-04-14T00:00:00+02:00</updated>
    <id>https://www.scala-lang.org/blog/2026/04/14/last-mile-towards-sbt2</id>
    <content type="html">&lt;blockquote&gt;
  &lt;p&gt;This post covers work done under the &lt;a href=&quot;https://www.scala-lang.org/blog/2026/01/27/sta-invests-in-scala.html&quot;&gt;Sovereign Tech Fund investment&lt;/a&gt; umbrella: &lt;a href=&quot;https://contributors.scala-lang.org/t/sbt-2-production-ready-roadmap/7351&quot;&gt;sbt 2 Stable Release and Maintenance&lt;/a&gt;. The work is coordinated by the &lt;a href=&quot;https://scala.epfl.ch/&quot;&gt;Scala Center&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;At conferences or on social media, the question we get most often is:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;When is sbt 2 coming out?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;We’ll discuss the plan in this post. But let’s go over the status first.&lt;/p&gt;

&lt;h2 id=&quot;whats-new-in-sbt-2&quot;&gt;What’s new in sbt 2?&lt;/h2&gt;

&lt;p&gt;sbt 2 is a new major version of sbt. If you’re familiar with sbt 1.x, hopefully the jump is not too far, but we have pushed sbt to a more modern standard. The headline features are:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;sbt 2.x uses Scala 3.x (rather than Scala 2.12) for build definitions and plugins (Both sbt 1.x and 2.x are capable of building Scala 2.x and 3.x)&lt;/li&gt;
  &lt;li&gt;Embraces a simpler build.sbt via common settings&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;test&lt;/code&gt; changed to an incremental test&lt;/li&gt;
  &lt;li&gt;Local and remote cache system that is Bazel-compatible&lt;/li&gt;
  &lt;li&gt;Uses sbtn (native-image client) for faster startup&lt;/li&gt;
  &lt;li&gt;Project matrix that can cross build subprojects in parallel&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;br /&gt;
For more details, please check out the Scala Days 2025 talk &lt;a href=&quot;https://www.youtube.com/watch?v=GM2ywMb4z7A&quot;&gt;sbt 2.0: go big&lt;/a&gt; that I gave in August 2025.&lt;/p&gt;

&lt;p&gt;To share the progress thus far, we released the &lt;a href=&quot;https://eed3si9n.com/sbt-2.0-ideas&quot;&gt;sbt 2.0 ideas&lt;/a&gt; post in 2023, with sbt 2.0.0-alpha7. After a few more years of development, we released a beta version &lt;a href=&quot;https://eed3si9n.com/sbt-2.0.0-RC2&quot;&gt;sbt 2.0.0-RC2&lt;/a&gt; that’s ready for testing, around Scala Days 2025. Since then, we have been releasing more beta versions with both bug fixes and community-contributed feature enhancements. Perhaps surprising to some, sbt 2.x already started the binary compatibility from the RC series. This gave us a head start on repopulating the plugin ecosystem.&lt;/p&gt;

&lt;h2 id=&quot;repopulating-the-plugin-ecosystem&quot;&gt;Repopulating the plugin ecosystem&lt;/h2&gt;

&lt;p&gt;Thanks to the community effort, we already have &lt;a href=&quot;https://www.scala-sbt.org/2.x/docs/en/community-plugins.html&quot;&gt;60+ plugins&lt;/a&gt; ported to sbt 2.x. This is amazing for a build tool that hasn’t been released yet. Special thanks to Kenji Yoshida for pull requests, preparing and porting many plugins to sbt 2.&lt;/p&gt;

&lt;p&gt;Under the sbt 2 workstream, Anatolii from Scala Center has created &lt;a href=&quot;/blog/2026/03/02/sbt2-compat.html&quot;&gt;the sbt2-compat plugin&lt;/a&gt;, which bridges the source-level differences between sbt 1.x and 2.x. This allows cross-building of a plugin, aiding the migration process. Also under the STA workstream, Rikito Taniguchi from VirtusLab has created a pull request to &lt;a href=&quot;https://github.com/scala-js/scala-js/pull/5314&quot;&gt;cross build Scala.JS plugin to sbt 2.x (scala-js#5314)&lt;/a&gt;.&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th style=&quot;text-align: right&quot;&gt;Plugin&lt;/th&gt;
      &lt;th style=&quot;text-align: right&quot;&gt;Version&lt;/th&gt;
      &lt;th style=&quot;text-align: center&quot;&gt;Published&lt;/th&gt;
      &lt;th style=&quot;text-align: right&quot;&gt;Notes&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;Scala Native&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0.5.11&lt;/code&gt;&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;✅&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt; &lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;sbt-assembly&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;2.3.1&lt;/code&gt;&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;✅&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt; &lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;Play&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;3.1.0-M9&lt;/code&gt;&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;⚠️&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;Pending scripted tests.&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;Scala.JS&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;n/a&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;n/a&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;Pending &lt;a href=&quot;https://github.com/scala-js/scala-js/pull/5314&quot;&gt;scala-js#5314&lt;/a&gt;&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;Independently, the Play and Scala Native projects have been working towards sbt 2.x support as well.&lt;/p&gt;

&lt;h2 id=&quot;tooling-support-and-documentation&quot;&gt;Tooling support and documentation&lt;/h2&gt;

&lt;p&gt;Both IntelliJ Scala Plugin and Metals have published sbt plugins to import sbt 2.x projects.&lt;/p&gt;

&lt;p&gt;Documentation has been reorganized and partly rewritten as &lt;a href=&quot;https://www.scala-sbt.org/2.x/docs/en/&quot;&gt;The book of sbt&lt;/a&gt;, which has also been translated to &lt;a href=&quot;https://www.scala-sbt.org/2.x/docs/ja/&quot;&gt;Japanese&lt;/a&gt; and &lt;a href=&quot;https://www.scala-sbt.org/2.x/docs/zh-cn/&quot;&gt;Chinese&lt;/a&gt;.&lt;/p&gt;

&lt;h2 id=&quot;locking-down-to-20x-branch&quot;&gt;Locking down to 2.0.x branch&lt;/h2&gt;

&lt;p&gt;We have now created the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;2.0.x&lt;/code&gt; branch, so by default, all pull requests will target sbt 2.1. Only the critical bug fixes will be backported to the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;2.0.x&lt;/code&gt; branch.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;On March 26, we released &lt;a href=&quot;https://eed3si9n.com/sbt-2.0.0-RC10&quot;&gt;sbt 2.0.0-RC10&lt;/a&gt;, kicking off the last mile process.&lt;/li&gt;
  &lt;li&gt;On April 7, we released &lt;a href=&quot;https://eed3si9n.com/sbt-2.0.0-RC11&quot;&gt;sbt 2.0.0-RC11&lt;/a&gt;.&lt;/li&gt;
  &lt;li&gt;On April 13, we released &lt;a href=&quot;https://eed3si9n.com/sbt-2.0.0-RC12&quot;&gt;sbt 2.0.0-RC12&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Next steps&lt;/strong&gt;: Please try using &lt;a href=&quot;https://github.com/sbt/sbt/releases&quot;&gt;the latest RC&lt;/a&gt; on your projects, and check out the newly updated documentation. If you find bugs or missing documentation, please let us know by creating &lt;a href=&quot;https://github.com/sbt/sbt/issues&quot;&gt;an issue on GitHub&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;We will likely release a few more release candidates, but if no critical bugs are found, we will graduate one of them to the final release. So when is sbt 2 coming out? Depending on the bugs we discover, we are hopeful that it can happen in a few weeks to a few months.&lt;/p&gt;

&lt;h2 id=&quot;participation&quot;&gt;Participation&lt;/h2&gt;

&lt;p&gt;The Scala Center has been entrusted with coordinating the commissioned Scala work for the Sovereign Tech Fund. The Scala Center is an independent, not-for-profit center sponsored by &lt;a href=&quot;/blog/2023/09/11/scala-center-fundraising.html&quot;&gt;corporate members and individual backers like you&lt;/a&gt; to promote and facilitate Scala. If you would like to participate and/or see more of these types of efforts, please reach out to your manager to see if your company can donate engineering time or membership to the Scala Center.&lt;/p&gt;

&lt;p&gt;See &lt;a href=&quot;/blog/2023/09/11/scala-center-fundraising.html&quot;&gt;The Scala Center Fundraising Campaign&lt;/a&gt; for more details.&lt;/p&gt;
</content>
  </entry>
  
  <entry>
    <title>Fixing a Command Injection Vulnerability in sbt</title>
    <link href="https://www.scala-lang.org/blog/2026/03/31/sbt-security-advisory.html"/>
    <updated>2026-03-31T00:00:00+02:00</updated>
    <id>https://www.scala-lang.org/blog/2026/03/31/sbt-security-advisory</id>
    <content type="html">&lt;blockquote&gt;
  &lt;p&gt;This post covers work done under the &lt;a href=&quot;https://www.scala-lang.org/blog/2026/01/27/sta-invests-in-scala.html&quot;&gt;Sovereign Tech Fund investment&lt;/a&gt; umbrella: &lt;a href=&quot;https://contributors.scala-lang.org/t/sbt-2-production-ready-roadmap/7351&quot;&gt;sbt 2 Stable Release and Maintenance&lt;/a&gt;. The work is coordinated by the &lt;a href=&quot;https://scala.epfl.ch/&quot;&gt;Scala Center&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;As part of our ongoing work on the sbt 2 release, we’ve been reviewing and hardening core parts of the sbt codebase. During that work, we discovered a command injection vulnerability in how sbt resolves source dependencies on Windows. The issue has been assigned &lt;a href=&quot;https://www.cve.org/CVERecord?id=CVE-2026-32948&quot;&gt;CVE-2026-32948&lt;/a&gt;, rated Moderate (CVSS 6.7), and is now fixed. If you use sbt on Windows, update to &lt;strong&gt;sbt 1.12.8&lt;/strong&gt; or &lt;strong&gt;sbt 2.0.0-RC10&lt;/strong&gt; or later to apply the fix.&lt;/p&gt;

&lt;h2 id=&quot;the-vulnerability&quot;&gt;The vulnerability&lt;/h2&gt;

&lt;p&gt;sbt has the &lt;a href=&quot;https://www.scala-sbt.org/1.x/docs/Multi-Project.html#Project+dependency&quot;&gt;source dependencies&lt;/a&gt; feature that lets you depend on a VCS repository in your build definition. For example, to depend on the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;develop&lt;/code&gt; branch of a project published to GitHub:&lt;/p&gt;

&lt;div class=&quot;language-scala highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;lazy&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;val&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;dep&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;RootProject&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;
  &lt;span class=&quot;nf&quot;&gt;uri&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;https://github.com/sbt/io.git#develop&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;When sbt resolves this, it clones the repository and checks out the branch specified in the URI fragment - the part after &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;#&lt;/code&gt;. To do this, sbt runs a VCS client (git, hg, or svn) as an external process.&lt;/p&gt;

&lt;p&gt;On Windows, sbt historically wrapped these VCS commands in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cmd /c&lt;/code&gt; - routing them through the Windows command interpreter. &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cmd.exe&lt;/code&gt; treats characters like &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&amp;amp;&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;|&lt;/code&gt;, and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;;&lt;/code&gt; as command separators. The URI fragment is user-controlled and was passed to VCS commands without any validation. This allows an attacker to break out of the intended git command and execute an arbitrary shell command on Windows.&lt;/p&gt;

&lt;p&gt;For example, consider a dependency declared as:&lt;/p&gt;

&lt;div class=&quot;language-scala highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;lazy&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;val&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;vulnerable&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;RootProject&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;
  &lt;span class=&quot;nf&quot;&gt;uri&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;https://github.com/sbt/io.git#develop%26%26calc.exe&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;%26%26&lt;/code&gt; decodes to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&amp;amp;&amp;amp;&lt;/code&gt;. When this reaches &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cmd /c git checkout develop&amp;amp;&amp;amp;calc.exe&lt;/code&gt;, the command interpreter executes two commands: first &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;git checkout develop&lt;/code&gt;, then &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;calc.exe&lt;/code&gt;, starting the Windows Calculator.&lt;/p&gt;

&lt;p&gt;This is a classic &lt;a href=&quot;https://cwe.mitre.org/data/definitions/78.html&quot;&gt;OS command injection&lt;/a&gt; (CWE-78). The vulnerability has existed since sbt 0.9.5 and affects both the sbt 1.x line and sbt 2.0 release candidates on Windows.&lt;/p&gt;

&lt;h2 id=&quot;severity&quot;&gt;Severity&lt;/h2&gt;

&lt;p&gt;The severity is moderate because exploitation requires an attacker to actively build a project containing a malicious dependency URI, then requires a user to proactively build that project on their local machine. As sbt is a build tool, building a project carries an inherent risk of arbitrary command execution. As with any untrusted software, before building a project, you should check the source code, including the build file definitions.&lt;/p&gt;

&lt;p&gt;The threat model here is that a malicious attacker may try to inject commands disguised as a source dependency URL, and pass the code review because the behavior is unexpected.&lt;/p&gt;

&lt;h2 id=&quot;the-fix&quot;&gt;The fix&lt;/h2&gt;

&lt;p&gt;The primary fix was to stop routing VCS commands through &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cmd /c&lt;/code&gt;. Git, Mercurial, and Subversion all ship as &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.exe&lt;/code&gt; binaries on Windows. When Java’s &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ProcessBuilder&lt;/code&gt; invokes an &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.exe&lt;/code&gt; directly, arguments are passed as separate strings to the operating system - shell metacharacters are not interpreted. By removing the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cmd /c&lt;/code&gt; wrapper, the injection vector disappears.&lt;/p&gt;

&lt;p&gt;As defense-in-depth, we also added input validation. URI fragments are now checked against an allowlist of characters - only alphanumeric characters, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;-&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;_&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/&lt;/code&gt;, and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;+&lt;/code&gt; are allowed.&lt;/p&gt;

&lt;p&gt;Both measures follow established guidance from &lt;a href=&quot;https://cheatsheetseries.owasp.org/cheatsheets/OS_Command_Injection_Defense_Cheat_Sheet.html&quot;&gt;OWASP&lt;/a&gt;, &lt;a href=&quot;https://www.oracle.com/java/technologies/javase/seccodeguide.html&quot;&gt;Oracle’s Secure Coding Guidelines&lt;/a&gt;, and the &lt;a href=&quot;https://openjdk.org/jeps/8263697&quot;&gt;JEP 8263697 proposal&lt;/a&gt; for safer process launching.&lt;/p&gt;

&lt;p&gt;The fix is available in sbt 1.12.8 and sbt 2.0.0-RC10. The full advisory is published as &lt;a href=&quot;https://github.com/sbt/sbt/security/advisories/GHSA-x4ff-q6h8-v7gw&quot;&gt;GHSA-x4ff-q6h8-v7gw&lt;/a&gt;.&lt;/p&gt;

&lt;h2 id=&quot;workflow-of-applying-the-fix&quot;&gt;Workflow of applying the fix&lt;/h2&gt;

&lt;p&gt;One interesting detail to mention is that GitHub provides a &lt;a href=&quot;https://docs.github.com/en/code-security/security-advisories/guidance-on-reporting-and-writing/privately-reporting-a-security-vulnerability&quot;&gt;way&lt;/a&gt; to report a vulnerability, work on the fix and submit a PR privately to prevent the vulnerability from being publicly disclosed before the fix is ready. If you encounter a security vulnerability in a Scala project, you should do the same, reporting it to the maintainers via Security Advisory on GitHub.&lt;/p&gt;

&lt;h2 id=&quot;applying-the-fix&quot;&gt;Applying the fix&lt;/h2&gt;

&lt;p&gt;Update your &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;project/build.properties&lt;/code&gt; to sbt 1.12.8 or later, or sbt 2.0.0-RC10 if you are using sbt 2. If your build uses source dependencies, verify that the URIs point to repositories you trust. In general, treat build definitions and VCS dependencies (including their build and source code) with the same review standards as application code. A &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;build.sbt&lt;/code&gt; runs arbitrary Scala at build time and deserves the same scrutiny as any other code in your repository.&lt;/p&gt;

&lt;h2 id=&quot;participation&quot;&gt;Participation&lt;/h2&gt;

&lt;p&gt;The Scala Center has been entrusted with coordinating the commissioned Scala work for the Sovereign Tech Fund. The Scala Center is an independent, not-for-profit center sponsored by &lt;a href=&quot;/blog/2023/09/11/scala-center-fundraising.html&quot;&gt;corporate members and individual backers like you&lt;/a&gt; to promote and facilitate Scala. If you would like to participate and/or see more of these types of efforts, please reach out to your manager to see if your company can donate engineering time or membership to the Scala Center.&lt;/p&gt;

&lt;p&gt;See &lt;a href=&quot;/blog/2023/09/11/scala-center-fundraising.html&quot;&gt;The Scala Center Fundraising Campaign&lt;/a&gt; for more details.&lt;/p&gt;
</content>
  </entry>
  
  <entry>
    <title>Scala 3.8.3 is now available!</title>
    <link href="https://www.scala-lang.org/news/3.8.3/"/>
    <updated>2026-03-31T00:00:00+02:00</updated>
    <id>https://www.scala-lang.org/news/release-notes-3.8.3</id>
    <content type="html">&lt;h1 id=&quot;scala-383-is-now-available&quot;&gt;Scala 3.8.3 is now available!&lt;/h1&gt;

&lt;h2 id=&quot;release-highlights&quot;&gt;Release highlights&lt;/h2&gt;

&lt;h3 id=&quot;local-coverage-exclusions-with--coverage-off-blocks-24486&quot;&gt;Local coverage exclusions with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;// $COVERAGE-OFF$&lt;/code&gt; blocks (&lt;a href=&quot;https://github.com/scala/scala3/pull/24486&quot;&gt;#24486&lt;/a&gt;)&lt;/h3&gt;

&lt;p&gt;Coverage-instrumented builds can now disable coverage for a selected region of code, instead of excluding a whole file or class. This is useful for generated code, intentionally defensive branches, or support code that would otherwise distort coverage results.&lt;/p&gt;

&lt;div class=&quot;language-scala highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;//&amp;gt; using scala 3.8.3&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;//&amp;gt; using options --coverage-out coverage-data&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Parser&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;kt&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;parse&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;input:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Int&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;
    &lt;span class=&quot;nv&quot;&gt;input&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;toInt&lt;/span&gt;

  &lt;span class=&quot;c1&quot;&gt;// $COVERAGE-OFF$&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;debugFallback&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;input&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Int&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;input&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;zero&quot;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;then&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;
  &lt;span class=&quot;c1&quot;&gt;// $COVERAGE-ON$&lt;/span&gt;

&lt;span class=&quot;nd&quot;&gt;@main&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;CoverageTest&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;val&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;parser&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Parser&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt;
  &lt;span class=&quot;nf&quot;&gt;assert&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;parser&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;parse&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;42&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;42&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Only the code between the markers is skipped by coverage instrumentation. The rest of the file is still measured as usual.&lt;/p&gt;

&lt;h3 id=&quot;safe-mode-for-capability-safe-code-25307&quot;&gt;Safe mode for capability-safe code (&lt;a href=&quot;https://github.com/scala/scala3/pull/25307&quot;&gt;#25307&lt;/a&gt;)&lt;/h3&gt;

&lt;p&gt;Scala 3.8.3 introduces &lt;strong&gt;safe mode&lt;/strong&gt;, a new experimental language subset that can be enabled with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;import language.experimental.safe&lt;/code&gt; or &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;-language:experimental.safe&lt;/code&gt;. As described in the &lt;a href=&quot;https://www.scala-lang.org/api/3.8.3/docs/experimental/capture-checking/safe.html&quot;&gt;safe mode reference&lt;/a&gt;, this is not just “stricter capture checking”: it is a capability-safe subset intended for agent-generated or otherwise untrusted code.&lt;/p&gt;

&lt;p&gt;The underlying model is also described in the research paper &lt;a href=&quot;https://arxiv.org/abs/2603.00991&quot;&gt;Tracking Capabilities for Safer Agents&lt;/a&gt;, which proposes using Scala 3 with capture checking as a programming-language-based safety harness for AI agents.&lt;/p&gt;

&lt;p&gt;When safe mode is enabled, the compiler rejects unchecked casts and unchecked pattern matches, forbids escape hatches such as &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;caps.unsafe&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;@unchecked&lt;/code&gt;, and runtime reflection, turns on capture checking with mutation tracking, and restricts access to global APIs unless they are known-safe or explicitly reviewed.&lt;/p&gt;

&lt;p&gt;That last point is what makes the feature practical. Safe code is meant to call a restricted set of APIs directly, while effectful or implementation-dependent behavior can still be exposed through wrappers marked &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;@assumeSafe&lt;/code&gt;. The implementation in &lt;a href=&quot;https://github.com/scala/scala3/pull/25307&quot;&gt;#25307&lt;/a&gt; makes that boundary explicit: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;@assumeSafe&lt;/code&gt; declarations are themselves written outside safe mode, and safe code calls them from within the restricted subset.&lt;/p&gt;

&lt;div class=&quot;language-scala highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;// app.scala&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;//&amp;gt; using scala 3.8.3&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;//&amp;gt; using file CheckedMailer.scala&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;//&amp;gt; using options -experimental&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;language.experimental.safe&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;object&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;PotentiallyUnsafeApp&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;kt&quot;&gt;val&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;address&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;EmailAddress&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;team@scala-lang.org&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;nv&quot;&gt;CheckedMailer&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;send&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;address&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;// ok&lt;/span&gt;
  &lt;span class=&quot;nf&quot;&gt;println&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;address&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;             &lt;span class=&quot;c1&quot;&gt;// error: rejected in safe mode&lt;/span&gt;
  &lt;span class=&quot;nv&quot;&gt;address&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;asInstanceOf&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// error: rejected in safe mode&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;address&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;match&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;EmailAddress&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rawAddress&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;???&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;// error: rejected in safe mode&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;div class=&quot;language-scala highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;// CheckedMailer.scala&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;scala.caps.assumeSafe&lt;/span&gt;

&lt;span class=&quot;nd&quot;&gt;@assumeSafe&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;object&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;CheckedMailer&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;send&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;to:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;EmailAddress&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;
        &lt;span class=&quot;nv&quot;&gt;scala&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;Console&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;out&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;println&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Sending message to $to&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;opaque&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;EmailAddress&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;&amp;lt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;object&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;EmailAddress&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;@assumeSafe&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;apply&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;value:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;EmailAddress&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;value&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;unapply&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;EmailAddress&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Option&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Some&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;In the example above, the safe code in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;app.scala&lt;/code&gt; can call &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;CheckedMailer.send&lt;/code&gt;, but the effectful operation is isolated behind an &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;@assumeSafe&lt;/code&gt; boundary. By contrast, direct calls to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;println&lt;/code&gt;, unchecked &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;asInstanceOf&lt;/code&gt; casts, or &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;scala.caps.unsafe&lt;/code&gt; helpers are rejected in safe mode.&lt;/p&gt;

&lt;h3 id=&quot;scala-2-jvm-optimizer-ported-to-scala-3-25165&quot;&gt;Scala 2 JVM optimizer ported to Scala 3 (&lt;a href=&quot;https://github.com/scala/scala3/pull/25165&quot;&gt;#25165&lt;/a&gt;)&lt;/h3&gt;

&lt;p&gt;Scala 3 now includes the port of the Scala 2 JVM backend optimizer. The optimizer is opt-in: compiler flag &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;-opt&lt;/code&gt; enables local bytecode optimizations, while &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;-opt-inline:...&lt;/code&gt; controls which classes and packages may be inlined across call sites. This brings Scala 3 to feature parity with the Scala 2 optimizer and opens the door to performance gains for JVM applications.&lt;/p&gt;

&lt;p&gt;Rather than enabling blanket inlining everywhere, it is usually better to start from explicit filters. The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;-opt-inline&lt;/code&gt; setting accepts a comma-separated list of patterns; &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;**&lt;/code&gt; matches all classes, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;a.**&lt;/code&gt; matches a package and its subpackages, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&amp;lt;sources&amp;gt;&lt;/code&gt; matches classes compiled in the current run, and a leading &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;!&lt;/code&gt; excludes matches. The last matching pattern wins.&lt;/p&gt;

&lt;div class=&quot;language-scala highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;//&amp;gt; using scala 3.8.3&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;//&amp;gt; using options -opt&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;//&amp;gt; using options &quot;-opt-inline:&amp;lt;sources&amp;gt;,my.app.**,!java.**,!org.example.**&quot;&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;//&amp;gt; using options &quot;-Wopt:at-inline-failed-summary,no-inline-missing-bytecode&quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;In this configuration, the optimizer may inline code from the current compilation (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&amp;lt;sources&amp;gt;&lt;/code&gt;) and from &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;my.app&lt;/code&gt; subpackages defined in external dependencies, but not from the JDK or the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;org.example&lt;/code&gt; packages. This is often a good starting point for applications. For libraries, the conservative choice is usually to inline only from &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&amp;lt;sources&amp;gt;&lt;/code&gt; or from packages you fully control.&lt;/p&gt;

&lt;p&gt;The optimizer port also brings additional settings:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;-Wopt:...&lt;/code&gt; enables optimizer warnings. Available choices are &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;all&lt;/code&gt; or &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;at-inline-failed-summary&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;at-inline-failed&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;any-inline-failed&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;no-inline-mixed&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;no-inline-missing-bytecode&lt;/code&gt;, and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;no-inline-missing-attribute&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;-Yopt-specific:...&lt;/code&gt; enables individual optimization passes such as &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;copy-propagation&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;box-unbox&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;nullness-tracking&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;closure-invocations&lt;/code&gt;, or &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;redundant-casts&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;-Yopt-inline-heuristics:default|everything|at-inline-annotated&lt;/code&gt; adjusts how aggressively the compiler chooses call sites for inlining&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;-Yopt-log-inline:&amp;lt;prefix&amp;gt;&lt;/code&gt; logs inliner activity for matching methods&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;-Yopt-trace:&amp;lt;prefix&amp;gt;&lt;/code&gt; traces optimizer progress for matching methods&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;-Wopt&lt;/code&gt; options let you choose between a one-line summary for failed &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;@inline&lt;/code&gt; calls, detailed per-callsite diagnostics, reporting for heuristic inlining failures, and warnings for cases where inlining could not even be decided because bytecode or Scala inline metadata was unavailable.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;-Y...&lt;/code&gt; optimizer flags are primarily intended for debugging and internal use. As with other &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;-Y&lt;/code&gt; settings, they are not stable user-facing interfaces, and their exact behavior may change between releases.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;As with the Scala 2 optimizer, inlining external code comes with a compatibility trade-off: if you compile against one version of a dependency and later run against a different one, any inlined bytecode will not pick up the dependency’s runtime bug fixes or behavior changes. In practice, that means aggressive cross-library inlining is best reserved for applications with tightly controlled runtime classpaths. Read more about binary compatibility of optimized code in the &lt;a href=&quot;https://docs.scala-lang.org/overviews/compiler-options/optimizer.html#binary-compatibility&quot;&gt;Scala 2 optimizer documentation&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The long-term plan is to build on this work in Scala 3.9 by enabling optimizations for the Scala standard library and the compiler itself.&lt;/p&gt;

&lt;h3 id=&quot;-print-lines-is-deprecated-for-removal-but-remains-accepted-as-a-no-op-25330&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;-print-lines&lt;/code&gt; is deprecated for removal, but remains accepted as a no-op (&lt;a href=&quot;https://github.com/scala/scala3/pull/25330&quot;&gt;#25330&lt;/a&gt;)&lt;/h3&gt;

&lt;p&gt;Scala 3.8.3 restores the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;-print-lines&lt;/code&gt; flag for compatibility, but only as a deprecated no-op. This avoids breaking existing builds in a patch release while giving users time to remove the setting from their build definitions.&lt;/p&gt;

&lt;p&gt;The flag no longer has any effect and is scheduled for removal in Scala 3.9.0.&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;For the complete list of changes and contributor credits, see the &lt;a href=&quot;https://github.com/scala/scala3/releases/tag/3.8.3&quot;&gt;release notes on GitHub&lt;/a&gt;.&lt;/p&gt;
</content>
  </entry>
  
  <entry>
    <title>Announcing Scala Days 2026</title>
    <link href="https://www.scala-lang.org/blog/2026/03/26/scala-days-2026.html"/>
    <updated>2026-03-26T00:00:00+01:00</updated>
    <id>https://www.scala-lang.org/blog/2026/03/26/scala-days-2026</id>
    <content type="html">&lt;p&gt;We are very happy to announce that the &lt;a href=&quot;https://scaladays.org/&quot;&gt;Scala Days 2026 conference&lt;/a&gt; will be taking place 12 - 13 October in Berlin, Germany, one of Europe’s most vibrant tech and open source hubs, known for its strong culture of collaboration and its growing role in advancing digital sovereignty through open technologies.&lt;/p&gt;

&lt;p&gt;Grab your &lt;a href=&quot;https://tickets.plainschwarz.com/scaladays26/&quot;&gt;Super Early Bird ticket&lt;/a&gt; and join us in Berlin this autumn!&lt;/p&gt;

&lt;h3 id=&quot;co-located-events&quot;&gt;Co-located events&lt;/h3&gt;

&lt;p&gt;Workshops will follow on 14–15 October, with various community-driven, co-located events taking place around the conference, possibly including the preceding weekend.&lt;/p&gt;

&lt;h3 id=&quot;meet-plain-schwarz&quot;&gt;Meet Plain Schwarz&lt;/h3&gt;

&lt;p&gt;For the Scala Days 2026 conference, the Scala Center partnered with Berlin-based company &lt;a href=&quot;https://plainschwarz.com&quot;&gt;Plain Schwarz&lt;/a&gt;, internationally renowned for organising conferences like Berlin Buzzwords and FOSS Backstage. Join us in welcoming Paul and the Plain Schwarz team to the Scala Days community as we work together on a refreshed and dynamic 2026 edition that stays true to Scala Days’ core spirit: business-driven and community-infused.&lt;/p&gt;

&lt;h3 id=&quot;call-to-action&quot;&gt;Call to action&lt;/h3&gt;

&lt;p&gt;Get your tickets at &lt;a href=&quot;https://tickets.plainschwarz.com/scaladays26/&quot;&gt;Super Early Bird&lt;/a&gt; price until April 9th, 23:55 CEST.&lt;/p&gt;

&lt;p&gt;Interested in sponsoring Scala Days 2026? Please inquire at &lt;a href=&quot;mailto:info@scaladays.org&quot;&gt;info@scaladays.org&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Follow us and share on &lt;a href=&quot;https://mastodon.social/@scaladays&quot;&gt;Mastodon&lt;/a&gt;, &lt;a href=&quot;https://bsky.app/profile/scaladays.org&quot;&gt;Bluesky&lt;/a&gt;, &lt;a href=&quot;https://www.linkedin.com/company/scala-center&quot;&gt;LinkedIn&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;To get early updates and special offers, please sign up for the &lt;a href=&quot;https://plainschwarz.com/scala-days-2026-newsletter/&quot;&gt;mailing list&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Join the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;#scala-days&lt;/code&gt; channel on the &lt;a href=&quot;https://discord.com/invite/scala&quot;&gt;Scala Discord&lt;/a&gt; to chat with fellow attendees.&lt;/p&gt;

&lt;p&gt;Call for talk and workshop proposals opens late April 2026.&lt;/p&gt;
</content>
  </entry>
  
  <entry>
    <title>Porting the Scala 2 optimizer to Scala 3</title>
    <link href="https://www.scala-lang.org/blog/2026/03/23/porting-the-optimizer.html"/>
    <updated>2026-03-23T00:00:00+01:00</updated>
    <id>https://www.scala-lang.org/blog/2026/03/23/porting-the-optimizer</id>
    <content type="html">&lt;blockquote&gt;
  &lt;p&gt;This post covers work done under the &lt;a href=&quot;https://www.scala-lang.org/blog/2026/01/27/sta-invests-in-scala.html&quot;&gt;Sovereign Tech Fund investment&lt;/a&gt; umbrella: &lt;a href=&quot;https://contributors.scala-lang.org/t/standard-library-now-open-for-improvements-and-suggestions/7337&quot;&gt;Maintenance of the Standard Library/Core Library Modules and APIs&lt;/a&gt;. The work is coordinated by the &lt;a href=&quot;https://scala.epfl.ch/&quot;&gt;Scala Center&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;We are porting the &lt;em&gt;optimizer&lt;/em&gt; from the Scala 2 compiler to the Scala 3 compiler, improving the performance of Scala 3 applications without requiring developers to write more complex code. In early microbenchmarks of code written in a high-level functional style, we’re seeing 10-30% faster execution. But what exactly is this optimizer and why is it necessary?&lt;/p&gt;

&lt;p&gt;&lt;em&gt;This work is available as of version &lt;a href=&quot;https://github.com/scala/scala3/releases/tag/3.8.3-RC3&quot;&gt;3.8.3-RC3&lt;/a&gt; of the Scala compiler.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Scala is a modern and concise language, meaning you can write code expressing &lt;em&gt;what&lt;/em&gt; you want to do by composing primitives, rather than &lt;em&gt;how&lt;/em&gt; to do it step-by-step.
High-level code is easier to read and maintain, in addition to being shorter to write.&lt;/p&gt;

&lt;p&gt;Scala’s expressiveness enables you to write what you mean:&lt;/p&gt;
&lt;div class=&quot;language-scala highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;addOneMap&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Array&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;])&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;_&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;However, from a CPU’s point of view, a high-level API like &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;map&lt;/code&gt; is conceptually more complex than the equivalent low-level code.
It’s a function call that is passed another function, leading to a “&lt;a href=&quot;https://shipilev.net/jvm/anatomy-quarks/16-megamorphic-virtual-calls/&quot;&gt;megamorphic&lt;/a&gt;” call site that is harder for the JVM to optimize, and the function argument might need a closure to be allocated on the heap if it captures local values.
Compiled naïvely, the high-level call wouldn’t be as fast as this equivalent low-level loop:&lt;/p&gt;
&lt;div class=&quot;language-scala highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;addOneLoop&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Array&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;])&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;val&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;l&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;length&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;val&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;r&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Array&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;](&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;l&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;while&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;l&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
    &lt;span class=&quot;nf&quot;&gt;r&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;r&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;You don’t want to write this loop, because its purpose is a lot less obvious and it is harder to maintain, but without compiler help, you might have to write it if that function is critical to your application’s performance.
(Why would adding one to an array be critical to your app’s performance? Because you’re reading a pedagogical blog post and thus suspending disbelief!)&lt;/p&gt;

&lt;p&gt;If you’ve ever written a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;map&lt;/code&gt; function yourself, you may recognize the loop above as being fairly close to how such a function is implemented, though the actual Scala implementation is a little more complex than you’d think because it needs to handle the mismatch between Scala’s generic array type and the JVM’s erased generics:&lt;/p&gt;
&lt;div class=&quot;language-scala highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;B&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;](&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Array&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;A&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;A&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;B&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;implicit&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ct&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;ClassTag&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;B&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;])&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Array&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;B&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;val&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;len&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;length&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;val&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;r&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Array&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;B&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;](&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;
  &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Any&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;@unchecked&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;match&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Array&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;AnyRef&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;  &lt;span class=&quot;k&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;while&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;r&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;asInstanceOf&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;A&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]);&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Array&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;     &lt;span class=&quot;k&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;while&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;r&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;asInstanceOf&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;A&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]);&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;cm&quot;&gt;/* ... 7 cases omitted for brevity ...  */&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;r&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;This method’s complexity is necessary to handle every possible array you can throw at it. You could also implement it with less code by using reflection to handle any possible array with just one code path, but that would lead to slower execution.
But in our &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;addOne&lt;/code&gt; case, we only need the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Array[Int]&lt;/code&gt; part. Type-checking the array isn’t needed, nor is casting &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;a(i)&lt;/code&gt; inside the loop, and the whole &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ClassTag&lt;/code&gt; machinery could go away too.&lt;/p&gt;

&lt;h2 id=&quot;optimizing-for-the-best-of-both-worlds&quot;&gt;Optimizing for the best of both worlds&lt;/h2&gt;

&lt;p&gt;How can we get the best of both worlds? By having an &lt;em&gt;optimizer&lt;/em&gt; in the compiler that simplifies code and heuristically determines when it is beneficial to &lt;em&gt;inline&lt;/em&gt; code to enable further simplifications. Scala 2 has had such an optimizer for years now, &lt;a href=&quot;https://docs.scala-lang.org/overviews/compiler-options/optimizer.html&quot;&gt;as documented here&lt;/a&gt;, and it’s finally time to port it to Scala 3! Let’s see why it works in a little more detail.&lt;/p&gt;

&lt;p&gt;The optimizer takes care of turning our single-line &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;addOneMap&lt;/code&gt; example into our fast &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;addOneLoop&lt;/code&gt; version. 
The key technique to perform this is &lt;em&gt;inlining&lt;/em&gt;: expanding the code of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;map&lt;/code&gt; into the function where it is called.
This allows the optimizer to remove redundant branches and operations, such as removing the &lt;a href=&quot;https://docs.oracle.com/javase/tutorial/java/data/autoboxing.html&quot;&gt;boxing&lt;/a&gt; of primitive types.
The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;match&lt;/code&gt; is simplified to just one of its branches, the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;asInstanceOf&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ClassTag&lt;/code&gt; disappear, and we end up with the fast version.&lt;/p&gt;

&lt;p&gt;Inlining is powerful but can also have big drawbacks.
For starters, your CPU keeps frequently-executed code in an “instruction cache” that is very fast to access.
When common functions get bigger, fewer of them fit in that cache, so execution might become slower because fetching the code is slower even if the code itself has fewer function calls.&lt;/p&gt;

&lt;p&gt;Furthermore, inlining is not always possible.
A classic case is recursion: you cannot infinitely inline a function into itself.
Some more tricky problems include the fact that you cannot inline a method that accesses a class’s private fields outside of that class.
(At least not on the JVM, Scala.js does not have that problem.)&lt;/p&gt;

&lt;p&gt;In this case, there is a heuristic modeling the fact that if a function call uses a function literal as argument, inlining it is probably worth it.
There are other heuristics, such as one related to generic array operations in general, one that forces inlining of “forwarder” functions that merely call another function with minor changes to their arguments, and so on.&lt;/p&gt;

&lt;p&gt;The JVM already has an optimizer as part of Just-In-Time compilation, but it’s designed to make Java code fast, and typical Java code does not look like typical Scala code, so there are some important optimization opportunities not covered by the JVM’s optimizer.
Furthermore, the Scala compiler can optimize code at compile-time based on knowledge that is internal to the compiler and subject to change between versions, such as which Scala runtime functions are guaranteed to be pure or to always return non-null references.&lt;/p&gt;

&lt;p&gt;Early results show that for individual methods such as the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;addOne&lt;/code&gt; example above, the optimizer successfully turns the high-level version into an exact equivalent of the low-level one, which translates to 10-30% gains in some microbenchmarks.&lt;/p&gt;

&lt;h2 id=&quot;limitations&quot;&gt;Limitations&lt;/h2&gt;

&lt;p&gt;Heuristics mostly lead to better performance, but performance is such a complex topic that no set of heuristics can guarantee improvements.
It’s possible that enabling the optimizer on your specific codebase could regress some scenarios, which is why you should benchmark any performance-related change just as you would test any correctness-related change.
You can override the heuristics with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;@inline&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;@noinline&lt;/code&gt; annotations, but these should be a last-resort solution that you re-evaluate frequently as the compiler and the JVM improve.&lt;/p&gt;

&lt;p&gt;The other key limitation of the optimizer is that you can only use it if you know your dependencies at run-time are the same as the ones you had at compile time.
For instance, if you compile against library &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;org.example&lt;/code&gt; version &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;1.3.6&lt;/code&gt;, and tomorrow the maintainers of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;org.example&lt;/code&gt; release version &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;1.3.7&lt;/code&gt; that fixes a bug in a small function, this bugfix only has an effect on the already-deployed version of your code if it actually calls that function, not if the optimizer inlined the buggy version into your code.&lt;/p&gt;

&lt;p&gt;Thus, the optimizer targets &lt;em&gt;application&lt;/em&gt; code as well as the &lt;em&gt;standard library&lt;/em&gt;, and is an opt-in compiler setting.
You should only use it for &lt;em&gt;library&lt;/em&gt; code if you carefully select what inlining is allowed, as explained below.
Typically this means only inlining code within your own library, or within dependencies you control.&lt;/p&gt;

&lt;h2 id=&quot;using-the-optimizer&quot;&gt;Using the optimizer&lt;/h2&gt;

&lt;p&gt;Pass the flag &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;-opt&lt;/code&gt; to the compiler to enable non-inlining optimizations, and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;-opt-inline:...&lt;/code&gt; arguments to enable inlining calls to specific packages.&lt;/p&gt;

&lt;p&gt;For instance, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;-opt-inline:**,!java.**,!org.example.*&lt;/code&gt; tells the optimizer that inlining is allowed for all functions except those anywhere in the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;java&lt;/code&gt; package and those directly in the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;org.example&lt;/code&gt; package.
More details are available with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;-opt-inline:help&lt;/code&gt;.&lt;/p&gt;

&lt;h2 id=&quot;future-directions&quot;&gt;Future directions&lt;/h2&gt;

&lt;p&gt;Now that the optimizer is at feature parity with its Scala 2 incarnation, we hope to bring further optimizations to Scala 3.
For instance, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Range&lt;/code&gt;-based abstractions cannot always be fully eliminated today, but could with further work on the optimizer.
If you’re interested, you can contribute either by participating as described below, or by &lt;a href=&quot;https://github.com/scala/scala3/blob/main/CONTRIBUTING.md&quot;&gt;contributing&lt;/a&gt; to the compiler itself!&lt;/p&gt;

&lt;h2 id=&quot;participation&quot;&gt;Participation&lt;/h2&gt;

&lt;p&gt;The Scala Center has been entrusted with coordinating the commissioned Scala work for the Sovereign Tech Fund. The Scala Center is an independent, not-for-profit center sponsored by &lt;a href=&quot;/blog/2023/09/11/scala-center-fundraising.html&quot;&gt;corporate members and individual backers like you&lt;/a&gt; to promote and facilitate Scala. If you would like to participate and/or see more of these types of efforts, please reach out to your manager to see if your company can donate engineering time or membership to the Scala Center.&lt;/p&gt;

&lt;p&gt;See &lt;a href=&quot;/blog/2023/09/11/scala-center-fundraising.html&quot;&gt;The Scala Center Fundraising Campaign&lt;/a&gt; for more details.&lt;/p&gt;
</content>
  </entry>
  
  <entry>
    <title>Hardening Scoverage Support in Scala 3</title>
    <link href="https://www.scala-lang.org/blog/2026/03/11/scoverage.html"/>
    <updated>2026-03-11T00:00:00+01:00</updated>
    <id>https://www.scala-lang.org/blog/2026/03/11/scoverage</id>
    <content type="html">&lt;blockquote&gt;
  &lt;p&gt;This post covers work done under the &lt;a href=&quot;https://www.scala-lang.org/blog/2026/01/27/sta-invests-in-scala.html&quot;&gt;Sovereign Tech Fund investment&lt;/a&gt; umbrella: &lt;a href=&quot;https://contributors.scala-lang.org/t/scoverage-hardening/7352&quot;&gt;Scoverage hardening&lt;/a&gt;. The work is coordinated by the &lt;a href=&quot;https://scala.epfl.ch/&quot;&gt;Scala Center&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2 id=&quot;summary&quot;&gt;Summary&lt;/h2&gt;

&lt;p&gt;Code coverage is a key part of maintaining high-quality Scala projects. We’ve recently made progress on making Scoverage more robust for Scala 3, expanding the way we test it and discovering and fixing new issues.&lt;/p&gt;

&lt;h2 id=&quot;background&quot;&gt;Background&lt;/h2&gt;

&lt;p&gt;Measuring how much of your Scala code is exercised by tests sounds simple until you try to do it yourself. That’s where code coverage tools come in. Code coverage is not optional for many organizations. As one of the QA metrics, coverage helps ensure reliability of the solution which is especially important in regulated sectors. Scoverage is the standard coverage tool for Scala, built directly into the Scala 3 compiler as a dedicated phase.&lt;/p&gt;

&lt;p&gt;A crucial requirement for Scoverage’s wide industry adoption is that Scoverage itself is reliable and well-tested. The tool is already tested via its own dedicated test suite - however, that is not enough. Most tricky bugs happen not in isolation but at intersections of language features. Therefore, Scoverage needs to be tested in interaction with all of the language features to be truly considered reliable. Furthermore, all future changes to the compiler should be tested in interaction with Scoverage to ensure the tool remains compatible with the compiler.&lt;/p&gt;

&lt;p&gt;To guarantee such a level of reliability, we have recently started a systematic rework of the testing strategy for Scoverage. This article reports on the progress we’ve made in 2026 so far.&lt;/p&gt;

&lt;h2 id=&quot;enabling-coverage-on-the-compiler-test-suite&quot;&gt;Enabling coverage on the compiler test suite&lt;/h2&gt;

&lt;p&gt;The first step was mapping out the current failures of Scoverage in interaction with other language features. The strategy for that was to enable Scoverage on the existing compiler test suite. This means, in addition to the usual CI run of the tests that we do for each new PR, now we run the same tests again, but with Scoverage enabled.&lt;/p&gt;

&lt;p&gt;Under this mode, for each test we verify three things:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;The compiler doesn’t crash&lt;/li&gt;
  &lt;li&gt;The coverage output file is produced&lt;/li&gt;
  &lt;li&gt;The coverage output file is valid and deserializable&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;As a result, we have discovered &lt;em&gt;97 failing tests&lt;/em&gt; when coverage instrumentation was switched on. Those tests are being addressed in the order of impact. They were disabled for the time being to allow the validation logic to be merged early, thus future-proofing Scoverage.&lt;/p&gt;

&lt;p&gt;As for the rest of the tests, they are now running with coverage instrumentation for each PR, and passing them is a requirement for a PR to be merged to the compiler codebase. Furthermore, every newly added test to the compiler test suite is tested against Scoverage by default, thus preventing future PRs from unintentionally introducing Scoverage breakages.&lt;/p&gt;

&lt;p&gt;Details of this work are in &lt;a href=&quot;https://github.com/scala/scala3/pull/25009&quot;&gt;PR #25009&lt;/a&gt;.&lt;/p&gt;

&lt;h2 id=&quot;addressing-breakages-erased-values-and-the-purity-constraint&quot;&gt;Addressing breakages: erased values and the purity constraint&lt;/h2&gt;

&lt;p&gt;We have also taken the first steps to address discovered issues. A pattern that emerged is that failing tests were clustered around a few common root causes.&lt;/p&gt;

&lt;p&gt;One of the root causes behind a significant cluster of failures was the interaction between coverage instrumentation and Scala 3’s capability system. Capabilities in Scala 3 are represented as erased values - values that exist at compile time but are eliminated at runtime. Because they are erased, they must be pure: they cannot have side effects, and the compiler enforces this constraint, failing compilation if that is not the case.&lt;/p&gt;

&lt;p&gt;Coverage instrumentation works by injecting calls into the compiled code to record which expressions were executed. These calls introduce side effects. The erasure phase would then reject the result with an error.&lt;/p&gt;

&lt;p&gt;The fix is conceptually simple: the coverage instrumentation phase now checks whether a value is erased and, if so, skips it. &lt;em&gt;23 tests&lt;/em&gt; that previously failed under coverage are now passing as a result of this fix, opening the door to using Scoverage together with capabilities.&lt;/p&gt;

&lt;p&gt;Details in &lt;a href=&quot;https://github.com/scala/scala3/pull/25298&quot;&gt;PR #25298&lt;/a&gt;.&lt;/p&gt;

&lt;h2 id=&quot;expanding-the-testing-surface&quot;&gt;Expanding the testing surface&lt;/h2&gt;

&lt;p&gt;The Scala 3 compiler’s test suite is extensive. The strategy has been to enable coverage testing incrementally: start with the core tests, exclude the currently failing ones so regressions are caught from day one, then gradually expand the testing surface and fix discovered issues.&lt;/p&gt;

&lt;p&gt;The latest expansion of the testing surface was done after fixing the first cluster of issues. Coverage instrumentation is now also exercised on additional test suites such as &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;rewrites&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;warn&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;explicit-nulls/pos&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;explicit-nulls/warn&lt;/code&gt;, and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;init&lt;/code&gt; test suites. As a part of this expansion, we have discovered &lt;em&gt;13 new breakages&lt;/em&gt; that are being addressed in the same manner.&lt;/p&gt;

&lt;p&gt;Details in &lt;a href=&quot;https://github.com/scala/scala3/pull/25385&quot;&gt;PR #25385&lt;/a&gt;.&lt;/p&gt;

&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h2&gt;

&lt;p&gt;To ensure the reliability of Scoverage in the industry, we are continuing to expand the testing surface of the tool and fix discovered issues. We will be sharing more updates as the work continues. If you are actively using Scoverage, your feedback is welcome! You can join the discussion on &lt;a href=&quot;https://contributors.scala-lang.org/t/scoverage-hardening/7352&quot;&gt;contributors.scala-lang.org&lt;/a&gt; or contribute Scoverage-related issues to the Scala 3 &lt;a href=&quot;https://github.com/scala/scala3/issues&quot;&gt;issue tracker&lt;/a&gt;.&lt;/p&gt;

&lt;h2 id=&quot;participation&quot;&gt;Participation&lt;/h2&gt;

&lt;p&gt;The Scala Center has been entrusted with coordinating the commissioned Scala work for the Sovereign Tech Fund. The Scala Center is an independent, not-for-profit center sponsored by &lt;a href=&quot;/blog/2023/09/11/scala-center-fundraising.html&quot;&gt;corporate members and individual backers like you&lt;/a&gt; to promote and facilitate Scala. If you would like to participate and/or see more of these types of efforts, please reach out to your manager to see if your company can donate engineering time or membership to the Scala Center.&lt;/p&gt;

&lt;p&gt;See &lt;a href=&quot;/blog/2023/09/11/scala-center-fundraising.html&quot;&gt;The Scala Center Fundraising Campaign&lt;/a&gt; for more details.&lt;/p&gt;
</content>
  </entry>
  
  <entry>
    <title>Migrating sbt plugins to sbt 2 with sbt2-compat plugin</title>
    <link href="https://www.scala-lang.org/blog/2026/03/02/sbt2-compat.html"/>
    <updated>2026-03-02T00:00:00+01:00</updated>
    <id>https://www.scala-lang.org/blog/2026/03/02/sbt2-compat</id>
    <content type="html">&lt;blockquote&gt;
  &lt;p&gt;This post covers work done under the &lt;a href=&quot;https://www.scala-lang.org/blog/2026/01/27/sta-invests-in-scala.html&quot;&gt;Sovereign Tech Fund investment&lt;/a&gt; umbrella: &lt;a href=&quot;https://contributors.scala-lang.org/t/sbt-2-production-ready-roadmap/7351&quot;&gt;sbt 2 Stable Release and Maintenance&lt;/a&gt;. The work is coordinated by the &lt;a href=&quot;https://scala.epfl.ch/&quot;&gt;Scala Center&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;There’s an ongoing, community-driven effort to repopulate the sbt plugin ecosystem in preparation for the sbt 2 release. From sbt 1.x, plugin authors can cross publish against sbt 2.0 release candidates. To facilitate the plugin migration, we’ve created the &lt;a href=&quot;https://github.com/sbt/sbt2-compat&quot;&gt;sbt2-compat plugin&lt;/a&gt;.&lt;/p&gt;

&lt;!-- more --&gt;

&lt;h2 id=&quot;the-plugincompat-pattern&quot;&gt;The PluginCompat Pattern&lt;/h2&gt;
&lt;p&gt;sbt 2 is a major upgrade from sbt 1 and makes breaking changes on the API level. As a plugin maintainer, you want to preserve compatibility with sbt 1 when migrating - so you want to cross-publish your plugin for sbt 1 and sbt 2. Ideally, you want to have the same codebase that compiles for both sbt 1 and sbt 2. However, due to the breaking changes to the API, this is not always possible. You end up with a situation where the same concept is expressed in a different way in sbt 1 and sbt 2.&lt;/p&gt;

&lt;p&gt;One such example is how files are represented in sbt 1 and sbt 2. In sbt 1, everything is a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;java.io.File&lt;/code&gt;, whereas in sbt 2 the types are more granular depending on the context. For example, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;HashedVirtualFileRef&lt;/code&gt; is used for classpath entries, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;VirtualFile&lt;/code&gt; - for task outputs and caching artifacts, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;VirtualFileRef&lt;/code&gt; - for path-like references. These types are defined in the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;xsbti&lt;/code&gt; package.&lt;/p&gt;

&lt;p&gt;The current approach to handling these discrepancies is to have a single codebase that compiles for both sbt 1 and sbt 2, and use the &lt;a href=&quot;https://www.scala-sbt.org/2.x/docs/en/changes/migrating-from-sbt-1.x.html#the-plugincompat-technique&quot;&gt;PluginCompat pattern&lt;/a&gt; to provide a compatibility layer. For example, suppose you want to define a new task key that builds a JAR file and returns it.&lt;/p&gt;

&lt;p&gt;In sbt 1, you would define it as:&lt;/p&gt;

&lt;div class=&quot;language-scala highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;lazy&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;val&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;assembly&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;taskKey&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;java.io.File&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;](&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Builds a deployable JAR file&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;In sbt 2, you would define it as:&lt;/p&gt;

&lt;div class=&quot;language-scala highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;lazy&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;val&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;assembly&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;taskKey&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;xsbti.file.HashedVirtualFileRef&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;](&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Builds a deployable JAR file&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Since you want to use the same codebase for both sbt 1 and sbt 2, you would need to abstract over the file type and define it separately for each sbt version. So:&lt;/p&gt;

&lt;div class=&quot;language-scala highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;// src/main/scala-2.12/PluginCompat.scala&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;FileRef&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;java&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;io&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;File&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// src/main/scala-3/PluginCompat.scala&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;FileRef&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;xsbti&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;file&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;HashedVirtualFileRef&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;You would then be able to define the task using this unified API:&lt;/p&gt;

&lt;div class=&quot;language-scala highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;lazy&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;val&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;assembly&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;taskKey&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;FileRef&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;](&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Builds a deployable JAR file&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This approach is a recurring pattern that you will encounter from plugin to plugin when attempting to cross-compile for sbt 1 and sbt 2. This is exactly the motivation behind the sbt2-compat plugin.&lt;/p&gt;

&lt;h2 id=&quot;cross-building-for-sbt-1-and-sbt-2-using-the-sbt2-compat-plugin&quot;&gt;Cross-building for sbt 1 and sbt 2 using the sbt2-compat plugin&lt;/h2&gt;
&lt;p&gt;The above encoding of the differences in the file API between sbt 1 and sbt 2 is already abstracted and ready to be reused in the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;sbt2-compat&lt;/code&gt; plugin. This plugin follows a similar pattern to the &lt;a href=&quot;https://github.com/dwijnand/sbt-compat&quot;&gt;sbt-compat&lt;/a&gt; plugin that handled cross-builds between sbt 0.x and 1.x. As a plugin maintainer, instead of manually defining the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;PluginCompat.scala&lt;/code&gt; shim as described above, you would instead add the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;sbt2-compat&lt;/code&gt; plugin to your build and use the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;PluginCompat&lt;/code&gt; pattern as before, relying on the unified implementation provided by &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;sbt2-compat&lt;/code&gt;.&lt;/p&gt;

&lt;h3 id=&quot;1-add-sbt2-compat-to-your-plugin&quot;&gt;1. Add sbt2-compat to your plugin&lt;/h3&gt;

&lt;p&gt;Add the plugin in your plugin’s &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;build.sbt&lt;/code&gt; (&lt;strong&gt;not&lt;/strong&gt; &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;project/plugins.sbt&lt;/code&gt;):&lt;/p&gt;

&lt;div class=&quot;language-scala highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nf&quot;&gt;addSbtPlugin&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;com.github.sbt&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;sbt2-compat&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;&amp;lt;version&amp;gt;&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;To cross-build for sbt 1 and sbt 2, see &lt;a href=&quot;https://www.scala-sbt.org/2.x/docs/en/changes/migrating-from-sbt-1.x.html#cross-building-sbt-plugins&quot;&gt;Cross building sbt plugins&lt;/a&gt; in the official migration guide.&lt;/p&gt;

&lt;div class=&quot;language-scala highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nc&quot;&gt;ThisBuild&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;crossScalaVersions&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:=&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Seq&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;3.8.1&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;2.12.21&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;nc&quot;&gt;ThisBuild&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;scalaVersion&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:=&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;crossScalaVersions&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;head&lt;/span&gt;

&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;pluginCrossBuild&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sbtVersion&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;nv&quot;&gt;scalaBinaryVersion&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;value&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;match&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;2.12&quot;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;1.12.3&quot;&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;_&lt;/span&gt;      &lt;span class=&quot;k&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;2.0.0-RC9&quot;&lt;/span&gt;
  &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;For a concrete example, see &lt;a href=&quot;https://github.com/sbt/sbt-assembly/blob/1c2f9c5eb38f86abc9516d93ed1f1ccd5a76e374/build.sbt&quot;&gt;sbt-assembly&lt;/a&gt;.&lt;/p&gt;

&lt;h3 id=&quot;2-use-sbt2-compat-to-handle-the-api-differences-between-sbt-1-and-sbt-2&quot;&gt;2. Use sbt2-compat to handle the API differences between sbt 1 and sbt 2&lt;/h3&gt;

&lt;p&gt;Let’s take a look at how &lt;a href=&quot;https://github.com/sbt/sbt-assembly&quot;&gt;sbt-assembly&lt;/a&gt; uses sbt2-compat to cross-build for sbt 1 and sbt 2. Here is how it is applied:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Task keys&lt;/strong&gt; — Import &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;FileRef&lt;/code&gt; and use it for task return types. Notice how the type comes from the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;sbt2-compat&lt;/code&gt; plugin and does not need to be defined manually. (&lt;a href=&quot;https://github.com/sbt/sbt-assembly/blob/1c2f9c5eb38f86abc9516d93ed1f1ccd5a76e374/src/main/scala/sbtassembly/AssemblyKeys.scala#L10&quot;&gt;AssemblyKeys.scala L6–10&lt;/a&gt;):&lt;/p&gt;

&lt;div class=&quot;language-scala highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;sbtcompat.PluginCompat.FileRef&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;lazy&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;val&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;assembly&lt;/span&gt;                  &lt;span class=&quot;k&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;taskKey&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;FileRef&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;](&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Builds a deployable über JAR&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;lazy&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;val&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;assemblyPackageScala&lt;/span&gt;      &lt;span class=&quot;k&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;taskKey&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;FileRef&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;](&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Produces the Scala artifact&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;lazy&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;val&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;assemblyPackageDependency&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;taskKey&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;FileRef&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;](&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Produces the dependency artifact&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;2. Shared logic&lt;/strong&gt; — Import compat helpers and use them for classpath handling, file conversion, and module metadata (&lt;a href=&quot;https://github.com/sbt/sbt-assembly/blob/1c2f9c5eb38f86abc9516d93ed1f1ccd5a76e374/src/main/scala/sbtassembly/Assembly.scala#L225-L294&quot;&gt;Assembly.scala L225–294&lt;/a&gt;):&lt;/p&gt;

&lt;div class=&quot;language-scala highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;sbtcompat.PluginCompat.&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;FileRef&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Out&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;toNioPath&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;toFile&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;toOutput&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;toNioPaths&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;toFiles&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;moduleIDStr&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;parseModuleIDStrAttribute&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// Classpath iteration&lt;/span&gt;
&lt;span class=&quot;nf&quot;&gt;val&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;jars&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;dirs&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;classpath&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;toVector&lt;/span&gt;
  &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;sortBy&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;toNioPath&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;toAbsolutePath&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;().&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;toString&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;())&lt;/span&gt;
  &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;partition&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;ClasspathUtil&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;isArchive&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;toNioPath&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)))&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// Convert classpath entry to File for JarFile&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;val&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;jarFile&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;JarFile&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;toFile&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;jar&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;))&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// ModuleID from metadata&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;val&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;module&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;jar&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;metadata&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;moduleIDStr&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;parseModuleIDStrAttribute&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;m&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;ModuleCoordinate&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;m&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;organization&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;m&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;m&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;revision&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;))&lt;/span&gt;
  &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;getOrElse&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;ModuleCoordinate&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;jar&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;replaceAll&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;.jar&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;))&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// Return task output&lt;/span&gt;
&lt;span class=&quot;nf&quot;&gt;toOutput&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;builtAssemblyJar&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;3. Disabling task caching&lt;/strong&gt; — Use &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Def.uncached&lt;/code&gt; so classpath tasks read fresh values on sbt 2 (&lt;a href=&quot;https://github.com/sbt/sbt-assembly/blob/1c2f9c5eb38f86abc9516d93ed1f1ccd5a76e374/src/main/scala/sbtassembly/AssemblyPlugin.scala#L86-L87&quot;&gt;AssemblyPlugin.scala L86–87&lt;/a&gt;):&lt;/p&gt;

&lt;div class=&quot;language-scala highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;sbtcompat.PluginCompat._&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;assembly&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;fullClasspath&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:=&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;Def&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;uncached&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fullClasspath&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;or&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Runtime&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;fullClasspath&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)).&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;),&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;assembly&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;externalDependencyClasspath&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:=&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;Def&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;uncached&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;externalDependencyClasspath&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;or&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Runtime&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;externalDependencyClasspath&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)).&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;),&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;project-status&quot;&gt;Project status&lt;/h2&gt;

&lt;p&gt;sbt2-compat currently covers the core API surface needed for cross-building plugins that work with files, classpaths, and packaging:&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;sbt2-compat provides&lt;/th&gt;
      &lt;th&gt;Use for&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;FileRef&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Out&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ArtifactPath&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;Task key types, return types&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;toNioPath&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;toNioPaths&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;toFile&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;toOutput&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;toFileRefsMapping&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;toAttributedFiles&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;Classpath and file conversion&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;moduleIDStr&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;artifactStr&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;parseModuleIDStrAttribute&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;parseArtifactStrAttribute&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;Module metadata from classpath&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Def.uncached&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;Opt out of sbt 2 task caching&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.name()&lt;/code&gt; on &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;FileRef&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;File name (via &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;FileRefOps&lt;/code&gt; on sbt 1)&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;toDirectCredentials&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;credentialForHost&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;Credentials handling&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;createScopedKey&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;setSetting&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;ScopedKey / settings API&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;attributedPutFile&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;attributedGetFile&lt;/code&gt;, etc.&lt;/td&gt;
      &lt;td&gt;Attributed metadata (typed vs string keys)&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;Plugin-specific compat (e.g. custom disk caching, test API differences, Scala stdlib bridges like &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Streamable&lt;/code&gt;) stays in each plugin’s own &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;PluginCompat.scala&lt;/code&gt;. sbt-assembly, for instance, still maintains local shims for its cache, test settings, and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;PackageOption&lt;/code&gt; types. The sbt2-compat &lt;a href=&quot;https://github.com/sbt/sbt2-compat&quot;&gt;README&lt;/a&gt; documents this design and lists known caveats.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Development model.&lt;/strong&gt; sbt2-compat evolves iteratively by porting real-world plugins. Each port validates the existing API and may reveal missing compat methods. The idea is that as you port your plugins to sbt 2, you will discover gaps in the API that you can contribute back to sbt2-compat. For the exact development model, see the &lt;a href=&quot;https://github.com/sbt/sbt2-compat&quot;&gt;README&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Contributions are welcome!&lt;/strong&gt; If you’re cross-building an sbt plugin for sbt 1 and sbt 2, the sbt 2 team would be happy to hear about your experiences! Share what worked, what didn’t, and what you wish sbt2-compat had. Pull requests with compat helpers that might help other plugins are welcome! You can share your experiences and participate in the discussion in the &lt;a href=&quot;https://contributors.scala-lang.org/t/sbt-2-production-ready-roadmap/7351&quot;&gt;sbt 2 production-ready roadmap&lt;/a&gt; thread at the Scala Contributors forum.&lt;/p&gt;

&lt;h2 id=&quot;participation&quot;&gt;Participation&lt;/h2&gt;

&lt;p&gt;The Scala Center has been entrusted with coordinating the commissioned Scala work for the Sovereign Tech Fund. The Scala Center is an independent, not-for-profit center sponsored by &lt;a href=&quot;/blog/2023/09/11/scala-center-fundraising.html&quot;&gt;corporate members and individual backers like you&lt;/a&gt; to promote and facilitate Scala. If you would like to participate and/or see more of these types of efforts, please reach out to your manager to see if your company can donate engineering time or membership to the Scala Center.&lt;/p&gt;

&lt;p&gt;See &lt;a href=&quot;/blog/2023/09/11/scala-center-fundraising.html&quot;&gt;The Scala Center Fundraising Campaign&lt;/a&gt; for more details.&lt;/p&gt;
</content>
  </entry>
  
  <entry>
    <title>Scala 3.8.2 is now available!</title>
    <link href="https://www.scala-lang.org/news/3.8.2/"/>
    <updated>2026-02-24T00:00:00+01:00</updated>
    <id>https://www.scala-lang.org/news/release-notes-3.8.2</id>
    <content type="html">&lt;h1 id=&quot;scala-382-is-now-available&quot;&gt;Scala 3.8.2 is now available!&lt;/h1&gt;

&lt;h2 id=&quot;release-highlights&quot;&gt;Release highlights&lt;/h2&gt;

&lt;h3 id=&quot;warning-for-for-with-many-vals-and-overloaded-map-25090&quot;&gt;Warning for &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;for&lt;/code&gt; with many &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;val&lt;/code&gt;s and overloaded &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;map&lt;/code&gt; (&lt;a href=&quot;https://github.com/scala/scala3/pull/25090&quot;&gt;#25090&lt;/a&gt;)&lt;/h3&gt;

&lt;p&gt;Scala 3.8’s &lt;strong&gt;betterFors&lt;/strong&gt; (available since 3.7 under &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;-preview&lt;/code&gt;) changes for-comprehension desugaring and removes an intermediate &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;map&lt;/code&gt; used for consecutive &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;val&lt;/code&gt; bindings.&lt;/p&gt;

&lt;p&gt;The following code snippet behaves differently at runtime depending on Scala version used for compilation. In Scala 3.7.x and earlier it produces &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;List((43,29), (43,30), (43,31))&lt;/code&gt;, but starting with 3.8 it results in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Map(43 -&amp;gt; 31)&lt;/code&gt;.&lt;/p&gt;

&lt;div class=&quot;language-scala highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;val&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;result&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Iterable&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;Int&lt;/span&gt;, &lt;span class=&quot;kt&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)]&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// warning: For comprehension with multiple val assignments may change result type&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;k&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;v&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Map&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;      &lt;span class=&quot;k&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;k&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;v&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;z&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Map&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;42&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;27&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;nf&quot;&gt;yield&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;z&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Before (3.7):&lt;/strong&gt; A synthetic tuple-producing &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;map&lt;/code&gt; was inserted; that step could make &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Map&lt;/code&gt; select a generic &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;map&lt;/code&gt; overload and become an &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Iterable&lt;/code&gt; (e.g. &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;List&lt;/code&gt;)&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;In 3.8:&lt;/strong&gt; That synthetic step is removed, so the conversion no longer happens and a different &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;map&lt;/code&gt;/&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;flatMap&lt;/code&gt; path can be selected.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The previous runtime behaviour can be achieved by explicitly converting first &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Map&lt;/code&gt; to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Iterable&lt;/code&gt; type or by compilation with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;-source:3.7&lt;/code&gt; settings.&lt;/p&gt;

&lt;p&gt;The new warning highlights code where this migration risk exists.&lt;/p&gt;

&lt;h2 id=&quot;notable-changes&quot;&gt;Notable changes&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;Support &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;:dep ...&lt;/code&gt; to add library dependencies in the Scala REPL &lt;a href=&quot;https://github.com/scala/scala3/pull/24131&quot;&gt;#24131&lt;/a&gt;&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Upgrade to Scala.js 1.20.2 &lt;a href=&quot;https://github.com/scala/scala3/pull/24898&quot;&gt;#24898&lt;/a&gt;&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Bump Scala CLI to v1.12.2 (was v1.11.0) &lt;a href=&quot;https://github.com/scala/scala3/pull/25217&quot;&gt;#25217&lt;/a&gt;:
New aliases for RC and nightly Scala versions.
See the Scala CLI release notes for additional details:
&lt;a href=&quot;https://github.com/VirtusLab/scala-cli/releases/tag/v1.12.0&quot;&gt;v1.12.0&lt;/a&gt;,
&lt;a href=&quot;https://github.com/VirtusLab/scala-cli/releases/tag/v1.12.1&quot;&gt;v1.12.1&lt;/a&gt; and
&lt;a href=&quot;https://github.com/VirtusLab/scala-cli/releases/tag/v1.12.2&quot;&gt;v1.12.2&lt;/a&gt;&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For the complete list of changes and contributor credits, see the &lt;a href=&quot;https://github.com/scala/scala3/releases/tag/3.8.2&quot;&gt;release notes on GitHub&lt;/a&gt;.&lt;/p&gt;
</content>
  </entry>
  
  <entry>
    <title>State of the TASTy reader and Scala 2.13 ↔ Scala 3 compatibility</title>
    <link href="https://www.scala-lang.org/blog/state-of-tasty-reader.html"/>
    <updated>2026-02-20T00:00:00+01:00</updated>
    <id>https://www.scala-lang.org/blog/state-of-tasty-reader</id>
    <content type="html">&lt;p&gt;With the release of &lt;a href=&quot;https://scala-lang.org/news/3.8/&quot;&gt;Scala 3.8&lt;/a&gt;, Scala 2.13 and Scala 3 interoperability is no longer bidirectional.&lt;/p&gt;

&lt;p&gt;Every &lt;strong&gt;Scala 3 version supports consuming Scala 2.13&lt;/strong&gt; artifacts. There are no reasons or plans to change that state.&lt;/p&gt;

&lt;p&gt;The &lt;strong&gt;Scala 2.13 TASTy reader&lt;/strong&gt; (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;-Ytasty-reader&lt;/code&gt;) remains useful for migrations and consuming Scala 3 artifacts, but it &lt;strong&gt;will never be able to consume Scala 3.8&lt;/strong&gt; and later artifacts. 
Scala 3.7 is the last minor version whose artifacts will remain consumable from Scala 2.&lt;/p&gt;

&lt;p&gt;This post summarizes the current state, the compatibility boundaries, and the recommended publishing strategy for teams that still need Scala 2.13 to consume Scala 3 libraries.&lt;/p&gt;

&lt;h2 id=&quot;what-is-the-tasty-reader&quot;&gt;What is the TASTy reader?&lt;/h2&gt;

&lt;p&gt;&lt;a href=&quot;https://docs.scala-lang.org/scala3/guides/tasty-overview.html&quot;&gt;TASTy&lt;/a&gt; (Typed Abstract Syntax Trees) is the high-level interchange format used by Scala 3.
Every Scala 3 compilation produces &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.tasty&lt;/code&gt; files alongside &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.class&lt;/code&gt; files.
While &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.class&lt;/code&gt; files lose type information due to JVM type erasure (e.g. &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;List[String]&lt;/code&gt; becomes &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;List[Object]&lt;/code&gt;), TASTy files preserve the complete type information — generic types, union types, intersection types, and more.&lt;/p&gt;

&lt;p&gt;The &lt;strong&gt;TASTy reader&lt;/strong&gt; is a feature built into the Scala 2.13 compiler, enabled with the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;-Ytasty-reader&lt;/code&gt; flag.
It allows a Scala 2.13 project to depend on libraries only published for Scala 3, by reading their &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.tasty&lt;/code&gt; files to reconstruct the precise type signatures that &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.class&lt;/code&gt; files alone cannot convey.&lt;/p&gt;

&lt;p&gt;The TASTy reader was designed as a &lt;strong&gt;migration aid&lt;/strong&gt; — not a permanent compatibility layer.
It addressed a critical chicken-and-egg problem during the Scala 3 ecosystem bootstrap: library authors wanted to publish for Scala 3 but couldn’t abandon Scala 2.13 users, while application developers on Scala 2.13 couldn’t migrate until their dependencies were available.
The TASTy reader broke this deadlock by enabling a &lt;a href=&quot;https://www.scala-lang.org/blog/2020/11/19/scala-3-forward-compat.html#forward-compatibility&quot;&gt;forward-compatibility&lt;/a&gt; path, allowing Scala 2.13 projects to consume Scala 3-only libraries directly.&lt;/p&gt;

&lt;h2 id=&quot;technical-limitations-of-the-scala-2-tasty-reader&quot;&gt;Technical limitations of the Scala 2 TASTy reader&lt;/h2&gt;

&lt;p&gt;Even though both Scala 2 and Scala 3 share most of the language features, some features of each cannot be used by the other.
As an example, macros or existential types produced by Scala 2 cannot be represented or consumed by Scala 3.&lt;/p&gt;

&lt;p&gt;The Scala 2 TASTy reader is able to consume the Scala 3 TASTy format, but is not able to correctly represent an increasing amount of language features in a semantically correct way. Some of the unsupported features include:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;inline&lt;/code&gt; (including Scala 3 macros)&lt;/li&gt;
  &lt;li&gt;Union types&lt;/li&gt;
  &lt;li&gt;Match types&lt;/li&gt;
  &lt;li&gt;Context functions&lt;/li&gt;
  &lt;li&gt;Polymorphic function types&lt;/li&gt;
  &lt;li&gt;Trait parameters&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The classpath compatibility guide documents which Scala 3 features are or are not representable for Scala 2 consumption:
&lt;a href=&quot;https://docs.scala-lang.org/scala3/guides/migration/compatibility-classpath.html&quot;&gt;Scala 3 migration guide - classpath compatibility&lt;/a&gt;.&lt;/p&gt;

&lt;h2 id=&quot;what-changed-in-scala-38&quot;&gt;What changed in Scala 3.8&lt;/h2&gt;

&lt;p&gt;Scala 3.8 introduced a major ecosystem change by publishing &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;scala-library&lt;/code&gt; artifacts compiled using Scala 3, instead of reusing the Scala 2.13 standard library. As a result, it introduced a major new dependency that needs to be covered by the TASTy reader when consuming from Scala 2.&lt;/p&gt;

&lt;p&gt;What’s more, Scala 3 contained a mechanism to patch parts of the Standard Library to improve its performance, with its &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;scala3-library_3&lt;/code&gt; replacements. One such example is &lt;a href=&quot;https://github.com/scala/scala3/blob/3.8.1/library/src/scala/Predef.scala#L314-L333&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;scala.Predef.assert&lt;/code&gt;&lt;/a&gt;, defined as a normal method in Scala 2 but replaced with a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;transparent inline&lt;/code&gt; variant in Scala 3. Inlines are one of the features that Scala 2 cannot support.
Starting with Scala 3.8, this mechanism was removed and replaced with direct standard library modifications after ensuring both source and binary backward compatibility.&lt;/p&gt;

&lt;p&gt;The standard library of Scala 3 is now compiled with enabled support for explicit-nulls and capture-checking. Unless explicitly enabled, this change is not visible to users. However, at the TASTy level, each of these introduces additional features that cannot be represented in a Scala 2 compatible way: union types and capture checking.&lt;/p&gt;

&lt;p&gt;As a result, the old “Scala 2.13 ↔ Scala 3 sandwich” is no longer bidirectional at the classpath level.&lt;/p&gt;

&lt;h2 id=&quot;compile-classpath-incompatibilities&quot;&gt;Compile Classpath incompatibilities&lt;/h2&gt;

&lt;p&gt;Both Scala 2 and Scala 3 make strict assumptions about what’s available on the classpath and assume usage of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;scala-library&lt;/code&gt; artifacts matching &lt;strong&gt;exactly&lt;/strong&gt; the version of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;scala-compiler&lt;/code&gt;. This is required for correct emission of references to members of the Scala Standard Library.
Usage of an incompatible version can lead to severe problems resulting in compilation crashes. On the Scala 2 side, it can trigger bytecode optimizer failures, as described in the &lt;a href=&quot;https://scala-lang.org/blog/post-mortem-3.8.0.html&quot;&gt;Scala 3.8.0 post-mortem&lt;/a&gt;. On the Scala 3 side, it can lead to &lt;a href=&quot;https://github.com/scala/scala3/issues/22890&quot;&gt;references to members not yet introduced&lt;/a&gt; or already removed from the actively developed standard library.
This requirement can easily be violated due to eviction rules of third-party dependencies and transitive dependencies on different versions of the Standard Library.&lt;/p&gt;

&lt;p&gt;Eviction of the Standard Library can also affect build tools. As an example, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;sbt&lt;/code&gt; has always ensured the use of matching versions of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;scala-compiler&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;scala-library&lt;/code&gt;, and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;scala-reflect&lt;/code&gt; to ensure their compatibility. Their perspective was recently documented in the sbt 1.12.3 release notes &lt;a href=&quot;https://eed3si9n.com/sbt-1.12.3#sm%C3%B8rrebr%C3%B8d---the-end-of-scala-213-3x-sandwich&quot;&gt;“Smørrebrød - the end of Scala 2.13-3.x sandwich”&lt;/a&gt;.
In that scenario, a Scala 2.13 project can pull in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;scala-library:3.8.x&lt;/code&gt; through &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;for2_13Use3&lt;/code&gt;, while sbt still needs aligned Scala 2 compiler artifacts for the 2.13 side.
That leads resolution to attempt &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;org.scala-lang:scala-reflect:3.8.x&lt;/code&gt; (and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;scala-compiler:3.8.x&lt;/code&gt;), but these artifacts do not exist.
The result is the well-known sbt update error: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Error downloading org.scala-lang:scala-reflect:3.8.x&lt;/code&gt;.&lt;/p&gt;

&lt;h2 id=&quot;hard-compatibility-guarantee&quot;&gt;Hard compatibility guarantee&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Scala 3 consuming Scala 2.13 artifacts will remain supported for the foreseeable future.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;That direction of compatibility is a hard requirement and remains part of the Scala 3 migration model.
The no-longer-supported direction is specifically Scala 2.13 consuming Scala 3.8+ artifacts through the TASTy reader.&lt;/p&gt;

&lt;h2 id=&quot;stable-tasty-reader-compatibility-scala-2136&quot;&gt;Stable TASTy reader compatibility (Scala 2.13.6+)&lt;/h2&gt;

&lt;p&gt;The table below starts at Scala 2.13.6 and covers stable, non-experimental TASTy support milestones.&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Scala 2.13 release&lt;/th&gt;
      &lt;th&gt;Scala 3 minor version supported via &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;-Ytasty-reader&lt;/code&gt;&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;2.13.6&lt;/td&gt;
      &lt;td&gt;3.0&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;2.13.7&lt;/td&gt;
      &lt;td&gt;3.1&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;2.13.9&lt;/td&gt;
      &lt;td&gt;3.2&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;2.13.11&lt;/td&gt;
      &lt;td&gt;3.3&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;2.13.13&lt;/td&gt;
      &lt;td&gt;3.4&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;2.13.15&lt;/td&gt;
      &lt;td&gt;3.5&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;2.13.16&lt;/td&gt;
      &lt;td&gt;3.6&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;2.13.17&lt;/td&gt;
      &lt;td&gt;3.7&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;Each Scala 2.13 release can consume artifacts from all Scala 3 versions up to and including the one listed in its row. For example, Scala 2.13.17 can consume artifacts published with Scala 3.0 through 3.7, but not forward-incompatible 3.8 or later. Intermediate Scala 2.13 releases between these milestones follow the most recent support level above.&lt;/p&gt;

&lt;h2 id=&quot;recommendations&quot;&gt;Recommendations&lt;/h2&gt;

&lt;h3 id=&quot;for-scala-213-users&quot;&gt;For Scala 2.13 users&lt;/h3&gt;

&lt;ol&gt;
  &lt;li&gt;Keep TASTy-reader-based dependencies on versions published using Scala 3.7 or below.&lt;/li&gt;
  &lt;li&gt;Prefer dependencies published on Scala 3.3 LTS when available.&lt;/li&gt;
  &lt;li&gt;Plan migration of remaining Scala 2.13 modules to Scala 3 to remove reliance on the TASTy compatibility layer.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3 id=&quot;for-scala-3-library-authors-supporting-scala-213-users&quot;&gt;For Scala 3 library authors supporting Scala 2.13 users&lt;/h3&gt;

&lt;p&gt;We recommend cross-compilation of libraries for Scala 2.13 and Scala 3 so that each series can be natively consumed.&lt;/p&gt;

&lt;p&gt;However, if that’s not possible we recommend for library authors:&lt;/p&gt;
&lt;ol&gt;
  &lt;li&gt;Publish Scala 3 artifacts on &lt;strong&gt;Scala 3.3 LTS&lt;/strong&gt; for that compatibility path.&lt;/li&gt;
  &lt;li&gt;Scala 3.3 LTS will remain actively supported until at least Q2 2027 (at least one year after Scala 3.9 LTS is released), making it the safest choice for the transition period.&lt;/li&gt;
  &lt;li&gt;Prefer publishing library using Scala 3.3 LTS - Scala 3.7 is not expected to receive further releases. Use Scala 3 Next series only if access to their features features is necessary.&lt;/li&gt;
  &lt;li&gt;Plan and communicate potential dropping of Scala 2.13 support with the users, before migrating to Scala 3.9 LTS.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2 id=&quot;summary&quot;&gt;Summary&lt;/h2&gt;

&lt;p&gt;The TASTy reader remains a migration bridge for Scala 2.13 with Scala 3.0 to 3.7 artifacts.
That bridge does not extend to Scala 3.8+ artifacts.&lt;/p&gt;

&lt;p&gt;At the same time, one direction is unchanged and guaranteed:
&lt;strong&gt;Scala 3 consuming Scala 2.13 artifacts is always supported.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;For mixed ecosystems that still need Scala 2.13 consumers, Scala 3.3 LTS is the recommended publishing baseline, with newer lines used only when post-3.3 features are required.&lt;/p&gt;
</content>
  </entry>
  
  <entry>
    <title>Recap of Advent of Code 2025</title>
    <link href="https://www.scala-lang.org/blog/2026/02/12/advent-of-code-recap.html"/>
    <updated>2026-02-12T00:00:00+01:00</updated>
    <id>https://www.scala-lang.org/blog/2026/02/12/advent-of-code-recap</id>
    <content type="html">&lt;p&gt;&lt;strong&gt;&lt;a href=&quot;https://adventofcode.com/&quot;&gt;Advent of Code&lt;/a&gt;&lt;/strong&gt;, started by &lt;a href=&quot;http://was.tl/&quot;&gt;Eric Wastl&lt;/a&gt;, is an annual event providing daily programming puzzles between December 1st and December 12th.&lt;/p&gt;

&lt;p&gt;Let’s see how the Scala community participated in Advent of Code 2025. We were pleased by the strong engagement on both the &lt;a href=&quot;https://discord.com/invite/scala&quot;&gt;Scala Discord&lt;/a&gt; and on &lt;a href=&quot;https://scalacenter.github.io/scala-advent-of-code/2025/&quot;&gt;our solutions website&lt;/a&gt;.&lt;/p&gt;

&lt;h2 id=&quot;why-we-do-this&quot;&gt;Why we do this&lt;/h2&gt;

&lt;p&gt;At the &lt;a href=&quot;https://scala.epfl.ch&quot;&gt;Scala Center&lt;/a&gt;, we love writing code in Scala, and we hope you do too. One of our core priorities is to &lt;em&gt;communicate excitement about Scala&lt;/em&gt;, which motivates us to participate in the Advent of Code and share experiences solving problems with Scala with the wider programming community.&lt;/p&gt;

&lt;p&gt;Another key priority is to improve the &lt;em&gt;onboarding experience for newcomers&lt;/em&gt;. Part of that experience comes from the first impressions someone has reading Scala code. We hope that through hosting articles on &lt;a href=&quot;https://scalacenter.github.io/scala-advent-of-code/2025/&quot;&gt;our solutions website&lt;/a&gt;, newcomers can see that programming in Scala is an elegant way to solve problems.&lt;/p&gt;

&lt;h2 id=&quot;engagement-from-the-community&quot;&gt;Engagement from the community&lt;/h2&gt;

&lt;h3 id=&quot;discord-channel&quot;&gt;Discord channel&lt;/h3&gt;

&lt;p&gt;This year, there was lively conversation (with spoilers duly grayed out, of course!) in the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;#advent-of-code&lt;/code&gt; channel on the &lt;a href=&quot;https://discord.com/invite/scala&quot;&gt;Scala Discord server&lt;/a&gt;. Thank you to everyone who shared their code and/or helped each other come up with the best solutions. We especially thank those who offered friendly help to Scala newcomers.&lt;/p&gt;

&lt;h3 id=&quot;community-solutions&quot;&gt;Community solutions&lt;/h3&gt;

&lt;p&gt;106 solutions were submitted to &lt;a href=&quot;https://scalacenter.github.io/scala-advent-of-code/2025/&quot;&gt;the website&lt;/a&gt; this year, including some from first-time contributors.&lt;/p&gt;

&lt;p&gt;We give a special shout-out again this year to &lt;a href=&quot;https://github.com/AvaPL&quot;&gt;Paweł Cembaluk&lt;/a&gt;, who was the only participant to submit a solution for all 12 days.&lt;/p&gt;

&lt;h3 id=&quot;explainer-articles&quot;&gt;Explainer articles&lt;/h3&gt;

&lt;p&gt;As usual, we reached out to the community to help write the daily articles that show well-coded, well-explained solutions. The community organized a posting schedule which led to a full set of 12 complete articles. Thank you to all the authors who contributed. Each article has the author’s name at the top. The articles are on &lt;a href=&quot;https://scalacenter.github.io/scala-advent-of-code/2025/&quot;&gt;our solutions website&lt;/a&gt;.&lt;/p&gt;

&lt;h2 id=&quot;summary&quot;&gt;Summary&lt;/h2&gt;

&lt;p&gt;If you read this far, thank you again everyone for contributing to Scala and participating in Advent of Code, we hope you all had fun – and learned some things, too. See you in December 2026!&lt;/p&gt;

</content>
  </entry>
  
  <entry>
    <title>Scala Standard Library Process</title>
    <link href="https://www.scala-lang.org/blog/2026/02/05/standard-library-process.html"/>
    <updated>2026-02-05T00:00:00+01:00</updated>
    <id>https://www.scala-lang.org/blog/2026/02/05/standard-library-process</id>
    <content type="html">&lt;h1 id=&quot;contributing-to-scala-standard-library&quot;&gt;Contributing to Scala Standard Library&lt;/h1&gt;

&lt;p&gt;After a long freeze, the Scala 3 standard library is again open to
contributions. The main place for contributing is now the
Scala 3 repository.&lt;/p&gt;

&lt;p&gt;Certain specific improvements might be eligible for backporting to Scala 2,
but this will be the exception rather than the norm. To
access most new functionality, you need to migrate to Scala 3.&lt;/p&gt;

&lt;h1 id=&quot;the-process&quot;&gt;The Process&lt;/h1&gt;

&lt;p&gt;The Scala 3 standard library is hosted in the
&lt;a href=&quot;https://github.com/scala/scala3&quot;&gt;scala/scala3&lt;/a&gt; repository. Any changes that
influence the standard library API should follow &lt;a href=&quot;https://github.com/scala/scala3/blob/main/docs/_docs/contributing/procedures/contributing-to-stdlib.md&quot;&gt;this process&lt;/a&gt;. If the changes are only internal, the process is 
the standard pull request one.&lt;/p&gt;

&lt;p&gt;The person responsible for coordinating the process is the Scala Core Coordinator. 
Current Coordinator can be found on the &lt;a href=&quot;https://www.scala-lang.org/scala-core/&quot;&gt;Scala Core Team page&lt;/a&gt;.&lt;/p&gt;
</content>
  </entry>
  
  <entry>
    <title>Postmortem of scala/scala3#24994</title>
    <link href="https://www.scala-lang.org/blog/post-mortem-3.8.0.html"/>
    <updated>2026-01-29T00:00:00+01:00</updated>
    <id>https://www.scala-lang.org/blog/post-mortem-3.8.0</id>
    <content type="html">&lt;p&gt;Incident Date: &lt;em&gt;January 13th, 2026&lt;/em&gt;&lt;br /&gt;
Nature of the incident: &lt;em&gt;The Scala 3.8.0 artifacts contain invalid references to private fields&lt;/em&gt;&lt;/p&gt;

&lt;h2 id=&quot;the-tldr&quot;&gt;The TL;DR&lt;/h2&gt;
&lt;p&gt;The Scala 3.8.0 artifacts were released with invalid references to private fields in its standard library.
The bug, while severe, only affects a very limited group of users.
A hotfix was implemented and included in a subsequent 3.8.1 release. 
Both releases were then announced simultaneously 
(link to the announcement can be found &lt;a href=&quot;https://scala-lang.org/news/3.8/&quot;&gt;here&lt;/a&gt;).&lt;/p&gt;

&lt;h2 id=&quot;recommendations&quot;&gt;Recommendations&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;Upgrade directly to Scala 3.8.1, or 3.8.2 once it becomes available.&lt;/li&gt;
  &lt;li&gt;Scala 3.8.0 is discouraged from being used because of the issue described in this document.&lt;/li&gt;
  &lt;li&gt;The issue is not flagged by the compiler, it manifests in a NoSuchFieldError thrown at runtime. 
We believe the exposure is very limited, and it’s unlikely for users to be affected.
Libraries compiled and published with Scala 3.8.0 are not corrupted and can be used safely.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;timeline&quot;&gt;Timeline&lt;/h2&gt;

&lt;p&gt;On Tuesday, 13th of January 2026 Scala 3.8.0 artifacts were published with a (at the time unknown) 
contract-breaking bug in its bytecode. The issue only got reported on Thursday, 15th of January, 
in the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;scalacenter/sbt-missinglink&lt;/code&gt; SBT plugin bug tracker 
under &lt;a href=&quot;https://github.com/scalacenter/sbt-missinglink/issues/54&quot;&gt;scalacenter/sbt-missinglink#54&lt;/a&gt;. 
This was re-raised in the Scala 3 compiler bug tracker a day later, on Friday, 16th of January, 
at &lt;a href=&quot;https://github.com/scala/scala3/issues/24994&quot;&gt;scala/scala3#24994&lt;/a&gt;. The issue was identified as severe enough 
to be treated as an incident and postpone the release announcement until due investigation. 
A hotfix was proposed on Monday, 19th of January 
under &lt;a href=&quot;https://github.com/scala/scala3/pull/25008&quot;&gt;scala/scala3#25008&lt;/a&gt; and then merged on the next day, 
Tuesday, 20th of January.&lt;/p&gt;

&lt;p&gt;The &lt;a href=&quot;https://www.scala-lang.org/scala-core/&quot;&gt;Scala Core Team&lt;/a&gt; decided not to cancel Scala 3.8.0.
While the bug is severe, it would affect a very limited number of users. Moreover, libraries successfully compiled 
and published with 3.8.0 are not corrupted and can safely be used in the ecosystem.
Scala 3.8.0 and 3.8.1 (containing the hotfix) were announced simultaneously on Thursday, 22th of January 2026 
(link to the announcement can be found &lt;a href=&quot;https://scala-lang.org/news/3.8/&quot;&gt;here&lt;/a&gt;), 
with advice for users to upgrade directly to 3.8.1.&lt;/p&gt;

&lt;h2 id=&quot;what-exactly-happened&quot;&gt;What exactly happened?&lt;/h2&gt;
&lt;p&gt;If you are interested in the full technical details behind this incident, read on.&lt;/p&gt;

&lt;p&gt;Scala 3.8 series, with 3.8.0 being its first release, introduces a standard library compiled with Scala 3, 
rather than depending on the Scala 2.13 standard library. This change is, however, under the restriction of 
being fully backward compatible with the old &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;scala-library&lt;/code&gt; from Scala 2.13, 
as per &lt;a href=&quot;https://scala-lang.org/development/#scala-3-semantic-versioning&quot;&gt;standard compatibility guarantees of Scala 3&lt;/a&gt;. 
That proves difficult with classes, traits and methods annotated as &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;@specialized&lt;/code&gt;, 
since Scala 3 does not currently support specialization.&lt;/p&gt;

&lt;p&gt;The solution was to copy and adjust &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.class&lt;/code&gt; files for those cases from the library built by Scala 2.13. 
This allowed the team to preserve binary compatibility, 
which was then checked against the combined artifacts of Scala 2.13.16 and 3.7.4.&lt;/p&gt;

&lt;p&gt;The actual issue lies in the fact that the standard library of Scala 2.13 is 
processed by its &lt;a href=&quot;https://docs.scala-lang.org/overviews/compiler-options/optimizer.html&quot;&gt;JVM Bytecode Optimizer&lt;/a&gt;. 
The tool can inline references to private fields. For example, in the case of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;private[this] val _empty&lt;/code&gt;, 
it does not have an accessor generated, but rather is accessed directly and then used by &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;@inline def empty[T]&lt;/code&gt;. 
This then caused the library to have an inlined, direct reference to a private field, 
which has a different qualified name when compiled using Scala 3, and causes the failure.&lt;/p&gt;

&lt;p&gt;Several similar cases were found during the investigation.&lt;/p&gt;

&lt;h2 id=&quot;examples&quot;&gt;Examples&lt;/h2&gt;

&lt;h3 id=&quot;empty-rangegrouped&quot;&gt;Empty Range.grouped&lt;/h3&gt;
&lt;p&gt;Note: Scala 3.8.0 throws an exception, where it should return a Boolean.&lt;/p&gt;
&lt;div class=&quot;language-scala highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nf&quot;&gt;println&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Range&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;grouped&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;hasNext&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;ul&gt;
  &lt;li&gt;Scala 2.13.18:
    &lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;false
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;
  &lt;/li&gt;
  &lt;li&gt;Scala 3.7.4:
    &lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;false
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;
  &lt;/li&gt;
  &lt;li&gt;Scala 3.8.0:
    &lt;div class=&quot;language-scala highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nc&quot;&gt;Exception&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;thread&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;main&quot;&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;java&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;lang&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;NoSuchFieldError&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Class&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;scala.collection.Iterator$&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;does&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;not&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;have&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;member&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;field&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;&apos;scala.collection.Iterator&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;scala$collection$Iterator$$_empty&apos;&lt;/span&gt;
  &lt;span class=&quot;kt&quot;&gt;at&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;scala.collection.immutable.Range.grouped&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;Range.scala:&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;550&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;kt&quot;&gt;at&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;snippet$_.&amp;lt;init&amp;gt;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;snippet:&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;kt&quot;&gt;at&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;snippet_sc$.script$lzyINIT1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;snippet:&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;15&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;kt&quot;&gt;at&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;snippet_sc$.script&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;snippet:&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;15&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;kt&quot;&gt;at&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;snippet_sc$.main&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;snippet:&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;19&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;kt&quot;&gt;at&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;snippet_sc.main&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;snippet&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;
  &lt;/li&gt;
  &lt;li&gt;Scala 3.8.1:
    &lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;false
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;arrayopsreverseiterator&quot;&gt;ArrayOps.ReverseIterator&lt;/h3&gt;
&lt;p&gt;Note: Scala 3.8.0 throws a different exception.&lt;/p&gt;
&lt;div class=&quot;language-scala highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nf&quot;&gt;println&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;Array&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;empty&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;].&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;reverseIterator&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;next&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;ul&gt;
  &lt;li&gt;Scala 2.13.18
    &lt;div class=&quot;language-scala highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nc&quot;&gt;Exception&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;thread&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;main&quot;&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;java&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;util&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;NoSuchElementException&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;next&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;on&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;empty&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;iterator&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;at&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;scala&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;collection&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;Iterator$$anon$19&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;next&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;Iterator&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;scala&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;980&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;at&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;scala&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;collection&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;Iterator$$anon$19&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;next&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;Iterator&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;scala&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;978&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;at&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;scala&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;collection&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;ArrayOps$ReverseIterator$mcI$sp&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;next$mcI$sp&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;ArrayOps&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;scala&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;151&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;at&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;scala&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;collection&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;ArrayOps$ReverseIterator$mcI$sp&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;next&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;ArrayOps&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;scala&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;150&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;at&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;scala&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;collection&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;ArrayOps$ReverseIterator$mcI$sp&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;next&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;ArrayOps&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;scala&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;147&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;at&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;snippet$&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;delayedEndpoint$snippet$1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;snippet&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;at&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;snippet$delayedInit$body&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;apply&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;snippet&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;65534&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;at&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;scala&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;Function0&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;apply$mcV$sp&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;Function0&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;scala&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;42&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;at&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;scala&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;Function0&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;apply$mcV$sp$&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;Function0&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;scala&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;42&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;at&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;scala&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;runtime&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;AbstractFunction0&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;apply$mcV$sp&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;AbstractFunction0&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;scala&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;17&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;at&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;scala&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;App&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;$anonfun$main$1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;App&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;scala&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;98&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;at&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;scala&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;App&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;$anonfun$main$1$adapted&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;App&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;scala&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;98&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;at&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;scala&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;collection&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;IterableOnceOps&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;foreach&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;IterableOnce&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;scala&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;630&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;at&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;scala&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;collection&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;IterableOnceOps&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;foreach$&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;IterableOnce&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;scala&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;628&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;at&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;scala&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;collection&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;AbstractIterable&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;foreach&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;Iterable&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;scala&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;936&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;at&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;scala&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;App&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;App&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;scala&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;98&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;at&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;scala&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;App&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;main$&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;App&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;scala&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;96&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;at&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;snippet$&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;snippet&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;65534&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;at&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;snippet&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;snippet&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;
  &lt;/li&gt;
  &lt;li&gt;Scala 3.7.4
    &lt;div class=&quot;language-scala highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nc&quot;&gt;Exception&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;thread&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;main&quot;&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;java&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;util&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;NoSuchElementException&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;next&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;on&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;empty&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;iterator&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;at&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;scala&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;collection&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;Iterator$$anon$19&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;next&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;Iterator&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;scala&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;973&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;at&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;scala&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;collection&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;Iterator$$anon$19&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;next&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;Iterator&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;scala&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;971&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;at&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;scala&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;collection&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;ArrayOps$ReverseIterator$mcI$sp&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;next$mcI$sp&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;ArrayOps&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;scala&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;151&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;at&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;scala&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;collection&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;ArrayOps$ReverseIterator$mcI$sp&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;next&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;ArrayOps&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;scala&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;150&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;at&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;scala&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;collection&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;ArrayOps$ReverseIterator$mcI$sp&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;next&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;ArrayOps&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;scala&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;147&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;at&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;snippet$_&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;init&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;snippet&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;at&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;snippet_sc$&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;script$lzyINIT1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;snippet&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;15&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;at&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;snippet_sc$&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;script&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;snippet&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;15&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;at&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;snippet_sc$&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;snippet&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;19&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;at&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;snippet_sc&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;snippet&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;
  &lt;/li&gt;
  &lt;li&gt;Scala 3.8.0
    &lt;div class=&quot;language-scala highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nc&quot;&gt;Exception&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;thread&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;main&quot;&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;java&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;lang&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;NoSuchFieldError&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Class&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;scala.collection.Iterator$&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;does&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;not&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;have&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;member&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;field&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;&apos;scala.collection.Iterator&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;scala$collection$Iterator$$_empty&apos;&lt;/span&gt;
  &lt;span class=&quot;kt&quot;&gt;at&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;scala.collection.ArrayOps$ReverseIterator.next&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;ArrayOps.scala:&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;151&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;kt&quot;&gt;at&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;snippet$_.&amp;lt;init&amp;gt;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;snippet:&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;kt&quot;&gt;at&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;snippet_sc$.script$lzyINIT1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;snippet:&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;15&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;kt&quot;&gt;at&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;snippet_sc$.script&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;snippet:&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;15&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;kt&quot;&gt;at&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;snippet_sc$.main&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;snippet:&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;19&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;kt&quot;&gt;at&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;snippet_sc.main&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;snippet&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;
  &lt;/li&gt;
  &lt;li&gt;Scala 3.8.1
    &lt;div class=&quot;language-scala highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nc&quot;&gt;Exception&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;thread&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;main&quot;&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;java&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;util&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;NoSuchElementException&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;next&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;on&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;empty&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;iterator&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;at&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;scala&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;collection&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;Iterator$$anon$19&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;next&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;Iterator&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;scala&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;991&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;at&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;scala&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;collection&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;Iterator$$anon$19&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;next&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;Iterator&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;scala&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;991&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;at&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;scala&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;collection&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;ArrayOps$ReverseIterator$mcI$sp&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;next$mcI$sp&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;ArrayOps&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;scala&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;151&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;at&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;scala&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;collection&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;ArrayOps$ReverseIterator$mcI$sp&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;next&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;ArrayOps&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;scala&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;150&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;at&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;scala&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;collection&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;ArrayOps$ReverseIterator$mcI$sp&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;next&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;ArrayOps&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;scala&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;147&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;at&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;snippet$_&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;init&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;snippet&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;at&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;snippet_sc$&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;script$lzyINIT1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;snippet&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;15&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;at&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;snippet_sc$&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;script&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;snippet&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;15&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;at&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;snippet_sc$&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;snippet&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;19&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;at&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;snippet_sc&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;snippet&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;how-was-this-fixed&quot;&gt;How was this fixed?&lt;/h2&gt;

&lt;p&gt;The solution was still to copy &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.class&lt;/code&gt; files for sources with the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;@specialized&lt;/code&gt; annotation from the library 
built by Scala 2.13. The difference in the approach is that this time, they were not processed 
with the JVM Bytecode Optimizer. Additionally, the Scala 2 library class files being used are now built in 
the Scala 3 compiler repository to ensure full control over how these artifacts are produced. 
This proved to solve the problem, as can be tested with Scala 3.8.1.&lt;/p&gt;

&lt;h2 id=&quot;why-did-it-happen&quot;&gt;Why did it happen?&lt;/h2&gt;

&lt;p&gt;The issue was introduced due to a number of factors:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;Copying of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.class&lt;/code&gt; files the way it happened was necessary due to specialization 
(via the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;@specialized&lt;/code&gt; annotation or otherwise) never being implemented in Scala 3. 
While it was discussed in the past, it was decided the old approach was in need of a redesign 
and the necessary work was large in scope. As a result, it was delayed until an unspecified future.&lt;/li&gt;
  &lt;li&gt;While porting the standard library, its JUnit tests were not ported at the same time.
We have since shown that the JUnit tests would not have caught this particular incident.
Nevertheless, it was a risky bet, and we have now successfully run all the JUnit tests on the new library.
(It is also worth pointing out that JUnit tests constitute a very small part of the unit tests applicable to the library.)&lt;/li&gt;
  &lt;li&gt;Despite an exceptionally long RC period, the issue was not discovered earlier. 
3.8.0-RC1 was released as early as the 14th of November 2025. It took almost 2 months 
to discover the problem in user code. This is perhaps a reasonable argument for the problem being rather niche.
    &lt;ul&gt;
      &lt;li&gt;For further context, the RC period is around 1 month, by default.&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;The difference introduced to the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.class&lt;/code&gt; files of the old Scala 2.13 standard library by the JVM Bytecode Optimizer 
in comparison to the unprocessed files is, in the end, a nuance, a detail easy to miss in the grand scope of things. 
While in retrospect it is clear what should have been done, human error seems to be the biggest factor.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;how-do-we-stop-it-from-repeating&quot;&gt;How do we stop it from repeating?&lt;/h2&gt;

&lt;p&gt;All things considered, this incident is a unique occurrence.
That being said, &lt;a href=&quot;https://www.scala-lang.org/maintainers/&quot;&gt;the maintenance team&lt;/a&gt; spent the time on due investigation. 
Every step of the way has been re-thought and re-checked. Dedicated tests were implemented to catch 
similar incompatibilities in the future, so that no adjacent problem could happen unnoticed 
as the standard library is developed.&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;scalacenter/sbt-missinglink&lt;/code&gt;, the SBT plugin for which a bug report initially caught the issue, 
has proved valuable to include in the compiler testing pipeline.&lt;/p&gt;

&lt;p&gt;The topic of implementing specialization in Scala 3 (even in a limited capacity) or working around the limitations 
of lacking thereof will be revisited in the future.&lt;/p&gt;

&lt;h2 id=&quot;further-reading&quot;&gt;Further reading&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://scala-lang.org/news/3.8/&quot;&gt;Scala 3.8 announcement&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/scalacenter/sbt-missinglink/issues/54&quot;&gt;earliest report of the incident at scalacenter/sbt-missinglink#54&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/scala/scala3/issues/24994&quot;&gt;the main ticket tracking this incident at scala/scala3#24994&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/scala/scala3/pull/25008&quot;&gt;hotfix pull request at scala/scala3#25008&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://docs.scala-lang.org/overviews/compiler-options/optimizer.html&quot;&gt;JVM Bytecode Optimizer&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/scala/scala3/issues/25011&quot;&gt;ticket tracking working around limitations imposed by the lack of specialization in Scala 3&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://scala-lang.org/development/#scala-3-semantic-versioning&quot;&gt;Scala development guarantees (including compatibility requirements)&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</content>
  </entry>
  
  <entry>
    <title>The Sovereign Tech Fund invests in Scala</title>
    <link href="https://www.scala-lang.org/blog/2026/01/27/sta-invests-in-scala.html"/>
    <updated>2026-01-27T00:00:00+01:00</updated>
    <id>https://www.scala-lang.org/blog/2026/01/27/sta-invests-in-scala</id>
    <content type="html">&lt;p&gt;We’re truly excited to share that &lt;a href=&quot;https://www.sovereign.tech/tech/scala&quot;&gt;Scala has received an investment from the Sovereign Tech Fund&lt;/a&gt; to strengthen Scala’s long-term security, maintenance, and developer experience.&lt;/p&gt;

&lt;p&gt;The work is coordinated by the &lt;a href=&quot;https://scala.epfl.ch/&quot;&gt;Scala Center&lt;/a&gt; and runs for two years, with a total investment of €377,300.&lt;/p&gt;

&lt;p&gt;The Sovereign Tech Fund is a program of the Sovereign Tech Agency that globally invests in open software components that build our core digital infrastructure.&lt;/p&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;the-sovereign-tech-agency-and-the-sovereign-tech-fund&quot;&gt;&lt;strong&gt;The Sovereign Tech Agency and the Sovereign Tech Fund&lt;/strong&gt;&lt;/h2&gt;

&lt;p&gt;&lt;a href=&quot;https://www.sovereign.tech/&quot;&gt;The Sovereign Tech Agency&lt;/a&gt; is the first publicly funded organization in Europe that supports the development, improvement, and maintenance of open digital infrastructures. It is financed by the German Federal Ministry for Digital Transformation and Government Modernisation and is a subsidiary of SPRIND, the Federal Agency for Disruptive Innovation.&lt;/p&gt;

&lt;p&gt;The Sovereign Tech Agency’s mission is to strengthen the open source ecosystem sustainably, focusing on resilience, technological diversity, and the people behind the code as foundations for a future-ready economy and modern society.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://www.sovereign.tech/programs/fund&quot;&gt;The Sovereign Tech Fund&lt;/a&gt; identifies and invests in open source software components that enable the creation of software, and supports key technologies with broad societal importance. Since October 2022, the Sovereign Tech Fund has invested a total of around €34 million in 95 critical technology projects.&lt;/p&gt;

&lt;h2 id=&quot;scala-is-critical-digital-infrastructure&quot;&gt;&lt;strong&gt;Scala is critical digital infrastructure&lt;/strong&gt;&lt;/h2&gt;

&lt;p&gt;Scala is widely used to build and operate essential systems across multiple industries. These systems include data pipelines and distributed applications, and some are in highly regulated environments like finance and public services. In these contexts, reliability is paramount. The safety, sustainability, and evolution of the Scala language and its tooling directly impact systems that people and institutions rely on every day.&lt;/p&gt;

&lt;p&gt;This is why, in 2016, the Scala Center was founded with a clear mission: to make the Scala open-source ecosystem stronger, more resilient, and sustainable over the long term. Thanks to the continued support of Scala Center industry partners (through the &lt;a href=&quot;https://scala.epfl.ch/corporate-membership.html&quot;&gt;Advisory Board program&lt;/a&gt;), &lt;a href=&quot;https://www.epfl.ch/about/&quot;&gt;EPFL&lt;/a&gt;, and the worldwide Scala contributor community, the ecosystem continues to grow stronger every day.&lt;/p&gt;

&lt;p&gt;And today, with the Sovereign Tech Fund’s investment in Scala, this commitment is reinforced at a public-infrastructure level. We are very thankful that the Fund’s support recognizes Scala as critical digital infrastructure and enables sustained, focused work on the language’s core foundations over the coming years.&lt;/p&gt;

&lt;h2 id=&quot;a-closer-look-what-this-investment-will-deliver&quot;&gt;&lt;strong&gt;A closer look: what this investment will deliver&lt;/strong&gt;&lt;/h2&gt;

&lt;h3 id=&quot;1-security-audit&quot;&gt;&lt;strong&gt;1) Security Audit&lt;/strong&gt;&lt;/h3&gt;

&lt;p&gt;A dedicated security audit by &lt;a href=&quot;https://ostif.org/&quot;&gt;Open Source Technology Improvement Fund&lt;/a&gt; (OSTIF) will uncover vulnerabilities and strengthen confidence in Scala’s core components. This supports not only Scala users, but also the broader environments where Scala runs, for example as a component of complex software supply chains. We are super thankful to the OSTIF team and support!&lt;/p&gt;

&lt;h3 id=&quot;2-improvement-of-scoverage&quot;&gt;&lt;strong&gt;2) Improvement of scoverage&lt;/strong&gt;&lt;/h3&gt;

&lt;p&gt;scoverage is a key tool in the Scala ecosystem for measuring code coverage. Improving it increases the reliability of Scala codebases and helps teams detect gaps in testing earlier, especially as systems evolve.&lt;/p&gt;

&lt;h3 id=&quot;3-maintenance-of-the-standard-library--core-library-modules-and-apis&quot;&gt;&lt;strong&gt;3) Maintenance of the Standard Library / Core Library Modules and APIs&lt;/strong&gt;&lt;/h3&gt;

&lt;p&gt;Long-term maintenance of core libraries and APIs is critical for stability. This includes keeping foundational modules healthy, reducing technical debt, and ensuring compatibility across versions.&lt;/p&gt;

&lt;h3 id=&quot;4-modernization-and-extension-of-the-standard-library--core-library-modules-and-api-documentation&quot;&gt;&lt;strong&gt;4) Modernization and extension of the Standard Library / Core Library Modules and API Documentation&lt;/strong&gt;&lt;/h3&gt;

&lt;p&gt;As Scala continues to evolve, modernizing and extending core modules ensures the language remains productive and relevant, while also supporting gradual adoption and stable upgrade paths. The work also brings improvements to API documentation and Scala websites, to improve understanding.&lt;/p&gt;

&lt;h3 id=&quot;5-build-tool-major-update-sbt-20&quot;&gt;&lt;strong&gt;5) Build tool major update: sbt 2.0&lt;/strong&gt;&lt;/h3&gt;

&lt;p&gt;Build tools are the backbone of developer productivity. The major update to sbt 2.0 will make Scala projects easier to build, maintain, and understand. This will be impactful for new users and contributors, as well as for established projects. Among other improvements, sbt 2 adopts Scala 3 (in place of 2.12) as the language for build definitions.&lt;/p&gt;

&lt;h2 id=&quot;the-scala-centers-role&quot;&gt;&lt;strong&gt;The Scala Center’s role&lt;/strong&gt;&lt;/h2&gt;

&lt;p&gt;The Scala Center has been entrusted with coordinating the commissioned work, check out &lt;a href=&quot;https://scala.epfl.ch/team.html&quot;&gt;the team working on the projects&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;We are very thankful that this support recognizes Scala’s importance in the broader digital landscape, and for investing in foundational work that strengthens the reliability of the systems and services built on Scala across the public sector and industries.&lt;/p&gt;

&lt;h2 id=&quot;stay-informed-and-get-involved&quot;&gt;&lt;strong&gt;Stay informed and get involved&lt;/strong&gt;&lt;/h2&gt;

&lt;p&gt;We’ll share updates as work progresses, including milestones, delivered improvements, and opportunities to engage with the effort.&lt;/p&gt;

&lt;p&gt;Scala is critical digital infrastructure, so keeping it healthy is a shared responsibility. If you’re using Scala in production, maintaining libraries, or contributing to tooling and documentation, your feedback and involvement help keep Scala strong.&lt;/p&gt;

&lt;p&gt;In addition to occasional blog posts such as this one, we’ll also post more detailed updates, progress reports, and calls for feedback on our Discourse-based contributors forum at &lt;a href=&quot;http://contributors.scala-lang.org&quot;&gt;&lt;strong&gt;contributors.scala-lang.org&lt;/strong&gt;&lt;/a&gt;. Please follow the relevant threads to stay informed.&lt;/p&gt;

&lt;h2 id=&quot;forum-threads&quot;&gt;&lt;strong&gt;Forum threads&lt;/strong&gt;&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://contributors.scala-lang.org/t/standard-library-now-open-for-improvements-and-suggestions/7337&quot;&gt;Standard Library: Now open for improvements and suggestions&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://contributors.scala-lang.org/t/scala-documentation-web-sites-what-should-be-improved/7354&quot;&gt;Scala documentation, web sites: What should be improved?&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://contributors.scala-lang.org/t/extending-scala-with-modern-concurrency-primitives/7350&quot;&gt;Extending Scala with modern concurrency primitives&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://contributors.scala-lang.org/t/sbt-2-production-ready-roadmap/7351&quot;&gt;Sbt 2 production-ready roadmap&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://contributors.scala-lang.org/t/scoverage-hardening/7352&quot;&gt;Scoverage hardening&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</content>
  </entry>
  
  <entry>
    <title>Scala 3.8 released!</title>
    <link href="https://www.scala-lang.org/news/3.8/"/>
    <updated>2026-01-22T00:00:00+01:00</updated>
    <id>https://www.scala-lang.org/news/release-notes-3.8</id>
    <content type="html">&lt;p&gt;&lt;img src=&quot;/resources/img/scala-3.8-launch.png&quot; alt=&quot;Scala 3.8&quot; /&gt;&lt;/p&gt;

&lt;p&gt;We’re pleased to announce the release of Scala 3.8 — a significant release that modernizes the Scala ecosystem and paves the way for Scala 3.9 LTS. This release introduces a standard library compiled by Scala 3 itself, stabilizes highly-anticipated features like &lt;strong&gt;Better Fors&lt;/strong&gt; (SIP-62) and &lt;strong&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;runtimeChecked&lt;/code&gt;&lt;/strong&gt; (SIP-57), and introduces experimental features including &lt;strong&gt;flexible varargs&lt;/strong&gt; and &lt;strong&gt;strict equality pattern matching&lt;/strong&gt;.&lt;/p&gt;

&lt;h2 id=&quot;known-regressions&quot;&gt;Known regressions&lt;/h2&gt;

&lt;h3 id=&quot;notable-regression-in-scala-380-only&quot;&gt;Notable regression in Scala 3.8.0 only:&lt;/h3&gt;

&lt;blockquote&gt;
  &lt;p&gt;A runtime regression was detected after publishing Scala 3.8.0 artifacts. Please &lt;strong&gt;use Scala 3.8.1&lt;/strong&gt; instead. &lt;br /&gt;
&lt;br /&gt;
The issue could lead to JVM linkage errors at runtime. It may have affected Scala 3 users who execute Scala 2.13 libraries, as well as certain uses of specialized members in the Scala standard library.
Any library published with Scala 3.8.0 is expected to remain binary compatible. Artifacts built with Scala 3.8.0 are safe to use and should stay binary compatible with subsequent Scala 3 releases. &lt;br /&gt;
&lt;br /&gt;
A more detailed postmortem will follow shortly after the Scala 3.8 release announcement.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3 id=&quot;notable-regressions-in-scala-381-and-380&quot;&gt;Notable regressions in Scala 3.8.1 and 3.8.0:&lt;/h3&gt;

&lt;blockquote&gt;
  &lt;p&gt;The following regressions still present in 3.8.1 will be addressed in a forthcoming 3.8.2 hotfix release:&lt;/p&gt;

  &lt;ul&gt;
    &lt;li&gt;Some &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;for&lt;/code&gt; comprehensions have incorrect behavior at runtime (&lt;a href=&quot;https://github.com/scala/scala3/issues/24673&quot;&gt;bug 24673&lt;/a&gt;)&lt;/li&gt;
    &lt;li&gt;Certain code involving calls to certain parts of the Java standard library fail to compile (&lt;a href=&quot;https://github.com/scala/scala3/issues/25133&quot;&gt;bug 25133&lt;/a&gt;)&lt;/li&gt;
  &lt;/ul&gt;

  &lt;p&gt;Cautious users may wish to wait for 3.8.2.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h1 id=&quot;whats-new-in-scala-38&quot;&gt;What’s new in Scala 3.8?&lt;/h1&gt;

&lt;h2 id=&quot;jdk17is-now-required&quot;&gt;JDK 17 is now required&lt;/h2&gt;

&lt;blockquote&gt;
  &lt;p&gt;&lt;strong&gt;Important:&lt;/strong&gt; This release requires &lt;strong&gt;JDK 17 or later&lt;/strong&gt; for compilation and execution. If your project runs on an older JDK, you must upgrade before migrating to &lt;strong&gt;Scala 3.8&lt;/strong&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The plans for this change were &lt;a href=&quot;https://www.scala-lang.org/news/next-scala-lts-jdk.html&quot;&gt;announced in early 2025&lt;/a&gt; by the Scala team and are required to support future JDK 26+, which restricts access to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;sun.misc.Unsafe&lt;/code&gt; functionalities used by our existing lazy-vals implementation. For most end users this might be just a small adjustment, but this change needs to be considered by the library authors and communicated to their users. If your project still runs on an older JDK, you must first upgrade to at least 17 before upgrading to Scala 3.8. Upgrading earlier will allow you to benefit from new language features and improved performance on the modern JVM.&lt;/p&gt;

&lt;p&gt;The LTS (long‑term support) version Scala 3.3 will continue to produce JDK 8 compatible bytecode, but all future Scala releases (including the 3.9 LTS) will require JDK 17 or higher.
For library authors who need to keep compatibility with at least some older JVM versions, we recommend using upcoming Scala 3.3.8 LTS when it’s released in the next months. That version will provide a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;-Yfuture-lazy-vals&lt;/code&gt; flag which activates new implementation of lazy vals, which still requires upgrading to at least JDK 9.&lt;/p&gt;

&lt;h2 id=&quot;standardlibrary-changes&quot;&gt;Standard Library changes&lt;/h2&gt;

&lt;h3 id=&quot;compiled-with-scala3&quot;&gt;Compiled with Scala 3&lt;/h3&gt;

&lt;p&gt;The Scala standard library has historically been compiled using Scala 2.13 and used by Scala 3 as-is, thanks to binary compatibility. In Scala 3.8 the library is now compiled with Scala 3. The change itself has been verified to be binary compatible and should not cause problems when migrating to Scala 3.8.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;&lt;strong&gt;Source Incompatibility:&lt;/strong&gt; Context bounds in standard library classes such as &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;scala.reflect.ClassTag&lt;/code&gt; used in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Array.empty[T]&lt;/code&gt; method, are now desugared to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;given&lt;/code&gt; instead of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;implicit&lt;/code&gt;. This change requires &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;using&lt;/code&gt; modifiers when supplying explicit parameters.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class=&quot;language-scala highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;object&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Array&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;kt&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;empty&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;T:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;ClassTag&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Array&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;val&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;fails&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;Array&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;empty&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;reflect&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;ClassTag&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// error: No ClassTag available for Any&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;val&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;works&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;Array&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;empty&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;using&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;reflect&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;ClassTag&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;val&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;recommended&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;Array&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;empty&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Most such errors can be automatically fixed by the compiler when using &lt;strong&gt;Scala 3.7.4&lt;/strong&gt; with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;-source:3.7-migration -rewrite&lt;/code&gt; options, before upgrading to &lt;strong&gt;Scala 3.8&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Looking ahead to Scala’s future, compiling the standard library with Scala 3 itself paves the way for Scala 3 to eventually have its own standard library, free from the constraints of compatibility with Scala 2. However, this process will not actually begin until Scala 3.10.&lt;/p&gt;

&lt;h2 id=&quot;repl-becomes-a-separate-artifact&quot;&gt;REPL becomes a separate artifact&lt;/h2&gt;

&lt;blockquote&gt;
  &lt;p&gt;&lt;strong&gt;Breaking Change:&lt;/strong&gt; Starting with Scala 3.8, the REPL is distributed as a separate artifact. Projects and tools that depend on the REPL must add an explicit dependency on &lt;a href=&quot;https://index.scala-lang.org/scala/scala3/artifacts/scala3-repl/3.8.1&quot;&gt;scala3-repl&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This makes it easier to embed the REPL in tools, reduces the size of the core compiler distribution, and allows for easier integration with external dependencies.&lt;/p&gt;

&lt;p&gt;The previous REPL printer was not dealing well with long expressions or literals, making the output difficult to read.
&lt;img src=&quot;/resources/img/scala-3.8-launch_repl_3.7.png&quot; alt=&quot;Scala 3.7 REPL example&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Starting with &lt;strong&gt;Scala 3.8&lt;/strong&gt; REPL rendering is now powered by &lt;a href=&quot;https://index.scala-lang.org/com-lihaoyi/fansi&quot;&gt;com-lihaoyi/fansi&lt;/a&gt; and &lt;a href=&quot;https://index.scala-lang.org/com-lihaoyi/pprint&quot;&gt;com-lihaoyi/pprint&lt;/a&gt;. This change allows us to provide better user experience, and present results in cleaner, formatted output.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/resources/img/scala-3.8-launch_repl_3.8.png&quot; alt=&quot;Scala 3.8 REPL example&quot; /&gt;&lt;/p&gt;

&lt;h2 id=&quot;stabilised-language-features&quot;&gt;Stabilised language features&lt;/h2&gt;

&lt;h3 id=&quot;sip-62-for-comprehension-improvements&quot;&gt;&lt;a href=&quot;https://docs.scala-lang.org/sips/62.html&quot;&gt;SIP-62: For comprehension improvements&lt;/a&gt;&lt;/h3&gt;

&lt;p&gt;The &lt;strong&gt;Better Fors&lt;/strong&gt; desugaring previewed in &lt;strong&gt;Scala 3.7&lt;/strong&gt; is now &lt;strong&gt;stabilised&lt;/strong&gt; and &lt;strong&gt;enabled by default&lt;/strong&gt;.
The improved desugaring removes some of the surprising behaviours of traditional for‑comprehensions and produces more efficient code. Two key improvements are:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Aliases before generators&lt;/strong&gt; - You can introduce alias definitions at the start of a for‑comprehension:&lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&quot;language-scala highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;for&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;sizes&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;List&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;size&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sizes&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;yield&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;size&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Avoiding unnecessary &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;map&lt;/code&gt; calls&lt;/strong&gt; - When the last generator yields a value of the same type as its input, the for‑comprehension now emits direct code without an intermediate &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;map&lt;/code&gt; call. This simplifies the generated bytecode and avoids constructing unnecessary tuples.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;sip-57-replace-non-sensical-unchecked-annotations&quot;&gt;&lt;a href=&quot;https://docs.scala-lang.org/sips/57.html&quot;&gt;SIP-57: Replace non-sensical &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;@unchecked&lt;/code&gt; annotations&lt;/a&gt;&lt;/h3&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;runtimeChecked&lt;/code&gt; is now a &lt;strong&gt;standard feature&lt;/strong&gt;. It enables you to opt-out of certain static checks and defer them to runtime without resorting to the older, syntactically awkward &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;: @unchecked&lt;/code&gt; type ascription.&lt;/p&gt;

&lt;p&gt;Consider the following example that tries to load an optional config value and match it against known values.&lt;/p&gt;

&lt;div class=&quot;language-scala highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;portFromConfig&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Option&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;???&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;val&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;Some&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;httpPort&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;portFromConfig&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;http&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// warning: right hand side expression is Option, not Some&lt;/span&gt;

&lt;span class=&quot;nf&quot;&gt;portFromConfig&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;https&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;match&lt;/span&gt; 
    &lt;span class=&quot;k&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Some&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;port&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;println&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;HTTPS port: $port&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;  
    &lt;span class=&quot;c1&quot;&gt;// warning: match may not be exhaustive.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The compiler detects and warns that in some cases your program throw an exception at runtime. The previous &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;: @unchecked&lt;/code&gt; annotation could have been used to suppress these warnings, but its syntax made it difficult to apply.
The new &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;runtimeChecked&lt;/code&gt; clearly marks that given operation might fail, similar to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.head&lt;/code&gt; or &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.get&lt;/code&gt;. What’s more, it’s perfect for use in chained calls!&lt;/p&gt;

&lt;div class=&quot;language-scala highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;portFromConfig&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Option&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;???&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;val&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;Some&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;httpPort&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;portFromConfig&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;http&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;runtimeChecked&lt;/span&gt; 

&lt;span class=&quot;k&quot;&gt;val&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;otherPort&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;portFromConfig&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;https&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;_&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;runtimeChecked&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;match&lt;/span&gt; 
        &lt;span class=&quot;k&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Some&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;port&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;port&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;runtimeChecked&lt;/code&gt; only suppresses checks that can be performed at runtime. If you write an obviously wrong pattern (for instance, matching an &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Int&lt;/code&gt; against a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;String&lt;/code&gt;) the compiler still emits an error.&lt;/p&gt;

&lt;h2 id=&quot;new-preview-features&quot;&gt;New preview features&lt;/h2&gt;

&lt;p&gt;Preview features are only enabled if the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;-preview&lt;/code&gt; flag is used. Features that have reached the preview stage are always eventually stabilized, but may change incompatibly before that time.&lt;/p&gt;

&lt;h3 id=&quot;sip-71-allow-fully-implicit-conversions-in-scala-3-with-into&quot;&gt;&lt;a href=&quot;https://docs.scala-lang.org/sips/71.html&quot;&gt;SIP-71: Allow fully implicit conversions in Scala 3 with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;into&lt;/code&gt;&lt;/a&gt;&lt;/h3&gt;

&lt;p&gt;Scala 3 normally requires &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;import scala.language.implicitConversions&lt;/code&gt; anywhere you &lt;em&gt;use&lt;/em&gt; &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;scala.Conversion&lt;/code&gt; instances implicitly.
The new &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;into&lt;/code&gt; keyword provides two opt-in ways to allow implicit conversions &lt;strong&gt;without&lt;/strong&gt; that import:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;into[T]&lt;/code&gt; as a type constructor&lt;/strong&gt;: marks specific parameter types as “conversion allowed”, giving fine-grained control (only where you wrap with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;into[...]&lt;/code&gt;)&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;into&lt;/code&gt; as a soft modifier&lt;/strong&gt;: declares a trait, class, or opaque type alias as an &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;into&lt;/code&gt; target (e.g., &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;into trait Modifier&lt;/code&gt;), so conversions to that type are allowed everywhere without rewriting lots of signatures&lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&quot;language-scala highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;//&amp;gt; using options -preview&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;scala.Conversion&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;scala.Conversion.into&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// Library code: allow conversions into IterableOnce[A] for this parameter only&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;concat&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;A&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;](&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;xs&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;List&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;A&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ys&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;into&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;IterableOnce&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;A&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]])&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;List&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;A&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;xs&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;++&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ys&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// inside the body, `ys` is treated as IterableOnce[A]&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// User code: no `import scala.language.implicitConversions`&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;given&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Conversion&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;Array&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;, &lt;span class=&quot;kt&quot;&gt;IterableOnce&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]]&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;_&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;iterator&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;val&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;xs&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;List&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;val&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;ys&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Array&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;val&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;out&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;concat&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;xs&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ys&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;   &lt;span class=&quot;c1&quot;&gt;// `ys` is implicitly converted because expected type is `into[IterableOnce[Int]]`&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;into&lt;/code&gt; is currently a &lt;strong&gt;preview feature&lt;/strong&gt; and is planned to be stabilised in the next minor version.
It requires compilation with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;-preview&lt;/code&gt; compiler flag and can be activated using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;import scala.language.experimental.into&lt;/code&gt;.
If you previously used experimental annotation-based preview implementation be aware of source incompatibilites when upgrading to Scala 3.8.&lt;/p&gt;

&lt;p&gt;More information about &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;into&lt;/code&gt; modifiers can be found in &lt;a href=&quot;https://docs.scala-lang.org/scala3/reference/preview/into.html&quot;&gt;the dedicated reference&lt;/a&gt;.&lt;/p&gt;

&lt;h2 id=&quot;experimental-features-changes&quot;&gt;Experimental features changes&lt;/h2&gt;

&lt;h3 id=&quot;future-proof-standard-library&quot;&gt;Future-proof Standard Library&lt;/h3&gt;

&lt;p&gt;With the standard library now compiled using Scala 3, it has been enhanced to better support two highly experimental language features. These features remain far from stabilization and should not be relied upon in production code.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Explicit nulls&lt;/strong&gt; - When you enable explicit nulls in your project (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;-Yexplicit-nulls&lt;/code&gt;), all reference types become non-nullable unless annotated with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;| Null&lt;/code&gt;. Library maintainers have annotated many standard library APIs with explicit null-return types, so the type checker will now warn if you forget to handle a possible &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Null&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Capture checking&lt;/strong&gt; - The library code has been adjusted to interact properly with the experimental capture-checking system. When you enable capture checking (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;-language:experimental.captureChecking&lt;/code&gt;) the type checker tracks references to capabilities and ensures you do not capture local resources in closures.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; Both null-safety and capture-checking annotations remain experimental, opt-in features. Your existing code will behave exactly as before unless you enable the appropriate language flag.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3 id=&quot;pure-functions-and-capture-checking&quot;&gt;Pure functions and capture checking&lt;/h3&gt;

&lt;p&gt;The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;scala.caps.Pure&lt;/code&gt; capability is used by the capture checker to model pure functions.
Experimental separation checking is new in Scala 3.8 and ensures that closures do not capture resources, providing stronger guarantees about side-effect isolation.
To experiment with capture checking, import &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;scala.language.experimental.captureChecking&lt;/code&gt; and annotate your functions with the appropriate capabilities. Adding these annotations does not require enabling experimental features and it will not affect users who are not using capture checking.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; Only core traits related to capture checking and defined in the Scala Standard Library have been stabilized, as these have been proven to be stable. The capture checking itself is still an experimental feature.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2 id=&quot;new-experimental-features&quot;&gt;New experimental features&lt;/h2&gt;

&lt;blockquote&gt;
  &lt;p&gt;The following features are provisional and subject to change or outright removal. Do not rely on them in production code yet.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Several experimental SIPs land in Scala 3.8. You can try them by importing the corresponding experimental language imports or using matching experimental flags to the compiler.&lt;/p&gt;

&lt;h3 id=&quot;sip-67-strict-equality-pattern-matching&quot;&gt;&lt;a href=&quot;https://github.com/scala/improvement-proposals/pull/97&quot;&gt;SIP-67: Strict equality pattern matching&lt;/a&gt;&lt;/h3&gt;

&lt;p&gt;Scala’s &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;strictEquality&lt;/code&gt; is great at preventing nonsensical &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;==&lt;/code&gt; comparisons, but it historically made some very common ADT pattern matches painful - especially for enums or case objects, because constant patterns are compiled using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;==&lt;/code&gt;, which in turn requires a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;CanEqual&lt;/code&gt; proof.&lt;/p&gt;

&lt;p&gt;SIP-67 introduces an experimental opt-in that makes “ADT-style” pattern matching work smoothly under &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;strictEquality&lt;/code&gt;, without forcing you to provide &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;CanEqual&lt;/code&gt; evidence just to match on enum cases / case objects. In particular, it targets the frustrating situation where &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;==&lt;/code&gt; should remain rejected (e.g., because parts of the ADT shouldn’t be comparable), yet &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;match&lt;/code&gt; should still be usable.&lt;/p&gt;

&lt;div class=&quot;language-scala highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;scala.language.strictEquality&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;scala.language.experimental.strictEqualityPatternMatching&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;enum&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Foo&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;kt&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Bar&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Baz&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Int&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// Still rejected: comparing Foo values with `==` can be nonsensical&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;eqIsStillIllegal&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Foo&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Foo&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;y&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// error (as intended)&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// But pattern matching is now practical under strictEquality:&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;eval&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Foo&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Int&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;match&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;Foo&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;Bar&lt;/span&gt;      &lt;span class=&quot;k&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;Foo&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;Baz&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fun&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;fun&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This keeps the core promise of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;strictEquality&lt;/code&gt; (“don’t let me compare things that shouldn’t be comparable”) while removing a major adoption blocker for real-world enums and ADTs.&lt;/p&gt;

&lt;h3 id=&quot;sip-70-flexible-varargs&quot;&gt;&lt;a href=&quot;https://github.com/scala/improvement-proposals/pull/105&quot;&gt;SIP-70: Flexible Varargs&lt;/a&gt;&lt;/h3&gt;

&lt;p&gt;SIP-70 removes a long-standing limitation of Scala varargs calls: you can now use &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;*&lt;/code&gt; (spread) more than once in a single argument list, and the spreads can appear in the middle, not just at the end of arguments list. This makes it much easier to build varargs calls from multiple collections without manual concatenation.&lt;/p&gt;

&lt;div class=&quot;language-scala highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;scala.language.experimental.multiSpreads&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;sum&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;xs&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Int*&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Int&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;xs&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;sum&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;val&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Seq&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Seq&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;val&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Array&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Array&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;val&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;total&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;sum&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;   &lt;span class=&quot;c1&quot;&gt;// 15&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;sip-75-allow-single-line-lambdas-after-&quot;&gt;&lt;a href=&quot;https://github.com/scala/improvement-proposals/pull/118&quot;&gt;SIP-75: Allow single-line lambdas after &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;:&lt;/code&gt;&lt;/a&gt;&lt;/h3&gt;

&lt;p&gt;The indentation based and fewer-braces syntax introduced in Scala 3 allows you to apply a method or operator by separating it from a block with a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;:&lt;/code&gt;. SIP-75 extends the supported syntax by allowing the body of the function to be defined in the same line after &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;:&lt;/code&gt;.
In this form, the lambda extends to the end of the line, making it easy to move between the indented and single-line styles without having to switch back to parentheses.
The change is primarily about consistency and refactoring ergonomics:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;You can read &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;:&lt;/code&gt; uniformly as “application” when it is followed by either an indented block or a lambda.&lt;/li&gt;
  &lt;li&gt;It becomes natural to split/merge lines as code grows or shrinks, without changing the delimiter style (parentheses vs &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;:&lt;/code&gt;)&lt;/li&gt;
  &lt;li&gt;The requirement of new line in the lambda body was confusing to users&lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&quot;language-scala highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;scala.language.experimental.relaxedLambdaSyntax&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;newSyntax&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;xs&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Option&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;])&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&lt;/span&gt;
  &lt;span class=&quot;nv&quot;&gt;xs&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;v&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;v&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;filter&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;v&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;v&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;v&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;8&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;oldSyntax&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;xs&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Option&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;])&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&lt;/span&gt;
  &lt;span class=&quot;nv&quot;&gt;xs&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;v&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;v&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;
  &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;filter&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;v&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;v&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;v&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;8&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;match-expressions-with-sub-cases-23786&quot;&gt;Match expressions with sub-cases &lt;a href=&quot;https://github.com/scala/scala3/pull/23786&quot;&gt;#23786&lt;/a&gt;&lt;/h3&gt;

&lt;p&gt;This change adds an experimental extension to pattern matching: a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;case&lt;/code&gt; in a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;match&lt;/code&gt; can be followed by a &lt;strong&gt;nested “sub-match”&lt;/strong&gt; introduced by the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;if&lt;/code&gt; keyword.
This feature enables you to:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;first match an “outer shape” (e.g., &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Some(x)&lt;/code&gt;), and then&lt;/li&gt;
  &lt;li&gt;immediately refine the result by matching on a field derived from the outer bindings (e.g., &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;x.version&lt;/code&gt;).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Crucially, if the nested pattern does not match, we still proceed to the next enclosing &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;case&lt;/code&gt;. This is fundamentally different than putting the sub-case within another level of nesting—in a traditional nested &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;match&lt;/code&gt;, a failed inner case would not cause the outer match to try subsequent cases.&lt;/p&gt;

&lt;div class=&quot;language-scala highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;scala.language.experimental.subCases&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;enum&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Version&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;kt&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Legacy&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Stable&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;major&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;minor&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Document&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;title&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;version&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Version&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;versionLabel&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;d&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Option&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;Document&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;])&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;d&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;match&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Some&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;doc&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;@&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Document&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;_&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;version&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;version&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;match&lt;/span&gt;
      &lt;span class=&quot;k&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;Version&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;Stable&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;m&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;m&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;$m.$n&quot;&lt;/span&gt;
      &lt;span class=&quot;k&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;Version&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;Legacy&lt;/span&gt;                &lt;span class=&quot;k&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;legacy&quot;&lt;/span&gt;
      &lt;span class=&quot;k&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;_&lt;/span&gt;                             &lt;span class=&quot;k&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;unsupported&quot;&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;_&lt;/span&gt;                               &lt;span class=&quot;k&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;default&quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;ul&gt;
  &lt;li&gt;The sub-cases are tested only if the outer case matches (here: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Some(Document(_, version))&lt;/code&gt;).&lt;/li&gt;
  &lt;li&gt;The sub-match scrutinee (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;version&lt;/code&gt;) can refer to variables bound by the outer pattern (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;doc&lt;/code&gt;).&lt;/li&gt;
  &lt;li&gt;Sub-matches do not have to be exhaustive. If none of the sub-cases match, the whole &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;case ... if &amp;lt;submatch&amp;gt;&lt;/code&gt; is treated as not matched, and the outer match continues with the next case.&lt;/li&gt;
  &lt;li&gt;Sub-matches can be nested (sub-sub-matches), and you can interleave additional boolean guards between them when needed.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This experimental feature has not yet been considered by the SIP committee, but we’d like to hear your feedback about this proposal.&lt;/p&gt;

&lt;h2 id=&quot;other-notable-changes&quot;&gt;Other notable changes&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Annotations can now annotate themselves&lt;/strong&gt; &lt;a href=&quot;https://github.com/scala/scala3/pull/24447&quot;&gt;#24447&lt;/a&gt; - Scala now allows an annotation class to be annotated with itself. This is useful for “meta-annotations” where you want the annotation’s own definition to carry the same marker it applies elsewhere.&lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&quot;language-scala highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;scala.annotation.StaticAnnotation&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;final&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;audited&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;extends&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;StaticAnnotation&lt;/span&gt;

&lt;span class=&quot;nd&quot;&gt;@audited&lt;/span&gt;                 &lt;span class=&quot;c1&quot;&gt;// now allowed: the annotation annotates itself&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;final&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;audited&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;extends&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;StaticAnnotation&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;LTS/Next series indicators&lt;/strong&gt; &lt;a href=&quot;https://github.com/scala/scala3/pull/24709&quot;&gt;#24709&lt;/a&gt; - Starting with Scala 3.3, all artifacts are published with a special attribute in the pom.xml. This attribute indicates whether a given version is part of the LTS or Next series. Tooling can use this information to adjust its behaviour. Starting with Scala 3.8 and the upcoming 3.3.8 LTS, the attribute name has changed from &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;scala.versionLine&lt;/code&gt; to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;info.scala.versionLine&lt;/code&gt;. The change was required due to a negative interaction with build tools that assume attributes starting with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;scala&lt;/code&gt; are reserved.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Nightly builds in a new repository&lt;/strong&gt; - Scala 3 nightly builds for both Scala Next and Scala 3.3 LTS series are now published to a new repository: &lt;a href=&quot;https://repo.scala-lang.org/&quot;&gt;https://repo.scala-lang.org/&lt;/a&gt;. You can read more about this change in a &lt;a href=&quot;https://www.scala-lang.org/news/new-scala-nightlies-repo.html&quot;&gt;dedicated blogpost&lt;/a&gt;.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;JDK 26 support&lt;/strong&gt; - Scala can now emit and consume JDK 26 bytecode. As mentioned &lt;a href=&quot;#jdk17is-now-required&quot;&gt;earlier&lt;/a&gt;, the internal implementation of lazy vals has been adjusted to replace the deprecated &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;sun.misc.Unsafe&lt;/code&gt; with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;VarHandles&lt;/code&gt;. Starting with JDK 24, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;sun.misc.Unsafe&lt;/code&gt; emits runtime warnings. In JDK 26, it will throw an exception. This change makes newly published code compatible with JDK 26. However, these problems might still be triggered by previously published libraries or their transitive dependencies. We are working on tools to modify existing lazy-vals-related code to make them future-proof and ease migration to upcoming JDK versions. For more details, see the technical discussion in &lt;a href=&quot;https://www.youtube.com/watch?v=K_omndY1ifI&quot;&gt;Jakub Kozłowski’s latest podcast with Łukasz Biały&lt;/a&gt;, VirtusLab’s Scala Advocate who prototyped this idea.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;tooling-support&quot;&gt;Tooling support&lt;/h2&gt;

&lt;p&gt;Scala 3.8 changes how parts of the standard library and the REPL are published, which can affect build tools and IDE integrations. For the smoothest upgrade, use the recommended versions (especially if you rely on the REPL).&lt;/p&gt;

&lt;h3 id=&quot;build-tools&quot;&gt;Build tools&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;sbt&lt;/strong&gt;
    &lt;ul&gt;
      &lt;li&gt;Minimum &lt;a href=&quot;https://github.com/sbt/sbt/releases/tag/v1.11.5&quot;&gt;sbt 1.11.5&lt;/a&gt; (no REPL support)&lt;/li&gt;
      &lt;li&gt;Recommended &lt;a href=&quot;https://github.com/sbt/sbt/releases/tag/v1.12.0&quot;&gt;sbt 1.12.0&lt;/a&gt;&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Mill&lt;/strong&gt;
    &lt;ul&gt;
      &lt;li&gt;Minimum &lt;a href=&quot;https://github.com/com-lihaoyi/mill/releases/tag/1.0.5&quot;&gt;mill 1.0.5&lt;/a&gt; (or &lt;a href=&quot;https://github.com/com-lihaoyi/mill/releases/tag/0.12.16&quot;&gt;mill 0.12.16&lt;/a&gt; on the 0.12 line) (no REPL support)&lt;/li&gt;
      &lt;li&gt;Recommended &lt;a href=&quot;https://github.com/com-lihaoyi/mill/releases/tag/1.1.0-RC4&quot;&gt;mill 1.1.0&lt;/a&gt;(*forthcoming available 1.1.0-RC4)&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Scala CLI&lt;/strong&gt;
    &lt;ul&gt;
      &lt;li&gt;Minimum &lt;a href=&quot;https://github.com/VirtusLab/scala-cli/releases/tag/v1.9.0&quot;&gt;scala-cli 1.9.0&lt;/a&gt; (no REPL support)&lt;/li&gt;
      &lt;li&gt;Recommended &lt;a href=&quot;https://github.com/VirtusLab/scala-cli/releases/tag/v1.11.0&quot;&gt;scala-cli 1.11.0&lt;/a&gt;&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;ides-and-developer-tools&quot;&gt;IDEs and developer tools&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;IntelliJ IDEA&lt;/strong&gt;: Recommended &lt;a href=&quot;https://blog.jetbrains.com/scala/2025/12/08/scala-plugin-2025-3-is-out/&quot;&gt;Scala Plugin 2025.3&lt;/a&gt;. The JetBrains team has also prepared a blog post showcasing &lt;a href=&quot;https://blog.jetbrains.com/scala/2026/01/15/scala-38-support-in-the-scala-plugin/&quot;&gt;IntelliJ support for Scala 3.8&lt;/a&gt;.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Metals&lt;/strong&gt;: Recommended: &lt;a href=&quot;https://scalameta.org/metals/blog/2025/11/25/osmium&quot;&gt;Metals 1.6.4&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;scalafmt&lt;/strong&gt;: Minimum &lt;a href=&quot;https://github.com/scalameta/scalafmt/releases/tag/v3.10.1&quot;&gt;scalafmt 3.10.1&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Scalameta&lt;/strong&gt;: Minimum: &lt;a href=&quot;https://github.com/scalameta/scalameta/releases/tag/v4.14.1&quot;&gt;scalameta 4.14.1&lt;/a&gt; (used by Metals, scalafmt, scalafix, and more)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;whats-next&quot;&gt;What’s next?&lt;/h2&gt;

&lt;p&gt;The language is now in feature freeze mode in preparation for Scala 3.9 LTS. No new language features will be accepted for 3.9. Development and improvement of existing features is still allowed. This allows us to focus on fixing existing bugs in both tooling and compiler to ensure a smooth transition into the Scala 3.9 LTS era. The freeze will be lifted with the start of the Scala 3.10 development cycle.&lt;/p&gt;

&lt;p&gt;Effectively, &lt;strong&gt;Scala 3.9 LTS would contain the same feature set as Scala 3.8&lt;/strong&gt;. We may promote preview features to stable, but no new experimental or preview features will be introduced. As a result, any codebase using Scala 3.8 should not require any additional changes to use Scala 3.9 LTS.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Scala 3.8.2-RC1&lt;/strong&gt; is already available and its stable version is expected to be released in the second half of February 2026.&lt;/p&gt;
</content>
  </entry>
  
  <entry>
    <title>Scala 2.12.21 is now available!</title>
    <link href="https://www.scala-lang.org/news/2.12.21/"/>
    <updated>2025-12-11T00:00:00+01:00</updated>
    <id>https://www.scala-lang.org/news/release-notes-2.12.21</id>
    <content type="html">&lt;p&gt;&lt;a href=&quot;https://github.com/scala/scala/releases/tag/v2.12.21&quot;&gt;Scala 2.12.21&lt;/a&gt; is now available!&lt;/p&gt;

&lt;p&gt;This release is compatible with JDK 25 LTS and also introduces preliminary support for JDK 26.&lt;/p&gt;

&lt;p&gt;For all the details, refer to the &lt;a href=&quot;https://github.com/scala/scala/releases/tag/v2.12.21&quot;&gt;release notes&lt;/a&gt; on GitHub.&lt;/p&gt;
</content>
  </entry>
  
  <entry>
    <title>Scala Days 2025: Conference Highlights and Talk Recordings</title>
    <link href="https://www.scala-lang.org/blog/2025/11/26/scaladays-2025-review-video-announcement.html"/>
    <updated>2025-11-26T00:00:00+01:00</updated>
    <id>https://www.scala-lang.org/blog/2025/11/26/scaladays-2025-review-video-announcement</id>
    <content type="html">&lt;p&gt;This summer, the Scala Center celebrated 15 years of Scala Days, returning this August to its birthplace: Lausanne, Switzerland. &lt;strong&gt;The recordings of all the talks are now available&lt;/strong&gt; on the &lt;a href=&quot;https://www.youtube.com/c/ScalaDaysConferences&quot; target=&quot;_blank&quot;&gt;Scala Days YouTube channel&lt;/a&gt;, and with that, here are some closing remarks, and a look ahead to the future.&lt;/p&gt;

&lt;p&gt;The theme Functional Programming And The Real World attracted 57 excellent talks, and with 5 workshops, 27 sponsors, around 300 attendees, including several co-located events, the town was buzzing with Scala energy. We heard that in a bar far from the conference center, a local bartender proudly welcomed Scala enthusiasts after spotting the logo on their T-shirts and, to everyone’s delight, replied:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;“Of course we know Scala, it was designed here at EPFL!”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Even the journey was part of the fun: thanks to the London Scala User Group, attendees boarded the &lt;em&gt;Scala Jam Train&lt;/em&gt; from London through Paris — a rolling meetup that brought the community together before the first talk even began.&lt;/p&gt;

&lt;p&gt;This wonderful experience  was only possible thanks to the many hands and hearts behind the scenes and on the stage.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Attendees&lt;/strong&gt; — for your questions, hallway conversations, and enthusiasm that filled Lausanne with Scala spirit.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Organizers&lt;/strong&gt; — for months of planning, coordination, and care that made it all seamless.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Program Committee&lt;/strong&gt; — for building such a thoughtful lineup.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Speakers&lt;/strong&gt; — for sharing your knowledge, passion, and curiosity.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Sponsors&lt;/strong&gt; — for your generous support and commitment to the Scala community, helping make Scala Days possible.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Volunteers&lt;/strong&gt; — for your energy, kindness, and problem-solving superpowers.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We thank you all ♥️&lt;/p&gt;

&lt;h2 id=&quot;all-talks-now-on-youtube-&quot;&gt;All Talks Now on YouTube 🎥&lt;/h2&gt;

&lt;p&gt;We knew choosing between four parallel tracks would be tough — and that’s exactly the feedback we heard throughout the week! Good news: &lt;strong&gt;all talks and keynotes are now available on the&lt;/strong&gt; &lt;a href=&quot;https://www.youtube.com/c/ScalaDaysConferences&quot; target=&quot;_blank&quot;&gt;Scala Days YouTube channel&lt;/a&gt;. Relive the insights, learn something new, or discover what you missed.&lt;/p&gt;

&lt;p&gt;🎯 &lt;a href=&quot;https://youtube.com/playlist?list=PLLMLOC3WM2r6jZ_67FgmnOQhW_hA2RsJW&amp;amp;si=BJ2R2x2YYCiiAa21&quot; target=&quot;_blank&quot;&gt;&lt;strong&gt;Panorama Track&lt;/strong&gt;&lt;/a&gt; – a grand tour of the Scala ecosystem: language evolution, tooling innovation, and community discussions.&lt;/p&gt;

&lt;p&gt;🏢 &lt;a href=&quot;https://youtube.com/playlist?list=PLLMLOC3WM2r7Y5QWDJU-f1meaJYZrSpXg&amp;amp;si=IBjRq4MlJxp7DsNc&quot; target=&quot;_blank&quot;&gt;&lt;strong&gt;Industry Track&lt;/strong&gt;&lt;/a&gt; – real-world stories from teams running Scala at scale, exploring lessons learned and business impact.&lt;/p&gt;

&lt;p&gt;💡 &lt;a href=&quot;https://youtube.com/playlist?list=PLLMLOC3WM2r5-8J6PYZIfPRKMEek8INzQ&amp;amp;si=WBoTYhFqiab5ixZJ&quot; target=&quot;_blank&quot;&gt;&lt;strong&gt;Developer Experience Track&lt;/strong&gt;&lt;/a&gt; – deep dives into tooling, productivity, and how to get more out of your daily Scala flow.&lt;/p&gt;

&lt;p&gt;🎨 &lt;a href=&quot;https://youtube.com/playlist?list=PLLMLOC3WM2r6DiGbvDIW49P25VhkGp1VV&amp;amp;si=W5mc1EcjhnV7H3s5&quot; target=&quot;_blank&quot;&gt;&lt;strong&gt;Creative &amp;amp; Mix Track&lt;/strong&gt;&lt;/a&gt; – a vibrant mix of technical talks, playful experiments, and unexpected ways Scala shows up in life and work.&lt;/p&gt;

&lt;h2 id=&quot;building-trust-inclusion-safety-and-community&quot;&gt;Building Trust: Inclusion, Safety, and Community&lt;/h2&gt;

&lt;p&gt;At the Scala organization, we aim to build trust in Scala as an open source software project by providing regular releases, clear governance and open processes. Beyond the codebase we work to cultivate trust by making Scala Days a welcoming and inclusive space where community members can learn, share, and engage professionally in a safe environment. This year’s conference strengthened this commitment by focusing further on these key areas:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Safe environment&lt;/strong&gt; An updated &lt;a href=&quot;https://archives.scaladays.org/2025/code-of-conduct.html&quot; target=&quot;_blank&quot;&gt;Code of Conduct&lt;/a&gt; and on-site expert support team were available throughout the event, and many attendees took the opportunity to learn more about these resources. Organizers and volunteers trained in advance, speakers received dedicated briefings, and all attendees were oriented before the conference began — ensuring that everyone, from first-timers to long-time participants, felt encouraged and equipped to contribute to a culture of safety.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Inclusive by design&lt;/strong&gt; Inclusion by design starts with infrastructure. This year we ensured full accessibility across the conference experience while continuing to invest in thoughtful, community-specific details: a quiet room, a tourist information point, and volunteers ready to assist. We also provided on-site childcare and encouraged participants to bring partners and families, making Scala Days a shared experience.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Community building&lt;/strong&gt; Our conference-wide icebreaker game, &lt;em&gt;Find Your Twin&lt;/em&gt;, gave everyone a simple, playful starting point to meet new people and begin building connections. Colocated social activities and informal gatherings throughout the week further supported this. A highlight for many was the Community Party at the Museum of Modern and Contemporary Arts (MUDAC), where attendees could stroll through exhibitions, spark fun informal conversations — a relaxed setting for getting to know one another and deepening community connections.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Program flow&lt;/strong&gt; We understood that with so many fantastic talks, it could be tough for our attendees to organise their day around which talks they wanted to see the most. To support this, we organized the agenda into four thematic tracks, giving attendees clearer pathways through the content. And through the speaker buddy program and other coordination efforts, speakers were encouraged to learn about related sessions and, when appropriate, highlight those connections during their talks that helped guide attendees toward topics most relevant to their interests.&lt;/p&gt;

&lt;p&gt;We hope that these efforts played a part in the remarkable outcome that nearly 50% of attendees were joining Scala Days for the first time — a promising indicator of renewed trust, openness, and growth.&lt;/p&gt;

&lt;h2 id=&quot;looking-ahead&quot;&gt;Looking Ahead&lt;/h2&gt;

&lt;p&gt;As we wrap up this year’s Scala Days, and thanks to your feedback, we already have many ideas about how to further enhance the conference experience: from business-driven opportunities to deepen industry engagement, to new formats that elevate technical learning, networking, and collaboration.&lt;/p&gt;

&lt;p&gt;Please stay tuned for Scala Days 2026 as we have announcements coming soon! Until then, keep learning, keep sharing, and keep Scala vibrant.&lt;/p&gt;

&lt;h2 id=&quot;one-more-thank-you-to-our-sponsors&quot;&gt;One More Thank-You to Our Sponsors&lt;/h2&gt;

&lt;p&gt;Your support keeps Scala Days thriving and the Scala community growing.&lt;/p&gt;

&lt;h3 id=&quot;-platinum-sponsors&quot;&gt;🌟 Platinum Sponsors&lt;/h3&gt;

&lt;p&gt;&lt;a href=&quot;https://virtuslab.com/&quot; target=&quot;_blank&quot;&gt;&lt;strong&gt;VirtusLab&lt;/strong&gt;&lt;/a&gt; – &lt;em&gt;The company behind Scala.&lt;/em&gt; VirtusLab showcased its long-standing commitment to the Scala ecosystem — from contributing to the language itself and developing key tools like Scala CLI and Metals, to building popular Scala OSS libraries. Their focus on developer productivity, IDE and Bazel expertise, and LLM-assisted workflows, combined with the efficient delivery of high-quality software solutions for numerous partners, reflects their 15+ years of leadership in Scala innovation.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://www.signifytechnology.com/&quot; target=&quot;_blank&quot;&gt;&lt;strong&gt;Signify Technology&lt;/strong&gt;&lt;/a&gt; – &lt;em&gt;Building a diverse future, one placement at a time.&lt;/em&gt; As a global Scala recruitment specialist, Signify connects top-tier engineering talent with forward-thinking companies. With offices in LA, Austin, and London, they continue to champion diversity and inclusion in tech hiring worldwide.&lt;/p&gt;

&lt;h3 id=&quot;-gold-sponsors&quot;&gt;🥇 Gold Sponsors&lt;/h3&gt;

&lt;p&gt;&lt;a href=&quot;https://gradle.com/&quot; target=&quot;_blank&quot;&gt;&lt;strong&gt;Gradle&lt;/strong&gt;&lt;/a&gt; – &lt;em&gt;Accelerate every Scala build.&lt;/em&gt; Gradle’s &lt;strong&gt;Develocity&lt;/strong&gt; platform now integrates with sbt to help teams observe, optimize, and speed up their builds — empowering faster feedback cycles and better developer experience.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://jetbrains.com/&quot; target=&quot;_blank&quot;&gt;&lt;strong&gt;JetBrains&lt;/strong&gt;&lt;/a&gt; – &lt;em&gt;Easier and smarter software development.&lt;/em&gt; JetBrains has supported the Scala community for many years. This time, the IntelliJ Scala Plugin team came to Scala Days to present the AI-powered tooling JetBrains offers for developers, along with both new capabilities and long-standing hidden gems of IntelliJ IDEA and the Scala Plugin. Together, these tools help developers boost their productivity and make everyday Scala development more enjoyable.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://scalac.io/&quot; target=&quot;_blank&quot;&gt;&lt;strong&gt;Scalac&lt;/strong&gt;&lt;/a&gt; – &lt;em&gt;Your Scala &amp;amp; AI engineering partner.&lt;/em&gt; With 11 years of expertise and over 130 delivered projects, Scalac continues to champion open source, community growth, and global partnerships. They invite you to explore the latest trends shaping Scala’s future, check out their &lt;a href=&quot;https://scalac.io/state-of-scala-2025/&quot;&gt;State of Scala Report&lt;/a&gt;—a comprehensive look at the ecosystem’s direction, challenges, and opportunities ahead.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://writer.com/&quot; target=&quot;_blank&quot;&gt;&lt;strong&gt;Writer&lt;/strong&gt;&lt;/a&gt; – &lt;em&gt;Where AI meets business.&lt;/em&gt; Writer showcased its agent-builder platform that bridges IT and business teams, offering tools to build, activate, and supervise enterprise AI agents — and invited Scala engineers to join their growing AI research and engineering efforts.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://xebia.com/&quot; target=&quot;_blank&quot;&gt;&lt;strong&gt;Xebia&lt;/strong&gt;&lt;/a&gt; – &lt;em&gt;Engineering excellence, powered by Scala and AI.&lt;/em&gt; Xebia reignited its Scala community presence with demos, workshops, and hands-on sessions on event-sourced domain modeling and domain-driven design in Scala 3.&lt;/p&gt;

&lt;h3 id=&quot;-silver-sponsor&quot;&gt;🥈 Silver Sponsor&lt;/h3&gt;

&lt;p&gt;&lt;a href=&quot;https://www.kpler.com/&quot; target=&quot;_blank&quot;&gt;&lt;strong&gt;Kpler&lt;/strong&gt;&lt;/a&gt; – &lt;em&gt;Scala powering data at scale.&lt;/em&gt;For over a decade, Kpler has been building high-performance applications powered by the Scala ecosystem — leveraging its strong type system, functional programming paradigm, and thriving community. At Scala Days, they shared their journey and commitment to contributing back to the community.&lt;/p&gt;

&lt;h3 id=&quot;-bronze-sponsors&quot;&gt;🥉 Bronze Sponsors&lt;/h3&gt;

&lt;p&gt;A warm thank-you to our Bronze sponsors for their continued support of Scala Days and the wider community: Scala Teams, Mastercard, MOIA, Les Toises, Rock the JVM, ngrok, YouMoni, DFiant Works, Snowplow Analytics, SoftwareMill, Tiko, Recorded Future, SwissBorg, Deltek, HES-SO Valais-Wallis, Artima, NuMind, SiriusXM, and Netflix.&lt;/p&gt;

&lt;h3 id=&quot;-venue--host-sponsor&quot;&gt;🎓 Venue &amp;amp; Host Sponsor&lt;/h3&gt;

&lt;p&gt;A special thank-you to EPFL, the birthplace of Scala, for hosting Scala Days 2025 and welcoming the community. From the lecture halls where Scala was first conceived to today’s thriving academic and industry ecosystem, EPFL continues to nurture the language’s growth and spirit.&lt;/p&gt;
</content>
  </entry>
  
  <entry>
    <title>Scala 2.13.18 is now available!</title>
    <link href="https://www.scala-lang.org/news/2.13.18/"/>
    <updated>2025-11-24T00:00:00+01:00</updated>
    <id>https://www.scala-lang.org/news/release-notes-2.13.18</id>
    <content type="html">&lt;p&gt;&lt;a href=&quot;https://github.com/scala/scala/releases/tag/v2.13.18&quot;&gt;Scala 2.13.18&lt;/a&gt; is now available!&lt;/p&gt;

&lt;p&gt;This release
fixes several regressions from 2.13.17.
It is compatible with JDKs 8 to 26.&lt;/p&gt;

&lt;p&gt;For details, refer to the &lt;a href=&quot;https://github.com/scala/scala/releases/tag/v2.13.18&quot;&gt;release notes&lt;/a&gt; on GitHub.&lt;/p&gt;
</content>
  </entry>
  
</feed>
