Skip to content

Commit fd56889

Browse files
authored
Add code tabs to contextual abstractions page (#2724)
1 parent 33b9f86 commit fd56889

File tree

1 file changed

+30
-14
lines changed

1 file changed

+30
-14
lines changed

_overviews/scala3-migration/incompat-contextual-abstractions.md

+30-14
Original file line numberDiff line numberDiff line change
@@ -27,25 +27,31 @@ The Scalafix rule named `ExplicitImplicitTypes` in [ohze/scala-rewrites](https:/
2727

2828
Scala 3 does not support implicit conversion from an implicit function value, of the form `implicit val ev: A => B`.
2929

30-
The following piece of code is now invalid:
30+
{% tabs scala-2-implicit_1 %}
31+
{% tab 'Scala 2 Only' %}
3132

32-
```scala
33+
The following piece of code is now invalid in Scala 3:
34+
~~~ scala
3335
trait Pretty {
3436
val print: String
3537
}
3638

3739
def pretty[A](a: A)(implicit ev: A => Pretty): String =
38-
a.print // Error: value print is not a member of A
39-
```
40+
a.print // In Scala 3, Error: value print is not a member of A
41+
~~~
42+
{% endtab %}
43+
{% endtabs %}
4044

4145
The [Scala 3 migration compilation](tooling-migration-mode.html) can warn you about those cases, but it does not try to fix it.
4246

4347
Be aware that this incompatibility can produce a runtime incompatibility and break your program.
4448
Indeed the compiler can find another implicit conversion from a broader scope, which would eventually cause an undesired behavior at runtime.
4549

46-
This example illustrates the case:
50+
{% tabs shared-implicit_2 %}
51+
{% tab 'Scala 2 and 3' %}
4752

48-
```scala
53+
This example illustrates the case:
54+
~~~ scala
4955
trait Pretty {
5056
val print: String
5157
}
@@ -54,13 +60,15 @@ implicit def anyPretty(any: Any): Pretty = new Pretty { val print = "any" }
5460

5561
def pretty[A](a: A)(implicit ev: A => Pretty): String =
5662
a.print // always print "any"
57-
```
63+
~~~
64+
{% endtab %}
65+
{% endtabs %}
5866

5967
The resolved conversion depends on the compiler mode:
6068
- `-source:3.0-migration`: the compiler performs the `ev` conversion
6169
- `-source:3.0`: the compiler cannot perform the `ev` conversion but it can perform the `anyPretty`, which is undesired
6270

63-
One simple fix is to supply the right conversion explicitly:
71+
In Scala 3, one simple fix is to supply the right conversion explicitly:
6472

6573
{% highlight diff %}
6674
def pretty[A](a: A)(implicit ev: A => Pretty): String =
@@ -73,11 +81,15 @@ def pretty[A](a: A)(implicit ev: A => Pretty): String =
7381
View bounds have been deprecated for a long time but they are still supported in Scala 2.13.
7482
They cannot be compiled with Scala 3 anymore.
7583

76-
```scala
84+
{% tabs scala-2-bounds_1 %}
85+
{% tab 'Scala 2 Only' %}
86+
~~~ scala
7787
def foo[A <% Long](a: A): Long = a
78-
```
88+
~~~
89+
{% endtab %}
90+
{% endtabs %}
7991

80-
In this example we get:
92+
In this example, in Scala 3, we get this following error message:
8193

8294
{% highlight text %}
8395
-- Error: src/main/scala/view-bound.scala:2:12
@@ -104,12 +116,16 @@ It is not the case in Scala 3 anymore, and leads to an ambiguous conversion.
104116

105117
For instance, in this example:
106118

107-
```scala
119+
{% tabs scala-2-ambiguous_1 %}
120+
{% tab 'Scala 2 Only' %}
121+
~~~ scala
108122
implicit def boolFoo(bool: Boolean): Foo = ???
109123
implicit def lazyBoolFoo(lazyBool: => Boolean): Foo = ???
110124

111125
true.foo()
112-
```
126+
~~~
127+
{% endtab %}
128+
{% endtabs %}
113129

114130
The Scala 2.13 compiler chooses the `boolFoo` conversion but the Scala 3 compiler fails to compile.
115131

@@ -131,4 +147,4 @@ implicit def lazyBoolFoo(lazyBool: => Boolean): Foo = ???
131147

132148
-true.foo()
133149
+boolFoo(true).foo()
134-
{% endhighlight %}
150+
{% endhighlight %}

0 commit comments

Comments
 (0)