Skip to content

Commit b6d57c0

Browse files
committed
@stableabi: transitivity and stdlib
1 parent 1ac1904 commit b6d57c0

File tree

1 file changed

+49
-7
lines changed

1 file changed

+49
-7
lines changed

sips/pending/_posts/2017-01-13-binary-compatibility.md

Lines changed: 49 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,15 @@ As long as declarations in source have not changed, `@stableABI` annotated class
5858
2. Defining a class which is supposed to be also used from other JVM languages such as Java\Kotlin.
5959
`@stableABI` will ensure both binary compatibility and that there are no unexpected methods
6060
that would show up in members of a class or an interface.
61+
62+
The biggest use-case envisioned here by the authors is migration to Dotty.
63+
We envision that there might be code-bases that for some reason don't compile either with Dotty or with Scalac.
64+
This can be either because they rely on union types, only present in Dotty,
65+
or because they need early initializers, which are only supported by Scalac.
66+
67+
At the same time, by marking either those classes themselves or their parents as `@stableABI`,
68+
the compiled artifacts could be used in both Dotty-compiled and Scalac-compiled projects.
69+
6170

6271
## Current Status
6372
In case there's a need to develop an API that will be used by clients compiled using different major versions of Scala,
@@ -153,7 +162,46 @@ The features listed below cannot be easily re-implemented in a class or trait an
153162
- default methods. See Addendum;
154163
- constant types(both explicit and inferred);
155164
- inline.
156-
165+
166+
## Binary compatibility and transitivity ##
167+
Consider a class, that is binary compatible but takes a non-binary compatible argument:
168+
```scala
169+
{% highlight scala %}
170+
@stableABI
171+
class Example {
172+
def foo[T](a: MyOption[T]): T = a.get
173+
}
174+
175+
trait MyOption[T]{
176+
lazy val get: T = ???
177+
}
178+
{% endhighlight %}
179+
```
180+
181+
Consider a situation when we re-compile `MyOption` using a different major compiler version than the one used to compile `Example`.
182+
Let's assume the new major version of compile has changing binary descriptor of method `get`.
183+
184+
While the code in runtime would still successfully invoke the method `Example.foo`, this method will fail in execution,
185+
as it will itself call a `MyOption.get` using an outdated descriptor.
186+
187+
While in perfect world it would be nice to require all `@stableABI` classes and traits to only take `@stableABI` arguments
188+
and only return `@stableABI` values, we believe that all-or-nothing system will be a lot harder to adopt and migrate to.
189+
190+
Because of this we propose to emmit warnings in those cases:
191+
- non-`@stableABI` value is returned from a method or field defined inside a `@stableABI` class or trait;
192+
- an invocation to a method not-defined inside a `@stableABI` class is used in
193+
implementation of a method or a field initializer inside a `@stableABI` class or trait.
194+
195+
Those warnings can be suppressed using an `@unchecked` annotations or made fatal using `+Xfatal-warnings`.
196+
197+
## The case of the standard library ##
198+
Standard library defines types commonly used in Scala signatures such as `Option` and `List`,
199+
as well as methods and implicit conversions imported from `scala` and `Predef`.
200+
201+
As such Standard library is expected would be the biggest source of warnings defined in previous section.
202+
203+
We propose to consider either making some classes in standard library use `@stableABI` or define new `@stableABI`
204+
super-interfaces for them that should be used in `@stableABI` classes. This would also allow to consume Scala classes from other JVM languages such as Kotlin and Java.
157205
## `@stableABI` and Scala.js
158206

159207
Allowing to write API-defining classes in Scala instead of Java will allow them to compile with Scala.js,
@@ -163,12 +211,6 @@ Scala.js currently is binary compatible as long as original bytecode compiled by
163211
Providing stronger binary compatibility guarantees for JVM will automatically provide stronger guarantees for Scala.js.
164212

165213

166-
## Binary compatibility and transitivity ##
167-
TODO
168-
169-
## The case of the standard library ##
170-
TODO
171-
172214
## Comparison with MiMa ##
173215
The Migration Manager for Scala (MiMa in short) is a tool for diagnosing binary incompatibilities for Scala libraries.
174216
MiMa allows to compare binary APIs of two already compiled classfiles and reports errors if APIs do not match perfectly.

0 commit comments

Comments
 (0)