The breakage in question here falls under changes to type inference, which are allowed within reason when they're relatively minor, when steps have been taken to mitigate any breakage in the broader ecosystem, and when the compiler has emitted warnings regarding the imminent change during a grace period, all of which have been done here.
You're downvoted but it's a very legitimate question. My main language at work is Rust, I had some expertise with the language (and deep interest for functional programming languages and type theory), but I almost don't read the code nowadays, I just skim though the functions and type definitions. I'm genuinely surprised that there are so many comments commenting the release. I thought most programmers wouldn't care anymore.
Thanks, it was also a genuine question on my part and something I personally noticed recently with the Python 3.15 release notes - I used to enjoy reading them and cared, but it seems a bit moot to read them nowadays.
So I wonder what programming languages should optimize for nowadays. Probably there's still something to be gained in developing Rust further, because its verifiable structure makes it mesh nicely with LLMs and helps them write code, but less so with more high level languages.
When we added the MSRV aware resolver, we decided to have it not affect `cargo install` because you could get an old version and not notice (especially with how noisy cargo is) when the right answer might be to upgrade.
Somewhat similar for min-publish-age but also we had defined the parent table for these config fields to not affect install.
The change to `--locked` made us feel a little better with this non-ideal circumstance.
Would you say that having 100 releases of the language more of a positive thing or a negative thing?
For comparison, C has had, say, 4 versions, and C++ 7 had versions (depending on how you count). But - Java has had 27 main versions and probably more than a 100 if you count minor versions/updates.
101 stable Rust minor releases, because 1.0 was a stable release, and many more micro releases incorporating merely urgent bug fixes with no other work.
Even ignoring K&R C there is C89, C99, C11, C17, C23 and C2y is in progress. I don't see any way to squint at that and count four.
They are completely different release processes, for different things. C and C++ are language specifications and Rust is a tool chain. Even comparing against another compiler tool chain like gcc it wouldn't be a 1 to 1 comparison. Rust having 100 minor releases is only a factor of the passage of time.
Last time I checked between a quarter and a third had a patch release, and those are closer to a signal of "a minor release had a problem". When analysing those my conclusion and the time was "for the most part they were needed because some niche feature or platform had a regression that wasn't caught by the suite and a handful of regressions causes by enabling a new feature or updating llvm".
Even Rust Editions are not a good point of comparison because they are also time based and only leveraged by things that would otherwise be breaking changes.
What you could use for direct comparison is accepted Rust RFCs against accepted C++ proposals papers or the equivalent for other languages. Or merged Pull/Merge Request counts for the different tool chains. But that's not perfect either (Rust only supports one language, while GCC several, but it has a package manager, which GCC doesn't).
GCC, clang and cmake had way more than 100 minor releases.
The version numbers are not comparable, because Rust bundles compiler, package manager, standard library in one release.
Additionally, Rust the language makes incremental changes stabilising individual features when they're ready, instead of bottling them up into rare grand releases. So number of releases doesn't tell you rate of change. It's like slicing pizza into smaller slices doesn't make a bigger pizza.
A defer that you can explicitly skip (via `dismiss()`) - I like it, that'd clean up a fair bit of "do this for safety unless successful" Go code that I've encountered. I've built similar things before, sometimes it helps a lot, and often that's in especially gnarly code which generally benefits from any clarity improvement.
Can anyone who knows Rust well explain why its so good for AI?
It seems like the AI can really write safe types and fast, efficient code in rust that beats anything else.
I've moved basically all my projects over to it. And I don't really know how it compares to other fast languages. My personal langue preference was always for readable languages like Clojure or Ruby, but at this point I'm not reading any code and just want performance.
Most of the reasons previously not to use Rust came down to the i) non-trivial learning curve, especially the ownership model, and ii) the (allegedly) overbearingly strict compiler that forces you to think through potential errors and solve them.
With agentic programming, (i) is a non-issue since LLMs have a very good grasp of the language, and it's no skin of your back, the agent is sweating it out with the compiler, not you, and (ii) is likely something you actually want.
I suspect it comes down to which other ecosystem you are coming from:
Python -> Rust: massive performance gains, type safety, much better concurrency
C++ -> Rust: much much better memory safety, much nicer compiler errors and warnings
But there are other language ecosystems where the gains become more subjective.
For eg. Golang -> Rust, I'd argue better "correctness", especially when concurrency is involved, but it's less pronounced than some of the other paths I mentioned above.
> Golang -> Rust, I'd argue better "correctness", especially when concurrency is involved, but it's less pronounced than some of the other paths
Tractable correctness is an underrated win at the scale of building enterprise solutions. But Rust also is a systems language, something that people had hoped from golang.
a well designed Rust project can leverage the type system to represent "weird states" in your program. what would otherwise be unstated rules or assumptions can be laid out cleanly as type invariants. a common example is `div(a, b) -> Option` where None is returned when b is zero. you can get really fancy with this, the blog post talks about a token struct that represents holding the GIL. doing this kind of thing can make certain logic errors more difficult to write and makes code self-documenting in some sense. going against the type system is flagged during compilation, which broadly contributes to rust code feeling like it "just works" when it compiles.
if code fails to compile, rustc will produce a very high quality error message 90% of the time (they can get pretty gnarly when you're doing something super tricky, but they're still very workable for agents). tests are a first class feature, so agents are able to spot check new features on the same turn you ask it to implement something new. documentation is also first class, and lots of libraries have excellent docs (read https://docs.rs/pyo3/0.30.1/pyo3/marker/struct.Python.html). the whole toolchain gives agents a lot to work with.
> It seems like the AI can really write safe types and fast, efficient code in rust that beats anything else.
This is also true for humans! Rust/C/C++ are all about equally fast, but Rust is more productive for most people. The downside for humans is that Rust's learning curve is pretty steep, but that doesn't bother the LLMs.
To be fair, as far as I know even bleeding edge LLMs have problems with the borrow checker and resort to similar workarounds as newbie human Rust coders.
Both C and C++ have a much steeper learning curve than many realize, just because the compilers let you get away with doing things that are fundamentally invalid (Undefined Behavior). Rust isn't actually much stricter, it just catches these problems at compile time.
Anyone capable of writing actually correct, standard-conforming C and C++ is mostly able to first-try the equivalent Rust code in almost all cases, because they are already thinking the same way that Rust requires you to think.
However, a significant portion of people who write both C and C++ don't realize that their code is full of UB - or worse, they don't care.
From a language perspective, the only new restriction in Rust compared to C++ is that mutable borrows (references) cannot overlap. Good C++ programmers are already avoiding this at all cost, because it's a mess to keep track of. When you actually do need it, Rust gives you the tools to build a safe abstraction.
EDIT: And to add, Rust is actually less restrictive in a few areas compared to C++. For example, Rust allows bitcasting between unrelated but compatible types (without going through char pointers).
* Very strong type system which helps catch bugs at compile time.
* The type system lets you enforce invariants, e.g. see the type state pattern and "make invalid states unrepresentable"
* The borrow checker encourages tree ownership which tends to be a less buggy structure than "anything can own anything" spaghetti you get in GC'd languages.
These give it an "if it compiles it works" character, that some other languages also have (e.g. Haskell), but most don't.
This was all well known before AI. I guess it's just more obvious to people that never tried Rust themselves.
It's not a proper solution. A malicious crate can just contain a time-based switching mechanism in order to be undetected some time (let's say a couple of months) in order to become widespread.
There exist companies who scan newly published crates (especially popular ones) for malicious code. Just because the code isn't active yet doesn't mean it won't be caught within a window like this. These measures provide real, albeit imperfect, security.
Isn't it the time between release for analysis and release for use? I suppose that finding malware only when it's activated isn't the only possible way, especially when the complete source code is available.
This is something I really appreciate about cargo/crates.io's source-only distribution, compared to e.g. npm or pip/PyPI.
You always know that the package contents match the source code. And you can always add a dependency by just downloading its source code and putting it into a subdirectory. You don't have to go and set up a different build system for each library if you want to avoid the pre-built artifacts.
Because rust 1.100.0 will still compile older code. To get the breaking changes, a crate has to opt into a newer edition. Older editions will still work fine. Apparently this has the added advantage that crates that use different editions can still work together, because the compiler understands all editions.
The release explicitly made a breaking change for _old_ editions regarding the `Infallible` type. Though they do explain that they consider the fallout of this to be minimal
It's a very minor breaking change. This happens all the time in large projects. E.g. when C++ or Python remove rarely used features. Python would be at version 10 by now if they followed strict backwards compatibility.
I've been thinking for a while about learning a programming language other than SQL and Python. I'm weighing three candidates: C, C++ (modern C++, with smart pointers and so on) or Rust, and I can't make up my mind. C is ideal because it would get me into the Linux world and make me 100% portable. But the threat Rust poses on the security front is significant. C++ is a real dark horse: almost all high-performance libraries are written in C++, as are critical pieces of software such as 3D engines, drone controllers and robotics. But the threat from Rust is still felt.
I have to choose: what would you recommend? I think C++ could be the perfect fit, but it keeps me out of Linux kernel development. With LLMs, is the safety advantage of Rust's borrow checker mitigated?
C is a simple language that is easy to understand but also easy to make classic mistakes like use-after-free and array boundaries.
C++ is an extremely complex language with lots of features and libraries and mountains of code, but it's not necessarily easy to write or debug. Compiler warnings alone can be crazy, considering the templating feature is almost a compile-time turing complete language.
Rust has some (to me) ugly syntax, but it tries to avoid the footguns of C++ while maintaining its commitment to removing the classic C problems in safe code. It also tries to maintain "zero cost abstractions" that are easier to program, but don't impact execution speed, primarily by having a much smarter compiler than C or C++.
I'd learn Rust. C will be easy after that, and C++ may be unnecessary.
What are your plans? C is a simple language, which brings you closer to assembler. It does allow some unusual syntax, which is why obfuscated C contests exist, but you will be able to program and understand basic C in very little time.
rust is different. Even if you are an experienced programmer you will encounter new concepts and patterns.
If you just want to learn a language for the fun of it, I would still start with C.
Learn rust, if you want to create "real" programs.
That is all very nice, but hardly anyone is writing original software in Rust. Most people use c2rust to steal C projects that are than unsafe Rust and 30% slower than the originals.
It is really the most uncreative and morally corrupt community in existence.
This is by far my most long-awaited Rust release! The kind of “memory safety” I fight with most in Systems Programming isn’t use-after-free, but keeping things running under memory starvation. Having standard containers abort on allocation failure always seemed wrong to me, especially in an ecosystem that got so many other things right!
Huge thanks to everyone making this happen! I’ve only been on the consuming end so far, but hopefully I’ll find something useful to contribute myself. Pointer provenance might be a nice next challenge :)
67 comments
[ 217 ms ] story [ 365 ms ] threadAs this release seems to include breaking changes, shouldn't the major version number have been bumped, as per semver?
Has the Rust book(s) been updated to include the new APIs?
"We reserve the right to fix compiler bugs, patch safety holes, and change type inference in ways that may occasionally require new type annotations."
https://blog.rust-lang.org/2014/10/30/Stability/#what-are-th...
The breakage in question here falls under changes to type inference, which are allowed within reason when they're relatively minor, when steps have been taken to mitigate any breakage in the broader ecosystem, and when the compiler has emitted warnings regarding the imminent change during a grace period, all of which have been done here.
Is that the raven that says Ni?
https://www.youtube.com/watch?v=bLiXjaPqSyY
So I wonder what programming languages should optimize for nowadays. Probably there's still something to be gained in developing Rust further, because its verifiable structure makes it mesh nicely with LLMs and helps them write code, but less so with more high level languages.
Why is that? It seems like that makes min-publish-age much less effective.
When we added the MSRV aware resolver, we decided to have it not affect `cargo install` because you could get an old version and not notice (especially with how noisy cargo is) when the right answer might be to upgrade.
Somewhat similar for min-publish-age but also we had defined the parent table for these config fields to not affect install.
The change to `--locked` made us feel a little better with this non-ideal circumstance.
For comparison, C has had, say, 4 versions, and C++ 7 had versions (depending on how you count). But - Java has had 27 main versions and probably more than a 100 if you count minor versions/updates.
Even ignoring K&R C there is C89, C99, C11, C17, C23 and C2y is in progress. I don't see any way to squint at that and count four.
Last time I checked between a quarter and a third had a patch release, and those are closer to a signal of "a minor release had a problem". When analysing those my conclusion and the time was "for the most part they were needed because some niche feature or platform had a regression that wasn't caught by the suite and a handful of regressions causes by enabling a new feature or updating llvm".
Even Rust Editions are not a good point of comparison because they are also time based and only leveraged by things that would otherwise be breaking changes.
What you could use for direct comparison is accepted Rust RFCs against accepted C++ proposals papers or the equivalent for other languages. Or merged Pull/Merge Request counts for the different tool chains. But that's not perfect either (Rust only supports one language, while GCC several, but it has a package manager, which GCC doesn't).
The version numbers are not comparable, because Rust bundles compiler, package manager, standard library in one release.
Additionally, Rust the language makes incremental changes stabilising individual features when they're ready, instead of bottling them up into rare grand releases. So number of releases doesn't tell you rate of change. It's like slicing pizza into smaller slices doesn't make a bigger pizza.
(and what sibling comment mentioned)
At least from a quick skim of the comments it seems there's still some stuff that needs to be worked on on the LLVM side of things as well.
Is this good for AI vibecoding ?
Human intelligibility and coherence does not seem to matter any more, for current software development.
Only if your software is throwaway that no one uses.
It seems like the AI can really write safe types and fast, efficient code in rust that beats anything else.
I've moved basically all my projects over to it. And I don't really know how it compares to other fast languages. My personal langue preference was always for readable languages like Clojure or Ruby, but at this point I'm not reading any code and just want performance.
With agentic programming, (i) is a non-issue since LLMs have a very good grasp of the language, and it's no skin of your back, the agent is sweating it out with the compiler, not you, and (ii) is likely something you actually want.
I suspect it comes down to which other ecosystem you are coming from:
Python -> Rust: massive performance gains, type safety, much better concurrency
C++ -> Rust: much much better memory safety, much nicer compiler errors and warnings
Java -> Rust: better memory utilisation, non-null-able types (though I think recent Java versions facilitate this), better performance
But there are other language ecosystems where the gains become more subjective.
For eg. Golang -> Rust, I'd argue better "correctness", especially when concurrency is involved, but it's less pronounced than some of the other paths I mentioned above.
Tractable correctness is an underrated win at the scale of building enterprise solutions. But Rust also is a systems language, something that people had hoped from golang.
if code fails to compile, rustc will produce a very high quality error message 90% of the time (they can get pretty gnarly when you're doing something super tricky, but they're still very workable for agents). tests are a first class feature, so agents are able to spot check new features on the same turn you ask it to implement something new. documentation is also first class, and lots of libraries have excellent docs (read https://docs.rs/pyo3/0.30.1/pyo3/marker/struct.Python.html). the whole toolchain gives agents a lot to work with.
When that happens, please file a ticket. That's how the errors get good: we hear about when they aren't and then we fix them.
This is also true for humans! Rust/C/C++ are all about equally fast, but Rust is more productive for most people. The downside for humans is that Rust's learning curve is pretty steep, but that doesn't bother the LLMs.
Both C and C++ have a much steeper learning curve than many realize, just because the compilers let you get away with doing things that are fundamentally invalid (Undefined Behavior). Rust isn't actually much stricter, it just catches these problems at compile time.
Anyone capable of writing actually correct, standard-conforming C and C++ is mostly able to first-try the equivalent Rust code in almost all cases, because they are already thinking the same way that Rust requires you to think.
However, a significant portion of people who write both C and C++ don't realize that their code is full of UB - or worse, they don't care.
From a language perspective, the only new restriction in Rust compared to C++ is that mutable borrows (references) cannot overlap. Good C++ programmers are already avoiding this at all cost, because it's a mess to keep track of. When you actually do need it, Rust gives you the tools to build a safe abstraction.
EDIT: And to add, Rust is actually less restrictive in a few areas compared to C++. For example, Rust allows bitcasting between unrelated but compatible types (without going through char pointers).
* Very strong type system which helps catch bugs at compile time.
* The type system lets you enforce invariants, e.g. see the type state pattern and "make invalid states unrepresentable"
* The borrow checker encourages tree ownership which tends to be a less buggy structure than "anything can own anything" spaghetti you get in GC'd languages.
These give it an "if it compiles it works" character, that some other languages also have (e.g. Haskell), but most don't.
This was all well known before AI. I guess it's just more obvious to people that never tried Rust themselves.
It's not a proper solution. A malicious crate can just contain a time-based switching mechanism in order to be undetected some time (let's say a couple of months) in order to become widespread.
You always know that the package contents match the source code. And you can always add a dependency by just downloading its source code and putting it into a subdirectory. You don't have to go and set up a different build system for each library if you want to avoid the pre-built artifacts.
I have to choose: what would you recommend? I think C++ could be the perfect fit, but it keeps me out of Linux kernel development. With LLMs, is the safety advantage of Rust's borrow checker mitigated?
C++ is an extremely complex language with lots of features and libraries and mountains of code, but it's not necessarily easy to write or debug. Compiler warnings alone can be crazy, considering the templating feature is almost a compile-time turing complete language.
Rust has some (to me) ugly syntax, but it tries to avoid the footguns of C++ while maintaining its commitment to removing the classic C problems in safe code. It also tries to maintain "zero cost abstractions" that are easier to program, but don't impact execution speed, primarily by having a much smarter compiler than C or C++.
I'd learn Rust. C will be easy after that, and C++ may be unnecessary.
Don't worry, you can change your mind. If you end up learning a little of all 3, that's a good thing.
The time you spend analyzing which you should learn would be better spent learning the worst possible pick of the 3.
But don't feel too bad, I also procrastinate by analysis. Many of us do. :)
If you just want to learn a language for the fun of it, I would still start with C.
Learn rust, if you want to create "real" programs.
It is really the most uncreative and morally corrupt community in existence.
Huge thanks to everyone making this happen! I’ve only been on the consuming end so far, but hopefully I’ll find something useful to contribute myself. Pointer provenance might be a nice next challenge :)