Skip to content

Backport changes to reference docs from 3.2.0 #16202

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions docs/_docs/reference/changed-features/pattern-bindings.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ movedTo: https://docs.scala-lang.org/scala3/reference/changed-features/pattern-b
In Scala 2, pattern bindings in `val` definitions and `for` expressions are
loosely typed. Potentially failing matches are still accepted at compile-time,
but may influence the program's runtime behavior.
From Scala 3.1 on, type checking rules will be tightened so that warnings are reported at compile-time instead.
From Scala 3.2 on, type checking rules will be tightened so that warnings are reported at compile-time instead.

## Bindings in Pattern Definitions

Expand All @@ -16,7 +16,7 @@ val xs: List[Any] = List(1, 2, 3)
val (x: String) :: _ = xs // error: pattern's type String is more specialized
// than the right-hand side expression's type Any
```
This code gives a compile-time warning in Scala 3.1 (and also in Scala 3.0 under the `-source future` setting) whereas it will fail at runtime with a `ClassCastException` in Scala 2. In Scala 3.1, a pattern binding is only allowed if the pattern is _irrefutable_, that is, if the right-hand side's type conforms to the pattern's type. For instance, the following is OK:
This code gives a compile-time warning in Scala 3.2 (and also earlier Scala 3.x under the `-source future` setting) whereas it will fail at runtime with a `ClassCastException` in Scala 2. In Scala 3.2, a pattern binding is only allowed if the pattern is _irrefutable_, that is, if the right-hand side's type conforms to the pattern's type. For instance, the following is OK:
```scala
val pair = (1, true)
val (x, y) = pair
Expand All @@ -25,7 +25,7 @@ Sometimes one wants to decompose data anyway, even though the pattern is refutab
```scala
val first :: rest = elems // error
```
This works in Scala 2. In fact it is a typical use case for Scala 2's rules. But in Scala 3.1 it will give a warning. One can avoid the warning by marking the right-hand side with an [`@unchecked`](https://scala-lang.org/api/3.x/scala/unchecked.html) annotation:
This works in Scala 2. In fact it is a typical use case for Scala 2's rules. But in Scala 3.2 it will give a warning. One can avoid the warning by marking the right-hand side with an [`@unchecked`](https://scala-lang.org/api/3.x/scala/unchecked.html) annotation:
```scala
val first :: rest = elems: @unchecked // OK
```
Expand All @@ -40,7 +40,7 @@ val elems: List[Any] = List((1, 2), "hello", (3, 4))
for (x, y) <- elems yield (y, x) // error: pattern's type (Any, Any) is more specialized
// than the right-hand side expression's type Any
```
This code gives a compile-time warning in Scala 3.1 whereas in Scala 2 the list `elems`
This code gives a compile-time warning in Scala 3.2 whereas in Scala 2 the list `elems`
is filtered to retain only the elements of tuple type that match the pattern `(x, y)`.
The filtering functionality can be obtained in Scala 3 by prefixing the pattern with `case`:
```scala
Expand All @@ -56,4 +56,4 @@ Generator ::= [‘case’] Pattern1 ‘<-’ Expr

## Migration

The new syntax is supported in Scala 3.0. However, to enable smooth cross compilation between Scala 2 and Scala 3, the changed behavior and additional type checks are only enabled under the `-source future` setting. They will be enabled by default in version 3.1 of the language.
The new syntax is supported in Scala 3.0. However, to enable smooth cross compilation between Scala 2 and Scala 3, the changed behavior and additional type checks are only enabled under the `-source future` setting. They will be enabled by default in version 3.2 of the language.
27 changes: 13 additions & 14 deletions docs/_docs/reference/changed-features/pattern-matching.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,15 @@ title: "Option-less pattern matching"
movedTo: https://docs.scala-lang.org/scala3/reference/changed-features/pattern-matching.html
---

