Skip to content

update tour/implicit-conversions for Scala 3 #2630

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 2 commits into from
Nov 9, 2022
Merged
Changes from 1 commit
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
59 changes: 30 additions & 29 deletions _tour/implicit-conversions.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,46 +10,33 @@ previous-page: implicit-parameters
redirect_from: "/tutorials/tour/implicit-conversions.html"
---

An implicit conversion from type `S` to type `T` is defined by an implicit value which has function type `S => T`, or by an implicit method convertible to a value of that type.
{% tabs implicit-conversion-defn class=tabs-scala-version %}
{% tab 'Scala 2' %}
In Scala 2, an implicit conversion from type `S` to type `T` is defined by an [implicit value]({% link _tour/implicit-parameters.md %}) which has function type `S => T`, or by an implicit method convertible to a value of that type.
{% endtab %}
{% tab 'Scala 3' %}
In Scala 3, an implicit conversion from type `S` to type `T` is defined by a [given instance]({% link _tour/implicit-parameters.md %}) which has type `scala.Conversion[S, T]`, or by an implicit method which can be eta-expanded to the function type `S => T`.
{% endtab %}
{% endtabs %}

Implicit conversions are applied in two situations:

* If an expression `e` is of type `S`, and `S` does not conform to the expression's expected type `T`.
* In a selection `e.m` with `e` of type `S`, if the selector `m` does not denote a member of `S`.
1. If an expression `e` is of type `S`, and `S` does not conform to the expression's expected type `T`.
2. In a selection `e.m` with `e` of type `S`, if the selector `m` does not denote a member of `S`.

In the first case, a conversion `c` is searched for which is applicable to `e` and whose result type conforms to `T`.
In the second case, a conversion `c` is searched for which is applicable to `e` and whose result contains a member named `m`.

If an implicit method `List[A] => Ordered[List[A]]` is in scope, as well as an implicit method `Int => Ordered[Int]`, the following operation on the two lists of type `List[Int]` is legal:

```
List(1, 2, 3) <= List(4, 5)
```

An implicit method `Int => Ordered[Int]` is provided automatically through `scala.Predef.intWrapper`. An example of an implicit method `List[A] => Ordered[List[A]]` is provided below.

```scala mdoc
import scala.language.implicitConversions

implicit def list2ordered[A](x: List[A])
(implicit elem2ordered: A => Ordered[A]): Ordered[List[A]] =
new Ordered[List[A]] {
//replace with a more useful implementation
def compare(that: List[A]): Int = 1
}
```
An example is to pass a `scala.Int`, e.g. `x`, to a method that expects `scala.Long`. In this case, the implicit conversion `Int.int2long(x)` is inserted.

The implicitly imported object `scala.Predef` declares several aliases to frequently used types (e.g. `scala.collection.immutable.Map` is aliased to `Map`) and methods (e.g. `assert`) but also several implicit conversions.

For example, when calling a Java method that expects a `java.lang.Integer`, you are free to pass it a `scala.Int` instead. That's because Predef includes the following implicit conversions:
In the second case, a conversion `c` is searched for which is applicable to `e` and whose result contains a member named `m`.

```scala mdoc
import scala.language.implicitConversions
An example is to compare two strings `"foo" < "bar"`. In this case, `String` has no member `<`, so the implicit conversion `Predef.augmentString("foo") < "bar"` is inserted.

implicit def int2Integer(x: Int) =
java.lang.Integer.valueOf(x)
```
**Beware the power of implicit conversions:**

{% tabs implicit-conversion-warning class=tabs-scala-version %}
{% tab 'Scala 2' %}
Because implicit conversions can have pitfalls if used indiscriminately the compiler warns when compiling the implicit conversion definition.

To turn off the warnings take either of these actions:
Expand All @@ -58,3 +45,17 @@ To turn off the warnings take either of these actions:
* Invoke the compiler with `-language:implicitConversions`

No warning is emitted when the conversion is applied by the compiler.
{% endtab %}
{% tab 'Scala 3' %}
Because implicit conversions can have pitfalls if used indiscriminately the compiler warns in two situations:
- when compiling the implicit conversion definition (for Scala 2 style conversions).
- at the call site where a given instance of `scala.Conversion` is inserted as a conversion.

To turn off the warnings take either of these actions:

- Import `scala.language.implicitConversions` into the scope of:
- the implicit conversion definition (for Scala 2 style conversions)
- the call site (when an inserted conversion was defined by a given instance of `scala.Conversion`)
- Invoke the compiler with `-language:implicitConversions`
{% endtab %}
{% endtabs %}