5 ms·
> There will not be a Rust 2.0. Isn’t Rust 2018 effectively Rust 2.0 (since it introduced new keywords and requires changes to old code if a user opts in to Ru
by cornstalks 8y ago
> There will not be a Rust 2.0.
Isn’t Rust 2018 effectively Rust 2.0 (since it introduced new keywords and requires changes to old code if a user opts in to Rust 2018)? So the function could be made unsafe in Rust 2021 (or whatever it’s called).
- steveklabnik 8y agoNo, because it is opt in. All existing code keeps compiling as-is. The standard library cannot change with editions for exactly this reason. It’s compiled with a particular edition, like any other crate, and so can’t work differently in different editions.
- cornstalks 8y agoYou’re conflating Cargo, Rust (the language), and std/core libraries, and rustc (the compiler). This is one of the difficult parts of Rust and when people say “there won’t be a Rust 2.0” they don’t clarify which part they’re talking about. Given the tight relationship of all of these parts (despite each one being capable of being individually versioned), it would seem feasible to add a cfg attribute for the Rust edition, and then make the function unsafe if the user had opted in to Rust 2021 (or whatever).
- steveklabnik 8y agoI am not conflating anything. The compilation model of the language does not permit such a thing, independently of implementations of any of those pieces. This is a crucial aspect of the design of the language and the edition system. Think of it this way: crate A uses edition 2015. Crate B uses edition 2018. There’s only one copy of the standard library. It can’t be compiled both ways. If, in theory, we let you have multiple copies of the standard library, maybe that could work, but that’s not possible nor desirable for a host of reasons.
- benesch 8y agoWith all due respect, I do think you're conflating the way things are with the way things have to be. glibc has a similar commitment to never breaking user code, and yet symbols have been removed from glibc! The trick is to use "symbol versioning"; code compiled against old versions of glibc is transparently rewritten to use the old versions of symbols, while code compiled against new versions is rewritten to use the new versions of the symbols. [0][1] You can imagine something similar for the Rust standard library, whereby both the unsafe and safe versions are provided, and packages are transparently rewritten to use the correct version based on their specified edition. You don't need two copies of the stdlib; just of the symbols that have diverged. In this case, you wouldn't even need two versions of the symbol in the resulting binary, since the addition of `unsafe` doesn't change the codegen of the function, but merely restricts what code is accepted by the compiler. It's true that this would require some serious shenanigans in the stdlib, but it's a tractable problem. It's also, in my mind, quite acceptable for the standard library to play games like this, since the compiler, the language, and the stdlib are always going to be tightly coupled, and the complexity can be shielded from users. All that said, it sounds like the list of deprecated stdlib features is nowhere near long enough to justify adding this kind of complexity. [0]: https://gcc.gnu.org/wiki/SymbolVersioning https://gcc.gnu.org/wiki/SymbolVersioning [1]: Note that symbol versioning is kind of a quagmire, but that's because it's seriously underdocumented and practically no developers are aware that it exists. The idea itself is sound.
- steveklabnik 8y agoMaybe we’re just speaking at odds here. The current design of the language does not allow this. A different design may make it possible, but that’s a completely different question. I think what you’re saying is “it is possible to do this with the correct design” and what I’m saying is “that design has not been proposed nor accepted and so the answer today is “that’s not possible”.” Does that sound about right?
- benesch 8y agoYes, absolutely! (Although note that I'm not the OP.)
- phaylon 8y agoI still feel that there is more to language compatibility than "Can rustc run it with the right setting". Rust 2018 is a new version, the fact that it's not called 2.0 is just semantics. And I still believe "version interopability" would have been a better term than misusing "backwards compatibility".
- steveklabnik 8y agoAll existing code continues to compile as-is. That’s the definition of compatibility.
- phaylon 8y agoCan I copy a module from an old project into a new crate and it will always work without adjustments? What about code examples from StackOverflow, or Github issues? Will these work without adjustments in my local project? Will a future syntax highlighter always be able to highlight the code in my old Rust articles? Will future tooling always be able to read my current code? Can I make editor macros and snippets that will keep working in every version of Rust? If I can write code in one crate and it will compile, but then write it again in another, newer crate and it doesn't, then it isn't backwards compatible. Plus, as noted above, "code will keep compiling" isn't even a guarantee that the language team gives you.
- steveklabnik 8y ago1. Depends on the new project, of course. Just like any language. 2. Same thing. You can construct an example that breaks any language in existence. 3. Yes. 4. Yes. 5. Yes. 6. You’re using an idiosyncratic definition, so yes, it’s not the same. Backwards compatibility is about the same thing continuing to compile, not about changing things and expecting it to still compile; that’s forwards compatibility.
- phaylon 8y agoOnce again something is at odds here. You give resounding "Yes" comments, but in the backwards compatibility discussions I had with language team members, those "Yes" comments were actually "not really our problem" answers. I also don't know how current code running in a future compiler is forward-compatibility. And the Rust guarantee only kind-of holds if you define "code" as "crate". Everything outside of or crossing that boundary is not compatible. To clarify and bring it to an example: Are you guaranteeing that `(a<b, c>(d))` will always be parsed as a tuple with two comparisons? Because if so I believe you're the only one.