The implementation of pattern matching in Scala 3 was greatly simplified compared to Scala 2. From a user perspective, this means that Scala 3 generated patterns are a *lot* easier to debug, as variables all show up in debug modes and positions are correctly preserved.
The implementation of pattern matching in Scala 3 was greatly simplified compared to Scala 2. From a user perspective, this means that Scala 3 generated patterns are a _lot_ easier to debug, as variables all show up in debug modes and positions are correctly preserved.

Scala 3 supports a superset of Scala 2 [extractors](https://www.scala-lang.org/files/archive/spec/2.13/08-pattern-matching.html#extractor-patterns).

## Extractors

Extractors are objects that expose a method `unapply` or `unapplySeq`:

```Scala
```scala
def unapply[A](x: T)(implicit x: B): U
def unapplySeq[A](x: T)(implicit x: B): U
```
Expand All @@ -25,7 +25,7 @@ called variadic extractors, which enables variadic patterns.

Fixed-arity extractors expose the following signature:

```Scala
```scala
def unapply[A](x: T)(implicit x: B): U
```

Expand All @@ -36,7 +36,7 @@ The type `U` conforms to one of the following matches:

Or `U` conforms to the type `R`:

```Scala
```scala
type R = {
def isEmpty: Boolean
def get: S
Expand All @@ -62,7 +62,7 @@ A usage of a fixed-arity extractor is irrefutable if one of the following condit

Variadic extractors expose the following signature:

```Scala
```scala
def unapplySeq[A](x: T)(implicit x: B): U
```

Expand All @@ -73,7 +73,7 @@ The type `U` conforms to one of the following matches:

Or `U` conforms to the type `R`:

```Scala
```scala
type R = {
def isEmpty: Boolean
def get: S
Expand Down Expand Up @@ -167,7 +167,7 @@ object Nat:
- `N > 1` is the maximum number of consecutive (parameterless `def` or `val`) `_1: P1 ... _N: PN` members in `U`
- Pattern-matching on exactly `N` patterns with types `P1, P2, ..., PN`

```Scala
```scala
object ProdEmpty:
def _1: Int = ???
def _2: String = ???
Expand All @@ -180,12 +180,11 @@ object ProdEmpty:
case _ => ()
```


## Sequence Match

- `U <: X`, `T2` and `T3` conform to `T1`

```Scala
```scala
type X = {
def lengthCompare(len: Int): Int // or, `def length: Int`
def apply(i: Int): T1
Expand Down Expand Up @@ -221,18 +220,18 @@ object CharList:
the type of the remaining patterns are determined as in Seq Pattern.

```Scala
class Foo(val name: String, val children: Int *)
class Foo(val name: String, val children: Int*)
object Foo:
def unapplySeq(f: Foo): Option[(String, Seq[Int])] =
Some((f.name, f.children))

def foo(f: Foo) = f match
case Foo(name, ns : _*) =>
case Foo(name, x, y, ns : _*) =>
case Foo(name, x, y, ns*) => ">= two children."
case Foo(name, ns*) => => "< two children."
```

There are plans for further simplification, in particular to factor out *product
match* and *name-based match* into a single type of extractor.
There are plans for further simplification, in particular to factor out _product match_
and _name-based match_ into a single type of extractor.

## Type testing

Expand Down
11 changes: 9 additions & 2 deletions docs/_docs/reference/contextual/context-bounds.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,14 @@ A context bound is a shorthand for expressing the common pattern of a context pa
def maximum[T: Ord](xs: List[T]): T = xs.reduceLeft(max)
```

A bound like `: Ord` on a type parameter `T` of a method or class indicates a context parameter `using Ord[T]`. The context parameter(s) generated from context bounds come last in the definition of the containing method or class. For instance,
A bound like `: Ord` on a type parameter `T` of a method or class indicates a context parameter `using Ord[T]`. The context parameter(s) generated from context bounds
are added as follows:

- If the method parameters end in an implicit parameter list or using clause,
context parameters are added in front of that list.
- Otherwise they are added as a separate parameter clause at the end.

Example:

```scala
def f[T: C1 : C2, U: C3](x: T)(using y: U, z: V): R
Expand All @@ -19,7 +26,7 @@ def f[T: C1 : C2, U: C3](x: T)(using y: U, z: V): R
would expand to

```scala
def f[T, U](x: T)(using y: U, z: V)(using C1[T], C2[T], C3[U]): R
def f[T, U](x: T)(using _: C1[T], _: C2[T], _: C3[U], y: U, z: V): R
```

Context bounds can be combined with subtype bounds. If both are present, subtype bounds come first, e.g.
Expand Down
25 changes: 13 additions & 12 deletions docs/_docs/reference/contextual/derivation-macro.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,12 @@ given derived[T: Type](using Quotes): Expr[Eq[T]]
and for comparison reasons we give the same signature we had with `inline`:

```scala
inline given derived[T]: (m: Mirror.Of[T]) => Eq[T] = ???
inline given derived[T](using Mirror.Of[T]): Eq[T] = ???
```

Note, that since a type is used in a subsequent stage it will need to be lifted
to a `Type` by using the corresponding context bound. Also, not that we can
summon the quoted `Mirror` inside the body of the `derived` this we can omit it
to a `Type` by using the corresponding context bound. Also, note that we can
summon the quoted `Mirror` inside the body of the `derived` thus we can omit it
from the signature. The body of the `derived` method is shown below:


Expand All @@ -49,15 +49,16 @@ given derived[T: Type](using Quotes): Expr[Eq[T]] =
ev match
case '{ $m: Mirror.ProductOf[T] { type MirroredElemTypes = elementTypes }} =>
val elemInstances = summonAll[elementTypes]
val eqProductBody: (Expr[T], Expr[T]) => Expr[Boolean] = (x, y) =>
elemInstances.zipWithIndex.foldLeft(Expr(true: Boolean)) {
case (acc, (elem, index)) =>
val e1 = '{$x.asInstanceOf[Product].productElement(${Expr(index)})}
val e2 = '{$y.asInstanceOf[Product].productElement(${Expr(index)})}
'{ $acc && $elem.asInstanceOf[Eq[Any]].eqv($e1, $e2) }
}

'{ eqProduct((x: T, y: T) => ${eqProductBody('x, 'y)}) }
def eqProductBody(x: Expr[Product], y: Expr[Product])(using Quotes): Expr[Boolean] = {
elemInstances.zipWithIndex.foldLeft(Expr(true)) {
case (acc, ('{ $elem: Eq[t] }, index)) =>
val indexExpr = Expr(index)
val e1 = '{ $x.productElement($indexExpr).asInstanceOf[t] }
val e2 = '{ $y.productElement($indexExpr).asInstanceOf[t] }
'{ $acc && $elem.eqv($e1, $e2) }
}
}
'{ eqProduct((x: T, y: T) => ${eqProductBody('x.asExprOf[Product], 'y.asExprOf[Product])}) }

// case for Mirror.ProductOf[T]
// ...
Expand Down
42 changes: 32 additions & 10 deletions docs/_docs/reference/contextual/derivation.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,27 +19,38 @@ The `derives` clause generates the following given instances for the `Eq`, `Orde
companion object of `Tree`,

```scala
given [T: Eq] : Eq[Tree[T]] = Eq.derived
given [T: Ordering] : Ordering[Tree] = Ordering.derived
given [T: Show] : Show[Tree] = Show.derived
given [T: Eq] : Eq[Tree[T]] = Eq.derived
given [T: Ordering] : Ordering[Tree[T]] = Ordering.derived
given [T: Show] : Show[Tree[T]] = Show.derived
```

We say that `Tree` is the _deriving type_ and that the `Eq`, `Ordering` and `Show` instances are _derived instances_.

### Types supporting `derives` clauses

All data types can have a `derives` clause. This document focuses primarily on data types which also have a given instance
of the `Mirror` type class available. Instances of the `Mirror` type class are generated automatically by the compiler
for,

+ enums and enum cases
+ case classes and case objects
+ sealed classes or traits that have only case classes and case objects as children
of the `Mirror` type class available.

`Mirror` type class instances provide information at the type level about the components and labelling of the type.
They also provide minimal term level infrastructure to allow higher level libraries to provide comprehensive
derivation support.

Instances of the `Mirror` type class are generated automatically by the compiler
unconditionally for:
- enums and enum cases,
- case objects.

Instances for `Mirror` are also generated conditionally for:
- case classes where the constructor is visible at the callsite (always true if the companion is not a case object)
- sealed classes and sealed traits where:
- there exists at least one child case,
- each child case is reachable from the parent's definition,
- if the sealed trait/class has no companion, then each child case is reachable from the callsite through the prefix of the type being mirrored,
- and where the compiler can generate a `Mirror` type class instance for each child case.


The `Mirror` type class definition is as follows:

```scala
sealed trait Mirror:

Expand Down Expand Up @@ -119,10 +130,21 @@ new Mirror.Product:
new Leaf(...)
```

If a Mirror cannot be generated automatically for a given type, an error will appear explaining why it is neither a supported
sum type nor a product type. For example, if `A` is a trait that is not sealed,

```
No given instance of type deriving.Mirror.Of[A] was found for parameter x of method summon in object Predef. Failed to synthesize an instance of type deriving.Mirror.Of[A]:
* trait A is not a generic product because it is not a case class
* trait A is not a generic sum because it is not a sealed trait
```


Note the following properties of `Mirror` types,

+ Properties are encoded using types rather than terms. This means that they have no runtime footprint unless used and
also that they are a compile time feature for use with Scala 3's metaprogramming facilities.
+ There is no restriction against the mirrored type being a local or inner class.
+ The kinds of `MirroredType` and `MirroredElemTypes` match the kind of the data type the mirror is an instance for.
This allows `Mirror`s to support ADTs of all kinds.
+ There is no distinct representation type for sums or products (ie. there is no `HList` or `Coproduct` type as in
Expand All @@ -145,7 +167,7 @@ following form,
```scala
import scala.deriving.Mirror

def derived[T](using Mirror.Of[T]): TC[T] = ...
inline def derived[T](using Mirror.Of[T]): TC[T] = ...
```

That is, the `derived` method takes a context parameter of (some subtype of) type `Mirror` which defines the shape of
Expand Down
2 changes: 1 addition & 1 deletion docs/_docs/reference/dropped-features/nonlocal-returns.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ title: "Deprecated: Nonlocal Returns"
movedTo: https://docs.scala-lang.org/scala3/reference/dropped-features/nonlocal-returns.html
---

Returning from nested anonymous functions has been deprecated.
Returning from nested anonymous functions has been deprecated, and will produce a warning from version `3.2`.

Nonlocal returns are implemented by throwing and catching `scala.runtime.NonLocalReturnException`-s. This is rarely what is intended by the programmer. It can be problematic because of the hidden performance cost of throwing and catching exceptions. Furthermore, it is a leaky implementation: a catch-all exception handler can intercept a `NonLocalReturnException`.

Expand Down
2 changes: 0 additions & 2 deletions docs/_docs/reference/dropped-features/this-qualifier.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,5 +29,3 @@ This can cause problems if a program tries to access the missing private field v
// [C] needed if `field` is to be accessed through reflection
val retained = field * field
```


2 changes: 1 addition & 1 deletion docs/_docs/reference/enums/enums-index.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---
layout: index
title: "Enums"
movedTo: https://docs.scala-lang.org/scala3/reference/enums.html
movedTo: https://docs.scala-lang.org/scala3/reference/enums/index.html
---

This chapter documents enums in Scala 3.
2 changes: 1 addition & 1 deletion docs/_docs/reference/experimental/explicit-nulls.md
Original file line number Diff line number Diff line change
Expand Up @@ -480,7 +480,7 @@ The program in [`unsafeNulls`](https://scala-lang.org/api/3.x/scala/runtime/stdL
For example, the following code cannot be compiled even using unsafe nulls. Because of the
Java interoperation, the type of the get method becomes `T | Null`.

```Scala
```scala
def head[T](xs: java.util.List[T]): T = xs.get(0) // error
```

Expand Down
Loading