Rust Blog: Posts

Rust Blog

Announcing rustup 1.29.0

The rustup team is happy to announce the release of rustup version 1.29.0.

Rustup is the recommended tool to install Rust, a programming language that empowers everyone to build reliable and efficient software.

What's new in rustup 1.29.0

Following the footsteps of many package managers in the pursuit of better toolchain installation performance, the headline of this release is that rustup has been enabled to download components concurrently and unpack during downloads in operations such as rustup update or rustup toolchain and to concurrently check for updates in rustup check, thanks to a GSoC 2025 project. This is by no means a trivial change so a long tail of issues might occur, please report them if you have found any!

Furthermore, rustup now officially supports the following host platforms:

  • sparcv9-sun-solaris
  • x86_64-pc-solaris

Also, rustup will start automatically inserting the right $PATH entries during rustup-init for the following shells, in addition to those already supported:

  • tcsh
  • xonsh

This release also comes with other quality-of-life improvements, to name a few:

  • When running rust-analyzer via a proxy, rustup will consider therust-analyzer binary from PATH when the rustup-managed one is not found.
    • This should be particularly useful if you would like to bring your ownrust-analyzer binary, e.g. if you use Neovim, Helix, etc. or are developing rust-analyzer itself.
  • Empty environment variables are now treated as unset. This should help with resetting configuration values to default when an override is present.
  • rustup check will use different exit codes based on whether new updates have been found: it will exit with 100 on any updates or 0 for no updates.

Furthermore, @FranciscoTGouveia has joined the team. He has shown his talent, enthusiasm and commitment to the project since the first interactions with rustup and has played a significant role in bring more concurrency to it, so we are thrilled to have him on board and are actively looking forward to what we can achieve together.

Further details are available in the changelog!

How to update

If you have a previous version of rustup installed, getting the new one is as easy as stopping any programs which may be using rustup (e.g. closing your IDE) and running:

$ rustup self update

Rustup will also automatically update itself at the end of a normal toolchain update:

$ rustup update

If you don't have it already, you can get rustup from the appropriate page on our website.

Rustup's documentation is also available in the rustup book.

Caveats

Rustup releases can come with problems not caused by rustup itself but just due to having a new release.

In particular, anti-malware scanners might block rustup or stop it from creating or copying files, especially when installing rust-docs which contains many small files.

Issues like this should be automatically resolved in a few weeks when the anti-malware scanners are updated to be aware of the new rustup release.

Thanks

Thanks again to all the contributors who made this rustup release possible!

Continue Reading…

Rust Blog

Announcing Rust 1.94.0

The Rust team is happy to announce a new version of Rust, 1.94.0. Rust is a programming language empowering everyone to build reliable and efficient software.

If you have a previous version of Rust installed via rustup, you can get 1.94.0 with:

$ rustup update stable

If you don't have it already, you can get rustup from the appropriate page on our website, and check out the detailed release notes for 1.94.0.

If you'd like to help us out by testing future releases, you might consider updating locally to use the beta channel (rustup default beta) or the nightly channel (rustup default nightly). Please report any bugs you might come across!

What's in 1.94.0 stable

Array windows

Rust 1.94 adds array_windows, an iterating method for slices. It works just like windows but with a constant length, so the iterator items are &[T; N] rather than dynamically-sized &[T]. In many cases, the window length may even be inferred by how the iterator is used!

For example, part of one 2016 Advent of Code puzzle is looking for ABBA patterns: "two different characters followed by the reverse of that pair, such as xyyx or abba." If we assume only ASCII characters, that could be written by sweeping windows of the byte slice like this:

fn has_abba(s: &str) -> bool {
    s.as_bytes()
        .array_windows()
        .any(|[a1, b1, b2, a2]| (a1 != b1) && (a1 == a2) && (b1 == b2))
}

The destructuring argument pattern in that closure lets the compiler infer that we want windows of 4 here. If we had used the older .windows(4) iterator, then that argument would be a slice which we would have to index manually, hoping that runtime bounds-checking will be optimized away.

Cargo config inclusion

Cargo now supports the include key in configuration files (.cargo/config.toml), enabling better organization, sharing, and management of Cargo configurations across projects and environments. These include paths may also be marked optional if they might not be present in some circumstances, e.g. depending on local developer choices.

# array of paths
include = [
    "frodo.toml",
    "samwise.toml",
]

# inline tables for more control
include = [
    { path = "required.toml" },
    { path = "optional.toml", optional = true },
]

See the full include documentation for more details.

TOML 1.1 support in Cargo

Cargo now parses TOML v1.1 for manifests and configuration files. See the TOML release notes for detailed changes, including:

  • Inline tables across multiple lines and with trailing commas
  • \xHH and \e string escape characters
  • Optional seconds in times (sets to 0)

For example, a dependency like this:

serde = { version = "1.0", features = ["derive"] }

... can now be written like this:

serde = {
    version = "1.0",
    features = ["derive"],
}

Note that using these features in Cargo.toml will raise your development MSRV (minimum supported Rust version) to require this new Cargo parser, and third-party tools that read the manifest may also need to update their parsers. However, Cargo automatically rewrites manifests on publish to remain compatible with older parsers, so it is still possible to support an earlier MSRV for your crate's users.

Stabilized APIs

These previously stable APIs are now stable in const contexts:

Other changes

Check out everything that changed in Rust, Cargo, and Clippy.

Contributors to 1.94.0

Many people came together to create Rust 1.94.0. We couldn't have done it without all of you. Thanks!

Continue Reading…

Rust Blog

2025 State of Rust Survey Results

Hello, Rust community!

Once again, the survey team is happy to share the results of the State of Rust survey, this year celebrating a round number - the 10th edition!

The survey ran for 30 days (from November 17th to December, 17th 2025) and collected 7156 responses, a slight decrease in responses compared to last year. In this blog post we will shine a light on some specific key findings. As usual, the full report is available for download.

| Survey | Started | Completed | Completion rate | Views | | ---------- | ----------- | ------------- | ------------------- | --------- | | 2024 | 9 450 | 7 310 | 77.4% | 13 564 | | 2025 | 9 389 | 7 156 | 76.2% | 20 397 |

Overall, the answers we received this year pretty closely match the results of last year, differences are often under a single percentage point. The number of respondents decreases slightly year over year. In 2025, we published multiple surveys (such as the Compiler Performance or Variadic Generics survey), which might have also contributed to less people answering this (longer) survey. We plan to discuss how (and whether) to combine the State of Rust survey with the ongoing work on the Rust Vision Doc.

Also to be noted that these numbers should be taken in context: we cannot extrapolate too much from a mere 7 000 answers and some optional questions have even less replies.

Let's point out some interesting pieces of data:

Screenshotting Rust use

Confirmed that people develop using the stable compiler and keep up with releases, trusting our stability and compatibility guarantees. On the other hand, people use nightly out of "necessity" (for example, something not yet stabilized). Compared to last year (link) we seem to have way less nightly users. This may not be a significant data point because we are looking at a sliding window of releases and differences could depend on many factors (for example, at a specific point in time we might have more downloads of the nightly compiler because of a highly anticipated feature).

One example might be the very popular let chains and async closures features, which were stabilized last year.

[PNG] [SVG] [Wordcloud of open answers]

[PNG] [SVG]

We are also interested to hear from (and grateful to) people not using Rust (or not anymore) when they tell us why they dropped the language. In most cases it seems to be a "see you again in the future" rather than a "goodbye".

[PNG] [SVG]

[PNG] [SVG] [Wordcloud of open answers]

Some specific topic we were interested in: how often people download crates using a git repository pinned in the Cargo.toml (something like foo = { git = "https://github.com/foo/bar" }).

[PNG] [SVG] [Wordcloud of open answers]

and if people actually find the output of --explain useful. Internal discussions hinted that we were not too sure about that but this graph contradicts our prior assumption. Seems like many Rust users actually do find compiler error code explanations useful.

[PNG] [SVG] [Wordcloud of open answers]

Challenges and wishes about Rust

We landed long-awaited features in 2025 (let chains and async closures) and the survey results show that they are indeed very popular and often used. That's something to celebrate! Now generic const expressions and improved trait methods are bubbling up in the charts as the most-wanted features. Most of the other desired features didn't change significantly.

[PNG] [SVG] [Wordcloud of open answers]

When asked about which non-trivial problems people encounter, little changes overall compared to 2024: resource usage (slow compile times and storage usage) is still up there. The debugging story slipped from 2nd to 4th place (~2pp). We just started a survey to learn more about it!

[PNG] [SVG] [Wordcloud of open answers]

Learning about Rust

Noticeable (within a ~3pp) flection in attendance for online and offline communities to learn about Rust (like meetups, discussion forums and other learning material). This hints at some people moving their questions to LLM tooling (as the word cloud for open answers suggests). Still, our online documentation is the preferred canonical reference, followed by studying the code itself.

[PNG] [SVG] [Wordcloud of open answers]

[PNG] [SVG]

Industry and community

Confirmed the hiring trend from organisations looking for more Rust developers. The steady growth may indicate a structural market presence of Rust in companies, codebases consolidate and the quantity of Rust code overall keeps increasing.

[PNG] [SVG]

As always we try to get a picture of the concerns about the future of Rust. Given the target group we are surveying, unsurprisingly the majority of respondents would like even more Rust! But at the same time concerns persist about the language becoming more and more complex.

