diff --git a/_tour/implicit-conversions.md b/_tour/implicit-conversions.md index 4915f51daf..80e1a64196 100644 --- a/_tour/implicit-conversions.md +++ b/_tour/implicit-conversions.md @@ -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]`. For compatibility with Scala 2, they can also be defined by an implicit method (read more in the Scala 2 tab). +{% 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`. +In the first case, a conversion `c` is searched for, which is applicable to `e` and whose result type conforms to `T`. -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: +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. -``` -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. +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. (`scala.Predef` is automatically imported into all Scala programs.) -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 - } -``` - -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: - -```scala mdoc -import scala.language.implicitConversions - -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: @@ -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 a Scala 2 style implicit conversion definition. +- 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: + - a Scala 2 style implicit conversion definition + - call sites where a given instance of `scala.Conversion` is inserted as a conversion. +- Invoke the compiler with `-language:implicitConversions` +{% endtab %} +{% endtabs %}