Idea: Drop the `1.-` from the Rust version

There will not be a Rust 2.0 so what's the deal with the prefix? I personally think that it would be nicer to refer directly to Rust 78 for example.

This is probably not feasible because it will break scripts that expect it though but I want to hear your thoughts.


Rust itself might not be bringing out a 2.0 version anytime soon, or ever, but the Rust ecosystem as a whole does have many components (for example many crates) that do have major version bumps sometimes.

I believe there is a lot of value in keeping consistency with the standard practice in our ecosystem and using semantic versioning numbering for the Rust compiler itself, too. If nothing else, it helps further promote the use of semver and itʼs the least arbitrary choice.

For users that know semver, itʼs also the most self-explanatory approach. Itʼs already hard enough to explain to users Rustʼs stability guarantees and stance on backwards compatibility, as it stands. (“Oh but look, Rust is moving so fast and so unstable”.) I believe all this is valuable enough that if we werenʼt doing it for the rustc versions already, then we would strongly consider adding the “1.—” in front of the Rust version numbers.


Is that guaranteed? I can imagine a future where so much unpleasant baggage accumulates in the language or in the standard library Rust may want to start from scratch with Rust 2.0.


And it won't even necessarily be as disruptive as something like the Python 2→3 transition was— We might, for example, discover at some point that continuing to support 2015-edition code is no longer worth the complexity and effort to maintain. Dropping that would require a semver-breaking version bump but not necessarily affect most users/crates.


The libc crate uses the 2015 edition to this day for compatibility with rust 1.0, so dropping the 2015 edition will break everything that depends on libc.

1 Like

There has been talk about adapting a MSRV policy for libc. So that point would be moot then. And it seems very unlikely that anyone still uses rust versions that old (except for bisecting issues occasionally). According to the table at the very bottom of State of the Rust/Cargo crates ecosystem // Rust 1.50 or newer account for 99.0% of the traffic.


It will take a long while before pretty much everyone has migrated away from libc 0.2 and thus doesn't indirectly depend on the 2015 edition.

long time != never. Didn't C23 remove some ancient syntax that nobody uses anymore?


Dropping the 1. prefix doesn't yield a lot of fruit IMO. It's prevalent enough that it will still be in common use even if The Rust Project stopped using the prefix. And then it will just lead to questions like, "What's the difference between Rust 1.78 and Rust 78?"


I strongly dislike this "modern" versioning scheme popularized by browsers. It makes certain sense for consumer-facing products, but for developer-facing products it's just loss of information. Also, at this point it's better to just use dates, at least you will know when the version was released without looking it up.

Personally, I think that Rust should release 2.0 eventually. We already have a noticeable amount of baggage which would be great to shed. If Rust will follow the path of ossification, I am sure we will get Rust 2.0 either way, it's just will not be called Rust anymore.


Sure, but it took almost 15 years from C to C++, and then another 35 years until C++ was obviously on the decline. And it will be with us for decades to come. Things might be moving a bit faster nowadays, but still, rust in it's current form will be with us for a long time.

I know of one programming language that did this kind of change: Java, starting from version 1.5.0, or simply 5.0 from that point onward. Their reasoning was: The number "5.0" is used to better reflect the level of maturity, stability, scalability and security of the J2SE..

One has to differentiate in one important aspect. Java requires a runtime to be installed on end user devices, i.e. non-devs have to interact with it, unlike Rust, which doesn't need to be installed to be able to run the resulting binaries. Java still uses the major version internally for parsing and backward compatibility. In that regard, unless Rust gets an official runtime + intermediate language in the future, I personally don't see an advantage of exposing a different versioning scheme to the public. Every user of Rust is either a developer or a lost lamb who was looking to play a game.


Early versions of Rust had a 0.* prefix. Though early Rust wasn't always semver compliant, the jump from 0.* to 1.* is a meaningful one, and pre-1.0 code still exists in the wild, so we still care to make the distinction today.


By that timeline, with Rust 1.0 dating to 2015, we should expect Rust++ to come along after another six years or so.


I would not be surprised to see something like a Rust-fork that forms a superset of rust and soft-deprecates some parts of original Rust that are deemed "less desirable". Or perhaps a new language with near-native FFI to Rust. Both of these depend on a few things:

  • That there is something new discovered / wanted enough, and that can't fit in with rust (or rust itself ossifies, splitting the community over wether to include this thing or not, in this scenario rust might be forked and we get a new name for the fork).
  • That there is a sufficiently large existing code base in rust at that point that the cost of not interacting well with rust would be too large.

I would not wish to speculate on an actual timeline for this though, nor what what it would contain. Perhaps effects system catch on. Perhaps we figure out a completely new and better way of doing some core part of programming in the next 10 years and that forms the basis of it. Perhaps this is all a moot point because we will be living in a post-apocalypse that is a cross-over between Mad Max and Terminator.

1 Like

Rust 2.0 may be the only way the language ever gets linear types or async drop. I’m in favor of advancing the state of the art in spite of strong backward compatibility. And a major version bump is a good way to do that.

1.x and 2.x can be maintained in parallel at the expense of maintainer bandwidth. So, there is some maintenance calculus that cannot be ignored. But the major version component is important because it keeps the option on the table.


I wonder whether Rust 2.0 couldn't mean that we do actually break compatibility in the compiler, but drop old stuff from the documentation and maybe also in the way how the compiler would be implemented.

For example the 2015 edition would no longer be implemented in the main compiler but instead in a kind of modernizing preprocessor, which first compiles a crate into Rust 2023 code and similarly std and core get cleaned up. The benefit would be, that the actively developed parts of the compiler and the library become cleaner. It would also help alternative implementations a little bit.

Such a change could be a reason to give the whole thing a new version number.

1 Like

Such a preprocessor has to run for all editions and include macro expansion as macros can bring 2015 edition code into a 2018+ edition crate. If anything I think that will only increase complexity as now we would have to introduce some lossless serialization mechanism for post expansion rust code. Formatting it as rust source would loose the macro hygiene information, which would cause name resolution to misbehave. In addition something like the changed closure capture rules is implemented partially in borrowck for determining which paths are captured, so doing that as preprocessor would likely be hard.

1 Like

If you're looking for something that would make a Rust 2.0 worth doing, I'd be looking for a construct in Unsafe Rust that currently works on all platforms supported by Rust[1], where the informally defined behaviour of that construct is consistent with its use in all crates on, but where there is no way to formally define the construct (per T-opsem's hard work on formalizing Rust) without making some important crates execute UB as a result of following the formal definition.

Should such a construct exist (and I'm not convinced any such construct does exist), then a Rust 2.0 could be the best way to resolve the fact that an important subset of crates are defined as "broken" when the language definition is formalized.

To find such a construct, you'd have to spend a lot of time and effort working with T-opsem on their effort to formally define what Rust code means - and I suspect (assuming that, like me, you don't have a PhD in a field closely related to operational semantics), you'll find that most constructs that look like this turn out to be possible to formally define in a way that's consistent with all usage of the informally defined version.

  1. Your best bet for finding such a construct is looking for things that cannot work on CHERI or similar unusual architectures. ↩︎

I'd argue that adding Cherry does not need to be a breaking change. Even today you can allready write code that doesn't work on all targets. Reducing the rule "usize can be casted into any pointer and vise versa without data loss" by adding ", but only on targets where this is guranteed." wouldn't reduce language compatibility, as long as you keep your past promises on all properly maintained targets. We added targets after Rust 1.0 which do not support "std" and that wasn't considered a breaking change.

1 Like