Slight uptick for "developer and maintainers support". We know and we are working on it. There are ongoing efforts from RustNL (https://rustnl.org/fund) and on the Foundation side. Funding efforts should focus on retaining talents that otherwise would leave after some time of unpaid labor.

This graph is also a message to companies using Rust: please consider supporting Rust project contributors and authors of Rust crates that you use in your projects. Either by joining the Rust Foundation, by allowing some paid time of your employees to be spent on Rust projects you benefit from or by funding through other collect funds (like https://opencollective.com, https://www.thanks.dev and similar) or personal sponsorships (GitHub, Liberapay or similar personal donation boxes).

Trust in the Rust Foundation is improving, which is definitively good to hear.

[PNG] [SVG] [Wordcloud of open answers]

As a piece of trivia we ask people which tools they use when programming in Rust. The Zed editor did a remarkable jump upward in the preferences of our respondents (with Helix as a good second). Editors with agentic support are also on the rise (as the word cloud shows) and seems they are eroding the userbase of VSCode and IntelliJ, if we were to judge by the histogram.

We're happy to meet again those 11 developers still using Atom (hey 👋!) and we salute those attached to their classic editors choice like Emacs and Vim (or derivatives).

[PNG] [SVG] [Wordcloud of open answers]

And finally a small group photo (17%) of what some respondents wanted to share about themselves. These numbers should be read in context: 8% of the respondents to this survey identify as LGBTQ+ folks, 6% as women and so on. Even if these numbers are just slightly better than last year, taken in context they show a picture that a very very small percentage of marginalized groups of people make it to our project (we are doing still better than other tech communities!) and is a reminder that one of our core values is to strive to be a diverse and welcoming FOSS community for everyone. But this only comes if we work hard on effective outreach programs.

[PNG] [SVG]

Conclusions

Overall, no big surprises and a few trends confirmed.

If you want to dig more into details, feel free to download the PDF report.

We want once again to thank all the volunteers that helped shaping and translating this survey and to all the participants, who took the time to provide us a picture of the Rust community.

A look back

Since this year we publish a round number, if you fancy a trip down the memory lane here the blog posts with the past years' survey results:

Rust Blog

Rust debugging survey 2026

We're launching a Rust Debugging Survey.

Various issues with debugging Rust code are often mentioned as one of the biggest challenges that annoy Rust developers. While it is definitely possible to debug Rust code today, there are situations where it does not work well enough, and the quality of debugging support also varies a lot across different debuggers and operating systems.

In order for Rust to have truly stellar debugging support, it should ideally:

  • Support (several versions!) of different debuggers (such as GDB, LLDB or CDB) across multiple operating systems.
  • Implement debugger visualizers that are able to produce quality presentation of most Rust types.
  • Provide first-class support for debugging async code.
  • Allow evaluating Rust expressions in the debugger.

Rust is not quite there yet, and it will take a lot of work to reach that level of debugger support. Furthermore, it is also challenging to ensure that debugging Rust code keeps working well, across newly released debugger versions, changes to internal representation of Rust data structures in the standard library and other things that can break the debugging experience.

We already have some plans to start improving debugging support in Rust, but it would also be useful to understand the current debugging struggles of Rust developers. That is why we have prepared the Rust Debugging Survey, which should help us find specific challenges with debugging Rust code.

You can fill out the survey here.

Filling the survey should take you approximately 5 minutes, and the survey is fully anonymous. We will accept submissions until Friday, March 13th, 2026. After the survey ends, we will evaluate the results and post key insights on this blog.

We would like to thank Sam Kellam (@hashcatHitman) who did a lot of great work to prepare this survey.

We invite you to fill the survey, as your responses will help us improve the Rust debugging experience. Thank you!

Continue Reading…

Rust Blog

Rust participates in Google Summer of Code 2026

We are happy to announce that the Rust Project will again be participating in Google Summer of Code (GSoC) 2026, same as in the previous two years. If you're not eligible or interested in participating in GSoC, then most of this post likely isn't relevant to you; if you are, this should contain some useful information and links.

Google Summer of Code (GSoC) is an annual global program organized by Google that aims to bring new contributors to the world of open-source. The program pairs organizations (such as the Rust Project) with contributors (usually students), with the goal of helping the participants make meaningful open-source contributions under the guidance of experienced mentors.

The organizations that have been accepted into the program have been announced by Google. The GSoC applicants now have several weeks to discuss project ideas with mentors. Later, they will send project proposals for the projects that they found the most interesting. If their project proposal is accepted, they will embark on a several months long journey during which they will try to complete their proposed project under the guidance of an assigned mentor.

We have prepared a list of project ideas that can serve as inspiration for potential GSoC contributors that would like to send a project proposal to the Rust organization. However, applicants can also come up with their own project ideas. You can discuss project ideas or try to find mentors in the #gsoc Zulip stream. We have also prepared a proposal guide that should help you with preparing your project proposals. We would also like to bring your attention to our GSoC AI policy.

You can start discussing the project ideas with Rust Project mentors and maintainers immediately, but you might want to keep the following important dates in mind:

  • The project proposal application period starts on March 16, 2026. From that date you can submit project proposals into the GSoC dashboard.
  • The project proposal application period ends on March 31, 2026 at 18:00 UTC. Take note of that deadline, as there will be no extensions!

If you are interested in contributing to the Rust Project, we encourage you to check out our project idea list and send us a GSoC project proposal! Of course, you are also free to discuss these projects and/or try to move them forward even if you do not intend to (or cannot) participate in GSoC. We welcome all contributors to Rust, as there is always enough work to do.

Our GSoC contributors were quite successful in the past two years (2024, 2025), so we are excited what this year's GSoC will bring! We hope that participants in the program can improve their skills, but also would love for this to bring new contributors to the Project and increase the awareness of Rust in general. Like last year, we expect to publish blog posts in the future with updates about our participation in the program.

Continue Reading…

Rust Blog

crates.io: an update to the malicious crate notification policy

The crates.io team will no longer publish a blog post each time a malicious crate is detected or reported. In the vast majority of cases to date, these notifications have involved crates that have no evidence of real world usage, and we feel that publishing these blog posts is generating noise, rather than signal.

We will always publish a RustSec advisory when a crate is removed for containing malware. You can subscribe to the RustSec advisory RSS feed to receive updates.

Crates that contain malware and are seeing real usage or exploitation will still get both a blog post and a RustSec advisory. We may also notify via additional communication channels (such as social media) if we feel it is warranted.

Recent crates

Since we are announcing this policy change now, here is a retrospective summary of the malicious crates removed since our last blog post and today:

  • finch_cli_rust, finch-rst, and sha-rst: the Rust security response working group was notified on December 9th, 2025 by Matthias Zepper of National Genomics Infrastructure Sweden that these crates were attempting to exfiltrate credentials by impersonating the finch and finch_cli crates. Advisories: RUSTSEC-2025-0150, RUSTSEC-2025-0151, RUSTSEC-2025-0152.
  • polymarket-clients-sdk: we were notified on February 6th by Socket that this crate was attempting to exfiltrate credentials by impersonating the polymarket-client-sdk crate. Advisory: RUSTSEC-2026-0010.
  • polymarket-client-sdks: we were notified on February 13th that this crate was attempting to exfiltrate credentials by impersonating the polymarket-client-sdk crate. Advisory: RUSTSEC-2026-0011.

In all cases, the crates were deleted, the user accounts that published them were immediately disabled, and reports were made to upstream providers as appropriate.

Thanks

Once again, our thanks go to Matthias, Socket, and the reporter of polymarket-client-sdks for their reports. We also want to thank Dirkjan Ochtman from the secure code working group, Emily Albini from the security response working group, and Walter Pearce from the Rust Foundation for aiding in the response.

Continue Reading…

Rust Blog

Announcing Rust 1.93.1

The Rust team has published a new point release of Rust, 1.93.1. Rust is a programming language that is empowering everyone to build reliable and efficient software.

If you have a previous version of Rust installed via rustup, getting Rust 1.93.1 is as easy as:

rustup update stable

If you don't have it already, you can get rustup from the appropriate page on our website.

What's in 1.93.1

Rust 1.93.1 resolves three regressions that were introduced in the 1.93.0 release.

Contributors to 1.93.1

Many people came together to create Rust 1.93.1. We couldn't have done it without all of you. Thanks!

Continue Reading…

Rust Blog

Announcing Rust 1.93.0

The Rust team is happy to announce a new version of Rust, 1.93.0. Rust is a programming language empowering everyone to build reliable and efficient software.

If you have a previous version of Rust installed via rustup, you can get 1.93.0 with:

$ rustup update stable

If you don't have it already, you can get rustup from the appropriate page on our website, and check out the detailed release notes for 1.93.0.

If you'd like to help us out by testing future releases, you might consider updating locally to use the beta channel (rustup default beta) or the nightly channel (rustup default nightly). Please report any bugs you might come across!

What's in 1.93.0 stable

Update bundled musl to 1.2.5

The various *-linux-musl targets now all ship with musl 1.2.5. This primarily affects static musl builds for x86_64, aarch64, and powerpc64le which bundled musl 1.2.3. This update comes with several fixes and improvements, and a breaking change that affects the Rust ecosystem.

For the Rust ecosystem, the primary motivation for this update is to receive major improvements to musl's DNS resolver which shipped in 1.2.4 and received bug fixes in 1.2.5. When using musltargets for static linking, this should make portable Linux binaries that do networking more reliable, particularly in the face of large DNS records and recursive nameservers.

However, 1.2.4 also comes with a breaking change: the removal of several legacy compatibility symbols that the Rust libc crate was using. A fix for this was shipped in libc 0.2.146 in June 2023 (2.5 years ago), and we believe has sufficiently widely propagated that we're ready to make the change in Rust targets.

See our previous announcement for more details.

Allow the global allocator to use thread-local storage

Rust 1.93 adjusts the internals of the standard library to permit global allocators written in Rust to use std's thread_local! andstd::thread::current without re-entrancy concerns by using the system allocator instead.

See docs for details.

cfg attributes on asm! lines

Previously, if individual parts of a section of inline assembly needed to be cfg'd, the full asm!block would need to be repeated with and without that section. In 1.93, cfg can now be applied to individual statements within the asm! block.

asm!( // or global_asm! or naked_asm!
    "nop",
    #[cfg(target_feature = "sse2")]
    "nop",
    // ...
    #[cfg(target_feature = "sse2")]
    a = const 123, // only used on sse2
);

Stabilized APIs

Other changes

Check out everything that changed in Rust, Cargo, and Clippy.

Contributors to 1.93.0

Many people came together to create Rust 1.93.0. We couldn't have done it without all of you. Thanks!

Continue Reading…

Rust Blog

crates.io: development update

Time flies! Six months have passed since our last crates.io development update, so it's time for another one. Here's a summary of the most notable changes and improvements made to crates.io over the past six months.

Security Tab

Crate pages now have a new "Security" tab that displays security advisories from the RustSec database. This allows you to quickly see if a crate has known vulnerabilities before adding it as a dependency.

Security Tab Screenshot

The tab shows known vulnerabilities for the crate along with the affected version ranges.

This feature is still a work in progress, and we plan to add more functionality in the future. We would like to thank the OpenSSF (Open Source Security Foundation) for funding this work and Dirkjan Ochtman for implementing it.

Trusted Publishing Enhancements

In our July 2025 update, we announced Trusted Publishing support for GitHub Actions. Since then, we have made several enhancements to this feature.

GitLab CI/CD Support

Trusted Publishing now supports GitLab CI/CD in addition to GitHub Actions. This allows GitLab users to publish crates without managing API tokens, using the same OIDC-based authentication flow.

Note that this currently only works with GitLab.com. Self-hosted GitLab instances are not supported yet. The crates.io implementation has been refactored to support multiple CI providers, so adding support for other platforms like Codeberg/Forgejo in the future should be straightforward. Contributions are welcome!

Trusted Publishing Only Mode

Crate owners can now enforce Trusted Publishing for their crates. When enabled in the crate settings, traditional API token-based publishing is disabled, and only Trusted Publishing can be used to publish new versions. This reduces the risk of unauthorized publishes from leaked API tokens.

Blocked Triggers

The pull_request_target and workflow_run GitHub Actions triggers are now blocked from Trusted Publishing. These triggers have been responsible for multiple security incidents in the GitHub Actions ecosystem and are not worth the risk.

Source Lines of Code

Crate pages now display source lines of code (SLOC) metrics, giving you insight into the size of a crate before adding it as a dependency. This metric is calculated in a background job after publishing using the tokei crate. It is also shown on OpenGraph images:

OpenGraph image showing SLOC metric

Thanks to XAMPPRocky for maintaining the tokei crate!

Publication Time in Index

A new pubtime field has been added to crate index entries, recording when each version was published. This enables several use cases:

  • Cargo can implement cooldown periods for new versions in the future
  • Cargo can replay dependency resolution as if it were a past date, though yanked versions remain yanked
  • Services like Renovate can determine release dates without additional API requests

Thanks to Rene Leonhardt for the suggestion and Ed Page for driving this forward on the Cargo side.

Svelte Frontend Migration

At the end of 2025, the crates.io team evaluated several options for modernizing our frontend and decided to experiment with porting the website to Svelte. The goal is to create a one-to-one port of the existing functionality before adding new features.

This migration is still considered experimental and is a work in progress. Using a more mainstream framework should make it easier for new contributors to work on the frontend. The new Svelte frontend uses TypeScript and generates type-safe API client code from our OpenAPI description, so types flow from the Rust backend to the TypeScript frontend automatically.

Thanks to eth3lbert for the helpful reviews and guidance on Svelte best practices. We'll share more details in a future update.

Miscellaneous

These were some of the more visible changes to crates.io over the past six months, but a lot has happened "under the hood" as well.

  • Cargo user agent filtering: We noticed that download graphs were showing a constant background level of downloads even for unpopular crates due to bots, scrapers, and mirrors. Download counts are now filtered to only include requests from Cargo, providing more accurate statistics.
  • HTML emails: Emails from crates.io now support HTML formatting.
  • Encrypted GitHub tokens: OAuth access tokens from GitHub are now encrypted at rest in the database. While we have no evidence of any abuse, we decided to improve our security posture. The tokens were never included in the daily database dump, and the old unencrypted column has been removed.
  • Source link: Crate pages now display a "Browse source" link in the sidebar that points to the corresponding docs.rs page. Thanks to Carol Nichols for implementing this feature.
  • Fastly CDN: The sparse index at index.crates.io is now served primarily via Fastly to conserve our AWS credits for other use cases. In the past month, static.crates.io served approximately 1.6 PB across 11 billion requests, while index.crates.io served approximately 740 TB across 19 billion requests. A big thank you to Fastly for providing free CDN services through their Fast Forward program!
  • OpenGraph image improvements: We fixed emoji and CJK character rendering in OpenGraph images, which was caused by missing fonts on our server.
  • Background worker performance: Database indexes were optimized to improve background job processing performance.
  • CloudFront invalidation improvements: Invalidation requests are now batched to avoid hitting AWS rate limits when publishing large workspaces.

Feedback

We hope you enjoyed this update on the development of crates.io. If you have any feedback or questions, please let us know on Zulip or GitHub. We are always happy to hear from you and are looking forward to your feedback!

Rust Blog

What does it take to ship Rust in safety-critical?

This is another post in our series covering what we learned through the Vision Doc process. In our first post, we described the overall approach and what we learned about doing user research. In our second post, we explored what people love about Rust. This post goes deep on one domain: safety-critical software.

When we set out on the Vision Doc work, one area we wanted to explore in depth was safety-critical systems: software where malfunction can result in injury, loss of life, or environmental harm. Think vehicles, airplanes, medical devices, industrial automation. We spoke with engineers at OEMs, integrators, and suppliers across automotive (mostly), industrial, aerospace, and medical contexts.

What we found surprised us a bit. The conversations kept circling back to a single tension: Rust's compiler-enforced guarantees support much of what Functional Safety Engineers and Software Engineers in these spaces spend their time preventing, but once you move beyond prototyping into the higher-criticality parts of a system, the ecosystem support thins out fast. There is no MATLAB/Simulink Rust code generation. There is no OSEK or AUTOSAR Classic-compatible RTOS written in Rust or with first-class Rust support. The tooling for qualification and certification is still maturing.

Quick context: what makes software "safety-critical"

If you've never worked in these spaces, here's the short version. Each safety-critical domain has standards that define a ladder of integrity levels: ISO 26262 in automotive, IEC 61508 in industrial, IEC 62304 in medical devices, DO-178C in aerospace. The details differ, but the shape is similar: as you climb the ladder toward higher criticality, the demands on your development process, verification, and evidence all increase, and so do the costs.1

This creates a strong incentive for decomposition: isolate the highest-criticality logic into the smallest surface area you can, and keep everything else at lower levels where costs are more manageable and you can move faster.

We'll use automotive terminology in this post (QM through ASIL D) since that's where most of our interviews came from, but the patterns generalize. These terms represent increasing levels of safety-criticality, with QM being the lowest and ASIL D being the highest. The story at low criticality looks very different from the story at high criticality, regardless of domain.

Rust is already in production for safety-critical systems

Before diving into the challenges, it is worth noting that Rust is not just being evaluated in these domains. It is deployed and running in production.

We spoke with a principal firmware engineer working on mobile robotics systems certified to IEC 61508 SIL 2:

"We had a new project coming up that involved a safety system. And in the past, we'd always done these projects in C using third party stack analysis and unit testing tools that were just generally never very good, but you had to do them as part of the safety rating standards. Rust presented an opportunity where 90% of what the stack analysis stuff had to check for is just done by the compiler. That combined with the fact that now we had a safety qualified compiler to point to was kind of a breakthrough." -- Principal Firmware Engineer (mobile robotics)

We also spoke with an engineer at a medical device company deploying IEC 62304 Class B software to intensive care units:

"All of the product code that we deploy to end users and customers is currently in Rust. We do EEG analysis with our software and that's being deployed to ICUs, intensive care units, and patient monitors." -- Rust developer at a medical device company

"We changed from this Python component to a Rust component and I think that gave us a 100-fold speed increase." -- Rust developer at a medical device company

These are not proofs of concept. They are shipping systems in regulated environments, going through audits and certification processes. The path is there. The question is how to make it easier for the next teams coming through.

Rust adoption is easiest at QM, and the constraints sharpen fast

At low criticality, teams described a pragmatic approach: use Rust and the crates ecosystem to move quickly, then harden what you ship. One architect at an automotive OEM told us:

"We can use any crate [from crates.io] [..] we have to take care to prepare the software components for production usage." -- Architect at Automotive OEM

But at higher levels, third-party dependencies become difficult to justify. Teams either rewrite, internalize, or strictly constrain what they use. An embedded systems engineer put it bluntly:

"We tend not to use 3rd party dependencies or nursery crates [..] solutions become kludgier as you get lower in the stack." -- Firmware Engineer

Some teams described building escape hatches, abstraction layers designed for future replacement:

"We create an interface that we'd eventually like to have to simplify replacement later on [..] sometimes rewrite, but even if re-using an existing crate we often change APIs, write more tests." -- Team Lead at Automotive Supplier (ASIL D target)

Even teams that do use crates from crates.io described treating that as a temporary accelerator, something to track carefully and remove from critical paths before shipping:

"We use crates mainly for things in the beginning where we need to set up things fast, proof of concept, but we try to track those dependencies very explicitly and for the critical parts of the software try to get rid of them in the long run." -- Team lead at an automotive software company developing middleware in Rust

In aerospace, the "control the whole stack" instinct is even stronger:

"In aerospace there's a notion of we must own all the code ourselves. We must have control of every single line of code." -- Engineering lead in aerospace

This is the first big takeaway: a lot of "Rust in safety-critical" is not just about whether Rust compiles for a target. It is about whether teams can assemble an evidence-friendly software stack and keep it stable over long product lifetimes.

The compiler is doing work teams used to do elsewhere

Many interviewees framed Rust's value in terms of work shifted earlier and made more repeatable by the compiler. This is not just "nice," it changes how much manual review you can realistically afford. Much of what was historically process-based enforcement through coding standards like MISRA C and CERT C becomes a language-level concern in Rust, checked by the compiler rather than external static analysis or manual review.

"Roughly 90% of what we used to check with external tools is built into Rust's compiler." -- Principal Firmware Engineer (mobile robotics)

We heard variations of this from teams dealing with large codebases and varied skill levels:

"We cannot control the skill of developers from end to end. We have to check the code quality. Rust by checking at compile time, or Clippy tools, is very useful for our domain." -- Engineer at a major automaker

Even on smaller teams, the review load matters:

"I usually tend to work on teams between five and eight. Even so, it's too much code. I feel confident moving faster, a certain class of flaws that you aren't worrying about." -- Embedded systems engineer (mobile robotics)

Closely related: people repeatedly highlighted Rust's consistency around error handling:

"Having a single accepted way of handling errors used throughout the ecosystem is something that Rust did completely right." -- Automotive Technical Lead

For teams building products with 15-to-20-year lifetimes and "teams of teams," compiler-enforced invariants scale better than "we will just review harder."

Teams want newer compilers, but also stability they can explain

A common pattern in safety-critical environments is conservative toolchain selection. But engineers pointed out a tension: older toolchains carry their own defect history.

"[..] traditional wisdom is that after something's been around and gone through motions / testing then considered more stable and safer [..] older compilers used tend to have more bugs [and they become] hard to justify" -- Software Engineer at an Automotive supplier

Rust's edition system was described as a real advantage here, especially for incremental migration strategies that are common in automotive programs:

"[The edition system is] golden for automotive, where incremental migration is essential." -- Software Engineer at major Automaker

In practice, "stability" is also about managing the mismatch between what the platform supports and what the ecosystem expects. Teams described pinning Rust versions, then fighting dependency drift:

"We can pin the Rust toolchain, but because almost all crates are implemented for the latest versions, we have to downgrade. It's very time-consuming." -- Engineer at a major automaker

For safety-critical adoption, "stability" is operational. Teams need to answer questions like: What does a Rust upgrade change, and what does it not change? What are the bounds on migration work? How do we demonstrate we have managed upgrade risk?

Target support matters in practical ways

Safety-critical software often runs on long-lived platforms and RTOSs. Even when "support exists," there can be caveats. Teams described friction around targets like QNX, where upstream Rust support exists but with limitations (for example, QNX 8.0 support is currently no_std only).2

This connects to Rust's target tier policy: the policy itself is clear, but regulated teams still need to map "tier" to "what can I responsibly bet on for this platform and this product lifetime."

"I had experiences where all of a sudden I was upgrading the compiler and my toolchain and dependencies didn't work anymore for the Tier 3 target we're using. That's simply not acceptable. If you want to invest in some technology, you want to have a certain reliability." -- Senior software engineer at a major automaker

core is the spine, and it sets expectations

In no_std environments, core becomes the spine of Rust. Teams described it as both rich enough to build real products and small enough to audit.

A lot of Rust's safety leverage lives there: Option and Result, slices, iterators, Cell and RefCell, atomics, MaybeUninit, Pin. But we also heard a consistent shape of gaps: many embedded and safety-critical projects want no_std-friendly building blocks (fixed-size collections, queues) and predictable math primitives, but do not want to rely on "just any" third-party crate at higher integrity levels.

"Most of the math library stuff is not in core, it's in std. Sin, cosine... the workaround for now has been the libm crate. It'd be nice if it was in core." -- Principal Firmware Engineer (mobile robotics)

Async is appealing, but the long-run story is not settled

Some safety-critical-adjacent systems are already heavily asynchronous: daemons, middleware frameworks, event-driven architectures. That makes Rust's async story interesting.

But people also expressed uncertainty about ecosystem lock-in and what it would take to use async in higher-criticality components. One team lead developing middleware told us:

"We're not sure how async will work out in the long-run [in Rust for safety-critical]. [..] A lot of our software is highly asynchronous and a lot of our daemons in the AUTOSAR Adaptive Platform world are basically following a reactor pattern. [..] [C++14] doesn't really support these concepts, so some of this is lack of familiarity." -- Team lead at an automotive software company developing middleware in Rust

And when teams look at async through an ISO 26262 lens, the runtime question shows up immediately:

"If we want to make use of async Rust, of course you need some runtime which is providing this with all the quality artifacts and process artifacts for ISO 26262." -- Team lead at an automotive software company developing middleware in Rust

Async is not "just a language feature" in safety-critical contexts. It pulls in runtime choices, scheduling assumptions, and, at higher integrity levels, the question of what it would mean to certify or qualify the relevant parts of the stack.

Recommendations

Find ways to help the safety-critical community support their own needs. Open source helps those who help themselves. The Ferrocene Language Specification (FLS) shows this working well: it started as an industry effort to create a specification suitable for safety-qualification of the Rust compiler, companies invested in the work, and it now has a sustainable home under the Rust Project with a team actively maintaining it.3

Contrast this with MC/DC coverage support in rustc. Earlier efforts stalled due to lack of sustained engagement from safety-critical companies.4 The technical work was there, but without industry involvement to help define requirements, validate the implementation, and commit to maintaining it, the effort lost momentum. A major concern was that the MC/DC code added maintenance burden to the rest of the coverage infrastructure without a clear owner. Now in 2026, there is renewed interest in doing this the right way: companies are working through the Safety-Critical Rust Consortium to create a Rust Project Goal in 2026 to collaborate with the Rust Project on MC/DC support. The model is shared ownership of requirements, with primary implementation and maintenance done by companies with a vested interest in safety-critical, done in a way that does not impede maintenance of the rest of the coverage code.

The remaining recommendations follow this pattern: the Safety-Critical Rust Consortium can help the community organize requirements and drive work, with the Rust Project providing the deep technical knowledge of Rust Project artifacts needed for successful collaboration. The path works when both sides show up.

Establish ecosystem-wide MSRV conventions. The dependency drift problem is real: teams pin their Rust toolchain for stability, but crates targeting the latest compiler make this difficult to sustain. An LTS release scheme, combined with encouraging libraries to maintain MSRV compatibility with LTS releases, could reduce this friction. This would require coordination between the Rust Project (potentially the release team) and the broader ecosystem, with the Safety-Critical Rust Consortium helping to articulate requirements and adoption patterns.

Turn "target tier policy" into a safety-critical onramp. The friction we heard is not about the policy being unclear, it is about translating "tier" into practical decisions. A short, target-focused readiness checklist would help: Which targets exist? Which ones are no_std only? What is the last known tested OS version? What are the top blockers? The raw ingredients exist in rustc docs, release notes, and issue trackers, but pulling them together in one place would lower the barrier. Clearer, consolidated information also makes it easier for teams who depend on specific targets to contribute to maintaining them. The Safety-Critical Rust Consortium could lead this effort, working with compiler team members and platform maintainers to keep the information accurate.

Document "dependency lifecycle" patterns teams are already using. The QM story is often: use crates early, track carefully, shrink dependencies for higher-criticality parts. The ASIL B+ story is often: avoid third-party crates entirely, or use abstraction layers and plan to replace later. Turning those patterns into a reusable playbook would help new teams make the same moves with less trial and error. This seems like a natural fit for the Safety-Critical Rust Consortium's liaison work.

Define requirements for a safety-case friendly async runtime. Teams adopting async in safety-critical contexts need runtimes with appropriate quality and process artifacts for standards like ISO 26262. Work is already happening in this space.5 The Safety-Critical Rust Consortium could lead the effort to define what "safety-case friendly" means in concrete terms, working with the async working group and libs team on technical feasibility and design.

Treat interop as part of the safety story. Many teams are not going to rewrite their world in Rust. They are going to integrate Rust into existing C and C++ systems and carry that boundary for years. Guidance and tooling to keep interfaces correct, auditable, and in sync would help. The compiler team and lang team could consider how FFI boundaries are surfaced and checked, informed by requirements gathered through the Safety-Critical Rust Consortium.

"We rely very heavily on FFI compatibility between C, C++, and Rust. In a safety-critical space, that's where the difficulty ends up being, generating bindings, finding out what the problem was." -- Embedded systems engineer (mobile robotics)

Conclusion

To sum up the main points in this post:

  • Rust is already deployed in production for safety-critical systems, including mobile robotics (IEC 61508 SIL 2) and medical devices (IEC 62304 Class B). The path exists.
  • Rust's defaults (memory safety, thread safety, strong typing) map directly to much of what Functional Safety Engineers spend their time preventing. But ecosystem support thins out as you move toward higher-criticality software.
  • At low criticality (QM), teams use crates freely and harden later. At higher levels (ASIL B+), third-party dependencies become difficult to justify, and teams rewrite, internalize, or build abstraction layers for future replacement.
  • The compiler is doing work that used to require external tools and manual review. Much of what was historically process-based enforcement through standards like MISRA C and CERT C becomes a language-level concern, checked by the compiler. That can scale better than "review harder" for long-lived products with large teams and supports engineers in these domains feeling more secure in the systems they ship.
  • Stability is operational: teams need to explain what upgrades change, manage dependency drift, and map target tier policies to their platform reality.
  • Async is appealing for middleware and event-driven systems, but the runtime and qualification story is not settled for higher-criticality use.

We make six recommendations: find ways to help the safety-critical community support their own needs, establish ecosystem-wide MSRV conventions, create target-focused readiness checklists, document dependency lifecycle patterns, define requirements for safety-case friendly async runtimes, and treat C/C++ interop as part of the safety story.

Get involved

If you're working in safety-critical Rust, or you want to help make it easier, check out the Rust Foundation's Safety-Critical Rust Consortium and the in-progress Safety-Critical Rust coding guidelines.

Hearing concrete constraints, examples of assessor feedback, and what "evidence" actually looks like in practice is incredibly helpful. The goal is to make Rust's strengths more accessible in environments where correctness and safety are not optional.

  1. If you're curious about how rigor scales with cost in ISO 26262, this Feabhas guide gives a good high-level overview.
  2. See the QNX target documentation for current status.
  3. The FLS team was created under the Rust Project in 2025. The team is now actively maintaining the specification, reviewing changes and keeping the FLS in sync with language evolution.
  4. See the MC/DC tracking issue for context. The initial implementation was removed due to maintenance concerns.
  5. Eclipse SDV's Eclipse S-CORE project includes an Orchestrator written in Rust for their async runtime, aimed at safety-critical automotive software.

Continue Reading…

Rust Blog

What do people love about Rust?

Rust has been named Stack Overflow's Most Loved (now called Most Admired) language every year since our 1.0 release in 2015. That means people who use Rust want to keep using Rust1--and not just for performance-heavy stuff or embedded development, but for shell scripts, web apps, and all kinds of things you wouldn't expect. One of our participants captured it well when they said, "At this point, I don't want to write code in any other language but Rust."

When we sat down to crunch the vision doc data, one of the things we really wanted to explain was: What is it that inspires that strong loyalty to Rust?2 Based on the interviews, the answer is at once simple and complicated. The short version is that Rust empowers them to write reliable and efficient software. If that sounds familiar, it should: it's the slogan that we have right there on our web page. The more interesting question is how that empowerment comes about, and what it implies for how we evolve Rust.

What do people appreciate about Rust?

The first thing we noticed is that, throughout every conversation, no matter whether someone is writing their first Rust program or has been using it for years, no matter whether they're building massive data clusters or embedded devices or just messing around, there are a consistent set of things that they say they like about Rust.

The first is reliability. People love that "if it compiles, it works" feeling:

"What I really love about Rust is that if it compiles it usually runs. That is fantastic, and that is something that I'm not used to in Java." -- Senior software engineer working in automotive embedded systems

"Rust is one of those languages that has just got your back. You will have a lot more sleep and you actually have to be less clever." -- Rust consultant and open source framework developer

Another, of course, is efficiency. This comes up in particular at the extremes, both very large scale (data centers) and very small scale (embedded):

"I want to keep the machine resources there for the [main] computation. Not stealing resources for a watchdog." -- Software engineer working on data science platforms

"You also get a speed benefit from using Rust. For example, [..] just the fact that we changed from this Python component to a Rust component gave us a 100fold speed increase." -- Rust developer at a medical device startup

Efficiency comes up particularly often when talking to customers running "at-scale" workloads, where even small performance wins can translate into big cost savings:

"We have a library -- effectively it's like an embedded database -- that we deploy on lots of machines. It was written in Java and we recently rewrote it from Java to Rust and we got close to I think 9x to 10x performance wins." -- Distinguished engineer working on cloud infrastructure services

"I'm seeing 4x efficiency in the same module between Java code that loads a VM and Rust. That's a lot of money you save in data center cost." -- Backend engineering company founder specializing in financial services

At the other end of the spectrum, people doing embedded development or working at low-levels of abstraction highlight Rust's ability to give low-level control and access to system details:

"Rust was that replacement for C I'd been looking for forever." -- Backend engineering company founder specializing in financial services

"If you're going to write something new and you do kind of low-level systemsy stuff, I think Rust is honestly the only real choice." -- Distinguished engineer

Many people cite the importance of Rust's supportive tooling, which helps them get up and going quickly, and in particular the compiler's error messages:

"I think a big part of why I was able to succeed at learning Rust is the tooling. For me, getting started with Rust, the language was challenging, but the tooling was incredibly easy." -- Executive at a developer tools company

"The tooling really works for me and works for us. The number one way that I think I engage with Rust is through its tooling ecosystem. I build my code through Cargo. I test it through Cargo. We rely on Clippy for everything." -- Embedded systems engineer working on safety-critical robotics

"I think the error messages and suggestions from the Rust compiler are super helpful also." -- Professor specializing in formal verification

Finally, one of Rust's most important virtues is its extensibility. Both in the language itself and through the crates.io ecosystem, Rust is designed to let end-users create libraries and abstractions that meet their needs:

"The crate ecosystem combined with the stability guarantees and the semantic versioning mean that it's the best grab and go ecosystem I've ever seen." -- Computer science professor and programming language designer

"I think proc macros are a really big superpower for Rust." -- Creator and maintainer of Rust networking libraries

"Rust is incredibly good at making it very very easy to get started, to reuse things, just to experiment quickly with new tools, new libraries, all the rest of it... so for me, as an experimentation platform, it's great." -- Rust expert and consultant focused on embedded and real-time systems

But what they love is the sense of empowerment and versatility

Reliability, efficiency, tooling, ecosystem—these are all things that people appreciate about Rust. But what they love isn't any one of those things. It's the way the combination makes Rust a trusted, versatile tool that you can bring to virtually any problem:

"When I got to know about it, I was like 'yeah this is the language I've been looking for'. This is the language that will just make me stop thinking about using C and Python. So I just have to use Rust because then I can go as low as possible as high as possible." -- Software engineer and community organizer in Africa

"I wanted a language that works well from top to bottom in a stacking all the way from embedded to very fancy applications" -- Computer science professor and programming language designer

"If [Rust] is going to try and sort of sell itself more in any particular way, I would probably be saying high performance, highly expressive, general purpose language, with the great aspect that you can write everything from the top to the bottom of your stack in it." -- Rust expert and consultant focused on embedded and real-time systems

Each piece is necessary for the whole to work

Take away the reliability, and you don't trust it: you're second-guessing every deployment, afraid to refactor, hesitant to let junior developers touch the critical paths.

"Rust just lowers that bar. It's a lot easier to write correct Rust code. As a leader on the team, I feel a lot safer when we have less experienced engineers contributing to these critical applications." -- Distinguished engineer working on cloud infrastructure services

"My experience with writing Rust software tends to be once you've got it working, it stays working. That's a combination of a lot of care taken in terms of backwards compatibility with the language and a lot of care taken around the general ecosystem." -- Rust expert and consultant focused on embedded and real-time systems

Reliability also provides guardrails that help people enter new domains—whether you're a beginner learning the ropes or an expert venturing into unfamiliar territory:

"Rust introduces you to all these things, like match and all these really nice functional programming methods." -- Software engineer with production Rust experience

"I think Rust ownership discipline is useful both for regular Rust programmers and also for verification. I think it allows you to within the scope of your function to know very clearly what you're modifying, what's not being modified, what's aliased and what's not aliased." -- Professor specializing in formal verification

"I discovered Rust... and was basically using it just to give myself a little bit more confidence being like a solo firmware developer" -- Software engineer working on automotive digital cockpit systems

Take away the efficiency and low-level control, and there are places you can't go: embedded systems, real-time applications, anywhere that cost-per-cycle matters.

"The performance in Rust is nutty. It is so much better and it's safe. When we rewrote C++ and C libraries or C applications into Rust, they would end up being faster because Rust was better at laying out memory." -- Senior Principal Engineer leading consumer shopping experiences

"9 times out of 10, I write microcontroller code and I only test it through unit testing. I put it on real hardware and it just works the first time." -- Embedded systems engineer working on safety-critical robotics

"I can confidently build systems that scale." -- Engineering manager with 20 years experience in media and streaming platforms

Take away the tooling and ecosystem, and you can't get started: or you can, but it's a slog, and you never feel productive.

"For me, getting started with Rust, the language was challenging, but the tooling was incredibly easy... I could just start writing code and it would build and run, and that to me made a huge difference." -- Founder and CEO of company creating developer tools

"Cargo is an amazing package manager. It is probably the best one I've ever worked with. I don't think I ever run into issues with Cargo. It just works." -- Software engineer with production Rust experience

"The Rust compiler is fantastic at kind of the errors it gives you. It's tremendously helpful in the type of errors it produces for it. But not just errors, but the fact it also catches the errors that other languages may not catch." -- Distinguished engineer working on cloud infrastructure services

The result: Rust as a gateway into new domains

When all these pieces come together, something interesting happens: Rust becomes a gateway into domains that would otherwise be inaccessible. We heard story after story of people whose careers changed because Rust gave them confidence to tackle things they couldn't before:

"I was civil engineering and I studied front-end development on my own, self taught. I had no computer background. I got interested in Rust and distributed systems and designs and systems around it. I changed my major, I studied CS and Rust at the same time." -- Software engineer transitioning to cryptography research

"I've been working with arbitrary subsidiaries of [a multinational engineering and technology company] for the last 25 years. Always doing software development mostly in the Java space... two years ago I started peeking into the automotive sector. In that context it was a natural consequence to either start working with C++ (which I did not want to do) or take the opportunity to dive into the newly established Rust ecosystem." -- Senior software engineer working in automotive embedded systems

"I started in blockchain. Currently I'm doing something else at my day job. Rust actually gave me the way to get into that domain." -- Rust developer and aerospace community leader

"Before that, I had 10 years of programming on some dynamic programming languages, especially Ruby, to develop web applications. I wanted to choose some language which focuses on system programming, so I chose Rust as my new choice. It is a change of my career." -- Rust consultant and author working in automotive systems and blockchain infrastructure

But the balance is crucial

Each of Rust's attributes are necessary for versatility across domains. But when taken too far, or when other attributes are missing, they can become an obstacle.

Example: Complex APIs and type complexity

One of the most powerful aspects of Rust is the way that its type system allows modeling aspects of the application domain. This prevents bugs and also makes it easier for noobs to get started3:

"Instead of using just a raw bit field, somebody encoded it into the type system. So when you'd have a function like 'open door', you can't pass an 'open door' if the door's already open. The type system will just kick that out and reject it." -- Software engineer working on automotive digital cockpit systems

"You can create contracts. For example, when you are allowed to use locks in which order." -- Senior embedded systems engineer working on automotive middleware development

The problem though is that sometimes the work to encode those invariants in types can create something that feels more complex than the problem itself:

"When you got Rust that's both async and generic and has lifetimes, then those types become so complicated that you basically have to be some sort of Rust god in order to even understand this code or be able to do it." -- Software engineer with production Rust experience

"Instead of spaghetti code, you have spaghetti typing" -- Platform architect at automotive semiconductor company

"I find it more opaque, harder to get my head around it. The types describe not just the interface of the thing but also the lifetime and how you are accessing it, whether it's on the stack or the heap, there's a lot of stuff packed into them." -- Software engineer working on data science platforms

This leads some to advocate for not using some of Rust's more complex features unless they are truly needed:

"My argument is that the hard parts of Rust -- traits, lifetimes, etc -- are not actually fundamental for being productive. There's a way to set up the learning curve and libraries to onboard people a lot faster." -- Creator and maintainer of Rust networking libraries

Example: Async ecosystem is performant but doesn't meet the bar for supportiveness

Async Rust has fueled a huge jump in using Rust to build network systems. But many commenters talked about the sense that "async Rust" was something altogether more difficult than sync Rust:

"I feel like there's a ramp in learning and then there's a jump and then there's async over here. And so the goal is to get enough excitement about Rust to where you can jump the chasm of sadness and land on the async Rust side." -- Software engineer working on automotive digital cockpit systems

"My general impression is actually pretty negative. It feels unbaked... there is a lot of arcane knowledge that you need in order to use it effectively, like Pin---like I could not tell you how Pin works, right?" -- Research software engineer with Rust expertise

For Rust to provide that "trusted tool that will help you tackle new domains" experience, people need to be leverage their expectations and knowledge of Rust in that new domain. With async, not only are there missing language features (e.g., async fn in traits only became available last year, and still have gaps), but the supportive tooling and ecosystem that users count on to "bridge the gap" elsewhere works less well:

"I was in favor of not using async, because the error messages were so hard to deal with." -- Desktop application developer

"The fact that there are still plenty of situations where you go that library looks useful, I want to use that library and then that immediately locks you into one of tokio-rs or one of the other runtimes, and you're like that's a bit disappointing because I was trying to write a library as well and now I'm locked into a runtime." -- Safety systems engineer working on functional safety for Linux

"We generally use Rust for services, and we use async a lot because a lot of libraries to interact with databases and other things are async. The times when we've had problems with this is like, um, unexplained high CPU usage, for example. The only really direct way to try to troubleshoot that or diagnose it is like, OK, I'm going to attach GDB and I'm gonna try to see what all of the threads are doing. GDB is -- I mean, this is not Rust's fault obviously -- but GDB is not a very easy to use tool, especially in a larger application. [..] And with async, it's, more difficult, because you don't see your code running, it's actually just sitting on the heap right now. Early on, I didn't actually realize that that was the case." -- Experienced Rust developer at a company using Rust and Python

Async is important enough that it merits a deep dive. Our research revealed a lot of frustration but we didn't go deep enough to give more specific insights. This would be a good task to be undertaken by the future User Research team (as proposed in our first post).

Example: The wealth of crates on crates.io are a key enabler but can be an obstacle

We mentioned earlier how Rust's extensibility is part of how it achieves versatility. Mechanisms like overloadable operators, traits, and macros let libraries create rich experiences for developers; a minimal standard library combined with easy package management encourage the creation of a rich ecosystem of crates covering needs both common and niche. However, particularly when people are first getting started, that extensibility can come at the cost of supportiveness, when the "tyranny of choice" becomes overwhelming:

"The crates to use are sort of undiscoverable. There's a layer of tacit knowledge about what crates to use for specific things that you kind of gather through experience and through difficulty. Everyone's doing all of their research." -- Web developer and conference speaker working on developer frameworks

"Crates.io gives you some of the metadata that you need to make those decisions, but it's not like a one stop shop, right? It's not like you go to crates.io and ask 'what I want to accomplish X, what library do I use'---it doesn't just answer that." -- Research software engineer

The Rust org has historically been reluctant to "bless" particular crates in the ecosystem. But the reality is that some crates are omnipresent. This is particular challenging for new users to navigate:

"The tutorial uses Result<Box<dyn Error>> -- but nobody else does. Everybody uses anyhow-result... I started off using the result thing but all the information I found has example code using anyhow. It was a bit of a mismatch and I didn't know what I should do." -- Software engineer working on data science platforms

"There is no clear recorded consensus on which 3P crates to use. [..] Sometimes it's really not clear---which CBOR crate do you use?[..] It's not easy to see which crates are still actively maintained. [..] The fact that there are so many crates on crates.io makes that a little bit of a risk." -- Rust team from a large technology company

Recommendations

Enumerate Rust's design goals and integrating them into our processes

We recommend creating an RFC that defines the goals we are shooting for as we work on Rust. The RFC should cover the experience of using Rust in total (language, tools, and libraries). This RFC could be authored by the proposed User Research team, though it's not clear who should accept it — perhaps the User Research team itself, or perhaps the leadership council.

This post identified how the real "empowering magic" of Rust arises from achieving a number of different attributes all at once -- reliability, efficiency, low-level control, supportiveness, and so forth. It would be valuable to have a canonical list of those values that we could collectively refer to as a community and that we could use when evaluating RFCs or other proposed designs.

There have been a number of prior approaches at this work that we could build on (e.g., this post from Tyler Mandry, the Rustacean Principles, or the Rust Design Axioms). One insight from our research is that we don't need to define which values are "most important". We've seen that for Rust to truly work, it must achieve all the factors at once. Instead of ranking, it may help to describe how it feels when you:

  • Don't achieve it (too little)
  • Get it right (the sweet spot)
  • Go overboard (too much)

This "goldilocks" framing helps people recognize where they are and course-correct, without creating false hierarchies.

Double down on extensibility

We recommend doubling down on extensibility as a core strategy. Rust's extensibility — traits, macros, operator overloading — has been key to its versatility. But that extensibility is currently concentrated in certain areas: the type system and early-stage proc macros. We should expand it to cover supportive interfaces (better diagnostics and guidance from crates) and compilation workflow (letting crates integrate at more stages of the build process).

Rust's extensibility is a big part of how Rust achieves versatility, and that versatility is a big part of what people love about Rust. Leveraging mechanisms like proc macros, the trait system, and the borrow checker, Rust crates are able to expose high-level, elegant interfaces that compile down to efficiemt machine code. At its best, it can feel a bit like magic.

Unfortunately, while Rust gives crates good tools for building safe, efficient abstractions, we don't provide tools to enable supportive ones. Within builtin Rust language concepts, we have worked hard to create effective error messages that help steer users to success; we ship the compiler with lints that catch common mistakes or enforce important conventions. But crates benefit from none of this. RFCs like RFC #3368, which introduced the diagnostic namespace and #[diagnostic::on_unimplemented], Rust has already begun moving in this direction. We should continue and look for opportunities to go further, particularly for proc-macros which often create DSL-like interfaces.

The other major challenge for extensibility is concerned with the build system and backend. Rust's current extensibility mechanisms (e.g., build.rs, proc-macros) are focused on the early stages of the compilation process. But many extensions to Rust, ranging from interop to theorem proving to GPU programming to distributed systems, would benefit from being able to integrate into other stages of the compilation process. The Stable MIR project and the build-std project goal are two examples of this sort of work.

Doubling down on extensibility will not only make current Rust easier to use, it will enable and support Rust's use in new domains. Safety Critical applications in particular require a host of custom lints and tooling to support the associated standards. Compiler extensibility allows Rust to support those niche needs in a more general way.

Help users get oriented in the Rust ecosystem

We recommend finding ways to help users navigate the crates.io ecosystem. Idiomatic Rust today relies on custom crates for everything from error-handling to async runtimes. Leaning on the ecosystem helps Rust to scale to more domains and allows for innovative new approaches to be discovered. But finding which crates to use presents a real obstacle when people are getting started. The Rust org maintains a carefully neutral stance, which is good, but also means that people don't have anywhere to go for advice on a good "starter set" crates.

The right solution here is not obvious. Expanding the standard library could cut off further experimentation; "blessing" crates carries risks of politics. But just because the right solution is difficult doesn't mean we should ignore the problem. Rust has a history of exploring creative solutions to old tradeoffs, and we should turn that energy to this problem as well.

Part of the solution is enabling better interop between libraries. This could come in the form of adding key interop traits (particularly for async) or by blessing standard building blocks (e.g., the http crate, which provides type definitions for HTTP libraries). Changes to coherence rules can also help, as the current rules do not permit a new interop trait to be introduced in the ecosystem and incrementally adopted.

Conclusion

To sum up the main points in this post:

  • What people love about Rust is the way it empowers them to tackle tough problems and new domains. This is not the result of any one attribute but rather a careful balancing act between many; if any of them are compromised, the language suffers significantly.
  • We make three recommendations to help Rust continue to scale across domains and usage levels
    • Enumerate and describe Rust's design goals and integrate them into our processes, helping to ensure they are observed by future language designers and the broader ecosystem.
    • Double down on extensibility, introducing the ability for crates to influence the develop experience and the compilation pipeline.
    • Help users to navigate the crates.io ecosystem and enable smoother interop
  1. In 2025, 72% of Rust users said they wanted to keep using it. In the past, Rust had a way higher score than any other language, but this year, Gleam came awfully close, with 70%! Good for them! Gleam looks awesome--and hey, good choice on the fn keyword. ;)
  2. And, uh, how can we be sure not to mess it up?
  3. ...for experienced devs operating on less sleep, who do tend to act a lot like noobs.

Continue Reading…

Rust Blog

Announcing Rust 1.92.0

The Rust team is happy to announce a new version of Rust, 1.92.0. Rust is a programming language empowering everyone to build reliable and efficient software.

If you have a previous version of Rust installed via rustup, you can get 1.92.0 with:

$ rustup update stable

If you don't have it already, you can get rustup from the appropriate page on our website, and check out the detailed release notes for 1.92.0.

If you'd like to help us out by testing future releases, you might consider updating locally to use the beta channel (rustup default beta) or the nightly channel (rustup default nightly). Please report any bugs you might come across!

What's in 1.92.0 stable

Deny-by-default never type lints

The language and compiler teams continue to work on stabilization of the never type. In this release the never_type_fallback_flowing_into_unsafe and dependency_on_unit_never_type_fallback future compatibility lints were made deny-by-default, meaning they will cause a compilation error when detected.

It's worth noting that while this can result in compilation errors, it is still a lint; these lints can all be #[allow]ed. These lints also will only fire when building the affected crates directly, not when they are built as dependencies (though a warning will be reported by Cargo in such cases).

These lints detect code which is likely to be broken by the never type stabilization. It is highly advised to fix them if they are reported in your crate graph.

We believe there to be approximately 500 crates affected by this lint. Despite that, we believe this to be acceptable, as lints are not a breaking change and it will allow for stabilizing the never type in the future. For more in-depth justification, see the Language Team's assessment.

unused_must_use no longer warns about Result<(), UninhabitedType>

Rust's unused_must_use lint warns when ignoring the return value of a function, if the function or its return type is annotated with #[must_use]. For instance, this warns if ignoring a return type of Result, to remind you to use ?, or something like .expect("...").

However, some functions return Result, but the error type they use is not actually "inhabited", meaning you cannot construct any values of that type (e.g. the ! or Infallible types).

The unused_must_use lint now no longer warns on Result<(), UninhabitedType>, or on ControlFlow<UninhabitedType, ()>. For instance, it will not warn on Result<(), Infallible>. This avoids having to check for an error that can never happen.

use core::convert::Infallible;
fn can_never_fail() -> Result<(), Infallible> {
    // ...
    Ok(())
}

fn main() {
    can_never_fail();
}

This is particularly useful with the common pattern of a trait with an associated error type, where the error type may sometimes be infallible:

trait UsesAssocErrorType {
    type Error;
    fn method(&self) -> Result<(), Self::Error>;
}

struct CannotFail;
impl UsesAssocErrorType for CannotFail {
    type Error = core::convert::Infallible;
    fn method(&self) -> Result<(), Self::Error> {
        Ok(())
    }
}

struct CanFail;
impl UsesAssocErrorType for CanFail {
    type Error = std::io::Error;
    fn method(&self) -> Result<(), Self::Error> {
        Err(std::io::Error::other("something went wrong"))
    }
}

fn main() {
    CannotFail.method(); // No warning
    CanFail.method(); // Warning: unused `Result` that must be used
}

Emit unwind tables even when -Cpanic=abort is enabled on linux

Backtraces with -Cpanic=abort previously worked in Rust 1.22 but were broken in Rust 1.23, as we stopped emitting unwind tables with -Cpanic=abort. In Rust 1.45 a workaround in the form of -Cforce-unwind-tables=yes was stabilized.

In Rust 1.92 unwind tables will be emitted by default even when -Cpanic=abort is specified, allowing for backtraces to work properly. If unwind tables are not desired then users should use -Cforce-unwind-tables=no to explicitly disable them being emitted.

Validate input to #[macro_export]

Over the past few releases, many changes were made to the way built-in attributes are processed in the compiler. This should greatly improve the error messages and warnings Rust gives for built-in attributes and especially make these diagnostics more consistent among all of the over 100 built-in attributes.

To give a small example, in this release specifically, Rust became stricter in checking what arguments are allowed to macro_export by upgrading that check to a "deny-by-default lint" that will be reported in dependencies.

Stabilized APIs

These previously stable APIs are now stable in const contexts:

Other changes

Check out everything that changed in Rust, Cargo, and Clippy.

Contributors to 1.92.0

Many people came together to create Rust 1.92.0. We couldn't have done it without all of you. Thanks!

Continue Reading…

Rust Blog

Making it easier to sponsor Rust contributors

TLDR: You can now find a list of Rust contributors that you can sponsor on this page.

Same as with many other open-source projects, Rust depends on a large number of contributors, many of whom make Rust better on a volunteer basis or are funded only for a fraction of their open-source contributions.

Supporting these contributors is vital for the long-term health of the Rust language and its toolchain, so that it can keep its current level of quality, but also evolve going forward. Of course, this is nothing new, and there are currently several ongoing efforts to provide stable and sustainable funding for Rust maintainers, such as the Rust Foundation Maintainer Fund or the RustNL Maintainers Fund. We are very happy about that!

That being said, there are multiple ways of supporting the development of Rust. One of them is sponsoring individual Rust contributors directly, through services like GitHub Sponsors. This makes it possible even for individuals or small companies to financially support their favourite contributors. Every bit of funding helps!

Previously, if you wanted to sponsor someone who works on Rust, you had to go on a detective hunt to figure out who are the people contributing to the Rust toolchain, if they are receiving sponsorships and through which service. This was a lot of work that could provide a barrier to sponsorships. So we simplified it!

Now we have a dedicated Funding page on the Rust website, which helpfully shows members of the Rust Project that are currently accepting funds through sponsoring1. You can click on the name of a contributor to find out what teams they are a part of and what kind of work they do in the Rust Project.

Note that the list of contributors accepting funding on this page is non-exhaustive. We made it opt in, so that contributors can decide on their own whether they want to be listed there or not.

If you ever wanted to support the development of Rust "in the small", it is now simpler than ever.

  1. The order of people on the funding page is shuffled on every page load to reduce unnecessary ordering bias.

Continue Reading…

Rust Blog

Updating Rust's Linux musl targets to 1.2.5

Updating Rust's Linux musl targets to 1.2.5

Beginning with Rust 1.93 (slated for stable release on 2026-01-22), the various *-linux-musl targets will all ship with musl 1.2.5. This primarily affects static musl builds for x86_64, aarch64, and powerpc64le which bundled musl 1.2.3. This update comes with several fixes and improvements, and a breaking change that affects the Rust ecosystem.

For the Rust ecosystem, the primary motivation for this update is to receive major improvements to musl's DNS resolver which shipped in 1.2.4 and received bug fixes in 1.2.5. When using musl targets for static linking, this should make portable linux binaries that do networking more reliable, particularly in the face of large DNS records and recursive nameservers.

However, 1.2.4 also comes with a breaking change: the removal of several legacy compatibility symbols that the Rust libc crate was using. A fix for this was shipped in libc 0.2.146 in June 2023 (2 years ago), and we have been waiting for newer versions of the libc crate to propagate throughout the ecosystem before shipping the musl update.

A crater run in July 2024 found only about 2.4% of Rust projects were still affected. A crater run in June 2025 found 1.5% of Rust projects were affected. Most of that change is from crater analyzing More Rust Projects. The absolute amount of broken projects went down by 15% while the absolute amount of analyzed projects went up by 35%.

At this point we expect there will be minimal breakage, and most breakage should be resolved by a cargo update. We believe this update shouldn't be held back any longer, as it contains critical fixes for the musl target.

Manual inspection of some of the affected projects indicates they largely haven't run cargo update in 2 years, often because they haven't had any changes in 2 years. Fixing these crates is as easy as cargo update.

Build failures from this change will typically look like "some `extern` functions couldn't be found; some native libraries may need to be installed or have their path specified", often specifically for "undefined reference to `open64'", often while trying to build very old versions of the getrandom crate (hence the outsized impact on gamedev projects that haven't updated their dependencies in several years in particular):

Example Build Failure

[INFO] [stderr]    Compiling guess_the_number v0.1.0 (/opt/rustwide/workdir)
[INFO] [stdout] error: linking with `cc` failed: exit status: 1
[INFO] [stdout]   |
[INFO] [stdout]   = note:  "cc" "-m64" "<sysroot>/lib/rustlib/x86_64-unknown-linux-musl/lib/self-contained/rcrt1.o" "<sysroot>/lib/rustlib/x86_64-unknown-linux-musl/lib/self-contained/crti.o" "<sysroot>/lib/rustlib/x86_64-unknown-linux-musl/lib/self-contained/crtbeginS.o" "/tmp/rustcMZMWZW/symbols.o" "<2 object files omitted>" "-Wl,--as-needed" "-Wl,-Bstatic" "/opt/rustwide/target/x86_64-unknown-linux-musl/debug/deps/{librand-bff7d8317cf08aa0.rlib,librand_chacha-612027a3597e9138.rlib,libppv_lite86-742ade976f63ace4.rlib,librand_core-be9c132a0f2b7897.rlib,libgetrandom-dc7f0d82f4cb384d.rlib,liblibc-abed7616303a3e0d.rlib,libcfg_if-66d55f6b302e88c8.rlib}.rlib" "<sysroot>/lib/rustlib/x86_64-unknown-linux-musl/lib/{libstd-*,libpanic_unwind-*,libobject-*,libmemchr-*,libaddr2line-*,libgimli-*,librustc_demangle-*,libstd_detect-*,libhashbrown-*,librustc_std_workspace_alloc-*,libminiz_oxide-*,libadler2-*,libunwind-*}.rlib" "-lunwind" "<sysroot>/lib/rustlib/x86_64-unknown-linux-musl/lib/{libcfg_if-*,liblibc-*}.rlib" "-lc" "<sysroot>/lib/rustlib/x86_64-unknown-linux-musl/lib/{librustc_std_workspace_core-*,liballoc-*,libcore-*,libcompiler_builtins-*}.rlib" "-L" "/tmp/rustcMZMWZW/raw-dylibs" "-Wl,-Bdynamic" "-Wl,--eh-frame-hdr" "-Wl,-z,noexecstack" "-nostartfiles" "-L" "<sysroot>/lib/rustlib/x86_64-unknown-linux-musl/lib/self-contained" "-L" "<sysroot>/lib/rustlib/x86_64-unknown-linux-musl/lib" "-o" "/opt/rustwide/target/x86_64-unknown-linux-musl/debug/deps/guess_the_number-41a068792b5f051e" "-Wl,--gc-sections" "-static-pie" "-Wl,-z,relro,-z,now" "-nodefaultlibs" "<sysroot>/lib/rustlib/x86_64-unknown-linux-musl/lib/self-contained/crtendS.o" "<sysroot>/lib/rustlib/x86_64-unknown-linux-musl/lib/self-contained/crtn.o"
[INFO] [stdout]   = note: some arguments are omitted. use `--verbose` to show all linker arguments
[INFO] [stdout]   = note: /usr/bin/ld: /opt/rustwide/target/x86_64-unknown-linux-musl/debug/deps/libgetrandom-dc7f0d82f4cb384d.rlib(getrandom-dc7f0d82f4cb384d.getrandom.828c5c30a8428cf4-cgu.0.rcgu.o): in function `getrandom::util_libc::open_readonly':
[INFO] [stdout]           /opt/rustwide/cargo-home/registry/src/index.crates.io-1949cf8c6b5b557f/getrandom-0.2.8/src/util_libc.rs:150:(.text._ZN9getrandom9util_libc13open_readonly17hdc55d6ead142a889E+0xbc): undefined reference to `open64'
[INFO] [stdout]           collect2: error: ld returned 1 exit status
[INFO] [stdout]           
[INFO] [stdout]   = note: some `extern` functions couldn't be found; some native libraries may need to be installed or have their path specified
[INFO] [stdout]   = note: use the `-l` flag to specify native libraries to link
[INFO] [stdout]   = note: use the `cargo:rustc-link-lib` directive to specify the native libraries to link with Cargo (see https://doc.rust-lang.org/cargo/reference/build-scripts.html#rustc-link-lib)
[INFO] [stdout] 
[INFO] [stdout] 
[INFO] [stderr] error: could not compile `guess_the_number` (bin "guess_the_number") due to 1 previous error

Updated targets

All Rust musl targets that bundle a copy of musl now bundle 1.2.5. All Rust musl targets now require musl 1.2.5 at a minimum.

The mostly only actually impacts the three "Tier 2 With Host Tools" musl targets which were pinned to musl 1.2.3:

  • aarch64-unknown-linux-musl
  • x86_64-unknown-linux-musl
  • powerpc64le-unknown-linux-musl

The fourth target at this level of support, loongarch64-unknown-linux-musl, is so new that it was always on musl 1.2.5.

Due to an apparent configuration oversight with crosstool-ng, all other targets were already bundling musl 1.2.5. These targets were silently upgraded to musl 1.2.4 in Rust 1.74.0 and silently upgraded to musl 1.2.5 in Rust 1.86. This oversight has been rectified and all targets have been pinned to musl 1.2.5 to prevent future silent upgrades (but hey, no one noticing bodes well for the ecosystem impact of this change). Their documentation has now been updated to reflect the fact that bundling 1.2.5 is actually intentional, and that 1.2.5 is now considered a minimum requirement.

Here are all the updated definitions:

Tier 2 with Host Tools

| target | notes | | ------------------------------------ | --------------------------------------- | | aarch64-unknown-linux-musl | ARM64 Linux with musl 1.2.5 | | powerpc64le-unknown-linux-musl | PPC64LE Linux (kernel 4.19, musl 1.2.5) | | x86_64-unknown-linux-musl | 64-bit Linux with musl 1.2.5 |

Tier 2 without Host Tools

| target | std | notes | | ---------------------------------- | --- | ------------------------------------------- | | arm-unknown-linux-musleabi | ✓ | Armv6 Linux with musl 1.2.5 | | arm-unknown-linux-musleabihf | ✓ | Armv6 Linux with musl 1.2.5, hardfloat | | armv5te-unknown-linux-musleabi | ✓ | Armv5TE Linux with musl 1.2.5 | | armv7-unknown-linux-musleabi | ✓ | Armv7-A Linux with musl 1.2.5 | | armv7-unknown-linux-musleabihf | ✓ | Armv7-A Linux with musl 1.2.5, hardfloat | | i586-unknown-linux-musl | ✓ | 32-bit Linux (musl 1.2.5, original Pentium) | | i686-unknown-linux-musl | ✓ | 32-bit Linux with musl 1.2.5 (Pentium 4) | | riscv64gc-unknown-linux-musl | ✓ | RISC-V Linux (kernel 4.20+, musl 1.2.5) |

Tier 3

| target | std | host | notes | | ------------------------------------ | --- | --------------------------------------------------------------- | ------------------------------------- | | hexagon-unknown-linux-musl | ✓ | Hexagon Linux with musl 1.2.5 | | | mips-unknown-linux-musl | ✓ | MIPS Linux with musl 1.2.5 | | | mips64-openwrt-linux-musl | ? | MIPS64 for OpenWrt Linux musl 1.2.5 | | | mips64-unknown-linux-muslabi64 | ✓ | MIPS64 Linux, N64 ABI, musl 1.2.5 | | | mips64el-unknown-linux-muslabi64 | ✓ | MIPS64 (little endian) Linux, N64 ABI, musl 1.2.5 | | | mipsel-unknown-linux-musl | ✓ | MIPS (little endian) Linux with musl 1.2.5 | | | powerpc-unknown-linux-musl | ? | PowerPC Linux with musl 1.2.5 | | | powerpc-unknown-linux-muslspe | ? | PowerPC SPE Linux with musl 1.2.5 | | | powerpc64-unknown-linux-musl | ✓ | ✓ | PPC64 Linux (kernel 4.19, musl 1.2.5) | | riscv32gc-unknown-linux-musl | ? | RISC-V Linux (kernel 5.4, musl 1.2.5 + RISCV32 support patches) | | | s390x-unknown-linux-musl | ✓ | S390x Linux (kernel 3.2, musl 1.2.5) | | | thumbv7neon-unknown-linux-musleabihf | ? | Thumb2-mode Armv7-A Linux with NEON, musl 1.2.5 | | | x86_64-unikraft-linux-musl | ✓ | 64-bit Unikraft with musl 1.2.5 | |

Continue Reading…

Rust Blog

crates.io: Malicious crates finch-rust and sha-rust

Summary

On December 5th, the crates.io team was notified by Kush Pandya from the Socket Threat Research Team of two malicious crates which were trying to cause confusion with the existing finch crate but adding a dependency on a malicious crate doing data exfiltration.

These crates were:

  • finch-rust - 1 version published November 25, 2025, downloaded 28 times, used sha-rust as a dependency
  • sha-rust - 8 versions published between November 20 and November 25, 2025, downloaded 153 times

Actions taken

The user in question, face-lessssss, was immediately disabled, and the crates in question were deleted from crates.io shortly after. We have retained the malicious crate files for further analysis.

The deletions were performed at 15:52 UTC on December 5th.

We reported the associated repositories to GitHub and the account has been removed there as well.

Analysis

Socket has published their analysis in a blog post.

These crates had no dependent downstream crates on crates.io, and there is no evidence of either of these crates being downloaded outside of automated mirroring and scanning services.

Thanks

Our thanks to Kush Pandya from the Socket Threat Research Team for reporting the crates. We also want to thank Carol Nichols from the crates.io team and Adam Harvey from the Rust Foundation for aiding in the response.

Continue Reading…

Rust Blog

crates.io: Malicious crates evm-units and uniswap-utils

Summary

On December 2nd, the crates.io team was notified by Olivia Brown from the Socket Threat Research Team of two malicious crates which were downloading a payload that was likely attempting to steal cryptocurrency.

These crates were:

  • evm-units - 13 versions published in April 2025, downloaded 7257 times
  • uniswap-utils - 14 versions published in April 2025, downloaded 7441 times, used evm-units as a dependency

Actions taken

The user in question, ablerust, was immediately disabled, and the crates in question were deleted from crates.io shortly after. We have retained the malicious crate files for further analysis.

The deletions were performed at 22:01 UTC on December 2nd.

Analysis

Socket has published their analysis in a blog post.

These crates had no dependent downstream crates on crates.io.

Thanks

Our thanks to Olivia Brown from the Socket Threat Research Team for reporting the crates. We also want to thank Carol Nichols from the crates.io team and Walter Pearce and Adam Harvey from the Rust Foundation for aiding in the response.

Continue Reading…

Rust Blog

Lessons learned from the Rust Vision Doc process

Starting earlier this year, a group of us set on a crazy quest: to author a "Rust vision doc". As we described it in the original project goal proposal:

The Rust Vision Doc will summarize the state of Rust adoption -- where is Rust adding value? what works well? what doesn't? -- based on conversations with individual Rust users from different communities, major Rust projects, and companies large and small that are adopting Rust.

Over the course of this year, the Vision Doc group has gathered up a lot of data. We began with a broad-based survey that got about 4200 responses. After that, we conducted over 70 interviews, each one about 45 minutes, with as broad a set of Rust users as we could find1.

This is the first of a series of blog posts covering what we learned throughout that process and what recommendations we have to offer as a result. This first post is going to go broad. We'll discuss the process we used and where we think it could be improved going forward. We'll talk about some of the big themes we heard -- some that were surprising and others that were, well, not surprising at all. Finally, we'll close with some recommendations for how the project might do more work like this in the future.

The questions we were trying to answer

One of the first things we did in starting out with the vision doc was to meet with a User Research expert, Holly Ellis, who gave us a quick tutorial on how User Research works2. Working with her, we laid out a set of research questions that we wanted to answer. Our first cut was very broad, covering three themes:

  • Rust the technology:
    • "How does Rust fit into the overall language landscape? What is Rust's mission?"
    • "What brings people to Rust and why do they choose to use it for a particular problem...?"
    • "What would help Rust to succeed in these domains...?" (e.g., network systems, embedded)
    • "How can we scale Rust to industry-wide adoption? And how can we ensure that, as we do so, we continue to have a happy, joyful open-source community?"
  • Rust the global project:
    • "How can we improve the experience of using Rust for people across the globe?"
    • "How can we improve the experience of contributing to and maintaining Rust for people across the globe?"
  • Rust the open-source project:
    • "How can we tap into the knowledge, experience, and enthusiasm of a growing Rust userbase to improve Rust?"
    • "How can we ensure that individual or volunteer Rust maintainers are well-supported?"
    • "What is the right model for Foundation-project interaction?"

Step 1: Broad-based survey

Before embarking on individual interviews, we wanted to get a broad snapshot of Rust usage. We also wanted to find a base of people that we could talk to. We created a survey that asked a few short "demographic" questions -- e.g., where does the respondent live, what domains do they work on, how would they rate their experience -- and some open-ended questions about their journey to Rust, what kind of projects they feel are a good fit for Rust, what they found challenging when learning, etc. It also asked for (optional) contact information.

We got a LOT of responses -- over 4200! Analyzing this much data is not easy, and we were very grateful to Kapiche, who offered us free use of their tool to work through the data. ❤

The survey is useful in two ways. First, it's an interesting data-set in its own right, although you have to be aware of selection bias. Second, the survey also gave us something that we can use to cross-validate some of what we heard in 1:1 interviews and to look for themes we might otherwise have missed. And of course it gave us additional names of people we can talk to (though most respondents didn't leave contact information).

Step 2: Interviewing individuals

The next step after the survey was to get out there and talk to people. We sourced people from a lot of places: the survey and personal contacts, of course, but we also sat down with people at conferences and went to meetups. We even went to a Python meetup in an effort to find people who were a bit outside the usual "Rust circle".

When interviewing people, the basic insight of User Experience research is that you don't necessarily ask people the exact questions you want to answer. That is likely to get them speculating and giving you the answer that they think they "ought" to say. Instead, you come at it sideways. You ask them factual, non-leading questions. In other words, you certainly don't say, "Do you agree the borrow checker is really hard?" And you probably don't even say, "What is the biggest pain point you had with Rust?" Instead, you might say, "What was the last time you felt confused by an error message?" And then go from there, "Is this a typical example? If not, what's another case where you felt confused?"

To be honest, these sorts of "extremely non-leading questions" are kind of difficult to do. But they can uncover some surprising results.

We got answers -- but not all the answers we wanted

4200 survey responses and 70 interviews later, we got a lot of information -- but we still don't feel like we have the answers to some of the biggest questions. Given the kinds of questions we asked, we got a pretty good view on the kinds of things people love about Rust and what it offers relative to other languages. We got a sense for the broad areas that people find challenging. We also learned a few things about how the Rust project interacts with others and how things vary across the globe.

What we really don't have is enough data to say "if you do X, Y, and Z, that will really unblock Rust adoption in this domain". We just didn't get into enough technical detail, for example, to give guidance on which features ought to be prioritized, or to help answer specific design questions that the lang or libs team may consider.

One big lesson: there are only 24 hours in a day

One of the things we learned was that you need to stay focused. There were so many questions we wanted to ask, but only so much time in which to do so. Ultimately, we wound up narrowing our scope in several ways:

  • we focused primarily on the individual developer experience, and only had minimal discussion with companies as a whole;
  • we dove fairly deep into one area (the Safety Critical domain) but didn't go as deep into the details of other domains;
  • we focused primarily on Rust adoption, and in particular did not even attempt to answer the questions about "Rust the open-source project".

Another big lesson: haters gonna... stay quiet?

One thing we found surprisingly difficult was finding people to interview who didn't like Rust. 49% of survey respondents, for example, rated their Rust comfort as 4 or 5 out of 5, and only 18.5% said 1 or 2. And of those, only a handful gave contact information.

It turns out that people who think Rust isn't worth using mostly don't read the Rust blog or want to talk about that with a bunch of Rust fanatics.3 This is a shame, of course, as likely those folks have a lot to teach us about the boundaries of where Rust adds value. We are currently doing some targeted outreach in an attempt to grow our scope here, so stay tuned, we may get more data.

One fun fact: enums are Rust's underappreciated superpower

We will do a deeper dive into the things people say that they like about Rust later (hint: performance and reliability both make the cut). One interesting thing we found was the number of people that talked specifically about Rust enums, which allow you to package up the state of your program along with the data it has available in that state. Enums are a concept that Rust adapted from functional languages like OCaml and Haskell and fit into the system programming setting.

"The usage of Enum is a new concept for me. And I like this concept. It's not a class and it's not just a boolean, limited to false or true. It has different states." -- New Rust developer

"Tagged unions. I don't think I've seriously used another production language which has that. Whenever I go back to a different language I really miss that as a way of accurately modeling the domain." -- Embedded developer

Where do we go from here? Create a user research team

When we set out to write the vision doc, we imagined that it would take the form of an RFC. We imagined that RFC identifying key focus areas for Rust and making other kinds of recommendations. Now that we've been through it, we don't think we have the data we need to write that kind of RFC (and we're also not sure if that's the right kind of RFC to write). But we did learn a lot and we are convinced of the importance of this kind of work.

Therefore, our plan is to do the following. First, we're going to write-up a series of blog posts diving into what we learned about our research questions along with other kinds of questions that we encountered as we went.

Second, we plan to author an RFC proposing a dedicated user research team for the Rust org. The role of this team would be to gather data of all forms (interviews, surveys, etc) and make it available to the Rust project. And whenever they can, they would help to connect Rust customers directly with people extending and improving Rust.

The vision doc process was in many ways our first foray into this kind of research, and it taught us a few things:

  • First, we have to go broad and deep. For this first round, we focused on high-level questions about people's experiences with Rust, and we didn't get deep into technical blockers. This gives us a good overview but limits the depth of recommendations we can make.
  • Second, to answer specific questions we need to do specific research. One of our hypotheses was that we could use UX interviews to help decide thorny questions that come up in RFCs -- e.g., the notorious debate between await x and x.await from yesteryear. What we learned is "sort of". The broad interviews we did did give us information about what kinds of things are important to people (e.g., convenience vs reliability, and so forth), and we'll cover some of that in upcoming write-ups. But to shed light on specific questions (e.g., "will x.await be confused for a field access") will really require more specific research. This may be interviews but it could also be other kinds of tests. These are all things though that a user research team could help with.
  • Third, we should find ways to "open the data" and publish results incrementally. We conducted all of our interviews with a strong guarantee of privacy and we expect to delete the information we've gathered once this project wraps up. Our goal was to ensure people could talk in an unfiltered way. This should always be an option we offer people -- but that level of privacy has a cost, which is that we are not able to share the raw data, even widely across the Rust teams, and (worse) people have to wait for us to do analysis before they can learn anything. This won't work for a long-running team. At the same time, even for seemingly innocuous conversations, posting full transcripts of conversations openly on the internet may not be the best option, so we need to find a sensible compromise.
  1. "As wide a variety of Rust users as we could find" -- the last part is important. One of the weaknesses of this work is that we wanted to hear from more Rust skeptics than we did.
  2. Thanks Holly! We are ever in your debt.
  3. Shocking, I know. But, actually, it is a little -- most programmers love telling you how much they hate everything you do, in my experience?

Continue Reading…

Rust Blog

Switching to Rust's own mangling scheme on nightly

TL;DR: rustc will use its own "v0" mangling scheme by default on nightly versions instead of the previous default, which re-used C++'s mangling scheme, starting in nightly-2025-11-21

Context

When Rust is compiled into object files and binaries, each item (functions, statics, etc) must have a globally unique "symbol" identifying it.

In C, the symbol name of a function is just the name that the function was defined with, such as strcmp. This is straightforward and easy to understand, but requires that each item have a globally unique name that doesn't overlap with any symbols from libraries that it is linked against. If two items had the same symbol then when the linker tried to resolve a symbol to an address in memory (of a function, say), then it wouldn't know which symbol is the correct one.

Languages like Rust and C++ define "symbol mangling schemes", leveraging information from the type system to give each item a unique symbol name. Without this, it would be possible to produce clashing symbols in a variety of ways - for example, every instantiation of a generic or templated function (or an overload in C++), which all have the same name in the surface language would end up with clashing symbols; or the same name in different modules, such as a::foo and b::foo would have clashing symbols.

Rust originally used a symbol mangling scheme based on theItanium ABI's name mangling scheme used by C++ (sometimes). Over the years, it was extended in an inconsistent and ad-hoc way to support Rust features that the mangling scheme wasn't originally designed for. Rust's current legacy mangling scheme has a number of drawbacks:

  • Information about generic parameter instantiations is lost during mangling
  • It is internally inconsistent - some paths use an Itanium ABI-style encoding but some don't
  • Symbol names can contain . characters which aren't supported on all platforms
  • Symbol names include an opaque hash which depends on compiler internals and can't be easily replicated by other compilers or tools
  • There is no straightforward way to differentiate between Rust and C++ symbols

If you've ever tried to use Rust with a debugger or a profiler and found it hard to work with because you couldn't work out which functions were which, it's probably because information was being lost in the mangling scheme.

Rust's compiler team started working on our own mangling scheme back in 2018 with RFC 2603 (see the "v0 Symbol Format" chapter in rustc book for our current documentation on the format). Our "v0" mangling scheme has multiple advantageous properties:

  • An unambiguous encoding for everything that can end up in a binary's symbol table
  • Information about generic parameters are encoded in a reversible way
  • Mangled symbols are decodable such that it should be possible to identify concrete instances of generic functions
  • It doesn't rely on compiler internals
  • Symbols are restricted to only A-Z, a-z, 0-9 and _, helping ensure compatibility with tools on varied platforms
  • It tries to stay efficient and avoid unnecessarily long names and computationally-expensive decoding

However, rustc is not the only tool that interacts with Rust symbol names: the aforementioned debuggers, profilers and other tools all need to be updated to understand Rust's v0 symbol mangling scheme so that Rust's users can continue to work with Rust binaries using all the tools they're used to without having to look at mangled symbols. Furthermore, all of those tools need to have new releases cut and then those releases need to be picked up by distros. This takes time!

Fortunately, the compiler team now believe that support for our v0 mangling scheme is now sufficiently widespread that it can start to be used by default by rustc.

Benefits

Reading Rust backtraces, or using Rust with debuggers, profilers and other tools that operate on compiled Rust code, will be able to output much more useful and readable names. This will especially help with async code, closures and generic functions.

It's easy to see the new mangling scheme in action, consider the following example:

fn foo<T>() {
    panic!()
}

fn main() {
    foo::<Vec<(String, &[u8; 123])>>();
}

With the legacy mangling scheme, all of the useful information about the generic instantiation of foo is lost in the symbol f::foo..

thread 'main' panicked at f.rs:2:5:
explicit panic
stack backtrace:
  0: std::panicking::begin_panic
    at /rustc/d6c...582/library/std/src/panicking.rs:769:5
  1: f::foo
  2: f::main
  3: core::ops::function::FnOnce::call_once
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.

..but with the v0 mangling scheme, the useful details of the generic instantiation are preserved with f::foo::<alloc::vec::Vec<(alloc::string::String, &[u8; 123])>>:

thread 'main' panicked at f.rs:2:5:
explicit panic
stack backtrace:
  0: std::panicking::begin_panic
    at /rustc/d6c...582/library/std/src/panicking.rs:769:5
  1: f::foo::<alloc::vec::Vec<(alloc::string::String, &[u8; 123])>>
  2: f::main
  3: <fn() as core::ops::function::FnOnce<()>>::call_once
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.

Possible drawbacks

Symbols using the v0 mangling scheme can be larger than symbols with the legacy mangling scheme, which can result in a slight increase in linking times and binary sizes if symbols aren't stripped (which they aren't by default). Fortunately this impact should be minor, especially with modern linkers like lld, which Rust will now default to on some targets.

Some old versions of tools/distros or niche tools that the compiler team are unaware of may not have had support for the v0 mangling scheme added. When using these tools, the only consequence is that users may encounter mangled symbols. rustfilt can be used to demangle Rust symbols if a tool does not.

In any case, using the new mangling scheme can be disabled if any problem occurs: use the -Csymbol-mangling-version=legacy -Zunstable-options flag to revert to using the legacy mangling scheme.

Explicitly enabling the legacy mangling scheme requires nightly, it is not intended to be stabilised so that support can eventually be removed.

Adding v0 support in your tools

If you maintain a tool that interacts with Rust symbols and does not support the v0 mangling scheme, there are Rust and C implementations of a v0 symbol demangler available in the rust-lang/rustc-demanglerepository that can be integrated into your project.

Summary

rustc will use our "v0" mangling scheme on nightly for all targets starting in tomorrow's rustup nightly (nightly-2025-11-21).

Let us know if you encounter problems, by opening an issue on GitHub.

If that happens, you can use the legacy mangling scheme with the -Csymbol-mangling-version=legacy -Zunstable-options flag. Either by adding it to the usual RUSTFLAGS environment variable, or to a project's .cargo/config.toml configuration file, like so:

[build]
rustflags = ["-Csymbol-mangling-version=legacy", "-Zunstable-options"]

If you like the sound of the new symbol mangling version and would like to start using it on stable or beta channels of Rust, then you can similarly use the -Csymbol-mangling-version=v0 flag today viaRUSTFLAGS or .cargo/config.toml:

[build]
rustflags = ["-Csymbol-mangling-version=v0"]

Rust Blog

Launching the 2025 State of Rust Survey

It’s time for the 2025 State of Rust Survey!

The Rust Project has been collecting valuable information about the Rust programming language community through our annual State of Rust Survey since 2016. Which means that this year marks the tenth edition of this survey!

We invite you to take this year’s survey whether you have just begun using Rust, you consider yourself an intermediate to advanced user, or you have not yet used Rust but intend to one day. The results will allow us to more deeply understand the global Rust community and how it evolves over time.

Like last year, the 2025 State of Rust Survey will likely take you between 10 and 25 minutes, and responses are anonymous. We will accept submissions until December 17. Trends and key insights will be shared on blog.rust-lang.org as soon as possible.

We are offering the State of Rust Survey in the following languages (if you speak multiple languages, please pick one). Language options are available on the main survey page:

  • English
  • Chinese (Simplified)
  • Chinese (Traditional)
  • French
  • German
  • Japanese
  • Ukrainian
  • Russian
  • Spanish
  • Portuguese (Brazil)

Note: the non-English translations of the survey are provided in a best-effort manner. If you find any issues with the translations, we would be glad if you could send us a pull request to improve the quality of the translations!

Please help us spread the word by sharing the survey link via your social media networks, at meetups, with colleagues, and in any other community that makes sense to you.

This survey would not be possible without the time, resources, and attention of the Rust Survey Team, the Rust Foundation, and other collaborators. We would also like to thank the following contributors who helped with translating the survey (in no particular order):

Thank you!

If you have any questions, please see our frequently asked questions.

We appreciate your participation!

Click here to read a summary of last year's survey findings.

By the way, the Rust Survey team is looking for new members. If you like working with data and coordinating people, and would like to help us out with managing various Rust surveys, please drop by our Zulip channel and say hi.

Continue Reading…

Rust Blog

Announcing Rust 1.91.1

The Rust team has published a new point release of Rust, 1.91.1. Rust is a programming language that is empowering everyone to build reliable and efficient software.

If you have a previous version of Rust installed via rustup, getting Rust 1.91.1 is as easy as:

rustup update stable

If you don't have it already, you can get rustup from the appropriate page on our website.

What's in 1.91.1

Rust 1.91.1 includes fixes for two regressions introduced in the 1.91.0 release.

Linker and runtime errors on Wasm

Most targets supported by Rust identify symbols by their name, but Wasm identifies them with a symbol name and a Wasm module name. The#[link(wasm_import_module)] attribute allows to customize the Wasm module name an extern block refers to:

#[link(wasm_import_module = "hello")]
extern "C" {
    pub fn world();
}

Rust 1.91.0 introduced a regression in the attribute, which could cause linker failures during compilation ("import module mismatch" errors) or the wrong function being used at runtime (leading to undefined behavior, including crashes and silent data corruption). This happened when the same symbol name was imported from two different Wasm modules across multiple Rust crates.

Rust 1.91.1 fixes the regression. More details are available in issue #148347.

Cargo target directory locking broken on illumos

Cargo relies on locking the target/ directory during a build to prevent concurrent invocations of Cargo from interfering with each other. Not all filesystems support locking (most notably some networked ones): if the OS returns the Unsupported error when attempting to lock, Cargo assumes locking is not supported and proceeds without it.

Cargo 1.91.0 switched from custom code interacting with the OS APIs to theFile::lock standard library method (recently stabilized in Rust 1.89.0). Due to an oversight, that method always returned Unsupported on the illumos target, causing Cargo to never lock the build directory on illumos regardless of whether the filesystem supported it.

Rust 1.91.1 fixes the oversight in the standard library by enabling theFile::lock family of functions on illumos, indirectly fixing the Cargo regression.

Contributors to 1.91.1

Many people came together to create Rust 1.91.1. We couldn't have done it without all of you. Thanks!

Continue Reading…

Rust Blog

Announcing Rust 1.91.0

The Rust team is happy to announce a new version of Rust, 1.91.0. Rust is a programming language empowering everyone to build reliable and efficient software.

If you have a previous version of Rust installed via rustup, you can get 1.91.0 with:

$ rustup update stable

If you don't have it already, you can get rustup from the appropriate page on our website, and check out the detailed release notes for 1.91.0.

If you'd like to help us out by testing future releases, you might consider updating locally to use the beta channel (rustup default beta) or the nightly channel (rustup default nightly). Please report any bugs you might come across!

What's in 1.91.0 stable

aarch64-pc-windows-msvc is now a Tier 1 platform

The Rust compiler supports a wide variety of targets, but the Rust Team can't provide the same level of support for all of them. To clearly mark how supported each target is, we use a tiering system:

  • Tier 3 targets are technically supported by the compiler, but we don't check whether their code build or passes the tests, and we don't provide any prebuilt binaries as part of our releases.
  • Tier 2 targets are guaranteed to build and we provide prebuilt binaries, but we don't execute the test suite on those platforms: the produced binaries might not work or might have bugs.
  • Tier 1 targets provide the highest support guarantee, and we run the full suite on those platforms for every change merged in the compiler. Prebuilt binaries are also available.

Rust 1.91.0 promotes the aarch64-pc-windows-msvc target to Tier 1 support, bringing our highest guarantees to users of 64-bit ARM systems running Windows.

Add lint against dangling raw pointers from local variables

While Rust's borrow checking prevents dangling references from being returned, it doesn't track raw pointers. With this release, we are adding a warn-by-default lint on raw pointers to local variables being returned from functions. For example, code like this:

fn f() -> *const u8 {
    let x = 0;
    &x
}

will now produce a lint:

warning: a dangling pointer will be produced because the local variable `x` will be dropped
 --> src/lib.rs:3:5
  |
1 | fn f() -> *const u8 {
  |           --------- return type of the function is `*const u8`
2 |     let x = 0;
  |         - `x` is part the function and will be dropped at the end of the function
3 |     &x
  |     ^^
  |
  = note: pointers do not have a lifetime; after returning, the `u8` will be deallocated
    at the end of the function because nothing is referencing it as far as the type system is
    concerned
  = note: `#[warn(dangling_pointers_from_locals)]` on by default

Note that the code above is not unsafe, as it itself doesn't perform any dangerous operations. Only dereferencing the raw pointer after the function returns would be unsafe. We expect future releases of Rust to add more functionality helping authors to safely interact with raw pointers, and with unsafe code more generally.

Stabilized APIs

These previously stable APIs are now stable in const contexts:

Platform Support

Refer to Rust’s platform support page for more information on Rust’s tiered platform support.

Other changes

Check out everything that changed in Rust, Cargo, and Clippy.

Contributors to 1.91.0

Many people came together to create Rust 1.91.0. We couldn't have done it without all of you. Thanks!

Continue Reading…

Rust Blog

Project goals for 2025H2

On Sep 9, we merged RFC 3849, declaring our goals for the "second half" of 2025H2 -- well, the last 3 months, at least, since "yours truly" ran a bit behind getting the goals program organized.

Flagship themes

In prior goals programs, we had a few major flagship goals, but since many of these goals were multi-year programs, it was hard to see what progress had been made. This time we decided to organize things a bit differently. We established four flagship themes, each of which covers a number of more specific goals. These themes cover the goals we expect to be the most impactful and constitute our major focus as a Project for the remainder of the year. The four themes identified in the RFC are as follows:

  • Beyond the &, making it possible to create user-defined smart pointers that are as ergonomic as Rust's built-in references &.
  • Unblocking dormant traits, extending the core capabilities of Rust's trait system to unblock long-desired features for language interop, lending iteration, and more.
  • Flexible, fast(er) compilation, making it faster to build Rust programs and improving support for specialized build scenarios like embedded usage and sanitizers.
  • Higher-level Rust, making higher-level usage patterns in Rust easier.

"Beyond the &"

| Goal | Point of contact | Team(s) and Champion(s) | | ---------------------------------------------------------- | -------------------- | ------------------------------------------------------------------ | | Reborrow traits | Aapo Alasuutari | compiler (Oliver Scherer), lang (Tyler Mandry) | | Design a language feature to solve Field Projections | Benno Lossin | lang (Tyler Mandry) | | Continue Experimentation with Pin Ergonomics | Frank King | compiler (Oliver Scherer), lang (TC) |

One of Rust's core value propositions is that it's a "library-based language"—libraries can build abstractions that feel built-in to the language even when they're not. Smart pointer types like Rc and Arc are prime examples, implemented purely in the standard library yet feeling like native language features. However, Rust's built-in reference types (&T and &mut T) have special capabilities that user-defined smart pointers cannot replicate. This creates a "second-class citizen" problem where custom pointer types can't provide the same ergonomic experience as built-in references.

The "Beyond the &" initiative aims to share the special capabilities of &, allowing library authors to create smart pointers that are truly indistinguishable from built-in references in terms of syntax and ergonomics. This will enable more ergonomic smart pointers for use in cross-language interop (e.g., references to objects in other languages like C++ or Python) and for low-level projects like Rust for Linux that use smart pointers to express particular data structures.

"Unblocking dormant traits"

| Goal | Point of contact | Team(s) and Champion(s) | | ---------------------------------------------- | ------------------- | ------------------------------------------------------------------------------------------------------------------- | | Evolving trait hierarchies | Taylor Cramer | compiler, lang (Taylor Cramer), libs-api, types (Oliver Scherer) | | In-place initialization | Alice Ryhl | lang (Taylor Cramer) | | Next-generation trait solver | lcnr | types (lcnr) | | Stabilizable Polonius support on nightly | Rémy Rakic | types (Jack Huey) | | SVE and SME on AArch64 | David Wood | compiler (David Wood), lang (Niko Matsakis), libs (Amanieu d'Antras), types |

Rust's trait system is one of its most powerful features, but it has a number of longstanding limitations that are preventing us from adopting new patterns. The goals in this category unblock a number of new capabilities:

  • Polonius will enable new borrowing patterns, and in particular unblock "lending iterators". Over the last few goal periods, we have identified an "alpha" version of Polonius that addresses the most important cases while being relatively simple and optimizable. Our goal for 2025H2 is to implement this algorithm in a form that is ready for stabilization in 2026.
  • The next-generation trait solver is a refactored trait solver that unblocks better support for numerous language features (implied bounds, negative impls, the list goes on) in addition to closing a number of existing bugs and sources of unsoundness. Over the last few goal periods, the trait solver went from being an early prototype to being in production use for coherence checking. The goal for 2025H2 is to prepare it for stabilization.
  • The work on evolving trait hierarchies will make it possible to refactor some parts of an existing trait into a new supertrait so they can be used on their own. This unblocks a number of features where the existing trait is insufficiently general, in particular stabilizing support for custom receiver types, a prior Project goal that wound up blocked on this refactoring. This will also make it safer to provide stable traits in the standard library while preserving the ability to evolve them in the future.
  • The work to expand Rust's Sized hierarchy will permit us to express types that are neither Sized nor ?Sized, such as extern types (which have no size) or Arm's Scalable Vector Extension (which have a size that is known at runtime but not at compilation time). This goal builds on RFC #3729 and RFC #3838, authored in previous Project goal periods.
  • In-place initialization allows creating structs and values that are tied to a particular place in memory. While useful directly for projects doing advanced C interop, it also unblocks expanding dyn Trait to support async fn and -> impl Trait methods, as compiling such methods requires the ability for the callee to return a future whose size is not known to the caller.

"Flexible, fast(er) compilation"

| Goal | Point of contact | Team(s) and Champion(s) | | ---------------------------------------- | ---------------------- | ---------------------------------------------------------------------------------------------------- | | build-std | David Wood | cargo (Eric Huss), compiler (David Wood), libs (Amanieu d'Antras) | | Promoting Parallel Front End | Sparrow Li | compiler | | Production-ready cranelift backend | Folkert de Vries | compiler, wg-compiler-performance |

The "Flexible, fast(er) compilation" initiative focuses on improving Rust's build system to better serve both specialized use cases and everyday development workflows:

"Higher-level Rust"

| Goal | Point of contact | Team(s) and Champion(s) | | ------------------------------------------------------ | ------------------- | ------------------------------------------------------------------------------------------------------------------ | | Stabilize cargo-script | Ed Page | cargo (Ed Page), compiler, lang (Josh Triplett), lang-docs (Josh Triplett) | | Ergonomic ref-counting: RFC decision and preview | Niko Matsakis | compiler (Santiago Pastorino), lang (Niko Matsakis) |

People generally start using Rust for foundational use cases, where the requirements for performance or reliability make it an obvious choice. But once they get used to it, they often find themselves turning to Rust even for higher-level use cases, like scripting, web services, or even GUI applications. Rust is often "surprisingly tolerable" for these high-level use cases -- except for some specific pain points that, while they impact everyone using Rust, hit these use cases particularly hard. We plan two flagship goals this period in this area:

  • We aim to stabilize cargo script, a feature that allows single-file Rust programs that embed their dependencies, making it much easier to write small utilities, share code examples, and create reproducible bug reports without the overhead of full Cargo projects.
  • We aim to finalize the design of ergonomic ref-counting and to finalize the experimental impl feature so it is ready for beta testing. Ergonomic ref-counting makes it less cumbersome to work with ref-counted types like Rc and Arc, particularly in closures.

What to expect next

For the remainder of 2025 you can expect monthly blog posts covering the major progress on the Project goals.

Looking at the broader picture, we have now done three iterations of the goals program, and we want to judge how it should be run going forward. To start, Nandini Sharma from CMU has been conducting interviews with various Project members to help us see what's working with the goals program and what could be improved. We expect to spend some time discussing what we should do and to be launching the next iteration of the goals program next year. Whatever form that winds up taking, Tomas Sedovic, the Rust program manager hired by the Leadership Council, will join me in running the program.

Appendix: Full list of Project goals.

Read the full slate of Rust Project goals.

The full slate of Project goals is as follows. These goals all have identified points of contact who will drive the work forward as well as a viable work plan.

Invited goals. Some of the goals below are "invited goals", meaning that for that goal to happen we need someone to step up and serve as a point of contact. To find the invited goals, look for the "Help wanted" badge in the table below. Invited goals have reserved capacity for teams and a mentor, so if you are someone looking to help Rust progress, they are a great way to get involved.

| Goal | Point of contact | Team(s) and Champion(s) | | ----------------------------------------------------------------------------- | ----------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------- | | Develop the capabilities to keep the FLS up to date | Pete LeVasseur | bootstrap (Jakub Beránek), lang (Niko Matsakis), opsem, spec (Pete LeVasseur), types | | Getting Rust for Linux into stable Rust: compiler features | Tomas Sedovic | compiler (Wesley Wiser) | | Getting Rust for Linux into stable Rust: language features | Tomas Sedovic | lang (Josh Triplett), lang-docs (TC) | | Borrow checking in a-mir-formality | Niko Matsakis | types (Niko Matsakis) | | Reborrow traits | Aapo Alasuutari | compiler (Oliver Scherer), lang (Tyler Mandry) | | build-std | David Wood | cargo (Eric Huss), compiler (David Wood), libs (Amanieu d'Antras) | | Prototype Cargo build analysis | Weihang Lo | cargo (Weihang Lo) | | Rework Cargo Build Dir Layout | Ross Sullivan | cargo (Weihang Lo) | | Prototype a new set of Cargo "plumbing" commands | Help Wanted | cargo | | Stabilize cargo-script | Ed Page | cargo (Ed Page), compiler, lang (Josh Triplett), lang-docs (Josh Triplett) | | Continue resolving cargo-semver-checks blockers for merging into cargo | Predrag Gruevski | cargo (Ed Page), rustdoc (Alona Enraght-Moony) | | Emit Retags in Codegen | Ian McCormack | compiler (Ralf Jung), opsem (Ralf Jung) | | Comprehensive niche checks for Rust | Bastian Kersting | compiler (Ben Kimock), opsem (Ben Kimock) | | Const Generics | Boxy | lang (Niko Matsakis) | | Ergonomic ref-counting: RFC decision and preview | Niko Matsakis | compiler (Santiago Pastorino), lang (Niko Matsakis) | | Evolving trait hierarchies | Taylor Cramer | compiler, lang (Taylor Cramer), libs-api, types (Oliver Scherer) | | Design a language feature to solve Field Projections | Benno Lossin | lang (Tyler Mandry) | | Finish the std::offload module | Manuel Drehwald | compiler (Manuel Drehwald), lang (TC) | | Run more tests for GCC backend in the Rust's CI | Guillaume Gomez | compiler (Wesley Wiser), infra (Marco Ieni) | | In-place initialization | Alice Ryhl | lang (Taylor Cramer) | | C++/Rust Interop Problem Space Mapping | Jon Bauman | compiler (Oliver Scherer), lang (Tyler Mandry), libs (David Tolnay), opsem | | Finish the libtest json output experiment | Ed Page | cargo (Ed Page), libs-api, testing-devex | | MIR move elimination | Amanieu d'Antras | compiler, lang (Amanieu d'Antras), opsem, wg-mir-opt | | Next-generation trait solver | lcnr | types (lcnr) | | Implement Open API Namespace Support | Help Wanted | cargo (Ed Page), compiler (b-naber), crates-io (Carol Nichols) | | Promoting Parallel Front End | Sparrow Li | compiler | | Continue Experimentation with Pin Ergonomics | Frank King | compiler (Oliver Scherer), lang (TC) | | Stabilizable Polonius support on nightly | Rémy Rakic | types (Jack Huey) | | Production-ready cranelift backend | Folkert de Vries | compiler, wg-compiler-performance | | Stabilize public/private dependencies | Help Wanted | cargo (Ed Page), compiler | | Expand the Rust Reference to specify more aspects of the Rust language | Josh Triplett | lang-docs (Josh Triplett), spec (Josh Triplett) | | reflection and comptime | Oliver Scherer | compiler (Oliver Scherer), lang (Scott McMurray), libs (Josh Triplett) | | Relink don't Rebuild | Jane Lusby | cargo, compiler | | Rust Vision Document | Niko Matsakis | leadership-council | | rustc-perf improvements | James | compiler, infra | | Stabilize rustdoc doc_cfg feature | Guillaume Gomez | rustdoc (Guillaume Gomez) | | Add a team charter for rustdoc team | Guillaume Gomez | rustdoc (Guillaume Gomez) | | SVE and SME on AArch64 | David Wood | compiler (David Wood), lang (Niko Matsakis), libs (Amanieu d'Antras), types | | Rust Stabilization of MemorySanitizer and ThreadSanitizer Support | Jakob Koschel | bootstrap, compiler, infra, project-exploit-mitigations | | Type System Documentation | Boxy | types (Boxy) | | Unsafe Fields | Jack Wrenn | compiler (Jack Wrenn), lang (Scott McMurray) |

Continue Reading…

Rust Blog

docs.rs: changed default targets

Changes to default build targets on docs.rs

This post announces two changes to the list of default targets used to build documentation on docs.rs.

Crate authors can specify a custom list of targets usingdocs.rs metadata in Cargo.toml. If this metadata is not provided, docs.rs falls back to a default list. We are updating this list to better reflect the current state of the Rust ecosystem.

Apple silicon (ARM64) replaces x86_64

Reflecting Apple's transition from x86_64 to its own ARM64 silicon, the Rust project has updated its platform support tiers. The aarch64-apple-darwintarget is now Tier 1, while x86_64-apple-darwin has moved to Tier 2. You can read more about this in RFC 3671and RFC 3841.

To align with this, docs.rs will now use aarch64-apple-darwin as the default target for Apple platforms instead of x86_64-apple-darwin.

Linux ARM64 replaces 32-bit x86

Support for 32-bit i686 architectures is declining, and major Linux distributions have begun to phase it out.

Consequently, we are replacing the i686-unknown-linux-gnu target withaarch64-unknown-linux-gnu in our default set.

New default target list

The updated list of default targets is:

  • x86_64-unknown-linux-gnu
  • aarch64-apple-darwin (replaces x86_64-apple-darwin)
  • x86_64-pc-windows-msvc
  • aarch64-unknown-linux-gnu (replaces i686-unknown-linux-gnu)
  • i686-pc-windows-msvc

Opting out

If your crate requires the previous default target list, you can explicitly define it in your Cargo.toml:

[package.metadata.docs.rs]
targets = [
    "x86_64-unknown-linux-gnu",
    "x86_64-apple-darwin",
    "x86_64-pc-windows-msvc",
    "i686-unknown-linux-gnu",
    "i686-pc-windows-msvc"
]

Note that docs.rs continues to support any target available in the Rust toolchain; only the default list has changed.

Continue Reading…

Rust Blog

Announcing the New Rust Project Directors

We are happy to announce that we have completed the annual process to elect new Project Directors.

The new Project Directors are:

They will join Ryan Levick and Carol Nichols to make up the five members of the Rust Foundation Board of Directors who represent the Rust Project.

We would also like to thank the outgoing going Project Directors for contributions and service:

The board is made up of Project Directors, who come from and represent the Rust Project, and Member Directors, who represent the corporate members of the Rust Foundation. Both of these director groups have equal voting power.

We look forward to working with and being represented by this new group of project directors.

We were fortunate to have a number of excellent candidates and this was a difficult decision. We wish to express our gratitude to all of the candidates who were considered for this role! We also extend our thanks to the project as a whole who participated by nominating candidates and providing additional feedback once the nominees were published.

Finally, we want to share our appreciation for Tomas Sedovic for facilitating the election process. An overview of the election process can be found in a previous blog post here.

Continue Reading…

Rust Blog

crates.io: Malicious crates faster_log and async_println

Summary

On September 24th, the crates.io team was notified by Kirill Boychenko from the Socket Threat Research Team of two malicious crates which were actively searching file contents for Etherum private keys, Solana private keys, and arbitrary byte arrays for exfiltration.

These crates were:

  • faster_log - Published on May 25th, 2025, downloaded 7181 times
  • async_println - Published on May 25th, 2025, downloaded 1243 times

The malicious code was executed at runtime, when running or testing a project depending on them. Notably, they did not execute any malicious code at build time. Except for their malicious payload, these crates copied the source code, features, and documentation of legitimate crates, using a similiar name to them (a case of typosquatting1).

Actions taken

The users in question were immediately disabled, and the crates in question were deleted2 from crates.io shortly after. We have retained copies of all logs associated with the users and the malicious crate files for further analysis.

The deletion was performed at 15:34 UTC on September 24, 2025.

Analysis

Both crates were copies of a crate which provided logging functionality, and the logging implementation remained functional in the malicious crates. The original crate had a feature which performed log file packing, which iterated over an associated directories files.

The attacker inserted code to perform the malicious action during a log packing operation, which searched the log files being processed from that directory for:

  • Quoted Ethereum private keys (0x + 64 hex)
  • Solana-style Base58 secrets
  • Bracketed byte arrays

The crates then proceeded to exfiltrate the results of this search to https://mainnet[.]solana-rpc-pool[.]workers[.]dev/.

These crates had no dependent downstream crates on crates.io.

The malicious users associated with these crates had no other crates or publishes, and the team is actively investigating associative actions in our retained3 logs.

Thanks

Our thanks to Kirill Boychenko from the Socket Threat Research Team for reporting the crates. We also want to thank Carol Nichols from the crates.io team, Pietro Albini from the Rust Security Response WG and Walter Pearce from the Rust Foundation for aiding in the response.

  1. typosquatting is a technique used by bad actors to initiate dependency confusion attacks where a legitimate user might be tricked into using a malicious dependency instead of their intended dependency — for example, a bad actor might try to publish a crate at proc-macro3 to catch users of the legitimate proc-macro2 crate.
  2. The crates were preserved for future analysis should there be other attacks, and to inform scanning efforts in the future.
  3. One year of logs are retained on crates.io, but only 30 days are immediately available on our log platform. We chose not to go further back in our analysis, since IP address based analysis is limited by the use of dynamic IP addresses in the wild, and the relevant IP address being part of an allocation to a residential ISP.

Continue Reading…

Rust Blog

Announcing Rust 1.90.0

The Rust team is happy to announce a new version of Rust, 1.90.0. Rust is a programming language empowering everyone to build reliable and efficient software.

If you have a previous version of Rust installed via rustup, you can get 1.90.0 with:

$ rustup update stable

If you don't have it already, you can get rustup from the appropriate page on our website, and check out the detailed release notes for 1.90.0.

If you'd like to help us out by testing future releases, you might consider updating locally to use the beta channel (rustup default beta) or the nightly channel (rustup default nightly). Please report any bugs you might come across!

What's in 1.90.0 stable

LLD is now the default linker on x86_64-unknown-linux-gnu

The x86_64-unknown-linux-gnu target will now use the LLD linker for linking Rust crates by default. This should result in improved linking performance vs the default Linux linker (BFD), particularly for large binaries, binaries with a lot of debug information, and for incremental rebuilds.

In the vast majority of cases, LLD should be backwards compatible with BFD, and you should not see any difference other than reduced compilation time. However, if you do run into any new linker issues, you can always opt out using the -C linker-features=-lld compiler flag. Either by adding it to the usual RUSTFLAGS environment variable, or to a project's .cargo/config.toml configuration file, like so:

[target.x86_64-unknown-linux-gnu]
rustflags = ["-Clinker-features=-lld"]

If you encounter any issues with the LLD linker, please let us know. You can read more about the switch to LLD, some benchmark numbers and the opt out mechanism here.

Cargo adds native support for workspace publishing

cargo publish --workspace is now supported, automatically publishing all of the crates in a workspace in the right order (following any dependencies between them).

This has long been possible with external tooling or manual ordering of individual publishes, but this brings the functionality into Cargo itself.

Native integration allows Cargo's publish verification to run a build across the full set of to-be-published crates as if they were published, including during dry-runs. Note that publishes are still not atomic -- network errors or server-side failures can still lead to a partially published workspace.

Demoting x86_64-apple-darwin to Tier 2 with host tools

GitHub will soon discontinue providing free macOS x86_64 runners for public repositories. Apple has also announced their plans for discontinuing support for the x86_64 architecture.

In accordance with these changes, as of Rust 1.90, we have demoted the x86_64-apple-darwin target from Tier 1 with host tools to Tier 2 with host tools. This means that the target, including tools like rustc and cargo, will be guaranteed to build but is not guaranteed to pass our automated test suite.

For users, this change will not immediately cause impact. Builds of both the standard library and the compiler will still be distributed by the Rust Project for use via rustup or alternative installation methods while the target remains at Tier 2. Over time, it's likely that reduced test coverage for this target will cause things to break or fall out of compatibility with no further announcements.

Stabilized APIs

These previously stable APIs are now stable in const contexts:

Platform Support

  • x86_64-apple-darwin is now a tier 2 target

Refer to Rust’s platform support page for more information on Rust’s tiered platform support.

Other changes

Check out everything that changed in Rust, Cargo, and Clippy.

Contributors to 1.90.0

Many people came together to create Rust 1.90.0. We couldn't have done it without all of you. Thanks!

Continue Reading…

Rust Blog

crates.io phishing campaign

We received multiple reports of a phishing campaign targeting crates.io users (from the rustfoundation.dev domain name), mentioning a compromise of our infrastructure and asking users to authenticate to limit damage to their crates.

These emails are malicious and come from a domain name not controlled by the Rust Foundation (nor the Rust Project), seemingly with the purpose of stealing your GitHub credentials. We have no evidence of a compromise of the crates.io infrastructure.

We are taking steps to get the domain name taken down and to monitor for suspicious activity on crates.io. Do not follow any links in these emails if you receive them, and mark them as phishing with your email provider.

If you have any further questions please reach out to security@rust-lang.organd help@crates.io.

Continue Reading…

Rust Blog

Rust compiler performance survey 2025 results

Two months ago, we launched the first Rust Compiler Performance Survey, with the goal of helping us understand the biggest pain points of Rust developers related to build performance. It is clear that this topic is very important for the Rust community, as the survey received over 3 700 responses! We would like to thank everyone who participated in the survey, and especially those who described their workflows and challenges with an open answer. We plan to run this survey annually, so that we can observe long-term trends in Rust build performance and its perception.

In this post, we'll show some interesting results and insights that we got from the survey and promote work that we have already done recently or that we plan to do to improve the build performance of Rust code. If you would like to examine the complete results of the survey, you can find them here.

And now strap in, as there is a lot of data to explore! As this post is relatively long, here is an index of topics that it covers:

Overall satisfaction

To understand the overall sentiment, we asked our respondents to rate their satisfaction with their build performance, on a scale from 0 (worst) to 10 (best). The average rating was 6, with most people rating their experience with 7 out of 10:

[PNG] [SVG]

To help us understand the overall build experience in more detail, we also analyzed all open answers (over a thousand of them) written by our respondents, to help us identify several recurring themes, which we will discuss in this post.

One thing that is clear from both the satisfaction rating and the open answers is that the build experience differs wildly across users and workflows, and it is not as clear-cut as "Rust builds are slow". We actually received many positive comments about users being happy with Rust build performance, and appreciation for it being improved vastly over the past several years to the point where it stopped being a problem.

People also liked to compare their experience with other competing technologies. For example, many people wrote that the build performance of Rust is not worse, or is even better, than what they saw with C++. On the other hand, others noted that the build performance of languages such as Go or Zig is much better than that of Rust.

While it is great to see some developers being happy with the state we have today, it is clear that many people are not so lucky, and Rust's build performance limits their productivity. Around 45% respondents who answered that they are no longer using Rust said that at least one of the reasons why they stopped were long compile times.

In our survey we received a lot of feedback pointing out real issues and challenges in several areas of build performance, which is what we will focus on in this post.

Important workflows

The challenges that Rust developers experience with build performance are not always as simple as the compiler itself being slow. There are many diverse workflows with competing trade-offs, and optimizing build performance for them might require completely different solutions. Some approaches for improving build performance can also be quite unintuitive. For example, stabilizing certain language features could help remove the need for certain build scripts or proc macros, and thus speed up compilation across the Rust ecosystem. You can watch this talk from RustWeek about build performance to learn more.

It is difficult to enumerate all possible build workflows, but we at least tried to ask about workflows that we assumed are common and could limit the productivity of Rust developers the most:

[PNG] [SVG]

We can see that all the workflows that we asked about cause significant problems to at least a fraction of the respondents, but some of them more so than others. To gain more information about the specific problems that developers face, we also asked a more detailed, follow-up question:

[PNG] [SVG]

Based on the answers to these two questions and other experiences shared in the open answers, we identified three groups of workflows that we will discuss next:

  • Incremental rebuilds after making a small change
  • Type checking using cargo check or with a code editor
  • Clean, from-scratch builds, including CI builds

Incremental rebuilds

Waiting too long for an incremental rebuild after making a small source code change was by far the most common complaint in the open answers that we received, and it was also the most common problem that respondents said they struggle with. Based on our respondents' answers, this comes down to three main bottlenecks:

  • Changes in workspaces trigger unnecessary rebuilds. If you modify a crate in a workspace that has several dependent crates and perform a rebuild, all those dependent crates will currently have to be recompiled. This can cause a lot of unnecessary work and dramatically increase the latency of rebuilds in large (or deep) workspaces. We have some ideas about how to improve this workflow, such as the "Relink, don't rebuild" proposal, but these are currently in a very experimental stage.
  • The linking phase is too slow. This was a very common complaint, and it is indeed a real issue, because unlike the rest of the compilation process, linking is always performed "from scratch". The Rust compiler usually delegates linking to an external/system linker, so its performance is not completely within our hands. However, we are attempting to switch to faster linkers by default. For example, the most popular target (x86_64-unknown-linux-gnu) will very soon switch to the LLD linker, which provides significant performance wins. Long-term, it is possible that some linkers (e.g. wild) will allow us to perform even linking incrementally.
  • Incremental rebuild of a single crate is too slow. The performance of this workflow depends on the cleverness of the incremental engine of the Rust compiler. While it is already very sophisticated, there are some parts of the compilation process that are not incremental yet or that are not cached in an optimal way. For example, expansion of derive proc macros is not currently cached, although work is underway to change that.

Several users have mentioned that they would like to see Rust perform hot-patching (such as the subsecond system used by the Dioxus UI framework or similar approaches used e.g. by the Bevy game engine). While these hot-patching systems are very exciting and can produce truly near-instant rebuild times for specialized use-cases, it should be noted that they also come with many limitations and edge-cases, and it does not seem that a solution that would allow hot-patching to work in a robust way has been found yet.

To gauge how long is the typical rebuild latency, we asked our respondents to pick a single Rust project that they work on and which causes them to struggle with build times the most, and tell us how long they have to wait for it to be rebuilt after making a code change.

[PNG] [SVG]

Even though many developers do not actually experience this latency after each code change, as they consume results of type checking or inline annotations in their code editor, the fact that 55% of respondents have to wait more than ten seconds for a rebuild is far from ideal.

If we partition these results based on answers to other questions, it is clear that the rebuild times depend a lot on the size of the project:

[PNG] [SVG]

And to a lesser factor also on the number of used dependencies:

[PNG] [SVG]

We would love to get to a point where the time needed to rebuild a Rust project is dependent primarily on the amount of performed code changes, rather than on the size of the codebase, but clearly we are not there yet.

Type checking and IDE performance

Approximately 60% of respondents say that they use cargo terminal commands to type check, build or test their code, with cargo check being the most commonly used command performed after each code change:

[PNG] [SVG]

While the performance of cargo check does not seem to be as big of a blocker as e.g. incremental rebuilds, it also causes some pain points. One of the most common ones present in the survey responses is the fact that cargo check does not share the build cache with cargo build. This causes additional compilation to happen when you run e.g. cargo check several times to find all type errors, and when it succeeds, you follow up with cargo build to actually produce a built artifact. This workflow is an example of competing trade-offs, because sharing the build cache between these two commands by unifying them more would likely make cargo check itself slightly slower, which might be undesirable to some users. It is possible that we might be able to find some middle ground to improve the status quo though. You can follow updates to this work in this issue.

A related aspect is the latency of type checking in code editors and IDEs. Around 87% of respondents say that they use inline annotations in their editor as the primary mechanism of inspecting compiler errors, and around 33% of them consider waiting for these annotations to be a big blocker. In the open answers, we also received many reports of Rust Analyzer's performance and memory usage being a limiting factor.

The maintainers of Rust Analyzer are working hard on improving its performance. Its caching system is being improved to reduce analysis latency, the distributed builds of the editor are now optimized with PGO, which provided 15-20% performance wins, and work is underway to integrate the compiler's new trait solver into Rust Analyzer, which could eventually also result in increased performance.

More than 35% users said that they consider the IDE and Cargo blocking one another to be a big problem. There is an existing workaround for this, where you can configure Rust Analyzer to use a different target directory than Cargo, at the cost of increased disk space usage. We realized that this workaround has not been documented in a very visible way, so we added it to the FAQ section of the Rust Analyzer book.

Clean and CI builds

Around 20% of participants responded that clean builds are a significant blocker for them. In order to improve their performance, you can try a recently introduced experimental Cargo and compiler option called hint-mostly-unused, which can in certain situations help improve the performance of clean builds, particularly if your dependencies contain a lot of code that might not actually be used by your crate(s).

One area where clean builds might happen often is Continuous Integration (CI). 1495 respondents said that they use CI to build Rust code, and around 25% of them consider its performance to be a big blocker for them. However, almost 36% of respondents who consider CI build performance to be a big issue said that they do not use any caching in CI, which we found surprising. One explanation might be that the generated artifacts (the target directory) is too large for effective caching, and runs into usage limits of CI providers, which is something that we saw mentioned repeatedly in the open answers section. We have recently introduced an experimental Cargo and compiler option called -Zembed-metadata that is designed to reduce the size of the target directories, and work is also underway to regularly garbage collect them. This might help with the disk space usage issue somewhat in the future.

One additional way to significantly reduce disk usage is to reduce the amount of generated debug information, which brings us to the next section.

Debug information

The default Cargo dev profile generates full debug information (debuginfo) both for workspace crates and also all dependencies. This enables stepping through code with a debugger, but it also increases disk usage of the target directory, and crucially it makes compilation and linking slower. This effect can be quite large, as our benchmarks show a possible improvement of 2-30% in cycle counts if we reduce the debuginfo level to line-tables-only (which only generates enough debuginfo for backtraces to work), and the improvements are even larger if we disable debuginfo generation completely1.

However, if Rust developers debug their code after most builds, then this cost might be justified. We thus asked them how often they use a debugger to debug their Rust code:

[PNG] [SVG]

Based on these results, it seems that the respondents of our survey do not actually use a debugger all that much2.

However, when we asked people if they require debuginfo to be generated by default, the responses were much less clear-cut:

[PNG] [SVG]

This is the problem with changing defaults: it is challenging to improve the workflows of one user without regressing the workflow of another. For completeness, here are the answers to the previous question partitioned on the answer to the "How often do you use a debugger" question:

[PNG] [SVG]

It was surprising for us to see that around a quarter of respondents who (almost) never use a debugger still want to have full debuginfo generated by default.

Of course, you can always disable debuginfo manually to improve your build performance, but not everyone knows about that option, and defaults matter a lot. The Cargo team is considering ways of changing the status quo, for example by reducing the level of generated debug information in the dev profile, and introducing a new built-in profile designed for debugging.

Workarounds for improving build performance

Build performance of Rust is affected by many different aspects, including the configuration of the build system (usually Cargo) and the Rust compiler, but also the organization of Rust crates and used source code patterns. There are thus several approaches that can be used to improve build performance by either using different configuration options or restructuring source code. We asked our respondents if they are even aware of such possibilities, whether they have tried them and how effective they were:

[PNG] [SVG]

It seems that the most popular (and effective) mechanisms for improving build performance are reducing the number of dependencies and their activated features, and splitting larger crates into smaller crates. The most common way of improving build performance without making source code changes seems to be the usage of an alternative linker. It seems that especially the mold and LLD linkers are very popular:

[PNG] [SVG] [Wordcloud of open answers]

We have good news here! The most popular x86_64-unknown-linux-gnu Linux target will start using the LLD linker in the next Rust stable release, resulting in faster link times by default. Over time, we will be able to evaluate how disruptive is this change to the overall Rust ecosystem, and whether we could e.g. switch to a different (even faster) linker.

Build performance guide

We were surprised by the relatively large number of users who were unaware of some approaches for improving compilation times, in particular those that are very easy to try and typically do not require source code changes (such as reducing debuginfo or using a different linker or a codegen backend). Furthermore, almost 42% of respondents have not tried to use any mechanism for improving build performance whatsoever. While this is not totally unexpected, as some of these mechanisms require using the nightly toolchain or making non-trivial changes to source code, we think that one the reasons is also simply that Rust developers might not know about these mechanisms being available. In the open answers, several people also noted that they would appreciate if there was some sort of official guidance from the Rust Project about such mechanisms for improving compile times.

It should be noted that the mechanisms that we asked about are in fact workarounds that present various trade-offs, and these should always be carefully considered. Several people have expressed dissatisfaction with some of these workarounds in the open answers, as they find it unacceptable to modify their code (which could sometimes result e.g. in increased maintenance costs or worse runtime performance) just to achieve reasonable compile times. Nevertheless, these workarounds can still be incredibly useful in some cases.

The feedback that we received shows that it might be beneficial to spread awareness of these mechanisms in the Rust community more, as some of them can make a really large difference in build performance, but also to candidly explain the trade-offs that they introduce. Even though several great resources that cover this topic already exist online, we decided to create an official guide for optimizing build performance (currently work-in-progress), which will likely be hosted in the Cargo book. The aim of this guide is to increase the awareness of various mechanisms for improving build performance, and also provide a framework for evaluating their trade-offs.

Our long-standing goal is to make compilation so fast that similar workarounds will not be necessary anymore for the vast majority of use-cases. However, there is no free lunch, and the combination of Rust's strong type system guarantees, its compilation model and also heavy focus on runtime performance often go against very fast (re)build performance, and might require usage of at least some workarounds. We hope that this guide will help Rust developers learn about them and evaluate them for their specific use-case.

Understanding why builds are slow

When Rust developers experience slow builds, it can be challenging to identify where exactly is the compilation process spending time, and what could be the bottleneck. It seems that only very few Rust developers leverage tools for profiling their builds:

[PNG] [SVG]

This hardly comes as a surprise. There are currently not that many ways of intuitively understanding the performance characteristics of Cargo and rustc. Some tools offer only a limited amount of information (e.g. cargo build --timings), and the output of others (e.g. -Zself-profile) is very hard to interpret without knowledge of the compiler internals.

To slightly improve this situation, we have recently added support for displaying link times to the cargo build --timings output, to provide more information about the possible bottleneck in crate compilation (note this feature has not been stabilized yet).

Long-term, it would be great to have tooling that could help Rust developers diagnose compilation bottlenecks in their crates without them having to understand how the compiler works. For example, it could help answer questions such as "Which code had to be recompiled after a given source change" or "Which (proc) macros take the longest time to expand or produce the largest output", and ideally even offer some actionable suggestions. We plan to work on such tooling, but it will take time to manifest.

One approach that could help Rust compiler contributors understand why are Rust (re)builds slow "in the wild" is the opt-in compilation metrics collection initiative.

What's next

There are more interesting things in the survey results, for example how do answers to selected questions differ based on the used operating system. You can examine the full results in the full report PDF.

We would like to thank once more everyone who has participated in our survey. It helped us understand which workflows are the most painful for Rust developers, and especially the open answers provided several great suggestions that we tried to act upon.

Even though the Rust compiler is getting increasingly faster every year, we understand that many Rust developers require truly significant improvements to improve their productivity, rather than "just" incremental performance wins. Our goal for the future is to finally stabilize long-standing initiatives that could improve build performance a lot, such as the Cranelift codegen backend or the parallel compiler frontend. One such initiative (using a faster linker by default) will finally land soon, but the fact that it took many years shows how difficult it is to make such large cutting changes to the compilation process.

There are other ambitious ideas for reducing (re)build times, such as avoiding unnecessary workspace rebuilds or e.g. using some form of incremental linking, but these will require a lot of work and design discussions.

We know that some people are wondering why it takes so much time to achieve progress in improving the build performance of Rust. The answer is relatively simple. These changes require a lot of work, domain knowledge (that takes a relatively long time to acquire) and many discussions and code reviews, and the pool of people that have time and motivation to work on them or review these changes is very limited. Current compiler maintainers and contributors (many of whom work on the compiler as volunteers, without any funding) work very hard to keep up with maintaining the compiler and keeping it working with the high-quality bar that Rust developers expect, across many targets, platforms and operating systems. Introducing large structural changes, which are likely needed to reach massive performance improvements, would require a lot of concentrated effort and funding.

  1. This benchmark was already performed using the fast LLD linker. If a slower linker was used, the build time wins would likely be even larger.
  2. Potentially because of the strong invariants upheld by the Rust type system, and partly also because the Rust debugging experience might not be optimal for many users, which is a feedback that we received in the State of Rust 2024 survey.
Rust Blog

Welcoming the Rust Innovation Lab

TL;DR: Rustls is the inaugural project of the Rust Innovation Lab, which is a new home for Rust projects under the Rust Foundation.

At the Rust Foundation's August meeting, the Project Directors and the rest of the Rust Foundation board voted to approve Rustls as the first project housed under the newly formed Rust Innovation Lab. Prior to the vote, the Project Directors consulted with the Leadership Council who confirmed the Project's support for this initiative.

The Rust Innovation Lab (RIL) is designed to provide support for funded Rust-based open source projects from the Rust Foundation in the form of governance, legal, networking, marketing, and administration, while keeping the technical direction solely in the hands of the current maintainers. As with the other work of the Rust Foundation (e.g. its many existing initiatives), the purpose of the RIL is to strengthen the Rust ecosystem generally.

The Foundation has been working behind the scenes to establish the Rust Innovation Lab, which includes setting up infrastructure under the Foundation to ensure smooth transition for Rustls into RIL. More details are available in the Foundation's announcement and on the Rust Innovation Lab's page.

We are all excited by the formation of the Rust Innovation Lab. The support this initiative will provide to Rustls (and, eventually, other important projects that are using Rust) will improve software security for the entire industry. The Rust Project is grateful for the support of the Rust Foundation corporate members who are making this initiative possible for the benefit of everyone.

More information on the criteria for projects wishing to become part of the RIL and the process for applying will be coming soon. The Project Directors and Leadership Council have been and will continue working with the Foundation to communicate information, questions, and feedback with the Rust community about the RIL as the details are worked out.

Continue Reading…

Rust Blog

Faster linking times with 1.90.0 stable on Linux using the LLD linker

TL;DR: rustc will start using the LLD linker by default on the x86_64-unknown-linux-gnu target starting with the next stable release (1.90.0, scheduled for 2025-09-18), which should significantly reduce linking times. Test it out on beta now, and please report any encountered issues.

Some context

Linking time is often a big part of compilation time. When rustc needs to build a binary or a shared library, it will usually call the default linker installed on the system to do that (this can be changed on the command-line or by the target for which the code is compiled).

The linkers do an important job, with concerns about stability, backwards-compatibility and so on. For these and other reasons, on the most popular operating systems they usually are older programs, designed when computers only had a single core. So, they usually tend to be slow on a modern machine. For example, when building ripgrep 13 in debug mode on Linux, roughly half of the time is actually spent in the linker.

There are different linkers, however, and the usual advice to improve linking times is to use one of these newer and faster linkers, like LLVM's lld or Rui Ueyama's mold.

Some of Rust's wasm and aarch64 targets already use lld by default. When using rustup, rustc ships with a version of lld for this purpose. When CI builds LLVM to use in the compiler, it also builds the linker and packages it. It's referred to as rust-lld to avoid colliding with any lld already installed on the user's machine.

Since improvements to linking times are substantial, it would be a good default to use in the most popular targets. This has been discussed for a long time, for example in issues #39915 and #71515.

To expand our testing, we have enabled rustc to use rust-lld by default on nightly, in May 2024. No major issues have been reported since then.

We believe we've done all the internal testing that we could, on CI, crater, on our benchmarking infrastructure and on nightly, and plan to enable rust-lld to be the linker used by default on x86_64-unknown-linux-gnu for stable builds in 1.90.0.

Benefits

While this also enables the compiler to use more linker features in the future, the most immediate benefit is much improved linking times.

Here are more details from the ripgrep example mentioned above: for an incremental rebuild, linking is reduced 7x, resulting in a 40% reduction in end-to-end compilation times. For a from-scratch debug build, it is a 20% improvement.

Before/after comparison of a ripgrep incremental debug build

Most binaries should see some improvements here, but it's especially significant with e.g. bigger binaries, or for incremental rebuilds, or when involving debuginfo. These usually see bottlenecks in the linker.

Here's a link to the complete results from our benchmarks.

Possible drawbacks

From our prior testing, we don't really expect issues to happen in practice. It is a drop-in replacement for the vast majority of cases, but lld is not bug-for-bug compatible with GNU ld.

In any case, using rust-lld can be disabled if any problem occurs: use the -C linker-features=-lld flag to revert to using the system's default linker.

Some crates somehow relying on these differences could need additional link args, though we also expect this to be quite rare. Let us know if you encounter problems, by opening an issue on GitHub.

Some of the big gains in performance come from parallelism, which could be undesirable in resource-constrained environments, or for heavy projects that are already reaching hardware limits.

Summary, and call for testing

rustc will use rust-lld on x86_64-unknown-linux-gnu, starting with the 1.90.0 stable release, for much improved linking times. Rust 1.90.0 will be released next month, on the 18th of September 2025.

This linker change is already available on the current beta (1.90.0-beta.6). To help everyone prepare for this landing on stable, please test your projects on beta and let us know if you encounter problems, by opening an issue on GitHub.

If that happens, you can revert to the default linker with the -C linker-features=-lld flag. Either by adding it to the usual RUSTFLAGS environment variable, or to a project's .cargo/config.toml configuration file, like so:

[target.x86_64-unknown-linux-gnu]
rustflags = ["-Clinker-features=-lld"]