Sure, imagine Rust in a couple years from now, with Rust Editon "C++20", so lets come up with 2015, 2018, 2021, 2024, 2030 as possible epochs.
Now imagine a scenario where everyone uses binary libraries, like plenty of corporations do with C, C++, Java, .NET, Swift and other compiled languages.
How can epochs ensure that a binary library compiled in edition 2018, will be able to take a callback using a lambda written in edition 2024 main application, calling into a function available in a edtion 2015 crate, and then statically linked into a common runtime?
The current answer is it can't, unless all libraries happen to be compiled with the same compiler, and linked with the same runtime version.
Yes, it is a problem hard to solve, which not even a stable API fully fixes, because having it stable it restricts the language evolution on what can be exposed at library boundary and runtime library expectations.
Long term editions won't be much different than a -source in Java or -std= in C, C++ and so on.
It works for the time being because 2018 is basically the only edition available, with 2015 being pre-1.0, the same compiler gets backports to have a runtime compatible with both versions and there are no breaking changes where the language semantics have changed.
Hey, thanks for the response. I still feel like I'm missing an assumption, or we're otherwise talking past each other.
Specifically, it sounds like you're assuming there is (or could be, or should be?) some relation between editions and ABI?
I agree that Rust's current answer to your scenario is that all of the crates must have been compiled with the same compiler, but that has nothing at all to do with editions, and it's the same answer for exactly the same reasons if all of the crates were using the same language edition.
Editions aren't relevant here because editions are very limited in the scope. Consider these quotes from the in-progress RFC "2021 Edition"[1]:
Editions are used to introduce changes into the language that would
otherwise have the potential to break existing code, such as the
introduction of a new keyword.
Editions are never allowed to split the ecosystem. We only permit
changes that still allow crates in different editions to interoperate.
The most important rule for editions is that crates in one edition
can interoperate seamlessly with crates compiled in other editions.
This ensures that the decision to migrate to a newer edition is a
"private one" that the crate can make without affecting others,
apart from the fact that it affects the version of rustc that is
required, akin to making use of any new feature.
The requirement for crate interoperability implies some limits on
the kinds of changes that we can make in an edition. In general,
changes that occur in an edition tend to be "skin deep". All Rust
code, regardless of edition, is ultimately compiled to the same
internal representation within the compiler.
Whatever stable ABI Rust might eventually get, I expect it to be completely edition-oblivious. There should not be any way to tell by inspecting a compiled artifact in a stable Rust ABI which edition its code was written in.
Having written all this, I'm now wondering if you might have instead been trying to express something about how Rust's editions are insufficient to handle the requirements that a stable ABI would address? If so, I completely agree, although I'd be confused by the comparison, as they're very different kinds of things.
> Editions aren't relevant here because editions are very limited in the scope.
Which is exactly my whole point, as language evolves they won't be able to cover all possible language changes and compromises will be required, specially regarding possible incompatible semantic differences across editions.
The ABI example is just one way to make this issue more visible.
Now imagine a scenario where everyone uses binary libraries, like plenty of corporations do with C, C++, Java, .NET, Swift and other compiled languages.
How can epochs ensure that a binary library compiled in edition 2018, will be able to take a callback using a lambda written in edition 2024 main application, calling into a function available in a edtion 2015 crate, and then statically linked into a common runtime?
The current answer is it can't, unless all libraries happen to be compiled with the same compiler, and linked with the same runtime version.
Yes, it is a problem hard to solve, which not even a stable API fully fixes, because having it stable it restricts the language evolution on what can be exposed at library boundary and runtime library expectations.
Long term editions won't be much different than a -source in Java or -std= in C, C++ and so on.
It works for the time being because 2018 is basically the only edition available, with 2015 being pre-1.0, the same compiler gets backports to have a runtime compatible with both versions and there are no breaking changes where the language semantics have changed.