Scala 3.0.0-RC1 – first release candidate is here

Greetings from the Scala 3 team! We are delighted to announce the first release candidate of the stable version of Scala 3 – Scala 3.0.0-RC1.

This release brings some last-minute polishings, clean-ups and changes before the big release. There were a few language changes to improve the user experience, as well as the polishings of the metaprogramming framework. We have also worked on the issues that had to be fixed before the stable release.

Overall, more than 400 PRs were merged after the M3 release and until today! Read more below!

Allow secondary type parameter list in extension methods

Type parameters on extensions can now be combined with type parameters on the methods themselves. E.g.:

List(1, 2, 3).second[Int]
extension [A](xs: List[A])
   def sumBy[B](f: A => B)(using Numeric[B]): B = ...

Type arguments matching method type parameters are passed as usual:

List("a", "bb", "ccc").sumBy[Int](_.length)

By contrast, type arguments matching type parameters following extension can be passed only if the method is referenced as a non-extension method:

sumBy[String](List("a", "bb", "ccc"))(_.length)

Or, when passing both type arguments:

sumBy[String](List("a", "bb", "ccc"))[Int](_.length)

For discussion, see PR #10940. For more information about the extension methods, see documentation.

New import syntax

The following are the changes to the import syntax made in this release.

Wildcard import _ is replaced by *. The motivation is that the majority of other languages use *. For example:

import scala.annotation.*  // imports everything in the annotation package

Renaming operator => is replaced by a soft keyword as. as is also allowed outside braces. For example:

import scala.collection.mutable as mut
import NumPy as np

For the details and discussion, see PR #11244. Read more about this change in the documentation.

Use * for vararg splices

PR #11240 changed the syntax of vararg splices in patterns and function arguments. The new syntax uses a postfix *, instead of : _*, analogously to how a vararg parameter is declared.

Use uninitialized for wildcard initializers

An obscure use of _ occurs in var definitions:

var x: T = _

It defines a concrete variable x without an initial value, or rather the default initial value that the JVM assigns to object fields. It can only be used in a class or object, not to initialize a local variable.

We came up with an arguably better way to express this idiom: the special uninitialized value in the scala.compiletime object. To get an uninitialized field, you now write:

import scala.compiletime.uninitialized

var x: A = uninitialized

This way expresses the intent of the idiom in a more verbose and easy to read way than simply writing an underscore.

For discussion, see PR #11231, and the documentation is available on our website.

Eta-expand companion object if functions are expected

Starting from RC1, we no longer generate a function parent for companions of case classes. Which means, for example, that given case class Foo(x: Int), you won't be able to use Foo in a position where a function is expected:

case class Foo(x: Int)
def f(g: Int => Foo) = g(10)


Results in:

1 |f(Foo)
  |  ^^^
  |The method `apply` is inserted. The auto insertion will be deprecated, please write `Foo.apply` explicitly.

As the warning suggests, now you should write Foo.apply instead of Foo. See Issue #6190 and PR #7207 for discussion.

Settling on scaladoc as the documentation tool

We have settled on using the well-known scaladoc as a name for the documentation tool for Scala 3 (known previously as scala3doc). The obsolete dotty-doc (or scala3-doc) is removed in RC1. We have also removed all the Kotlin dependencies (Dokka, etc.) from scaladoc. For details, see PR #11349. To read more about scaladoc, see documentation

Use future and future-migration to specify language versions after 3.0 in -source

PR #11355 changes the -source specifier for the Scala version(s) after 3.0 from 3.1 to future. I.e. it is now -source future and -source future-migration instead of -source 3.1 and -source 3.1-migration. Language imports are changed analogously. The reason for the change is that we want to keep the possibility open to ship a 3.1 version that does not yet contain all the changes enabled under -source future.

Other language changes

  • Warn when matching against an opaque type #10664
  • Fix #8634: Support -release option #10746 – the same way Scala 2 does. This setting allows you to specify a version of the Java platform (8, 9 etc) and compile the code with classes specific to the that Java platform, and emit the bytecode for that version.

Metaprogramming changes

A lot of work has been done on the metaprogramming side of things. Mostly we are cleaning up and polishing the API to prepare it for the stable release. The following are the important metaprogramming changes that took place:

  • Add scala.quoted.Expr.unapply as dual of Expr.apply #10580
  • Remove Expr.StringContext.unapply #10675
  • Add reflect MatchCase TypeRepr #10735
  • Rename scala.quoted.staging.{Toolbox => Compiler} #11129
  • Fix #10863: Make show AnyKinded #10988
  • Add ParamClause to allow multiple type param clauses #11074
  • Rework reflect Symbol fields API #10705
  • Rename Liftable to ToExpr and Unliftable to FromExpr #10618
  • Expand non-transparent macros after Typer #9984
  • Rework TastyInspector API to allow inspection of all files #10792
  • Allow leading context parameters in extension methods #10940
  • Rename Not to NotGiven to make its purpose clearer #10720
  • Fix #10709: Add missing level check before inlining #10781

Let us know what you think!

If you have questions or any sort of feedback, feel free to send us a message on our Gitter channel. If you encounter a bug, please open an issue on GitHub.


Thank you to all the contributors who made this release possible 🎉

According to git shortlog -sn --no-merges 3.0.0-M3..3.0.0-RC1 these are:

   183  Martin Odersky
   138  Nicolas Stucki
    36  Krzysztof Romanowski
    25  Filip Zybała
    25  Liu Fengyun
    24  Lan, Jian
    22  Jamie Thompson
    19  Tom Grigg
    17  Andrzej Ratajczak
    16  Stéphane Micheloud
    15  Guillaume Martres
    11  Paweł Marks
     9  Phil
     6  Aleksander Boruch-Gruszecki
     6  Jonathan Brachthäuser
     6  Natsu Kagami
     6  odersky
     4  Jasper Moeys
     4  Adrien Piquerez
     3  Sébastien Doeraene
     3  Michał Pałka
     3  Albert Chen
     2  Alexandre Archambault
     2  Som Snytt
     2  kenji yoshida
     2  Luc Henninger
     2  Ayush
     2  Raphael Jolly
     2  Anatolii Kmetiuk
     2  Olivier Blanvillain
     2  changvvb
     1  ysthakur
     1  Ang Hao Yang
     1  Ang9876
     1  AngAng
     1  August Nagro
     1  Ciara O'Brien
     1  Dale Wijnand
     1  Florian Cassayre
     1  Florian Schmaus
     1  Iltotore
     1  Jason Zaugg
     1  Julien Richard-Foy
     1  Katrix
     1  Master-Killer
     1  Michael Pilquist
     1  Mikael Blomstrand
     1  Mike Samuel
     1  Philippus
     1  Philippus Baalman
     1  Rick M
     1  Stephane MICHELOUD
     1  Timur Abishev
     1  Tomas
     1  ansvonwa
     1  ayush
     1  costa100
     1  iroha168
     1  noti0na1
     1  riiswa
     1  tanishiking

If you want to get your hands dirty and contribute to Scala 3, now is a good time to get involved! Head to our Getting Started page for new contributors, and have a look at some of the good first issues. They make perfect entry points into hacking on the compiler.

We are looking forward to having you join the team of contributors.