The Rust Programming Language Blog's Avatar

The Rust Programming Language Blog

@blog.rust-lang.org.web.brid.gy

Empowering everyone to build reliable and efficient software. [bridged from https://blog.rust-lang.org/ on the web: https://fed.brid.gy/web/blog.rust-lang.org ]

616
Followers
0
Following
218
Posts
01.01.0001
Joined
Posts Following

Latest posts by The Rust Programming Language Blog @blog.rust-lang.org.web.brid.gy

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 * `<[T]>::array_windows` * `<[T]>::element_offset` * `LazyCell::get` * `LazyCell::get_mut` * `LazyCell::force_mut` * `LazyLock::get` * `LazyLock::get_mut` * `LazyLock::force_mut` * `impl TryFrom<char> for usize` * `std::iter::Peekable::next_if_map` * `std::iter::Peekable::next_if_map_mut` * x86 `avx512fp16` intrinsics (excluding those that depend directly on the unstable `f16` type) * AArch64 NEON fp16 intrinsics (excluding those that depend directly on the unstable `f16` type) * `f32::consts::EULER_GAMMA` * `f64::consts::EULER_GAMMA` * `f32::consts::GOLDEN_RATIO` * `f64::consts::GOLDEN_RATIO` These previously stable APIs are now stable in const contexts: * `f32::mul_add` * `f64::mul_add` ### 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!
05.03.2026 00:00 πŸ‘ 0 πŸ” 0 πŸ’¬ 0 πŸ“Œ 0
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 * Challenges and wishes about Rust * Learning about Rust * Industry and community ## 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, here are some data about marginalized groups, out of all participants who completed our survey: Marginalized group| Count| Percentage ---|---|--- Lesbian, gay, bisexual, queer, or otherwise non-heterosexual| 752| 10.59% Neurodivergent| 706| 9.94% Trans| 548| 7.72% Woman or perceived as a woman| 457| 6.43% Non-binary gender| 292| 4.11% Disabled (physically, mentally, or otherwise)| 218| 3.07% Racial or ethnic minority| 217| 3.06% Political beliefs| 211| 2.97% Educational background| 170| 2.39% Cultural beliefs| 139| 1.96% Language| 134| 1.89% Religious beliefs| 100| 1.41% Other| 61| 0.86% Older or younger than the average developers I know| 22| 0.31% While some of these numbers have slightly improved, this still shows that only a very small percentage of the people who are part of marginalized groups make it to our project. While we still do better than many other tech communities, it is a reminder that we need to keep working hard on being a diverse and welcoming FOSS community _for everyone_ , which has always been and always will be one of our core values. ## 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: * 2024 State of Rust Survey results * 2023 Rust Annual Survey results * 2022 Rust Annual Survey results * 2021 Rust Survey results * 2020 Rust Survey results * 2019 Rust Survey results * 2018 Rust Survey results * 2017 Rust Survey results * 2016 State of Rust survey
02.03.2026 00:00 πŸ‘ 0 πŸ” 0 πŸ’¬ 0 πŸ“Œ 0
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 surveyhere.** 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!
23.02.2026 00:00 πŸ‘ 0 πŸ” 0 πŸ’¬ 0 πŸ“Œ 0
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.
19.02.2026 00:00 πŸ‘ 1 πŸ” 0 πŸ’¬ 0 πŸ“Œ 0
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.
13.02.2026 00:00 πŸ‘ 0 πŸ” 0 πŸ’¬ 0 πŸ“Œ 0
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. * Don't try to recover a keyword as a non-keyword identifier, fixing an internal compiler error (ICE) that especially affected rustfmt. * Fix a `clippy::panicking_unwrap` false-positive on field access with an implicit dereference. * Revert an update to wasm-related dependencies, fixing file descriptor leaks on the `wasm32-wasip2` target. This only affects the `rustup` component for this target, so downstream toolchain builds should check their own dependencies too. ### 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!
12.02.2026 00:00 πŸ‘ 0 πŸ” 0 πŸ’¬ 0 πŸ“Œ 0
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 `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.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!` and `std::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 * `<[MaybeUninit<T>]>::assume_init_drop` * `<[MaybeUninit<T>]>::assume_init_ref` * `<[MaybeUninit<T>]>::assume_init_mut` * `<[MaybeUninit<T>]>::write_copy_of_slice` * `<[MaybeUninit<T>]>::write_clone_of_slice` * `String::into_raw_parts` * `Vec::into_raw_parts` * `<iN>::unchecked_neg` * `<iN>::unchecked_shl` * `<iN>::unchecked_shr` * `<uN>::unchecked_shl` * `<uN>::unchecked_shr` * `<[T]>::as_array` * `<[T]>::as_mut_array` * `<*const [T]>::as_array` * `<*mut [T]>::as_mut_array` * `VecDeque::pop_front_if` * `VecDeque::pop_back_if` * `Duration::from_nanos_u128` * `char::MAX_LEN_UTF8` * `char::MAX_LEN_UTF16` * `std::fmt::from_fn` * `std::fmt::FromFn` ### 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!
22.01.2026 00:00 πŸ‘ 0 πŸ” 0 πŸ’¬ 0 πŸ“Œ 0
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. 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: 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!
21.01.2026 00:00 πŸ‘ 0 πŸ” 0 πŸ’¬ 0 πŸ“Œ 0
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. Inour 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. ↩
14.01.2026 00:00 πŸ‘ 0 πŸ” 0 πŸ’¬ 0 πŸ“Œ 0
Project goals update β€” December 2025 The Rust project is currently working towards a slate of 41 project goals, with 13 of them designated as Flagship Goals. This post provides selected updates on our progress towards these goals (or, in some cases, lack thereof). The full details for any particular goal are available in its associated tracking issue on the rust-project-goals repository. ## Flagship goals ### "Beyond the `&`" Continue Experimentation with Pin Ergonomics (rust-lang/rust-project-goals#389) Progress | ---|--- Point of contact | Frank King Champions | compiler (Oliver Scherer), lang (TC) Task owners | Frank King 1 detailed update available. Comment by @frank-king posted on 2025-12-18: * **Key developments** : forbid manual impl of `Unpin` for `#[pin_v2]` types. * **Blockers** : PRs waiting for review: * impl `Drop::pin_drop` (the submodule issue) * coercion of `&pin mut|const T` <-> `&[mut] T` * **Help wanted** : None yet. Design a language feature to solve Field Projections (rust-lang/rust-project-goals#390) Progress | ---|--- Point of contact | Benno Lossin Champions | lang (Tyler Mandry) Task owners | Benno Lossin 5 detailed updates available. Comment by @BennoLossin posted on 2025-12-07: Since we have chosen virtual places as the new approach, we reviewed what open questions are most pressing for the design. Our discussion resulted in the following five questions: 1. Should we have 1-level projections xor multi-level projections? 2. What is the semantic meaning of the borrow checker rules (`BorrowKind`)? 3. How should we add "canonical projections" for types such that we have nice and short syntax (like `x~y` or `x.@y`)? 4. What to do about non-indirected containers (Cell, MaybeUninit, Mutex, etc)? 5. How does one inspect/query `Projection` types? We will focus on these questions in December as well as implementing FRTs. Comment by @BennoLossin posted on 2025-12-12: ## Canonical Projections We have discussed canonical projections and come up with the following solution: pub trait CanonicalReborrow: HasPlace { type Output<'a, P: Projection<Source = Self::Target>>: HasPlace<Target = P::Target> where Self: PlaceBorrow<'a, P, Self::Output<'a, P>>; } Implementing this trait permits using the syntax `@$place_expr` where the place's origin is of the type `Self` (for example `@x.y` where `x: Self` and `y` is an identifier or tuple index, or `@x.y.z` etc). It is desugared to be: @<<Self as CanonicalReborrow>::Output<'_, projection_from_place_expr!($place_expr)>> $place_expr (The names of the trait, associated type and syntax are not final, better suggestions welcome.) ### Reasoning * We need the `Output` associated type to support the `@x.y` syntax for `Arc` and `ArcRef`. * We put the FRT and lifetime parameter on `Output` in order to force implementers to always provide a canonical reborrow, so if `@x.a` works, then `@x.b` also works (when `b` also is a field of the struct contained by `x`). * This (sadly or luckily) also has the effect that making `@x.a` and `@x.b` return different wrapper types is more difficult to implement and requires a fair bit of trait dancing. We should think about discouraging this in the documentation. Comment by @BennoLossin posted on 2025-12-16: ## Non-Indirected Containers Types like `MaybeUninit<T>`, `Cell<T>`, `ManuallyDrop<T>`, `RefCell<T>` etc. currently do not fit into our virtual places model, since they don't have an indirection. They contain the place directly inline (and some are even `repr(transparent)`). For this reason, we currently don't have projections available for `&mut MaybeUninit<T>`. Enter our new trait `PlaceWrapper` which these types implement in order to make projections available for them. We call these types _place wrappers_. Here is the definition of the trait: pub unsafe trait PlaceWrapper<P: Projection<Source = Self::Target>>: HasPlace { type WrappedProjection: Projection<Source = Self>; fn wrap_projection(p: P) -> Self::WrappedProjection; } This trait should only be implemented when `Self` doesn't contain the place as an indirection (so for example `Box` must not implement the trait). When this trait is implemented, then `Self` has "virtual fields" available (actually all kinds of place projections). The name of these virtual fields/projections is the same as the ones of the contained place. But their output type is controlled by this trait. As an example, here is the implementation for `MaybeUninit`: impl<T, P: Projection<Source = T>> PlaceWrapper<P> for MaybeUninit<T> { type WrappedProjection = TransparentProjection<P, MaybeUninit<T>, MaybeUninit<P::Target>>; fn wrap_projection(p: P) -> Self::WrappedProjection { TransparentProjection(p, PhantomData, PhantomData) } } Where `TransparentProjection` will be available in the standard library defined as: pub struct TransparentProjection<P, Src, Tgt>(P, PhantomData<Src>, PhantomData<Tgt>); impl<P: Projection, Src, Tgt> Projection for TransparentProjection<P, Src, Tgt> { type Source = Src; type Target = Tgt; fn offset(&self) -> usize { self.0.offset() } } When there is ambiguity, because the wrapper and the wrapped types both have the same field, the wrapper's field takes precedence (this is the same as it currently works for `Deref`). It is still possible to refer to the wrapped field by first dereferencing the container, so `x.field` refers to the wrapper's `field` and `(*x).field` refers to the field of the wrapped type. Comment by @BennoLossin posted on 2025-12-20: ## Field-by-Field Projections vs One-Shot Projections We have used several different names for these two ways of implementing projections. The first is also called 1-level projections and the second multi-level projections. The field-by-field approach uses field representing types (FRTs), which represent a single field of a struct with no indirection. When writing something like `@x.y.z`, we perform the place operation twice, first using the FRT `field_of!(X, y)` and then again with `field_of!(T, z)` where `T` is the resulting type of the first projection. The second approach called one-shot projections instead extends FRTs with _projections_ , these are compositions of FRTs, can be empty and dynamic. Using these we desugar `@x.y.z` to a single place operation. Field-by-field projections have the advantage that they simplify the implementation for users of the feature, the compiler implementation and the mental model that people will have to keep in mind when interacting with field projections. However, they also have pretty big downsides, which either are fundamental to their design or would require significant complification of the feature: * They have less expressiveness than one-shot projections. For example, when moving out a subsubfield of `x: &own Struct` by doing `let a = @x.field.a`, we have to move out `field`, which prevents us from later writing `let b = @x.field.b`. One-shot projections allow us to track individual subsubfields with the borrow checker. * Field-by-field projections also make it difficult to define type-changing projections in an inference friendly way. Projecting through multiple fields could result in several changes of types in between, so we would have to require only canonical projections in certain places. However, this requires certain intermediate types for which defining their safety invariants is very complex. We additionally note that the single function call desugaring is also a simplification that also lends itself much better when explaining what the `@` syntax does. All of this points in the direction of proceeding with one-shot projections and we will most likely do that. However, we must note that the field-by-field approach might yield easier trait definitions that make implementing the various place operations more manageable. There are several open issues on how to design the field-by-field API in the place variation (the previous proposal did have this mapped out clearly, but it does not translate very well to places), which would require significant effort to solve. So at this point we cannot really give a fair comparison. Our initial scouting of the solutions revealed that they all have some sort of limitation (as we explained above for intermediate projection types for example), which make field-by-field projections less desirable. So for the moment, we are set on one-shot projections, but when the time comes to write the RFC we need to revisit the idea of field-by-field projections. Comment by @BennoLossin posted on 2025-12-25: ## Wiki Project We started a wiki project at https://rust-lang.github.io/beyond-refs to map out the solution space. We intend to grow it into the single source of truth for the current state of the field projection proposal as well as unfinished and obsolete ideas and connections between them. Additionally, we will aim to add the same kind of information for the in-place initialization effort, since it has overlap with field projections and, more importantly, has a similarly large solution space. In the beginning you might find many stub pages in the wiki, which we will work on making more complete. We will also mark pages that contain old or abandoned ideas as such as well as mark the current proposal. This issue will continue to receive regular detailed updates, which are designed for those keeping reasonably up-to-date with the feature. For anyone out of the loop, the wiki project will be a much better place when it contains more content. Reborrow traits (rust-lang/rust-project-goals#399) Progress | ---|--- Point of contact | Aapo Alasuutari Champions | compiler (Oliver Scherer), lang (Tyler Mandry) Task owners | Aapo Alasuutari 1 detailed update available. Comment by @aapoalas posted on 2025-12-17: ## Purpose A refresher on what we want to achieve here: the most basic form of reborrowing we want to enable is this: // Note: not Clone or Copy #[derive(Reborrow)] struct MyMutMarker<'a>(...); // ... let marker: MyMarkerMut = MyMutMarker::new(); some_call(marker); some_call(marker); ie. make it possible for an owned value to be passed into a call twice and have Rust inject a reborrow at each call site to produce a new bitwise copy of the original value for the passing purposes, and mark the original value as disabled for reads and writes for the duration of the borrow. A notable complication appears with implementing such reborrowing in userland using explicit cals when dealing with returned values: return some_call(marker.reborrow()); If the borrowed lifetime escapes through the return value, then this will not compile as the borrowed lifetime is based on a value local to this function. Alongside convenience, this is the major reason for the Reborrow traits work. `CoerceShared` is a secondary trait that enables equivalent reborrowing that only disables the original value for writes, ie. matching the `&mut T` to `&T` coercion. ## Update We have the `Reborrow` trait working, albeit currently with a bug in which the `marker` must be bound as `let mut`. We are working towards a working `CoerceShared` trait in the following form: trait CoerceShared<Target: Copy> {} Originally the trait had a `type Target` ADT but this turned out to be unnecessary, as there is no reason to particularly disallow multiple coercion targets. The original reason for using an ADT to disallow multiple coercion targets was based on the trait also having an unsafe method, at which point unscrupulous users could use the trait as a generic coercion trait. Because the trait method was found to be unnecessary, the fear is also unnecessary. This means that the trait has better chances of working with multiple coercing lifetimes (think a collection of `&mut`s all coercing to `&`s, or only some of them). However, we are currently avoiding any support of multiple lifetimes as we want to avoid dealing with rmeta before we have the basic functionality working. ### "Flexible, fast(er) compilation" build-std (rust-lang/rust-project-goals#274) Progress | ---|--- Point of contact | David Wood Champions | cargo (Eric Huss), compiler (David Wood), libs (Amanieu d'Antras) Task owners | Adam Gemmell, David Wood 1 detailed update available. Comment by @davidtwco posted on 2025-12-15: rust-lang/rfcs#3873 is waiting on one checkbox before entering the final comment period. We had our sync meeting on the 11th and decided that we would enter FCP on rust-lang/rfcs#3874 and rust-lang/rfcs#3875 after rust-lang/rfcs#3873 is accepted. We've responded to almost all of the feedback on the next two RFCs and expect the FCP to act as a forcing-function so that the relevant teams take a look, they can always register concerns if there are things we need to address, and if we need to make any major changes then we'll restart the FCP. Production-ready cranelift backend (rust-lang/rust-project-goals#397) Progress | ---|--- Point of contact | Folkert de Vries Champions | compiler (bjorn3) Task owners | bjorn3, Folkert de Vries, [Trifecta Tech Foundation] 1 detailed update available. Comment by @folkertdev posted on 2025-12-01: We did not receive the funding we needed to work on this goal, so no progress has been made. Overall I think the improvements we felt comfortable promising are on the low side. Overall the amount of time spent in codegen for realistic changes to real code bases was smaller than expected, meaning that the improvements that cranelift can deliver for the end-user experience are smaller. We still believe larger gains can be made with more effort, but did not feel confident in promising hard numbers. So for now, let's close this. Promoting Parallel Front End (rust-lang/rust-project-goals#121) Progress | ---|--- Point of contact | Sparrow Li Task owners | Sparrow Li No detailed updates available. Relink don't Rebuild (rust-lang/rust-project-goals#400) Progress | ---|--- Point of contact | Jane Lusby Champions | cargo (Weihang Lo), compiler (Oliver Scherer) Task owners | @dropbear32, @osiewicz No detailed updates available. ### "Higher-level Rust" Ergonomic ref-counting: RFC decision and preview (rust-lang/rust-project-goals#107) Progress | ---|--- Point of contact | Niko Matsakis Champions | compiler (Santiago Pastorino), lang (Niko Matsakis) Task owners | Niko Matsakis, Santiago Pastorino No detailed updates available. Stabilize cargo-script (rust-lang/rust-project-goals#119) Progress | ---|--- Point of contact | Ed Page Champions | cargo (Ed Page), lang (Josh Triplett), lang-docs (Josh Triplett) Task owners | Ed Page 1 detailed update available. Comment by @epage posted on 2025-12-15: Key developments * A fence length limit was added in response to T-lang feedback (https://github.com/rust-lang/rust/pull/149358) * Whether to disallow or lint for CR inside of a frontmatter is under discussion (https://github.com/rust-lang/rust/pull/149823) Blockers * https://github.com/rust-lang/rust/pull/146377 * rustdoc deciding on and implementing how they want frontmatter handled in doctests ### "Unblocking dormant traits" Evolving trait hierarchies (rust-lang/rust-project-goals#393) Progress | ---|--- Point of contact | Taylor Cramer Champions | lang (Taylor Cramer), types (Oliver Scherer) Task owners | Taylor Cramer, Taylor Cramer & others 1 detailed update available. Comment by @cramertj posted on 2025-12-17: Current status: * The RFC for `auto impl` supertraits has been updated to address SemVer compatibility issues. * There is a parsing PR kicking off an experimental implementation. The tracking issue for this experimental implementation is here. In-place initialization (rust-lang/rust-project-goals#395) Progress | ---|--- Point of contact | Alice Ryhl Champions | lang (Taylor Cramer) Task owners | Benno Lossin, Alice Ryhl, Michael Goulet, Taylor Cramer, Josh Triplett, Gary Guo, Yoshua Wuyts No detailed updates available. Next-generation trait solver (rust-lang/rust-project-goals#113) Progress | ---|--- Point of contact | lcnr Champions | types (lcnr) Task owners | Boxy, Michael Goulet, lcnr 1 detailed update available. Comment by @lcnr posted on 2025-12-15: We've continued to fix a bunch of smaller issues over the last month. Tim (Theemathas Chirananthavat) helped uncover a new potential issue due to non-fatal overflow which we'll have to consider before stabilizing the new solver: https://github.com/rust-lang/trait-system-refactor-initiative/issues/258. I fixed two issues myself in https://github.com/rust-lang/rust/pull/148823 and https://github.com/rust-lang/rust/pull/148865. tiif with help by Boxy fixed query cycles when evaluating constants in where-clauses: https://github.com/rust-lang/rust/pull/148698. @adwinwhite fixed a subtle issues involving coroutine witnesses in https://github.com/rust-lang/rust/pull/149167 after having diagnosed the underlying issue there last month. They've also fixed a smaller diagnostics issue in https://github.com/rust-lang/rust/pull/149299. Finally, they've also fixed an edge case of impl well-formedness checking in https://github.com/rust-lang/rust/pull/149345. Shoyu Vanilla fixed a broken interaction of aliases and fudging in https://github.com/rust-lang/rust/pull/149320. Looking into fudging and HIR typeck `Expectation` handling also uncovered a bunch of broken edge-cases and I've openedhttps://github.com/rust-lang/rust/issues/149379 to track these separately. I have recently spent some time thinking about the remaining necessary work and posted a write-up on my personal blog: https://lcnr.de/blog/2025/12/01/next-solver-update.html. I am currently trying to get a clearer perspective on our cycle handling while slowly working towards an RFC for the changes there. This is challenging as we don't have a good theoretical foundation here yet. Stabilizable Polonius support on nightly (rust-lang/rust-project-goals#118) Progress | ---|--- Point of contact | RΓ©my Rakic Champions | types (Jack Huey) Task owners | Amanda Stjerna, RΓ©my Rakic, Niko Matsakis 2 detailed updates available. Comment by @lqd posted on 2025-12-30: This month's key developments were: * borrowck support in `a-mir-formality` has been progressing steadily β€” it has its own dedicated updates in https://github.com/rust-lang/rust-project-goals/issues/122 for more details * we were also able to find a suitable project for the master's student project on a-mir-formality (and they accepted and should start around February) and which will help expand our testing coverage for the polonius alpha as well. * tiif has kept making progress on fixing opaque type soundness issue https://github.com/rust-lang/trait-system-refactor-initiative/issues/159. It is the one remaining blocker for passing all tests. By itself it will not immediately fix the two remaining (soundness) issues with opaque type region liveness, but we'll able to use the same supporting code to ensure the regions are indeed live where they need to be. * I quickly cleaned up some inefficiencies in constraint conversion, it hasn't landed yet but it maybe won't need to because of the next item * but most of the time this month was spent on this final item: we have the first interesting results from the rewriting effort. After a handful of wrong starts, I have a branch almost ready to switch the constraint graph to be lazy and computed during traversal. It removes the need to index the numerous list of constraints, or to convert liveness data to a different shape. It thus greatly reduces the current alpha overhead (some rare cases look faster than NLLs but I don't yet know why, maybe due to being able to better use the sparseness, low connectivity of the constraint graph, and a small number of loans). The overhead wasn't entirely removed of course: the worst offending benchmark has a +5% wall-time regression, but icounts are worse looking (+13%). This was also only benchmarking the algorithm itself, without the improvements to the rest of borrowck mentioned in previous updates. I should be able to open a PR in the next couple days, once I figure out how to best convert the polonius mermaid graph dump to the new lazy localized constraint generation. * and finally, happy holidays everyone! Comment by @lqd posted on 2025-12-31: > * I should be able to open a PR in the next couple days > done in https://github.com/rust-lang/rust/pull/150551 ## Goals looking for help ## Other goal updates Add a team charter for rustdoc team (rust-lang/rust-project-goals#387) Progress | ---|--- Point of contact | Guillaume Gomez Champions | rustdoc (Guillaume Gomez) No detailed updates available. Borrow checking in a-mir-formality (rust-lang/rust-project-goals#122) Progress | ---|--- Point of contact | Niko Matsakis Champions | types (Niko Matsakis) Task owners | Niko Matsakis, tiif 4 detailed updates available. Comment by @nikomatsakis posted on 2025-12-03: PR https://github.com/rust-lang/a-mir-formality/pull/206 contains a "first draft" for the NLL rules. It checks for loan violations (e.g., mutating borrowed data) as well as some notion of outlives requirements. It does not check for move errors and there aren't a lot of tests yet. Comment by @nikomatsakis posted on 2025-12-03: The PR also includes two big improvements to the a-mir-formality framework: * support for `(for_all)` rules that can handle "iteration" * tracking proof trees, making it _much_ easier to tell why something is accepted that should not be Comment by @nikomatsakis posted on 2025-12-10: Update: opened https://github.com/rust-lang/a-mir-formality/pull/207 which contains support for `&mut`, wrote some new tests (including one FIXME), and added a test for NLL Problem Case #3 (which behaved as expected). One interesting thing (cc Ralf Jung) is that we have diverged from MiniRust in a few minor ways: * We do not support embedding value expressions in place expressions. * Where MiniRust has a `AddrOf` operator that uses the `PtrType` to decide what kind of operation it is, we have added a `Ref` MIR operation. This is in part because we need information that is not present in MiniRust, specifically a lifetime. * We have also opted to extend `goto` with the ability to take multiple successors, so that `goto b1, b2` can be seen as "goto either b1 or b2 non-deterministically" (the actual opsem would probably be to always go to b1, making this a way to add "fake edges", but the analysis should not assume that). Comment by @nikomatsakis posted on 2025-12-17: Update: opened https://github.com/rust-lang/a-mir-formality/pull/210 with today's work. We are discussing how to move the checker to support polonius-alpha. To that end, we introduced feature gates (so that a-mir-formality can model nightly features) and did some refactoring of the type checker aiming at allowing outlives to become flow-sensitive. C++/Rust Interop Problem Space Mapping (rust-lang/rust-project-goals#388) Progress | ---|--- Point of contact | Jon Bauman Champions | compiler (Oliver Scherer), lang (Tyler Mandry), libs (David Tolnay) Task owners | Jon Bauman No detailed updates available. Comprehensive niche checks for Rust (rust-lang/rust-project-goals#262) Progress | ---|--- Point of contact | Bastian Kersting Champions | compiler (Ben Kimock), opsem (Ben Kimock) Task owners | Bastian Kersting], Jakob Koschel No detailed updates available. Const Generics (rust-lang/rust-project-goals#100) Progress | ---|--- Point of contact | Boxy Champions | lang (Niko Matsakis) Task owners | Boxy, Noah Lev 3 detailed updates available. Comment by @BoxyUwU posted on 2025-12-30: Since the last update both of my PRs I mentioned have landed, allowing for constructing ADTs in const arguments while making use of generic parameters. This makes MGCA effectively a "full" prototype where it can now fully demonstrate the core concept of the feature. There's still a lot of work left to do but now we're at the point of finishing out the feature :) Once again huge thanks to camelid for sticking with me throughout this. Also thanks to errs, oli and lcnr for reviewing some of the work and chatting with me about possible impl decisions. Some examples of what is possible with MGCA as of the end of this goal cycle: #![feature(const_default, const_trait_impl, min_generic_const_args)] trait Trait { #[type_const] const ASSOC: usize; } fn mk_array<T: const Default + Trait>() -> [T; T::ASSOC] { [const { T::default() }; _] } #![feature(adt_const_params, min_generic_const_args)] fn foo<const N: Option<u32>>() {} trait Trait { #[type_const] const ASSOC: usize; } fn bar<T: Trait, const N: u32>() { // the initializer of `_0` is a `N` which is a legal const argument // so this is ok. foo::<{ Some::<u32> { 0: N } }>(); // this is allowed as mgca supports uses of assoc consts in the // type system. ie `<T as Trait>::ASSOC` is a legal const argument foo::<{ Some::<u32> { 0: <T as Trait>::ASSOC } }>(); // this on the other hand is not allowed as `N + 1` is not a legal // const argument foo::<{ Some::<u32> { 0: N + 1 } }>(); // ERROR } As for `adt_const_params` we now have a zulip stream specifically for discussion of the upcoming RFC and the drafting of the RFC: #project-const-generics/adt_const_params-rfc. I've gotten part of the way through actually writing the RFC itself though it's gone slower than I had originally hoped as I've also been spending more time thinking through the implications of allowing private data in const generics. I've debugged the remaining two ICEs making `adt_const_params` not fully ready for stabilization and written some brief instructions on how to resolve them. One ICE has been incidentally fixed (though more _masked_) by some work that Kivooeo has been doing on MGCA. The other has been picked up by someone I'm not sure the github handle of so that will also be getting fixed soon. Comment by @BoxyUwU posted on 2025-12-30: Ah I forgot to mention, even though MGCA has a tonne of work left to do I expect it should be somewhat approachable for people to help out with. So if people are interested in getting involved now is a good time :) Comment by @BoxyUwU posted on 2025-12-30: Ah another thing I forgot to mention. David Wood spent some time looking into the name mangling scheme for `adt_const_params` stuff to make sure it would be fine to stabilize and it seems it is so that's another step closer to `adt_const_params` being stabilizable Continue resolving `cargo-semver-checks` blockers for merging into cargo (rust-lang/rust-project-goals#104) Progress | ---|--- Point of contact | Predrag Gruevski Champions | cargo (Ed Page), rustdoc (Alona Enraght-Moony) Task owners | Predrag Gruevski No detailed updates available. Develop the capabilities to keep the FLS up to date (rust-lang/rust-project-goals#391) Progress | ---|--- Point of contact | Pete LeVasseur Champions | bootstrap (Jakub BerΓ‘nek), lang (Niko Matsakis), spec (Pete LeVasseur) Task owners | Pete LeVasseur, Contributors from Ferrous Systems and others TBD, `t-spec` and contributors from Ferrous Systems 1 detailed update available. Comment by @PLeVasseur posted on 2025-12-16: Meeting notes here: FLS team meeting 2025-12-12 **Key developments** : We're close to completing the FLS release for 1.91.0, 1.91.1. We've started to operate as a team, merging a PR with the changelog entries, then opening up issues for each change required: βœ… #624(https://github.com/rust-lang/fls/issues/624), βœ… #625(https://github.com/rust-lang/fls/issues/625), βœ… #626(https://github.com/rust-lang/fls/issues/626), ⚠️ #623(https://github.com/rust-lang/fls/issues/623). #623(https://github.com/rust-lang/fls/issues/623) is still pending, as it requires a bit of alignment with the Reference on definitions and creation of a new example. **Blockers** : None currently **Help wanted** : We'd love more folks from the safety-critical community to contribute to picking up issues or opening an issue if you notice something is missing. Emit Retags in Codegen (rust-lang/rust-project-goals#392) Progress | ---|--- Point of contact | Ian McCormack Champions | compiler (Ralf Jung), opsem (Ralf Jung) Task owners | Ian McCormack 1 detailed update available. Comment by @icmccorm posted on 2025-12-16: Here's our December status update! * We have revised our prototype of the pre-RFC based on Ralf Jung's feedback. Now, instead of having two different retag functions for operands and places, we emit a single `__rust_retag` intrinsic in every situation. We also track interior mutability precisely. At this point, the implementation is mostly stable and seems to be ready for an MCP. * There's been some discussion here and in the pre-RFC about whether or not Rust will still have explicit MIR retag statements. We plan on revising our implementation so that we no longer rely on MIR retags to determine where to insert our lower-level retag calls. This should be a relatively straightforward change to the current prototype. If anything, it should make these changes easier to merge upstream, since they will no longer affect Miri. * BorrowSanitizer continues to gain new features, and we've started testing it on our first real crate (lru) (which has uncovered a few new bugs in our implementation). The two core Tree Borrows features that we have left to support are error reporting and garbage collection. Once these are finished, we will be able to expand our testing to more real-world libraries and confirm that we are passing each of Miri's test cases (and likely find more bugs lurking in our implementation). Our instrumentation pass ignores global and thread-local state for now, and it does not support atomic memory accesses outside of atomic `load` and `store` instructions. These operations should be relatively straightforward to add once we've finished higher-priority items. * Performance is slow. We do not know exactly how slow yet, since we've been focusing on feature support over benchmarking and optimization. This is at least partially due to the lack of garbage collection, based on what we're seeing from profiling. We will have a better sense of what our performance is like once we can compare against Miri on more real-world test cases. As for what's next, we plan on posting an MCP soon, now that it's clear that we will be able to do without MIR retags. You can expect a more detailed status update on BorrowSanitizer by the end of January. This will discuss our implementation and plans for 2026. We will post that here and on our project website. Expand the Rust Reference to specify more aspects of the Rust language (rust-lang/rust-project-goals#394) Progress | ---|--- Point of contact | Josh Triplett Champions | lang-docs (Josh Triplett), spec (Josh Triplett) Task owners | Amanieu d'Antras, Guillaume Gomez, Jack Huey, Josh Triplett, lcnr, Mara Bos, Vadim Petrochenkov, Jane Lusby 1 detailed update available. Comment by @joshtriplett posted on 2025-12-17: In addition to further ongoing work on reference material (some of which is on track to be merged), we've had some extensive discussions about reference processes, maintenance, and stability markers. Niko Matsakis is putting together a summary and proposal for next steps. Finish the libtest json output experiment (rust-lang/rust-project-goals#255) Progress | ---|--- Point of contact | Ed Page Champions | cargo (Ed Page) Task owners | Ed Page No detailed updates available. Finish the std::offload module (rust-lang/rust-project-goals#109) Progress | ---|--- Point of contact | Manuel Drehwald Champions | compiler (Manuel Drehwald), lang (TC) Task owners | Manuel Drehwald, LLVM offload/GPU contributors 2 detailed updates available. Comment by @ZuseZ4 posted on 2025-12-02: It's only been two weeks, but we got a good number of updates, so I already wanted to share them. ## autodiff 1. On the autodiff side, we landed the support for rlib and better docs. This means that our autodiff frontend is "almost" complete, since there are almost no cases left where you can't apply autodiff. There are a few features like custom-derivatives or support for `dyn` arguments that I'd like to add, but they are currently waiting for better docs on the Enzyme side. There is also a long-term goal off replacing the fat-lto requirement with the less invasive embed-bc requirement, but this proved to be tricky in the past and only affects compile times. 2. @sgasho picked up my old PR to dlopen enzyme, and found the culprit of it failing after my last rebase. A proper fix might take a bit longer, but it might be worth waiting for. As a reminder, using dlopen in the future allows us to ship autodiff on nightly without increasing the size of rustc and therefore without making our infra team sad. All in all, we have landed most of the hard work here, so that's a very comfortable position to be in before enabling it on nightly. ## offload 1. We have landed the intrinsic implementation of Marcelo DomΓ­nguez, so now you can offload functions with almost arbitrary arguments. In my first prototype, I had limited it to pointers to 256 f64 values. The updated usage example continues to live here in our docs. As you can see, we still require `#[cfg(target_os=X)]` annotations. Under the hood, the LLVM-IR which we generate is also still a bit convoluted. In his next PRs, he'll clean up the generated IR, and introduce an offload macro that users shall call instead of the internal offload intrinsic. 2. I spend more time on enabling offload in our CI, to enable `std::offload` in nightly. After multiple iterations and support from LLVM offload devs, we found a cmake config that does not run into bugs, should not increase Rust CI time too much, and works with both in-tree llvm/clang builds, as well as external clang's (the current case in our Rust CI). 3. I spend more time on simplifying the usage instructions in the dev guide. We started with two cargo calls, one rustc call, two clang calls, and two clang-helper binary calls. I was able to remove the rustc and one of the clang-offload-packager calls, by directly calling the underlying LLVM APIs. I also have an unmerged PR which removes the two clang calls. Once I cleaned it up and landed it, we would be down to only two cargo calls and one binary call to `clang-linker-wrapper`. Once I automated this last wrapper (and enabled offload in CI), nightly users should be able to experiment with `std::offload`. Comment by @ZuseZ4 posted on 2025-12-26: Time for the next round of updates. Again, most of the updates were on the GPU side, but with some notable autodiff improvements too. ### autodiff: 1. @sgasho finished his work on using dlopen to load enzyme and the pr landed. This allowed Jakub BerΓ‘nek and me to start working on distributing Enzyme via a standalone component. 2. As a first step, I added a nicer error if we fail to find or dlopen our Enzyme backend. I also removed most of our autodiff fallbacks, we now unconditionally enable our macro frontend on nightly: https://github.com/rust-lang/rust/pull/150133 **You may notice that`cargo expand` now works on autodiff code.** This also allowed the first bug reports about ICE (internal compiler error) in our macro parser logic. 3. Kobzol opened a PR to build Enzyme in CI. In theory, I should have been able to download that artifact, put it into my sysroot, and use the latest nightly to automatically load it. If that had worked, we could have just merged his PR, and everyone could have started using AD on nightly. Of course, things are never that easy. Even though both Enzyme, LLVM, and rustc were built in CI, the LLVM version shipped along with rustc does not seem compatible with the LLVM version Enzyme was built against. We assume some slight cmake mismatch during our CI builds, which we will have to debug. ### offload: 1. On the gpu side, Marcelo DomΓ­nguez finished his cleanup PR, and along the way also fixed using multiple kernels within a single codebase. When developing the offload MVP I had taken a lot of inspiration from the LLVM-IR generated by clang - and it looks like I had gotten one of the (way too many) LLVM attributes wrong. That caused some metadata to be fused when multiple kernels are present, confusing our offload backend. We started to find more bugs when working on benchmarks, more about the fixes for those in the next update. 2. I finished cleaning up my offload build PR, and Oliver Scherer reviewed and approved it. Once the dev-guide gets synced, you should see much simpler usage instructions. Now it's just up to me to automate the last part, then you can compile offload code purely with cargo or rustc. I also improved how we build offload, which allows us to build it both in CI and locally. CI had some very specific requirements to not increase build times, since our x86-64-dist runner is already quite slow. 3. Our first benchmarks directly linked against NVIDIA and AMD intrinsics on llvm-ir level. However, we already had an nvptx Rust module for a while, and since recently also an amdgpu module which nicely wraps those intrinsics. I just synced the stdarch repository into rustc a few minutes ago, so from now on, we can replace both with the corresponding Rust functions. In the near future we should get a higher level GPU module, which abstracts away naming differences between vendors. 4. Most of my past rustc contributions were related to LLVM projects or plugins (Offload and Enzyme), and I increasingly encountered myself asking other people for updates or backports of our LLVM submodule, since upstream LLVM has fixes which were not yet merged into our LLVM submodule. Our llvm working group is quite small and I didn't want to burden them too much with my requests, so I recently asked them to join it, which also got approved. In the future I intend to help a little with the maintenance here. Getting Rust for Linux into stable Rust: compiler features (rust-lang/rust-project-goals#407) Progress | ---|--- Point of contact | Tomas Sedovic Champions | compiler (Wesley Wiser) Task owners | (depending on the flag) 1 detailed update available. Comment by @tomassedovic posted on 2025-12-05: Update from the 2025-12-03 meeting: ## `-Zharden-sls` Wesley reviewed it again, provided a qualification, more changes requested. Getting Rust for Linux into stable Rust: language features (rust-lang/rust-project-goals#116) Progress | ---|--- Point of contact | Tomas Sedovic Champions | lang (Josh Triplett), lang-docs (TC) Task owners | Ding Xiang Fei 2 detailed updates available. Comment by @tomassedovic posted on 2025-12-05: Update from the 2025-12-03 meeting. ## `Deref` / `Receiver` Ding keeps working on the Reference draft. The idea is still not well-proliferated and people are not convinced this is a good way to go. We hope the method-probing section in Reference PR could clear thins up. We're keeping the supertrait auto-impl experiment as an alternative. ## RFC #3851: Supertrait Auto-impl Ding addressed Predrag's requests on SemVer compatibility. He's also opened an implementation PR: https://github.com/rust-lang/rust/pull/149335. Here's the tracking issue: https://github.com/rust-lang/rust/issues/149556. ## `derive(CoercePointee)` Ding opened a PR to require additional checks for DispatchFromDyn: https://github.com/rust-lang/rust/pull/149068 ## In-place initialization Ding will prepare material for a discussion at the LPC (Linux Plumbers Conference). We're looking to hear feedback on the end-user syntax for it. The feature is going quite large, Ding will check with Tyler on the whether this might need a series of RFCs. The various proposals on the table continue being discussed and there are signs (albeit slow) of convergence. The placing function and guaranteed return ones are superseded by outpointer. The more ergonomic ideas can be built on top. The guaranteed value placement one would be valuable in the compiler regardless and we're waiting for Olivier to refine it. The feeling is that we've now clarified the constraints that the proposals must operate under. ## Field projections Nadri's Custom places proposal is looking good at least for the user-facing bits, but the whole thing is growing into a large undertaking. Benno's been focused on academic work that's getting wrapped up soon. The two will sync afterwards. Comment by @tomassedovic posted on 2025-12-18: Quick bit of great news: Rust in the Linux kernel is no longer treated as an experiment, it's here to stay πŸŽ‰ https://lwn.net/SubscriberLink/1050174/63aa7da43214c3ce/ Implement Open API Namespace Support (rust-lang/rust-project-goals#256) Progress | ---|--- Point of contact | Champions | cargo (Ed Page), compiler (b-naber), crates-io (Carol Nichols) Task owners | b-naber, Ed Page 3 detailed updates available. Comment by @sladyn98 posted on 2025-12-03: Ed Page hey i would like to contribute to this I reached out on zulip. Bumping up the post in case it might have gone under the radar CC Niko Matsakis Comment by @epage posted on 2025-12-03: The work is more on the compiler side atm, so Eric Holk and b-naber could speak more to where they could use help. Comment by @eholk posted on 2025-12-06: Hi @sladyn98 - feel free to ping me on Zulip about this. MIR move elimination (rust-lang/rust-project-goals#396) Progress | ---|--- Point of contact | Amanieu d'Antras Champions | lang (Amanieu d'Antras) Task owners | Amanieu d'Antras 1 detailed update available. Comment by @Amanieu posted on 2025-12-17: The RFC draft was reviewed in detail and Ralf Jung pointed out that the proposed semantics introduce issues because they rely on "no-behavior" (NB) with regards to choosing an address for a local. This can lead to surprising "time-traveling" behavior where the set of possible addresses that a local may have (and whether 2 locals can have the same address) depends on information from the future. For example: // This program has DB let x = String::new(); let xaddr = &raw const x; let y = x; // Move out of x and de-initialize it. let yaddr = &raw const y; x = String::new(); // assuming this does not change the address of x // x and y are both live here. Therefore, they can't have the same address. assume(xaddr != yaddr); drop(x); drop(y); // This program has UB let x = String::new(); let xaddr = &raw const x; let y = x; // Move out of x and de-initialize it. let yaddr = &raw const y; // So far, there has been no constraint that would force the addresses to be different. // Therefore we can demonically choose them to be the same. Therefore, this is UB. assume(xaddr != yaddr); // If the addresses are the same, this next line triggers NB. But actually this next // line is unreachable in that case because we already got UB above... x = String::new(); // x and y are both live here. drop(x); drop(y); * * * With that said, there is still a possibility of achieving the optimization, but the scope will need to be scaled down a bit. Specifically, we would need to: * no longer perform a "partial free"/"partial allocation" when initializing or moving out of a single field of a struct. The lifetime of a local starts when any part of it is initialized and ends when it is fully moved out. * allow a local's address to change when it is re-initialized after having been fully moved out, which eliminates the need for NB. This reduces the optimization opportunities since we can't merge arbitrary sub-field moves, but it still allows for eliminating moves when constructing a struct from multiple values. The next step is for me to rework the RFC draft to reflect this. Prototype a new set of Cargo "plumbing" commands (rust-lang/rust-project-goals#264) Progress | ---|--- Point of contact | Task owners | , Ed Page No detailed updates available. Prototype Cargo build analysis (rust-lang/rust-project-goals#398) Progress | ---|--- Point of contact | Weihang Lo Champions | cargo (Weihang Lo) Task owners | Weihang Lo, Weihang Lo 2 detailed updates available. Comment by @weihanglo posted on 2025-12-13: **Key developments** : HTML replay logic has merge. Once it gets into nightly `cargo report timings` can open the timing report you have previously logged. * https://github.com/rust-lang/cargo/pull/16377 * https://github.com/rust-lang/cargo/pull/16378 * https://github.com/rust-lang/cargo/pull/16382 **Blockers** : No, except my own availability **Help wanted** : Same as https://github.com/rust-lang/rust-project-goals/issues/398#issuecomment-3571897575 Comment by @weihanglo posted on 2025-12-26: **Key developments** : Headline: You should always enable build analysis locally, if you are using nightly and want the timing info data always available. [unstable] build-analysis = true [build.analysis] enabled = true * More log events are emitted: https://github.com/rust-lang/cargo/pull/16390 * dependency resolution time * unit-graph construction * unit-registration (which contain unit metadata) * Timing replay from `cargo report timings` now has almost the same feature parity as `cargo build --timings`, except CPU usage: https://github.com/rust-lang/cargo/pull/16414 * Rename `rebuild` event to `unit-fingerprint`, and is emitted also for fresh unit: https://github.com/rust-lang/cargo/pull/16408. * Proposed a new `cargo report sessions` command so that people can retrieve previous sessions IDs not use the latest one: https://github.com/rust-lang/cargo/pull/16428 * Proposed to remove `--timings=json` which timing info in log files should be a great replacement: https://github.com/rust-lang/cargo/pull/16420 * Documenting efforts for having man pages for nested commands `cargo report : https://github.com/rust-lang/cargo/pull/16430 and https://github.com/rust-lang/cargo/pull/16432 Besides implementations, we also discussed about: * The interaction of `--message-format` and structured logging system, as well as log event schemas and formats: https://rust-lang.zulipchat.com/#narrow/channel/246057-t-cargo/topic/build.20analysis.20log.20format/with/558294271 * A better name for `RunId`. We may lean towards `SessionId` which is a common name for logging/tracing ecosystem. * Nested Cargo calls to have a sticky session ID. At least a way to show they were invoked from the same top-level Cargo call. **Blockers** : No, except my own availability **Help wanted** : Same as https://github.com/rust-lang/rust-project-goals/issues/398#issuecomment-3571897575 reflection and comptime (rust-lang/rust-project-goals#406) Progress | ---|--- Point of contact | Oliver Scherer Champions | compiler (Oliver Scherer), lang (Scott McMurray), libs (Josh Triplett) Task owners | oli-obk 1 detailed update available. Comment by @oli-obk posted on 2025-12-15: ### Updates * https://github.com/rust-lang/rust/pull/148820 adds a way to mark functions and intrinsics as only callable during CTFE * https://github.com/rust-lang/rust/pull/144363 has been unblocked and just needs some minor cosmetic work ### Blockers * https://github.com/rust-lang/rust/pull/146923 (reflection MVP) has not been reviewed yet Rework Cargo Build Dir Layout (rust-lang/rust-project-goals#401) Progress | ---|--- Point of contact | Ross Sullivan Champions | cargo (Weihang Lo) Task owners | Ross Sullivan 1 detailed update available. Comment by @ranger-ross posted on 2025-12-23: ## Status update December 23, 2025 The majority of December was spent iterating on https://github.com/rust-lang/cargo/pull/16155 . As mentioned in the previous update, the original locking design was not correct and we have been working through other solutions. As locking is tricky to get right and there are many scenarios Cargo needs to support, we are trying to descope the initial implementation to an MVP, even if that means we lose some of the concurrency. Once we have an MVP on nightly, we can start gathering feedback on the scenarios that need improvement and iterate. I'm hopeful that we get an unstable `-Zfine-grain-locking` on nightly in January for folks to try out in their workflows. * * * Also we are considering adding an opt-in for the new build-dir layout using an env var (`CARGO_BUILD_DIR_LAYOUT_V2=true`) to allow tool authors to begin migrating to the new layout. https://github.com/rust-lang/cargo/pull/16336 Before stabilizing this, we are doing crater run to test the impact of the changes and proactively reaching out to projects to minimize breakage as much as possible. https://github.com/rust-lang/rust/pull/149852 Run more tests for GCC backend in the Rust's CI (rust-lang/rust-project-goals#402) Progress | ---|--- Point of contact | Guillaume Gomez Champions | compiler (Wesley Wiser), infra (Marco Ieni) Task owners | Guillaume Gomez No detailed updates available. Rust Stabilization of MemorySanitizer and ThreadSanitizer Support (rust-lang/rust-project-goals#403) Progress | ---|--- Point of contact | Jakob Koschel Task owners | Bastian Kersting, Jakob Koschel 1 detailed update available. Comment by @jakos-sec posted on 2025-12-15: Based on the gathered feedback I opened a new MCP for the proposed new Tier 2 targets with sanitizers enabled. (https://github.com/rust-lang/compiler-team/issues/951) Rust Vision Document (rust-lang/rust-project-goals#269) Progress | ---|--- Point of contact | Niko Matsakis Task owners | vision team No detailed updates available. rustc-perf improvements (rust-lang/rust-project-goals#275) Progress | ---|--- Point of contact | James Champions | compiler (David Wood), infra (Jakub BerΓ‘nek) Task owners | James, Jakub BerΓ‘nek, David Wood 1 detailed update available. Comment by @Kobzol posted on 2025-12-15: We have enabled the second x64 machine, so we now have benchmarks running in parallel πŸŽ‰ There are some smaller things to improve, but next year we can move onto running benchmarks on Arm collectors. Stabilize public/private dependencies (rust-lang/rust-project-goals#272) Progress | ---|--- Point of contact | Champions | cargo (Ed Page) Task owners | , Ed Page No detailed updates available. Stabilize rustdoc `doc_cfg` feature (rust-lang/rust-project-goals#404) Progress | ---|--- Point of contact | Guillaume Gomez Champions | rustdoc (Guillaume Gomez) Task owners | Guillaume Gomez 1 detailed update available. Comment by @GuillaumeGomez posted on 2025-12-17: Opened stabilization PR but we have blockers I didn't hear of, so stabilization will be postponed until then. SVE and SME on AArch64 (rust-lang/rust-project-goals#270) Progress | ---|--- Point of contact | David Wood Champions | compiler (David Wood), lang (Niko Matsakis), libs (Amanieu d'Antras) Task owners | David Wood 3 detailed updates available. Comment by @davidtwco posted on 2025-12-15: I haven't made any progress on `Deref::Target` yet, but I have been focusing on landing rust-lang/rust#143924 which has went through two rounds of review and will hopefully be approved soon. Comment by @nikomatsakis posted on 2025-12-18: Update: David and I chatted on Zulip. Key points: David has made "progress on the non-Sized Hierarchy part of the goal, the infrastructure for defining scalable vector types has been merged (with them being Sized in the interim) and that'll make it easier to iterate on those and find issues that need solving". On the Sized hierarchy part of the goal, no progress. We discussed options for migrating. There seem to be three big options: (A) The **conservative-but-obvious route** where the `T: Deref`in the old edition is expanded to `T: Deref<Target: SizeOfVal>` (but in the new edition it means `T: Deref<Target: Pointee>`, i.e., no additional bounds). The main _downside_ is that new Edition code using `T: Deref` can't call old Edition code using `T: Deref` as the old edition code has stronger bounds. Therefore new edition code must either use stronger bounds than it needs _or_ wait until that old edition code has been updated. (B) You do something smart with Edition.Old code where you figure out if the bound can be loose or strict by bottom-up computation. So `T: Deref` in the old could mean either `T: Deref<Target: Pointee>` or `T: Deref<Target: SizeOfVal>`, depending on what the function actually does. (C) You make Edition.Old code always mean `T: Deref<Target: Pointee>` and you still allow calls to `size_of_val` but have them cause post-monomorphization errors if used inappropriately. In Edition.New you use stricter checking. Options (B) and (C) have the downside that changes to the function body (adding a call to `size_of_val`, specifically) in the old edition can stop callers from compiling. In the case of Option (B), that breakage is at type-check time, because it can change the where-clauses. In Option (C), the breakage is post-monomorphization. Option (A) has the disadvantage that it takes longer for the new bounds to roll out. Given this, (A) seems the preferred path. We discussed options for how to encourage that roll-out. We discussed the idea of a lint that would warn Edition.Old code that its bounds are stronger than needed and suggest rewriting to `T: Deref<Target: Pointee>` to explicitly disable the stronger Edition.Old default. This lint could be implemented in one of two ways * at type-check time, by tracking what parts of the environment are used by the trait solver. This may be feasible in the new trait solver, someone from @rust-lang/types would have to say. * at post-mono time, by tracking which functions _actually call_ `size_of_val` and propagating that information back to callers. You could then compare against the generic bounds declared on the caller. The former is more useful (knowing what parts of the environment are necessary could be useful for more things, e.g., better caching); the latter may be easier or more precise. Comment by @nikomatsakis posted on 2025-12-19: Update to the previous post. Tyler Mandry pointed me at this thread, where lcnr posted this nice blog post that he wrote detailing more about (C). Key insights: * Because the use of `size_of_val` would still cause post-mono errors when invoked on types that are not `SizeOfVal`, you know that adding `SizeOfVal` into the function's where-clause bounds is not a breaking change, even though adding a where clause is a breaking change more generally. * But, to David Wood's point, it _does_ mean that there is a change to Rust's semver rules: adding `size_of_val` would become a breaking change, where it is not today. This may well be the best option though, particularly as it allows us to make changes to the defaults across-the-board. A change to Rust's _semver rules_ is not a breaking change in the usual sense. It _is_ a notable shift. Type System Documentation (rust-lang/rust-project-goals#405) Progress | ---|--- Point of contact | Boxy Champions | types (Boxy) Task owners | Boxy, lcnr 1 detailed update available. Comment by @BoxyUwU posted on 2025-12-30: This month I've written some documentation for how Const Generics is implemented in the compiler. This mostly covers the implementation of the stable functionality as the unstable features are quite in flux right now. These docs can be found here: https://rustc-dev-guide.rust-lang.org/const-generics.html Unsafe Fields (rust-lang/rust-project-goals#273) Progress | ---|--- Point of contact | Jack Wrenn Champions | compiler (Jack Wrenn), lang (Scott McMurray) Task owners | Jacob Pratt, Jack Wrenn, Luca Versari No detailed updates available.
05.01.2026 00:00 πŸ‘ 1 πŸ” 0 πŸ’¬ 0 πŸ“Œ 0
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. ↩
19.12.2025 00:00 πŸ‘ 0 πŸ” 0 πŸ’¬ 1 πŸ“Œ 0
Project goals update β€” November 2025 The Rust project is currently working towards a slate of 41 project goals, with 13 of them designated as Flagship Goals. This post provides selected updates on our progress towards these goals (or, in some cases, lack thereof). The full details for any particular goal are available in its associated tracking issue on the rust-project-goals repository. ## Flagship goals ### "Beyond the `&`" Continue Experimentation with Pin Ergonomics (rust-lang/rust-project-goals#389) Progress | ---|--- Point of contact | Frank King Champions | compiler (Oliver Scherer), lang (TC) Task owners | Frank King 1 detailed update available. Comment by @frank-king posted on 2025-11-21: Status update: * x] [pattern matching support of `&pin const|mut T` types, merged. * x] [`&pin` pattern and `ref pin mut` binding mode, merged. * ] [`Drop::pin_drop`, waiting for review (new updates since the last review). * **Unresolved question** : the current implementation requires changing the `src/docs/book` submodule, but the top repo and the sub repo must be changed together to pass the CI tests in both repos. It's because a default body is added to `Drop::drop` and it becomes a provided method instead of a required method in rustdoc. Is there any way to avoid that? (Possibly keep rustdoc treating `Drop::drop` as a required method?) * ] [coercion between `&pin const|mut T` and `&{mut} T`, waiting for review (fresh). Design a language feature to solve Field Projections (rust-lang/rust-project-goals#390) Progress | ---|--- Point of contact | Benno Lossin Champions | lang (Tyler Mandry) Task owners | Benno Lossin **TL;DR.** * We have made lot's of progress with the novel place-based proposal made by @Nadrieril. Since the last update, he released his idea as a blog post and have had an immense amount of discussions on Zulip. There are still many open questions and problems left to solve. If you have any ideas, feel free to share them on Zulip. * At the beginning of this month, we explored moving projections and `&own`. We also looked into reducing the number of projection traits. * The PR https://github.com/rust-lang/rust/pull/146307 has been stale for this month, but will be picked up again in December. 3 detailed updates available. Comment by @BennoLossin posted on 2025-11-01: ### Moving Projections and `&own` _Moving_ projections are a third kind of projection that already exists in Rust today for `Box` as well as any local variable holding a struct. While we won't be including it in an MVP, we still want to make sure that we can extend the language with moving projections. Here is an example with `Box`: fn destructure_box(mut b: Box<Struct>) -> Box<Struct> { let f1 = b.f1; b.f1 = F1::new(); b } This projection moves the field out of the box, invalidating it in the process. To make it valid again, a new value has to be moved in for that field. Alternatively, the partially valid box can be dropped, this will drop all other fields of `Struct` and then deallocate the `Box`. Note that this last property is implemented by compiler magic today and moving projections would allow this special behavior for `Box` to be a library implementation instead. To make this kind of projection available for all types, we can make it a proper operation by adding this trait: pub unsafe trait ProjectMove: Projectable { type OutputMove<'a, F: Field<Base = Self::Target>>; unsafe fn project_move<'a, F: Field<Base = Self::Target>>( this: *mut Self, ) -> Self::OutputMove<'a, F>; unsafe fn drop_husk(husk: *mut Self); } Importantly, we also need a `drop_husk` function which is responsible for cleaning up the "husk" that remains when all fields have been move-projected. In the case of `Box`, it deallocates the memory. So for `Box` we could implement this trait like this: impl<T> ProjectMove for Box<T> { type OutputMove<'a, F: Field<Base = T>> = F::Type; unsafe fn project_move<'a, F: Field<Base = T>>( this: *mut Self, ) -> F::Type { let ptr = unsafe { (*this).0.pointer.as_ptr() }; ptr::read(unsafe { <*const T as Project>::project::<'a, F>(&raw const ptr) }) } unsafe fn drop_husk(husk: *mut Self) { // this is exactly the code run by `Box::drop` today, as the compiler // drops the `T` before `Box::drop` is run. let ptr = (*husk).0; unsafe { let layout = Layout::for_value_raw(ptr.as_ptr()); if layout.size() != 0 { (*husk).1.deallocate(From::from(ptr.cast()), layout); } } } } To support moving back into a value we have two options: 1. Add a `ProjectMoveBack` trait that declares an operation which accepts a value that is moved back into the projected one, or 2. Add `&own` references. Until now, we have explored the second option, because there are lot's of other applications for `&own`. ##### `&own` References A small interlude on `&own` references. An `&'a own T` is a special kind of exclusive reference that _owns_ the value it points to. This means that if you drop an `&own T`, you also drop the pointee. You can obtain an `&own T` by constructing it directly to local variable `&own my_local` or by deriving it from an existing `&own` via field projections. Smart pointers generally also allow creating `&own T` from `&own SmartPtr<T>`. One important difference to `&mut T` is that `&own` is not only temporally unique (i.e. there are no other references to that value not derived from it) but also unique for that value. In other words, one can create at most one `&own T` to a local variable. let mut val = Struct { ... }; let x = &own val; //~ HELP: ownership transferred here drop(x); let y = &own val; //~ ERROR: cannot own `val` twice Since the `drop(x)` statement drops `val`, the borrow checker must disallow any future access. However, we are allowed to move a value back into the memory of `val`: let mut val = Struct { ... }; let x = &own val; drop(x); val = Struct { ... }; let y = &own val; The lifetime `'a` in `&'a own T` is that of the backing memory. It means that when `'a` expires, the memory also is no longer valid (or rather it cannot be proven that it is valid after `'a`). For this reason an `&'a own T` has to be dropped (or forgotten) before `'a` expires (since after that it cannot be dropped any more). `&own T` itself supports moving projections (another indicator that having them is a good idea). However only for types that don't implement `Drop` (similar to normal struct destructuring -- there are also talks about lifting this requirement, but no new issues arise from projecting `&own`). ##### `&own` and pinning To make `&pin own T` with `!(T: Unpin)` sound in the face of panics, we have to add drop flags or have unforgettable types. We explored a design using drop flags below; there are separate efforts to experimenting with a `Leak`/`Forget` trait ongoing, I think it might be a better solution than drop flags at least for `&own`. We need drop flags to ensure the drop guarantee of pinned values. The drop flag will be stored when the original `&own` is created and it will live on the stack of the function that created it. They are needed for the following scenario: fn foo() { let x = Struct { ... }; bar(&pin own x); } fn bar(x: &pin own Struct) { if random() { std::mem::forget(x); } if random() { panic!() } } Since `x` is pinned on the stack, it needs to be dropped before `foo` returns (even if it unwinds). When `bar` forgets the owned reference, the destructor is not run, if it now panics, the destructor needs to be run in `foo`. But since it gave away ownership of `x` to `bar`, it is possible that `bar` already dropped `x` (this is the case when the first `random()` call returns `false`). To keep track of this, we need a drop flag in the stack frame of `foo` that gets set to `true` when `x` is dropped. There are several issues with drop flags: * we can't have `&'static own T` pointing to non-static values (for example coming from a `Box::leak_owned` function). * field projections complicate things: if we project to a field, then we could possibly forget one field, but drop another * solution: just store drop flags not only for the whole struct, but also all transitive fields that implement `Drop` * there is different behavior between `&own T` and `&pin own T`, the former can be forgotten and the destructor will not run, the latter can also be forgotten, but the destructor runs regardless. This last point convinces me that we actually want `&pin own T: !Leak` when `T: !Leak`; but IIUC, that wouldn't prevent the following code from working: fn main() { let x = Struct { ... }; let x = &pin own x; Box::leak(Box::new(x)); } ##### `DerefMove` The `DerefMove` operation & trait is something that has been discussed in the past (I haven't dug up any discussions on it though). It is the analogous operation of `&own` to `Deref`. We need to figure out the hierarchy wrt. `Deref` and `DerefMut`, but ignoring that issue for the moment, here is how `DerefMove` would look like: trait DerefMove: DropHusk { trait Target: ?Sized; fn deref_move(&own self) -> &own Self::Target; } Note the super trait requirement `DropHusk` -- it provides a special drop operation for `Self` when the `&own Self::Target` reference has been dropped. `Box<T>` for example would deallocate the backing memory via `DropHusk`. Its definition looks like this: pub unsafe trait DropHusk { unsafe fn drop_husk(husk: *mut Self); } We would of course also use this trait for `ProjectMove`. Implementing `DropHusk` on its own does nothing; implementing `DerefMove` or `ProjectMove` will make the compiler call `drop_husk` instead of `Drop::drop` when the value goes out of scope _after_ it has been projected or `DerefMove::deref_move` has been called. We observed that `DerefMove` is a lot more restrictive in its usability than `Deref`--- and we need projections to make it actually useful in the common case. The reason for this is that `&own` can only be created once, but one would like to be able to create it once _per field_ (which is exactly what moving projections allow). Consider this example: let b = Box::new(Struct { ... }); let field1 = &own b.field1; // desugars to `DerefMove::deref_move` let field2 = &own b.field2; //~ ERROR: cannot own `b` twice The `"cannot own `b` twice` error comes from the way the deref desugaring works: let b = Box::new(Struct { ... }); let field1 = &own DerefMove::deref_move(&own b).f1; let field2 = &own DerefMove::deref_move(&own b).f2; // ^^^ ERROR: cannot own `b` twice Now it's clear that we're trying to create two `&own` to the same value and that can't work (the issue also arises for `&mut`, but that already is covered by `ProjectExclusive`). We can write this instead: let b = Box::new(Struct { ... }); let b = &own b; let field1 = &own b.field1; let field2 = &own b.field2; But that's cumbersome. We also note that `ProjectMove` is the correct projection for `ArcRef`, as it avoids any additional refcount updates. We can rely on the ergonomic refcounting proposal to provide ergonomic ways to clone the value & perform more projections. Comment by @BennoLossin posted on 2025-11-02: ## Having a single `Project` trait The definition of the now 3 `Project*` traits are 100% verbatim the same (modulo renaming of course), so we spent some time trying to unify them into a single trait. While we cannot get rid of having to have three traits, we can merge them into a single one by adding a generic: #[sealed] pub trait ProjectKind { type Ptr<T: ?Sized>; } pub enum Shared {} pub enum Exclusive {} impl ProjectKind for Shared { type Ptr<T: ?Sized> = *const T; } impl ProjectKind for Exclusive { type Ptr<T: ?Sized> = *mut T; } pub trait Projectable { type Target; } pub unsafe trait Project<Kind: ProjectKind>: Projectable { type Output<'a, F: Field<Base = Self::Target>>; unsafe fn project<'a, F: Field<Base = Self::Target>>( this: Kind::Ptr<Self>, ) -> Self::Output<'a, F>; } We would need some more compiler magic to ensure that nobody implements this trait generically, so `impl<K> Project<K> for MyType`, to keep our approach extensible (this could be an attribute if it is also useful in other cases `#[rustc_deny_generic_impls]`). The benefit of merging the definitions is that we only have one single trait that we need to document and we could also add documentation on the `ProjectKind` types. There are also ergonomic downsides, for example all output types are now called `Output` and thus need to be fully qualified if multiple projection impls exist (`<MyType as Project<Exclusive>>::Output<'_, F>` vs `MyType::OutputExclusive<'_, F>`). To make this proposal compatible with moving projections, we also either need more compiler magic to ensure that if `Kind = Move` we require `Self: DropHusk`. Or we could use associated traits and add one to `ProjectKind` that's then used in `Project` (`Kind = Shared` would then set this to `Pointee`). This approach also makes me think a bit more about the syntax, if we discover more projections in the future, it might make sense to go for an extensible approach, like `@keyword expr{->,.@,.,~}ident` (so for example `@move x->y` or `@mut x.y`). Comment by @BennoLossin posted on 2025-11-06: ## A new Perspective: Projections via Places @Nadrieril opened this zulip thread with the idea that "_The normal rust way to reborrow a field uses places_ ". He then proceeded to brainstorm a similar design for field projections with a crucial difference: making places the fundamental building block. We had a very long discussion in that thread (exchanging the existing ideas about field projection and the novel place-involving ones) that culminated in this awesome writeup by @Nadrieril: https://hackmd.io/[@Nadrieril][]/HJ0tuCO1-e. It is a very thorough document, so I will only be able to summarize it partially here: * instead of the `Project*` traits, we have the `Place*` traits which govern what kind of place operations are possible on `*x` given `x: MySmartPtr`, those are reading, writing and borrowing. * we can allow custom smart pointer reborrowing possibly using the syntax `@MySmartPtr <place-expr>` * we need multi-projections to allow simultaneous existence of `&mut x.field.a` and `&mut x.field.b` We still have many things to flesh out in this proposal (some of these pointed out by @Nadrieril): * how do FRTs still fit into the equation? And what are the types implementing the `Projection` trait? * What do we do about non-indirected place containers like `MaybeUninit<T>`, `UnsafeCell<T>` and `ManuallyDrop<T>`? * does `BorrowKind` work as a model for the borrow checker? * how do we make `match` ergonomics work nicely? * how do we get around the orphan rule limitations? * several smaller issues/questions... This is a very interesting viewpoint and I'm inclined to make this the main proposal idea. The traits are not too different from the current field projection design and the special borrow checker behavior was also intended at least for the first level of fields. So this is a natural evolution of the field projection proposal. Thanks a lot to @Nadrieril for the stellar writeup! Reborrow traits (rust-lang/rust-project-goals#399) Progress | ---|--- Point of contact | Aapo Alasuutari Champions | compiler (Oliver Scherer), lang (Tyler Mandry) Task owners | Aapo Alasuutari 1 detailed update available. Comment by @aapoalas posted on 2025-11-11: We've worked towards coherence checking of the CoerceShared trait, and have come to a conclusion that (at least as a first step) only one lifetime, the first one, shall participate in reborrowing. Problems abound with how to store the field mappings for CoerceShared. ### "Flexible, fast(er) compilation" build-std (rust-lang/rust-project-goals#274) Progress | ---|--- Point of contact | David Wood Champions | cargo (Eric Huss), compiler (David Wood), libs (Amanieu d'Antras) Task owners | Adam Gemmell, David Wood 1 detailed update available. Comment by @davidtwco posted on 2025-11-22: Our first RFC - rust-lang/rfcs#3873 - is in the FCP process, waiting on boxes being checked. rust-lang/rfcs#3874 and rust-lang/rfcs#3875 are receiving feedback which is being addressed. Production-ready cranelift backend (rust-lang/rust-project-goals#397) Progress | ---|--- Point of contact | Folkert de Vries Champions | compiler (bjorn3) Task owners | bjorn3, Folkert de Vries, [Trifecta Tech Foundation] No detailed updates available. Promoting Parallel Front End (rust-lang/rust-project-goals#121) Progress | ---|--- Point of contact | Sparrow Li Task owners | Sparrow Li No detailed updates available. Relink don't Rebuild (rust-lang/rust-project-goals#400) Progress | ---|--- Point of contact | Jane Lusby Champions | cargo (Weihang Lo), compiler (Oliver Scherer) Task owners | @dropbear32, @osiewicz 1 detailed update available. Comment by @yaahc posted on 2025-11-21: linking this here so people know why there hasn't been any progress on this project goal. #t-compiler > 2025H2 Goal Review @ πŸ’¬ ### "Higher-level Rust" Ergonomic ref-counting: RFC decision and preview (rust-lang/rust-project-goals#107) Progress | ---|--- Point of contact | Niko Matsakis Champions | compiler (Santiago Pastorino), lang (Niko Matsakis) Task owners | Niko Matsakis, Santiago Pastorino 2 detailed updates available. Comment by @nikomatsakis posted on 2025-11-05: Three new blog posts: * Explicit capture clauses * Bikeshedding `Handle` and other follow-up thoughts * But then again...maybe alias? The most important conclusions from those posts are * Explicit capture clauses would be useful, I proposed one specific syntax but bikeshedding will be required. To be "ergonomic" we need the ability to refer to full places, e.g., `move(cx.foo.clone()) || use(cx.foo)`. * We should consider `Alias` or `Share` as the name for `Handle` trait; I am currently leaning towards `Alias` because it can be used as both a noun and a verb and is a bit more comparable to clone -- i.e., you can say "an `alias` of `foo`" just like you'd say "a `clone` of `foo`". * We should look for solutions that apply well to `clone` _and_ `alias` so that higher-level Rust gets the ergonomic benefits even when cloning "heavier-weight" types to which `Alias` does not apply. Comment by @nikomatsakis posted on 2025-11-12: New blog post: * https://smallcultfollowing.com/babysteps/blog/2025/11/10/just-call-clone/ Exploring one way to make things more ergonomic while remaining explicit, which is to make `.clone()` and `.alias()` (1) understood by move closure desugaring and (2) optimized away when redundant. Stabilize cargo-script (rust-lang/rust-project-goals#119) Progress | ---|--- Point of contact | Ed Page Champions | cargo (Ed Page), lang (Josh Triplett), lang-docs (Josh Triplett) Task owners | Ed Page 1 detailed update available. Comment by @epage posted on 2025-11-21: Key developments * rust-lang/rust#148051 Blockers: * rustdoc deciding on and implementing how they want frontmatter handled in doctests ### "Unblocking dormant traits" Evolving trait hierarchies (rust-lang/rust-project-goals#393) Progress | ---|--- Point of contact | Taylor Cramer Champions | lang (Taylor Cramer), types (Oliver Scherer) Task owners | Taylor Cramer, Taylor Cramer & others No detailed updates available. In-place initialization (rust-lang/rust-project-goals#395) Progress | ---|--- Point of contact | Alice Ryhl Champions | lang (Taylor Cramer) Task owners | Benno Lossin, Alice Ryhl, Michael Goulet, Taylor Cramer, Josh Triplett, Gary Guo, Yoshua Wuyts 1 detailed update available. Comment by @Darksonn posted on 2025-11-14: On Nov 12th, there was a mini-design meeting organized by Xiangfei Ding on inplace initialization. The attendees were Xiangfei Ding, Alice Ryhl, Benno Lossin, Tyler Mandry, and Taylor Cramer. We discussed this document: https://hackmd.io/@rust-for-linux-/H11r2RXpgl Next-generation trait solver (rust-lang/rust-project-goals#113) Progress | ---|--- Point of contact | lcnr Champions | types (lcnr) Task owners | Boxy, Michael Goulet, lcnr 1 detailed update available. Comment by @lcnr posted on 2025-11-13: The new solver is now officially used by Rust Analyzer: https://rust-analyzer.github.io/thisweek/2025/10/27/changelog-299.html. A huge shoutout to Jack Huey Chayim Refael Friedman Shoyu Vanilla and LaurenΘ›iu Nicola for that work. On the `rustc` end RΓ©my Rakic spent a lot of time triaging the most recent crater run. This uncovered a bunch of new edge cases, resulting in 6 new tracked issues. We've also merged fixes for 4 minor issues over the last 3 weeks: https://github.com/rust-lang/rust/pull/148292 https://github.com/rust-lang/rust/pull/148173 https://github.com/rust-lang/rust/pull/147840. Thanks to Jana DΓΆnszelmann, tiif and @adwinwhite for implementing these. @adwinwhite was also instrumental in diagnosing the underlying issue of https://github.com/rust-lang/trait-system-refactor-initiative/issues/245. Going forward, we intend to continue the crater triage while fixing remaining issues until we're ready for stabilization :> the remaining issues are tracked in https://github.com/orgs/rust-lang/projects/61/views/1. Stabilizable Polonius support on nightly (rust-lang/rust-project-goals#118) Progress | ---|--- Point of contact | RΓ©my Rakic Champions | types (Jack Huey) Task owners | Amanda Stjerna, RΓ©my Rakic, Niko Matsakis 1 detailed update available. Comment by @lqd posted on 2025-11-25: Key developments: * I prototyped building blocks to fix the liveness soundness issue, but this was deemed too brittle. * so we prepared a meeting for the types team to discuss the problem, and possible solutions. * it turns out the issue is related to another soundness issue for opaque types in the new trait solver, https://github.com/rust-lang/trait-system-refactor-initiative/issues/159, and that tiif is already working on. The same solution is needed for both issues: with the full implied bounds available for opaque types in liveness, we'll able to require all the regions outliving the opaque lower bound to be live, while ignoring the unrelated regions (that the hidden type _cannot_ use anyway). There will be no relevant dead region through which loans flow, and code relying on unused lifetimes being dead (like a lot of ed2024 code with the default capture changes) will still compile * we prepared another types-team meeting to discuss polonius in general, and the alpha algorithm in particular, to share knowledge among the team. This will also be helpful to then on apply member constraints in a location-sensitive manner, since right now they're applied at the SCC level and we need to make sure these constraints with the choice regions are present in the localized subset graph. * niko and tiif have made a lot of progress on adding support for borrow checking in `a-mir-formality`, so I've also joined these meetings, since we'll also want to model the alpha. * I've looked into Prusti's Place Capability Graphs, and plan to see how to integrate the alpha there, and if possible with the fuzzing capabilities mentioned in the paper, with the usual goal to expand testing as we've mentioned many times * we also had some discussion for a possible masters' student project, and thought about different practical and theoretical topics ## Goals looking for help ## Other goal updates Add a team charter for rustdoc team (rust-lang/rust-project-goals#387) Progress | ---|--- Point of contact | Guillaume Gomez Champions | rustdoc (Guillaume Gomez) 1 detailed update available. Comment by @GuillaumeGomez posted on 2025-11-21: Done in https://github.com/rust-lang/rust-forge/pull/852. Borrow checking in a-mir-formality (rust-lang/rust-project-goals#122) Progress | ---|--- Point of contact | Niko Matsakis Champions | types (Niko Matsakis) Task owners | Niko Matsakis, tiif 3 detailed updates available. Comment by @nikomatsakis posted on 2025-11-05: tiif and I have been meeting weekly here and pushing changes to the `living-large` branch of `a-mir-formality/nikomatsakis`. We are making progress, we have a minirust type checker and the start of a borrow checker. We've decided to try to use a "judgment-like" approach rather than modeling this as dataflow, as I believe it will give greater insight into the "structure" of the trait checker. Comment by @nikomatsakis posted on 2025-11-12: tiif, Jack Huey, and I met today and did more work on the "living-large" branch. The borrow checker judgments are taking shape. My expectation is that we will walk the CFG, tracking the sets of borrows that have occurred so far. At each statement, we will have a judgment that looks at (a) the subtyping relations generated by the type check (flow-insensitive, like NLL); (b) the loans issued so far and not killed; and (c) the live places that may be accessed later. We'll require then that if you are accessing a place P, then there are no loans accessible from a live place that have borrowed P in an incompatible way. Comment by @nikomatsakis posted on 2025-11-19: Continued work this week: Elaborated some on the definition of the when an access or a statement is valid. We are working our way towards what we believe will be a "largely accurate" model of today's NLL -- obviously we'll then want to test it and compare behavior around various edge cases. C++/Rust Interop Problem Space Mapping (rust-lang/rust-project-goals#388) Progress | ---|--- Point of contact | Jon Bauman Champions | compiler (Oliver Scherer), lang (Tyler Mandry), libs (David Tolnay) Task owners | Jon Bauman 1 detailed update available. Comment by @baumanj posted on 2025-11-26: **Key developments** : _What has happened since the last time. It's perfectly ok to list "nothing" if that's the truth, we know people get busy._ Nothing! This is the first update and I have yet to focus attention on the project goal. For context, I am employed by the Rust Foundation leading the C++ Interoperability initiative and so far have been executing against the strategy detailed in the problem statement. Owing to greater than anticipated success and deadlines related to WG21 meetings, I've been focusing on the Social Interoperability strategy recently. I have just reached a point where I can turn more attention to the other strategies and so expect to make progress on this goal soon. **Blockers** : _List any Rust teams you are waiting on and what you are waiting for._ None; I'm getting excellent support from the Project in everything I'm doing. My successes thus far would not have been possible without them, and there are too many to enumerate in this space. There will be a blog post coming soon detailing the past year of work in the initiative where I intend to go into detail. Watch this space for updates. **Help wanted** : _Are there places where you are looking for contribution or feedback from the broader community?_ I am always interested in contribution and feedback. If you're interested, please reach out via interop@rustfoundation.org or t-lang/interop. Comprehensive niche checks for Rust (rust-lang/rust-project-goals#262) Progress | ---|--- Point of contact | Bastian Kersting Champions | compiler (Ben Kimock), opsem (Ben Kimock) Task owners | Bastian Kersting], Jakob Koschel No detailed updates available. Const Generics (rust-lang/rust-project-goals#100) Progress | ---|--- Point of contact | Boxy Champions | lang (Niko Matsakis) Task owners | Boxy, Noah Lev 2 detailed updates available. Comment by @BoxyUwU posted on 2025-11-05: Since the lang meeting most progress on this project goal has been unrelated to `adt_const_params`. There's been a large amount of work on `min_generic_const_args`, specifically Noah Lev's PR (rust-lang/rust#139558) which once landed the core of the impl work for the feature will be done. I've reviewed it together with Oliver Scherer and it's pretty much ready to go other than some small reviews. Once this PR lands I'm hoping that there should be a fair amount of "smallish" PRs that can be made which could be a good set of PRs to mentor new-ish contributors on. Comment by @BoxyUwU posted on 2025-11-29: Once again most progress here has been on `min_generic_const_args`. Noah Lev's PR (rust-lang/rust#139558) has now landed, as well as an additional PR of his: rust-lang/rust#148716. Between the two of these the core impl should be "mostly done" now, atleast with no additional feature gates enabled :). The next big step is to make the `min_generic_const_args` prototype work well with `adt_const_params` which I've implemented myself in rust-lang/rust#149136 and rust-lang/rust#149114. These PRs still need to be reviewed but the bulk of the impl work there is now done. These PRs allow for constructing ADTs where the field values may themselves be const parameters or non-concrete uses of `type_const`s (ie the values are const argument positions). Once my PRs have landed I would consider mgca as a _prototype_ to be truly "done" though not done as an actual feature. Huge thanks to camelid for sticking through a bunch of fairly painful PRs to get us to this point. Continue resolving `cargo-semver-checks` blockers for merging into cargo (rust-lang/rust-project-goals#104) Progress | ---|--- Point of contact | Predrag Gruevski Champions | cargo (Ed Page), rustdoc (Alona Enraght-Moony) Task owners | Predrag Gruevski 2 detailed updates available. Comment by @obi1kenobi posted on 2025-11-02: Status update as of November 1 **Key developments:** * Draft PR for exposing implied bounds in rustdoc JSON: https://github.com/rust-lang/rust/pull/148379 * A concrete plan for how that new info turns into dozens of new lints covering many kinds of bounds Linting `?Sized` and `'static` bounds turned out to be quite a bit more complex than I anticipated. The key issue is that seeing `T: Foo + ?Sized` does not guarantee that `T` can be unsized, since we might have `Foo: Sized` which renders the `?Sized` relaxation ineffective. Similarly, seeing `T: Foo` might also non-obviously imply `T: 'static` via a similar implied bound. Failure to correctly account for implied bounds would lead to catastrophic false-positives and false-negatives. For example, changing `T: Foo` to `T: Foo + 'static` could be a major breaking change or a no-op, depending on whether we have `Foo: 'static` (either directly or implicitly via other trait bounds). We cannot determine implied bounds using information present in rustdoc JSON today, so the rustdoc team and I have been iterating on the best way to compute and include that information in rustdoc JSON. Assuming something similar to the aforementioned PR becomes part of rustdoc JSON, `cargo-semver-checks` stands to gain several dozen new lints covering these tricky cases over trait associated types, generic type parameters, and APIT/RPIT/RPITIT. Comment by @obi1kenobi posted on 2025-11-23: Google Summer of Code 2025 is complete + finally some movement on cross-crate linting! πŸš€ **Key developments** * Two students had a successful conclusion of Google Summer of Code working on `cargo-semver-checks` β€” find more details here! * rustdoc JSON now includes rlib information, following the design for cross-crate rustdoc JSON info created at RustWeek 2025: https://github.com/rust-lang/rust/pull/149043 * A cargo issue was discovered that prevents this rlib info from being used; it's currently being triaged: https://github.com/rust-lang/cargo/issues/16291 * Once that's resolved, we'll have enough here for a basic prototype. Getting features right in dependencies will likely require more work due to having many more cargo-related edge cases. Develop the capabilities to keep the FLS up to date (rust-lang/rust-project-goals#391) Progress | ---|--- Point of contact | Pete LeVasseur Champions | bootstrap (Jakub BerΓ‘nek), lang (Niko Matsakis), spec (Pete LeVasseur) Task owners | Pete LeVasseur, Contributors from Ferrous Systems and others TBD, `t-spec` and contributors from Ferrous Systems 2 detailed updates available. Comment by @PLeVasseur posted on 2025-11-05: Meeting minutes from meeting held on 2025-10-31 (thank you to Tomas Sedovic πŸ₯°) Top-level: * Keep high quality bar, merge small, well-vetted changes when possible * Need concentrated effort to get the 1.90 FLS updates merged * Hristian Kirtchev and Tshepang Mbambo are navigating this currently with TC * Once 1.90 merged, we attempt first go as a team at 1.91 Discussion: * Suggest that everyone read the Glossary as a starting point * How to best triage / handle incoming issues? * TC and Pete LeVasseur moved labels onto FLS repo that were needed * Pete LeVasseur created issue template, that's in review, to help focus triage Comment by @PLeVasseur posted on 2025-11-21: Meeting notes here: 2025-11-14 - `t-fls` Meeting **Key developments** : PR merged for 1.90 update of the FLS. We're preparing now to work on the 1.91 update of the FLS. **Blockers** : None currently **Help wanted** : Anyone that's familiar with the Rust Reference is more than encouraged to read through the FLS to get a sense of it and where further alignment may be possible. Feel free to open issues on the FLS repo as you find things. Emit Retags in Codegen (rust-lang/rust-project-goals#392) Progress | ---|--- Point of contact | Ian McCormack Champions | compiler (Ralf Jung), opsem (Ralf Jung) Task owners | Ian McCormack 1 detailed update available. Comment by @icmccorm posted on 2025-11-11: We've posted a pre-RFC for feedback, and we'll continue updating and expanding the draft here. This reflects most of the current state of the implementation, aside from tracking interior mutability precisely, which is still TBD but is described in the RFC. Expand the Rust Reference to specify more aspects of the Rust language (rust-lang/rust-project-goals#394) Progress | ---|--- Point of contact | Josh Triplett Champions | lang-docs (Josh Triplett), spec (Josh Triplett) Task owners | Amanieu d'Antras, Guillaume Gomez, Jack Huey, Josh Triplett, lcnr, Mara Bos, Vadim Petrochenkov, Jane Lusby 1 detailed update available. Comment by @joshtriplett posted on 2025-11-12: We're putting together a prototype/demo of our reference changes at https://rust-lang.github.io/project-goal-reference-expansion/ . This includes a demonstration of tooling changes to provide stability markers (both "documenting unstable Rust" and "unstable documentation of stable Rust"). Finish the libtest json output experiment (rust-lang/rust-project-goals#255) Progress | ---|--- Point of contact | Ed Page Champions | cargo (Ed Page) Task owners | Ed Page 1 detailed update available. Comment by @epage posted on 2025-11-21: Key developments: * libtest2: * `#[test]` macro added * Support for `should_panic` * Support for `ignore` * Support for custom error types * compile-fail tests for macros Blockers * None Help wanted: * Round out libtest compatibility Finish the std::offload module (rust-lang/rust-project-goals#109) Progress | ---|--- Point of contact | Manuel Drehwald Champions | compiler (Manuel Drehwald), lang (TC) Task owners | Manuel Drehwald, LLVM offload/GPU contributors 1 detailed update available. Comment by @ZuseZ4 posted on 2025-11-19: ## Automatic Differentiation Time for the next update. By now, we've had `std::autodiff` for around a year in upstream rustc, but not in nightly. In order to get some more test users, I asked the infra team to re-evaluate just shipping `autodiff` as-is. This means that for the moment, we will increase the binary size of rustc by ~5%, even for nightly users who don't use this feature. We still have an open issue to avoid this overhead by using dlopen, please reach out if you have time to help. Thankfully, my request was accepted, so I spent most of my time lately preparing that release. 1. As part of my cleanup I went through old issues, and realized we now partly support rlib's! That's a huge improvement, because it means you can use autodiff not only in your `main.rs` file, but also in dependencies (either `lib.rs`, or even rely on crates that use autodiff). With the help of Ben Kimock I figured out how to get the remaining cases covered, hopefully the PR will land soon. 2. I started documentation improvements in https://github.com/rust-lang/rust/pull/149082 and https://github.com/rust-lang/rust/pull/148201, which should be visible on the website from tomorrow onwards. They are likely still not perfect, so please keep opening issues if you have questions. 3. We now provide a helpful error message if a user forgets enabling `lto=fat`: https://github.com/rust-lang/rust/pull/148855 4. After two months of work, @sgasho managed to add Rust CI to enzyme! Unfortunately, Enzyme devs broke and disabled it directly, so we'll need to talk about maintaining it as part of shipping Enzyme in nightly. I have the following elements on my TODO list as part shipping AD on nightly 1. Re-enable macOS build (probably easy) 2. Talk with Enzyme Devs about maintenance 3. Merge rlib support (under review) 4. upstream ADbenchmarks from r-l/enzyme to r-l/r as codegen tests (easy) 5. Write a block post/article for https://blog.rust-lang.org/inside-rust/ ## GPU offload 1. The llvm dev talk about GPU programming went great, I got to talk to a lot of other developers in the area of llvm offload. I hope to use some of the gained knowledge soon. Concrete steps planned are the integration of libc-gpu for IO from kernels, as well as moving over my code from the OpenMP API to the slightly lower level liboffload API. 2. We confirmed that our gpu offload prototype works on more hardware. By now we have the latest AMD APU generation covered, as well as an MI 250X and an RTX 4050. My own Laptop with a slightly older `AMD Ryzen 7 PRO 7840U` unfortunately turned out to be not supported by AMD drivers. 3. The offload intrinsic PR by Marcelo DomΓ­nguez is now marked as ready, and I left my second round of review. Hopefully, we can land it soon! 4. I spend some time trying to build and potentially ship the needed offload changes in nightly, unfortunately I still fail to build it in CI: https://github.com/rust-lang/rust/pull/148671. All in all, I think we made great progress over the last month, and it's motivating that we finally have no blockers left for flipping the `llvm.enzyme` config on our nightly builds. Getting Rust for Linux into stable Rust: compiler features (rust-lang/rust-project-goals#407) Progress | ---|--- Point of contact | Tomas Sedovic Champions | compiler (Wesley Wiser) Task owners | (depending on the flag) 2 detailed updates available. Comment by @tomassedovic posted on 2025-11-19: Update from the 2025-11-05 meeting. ## `-Zharden-sls` / rust#136597 Wesley Wiser left a comment on the PR, Andr ## -Zno-jump-tables / rust#145974 Merged, expected to ship in Rust 1.93. The Linux kernel added support for the new name for the option (`-Cjump-tables=n`). Comment by @tomassedovic posted on 2025-11-28: Update form the 2025-11-19 meeting: ## `-Zharden-sls` / rust#136597 Andrew addressed the comment and rebased the PR. It's waiting for a review again. ## `#!register_tool]` / [rust#66079 Tyler Mandry had an alternative proposal where lints would be defined in an external crate and could be brought in via `use` or something similar: https://rust-lang.zulipchat.com/#narrow/channel/213817-t-lang/topic/namespaced.20tool.20attrs. A concern people had was the overhead of having to define a new crate and the potential difficulty with experimenting on new lints. Tyler suggested adding this as a future possibility to RFC#3808 and FCPing it. Getting Rust for Linux into stable Rust: language features (rust-lang/rust-project-goals#116) Progress | ---|--- Point of contact | Tomas Sedovic Champions | lang (Josh Triplett), lang-docs (TC) Task owners | Ding Xiang Fei 2 detailed updates available. Comment by @tomassedovic posted on 2025-11-19: Update from the 2025-11-05 meeting. ## `Deref`/`Receiver` Ding Xiang Fei posted his reasoning for the trait split in the Zulip thread and suggested adding a second RFC to explain. TC recommended writing a Reference PR. The style forces one to explain the model clearly which should then make writing the RFC easier. The lang experiment PR for arbitrary self types have feature gates for the two options we're exploring. ## Arbitrary Self Types and `derive(CoercePointee)` / tracking issue #44874 theemathas opened an issue `derive(CoercePointee)` accepts `?Sized + Sized` #148399. This isn't a critical issue, just an error that arguably should be a lint. Boxy opened a fix for a `derive(CoercePointee)` blocker: Forbid freely casting lifetime bounds of dyn-types . ## RFC #3851: Supertrait Auto-impl Ding Xiang Fei is working on the implementation (the parser and HIR interface for it). Ding's also working on a more complete section dedicated to questions raised by obi1kenobi ## Field projections Benno Lossin has been posting super detailed updates on the tracking issue We've discussed the idea of virtual places (see Zulip thread where they were proposed). ## Inlining C code into Rust code Matt Mauer had an idea to compile C code into LLVM bytecode (instead of object file) and then the llvm-link tool to merge them together and treat everything in the second bytecode file as a static inlined function. Matt suggested we could integrate this into the rustc passes. This would make it easy to inline certain functions into Rust code without full LTO. Relevant Zulip thread. This sounds like a good candidate for the next Project Goals period. Comment by @tomassedovic posted on 2025-11-28: Update from the 2025-11-19 meeting. ## `rustdoc` checking for private and hidden items (rust##149105 & rust#149106) Miguel proposed Rust Doc checking for invalid links to items that are hidden or private even if no docs are built for them. This can help catch typos or dead links because the docs became out of date. Guillaume was much more open to this being a toggle, lolbinarycat opened a PR here: https://github.com/rust-lang/rust/pull/141299 ## `unsafe_op_in_unsafe_fn` not respected in imported declarative macros rust#112504 This lint doesn't trigger when importing a declarative macro that's calling unsafe code without having an `unsafe` block and without a `SAFETY` comment. The lint is only triggered when the macro was actually used. ## Fix for `imports_granularity` is not respected for `#cfg]`'d items / [rustfmt#6666 Ding opened a PR to fix this: https://github.com/rust-lang/rustfmt/issues/6666 ## rustfmt trailing comma hack Ding and Manish were talking about writing up a proper fix for the vertical layout that's currently being solved by the `, //,` hack ## `TypeId` layout This has been discussed in https://github.com/rust-lang/rust/pull/148265 and https://rust-lang.zulipchat.com/#narrow/channel/213817-t-lang/topic/TypeID.20design/near/560189854. Apiraino proposed a compiler design meeting here: https://github.com/rust-lang/compiler-team/issues/941. That meeting has not been scheduled yet, though. ## `Deref` / `Receiver` Following TC's recommendation, Ding is drafting the Reference PR. ## Arbitrary Self Types and `derive(CoercePointee)` Ding opened a PR to fix unsoundness in the `DispatchFromDyn` trait: https://github.com/rust-lang/rust/pull/149068 Theemathas opened a question on whether `Receiver` should by dyn-compatible: https://github.com/rust-lang/rust/issues/149094 ## RFC #3848: Pass pointers to `const` in assembly Merged! ## In-place initialization Benno noted that Effects and In-place Init are not compatible with each other: https://rust-lang.zulipchat.com/#narrow/channel/528918-t-lang.2Fin-place-init/topic/Fundamental.20Issue.20of.20Effects.20and.20In-place-init/with/558268061 This is going to affect any in-place init proposal. Benno proposes fixing this with keyword generics. This is a topic that will receive a lot of discussion doing forward. ## Alice has been nominated and accepted as `language-advisor`. Fantastic news and congratulations! Implement Open API Namespace Support (rust-lang/rust-project-goals#256) Progress | ---|--- Point of contact | Champions | cargo (Ed Page), compiler (b-naber), crates-io (Carol Nichols) Task owners | b-naber, Ed Page No detailed updates available. MIR move elimination (rust-lang/rust-project-goals#396) Progress | ---|--- Point of contact | Amanieu d'Antras Champions | lang (Amanieu d'Antras) Task owners | Amanieu d'Antras 1 detailed update available. Comment by @Amanieu posted on 2025-11-15: An RFC draft covering the MIR changes necessary to support this optimization has been written and is currently being reviewed by T-opsem. It has already received one round of review and the feedback has been incorporated in the draft. Prototype a new set of Cargo "plumbing" commands (rust-lang/rust-project-goals#264) Progress | ---|--- Point of contact | Task owners | , Ed Page No detailed updates available. Prototype Cargo build analysis (rust-lang/rust-project-goals#398) Progress | ---|--- Point of contact | Weihang Lo Champions | cargo (Weihang Lo) Task owners | Weihang Lo, Weihang Lo 2 detailed updates available. Comment by @weihanglo posted on 2025-11-04: Instead of using a full-fledged database like SQLite, we switched to a basic JSONL-based logging system to collect build metrics. A simple design doc can be found here: https://hackmd.io/K5-sGEJeR5mLGsJLXqsHrw. Here are the recent pull requests: * https://github.com/rust-lang/cargo/pull/16150 * https://github.com/rust-lang/cargo/pull/16179 To enable it, set `CARGO_BUILD_ANALYSIS_ENABLED=true` or set the Cargo config file like this: [build.analysis] enabled = true As of today (nightly-2025-11-03), it currently emits `build-started` and `timing-info` two log events to `$CARGO_HOME/log/` (`~/.cargo/log/` by default). The shape of `timing-info` JSON is basically the shape of the unstable `--timing=json`. I anticipate when this is stabilized we don't need `--timing=json`. The `build.analysis.enable` is a non-blocking unstable feature. Unless bugs, should be able to set unconditionally even on stable toolchain. When not supported, it would just warn the unknown config merely. Comment by @weihanglo posted on 2025-11-24: **Key developments** : Started emitting basic fingerprint information, and kicked off the refactor of rendering HTML timing report for future report replay through `cargo report timings` command. * https://github.com/rust-lang/cargo/pull/16203 * https://github.com/rust-lang/cargo/pull/16282 **Blockers** : no except my own availability **Help wanted** : Mendy on Zulip brought up log compression (#t-cargo > build analysis log format @ πŸ’¬) but I personally don't have time looking at it durnig this period. Would love to see people create an issue in rust-lang/cargo and help explore the idea. reflection and comptime (rust-lang/rust-project-goals#406) Progress | ---|--- Point of contact | Oliver Scherer Champions | compiler (Oliver Scherer), lang (Scott McMurray), libs (Josh Triplett) Task owners | oli-obk 1 detailed update available. Comment by @nikomatsakis posted on 2025-11-12: Another related PR: https://github.com/rust-lang/rust/pull/148820 Rework Cargo Build Dir Layout (rust-lang/rust-project-goals#401) Progress | ---|--- Point of contact | Ross Sullivan Champions | cargo (Weihang Lo) Task owners | Ross Sullivan 1 detailed update available. Comment by @ranger-ross posted on 2025-11-21: ### Status update November 21, 2025 October was largely spent working out design details of the build cache and locking design. https://github.com/rust-lang/cargo/pull/16155 was opened with an initial implementation for fine grain locking for Cargo's `build-dir` however it needs to be reworked after the design clarifications mentioned above. In November I had a change of employer so I my focus was largely on that. However, we did make some progress towards locking in https://github.com/rust-lang/cargo/pull/16230 which no longer lock the `artifact-dir` for `cargo check`. This is expected to land in `1.93.0`. I'm hoping to push fine grain locking forward later this month and in December. Run more tests for GCC backend in the Rust's CI (rust-lang/rust-project-goals#402) Progress | ---|--- Point of contact | Guillaume Gomez Champions | compiler (Wesley Wiser), infra (Marco Ieni) Task owners | Guillaume Gomez 1 detailed update available. Comment by @GuillaumeGomez posted on 2025-11-19: This project goal has been completed. I updated the first issue to reflect it. Closing the issue then. Rust Stabilization of MemorySanitizer and ThreadSanitizer Support (rust-lang/rust-project-goals#403) Progress | ---|--- Point of contact | Jakob Koschel Task owners | Bastian Kersting, Jakob Koschel 1 detailed update available. Comment by @jakos-sec posted on 2025-11-21: We've had a bunch of discussions and I opened a MCP (link, zulip). I think the final sentiment was creating new targets for the few sanitizers and platforms that are critical. I'm in the process of prototyping something to get new feedback on it. Rust Vision Document (rust-lang/rust-project-goals#269) Progress | ---|--- Point of contact | Niko Matsakis Task owners | vision team 1 detailed update available. Comment by @nikomatsakis posted on 2025-11-05: Update: Jack Huey has been doing great work building out a system for analyzing interviews. We are currently looking at slicing the data along a few dimensions: * What you know (e.g., experience in other languages, how much experience with Rust) * What you are trying to do (e.g., application area) * Where you are trying to do it (e.g., country) and asking _essentially_ the same set of questions for each, e.g., what about Rust worked well, what did not work as well, what got you into Rust, etc. Our plan is to prepare a draft of an RFC with some major conclusions and next steps also a repository with more detailed analysis (e.g., a deep dive into the Security Critical space). rustc-perf improvements (rust-lang/rust-project-goals#275) Progress | ---|--- Point of contact | James Champions | compiler (David Wood), infra (Jakub BerΓ‘nek) Task owners | James, Jakub BerΓ‘nek, David Wood 1 detailed update available. Comment by @Kobzol posted on 2025-11-19: The new system has been running in production without any major issues for a few weeks now. In a few weeks, I plan to start using the second collector, and then announce the new system to Project members to tell them how they can use its new features. Stabilize public/private dependencies (rust-lang/rust-project-goals#272) Progress | ---|--- Point of contact | Champions | cargo (Ed Page) Task owners | , Ed Page No detailed updates available. Stabilize rustdoc `doc_cfg` feature (rust-lang/rust-project-goals#404) Progress | ---|--- Point of contact | Guillaume Gomez Champions | rustdoc (Guillaume Gomez) Task owners | Guillaume Gomez No detailed updates available. SVE and SME on AArch64 (rust-lang/rust-project-goals#270) Progress | ---|--- Point of contact | David Wood Champions | compiler (David Wood), lang (Niko Matsakis), libs (Amanieu d'Antras) Task owners | David Wood 2 detailed updates available. Comment by @nikomatsakis posted on 2025-11-05: Notes from our meeting today: ## Syntax proposal: `only` keyword We are exploring the use of a new `only` keyword to identify "special" bounds that will affect the default bounds applied to the type parameter. Under this proposal, `T: SizeOfVal` is a regular bound, but `T: only SizeOfVal` indicates that the `T: const Sized` default is suppressed. For the initial proposal, `only` can only be applied to a known set of traits; one possible extension would be to permit traits with `only` supertraits to also have `only` applied to them: trait MyDeref: only SizeOfVal { } fn foo<T: only MyDeref>() { } // equivalent to trait MyDeref: only SizeOfVal { } fn foo<T: MyDeref + only SizeOfVal>() { } We discussed a few other syntactic options: * A `^SizeOfVal` sigil was appealing due to the semver analogy but rejected on the basis of it being cryptic and hard to google. * The idea of applying the keyword to the _type parameter_ `only T: SizeOfVal` sort of made sense, but it would not compose well if we add additional families of "opt-out" traits like `Destruct` and `Forget`, and it's not clear how it applies to supertraits. ## Transitioning target After testing, we confirmed that relaxing `Target` bound will result in significant breakage without some kind of transitionary measures. We discussed the options for addressing this. One option would be to leverage "Implementable trait aliases" RFC but that would require a new trait (`Deref20XX`) that has a weaker bound an alias `trait Deref = Deref20XX<Target: only SizeOfVal>`. That seems very disruptive. Instead, we are considering an edition-based approach where (in Rust 2024) a `T: Target` bound is defaulted to `T: Deref<Target: only SizeOfVal>` and (in Rust 20XX) `T: Target` is defaulted to `T: Deref<Target: only Pointee>`. The edition transition would therefore convert bounds to one of those two forms to be fully explicit. One caveat here is that this edition transition, if implemented naively, would result in stronger bounds than are needed much of the time. Therefore, we will explore the option of using bottom-up analysis to determine when transitioning whether the 20XX bound can be used instead of the more conservative 2024 bound. ## Supertrait bounds We explored the implications of weakening supertrait bounds a bit, looking at this example trait FooTr<T: ?Sized> {} struct Foo<T: ?Sized>(std::marker::PhantomData<T>); fn bar<T: ?Sized>() {} trait Bar: FooTr<Self> /*: no longer MetaSized */ { // ^^^^^^^^^^^ error! // real examples are `Pin` and `TypeOf::of`: fn foo(&self, x: Foo<Self>) { // ^^^^^^^^^^^^ error! bar::<Self>(); // ^^^^^^^^^^ error! // real examples are in core::fmt and core::iter: trait DoThing { fn do_thing() {} } impl<T: ?Sized> DoThing for T { default fn do_thing() {} } impl<T: Sized> DoThing for T { fn do_thing() {} } self.do_thing(); // ^^^^^^^^^^^^^ error! // specialisation case is not an issue because that feature isn't stable, we can adjust core, but is a hazard with expanding trait hierarchies in future if stabilisation is ever stabilised } } The `experimental_default_bounds` work originally added `Self: Trait` bounds to default methods but moved away from that because it could cause region errors (source 1 / source 2). We expect the same would apply to us but we are not sure. We decided not to do much on this, the focus remains on the `Deref::Target` transition as it has more uncertainty. Comment by @davidtwco posted on 2025-11-22: No progress since Niko Matsakis's last comment - intending to experiment with resolving challenges with `Deref::Target` and land the SVE infrastructure with unfinished parts for experimentation. Type System Documentation (rust-lang/rust-project-goals#405) Progress | ---|--- Point of contact | Boxy Champions | types (Boxy) Task owners | Boxy, lcnr 2 detailed updates available. Comment by @BoxyUwU posted on 2025-11-05: A bit late on this update but I've sat down with lcnr a little while back and we tried to come up with a list of topics that we felt fell under type system documentation. This is an entirely unordered list and some topics may already be adequately covered in the dev guide already. Regardless this effectively serves as a "shiny future" for everything I'd like to have documentation about somewhere (be it dev guide or in-tree module level documentation): * opaque types * non defining vs defining uses * member constraints (borrowck overlap) * checking item bounds * high level normalization/opaque type storage approach (new solver) * normalization incompleteness * method/function incompleteness * how does `use<...>` work * `'erased` regions causes problems with outlives item bounds in liveness * consistency across defining scopes * RPITIT inference? does this have special stuff * capturing of bound vars in opaques under binders, `Fn` bounds are somewhat special in relation to this * opaques inheriting late bound function parameters * non opaque type, `impl Trait` * RPITIT in traits desugaring * `impl Trait` in bindings * APIT desugaring impl details * const generics * anonymous constants * ConstArgHasType * TSVs vs RVs and generally upstream doc from lang meeting to dev guide * deterministic CTFE requirement * HIR typeck * expectations (and how used incorrectly :3) * method lookup + assorted code cleanups * coercions * auto-deref/reborrows (in coercions/method selection) * closure signature inference * fudge_inference_if_ok :> * diverging block handling :3 * fallback :3 * MIR borrowck * MIR typeck * why do we want two typecks * region dependent goals in new solver (interaction with lack-of region uniquification) * overlaps with opaque types * compute region graph * closure requirements * borrowck proper * compare predicate entailment :> * param env jank * implied bounds handling * trait objects: recent FCPs :3 * dyn compatibility soundness interactions (see coerce pointee/arbitrary self types stuff) * dyn compatibility for impl reasons (monomorphization) * projection bounds handling * args not required for wf * `ty::Infer` in `ty` overview * generalization * coroutines * deferred coroutine obligations * witness types? * why `-Zhigher-ranked-assumptions` exists * binders and universes `existsA forallB A == B` * build more of an intuition than current docs :thinking_face: * talk about hr implied bounds there/be more explicit/clear in https://rustc-dev-guide.rust-lang.org/traits/implied-bounds.html?highlight=implied#proving-implicit-implied-bounds * incompleteness * what is it * what kinds are OK (not entirely sure yet. small explanation and add a note) * trait solving * cycles * general overview of how trait solving works as a concept (probably with example and handwritten proof trees) * important: first go "prove stuff by recursively proving nested requirements", then later introduce candidates * clauses/predicates * running pending goals in a loop * what kinds of incompleteness (overlap with opaques) * builtin impls and how to add them * hir to ty lowering :> * itemctxt vs fnctxt behaviours * normalization in lowering * lowering should be lossy * idempotency(?) * cycles from param env construction * const generics jank about Self and no generic parameters allowed * well formedness checking + wf disambiguation page * normalization & aliases * be more clear about normalizing ambig aliases to infer vars :thinking_face: * normalize when equating infer vars with aliases (overlap with generalization?) * item bounds checking * interactions with implied bounds (overlap with implied bounds and hir ty lowering) * variance Since making this list I've started working on writing documentation about coercions/adjustments. So far this has mostly resulted in spending a lot of time reading the relevant code in rustc. I've discovered a few bugs and inconsistencies in behaviour and made some nice code cleanups which should be valuable for people learning how coercions are implemented already. This can be seen in #147565 I intend to start actually writing stuff in the dev guide for coercions/adjustments now as that PR is almost done. I also intend to use a zulip thread (#t-compiler/rustc-dev-guide > Type System Docs Rewrite) for more "lightweight" and informal updates on this project goal, as well as just miscellaneous discussion about work relating to this project goal Comment by @BoxyUwU posted on 2025-11-29: I've made a tracking issue on the dev guide repo for this project goal: rust-lang/rustc-dev-guide#2663. I've also written documentation for coercions: rust-lang/rustc-dev-guide#2662. There have been a few extra additions to the list in the previous update. Unsafe Fields (rust-lang/rust-project-goals#273) Progress | ---|--- Point of contact | Jack Wrenn Champions | compiler (Jack Wrenn), lang (Scott McMurray) Task owners | Jacob Pratt, Jack Wrenn, Luca Versari No detailed updates available.
16.12.2025 00:00 πŸ‘ 0 πŸ” 0 πŸ’¬ 0 πŸ“Œ 0
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 * `NonZero<u{N}>::div_ceil` * `Location::file_as_c_str` * `RwLockWriteGuard::downgrade` * `Box::new_zeroed` * `Box::new_zeroed_slice` * `Rc::new_zeroed` * `Rc::new_zeroed_slice` * `Arc::new_zeroed` * `Arc::new_zeroed_slice` * `btree_map::Entry::insert_entry` * `btree_map::VacantEntry::insert_entry` * `impl Extend<proc_macro::Group> for proc_macro::TokenStream` * `impl Extend<proc_macro::Literal> for proc_macro::TokenStream` * `impl Extend<proc_macro::Punct> for proc_macro::TokenStream` * `impl Extend<proc_macro::Ident> for proc_macro::TokenStream` These previously stable APIs are now stable in const contexts: * `<[_]>::rotate_left` * `<[_]>::rotate_right` ### 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!
11.12.2025 00:00 πŸ‘ 3 πŸ” 1 πŸ’¬ 0 πŸ“Œ 0
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. ↩
08.12.2025 00:00 πŸ‘ 0 πŸ” 0 πŸ’¬ 0 πŸ“Œ 0
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
05.12.2025 00:00 πŸ‘ 0 πŸ” 0 πŸ’¬ 0 πŸ“Œ 0
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? ↩
03.12.2025 00:00 πŸ‘ 0 πŸ” 0 πŸ’¬ 0 πŸ“Œ 0
Interview with Jan David Nose On the Content Team, we had our first whirlwind outing at RustConf 2025 in Seattle, Washington, USA. There we had a chance to speak with folks about interesting things happening in the Project and the wider community. # Jan David Nose, Infrastructure Team In this interview, Xander Cesari sits down with Jan David Nose, then one of the full-time engineers on the Infrastructure Team, which maintains and develops the infrastructure upon which Rust is developed and deployed -- including CI/CD tooling and crates.io. We released this video on an accelerated timeline, some weeks ago, in light of the recent software supply chain attacks, but the interview was conducted prior to the news of compromised packages in other languages and ecosystems. Check out the interview here or click below. * * * ## Transcript **Xander Cesari** : Hey, this is Xander Cesari with the Rust Project Content Team, recording on the last hour of the last day of RustConf 2025 here in Seattle. So it's been a long and amazing two days. And I'm sitting down here with a team member from the Rust Project Infra Team, the unsung heroes of the Rust language. Want to introduce yourself and kind of how you got involved? **Jan David Nose** : Yeah, sure. I'm JD. Jan David is the full name, but especially in international contexts, I just go with JD. I've been working for the Rust Foundation for the past three years as a full-time employee and I essentially hit the jackpot to work full-time on open source and I've been in the Infra Team of the Rust Project for the whole time. For the past two years I've led the team together with Jake. So the Infra Team is kind of a thing that lets Rust happen and there's a lot of different pieces. **Xander Cesari** : Could you give me an overview of the responsibility of the Infra Team? **Jan David Nose** : Sure. I think on a high level, we think about this in terms of, we serve two different groups of people. On one side, we have users of the language, and on the other side, we really try to provide good tooling for the maintainers of the language. **Jan David Nose** : Starting with the maintainer side, this is really everything about how Rust is built. From the moment someone makes a contribution or opens a PR, we maintain the continuous integration that makes sure that the PR actually works. There's a lot of bots and tooling helping out behind the scenes to kind of maintain a good status quo, a sane state. Lots of small things like triage tools on GitHub to set labels and ping people and these kinds of things. And that's kind of managed by the Infra Team at large. **Jan David Nose** : And then on the user side, we have a lot of, or the two most important things are making sure users can actually download Rust. We don't develop crates.io, but we support the infrastructure to actually ship crates to users. All the downloads go through content delivery networks that we provide. The same for Rust releases. So if I don't do my job well, which has happened, there might be a global outage of crates.io and no one can download stuff. But those are kind of the two different buckets of services that we run and operate. **Xander Cesari** : Gotcha. So on the maintainer side, the Rust organization on GitHub is a large organization with a lot of activity, a lot of code. There's obviously a lot of large code bases being developed on GitHub, but there are not that many languages the size of Rust being developed on GitHub. Are there unique challenges to developing a language and the tooling that's required versus developing other software projects? **Jan David Nose** : I can think of a few things that have less to do with the language specifically, but with some of the architecture decisions that were made very early on in the life cycle of Rust. So one of the things that actually caused a lot of headache for mostly GitHub, and then when they complained to us, for us as well, is that for a long, long time, the index for crates.io was a Git repo on GitHub. As Rust started to grow, the activity on the repo became so big that it actually caused some issues, I would say, in a friendly way on GitHub, just in terms of how much resources that single repository was consuming. That then kind of started this work on a web-based, HTTP-based index to shift that away. That's certainly one area where we've seen how Rust has struggled a little bit with the platform, but also the platform provider struggled with us. **Jan David Nose** : I think for Rust itself, especially when we look at CI, we really want to make sure that Rust works well on all of the targets and all the platforms we support. That means we have an extremely wide CI pipeline where, for every Tier 1 target, we want to run all the tests, we want to build the release artifacts, we want to upload all of that to S3. We want to do as much as we reasonably can for Tier 2 targets and, to a lesser extent, maybe even test some stuff on Tier 3. That has turned into a gigantic build pipeline. Marco gave a talk today on what we've done with CI over the last year. One of the numbers that came out of doing the research for this talk is that we accumulate over three million build minutes per month, which is about six years of CPU time every month. **Jan David Nose** : Especially when it comes to open source projects, I think we're one of the biggest consumers of GitHub Actions in that sense. Not the biggest in total; there are definitely bigger commercial projects. But that's a unique challenge for us to manage because we want to provide as good a service as we can to the community and make sure that what we ship is high quality. That comes at a huge cost in terms of scaling. As Rust gets more popular and we want to target more and more platforms, this is like a problem that just continues to grow. **Jan David Nose** : We'll probably never remove a lot of targets, so there's an interesting challenge to think about. If it's already big now, how does this look in 5 years, 10 years, 15 years, and how can we make sure we can maintain the level of quality we want to ship? When you build and run for a target in the CI pipeline, some of those Tier 1 targets you can just ask a cloud service provider to give you a VM running on that piece of hardware, but some of them are probably not things that you can just run in the cloud. **Xander Cesari** : Is there some HIL (Hardware-In-the-Loop) lab somewhere? **Jan David Nose** : So you're touching on a conversation that's happening pretty much as we speak. So far, as part of our target tier policy, there is a clause that says it needs to be able to run in CI. That has meant being very selective about only promoting things to Tier 1 that we can actually run and test. For all of this, we had a prerequisite that it runs on GitHub Actions. So far we've used very little hardware that is not natively supported or provided by GitHub. **Jan David Nose** : But this is exactly the point with Rust increasing in popularity. We just got requests to support IBM platforms and RISC-V, and those are not natively supported on GitHub. That has kicked off an internal conversation about how we even support this. How can we as a project enable companies that can provide us hardware to test on? What are the implications of that? **Jan David Nose** : On one side, there are interesting constraints and considerations. For example, you don't want your PRs to randomly fail because someone else's hardware is not available. We're already so resource-constrained on how many PRs we can merge each day that adding noise to that process would really slow down contributions to Rust. On the other side, there are security implications. Especially if we talk about promoting something to Tier 1 and we want to build release artifacts on that hardware, we need to make sure that those are actually secure and no one sneaks a back door into the Rust compiler target for RISC-V. **Jan David Nose** : So there are interesting challenges for us, especially in the world we live in where supply chain security is a massive concern. We need to figure out how we can both support the growth of Rust and the growth of the language, the community, and the ecosystem at large while also making sure that the things we ship are reliable, secure, and performant. That is becoming an increasingly relevant and interesting piece to work on. So far we've gotten away with the platforms that GitHub supports, but it's really cool to see that this is starting to change and people approach us and are willing to provide hardware, provide sponsorship, and help us test on their platforms. But essentially we don't have a good answer for this yet. We're still trying to figure out what this means, what we need to take into consideration, and what our requirements are to use external hardware. **Xander Cesari** : Yeah, everyone is so excited about Rust will run everywhere, but there's a maintenance cost there that is almost exponential in scope. **Jan David Nose** : It's really interesting as well because there's a tension there. I think with IBM, for example, approaching us, it's an interesting example. Who has IBM platforms at home? The number of users for that platform is really small globally, but IBM also invests heavily in Rust, tries to make this happen, and is willing to provide the hardware. **Jan David Nose** : For us, that leads to a set of questions. Is there a line? Is there a certain requirement? Is there a certain amount of usage that a platform would need for us to promote it? Or do we say we want to promote as much as we can to Tier 1? This is a conversation we haven't really had to have yet. It's only now starting to creep in as Rust is adopted more widely and companies pour serious money and resources into it. That's exciting to see. **Jan David Nose** : In this specific case, companies approach the Infra Team to figure out how we can add their platforms to CI as a first step towards Tier 1 support. But it's also a broader discussion we need to have with larger parts of the Rust Project. For Tier 1 promotions, for example, the Compiler Team needs to sign off, Infra needs to sign off. Many more people need to be involved in this discussion of how we can support the growing needs of the ecosystem at large. **Xander Cesari** : I get the feeling that's going to be a theme throughout this interview. **Jan David Nose** : 100%. **Xander Cesari** : So one other tool that's part of this pipeline that I totally didn't know about for a long time, and I think a talk at a different conference clued me into it, is Crater. It's a tool that attempts to run all of the Rust code it can find on the internet. Can you talk about what that tool does and how it integrates into the release process? **Jan David Nose** : Whenever someone creates a pull request on GitHub to add a new feature or bug fix to the Rust compiler, they can start what's called a Crater run, or an experiment. Crater is effectively a large fleet of machines that tries to pull in as many crates as it can. Ideally, we would love to test all crates, but for a variety of reasons that's not possible. Some crates simply don't build reliably, so we maintain lists to exclude those. From the top of my head, I think we currently test against roughly 60% of crates. **Jan David Nose** : The experiment takes the code from your pull request, builds the Rust compiler with it, and then uses that compiler to build all of these crates. It reports back whether there are any regressions related to the change you proposed. That is a very important tool for us to maintain backwards compatibility with new versions and new features in Rust. It lets us ask: does the ecosystem still compile if we add this feature to the compiler, and where do we run into issues? Then, and this is more on the Compiler Team side, there's a decision about how to proceed. Is the breakage acceptable? Do we need to adjust the feature? Having Crater is what makes that conversation possible because it gives us real data on the impact on the wider ecosystem. **Xander Cesari** : I think that's so interesting because as more and more companies adopt Rust, they're asking whether the language is going to be stable and backward compatible. You hear about other programming languages that had a big version change that caused a lot of drama and code changes. The fact that if you have code on crates.io, the Compiler Team is probably already testing against it for backwards compatibility is pretty reassuring. **Jan David Nose** : Yeah, the chances are high, I would say. Especially looking at the whole Python 2 to Python 3 migration, I think as an industry we've learned a lot from those big version jumps. I can't really speak for the Compiler Team because I'm not a member and I wasn't involved in the decision-making, but I feel this is one of the reasons why backwards compatibility is such a big deal in Rust's design. We want to make it as painless as possible to stay current, stay up to date, and make sure we don't accidentally break the language or create painful migration points where the entire ecosystem has to move at once. **Xander Cesari** : Do you know if there are other organizations pulling in something like Crater and running it on their own internal crate repositories, maybe some of the big tech companies or other compiler developers or even other languages? Or is this really bespoke for the Rust compiler team? **Jan David Nose** : I don't know of anyone who runs Crater itself as a tool. Crater is built on a sandboxing framework that we also use in other places. For example, docs.rs uses some of the same underlying infrastructure to build all of the documentation. We try to share as much as we can of the functionality that exists in Crater, but I'm not aware of anyone using Crater in the same way we do. **Xander Cesari** : Gotcha. The other big part of your job is that the Infra Team works on supporting maintainers, but it also supports users and consumers of Rust who are pulling from crates.io. It sounds like crates.io is not directly within your team, but you support a lot of the backend there. **Jan David Nose** : Yeah, exactly. crates.io has its own team, and that team maintains the web application and the APIs. The crates themselves, all the individual files that people download, are hosted within our infrastructure. The Infra Team maintains the content delivery network that sits in front of that. Every download of a crate goes through infrastructure that we maintain. We collaborate very closely with the crates.io team on this shared interface. They own the app and the API, and we make sure that the files get delivered to the end user. **Xander Cesari** : So it sounds like there's a lot of verification of the files that get uploaded and checks every time someone pushes a new version to crates.io. That part all happens within crates.io as an application. **Jan David Nose** : Cargo uses the crates.io API to upload the crate file. crates.io has a lot of internal logic to verify that it is valid and that everything looks correct. For us, as the Infra Team, we treat that as a black box. crates.io does its work, and if it is happy with the upload, it stores the file in S3. From that point onward, infrastructure makes sure that the file is accessible and can be downloaded so people can start using your crate. **Xander Cesari** : In this theme of Rust being a bit of a victim of its own success, I assume all of the traffic graphs and download graphs are very much up and to the right. **Jan David Nose** : On the Foundation side, one of our colleagues likes to check how long it takes for one billion downloads to happen on crates.io, and that number has been falling quickly. I don't remember what it was three years ago, but it has come down by orders of magnitude. In our download traffic we definitely see exponential growth. Our traffic tends to double year over year, and that trend has been pretty stable. It really seems like Rust is getting a lot of adoption in the ecosystem and people are using it for more and more things. **Xander Cesari** : How has the Infra Team scaled with that? Are you staying ahead of it, or are there a lot of late nights? **Jan David Nose** : There have definitely been late nights. In the three years I've been working in the Infra Team, every year has had a different theme that was essentially a fire to put out. **Jan David Nose** : It changes because we fix one thing and then the next thing breaks. So far, luckily, those fires have been mostly sequential, not parallel. When I joined, bandwidth was the big topic. Over the last year, it has been more about CI. About three years ago, we hit this inflection point where traffic was doubling and the sponsorship capacity we had at the time was reaching its limits. **Jan David Nose** : Two or three years ago, Fastly welcomed us into their Fast Forward program and has been sponsoring all of our bandwidth since then. That has mostly helped me sleep at night. It has been a very good relationship. They have been an amazing partner and have helped us at every step to remove the fear that we might hit limits. They are very active in the open source community at large; most famously they also sponsor PyPI and the Python ecosystem, compared to which we're a tiny fish in a very big pond. That gives us a lot of confidence that we can sustain this growth and keep providing crates and releases at the level of quality people expect. **Xander Cesari** : In some ways, Rust did such a good job of making all of that infrastructure feel invisible. You just type Cargo commands into your terminal and it feels magical. **Jan David Nose** : I'm really happy about that. It's an interesting aspect of running an infrastructure team in open source. If you look at the ten-year history since the first stable release, or even the fifteen years since Rust really started, infrastructure was volunteer-run for most of that time. I've been here for three years, and I was the first full-time infrastructure engineer. So for ten to twelve years, volunteers ran the infrastructure. **Jan David Nose** : For them, it was crucial that things just worked, because you can't page volunteers in the middle of the night because a server caught fire or downloads stopped working. From the beginning, our infrastructure has been designed to be as simple and as reliable as possible. The same is true for our CDNs. I always feel a bit bad because Fastly is an amazing sponsor. Every time we meet them at conferences or they announce new features, they ask whether we want to use them or talk about how we use Fastly in production. And every time I have to say: we have the simplest configuration possible. We set some HTTP headers. That's pretty much it. **Jan David Nose** : It's a very cool platform, but we use the smallest set of features because we need to maintain all of this with a very small team that is mostly volunteer-based. Our priority has always been to keep things simple and reliable and not chase every fancy new technology, so that the project stays sustainable. **Xander Cesari** : Volunteer-based organizations seem to have to care about work-life balance, which is probably terrific, and there are lessons to be learned there. **Jan David Nose** : Yeah, it's definitely a very interesting environment to work in. It has different rules than corporations or commercial teams. We have to think about how much work we can do in a given timeframe in a very different way, because it's unpredictable when volunteers have time, when they're around, and what is happening in their lives. **Jan David Nose** : Over the last few years, we've tried to reduce the number of fires that can break out. And when they do happen, we try to shield volunteers from them and take that work on as full-time employees. That started with me three years ago. Last year Marco joined, which increased the capacity we have, because there is so much to do on the Infra side that even with me working full-time, we simply did not have enough people. **Xander Cesari** : So you're two full-time and everything else is volunteer. **Jan David Nose** : Exactly. The team is around eight people. Marco and I work full-time and are paid by the Rust Foundation to focus exclusively on infrastructure. Then we have a handful of volunteers who work on different things. **Jan David Nose** : Because our field of responsibility is so wide, the Infra Team works more in silos than other teams might. We have people who care deeply about very specific parts of the infrastructure. Otherwise there is simply too much to know for any one person. It has been a really nice mix, and it's amazing to work with the people on the team. **Jan David Nose** : As someone who is privileged enough to work full-time on this and has the time and resources, we try to bear the bigger burden and create a space that is fun for volunteers to join. We want them to work on exciting things where there is less risk of something catching fire, where it's easier to come in, do a piece of work, and then step away. If your personal life takes over for two weeks, that's okay, because someone is there to make sure the servers and the lights stay on. **Jan David Nose** : A lot of that work lives more on the maintainer side: the GitHub apps, the bots that help with triage. It's less risky if something goes wrong there. On the user side, if you push the wrong DNS setting, as someone might have done, you can end up in a situation where for 30 minutes no one can download crates. And in this case, "no one" literally means no user worldwide. That's not an experience I want volunteers to have. It's extremely stressful and was ultimately one of the reasons I joined in the first placeβ€”there was a real feeling of burnout from carrying that responsibility. **Jan David Nose** : It's easier to carry that as a full-timer. We have more time and more ways to manage the stress. I'm honestly extremely amazed by what the Infra Team was able to do as volunteers. It's unbelievable what they built and how far they pushed Rust to get to where we are now. **Xander Cesari** : I think anyone who's managing web traffic in 2025 is talking about traffic skyrocketing due to bots and scrapers for AI or other purposes. Has that hit the Rust network as well? **Jan David Nose** : Yeah, we've definitely seen that. It's handled by a slightly different team, but on the docs.rs side in particular we've seen crawlers hit us hard from time to time, and that has caused noticeable service degradation. We're painfully aware of the increase in traffic that comes in short but very intense bursts when crawlers go wild. **Jan David Nose** : That introduces a new challenge for our infrastructure. We need to figure out how to react to that traffic and protect our services from becoming unavailable to real users who want to use docs.rs to look up something for their work. On the CDN side, our providers can usually handle the traffic. It is more often the application side where things hurt. **Jan David Nose** : On the CDN side we also see people crawling crates.io, presumably to vacuum up the entire crates ecosystem into an LLM. Fortunately, over the last two years we've done a lot of work to make sure crates.io as an application is less affected by these traffic spikes. Downloads now bypass crates.io entirely and go straight to the CDN, so the API is not hit by these bursts. In the past, this would have looked like a DDoS attack, with so many requests from so many sources that we couldn't handle it. **Jan David Nose** : We've done a lot of backend work to keep our stack reliable, but it's definitely something that has changed the game over the last year. We can clearly see that crawlers are much more active than before. **Xander Cesari** : That makes sense. I'm sure Fastly is working on this as well. Their business has to adapt to be robust to this new internet. **Jan David Nose** : Exactly. For example, one of the conversations we're having right now is about docs.rs. It's still hosted on AWS behind CloudFront, but we're talking about putting it behind Fastly because through Fastly we get features like bot protection that can help keep crawlers out. **Jan David Nose** : This is a good example of how our conversations have changed in the last six months. At the start of the year I did not think this would be a topic we would be discussing. We were focused on other things. For docs.rs we have long-term plans to rebuild the infrastructure that powers it, and I expected us to spend our energy there. But with the changes in the industry and everyone trying to accumulate as much data as possible, our priorities have shifted. The problems we face and the order in which we tackle them have changed. **Xander Cesari** : And I assume as one of the few paid members of a mostly volunteer team, you often end up working on the fires, not the interesting next feature that might be more fun. **Jan David Nose** : That is true, although it sounds a bit negative to say I only get to work on fires. Sometimes it feels like that because, as with any technology stack, there is a lot of maintenance overhead. We definitely pay that price on the infrastructure side. **Jan David Nose** : Marco, for example, spent time this year going through all the servers we run, cataloging them, and making sure they're patched and on the latest operating system version. We updated our Ubuntu machines to the latest LTS. It feels a bit like busy workβ€”you just have to do it because it's important and necessary, but it's not the most exciting project. **Jan David Nose** : On the other hand, when it comes to things like CDN configuration and figuring out how bot protection features work and whether they are relevant to us, that is also genuinely interesting work. It lets us play with new tools vendors provide, and we're working on challenges that the wider industry is facing. How do you deal with this new kind of traffic? What are the implications of banning bots? How high is the risk of blocking real users? Sometimes someone just misconfigures a curl script, and from the outside it looks like they're crawling our site. **Jan David Nose** : So it's an interesting field to work in, figuring out how we can use new features and address new challenges. That keeps it exciting even for us full-timers who do more of the "boring" work. We get to adapt alongside how the world around us is changing. If there's one constant, it's change. **Xander Cesari** : Another ripped-from-the-headlines change around this topic is software supply chain security, and specifically xz-utils and the conversation around open source security. How much has that changed the landscape you work in? **Jan David Nose** : The xz-utils compromise was scary. I don't want to call it a wake-up call, because we've been aware that supply chain security is a big issue and this was not the first compromise. But the way it happened felt very unsettling. You saw an actor spend a year and a half building social trust in an open source project and then using that to introduce a backdoor. **Jan David Nose** : Thinking about that in the context of Rust: every team in the project talks about how we need more maintainers, how there's too much workload on the people who are currently contributing, and how Rust's growth puts strain on the organization as a whole. We want to be an open and welcoming project, and right now we also need to bring new people in. If someone shows up and says, "I'm willing to help, please onboard me," and they stick around for a year and then do something malicious, we would be susceptible to that. I don't think this is unique to Rust. This is an inherent problem in open source. **Xander Cesari** : Yeah, it's antithetical to the culture. **Jan David Nose** : Exactly. So we're trying to think through how we, as a project and as an ecosystem, deal with persistent threat actors who have the time and resources to play a long game. Paying someone to work full-time on open source for a year is a very different threat model than what we used to worry about. **Jan David Nose** : I used to joke that the biggest threat to crates.io was me accidentally pulling the plug on a CDN. I think that has changed. Today the bigger threat is someone managing to insert malicious code into our releases, our supply chain, or crates.io itself. They could find ways to interfere with our systems in ways we're simply not prepared for, where, as a largely volunteer organization, we might be too slow to react to a new kind of attack. **Jan David Nose** : Looking back over the last three years, this shift became very noticeable, especially after the first year. Traffic was doubling, Rust usage was going up a lot, and there were news stories about Rust being used in the Windows kernel, in Android, and in parts of iOS. Suddenly Rust is everywhere. If you want to attack "everywhere," going after Rust becomes attractive. That definitely puts a target on our back and has changed the game. **Jan David Nose** : I'm very glad the Rust Foundation has a dedicated security engineer who has done a lot of threat modeling and worked with us on infrastructure security. There's also a lot of work happening specifically around the crates ecosystem and preventing supply chain attacks through crates. Luckily, it's not something the Infra side has to solve alone. But it is getting a lot more attention, and I think it will be one of the big challenges for the future: how a mostly volunteer-run project keeps up with this looming threat. **Xander Cesari** : And it is the industry at large. This is not a unique problem to the Rust package manager. All package registries, from Python to JavaScript to Nix, deal with this. Is there an industry-wide conversation about how to help each other out and share learnings? **Jan David Nose** : Yeah, there's definitely a lot happening. I have to smile a bit because, with a lot of empathy but also a bit of relief, we sometimes share news when another package ecosystem gets compromised. It is a reminder that it's not just us, sometimes it's npm this time. **Jan David Nose** : We really try to stay aware of what's happening in the industry and in other ecosystems: what new threats or attack vectors are emerging, what others are struggling with. Sometimes that is security; sometimes it's usability. A year and a half ago, for example, npm had the "everything" package where someone declared every package on npm as a dependency, which blew up the index. We look at incidents like that and ask whether crates.io would struggle with something similar and whether we need to make changes. **Jan David Nose** : On the security side we also follow closely what others are doing. In the packaging community, the different package managers are starting to come together more often to figure out which problems everyone shares. There is a bit of a joke that we're all just shipping files over the internet. Whether it's an npm package or a crate, ultimately it's a bunch of text files in a zip. So from an infrastructure perspective the problems are very similar. **Jan David Nose** : These communities are now talking more about what problems PyPI has, what problems crates.io has, what is happening in the npm space. One thing every ecosystem has seenβ€”even the very established onesβ€”is a big increase in bandwidth needs, largely connected to the emergence of AI. PyPI, for example, publishes download charts, and it's striking. Python had steady growthβ€”slightly exponential, but manageableβ€”for many years. Then a year or two ago you see a massive hockey stick. People discovered that PyPI was a great distribution system for their models. There were no file size limits at the time, so you could publish precompiled GPU models there. **Jan David Nose** : That pattern shows up everywhere. It has kicked off a new era for packaging ecosystems to come together and ask: in a time where open source is underfunded and traffic needs keep growing, how can we act together to find solutions to these shared problems? crates.io is part of those conversations. It's interesting to see how we, as an industry, share very similar problems across ecosystemsβ€”Python, npm, Rust, and others. **Xander Cesari** : With a smaller, more hobbyist-focused community, you can have relaxed rules about what goes into your package manager. Everyone knows the spirit of what you're trying to do and you can get away without a lot of hard rules and consequences. Is the Rust world going to have to think about much harder rules around package sizes, allowed files, and how you're allowed to distribute things? **Jan David Nose** : Funnily enough, we're coming at this from the opposite direction. Compared to other ecosystems, we've always had fairly strict limits. A crate can be at most around ten megabytes in size. There are limits on what kinds of files you can put in there. Ironically, those limits have helped us keep traffic manageable in this period. **Jan David Nose** : At the same time, there is a valid argument that these limits may not serve all Rust use cases. There are situations where you might want to include something precompiled in your crate because it is hard to compile locally, takes a very long time, or depends on obscure headers no one has. I don't think we've reached the final state of what the crates.io package format should look like. **Jan David Nose** : That has interesting security implications. When we talk about precompiled binaries or payloads, we all have that little voice in our head every time we see a curl | sh command: can I trust this? The same is true if you download a crate that contains a precompiled blob you cannot easily inspect. **Jan David Nose** : The Rust Foundation is doing a lot of work and research here. My colleague Adam, who works on the crates.io team, is working behind the scenes to answer some of these questions. For example: what kind of security testing can we do before we publish crates to make sure they are secure and don't contain malicious payloads? How do we surface this information? How do we tell a publisher that they included files that are not allowed? And from the user's perspective, when you visit crates.io, how can you judge how well maintained and how secure a crate is? **Jan David Nose** : Those conversations are happening quite broadly in the ecosystem. On the Infra side we're far down the chain. Ultimately we integrate with whatever security scanning infrastructure crates.io builds. We don't have to do the security research ourselves, but we do have to support it. **Jan David Nose** : There's still a lot that needs to happen. As awesome as Rust already is, and as much as I love using it, it's important to remember that we're still a very young ecosystem. Python is now very mature and stable, but it's more than 25 years old. Rust is about ten years old as a stable language. We still have a lot to learn and figure out. **Xander Cesari** : Is the Rust ecosystem running into problems earlier than other languages because we're succeeding at being foundational software and Rust is used in places that are even more security-critical than other languages, so you have to hit these hard problems earlier than the Python world did? **Jan David Nose** : I think that's true. Other ecosystems probably had more time to mature and answer these questions. We're operating on a more condensed timeline. There is also simply more happening now. Open source has been very successful; it's everywhere. That means there are more places where security is critical. **Jan David Nose** : So this comes with the success of open source, with what is happening in the ecosystem at large, and with the industry we're in. It does mean we have less time to figure some things out. On the flip side, we also have less baggage. We have less technical debt and fifteen fewer years of accumulated history. That lets us be on the forefront in some areas, like how a package ecosystem can stay secure and what infrastructure a 21st century open source project needs. **Jan David Nose** : Here I really want to call out the Rust Foundation. They actively support this work: hiring people like Marco and me to work full-time on infrastructure, having Walter and Adam focus heavily on security, and as an organization taking supply chain considerations very seriously. The Foundation also works with other ecosystems so we can learn and grow together and build a better industry. **Jan David Nose** : Behind the scenes, colleagues constantly work to open doors for us as a relatively young language, so we can be part of those conversations and sit at the table with other ecosystems. That lets us learn from what others have already gone through and also help shape where things are going. Sustainability is a big part of that: how do we fund the project long term? How do we make sure we have the human resources and financial resources to run the infrastructure and support maintainers? I definitely underestimated how much of my job would be relationship management and budget planning, making sure credits last until new ones arrive. **Xander Cesari** : Most open core business models give away the thing that doesn't cost muchβ€”the softwareβ€”and charge for the thing that scales with useβ€”the service. In Rust's case, it's all free, which is excellent for adoption, but it must require a very creative perspective on the business side. **Jan David Nose** : Yeah, and that's where different forces pull in opposite directions. As an open source project, we want everyone to be able to use Rust for free. We want great user experience. When we talk about downloads, there are ways for us to make them much cheaper, but that might mean hosting everything in a single geographic location. Then everyone, including people in Australia, would have to download from, say, Europe, and their experience would get much worse. **Jan David Nose** : Instead, we want to use services that are more expensive but provide a better experience for Rust users. There's a real tension there. On one side we want to do the best we can; on the other side we need to be realistic that this costs money. **Xander Cesari** : I had been thinking of infrastructure as a binary: it either works or it doesn't. But you're right, it's a slider. You can pick how much money you want to spend and what quality of service you get. Are there new technologies coming, either for the Rust Infra Team or the packaging world in general, to help with these security problems? New sandboxing technologies or higher-level support? **Jan David Nose** : A lot of people are working on this problem from different angles. Internally we've talked a lot about it, especially in the context of Crater. Crater pulls in all of those crates to build them and get feedback from the Rust compiler. That means if someone publishes malicious code, we will download it and build it. **Jan David Nose** : In Rust this is a particular challenge because build scripts can essentially do anything on your machine. For us that means we need strong sandboxing. We've built our own sandboxing framework so every crate build runs in an isolated container, which prevents malicious code from escaping and messing with the host systems. **Jan David Nose** : We feel that pain in Crater, but if we can solve it in a way that isn't exclusive to Craterβ€”if it also protects user machines from the same vulnerabilitiesβ€”that would be ideal. People like Walter on the Foundation side are actively working on that. I'm sure there are conversations in the Cargo and crates teams as well, because every team that deals with packages sees a different angle of the problem. We all have to come together to solve it, and there is a lot of interesting work happening in that area. **Xander Cesari** : I hope help is coming. **Jan David Nose** : I'm optimistic. **Xander Cesari** : We have this exponential curve with traffic and everything else. It seems like at some point it has to taper off. **Jan David Nose** : We'll see. Rust is a young language. I don't know when that growth will slow down. I think there's a good argument that it will continue for quite a while as adoption grows. **Jan David Nose** : Being at a conference like RustConf, it's exciting to see how the mix of companies has changed over time. We had a talk from Rivian on how they use Rust in their cars. We've heard from other car manufacturers exploring it. Rust is getting into more and more applications that a few years ago would have been hard to imagine or where the language simply wasn't mature enough yet. **Jan David Nose** : As that continues, I think we'll see new waves of growth that sustain the exponential curve we currently have, because we're moving into domains that are new for us. It's amazing to see who is talking about Rust and how they're using it, sometimes in areas like space that you wouldn't expect. **Jan David Nose** : I'm very optimistic about Rust's future. With this increase in adoption, we'll see a lot of interesting lessons about how to use Rust and a lot of creative ideas from people building with it. With more corporate adoption, I also expect a new wave of investment into the ecosystem: companies paying people to work full-time on different parts of Rust, both in the ecosystem and in the core project. I'm very curious what the next ten years will look like, because I genuinely don't know. **Xander Cesari** : The state of Rust right now does feel a bit like the dog that caught the car and now doesn't know what to do with it. **Jan David Nose** : Yeah, I think that's a good analogy. Suddenly we're in a situation where we realize we haven't fully thought through every consequence of success. It's fascinating to see how the challenges change every year. We keep running into new growing pains where something that wasn't an issue a year ago suddenly becomes one because growth keeps going up. **Jan David Nose** : We're constantly rebuilding parts of our infrastructure to keep up with that growth, and I don't see that stopping soon. As a user, that makes me very excited. With the language and the ecosystem growing at this pace, there are going to be very interesting things coming that I can't predict today. **Jan David Nose** : For the project, it also means there are real challenges: financing the infrastructure we need, finding maintainers and contributors, and creating a healthy environment where people can work without burning out. There is a lot of work to be done, but it's an exciting place to be. **Xander Cesari** : Well, thank you for all your work keeping those magic Cargo commands I can type into my terminal just working in the background. If there's any call to action from this interview, it's that if you're a company using Rust, maybe think about donating to keep the Infra Team working. **Jan David Nose** : We always love new Rust Foundation members. Especially if you're a company, that's one of the best ways to support the work we do. Membership gives us a budget we can use either to fund people who work full-time on the project or to fill gaps in our infrastructure sponsorship where we don't get services for free and have to pay real money. **Jan David Nose** : And if you're not a company, we're always looking for people to help out. The Infra Team has a lot of Rust-based bots and other areas where people can contribute relatively easily. **Xander Cesari** : Small scoped bots that you can wrap your head around and help out with. **Jan David Nose** : Exactly. It is a bit harder on the Infra side because we can't give people access to our cloud infrastructure. There are areas where it's simply not possible to contribute as a volunteer because you can't have access to the production systems. But there is still plenty of other work that can be done. **Jan David Nose** : Like every other team in the project, we're a bit short-staffed. So when you're at conferences, come talk to me or Marco. We have work to do. **Xander Cesari** : Well, thank you for doing the work that keeps Rust running. **Jan David Nose** : I'm happy to. **Xander Cesari** : Awesome. Thank you so much.
25.11.2025 00:00 πŸ‘ 0 πŸ” 0 πŸ’¬ 0 πŸ“Œ 0
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 the Itanium 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-demangle repository 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 via `RUSTFLAGS` or `.cargo/config.toml`: [build] rustflags = ["-Csymbol-mangling-version=v0"]
20.11.2025 00:00 πŸ‘ 2 πŸ” 1 πŸ’¬ 0 πŸ“Œ 0
Project goals update β€” October 2025 The Rust project is currently working towards a slate of 41 project goals, with 13 of them designated as Flagship Goals. This post provides selected updates on our progress towards these goals (or, in some cases, lack thereof). The full details for any particular goal are available in its associated tracking issue on the rust-project-goals repository. ## Flagship goals ### "Beyond the `&`" Continue Experimentation with Pin Ergonomics (rust-lang/rust-project-goals#389) Progress | ---|--- Point of contact | Frank King Champions | compiler (Oliver Scherer), lang (TC) Task owners | Frank King 1 detailed update available. Comment by @frank-king posted on 2025-10-22: Status update: Regarding the TODO list in the next 6 months, here is the current status: ## Introduce `&pin mut|const place` borrowing syntax * x] parsing: [#135731, merged. * [ ] lowering and borrowck: not started yet. I've got some primitive ideas about borrowck, and I probably need to confirm with someone who is familiar with MIR/borrowck before starting to implement. A pinned borrow consists two MIR statements: 1. a borrow statement that creates the mutable reference, 2. and an adt aggregate statement that put the mutable reference into the `Pin` struct. I may have to add a new borrow kind so that pinned borrows can be recognized. Then traverse the dataflow graph to make sure that pinned places cannot been moved. ## Pattern matching of `&pin mut|const T` types In the past few months, I have struggled with the `!Unpin` stuffs (the original design sketch _Alternative A_), trying implementing it, refactoring, discussing on zulips, and was constantly confused; luckily, we have finally reached a new agreement of the _Alternative B_ version. * ] [#139751 under review (reimplemented regarding _Alternative B_). ## Support `drop(&pin mut self)` for structurally pinned types * ] adding a new `Drop::pin_drop(&pin mut self)` method: draft PR [#144537 Supporting both `Drop::drop(&mut self)` and `Drop::drop(&pin mut self)` seems to introduce method-overloading to Rust, which I think might need some more general ways to handle (maybe by a rustc attribute?). So instead, I'd like to implemenent this via a new method `Drop::pin_drop(&pin mut self)` first. ## Introduce `&pin pat` pattern syntax Not started yet (I'd prefer doing that when pattern matching of `&pin mut|const T` types is ready). ## Support `&pin mut|const T` -> `&|&mut T` coercion (requires `T: Unpin` of `&pin mut T` -> `&mut T`) Not started yet. (It's quite independent, probably someone else can help with it) ## Support auto borrowing of `&pin mut|const` place in method calls with `&pin mut|const self` receivers Seems to be handled by Autoreborrow traits? Design a language feature to solve Field Projections (rust-lang/rust-project-goals#390) Progress | ---|--- Point of contact | Benno Lossin Champions | lang (Tyler Mandry) Task owners | Benno Lossin **TL;DR.** There have been lots of internal developments since the last update: * field representing types and chained projections have received a fundamental overhaul: disallowing field paths and requiring projections to decompose. Additionally we explored how const generics could emulate FRTs. * we discussed a potential solution to having only a single project operator & trait through a decay operation with special borrow checker treatment. * we were able to further simplify the project trait moving the generic argument of the represented field to the project function. We also discovered the possibility that FRTs are not fundamentally necessary for field projections -- however, they are still very useful in other applications and my gut feeling is that they are also right for field projections. So we will continue our experiment with them. * we talked about making `Project::project` be a safe function by introducing a new kind of type. **Next Steps** : * we're still planning to merge https://github.com/rust-lang/rust/pull/146307, after I have updated it with the new FRT logic and it has been reviewed * once that PR lands, I plan to update the library experiment to use the experimental FRTs * then the testing using that library can begin in the Linux kernel and other projects (this is where anyone interested in trying field projections can help out!) 4 detailed updates available. Comment by @BennoLossin posted on 2025-10-23: ### Decomposing Projections A chained projection operation should naturally decompose, so `foo.[Ber Clausen][].[Baz Shkara][]` should be the same as writing `(foo.[Ber Clausen][]).[Baz Shkara][]`. Until now, the different parenthesizing would have allowed different outcomes. This behavior is confusing and also makes many implementation details more complicated than they need to be. ### Field Representing Types Since projections now decompose, we have no need from a design perspective for multi-level FRTs. So `field_of!(Foo, bar.baz)` is no longer required to work. Thus we have decided to restrict FRTs to only a single field and get rid of the path. This simplifies the implementation in the compiler and also avoids certain difficult questions such as the locality of FRTs (if we had a path, we would have to walk the path and it is local, if all structs included in the path are local). Now with only a single field, the FRT is local if the struct is. We also discovered that it is a good idea to make FRTs inhabited (they still are ZSTs), since then it allows the following pattern to work: fn project_free_standing<F: Field>(_: Field, r: &F::Base) -> &F::Type { ... } // can now call the function without turbofish: let my_field = project_free_standing(field_of!(MyStruct, my_field), &my_struct); #### FRTs via `const` Generics We also spent some time thinking about const generics and FRTs on zulip: * https://rust-lang.zulipchat.com/#narrow/channel/144729-t-types/topic/const.20generics.3A.20implementing.20field.20representing.20types/with/544617587 * https://rust-lang.zulipchat.com/#narrow/channel/144729-t-types/topic/field.20representing.20values.20.26.20.60Field.3Cconst.20F.3A.20.3F.3F.3F.3E.60.20trait/with/542855620 In short, this won't be happening any time soon. However, it could be a future implementation of the `field_of!` macro depending on how reflection through const generics evolves (but also only in the far-ish future). Comment by @BennoLossin posted on 2025-10-23: ### Single Project Operator & Trait via **Exclusive Decay** It would be great if we only had to add a single operator and trait and could obtain the same features as we have with two. The current reason for having two operators is to allow both shared and exclusive projections. If we could have another operation that _decays_ an exclusive reference (or custom, exclusive smart-pointer type) into a shared reference (or the custom, shared version of the smart pointer). This decay operation would need borrow checker support in order to have simultaneous projections of one field exclusively and another field shared (and possibly multiple times). This goes into a similar direction as the reborrowing project goal https://github.com/rust-lang/rust-project-goals/issues/399, however, it needs extra borrow checker support. fn add(x: cell::RefMut<'_, i32>, step: i32) { *x = *x + step; } struct Point { x: i32, y: i32, } fn example(p: cell::RefMut<'_, Point>) { let y: cell::Ref<'_, i32> = coerce_shared!(p.[@y][]); let y2 = coerce_shared!(p.[@y][]); // can project twice if both are coerced add(p.[Devon Peticolas][], *y); add(p.[Devon Peticolas][], *y2); assert_eq!(*y, *y2); // can still use them afterwards } Problems: * explicit syntax is annoying for these "coercions", but * we cannot make this implicit: * if this were an implicit operation, only the borrow checker would know when one had to coerce, * this operation is allowed to change the type, * this results in borrow check backfeeding into typecheck, which is not possible or at least extremely difficult ### Syntax Not much movement here, it depends on the question discussed in the previous section, since if we only have one operator, we could choose `.@`, `->` or `~`; if we have to have two, then we need additional syntax to differentiate them. Comment by @BennoLossin posted on 2025-10-23: ### Simplifying the `Project` trait There have been some developments in pin ergonomics https://github.com/rust-lang/rust/issues/130494: "alternative B" is now the main approach which means that `Pin<&mut T>` has _linear_ projections, which means that it doesn't change its output type depending on the concrete field (really depending on the **field** , not only its type). So it falls into the general projection pattern `Pin<&mut Struct>` -> `Pin<&mut Field>` which means that `Pin` doesn't need any `where` clauses when implementing `Project`. Additionally we have found out that RCU also doesn't need `where` clauses, as we can also make its projections linear by introducing a `MutexRef<'_, T>` smart pointer that always allows projections and only has special behavior for `T = Rcu<U>`. Discussed on zulip after this message. For this reason we can get rid of the generic argument to `Project` and mandate that all types that support projections support them for _all_ fields. So the new `Project` trait looks like this: // still need a common super trait for `Project` & `ProjectMut` pub trait Projectable { type Target: ?Sized; } pub unsafe trait Project: Projectable { type Output<F: Field<Base = Self::Target>>; unsafe fn project<F: Field<Base = Self::Target>>( this: *const Self, ) -> Self::Output<F>; } #### Are FRTs even necessary? With this change we can also think about getting rid of FRTs entirely. For example we could have the following `Project` trait: pub unsafe trait Project: Projectable { type Output<F>; unsafe fn project<const OFFSET: usize, F>( this: *const Self, ) -> Self::Output<F>; } There are other applications for FRTs that are very useful for Rust-for-Linux. For example, storing field information for intrusive data structures directly in that structure as a generic. More concretely, in the kernel there are workqueues that allow you to run code in parallel to the currently running thread. In order to insert an item into a workqueue, an intrusive linked list is used. However, we need to be able to insert the same item into multiple lists. This is done by storing multiple instances of the `Work` struct. Its definition is: pub struct Work<T, const ID: u64> { ... } Where the `ID` generic must be unique inside of the struct. struct MyDriver { data: Arc<MyData>, main_work: Work<Self, 0>, aux_work: Work<Self, 1>, // more fields ... } // Then you call a macro to implement the unsafe `HasWork` trait safely. // It asserts that there is a field of type `Work<MyDriver, 0>` at the given field // (and also exposes its offset). impl_has_work!(impl HasWork<MyDriver, 0> for MyDriver { self.main_work }); impl_has_work!(impl HasWork<MyDriver, 1> for MyDriver { self.aux_work }); // Then you implement `WorkItem` twice: impl WorkItem<0> for MyDriver { type Pointer = Arc<Self>; fn run(this: Self::Pointer) { println!("doing the main work here"); } } impl WorkItem<1> for MyDriver { type Pointer = Arc<Self>; fn run(this: Self::Pointer) { println!("doing the aux work here"); } } // And finally you can call `enqueue` on a `Queue`: let my_driver = Arc::new(MyDriver::new()); let queue: &'static Queue = kernel::workqueue::system_highpri(); queue.enqueue::<_, 0>(my_driver.clone()).expect("my_driver is not yet enqueued for id 0"); // there are different queues let queue = kernel::workqueue::system_long(); queue.enqueue::<_, 1>(my_driver.clone()).expect("my_driver is not yet enqueued for id 1"); // cannot insert multiple times: assert!(queue.enqueue::<_, 1>(my_driver.clone()).is_err()); FRTs could be used instead of this id, making the definition be `Work<F: Field>` (also merging the `T` parameter). struct MyDriver { data: Arc<MyData>, main_work: Work<field_of!(Self, main_work)>, aux_work: Work<field_of!(Self, aux_work)>, // more fields ... } impl WorkItem<field_of!(MyDriver, main_work)> for MyDriver { type Pointer = Arc<Self>; fn run(this: Self::Pointer) { println!("doing the main work here"); } } impl WorkItem<field_of!(MyDriver, aux_work)> for MyDriver { type Pointer = Arc<Self>; fn run(this: Self::Pointer) { println!("doing the aux work here"); } } let my_driver = Arc::new(MyDriver::new()); let queue: &'static Queue = kernel::workqueue::system_highpri(); queue .enqueue(my_driver.clone(), field_of!(MyDriver, main_work)) // ^ using Gary's idea to avoid turbofish .expect("my_driver is not yet enqueued for main_work"); let queue = kernel::workqueue::system_long(); queue .enqueue(my_driver.clone(), field_of!(MyDriver, aux_work)) .expect("my_driver is not yet enqueued for aux_work"); assert!(queue.enqueue(my_driver.clone(), field_of!(MyDriver, aux_work)).is_err()); This makes it overall a lot more readable (by providing sensible names instead of magic numbers), and maintainable (we can add a new variant without worrying about which IDs are unused). It also avoids the `unsafe` `HasWork` trait and the need to write the `impl_has_work!` macro for each `Work` field. I still think that having FRTs is going to be the right call for field projections as well, so I'm going to keep their experiment going. However, we should fully explore their necessity and rationale for a future RFC. Comment by @BennoLossin posted on 2025-10-23: ### Making `Project::project` safe In the current proposal the `Project::project` function is `unsafe`, because it takes a raw pointer as an argument. This is pretty unusual for an operator trait (it would be the first). Tyler Mandry thought about a way of making it safe by introducing "partial struct types". This new type is spelled `Struct.F` where `F` is an FRT of that struct. It's like `Struct`, but with the restriction that only the field represented by `F` can be accessed. So for example `&Struct.F` would point to `Struct`, but only allow one to read that single field. This way we could design the `Project` trait in a safe manner: // governs conversion of `Self` to `Narrowed<F>` & replaces Projectable pub unsafe trait NarrowPointee { type Target; type Narrowed<F: Field<Base = Self::Target>>; } pub trait Project: NarrowPointee { type Output<F: Field<Base = Self::Type>>; fn project(narrowed: Self::Narrowed<F>) -> Self::Output<F>; } The `NarrowPointee` trait allows a type to declare that it supports conversions of its `Target` type to `Target.F`. For example, we would implement it for `RefMut` like this: unsafe impl<'a, T> NarrowPointee for RefMut<'a, T> { type Target = T; type Narrowed<F: Field<Base = T>> = RefMut<'a, T.F>; } Then we can make the narrowing a builtin operation in the compiler that gets prepended on the actual coercion operation. However, this "partial struct type" has a fatal flaw that Oliver Scherer found (edit by oli: it was actually boxy who found it): it conflicts with `mem::swap`, if `Struct.F` has the same layout as `Struct`, then writing to such a variable will overwrite all bytes, thus also overwriting field that aren't `F`. Even if we make an exception for these types and moves/copies, this wouldn't work, as a user today can rely on the fact that they write `size_of::<T>()` bytes to a `*mut T` and thus have a valid value of that type at that location. Tyler Mandry suggested we make it `!Sized` and even `!MetaSized` to prevent overwriting values of that type (maybe the `Overwrite` trait could come in handy here as well). But this might make "partial struct types" too weak to be truly useful. Additionally this poses many more questions that we haven't yet tackled. Reborrow traits (rust-lang/rust-project-goals#399) Progress | ---|--- Point of contact | Aapo Alasuutari Champions | compiler (Oliver Scherer), lang (Tyler Mandry) Task owners | Aapo Alasuutari 1 detailed update available. Comment by @aapoalas posted on 2025-10-22: Initial implementation of a Reborrow trait for types with only lifetimes with exclusive reference semantics is working but not yet upstreamed not in review. CoerceShared implementation is not yet started. Proper composable implementation will likely require a different tactic than the current one. Safety and validity checks are currently absent as well and will require more work. ### "Flexible, fast(er) compilation" build-std (rust-lang/rust-project-goals#274) Progress | ---|--- Point of contact | David Wood Champions | cargo (Eric Huss), compiler (David Wood), libs (Amanieu d'Antras) Task owners | Adam Gemmell, David Wood 1 detailed update available. Comment by @davidtwco posted on 2025-10-31: We've now opened our first batch of RFCs: rust-lang/rfcs#3873, rust-lang/rfcs#3874 and rust-lang/rfcs#3875 Production-ready cranelift backend (rust-lang/rust-project-goals#397) Progress | ---|--- Point of contact | Folkert de Vries Champions | compiler (bjorn3) Task owners | bjorn3, Folkert de Vries, [Trifecta Tech Foundation] No detailed updates available. Promoting Parallel Front End (rust-lang/rust-project-goals#121) Progress | ---|--- Point of contact | Sparrow Li Task owners | Sparrow Li No detailed updates available. Relink don't Rebuild (rust-lang/rust-project-goals#400) Progress | ---|--- Point of contact | Jane Lusby Champions | cargo (Weihang Lo), compiler (Oliver Scherer) Task owners | Ally Sommers, Piotr Osiewicz No detailed updates available. ### "Higher-level Rust" Ergonomic ref-counting: RFC decision and preview (rust-lang/rust-project-goals#107) Progress | ---|--- Point of contact | Niko Matsakis Champions | compiler (Santiago Pastorino), lang (Niko Matsakis) Task owners | Niko Matsakis, Santiago Pastorino 3 detailed updates available. Comment by @nikomatsakis posted on 2025-10-07: I posted this blog post that proposes that we ought to name the trait `Handle` and define it as a trait where clone produces an "entangled" value -- i.e., a second handle to the same underlying value. Before that, there's been a LOT of conversation that hasn't made its way onto this tracking issue. Trying to fix that! Here is a brief summary, in any case: * It began with the first Rust Project Goals program in 2024H2, where Jonathan Kelley from Dioxus wrote a thoughtful blog post about a path to high-level Rust that eventually became a 2024H2 project goal towards ergonomic ref-counting. * I wrote a series of blog posts about a trait I called `Claim`. * Josh Triplett and I talked and Josh Triplett opened RFC #3680], which proposed a `use` keyword and `use ||` closures. Reception, I would say, was mixed; yes, this is tackling a real problem, but there were lots of concerns on the approach. [I summarized the key points here. * Santiago Pastorino implemented experimental support for (a variant of) RFC #3680] as part of the [2025H1 project goal. * I authored a 2025H2 project goal proposing that we create an alternative RFC focused on higher-level use-cases which prompted Josh Triplett and I have to have a long and fruitful conversation in which he convinced me that this was not the right approach. * We had a lang-team design meeting on 2025-08-27 in which I presented this survey and summary of the work done thus far. * And then at the RustConf 2025 Unconf we had a big group discussion on the topic that I found very fruitful, as well as various follow-up conversations with smaller groups. The name `Handle` arose from this and I plan to be posting further thoughts as a result. RFC #3680: https://github.com/rust-lang/rfcs/pull/3680 Comment by @nikomatsakis posted on 2025-10-09: I wrote up a brief summary of my current thoughts on Zulip; I plan to move this content into a series of blog posts, but I figured it was worth laying it out here too for those watching this space: > 09:11 (1) I don't think clones/handles are categorically different when it comes to how much you want to see them made explicit; some applications want them both to be explicit, some want them automatic, some will want a mix -- and possibly other kinds of categorizations. > > 09:11 (2) But I do think that if you are making everything explicit, it's useful to see the difference between a general purpose clone and a handle. > > 09:12 (3) I also think there are many classes of software where there is value in having everything explicit -- and that those classes are often the ones most in Rust's "sweet spot". So we should make sure that it's possible to have everything be explicit ergonomically. > > 09:12 (4) This does not imply that we can't make automatic clones/handles possible too -- it is just that we should treat both use cases (explicit and automatic) as first-class in importance. > > 09:13 (5) Right now I'm focused on the explicit case. I think this is what the use-use-everywhere was about, though I prefer a different proposal now -- basically just making handle and clone methods understood and specially handled by the compiler for optimization and desugaring purposes. There are pros and cons to that, obviously, and that's what I plan to write-up in more detail. > > 09:14 (6) On a related note, I think we also need explicit closure captures, which is a whole interesting design space. I don't personally find it "sufficient" for the "fully explicit" case but I could understand why others might think it is, and it's probably a good step to take. > > 09:15 (7) I go back and forth on profiles -- basically a fancy name for lint-groups based on application domain -- and whether I think we should go that direction, but I think that if we were going to go automatic, that's the way I would do it: i.e., the compiler will automatically insert calls to clone and handle, but it will lint when it does so; the lint can by deny-by-default at first but applications could opt into allow for either or both. > > I previously wanted allow-by-default but I've decided this is a silly hill to die on, and it's probably better to move in smaller increments. Comment by @nikomatsakis posted on 2025-10-22: Update: There has been more discussion about the Handle trait on Zulip and elsewhere. Some of the notable comments: * Downsides of the current name: it's a noun, which doesn't follow Rust naming convention, and the verb `handle` is very generic and could mean many things. * Alternative names proposed: `Entangle/entangle` or `entangled`, `Share`/`share`, `Alias/alias`, or `Retain/retain`. if we want to seriously hardcore on the science names -- `Mitose/mitose` or `Fission/fission`. * There has been some criticism pointing out that focusing on handles means that other types which _might_ be "cheaply cloneable" don't qualify. For now I will go on using the term Handle, but I agree with the critique that it should be a verb, and currently prefer Alias/alias as an alternative. * * * I'm continuing to work my way through the backlog of blog posts about the conversations from Rustconf. The purposes of these blog posts is not just to socialize the ideas more broadly but also to help myself think through them. Here is the latest post: https://smallcultfollowing.com/babysteps/blog/2025/10/13/ergonomic-explicit-handles/ The point of this post is to argue that, whatever else we do, Rust should have a way to create handles/clones (and closures that work with them) which is at once explicit _and_ ergonomic. To give a preview of my current thinking, I am working now on the next post which will discuss how we should add an explicit capture clause syntax. This is somewhat orthogonal but not really, in that an explicit syntax would make closures that clone more ergonomic (but only mildly). I don't have a proposal I fully like for this syntax though and there are a lot of interesting questions to work out. As a strawperson, though, you might imagine this older proposal I wrote up](https://hackmd.io/[Niko Matsakis/SyI0eMFXO?type=view), which would mean something like this: let actor1 = async move(reply_tx.handle()) { reply_tx.send(...); }; let actor2 = async move(reply_tx.handle()) { reply_tx.send(...); }; This is an improvement on let actor1 = { let reply_tx = reply_tx.handle(); async move(reply_tx.handle()) { reply_tx.send(...); } }; but only mildly. The next post I intend to write would be a variant on "use, use everywhere" that recommends _method call syntax_ and permitting the compiler to elide handle/clone calls, so that the example becomes let actor1 = async move { reply_tx.handle().send(...); // -------- due to optimizations, this would capture the handle creation to happen only when future is *created* }; This would mean that cloning of strings and things might benefit from the same behavior: let actor1 = async move { reply_tx.handle().send(some_id.clone()); // -------- the `some_id.clone()` would occur at future creation time }; The rationable that got me here is (a) minimizing perceived complexity and focusing on muscle memory (just add `.clone()` or `.handle()` to fix use-after-move errors, no matter when/where they occur). The cost of course is that (a) Handle/Clone become very special; and (b) it blurs the lines on when code execution occurs. Despite the `.handle()` occurring inside the future (resp. closure) body, it actually executes when the future (resp. closure) is created in this case (in other cases, such as a closure that implements `Fn` or `FnMut` and hence executes more than once, it might occur during each execution as well). Stabilize cargo-script (rust-lang/rust-project-goals#119) Progress | ---|--- Point of contact | Ed Page Champions | cargo (Ed Page), lang (Josh Triplett), lang-docs (Josh Triplett) Task owners | Ed Page No detailed updates available. ### "Unblocking dormant traits" Evolving trait hierarchies (rust-lang/rust-project-goals#393) Progress | ---|--- Point of contact | Taylor Cramer Champions | lang (Taylor Cramer), types (Oliver Scherer) Task owners | Taylor Cramer, Taylor Cramer & others No detailed updates available. In-place initialization (rust-lang/rust-project-goals#395) Progress | ---|--- Point of contact | Alice Ryhl Champions | lang (Taylor Cramer) Task owners | Benno Lossin, Alice Ryhl, Michael Goulet, Taylor Cramer, Josh Triplett, Gary Guo, Yoshua Wuyts 1 detailed update available. Comment by @Darksonn posted on 2025-10-22: This is our first update we’re posting for the in-place init work. Overall things are progressing well, with lively discussion happening on the newly minted `t-lang/in-place-init` Zulip channel. Here are the highlights since the lang team design meeting at the end of July: * **Zulip** : we now have a dedicated zulip channel that includes all topics surrounding in-place initialization: #t-lang/in-place-init. * **Guaranteed value emplacement** : Olivier FAURE shared a new version of C++ inspired emplacement in #t-lang/in-place-init > RFC Draft: Guaranteed Value Emplacement inspired by C++’s emplacement system. * **Rosetta code sample** : to help guide the comparison of the various proposals, we’ve started collecting examples to compare against each other. The first one was contributed by Alice Ryhl and is: _β€œHow can we construct a`Box<Mutex<MyType>>` in-place inside the `Box`”_. For more see #t-lang/in-place-init > Shared example: emplacing into `Box. * **Evolution of the outptr proposal** : Taylor Cramer’s original outptr-based emplacement proposal used concrete types as part of her proposal. Since then there has been significant discussion about alternative ways to represent out-pointers, including: #t-lang/in-place-init > out-pointer type and MIR semantics consideration. * **Placing functions as a high-level notation** : Yoshua Wuyts has begun reworking the β€œplacing functions” proposal as a high-level sugar on top of one of the other proposals, instead of directly desugaring to `MaybeUninit`. For more see: #t-lang/in-place-init > Placing functions as sugar for low-level emplacement. * **Generic fallibility for the`Init` proposal**: following feedback from the lang team meeting, Alice Ryhl posted an update showing how the `Init` trait could be made generic over _all_ `Try` types instead of being limited to just `Result`. For more see: #t-lang/in-place-init > Making `impl Init` generic over `Result`/`Option`/infallible. * **Interactions between emplacement and effects** : Yoshua Wuyts has begun documenting the expected interactions between placing functions and other function-transforming effects (e.g. `async`, `try`, `gen`). For more see: #t-lang/in-place-init > placing functions and interactions with effects. Next-generation trait solver (rust-lang/rust-project-goals#113) Progress | ---|--- Point of contact | lcnr Champions | types (lcnr) Task owners | Boxy, Michael Goulet, lcnr 1 detailed update available. Comment by @lcnr posted on 2025-10-23: Since the last update we've fixed the hang in rayon in https://github.com/rust-lang/rust/pull/144991 and https://github.com/rust-lang/rust/pull/144732 which relied on https://github.com/rust-lang/rust/pull/143054 https://github.com/rust-lang/rust/pull/144955 https://github.com/rust-lang/rust/pull/144405 https://github.com/rust-lang/rust/pull/145706. This introduced some search graph bugs which we fixed in https://github.com/rust-lang/rust/pull/147061 https://github.com/rust-lang/rust/pull/147266. We're mostly done with the opaque type support now. Doing so required a lot of quite involved changes: * https://github.com/rust-lang/rust/pull/145244 non-defining uses in borrowck * https://github.com/rust-lang/rust/pull/145925 non-defining uses in borrowck closure support * https://github.com/rust-lang/rust/pull/145711 non-defining uses in hir typeck * https://github.com/rust-lang/rust/pull/140375 eagerly compute sub_unification_table again * https://github.com/rust-lang/rust/pull/146329 item bounds * https://github.com/rust-lang/rust/pull/145993 function calls * https://github.com/rust-lang/rust/pull/146885 method selection * https://github.com/rust-lang/rust/pull/147249 fallback We also fixed some additional self-contained issues and perf improvements: https://github.com/rust-lang/rust/pull/146725 https://github.com/rust-lang/rust/pull/147138 https://github.com/rust-lang/rust/pull/147152 https://github.com/rust-lang/rust/pull/145713 https://github.com/rust-lang/rust/pull/145951 We have also migrated rust-analyzer to entirely use the new solver instead of `chalk`. This required a large effort mainly by Jack Huey Chayim Refael Friedman and Shoyu Vanilla. That's some really impressive work on their end πŸŽ‰ See this list of merged PRs for an overview of what this required on the r-a side. Chayim Refael Friedman also landed some changes to the trait solver itself to simplify the integration: https://github.com/rust-lang/rust/pull/145377 https://github.com/rust-lang/rust/pull/146111 https://github.com/rust-lang/rust/pull/147723 https://github.com/rust-lang/rust/pull/146182. We're still tracking the remaining issues in https://github.com/orgs/rust-lang/projects/61/views/1. Most of these issues are comparatively simple and I expect us to fix most of them over the next few months, getting us close to stabilization. We're currently doing another crater triage which may surface a few more issues. Stabilizable Polonius support on nightly (rust-lang/rust-project-goals#118) Progress | ---|--- Point of contact | RΓ©my Rakic Champions | types (Jack Huey) Task owners | Amanda Stjerna, RΓ©my Rakic, Niko Matsakis 1 detailed update available. Comment by @lqd posted on 2025-10-22: Here's another summary of the most interesting developments since the last update: * reviews and updates have been done on the polonius alpha, and it has since landed * the last 2 trivial diagnostics failures were fixed * we've done perf runs, crater runs, completed gathering stats on crates.io for avg and outliers in CFG sizes, locals, loan and region counts, dataflow framework behavior on unexpected graph shapes and bitset invalidations * I worked on dataflow for borrowck: single pass analyses on acyclic CFGs, dataflow analyses on SCCs for cyclic CFGs * some more pieces of amanda's SCC rework have landed, with lcnr's help * lcnr's opaque type rework, borrowcking of nested items, and so on, also fixed some issues we mentioned in previous updates with member constraints for computing when loans are going out of scope * we also studied recent papers in flow-sensitive pointer analysis * I also started the loans-in-scope algorithm rework, and also have reachability acceleration with the CFG SCCs * the last 2 actual failures in the UI tests are soundness issues, related to liveness of captured regions for opaque types: some regions that should be live are not, which were done to help with precise capture and limit the impact of capturing unused regions that cannot be actually used in the hidden type. The unsoundness should not be observable with NLLs, but polonius alpha relies on liveness to propagate loans throughout the CFG: these dead regions prevent detecting some error-causing loan invalidations. The easiest fix would cause breakage in code that's now accepted. niko, jack and I have another possible solution and I'm trying to implement it now ## Goals looking for help ## Other goal updates Add a team charter for rustdoc team (rust-lang/rust-project-goals#387) Progress | ---|--- Point of contact | Guillaume Gomez Champions | rustdoc (Guillaume Gomez) No detailed updates available. Borrow checking in a-mir-formality (rust-lang/rust-project-goals#122) Progress | ---|--- Point of contact | Niko Matsakis Champions | types (Niko Matsakis) Task owners | Niko Matsakis, tiif No detailed updates available. C++/Rust Interop Problem Space Mapping (rust-lang/rust-project-goals#388) Progress | ---|--- Point of contact | Jon Bauman Champions | compiler (Oliver Scherer), lang (Tyler Mandry), libs (David Tolnay) Task owners | Jon Bauman No detailed updates available. Comprehensive niche checks for Rust (rust-lang/rust-project-goals#262) Progress | ---|--- Point of contact | Bastian Kersting Champions | compiler (Ben Kimock), opsem (Ben Kimock) Task owners | Bastian Kersting], Jakob Koschel No detailed updates available. Const Generics (rust-lang/rust-project-goals#100) Progress | ---|--- Point of contact | Boxy Champions | lang (Niko Matsakis) Task owners | Boxy, Noah Lev 1 detailed update available. Comment by @nikomatsakis posted on 2025-10-22: We had a design meeting on 2025-09-10, minutes available here, aiming at these questions: > There are a few concrete things I would like to get out of this meeting, listed sequentially in order of most to least important: > > 1. Would you be comfortable stabilizing the initial ADTs-only extensions? > * This would be properly RFC'd before stabilization, this ask is just a "vibe check". > 2. Are you interested in seeing Per-Value Rejection for enums with undesirable variants? > 3. How do you feel about the idea of Lossy Conversion as an approach in general, what about specifically for the References and Raw Pointers extensions? > 4. How do you feel about the idea of dropping the One Equality ideal in general, what about specifically for `-0.0` vs `+0.0`, what about specifically for `NaN` values? > The vibe checks on the first one were as follows: > ## Vibe check > > The main ask: > >> Would you be comfortable stabilizing the initial ADTs-only extensions? > > (plus the other ones) > > ### nikomatsakis > > I am +1 on working incrementally and focusing first on ADTs. I am supportive of stabilization overall but I don't feel like we've "nailed" the way to talk or think about these things. So I guess my "vibe" is +1 but if this doc were turned into an RFC kind of "as is" I would probably wind up -1 on the RFC, I think more work is needed (in some sense, the question is, "what is the name of the opt-in trait and why is it named that"). This space is complex and I think we have to do better at helping people understand the fine-grained distinctions between runtime values, const-eval values, and type-safe values. > > Niko: if we add some sort of derive of a trait name, how much value are we getting from the derive, what should the trait be named? > > ### tmandry > > I think we'll learn the most by stabilizing ADTs in a forward compatible way (including an opt-in) now. So +1 from me on the proposed design. > > It's worth noting that this is a feature that interacts with many other features, and we will be considering extensions to the MVP for the foreseeable future. To some extent the lang team has committed to this already but we should know what we're signing ourselves up for. > > ### scottmcm > > scottmcm: concern over the private fields restriction (see question below), but otherwise for the top ask, yes happy to just do "simple" types (no floats, no cells, no references, etc). > > ### TC > > As Niko said, +1 on working incrementally, and I too am supportive overall. > > As a vibe, per-value rejection seems fairly OK to me in that we decided to do value-based reasoning for other const checks. It occurs to me there's some parallel with that. > > https://github.com/rust-lang/rust/pull/119044 > > As for the opt-in on types, I see the logic. I do have reservations about adding too many opt-ins to the language, and so I'm curious about whether this can be safely removed. > > Regarding floats, I see the question on these as related to our decision about how to handle padding in structs. If it makes sense to normalize or otherwise treat `-0.0` and `+0.0` as the same, then it'd also make sense in my view to normalize or otherwise treat two structs with the same values but different padding (or where only one has initialized padding) as the same. Continue resolving `cargo-semver-checks` blockers for merging into cargo (rust-lang/rust-project-goals#104) Progress | ---|--- Point of contact | Predrag Gruevski Champions | cargo (Ed Page), rustdoc (Alona Enraght-Moony) Task owners | Predrag Gruevski No detailed updates available. Develop the capabilities to keep the FLS up to date (rust-lang/rust-project-goals#391) Progress | ---|--- Point of contact | Pete LeVasseur Champions | bootstrap (Jakub BerΓ‘nek), lang (Niko Matsakis), spec (Pete LeVasseur) Task owners | Pete LeVasseur, Contributors from Ferrous Systems and others TBD, `t-spec` and contributors from Ferrous Systems 2 detailed updates available. Comment by @nikomatsakis posted on 2025-10-22: After much discussion, we have decided to charter this team as a t-spec subteam. Pete LeVasseur and I are working to make that happen now. Comment by @nikomatsakis posted on 2025-10-22: PR with charters: https://github.com/rust-lang/team/pull/2028 Emit Retags in Codegen (rust-lang/rust-project-goals#392) Progress | ---|--- Point of contact | Ian McCormack Champions | compiler (Ralf Jung), opsem (Ralf Jung) Task owners | Ian McCormack 1 detailed update available. Comment by @icmccorm posted on 2025-10-25: Here's our first status update! * We've been experimenting with a few different ways of emitting retags in codegen, as well as a few different forms that retags should take at this level. We think we've settled on a set of changes that's worth sending out to the community for feedback, likely as a pre-RFC. You can expect more engagement from us on this level in the next couple of weeks. * We've used these changes to create an initial working prototype for BorrowSanitizer that supports finding Tree Borrows violations in tiny, single-threaded Rust programs. We're working on getting Miri's test suite ported over to confirm that everything is working correctly and that we've quashed any false positives or false negatives. * This coming Monday, I'll be presenting on BorrowSanitizer and this project goal at the Workshop on Supporting Memory Safety in LLVM. Please reach out if you're attending and would like to chat more in person! Expand the Rust Reference to specify more aspects of the Rust language (rust-lang/rust-project-goals#394) Progress | ---|--- Point of contact | Josh Triplett Champions | lang-docs (Josh Triplett), spec (Josh Triplett) Task owners | Amanieu d'Antras, Guillaume Gomez, Jack Huey, Josh Triplett, lcnr, Mara Bos, Vadim Petrochenkov, Jane Lusby 1 detailed update available. Comment by @joshtriplett posted on 2025-10-22: The work on this goal has led to many ongoing discussions on the current status of the Reference. Those discussions are still in progress. Meanwhile, many people working on this goal have successfully written outlines or draft chapters, at various stages of completeness. There's a broken-out status report at https://github.com/rust-lang/project-goal-reference-expansion/issues/11 . Finish the libtest json output experiment (rust-lang/rust-project-goals#255) Progress | ---|--- Point of contact | Ed Page Champions | cargo (Ed Page) Task owners | Ed Page No detailed updates available. Finish the std::offload module (rust-lang/rust-project-goals#109) Progress | ---|--- Point of contact | Manuel Drehwald Champions | compiler (Manuel Drehwald), lang (TC) Task owners | Manuel Drehwald, LLVM offload/GPU contributors 1 detailed update available. Comment by @ZuseZ4 posted on 2025-10-22: A longer update of the changes over the fall. We had two gsoc contributors and a lot of smaller improvements for std::autodiff. The first two improvements were already mentioned as draft PRs in the previous update, but got merged since. I also upstreamed more std::offload changes. 1. Marcelo DomΓ­nguez refactored the autodiff frontend to be a proper rustc intrinsic, rather than just hackend into the frontend like I first implemented it. This already solved multiple open issues, reduced the code size, and made it generally easier to maintain going forward. 2. Karan Janthe upstreamed a first implementation of "TypeTrees", which lowers rust type and layout information to Enzyme, our autodiff backend. This makes it more likely that you won't see compilation failures with the error message "Can not deduce type of ". We might refine in the future what information exactly we lower. 3. Karan Janthe made sure that std::autodiff has support for f16 and and f128 types. 4. One more of my offload PRs landed. I also figured out why the LLVM-IR generated by the std::offload code needed some manual adjustments in the past. We were inconsistent when communicating with LLVM's offload module, about whether we'd want a magic, extra, _dyn_ptr_ argument, that enables kernels to use some extra features. We don't use these features yet, but for consistency we now always generate and expect the extra pointer. The bugfix is currently under review, once it lands upstream, rustc is able to run code on GPUs (still with a little help of clang). 5. Marcelo DomΓ­nguez refactored my offload frontend, again introducing a proper rustc intrinsic. That code will still need to go through review, but once it lands it will get us a lot closer to a usable frontend. He also started to generate type information for our offload backend to know how many bytes to copy to and from the devices. This is a very simplified version of our autodiff typetrees. 6. At RustChinaConf, I was lucky to run into the wild linker author David Lattimore, which helped me to create a draft PR that can dlopen Enzyme at runtime. This means we could ship it via rustup for people interested in std::autodiff, and don't have to link it in at build time, which would increase binary size even for those users that are not interested in it. There are some open issues, so please reach out if you have time to get the PR ready! 7. @sgasho spend a lot of time trying to get Rust into the Enzyme CI. Unfortunately that is a tricky process due to Enzyme's CI requirements, so it's not merged yet. 8. I tried to simplify building std::autodiff by marking it as compatible with download-llvm-ci. Building LLVM from source was previously the by far slowest part of building rustc with autodiff, so this has a large potential. Unfortunately the CI experiments revealed some issues around this setting. We think we know why Enzyme's Cmake causes issues here and are working on a fix to make it more reliable. 9. Osama Abdelkader and bjorn3 looked into automatically enabling fat-lto when autodiff is enabled. In the past, forgetting to enable fat-lto resulted in incorrect (zero) derivatives. The first approach unfortunately wasn't able to cover all cases, so we need to see whether we can handle it nicely. If that turns out to be too complicated, we will revert it and instead "just" provide a nice error message, rather than returning incorrect derivatives. All-in-all I spend a lot more time on infra (dlopen, cmake, download-llvm-ci, ...) then I'd like, but on the happy side there are only so many features left that I want to support here so there is an end in sight. I am also about to give a tech-talk at the upcoming LLVM dev meeting about safe GPU programming in Rust. Getting Rust for Linux into stable Rust: compiler features (rust-lang/rust-project-goals#407) Progress | ---|--- Point of contact | Tomas Sedovic Champions | compiler (Wesley Wiser) Task owners | (depending on the flag) 3 detailed updates available. Comment by @tomassedovic posted on 2025-10-09: I've updated the top-level description to show everything we're tracking here (please let me know if anything's missing or incorrect!). Comment by @tomassedovic posted on 2025-10-10: * [merged] Sanitizers target modificators / https://github.com/rust-lang/rust/pull/138736 * [merged] Add assembly test for -Zreg-struct-return option / https://github.com/rust-lang/rust/pull/145382 * [merged] CI: rfl: move job forward to Linux v6.17-rc5 to remove temporary commits / https://github.com/rust-lang/rust/pull/146368 * `-Zharden-sls` / https://github.com/rust-lang/rust/pull/136597 * Waiting on review * `#![register_tool]` / https://github.com/rust-lang/rust/issues/66079 * Waiting on https://github.com/rust-lang/rfcs/pull/3808 * `-Zno-jump-tables` / https://github.com/rust-lang/rust/pull/145974 * Active FCP, waiting on 2 check boxes Comment by @tomassedovic posted on 2025-10-24: ### `-Cunsigned-char` We've discussed adding an option analogous to `-funsigned-char` in GCC and Clang, that would allow you to set whether `std::ffi::c_char` is represented by `i8` or `u8`. Right now, this is platform-specific and should map onto whatever `char` is in C on the same platform. However, Linux explicitly sets `char` to be unsigned and then our Rust code conflicts with that. And isn this case the sign is significant. Rust for Linux works around this this with their rust::ffi module, but now that they've switched to the standard library's `CStr` type, they're running into it again with the `as_ptr` method. Tyler mentioned https://docs.rs/ffi_11/latest/ffi_11/ which preserves the `char` / signed `char` / unsigned `char` distinction. ### Grouping target modifier flags The proposed `unsigned-char` option is essentially a target modifier. We have several more of these (e.g. `llvm-args`, `no-redzone`) in the Rust compiler and Josh suggested we distinguish them somehow. E.g. by giving them the same prefix or possibly creating a new config option (right now we have `-C` and `-Z`, maybe we could add `-T` for target modifiers) so they're distinct from the e.g. the codegen options. Josh started a Zulip thread here: https://rust-lang.zulipchat.com/#narrow/channel/131828-t-compiler/topic/Grouping.20target.20modifier.20options.3F/with/546524232 ### `#!register_tool]` / rust#66079 / [RFC#3808 Tyler looked at the RFC. The Crubit team started using `register_tool` but then moved to using an attribute instead. He proposed we could do something similar here, although it would require a new feature and RFC. The team was open to seeing how it would work. Getting Rust for Linux into stable Rust: language features (rust-lang/rust-project-goals#116) Progress | ---|--- Point of contact | Tomas Sedovic Champions | lang (Josh Triplett), lang-docs (TC) Task owners | Ding Xiang Fei 3 detailed updates available. Comment by @tomassedovic posted on 2025-10-09: I've updated the top-level description to show everything we're tracking here (please let me know if anything's missing or incorrect!). Comment by @tomassedovic posted on 2025-10-10: ### `Deref`/`Receiver` * Ding Xiang Fei keeps updating the PR: https://github.com/rust-lang/rust/pull/146095 * They're also working on a document to explain the consequences of this split ### Arbitrary Self Types * https://github.com/rust-lang/rust/issues/44874 * Waiting on the `Deref`/`Receiver` work, no updates ### `derive(CoercePointee)` * https://github.com/rust-lang/rust/pull/133820 * Waiting on Arbitrary self types ### Pass pointers to `const` in `asm!` blocks * RFC: https://github.com/rust-lang/rfcs/pull/3848 * The Lang team went through the RFC with Alice Ryhl on 2025-10-08 and it's in FCP now ### Field projections * Benno Lossin opened a PR here: https://github.com/rust-lang/rust/pull/146307 * Being reviewed by the compiler folks ### Providing `\0` terminated file names with `#[track_caller]` * The feature has been implemented and stabilized with `file_as_c_str` as the method name: https://github.com/rust-lang/rust/pull/145664 ### Supertrait auto impl RFC * Ding Xiang Fei opened the RFC and works with the reviewers: https://github.com/rust-lang/rfcs/pull/3851 ### Other * Miguel Ojeda spoke to Linus about rustfmt and they came to agreement. Comment by @tomassedovic posted on 2025-10-24: ### Layout of `core::any::TypeId` Danilo asked about the layout of `TypeId` -- specifically its size and whether they can rely on it because they want to store it in a C `struct`. The struct's size is currently 16 bytes, but that's an implementation detail. As a vibe check, Josh Triplett and Tyler Mandry were open to guaranteeing that it's going to be at most 16 bytes, but they wanted to reserve the option to reduce the size at some point. The next step is to have the full Lang and Libs teams discuss the proposal. Danilo will open a PR to get that discussion started. ### rustfmt Miguel brought up the "trailing empty comment" workaround for the formatting issue that made the rounds on the Linux kernel a few weeks ago. The kernel style places each import on a single line: use crate::{ fmt, page::AsPageIter, }; rustfmt compresses this to: use crate::{fmt, page::AsPageIter}; The workaround is to put an empty trailing comment at the end use crate::{ fmt, page::AsPageIter, // }; This was deemed acceptable (for the time being) and merged into the mainline kernel: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=4a9cb2eecc78fa9d388481762dd798fa770e1971 Miguel is in contact with rustfmt to support this behaviour without a workaround. ### `// PANIC: ...` comments / clippy#15895 This is a proposal to add a lint that would require a `PANIC` comment (modeled after the `SAFETY` comment) to explain the circumstances during which the code will or won't panic. Alejandra GonzΓ‘lez was open to the suggestion and Henry Barker stepped up to implement it. ### `Deref`/`Receiver` During the experimentation work, Ding ran into an issue with overlapping `impls` (that was present even with `#[unstable_feature_bound(..)]`). We ran out of time but we'll discuss this offline and return to it at the next meeting. Implement Open API Namespace Support (rust-lang/rust-project-goals#256) Progress | ---|--- Point of contact | Champions | cargo (Ed Page), compiler (b-naber), crates-io (Carol Nichols) Task owners | b-naber, Ed Page No detailed updates available. MIR move elimination (rust-lang/rust-project-goals#396) Progress | ---|--- Point of contact | Amanieu d'Antras Champions | lang (Amanieu d'Antras) Task owners | Amanieu d'Antras No detailed updates available. Prototype a new set of Cargo "plumbing" commands (rust-lang/rust-project-goals#264) Progress | ---|--- Point of contact | Task owners | , Ed Page No detailed updates available. Prototype Cargo build analysis (rust-lang/rust-project-goals#398) Progress | ---|--- Point of contact | Weihang Lo Champions | cargo (Weihang Lo) Task owners | Weihang Lo, Weihang Lo 1 detailed update available. Comment by @weihanglo posted on 2025-10-04: Cargo tracking issue: https://github.com/rust-lang/cargo/issues/15844. The first implementation was https://github.com/rust-lang/cargo/pull/15845 in August that added `build.analysis.enabled = true` to unconditionally generate timing HTML. Further implementations tasks is listed in https://github.com/rust-lang/cargo/issues/15844#issuecomment-3192779748. Haven't yet got any progress in September. reflection and comptime (rust-lang/rust-project-goals#406) Progress | ---|--- Point of contact | Oliver Scherer Champions | compiler (Oliver Scherer), lang (Scott McMurray), libs (Josh Triplett) Task owners | oli-obk 1 detailed update available. Comment by @oli-obk posted on 2025-10-22: I implemented an initial MVP supporting only tuples and primitives (tho those are just opaque things you can't interact with further), and getting offsets for the tuple fields as well as the size of the tuple: https://github.com/rust-lang/rust/pull/146923 There are two designs of how to expose this from a libs perspective, but after a sync meeting with scottmcm yesterday we came to the conclusion that neither is objectively better at this stage so we're just going to go with the nice end-user UX version for now. For details see the PR description. Once the MVP lands, I will mentor various interested contributors who will keep adding fields to the Type struct and variants the TypeKind enum. The next major step is restricting what information you can get from structs outside of the current module or crate. We want to honor visibility, so an initial step would be to just never show private fields, but we want to explore allowing private fields to be shown either just within the current module or via some opt-in marker trait Rework Cargo Build Dir Layout (rust-lang/rust-project-goals#401) Progress | ---|--- Point of contact | Ross Sullivan Champions | cargo (Weihang Lo) Task owners | Ross Sullivan 1 detailed update available. Comment by @ranger-ross posted on 2025-10-06: ### Status update October 6, 2025 The `build-dir` was split out of `target-dir` as part of https://github.com/rust-lang/cargo/issues/14125 and scheduled for stabilization in Rust `1.91.0`. πŸŽ‰ Before re-organizing the `build-dir` layout we wanted to improve the existing layout tests to make sure we do not make any unexpected changes. This testing harness improvement was merged in https://github.com/rust-lang/cargo/pull/15874. The initial `build-dir` layout reorganization PR has been posted https://github.com/rust-lang/cargo/pull/15947 and discussion/reviews are under way. Run more tests for GCC backend in the Rust's CI (rust-lang/rust-project-goals#402) Progress | ---|--- Point of contact | Guillaume Gomez Champions | compiler (Wesley Wiser), infra (Marco Ieni) Task owners | Guillaume Gomez No detailed updates available. Rust Stabilization of MemorySanitizer and ThreadSanitizer Support (rust-lang/rust-project-goals#403) Progress | ---|--- Point of contact | Jakob Koschel Task owners | Bastian Kersting, Jakob Koschel No detailed updates available. Rust Vision Document (rust-lang/rust-project-goals#269) Progress | ---|--- Point of contact | Niko Matsakis Task owners | vision team 1 detailed update available. Comment by @jackh726 posted on 2025-10-22: Update: Niko and I gave a talk at RustConf 2025 (and I represented that talk at RustChinaConf 2025) where we gave an update on this (and some intermediate insights). We have started to seriously plan the shape of the final doc. We have some "blind spots" that we'd like to cover before finishing up, but overall we're feeling close to the finish line on interviews. rustc-perf improvements (rust-lang/rust-project-goals#275) Progress | ---|--- Point of contact | James Champions | compiler (David Wood), infra (Jakub BerΓ‘nek) Task owners | James, Jakub BerΓ‘nek, David Wood 1 detailed update available. Comment by @Kobzol posted on 2025-10-21: We moved forward with the implementation, and the new job queue system is now being tested in production on a single test pull request. Most things seem to be working, but there are a few things to iron out and some profiling to be done. I expect that within a few weeks we could be ready to switch to the new system fully in production. Stabilize public/private dependencies (rust-lang/rust-project-goals#272) Progress | ---|--- Point of contact | Champions | cargo (Ed Page) Task owners | , Ed Page No detailed updates available. Stabilize rustdoc `doc_cfg` feature (rust-lang/rust-project-goals#404) Progress | ---|--- Point of contact | Guillaume Gomez Champions | rustdoc (Guillaume Gomez) Task owners | Guillaume Gomez No detailed updates available. SVE and SME on AArch64 (rust-lang/rust-project-goals#270) Progress | ---|--- Point of contact | David Wood Champions | compiler (David Wood), lang (Niko Matsakis), libs (Amanieu d'Antras) Task owners | David Wood 1 detailed update available. Comment by @nikomatsakis posted on 2025-10-22: # Sized hierarchy The focus right now is on the "non-const" parts of the proposal, as the "const" parts are blocked on the new trait solver (https://github.com/rust-lang/rust-project-goals/issues/113). Now that the types team FCP https://github.com/rust-lang/rust/pull/144064 has completed, work can proceed to land the implementation PRs. David Wood plans to split the RFC to separate out the "non-const" parts of the proposal so it can move independently, which will enable extern types. To that end, there are three interesting T-lang design questions to be considered. ## Naming of the traits The RFC currently proposes the following names * `Sized` * `MetaSized` * `PointeeSized` However, these names do not follow the "best practice" of naming the trait after the capability that it provides. As champion Niko is recommending we shift to the following names: * `Sized` -- should righly be called `SizeOf`, but oh well, not worth changing. * `SizeOfVal` -- named after the method `size_of_val` that you get access to. * `Pointee` -- the only thing you can do is point at it. The last trait name is already used by the (unstable) `std::ptr::Pointee` trait. We do not want to have these literally be the same trait because that trait adds a `Metadata` associated type which would be backwards incompatible; if existing code uses `T::Metadata` to mean `<T as SomeOtherTrait>::Metadata`, it could introduce ambiguity if now `T: Pointee` due to defaults. My proposal is to rename `std::ptr::Pointee` to `std::ptr::PointeeMetadata` for now, since that trait is unstable and the design remains under some discussion. The two traits could either be merged eventually or remain separate. Note that `PointeeMetadata` _would_ be implemented automatically by the compiler for anything that implements `Pointee`. ## Syntax opt-in The RFC proposes that an explicit bound like `T: MetaSized` disabled the default `T: Sized ` bound. However, this gives no signal that this trait bound is "special" or different than any other trait bound. Naming conventions can help here, signalling to users that these are special traits, but that leads to constraints on naming and may not scale as we consider using this mechanism to relax other defaults as proposed in my recent blog post. One idea is to use some form of syntax, so that `T: MetaSized` is just a regular bound, but (for example) `T: =MetaSized` indicates that this bound "disables" the default `Sized` bound. This gives users some signal that something special is going on. This `=` syntax is borrowing from semver constraints, although it's not a precise match (it does not mean that `T: Sized` doesn't hold, after all). Other proposals would be some other sigil (`T: ?MetaSized`, but it means "opt out from the traits above you"; `T: #MetaSized`, ...) or a keyword (no idea). To help us get a feel for it, I'll use `T: =Foo` throughout this post. ## Implicit trait supertrait bounds, edition interaction In Rust 2024, a trait is implicitly `?Sized` which gets mapped to `=SizeOfVal`: trait Marker {} // cannot be implemented by extern types This is not desirable but changing it would be backwards incompatible if traits have default methods that take advantage of this bound: trait NotQuiteMarker { fn dummy(&self) { let s = size_of_val(self); } } We need to decide how to handle this. Options are * Just change it, breakage will be small (have to test that). * Default to `=SizeOfVal` but let users explicitly write `=Pointee` if they want that. Bad because all traits will be incompatible with extern types. * Default to `=SizeOfVal` only if defaulted methods are present. Bad because it's a backwards incompatible change to add a defaulted method now. * Default to `=Pointee` but add `where Self: =SizeOfVal` implicitly to defaulted methods. Now it's not backwards incompatible to add a new defaulted method, but it is backwards incompatible to change an existing method to have a default. If we go with one of the latter options, Niko proposes that we should relax this in the next Edition (Rust 2026?) so that the default becomes `Pointee` (or maybe not even that, if we can). ## Relaxing associated type bounds Under the RFC, existing `?Sized` bounds would be equivalent to `=SizeOfVal`. This is mostly fine but will cause problems in (at least) two specific cases: closure bounds and the `Deref` trait. For closures, we can adjust the bound since the associated type is unstable and due to the peculiarities of our `Fn() -> T` syntax. Failure to adjust the Deref bound in particular would prohibit the use of `Rc<E>` where `E` is an extern type, etc. For deref bounds, David Wood is preparing a PR that simply changes the bound in a backwards incompatible way to assess breakage on crater. There is some chance the breakage will be small. If the breakage proves problematic, or if we find other traits that need to be relaxed in a similar fashion, we do have the option of: * In Rust 2024, `T: Deref` becomes equivalent to `T: Deref<Target: SizeOfVal>` unless written like `T: Deref<Target: =Pointee>`. We add that annotation throughout stdlib. * In Rust 202X, we change the default, so that `T: Deref` does not add any special bounds, and existing Rust 2024 `T: Deref` is rewritten to `T: Deref<Target: SizeOfVal>` as needed. ## Other notes One topic that came up in discussion is that we may eventually wish to add a level "below" `Pointee`, perhaps `Value`, that signifies webassembly external values which cannot be pointed at. That is not currently under consideration but should be backwards compatible. Type System Documentation (rust-lang/rust-project-goals#405) Progress | ---|--- Point of contact | Boxy Champions | types (Boxy) Task owners | Boxy, lcnr No detailed updates available. Unsafe Fields (rust-lang/rust-project-goals#273) Progress | ---|--- Point of contact | Jack Wrenn Champions | compiler (Jack Wrenn), lang (Scott McMurray) Task owners | Jacob Pratt, Jack Wrenn, Luca Versari No detailed updates available.
19.11.2025 00:00 πŸ‘ 2 πŸ” 1 πŸ’¬ 0 πŸ“Œ 0
Google Summer of Code 2025 results As we have announced previously this year, the Rust Project participated in Google Summer of Code (GSoC) for the second time. Almost twenty contributors have been working very hard on their projects for several months. Same as last year, the projects had various durations, so some of them have ended in September, while the last ones have been concluded in the middle of November. Now that the final reports of all projects have been submitted, we are happy to announce that 18 out of 19 projects have been successful! We had a very large number of projects this year, so we consider this number of successfully finished projects to be a great result. We had awesome interactions with our GSoC contributors over the summer, and through a video call, we also had a chance to see each other and discuss the accepted GSoC projects. Our contributors have learned a lot of new things and collaborated with us on making Rust better for everyone, and we are very grateful for all their contributions! Some of them have even continued contributing after their project has ended, and we hope to keep working with them in the future, to further improve open-source Rust software. **We would like to thank all our Rust GSoC 2025 contributors. You did a great job!** Same as last year, Google Summer of Code 2025 was overall a success for the Rust Project, this time with more than double the number of projects. We think that GSoC is a great way of introducing new contributors to our community, and we are looking forward to participating in GSoC (or similar programs) again in the near future. If you are interested in becoming a (GSoC) contributor, check out our GSoC project idea list and our guide for new contributors. Below you can find a brief summary of our GSoC 2025 projects. You can find more information about the original goals of the projects here. For easier navigation, here is an index of the project descriptions in alphabetical order: * ABI/Layout handling for the automatic differentiation feature by Marcelo DomΓ­nguez * Add safety contracts by Dawid Lachowicz * Bootstrap of rustc with rustc_codegen_gcc by MichaΕ‚ Kostrubiec * Cargo: Build script delegation by Naman Garg * Distributed and resource-efficient verification by Jiping Zhou * Enable Witness Generation in cargo-semver-checks by Talyn Veugelers * Extend behavioural testing of std::arch intrinsics by Madhav Madhusoodanan * Implement merge functionality in bors by Sakibul Islam * Improve bootstrap by Shourya Sharma * Improve Wild linker test suites by Kei Akiyama * Improving the Rustc Parallel Frontend: Parallel Macro Expansion by Lorrens Pantelis * Make cargo-semver-checks faster by Joseph Chung * Make Rustup Concurrent by Francisco Gouveia * Mapping the Maze of Rust's UI Test Suite with Established Continuous Integration Practices by Julien Robert * Modernising the libc Crate by Abdul Muiz * Prepare stable_mir crate for publishing by Makai * Prototype an alternative architecture for cargo fix using cargo check by Glen Thalakottur * Prototype Cargo Plumbing Commands by Vito Secona And now strap in, as there is a ton of great content to read about here! ### ABI/Layout handling for the automatic differentiation feature * Contributor: Marcelo DomΓ­nguez * Mentors: Manuel Drehwald, Oli Scherer * Final report The `std::autodiff` module allows computing gradients and derivatives in the calculus sense. It provides two autodiff macros, which can be applied to user-written functions and automatically generate modified versions of those functions, which also compute the requested gradients and derivatives. This functionality is very useful especially in the context of scientific computing and implementation of machine-learning models. Our autodiff frontend was facing two challenges. * First, we would generate a new function through our macro expansion, however, we would not have a suitable function body for it yet. Our autodiff implementation relies on an LLVM plugin to generate the function body. However, this plugin only gets called towards the end of the compilation pipeline. Earlier optimization passes, either on the LLVM or the Rust side, could look at the placeholder body and either "optimize" or even delete the function since it has no clear purpose yet. * Second, the flexibility of our macros was causing issues, since it allows requesting derivative computations on a per-argument basis. However, when we start to lower Rust arguments to our compiler backends like LLVM, we do not always have a 1:1 match of Rust arguments to LLVM arguments. As a simple example, an array with two double values might be passed as two individual double values on LLVM level, whereas an array with three doubles might be passed via a pointer. Marcelo helped rewrite our `autodiff` macros to not generate hacky placeholder function bodies, but instead introduced a proper `autodiff` intrinsic. This is the proper way for us to declare that an implementation of this function is not available yet and will be provided later in the compilation pipeline. As a consequence, our generated functions were not deleted or incorrectly optimized anymore. The intrinsic PR also allowed removing some previous hacks and therefore reduced the total lines of code in the Rust compiler by over 500! You can find more details in this PR. Beyond autodiff work, Marcelo also initiated work on GPU offloading intrinsics, and helped with multiple bugs in our argument handling. We would like to thank Marcelo for all his great work! ### Add safety contracts * Contributor: Dawid Lachowicz * Mentor: Michael Tautschnig * Final report The Rust Project has an ambitious goal to instrument the Rust standard library with safety contracts, moving from informal comments that specify safety requirements of `unsafe` functions to executable Rust code. This transformation represents a significant step toward making Rust's safety guarantees more explicit and verifiable. To prioritize which functions should receive contracts first, there is a verification contest ongoing. Given that Rust contracts are still in their early stages, Dawid's project was intentionally open-ended in scope and direction. This flexibility allowed Dawid to identify and tackle several key areas that would add substantial value to the contracts ecosystem. His contributions were in the following three main areas: * **Pragmatic Contracts Integration** : Refactoring contract HIR lowering to ensure no contract code is executed when contract-checks are disabled. This has major impact as it ensures that contracts do not have runtime cost when contract checks are disabled. * **Variable Reference Capability** : Adding the ability to refer to variables from preconditions within postconditions. This fundamental enhancement to the contracts system has been fully implemented and merged into the compiler. This feature provides developers with much more expressive power when writing contracts, allowing them to establish relationships between input and output states. * **Separation Logic Integration** : The bulk of Dawid's project involved identifying, understanding, and planning the introduction of owned and block ownership predicates for separation-logic style reasoning in contracts for unsafe Rust code. This work required extensive research and collaboration with experts in the field. Dawid engaged in multiple discussions with authors of Rust validation tools and Miri developers, both in person and through Zulip discussion threads. The culmination of this research is captured in a comprehensive MCP (Major Change Proposal) that Dawid created. Dawid's work represents crucial foundational progress for Rust's safety contracts initiative. By successfully implementing variable reference capabilities and laying the groundwork for separation logic integration, he has positioned the contracts feature for significant future development. His research and design work will undoubtedly influence the direction of this important safety feature as it continues to mature. Thank you very much! ### Bootstrap of rustc with rustc_codegen_gcc * Contributor: MichaΕ‚ Kostrubiec * Mentor: antoyo * Final report The goal of this project was to improve the Rust GCC codegen backend (`rustc_codegen_gcc`), so that it would be able to compile the "stage 2"1 Rust compiler (`rustc`) itself again. You might remember that MichaΕ‚ already participated in GSoC last year, where he was working on his own .NET Rust codegen backend, and he did an incredible amount of work. This year, his progress was somehow even faster. Even before the official GSoC implementation period started (!), he essentially completed his original project goal and managed to build `rustc` with GCC. This was no small feat, as he had to investigate and fix several miscompilations that occurred when functions marked with `#inline(always)]` were called recursively or when the compiled program was trying to work with 128-bit integers. You can read more about this initial work at his [blog. After that, he immediately started working on stretch goals of his project. The first one was to get a "stage-3" `rustc` build working, for which he had to vastly improve the memory consumption of the codegen backend. Once that was done, he moved on to yet another goal, which was to build `rustc` for a platform not supported by LLVM. He made progress on this for Dec Alpha and m68k. He also attempted to compile `rustc` on Aarch64, which led to him finding an ABI bug. Ultimately, he managed to build a `rustc` for m68k (with a few workarounds that we will need to fix in the future). That is a very nice first step to porting Rust to new platforms unsupported by LLVM, and is important for initiatives such as Rust for Linux. MichaΕ‚ had to spend a lot of time starting into assembly code and investigating arcane ABI problems. In order to make this easier for everyone, he implemented support for fuzzing and automatically checking ABI mismatches in the GCC codegen backend. You can read more about his testing and fuzzing efforts here. We were really impressed with what MichaΕ‚ was able to achieve, and we really appreciated working with him this summer. Thank you for all your work, MichaΕ‚! ### Cargo: Build script delegation * Contributor: Naman Garg * Mentor: Ed Page * Final report Cargo build scripts come at a compile-time cost, because even to run `cargo check`, they must be built as if you ran `cargo build`, so that they can be executed during compilation. Even though we try to identify ways to reduce the need to write build scripts in the first place, that may not always be doable. However, if we could shift build scripts from being defined in every package that needs them, into a few core build script packages, we could both reduce the compile-time overhead, and also improve their auditability and transparency. You can find more information about this idea here. The first step required to delegate build scripts to packages is to be able to run multiple build scripts per crate, so that is what Naman was primarily working on. He introduced a new unstable `multiple-build-scripts` feature to Cargo, implemented support for parsing an array of build scripts in `Cargo.toml`, and extended Cargo so that it can now execute multiple build scripts while building a single crate. He also added a set of tests to ensure that this feature will work as we expect it to. Then he worked on ensuring that the execution of builds scripts is performed in a deterministic order, and that crates can access the output of each build script separately. For example, if you have the following configuration: [package] build = ["windows-manifest.rs", "release-info.rs"] then the corresponding crate is able to access the `OUT_DIR`s of both build scripts using `env!("windows-manifest_OUT_DIR")` and `env!("release-info_OUTDIR")`. As future work, we would like to implement the ability to pass parameters to build scripts through metadata specified in `Cargo.toml` and then implement the actual build script delegation to external build scripts using artifact-dependencies. We would like to thank Naman for helping improving Cargo and laying the groundwork for a feature that could have compile-time benefits across the Rust ecosystem! ### Distributed and resource-efficient verification * Contributor: Jiping Zhou * Mentor: Michael Tautschnig * Final report The goal of this project was to address critical scalability challenges of formally verifying Rust's standard library by developing a distributed verification system that intelligently manages computational resources and minimizes redundant work. The Rust standard library verification project faces significant computational overhead when verifying large codebases, as traditional approaches re-verify unchanged code components. With Rust's standard library containing thousands of functions and continuous development cycles, this inefficiency becomes a major bottleneck for practical formal verification adoption. Jiping implemented a distributed verification system with several key innovations: * **Intelligent Change Detection** : The system uses hash-based analysis to identify which parts of the codebase have actually changed, allowing verification to focus only on modified components and their dependencies. * **Multi-Tool Orchestration** : The project coordinates multiple verification backends including Kani model checker, with careful version pinning and compatibility management. * **Distributed Architecture** : The verification workload is distributed across multiple compute nodes, with intelligent scheduling that considers both computational requirements and dependency graphs. * **Real-time Visualization** : Jiping built a comprehensive web interface that provides live verification status, interactive charts, and detailed proof results. You can check it out here! You can find the created distributed verification tool in this repository. Jiping's work established a foundation for scalable formal verification that can adapt to the growing complexity of Rust's ecosystem, while maintaining verification quality and completeness, which will go a long way towards ensuring that Rust's standard library remains safe and sound. Thank you for your great work! ### Enable Witness Generation in cargo-semver-checks * Contributor: Talyn Veugelers * Mentor: Predrag Gruevski * Final report `cargo-semver-checks` is a Cargo subcommand for finding SemVer API breakages in Rust crates. Talyn's project aimed to lay the groundwork for it to tackle our most vexing limitation: the inability to catch SemVer breakage due to type changes. Imagine a crate makes the following change to its public API: // baseline version pub fn example(value: i64) {} // new version pub fn example(value: String) {} This is _clearly_ a major breaking change, right? And yet `cargo-semver-checks` with its hundreds of lints is _still_ unable to flag this. While this case seems trivial, it's just the tip of an enormous iceberg. Instead of changing `i64` to `String`, what if the change was from `i64` to `impl Into<i64>`, or worse, into some monstrosity like: pub fn example<T, U, const N: usize>( value: impl for<'a> First<'a, T> + Second<U, N> + Sync ) {} Figuring out whether this change is breaking requires checking whether the original `i64` parameter type can "fit" into that monstrosity of an `impl Trait` type. But reimplementing a Rust type checker and trait solver inside `cargo-semver-checks` is out of the question! Instead, we turn to a technique created for a previous study of SemVer breakage on crates.ioβ€”we generate a "witness" program that will fail to compile if, and only if, there's a breaking change between the two versions. The witness program is a separate crate that can be made to depend on either the old or the new version of the crate being scanned. If our `example` function comes from a crate called `upstream`, its witness program would look something like: // take the same parameter type as the baseline version fn witness(value: i64) { upstream::example(value); } > This example is cherry-picked to be easy to understand. Witness programs are rarely this straightforward! Attempting to `cargo check` the witness while plugging in the new version of `upstream` forces _the Rust compiler_ to decide whether `i64` matches the new `impl Trait` parameter. If `cargo check` passes without errors, there's no breaking change here. But if there's a compilation error, then this is concrete, incontrovertible evidence of breakage! Over the past 22+ weeks, Talyn worked tirelessly to move this from an idea to a working proof of concept. For every problem we foresaw needing to solve, ten more emerged along the way. Talyn did a lot of design work to figure out an approach that would be able to deal with crates coming from various sources (crates.io, a path on disk, a git revision), would support multiple rustdoc JSON formats for all the hundreds of existing lints, and do so in a fashion that doesn't get in the way of adding hundreds more lints in the future. Even the above list of daunting challenges fails to do justice to the complexity of this project. Talyn created a witness generation prototype that lays the groundwork for robust checking of type-related SemVer breakages in the future. The success of this work is key to the `cargo-semver-checks` roadmap for 2026 and beyond. We would like to thank Talyn for their work, and we hope to continue working with them on improving witness generation in the future. ### Extend behavioural testing of std::arch intrinsics * Contributor: Madhav Madhusoodanan * Mentor: Amanieu d'Antras * Final report The `std::arch` module contains target-specific intrinsics (low-level functions that typically correspond to single machine instructions) which are intended to be used by other libraries. These are intended to match the equivalent intrinsics available as vendor-specific extensions in C. The intrinsics are tested with three approaches. We test that: * The signatures of the intrinsics match the one specified by the architecture. * The intrinsics generate the correct instruction. * The intrinsics have the correct runtime behavior. These behavior tests are implemented in the intrinsics-test crate. Initially, this test framework only covered the AArch64 and AArch32 targets, where it was very useful in finding bugs in the implementation of the intrinsics. Madhav's project was about refactoring and improving this framework to make it easier (or really, possible) to extend it to other CPU architectures. First, Madhav split the codebase into a module with shared (architecturally independent) code and a module with ARM-specific logic. Then he implemented support for testing intrinsics for the x86 architecture, which is Rust's most widely used target. In doing so, he allowed us to discover real bugs in the implementation of some intrinsics, which is a great result! Madhav also did a lot of work in optimizing how the test suite is compiled and executed, to reduce CI time needed to run tests, and he laid the groundwork for supporting even more architectures, specifically LoongArch and WebAssembly. We would like to thank Madhav for all his work on helping us make sure that Rust intrinsics are safe and correct! ### Implement merge functionality in bors * Contributor: Sakibul Islam * Mentor: Jakub BerΓ‘nek * Final report The main Rust repository uses a pull request merge queue bot that we call `bors`. Its current Python implementation has a lot of issues and was difficult to maintain. The goal of this GSoC project was thus to implement the primary merge queue functionality in our Rust rewrite of this bot. Sakibul first examined the original Python codebase to figure out what it was doing, and then he implemented several bot commands that allow contributors to approve PRs, set their priority, delegate approval rights, temporarily close the merge tree, and many others. He also implemented an asynchronous background process that checks whether a given pull request is mergeable or not (this process is relatively involved, due to how GitHub works), which required implementing a specialized synchronized queue for deduplicating mergeability check requests to avoid overloading the GitHub API. Furthermore, Sakibul also reimplemented (a nicer version of) the merge queue status webpage that can be used to track which pull requests are currently being tested on CI, which ones are approved, etc. After the groundwork was prepared, Sakibul could work on the merge queue itself, which required him to think about many tricky race conditions and edge cases to ensure that bors doesn't e.g. merge the wrong PR into the default branch or merge a PR multiple times. He covered these edge cases with many integration tests, to give us more confidence that the merge queue will work as we expect it to, and also prepared a script for creating simulated PRs on a test GitHub repository so that we can test bors "in the wild". And so far, it seems to be working very well! After we finish the final piece of the merge logic (creating so-called "rollups") together with Sakibul, we will start using bors fully in the main Rust repository. Sakibul's work will thus be used to merge all `rust-lang/rust` pull requests. Exciting! Apart from working on the merge queue, Sakibul made many other awesome contributions to the codebase, like refactoring the test suite or analyzing performance of SQL queries. In total, Sakibul sent around fifty pull requests that were already merged into bors! What can we say, other than: Awesome work Sakibul, thank you! ### Improve bootstrap * Contributor: Shourya Sharma * Mentors: Jakub BerΓ‘nek, Jieyou Xu, Onur Γ–zkan * Final report bootstrap is the build system of Rust itself, which is responsible for building the compiler, standard library, and pretty much everything else that you can download through `rustup`. This project's goal was very open-ended: "improve bootstrap". And Shourya did just that! He made meaningful contributions to several parts of bootstrap. First, he added much-needed documentation to several core bootstrap data structures and modules, which were quite opaque and hard to understand without any docs. Then he moved to improving command execution, as each bootstrap invocation invokes hundreds of external binaries, and it was difficult to track them. Shourya finished a long-standing refactoring that routes almost all executed commands through a single place. This allowed him to also implement command caching and also command profiling, which shows us which commands are the slowest. After that, Shourya moved on to refactoring config parsing. This was no easy task, because bootstrap has A LOT of config options; the single _function_ that parses them had over a thousand lines of code (!). A set of complicated config precedence rules was frequently causing bugs when we had to modify that function. It took him several weeks to untangle this mess, but the result is worth it. The refactored function is much less brittle and easier to understand and modify, which is great for future maintenance. The final area that Shourya improved were bootstrap tests. He made it possible to run them using bare `cargo`, which enables debugging them e.g. in an IDE, which is very useful, and mainly he found a way to run the tests in parallel, which makes contributing to bootstrap itself much more pleasant, as it reduced the time to execute the tests from a minute to under ten seconds. These changes required refactoring many bootstrap tests that were using global state, which was not compatible with parallel execution. Overall, Shourya made more than 30 PRs to bootstrap since April! We are very thankful for all his contributions, as they made bootstrap much easier to maintain. Thank you! ### Improve Wild linker test suites * Contributor: Kei Akiyama * Mentor: David Lattimore * Final report Wild is a very fast linker for Linux that’s written in Rust. It can be used to build executables and shared objects. Kei’s project was to leverage the test suite of one of the other Linux linkers to help test the Wild linker. This goal was accomplished. Thanks to Kei’s efforts, we now run the Mold test suite against Wild in our CI. This has helped to prevent regressions on at least a couple of occasions and has also helped to show places where Wild has room for improvement. In addition to this core work, Kei also undertook numerous other changes to Wild during GSoC. Of particular note was the reworking of argument parsing to support `--help`, which we had wanted for some time. Kei also fixed a number of bugs and implemented various previously missing features. This work has helped to expand the range of projects that can use Wild to build executables. Kei has continued to contribute to Wild even after the GSoC project finished and has now contributed over seventy PRs. We thank Kei for all the hard work and look forward to continued collaboration in the future! ### Improving the Rustc Parallel Frontend: Parallel Macro Expansion * Contributor: Lorrens Pantelis * Mentors: Sparrow Li, Vadim Petrochenkov * Final report The Rust compiler has a (currently unstable) parallel compilation mode in which some compiler passes run in parallel. One major part of the compiler that is not yet affected by parallelization is name resolution. It has several components, but those selected for this GSoC project were import resolution and macro expansion (which are in fact intermingled into a single fixed-point algorithm). Besides the parallelization itself, another important point of the work was improving the correctness of import resolution by eliminating accidental order dependencies in it, as those also prevent parallelization. We should note that this was a _very_ ambitious project, and we knew from the beginning that it would likely be quite challenging to reach the end goal within the span of just a few months. And indeed, Lorrens did in fact run into several unexpected issues that showed us that the complexity of this work is well beyond a single GSoC project, so he didn't actually get to parallelizing the macro expansion algorithm. Nevertheless, he did a lot of important work to improve the name resolver and prepare it for being parallelized. The first thing that Lorrens had to do was actually understand how Rust name resolution works and how it is implemented in the compiler. That is, to put it mildly, a _very complex_ piece of logic, and is affected by legacy burden in the form of backward compatibility lints, outdated naming conventions, and other technical debt. Even this learned knowledge itself is incredibly useful, as the set of people that understand Rust's name resolution today is very low, so it is important to grow it. Using this knowledge, he made a lot of refactorings to separate _significant_ mutability in name resolver data structures from "cache-like" mutability used for things like lazily loading otherwise immutable data from extern crates, which was needed to unblock parallelization work. He split various parts of the name resolver, got rid of unnecessary mutability and performed a bunch of other refactorings. He also had to come up with a very tricky data structure that allows providing conditional mutable access to some data. These refactorings allowed him to implement something called "batched import resolution", which splits unresolved imports in the crate into "batches", where all imports in a single batch can be resolved independently and potentially in parallel, which is crucial for parallelizing name resolution. We have to resolve a few remaining language compatibility issues, after which the batched import resolution work will hopefully be merged. Lorrens laid an important groundwork for fixing potential correctness issues around name resolution and macro expansion, which unblocks further work on parallelizing these compiler passes, which is exciting. His work also helped unblock some library improvements that were stuck for a long time. We are grateful for your hard work on improving tricky parts of Rust and its compiler, Lorrens. Thank you! ### Make cargo-semver-checks faster * Contributor: Joseph Chung * Mentor: Predrag Gruevski * Final report `cargo-semver-checks` is a Cargo subcommand for finding SemVer API breakages in Rust crates. It is adding SemVer lints at an _exponential_ pace: the number of lints has been doubling every year, and currently stands at `229`. More lints mean more work for `cargo-semver-checks` to do, as well as more work for its test suite which runs over 250000 lint checks! Joseph's contributions took three forms: * Improving `cargo-semver-checks` runtime performanceβ€”on large crates, our query runtime went from ~8s to ~2s, a 4x improvement! * Improving the test suite's performance, enabling us to iterate faster. Our test suite used to take ~7min and now finishes in ~1min, a 7x improvement! * Improving our ability to profile query performance and inspect performance anomalies, both of which were proving a bottleneck for our ability to ship further improvements. Joseph described all the clever optimization tricks leading to these results in his final report. To encourage you to check out the post, we'll highlight a particularly elegant optimization described there. `cargo-semver-checks` relies on rustdoc JSON, an unstable component of Rust whose output format often has breaking changes. Since each release of `cargo-semver-checks` supports a range of Rust versions, it must also support a range of rustdoc JSON formats. Fortunately, each file carries a version number that tells us which version's `serde` types to use to deserialize the data. Previously, we used to deserialize the JSON file twice: once with a `serde` type that only loaded the `format_version: u32` field, and a second time with the appropriate `serde` type that matches the format. This works fine, but many large crates generate rustdoc JSON files that are 500 MiB+ in size, requiring us to walk all that data twice. While `serde` is quite fast, there's nothing as fast as _not_ doing the work twice in the first place! So we used a trick: _optimistically_ check if the `format_version` field is the last field in the JSON file, which happens to be the case every time (even though it is not guaranteed). Rather than parsing JSON, we merely look for a `,` character in the last few dozen bytes, then look for `:` after the `,` character, and for `format_version` between them. If this is successful, we've discovered the version number while avoiding going through hundreds of MB of data! If we failed for any reason, we just fall back to the original approach having only wasted the effort of looking at 20ish extra bytes. Joseph did a lot of profiling and performance optimizations to make `cargo-semver-checks` faster for everyone, with awesome results. Thank you very much for your work! ### Make Rustup Concurrent * Contributor: Francisco Gouveia * Mentor: rami3l * Final report As a very important part of the Rustup team's vision of migrating the rustup codebase to using async IO since the introduction of the global `tokio` runtime in #3367, this project's goal was to introduce proper concurrency to rustup. Francisco did that by attacking two aspects of the codebase at once: 1. He created a new set of user interfaces for displaying concurrent progress. 2. He implemented a new toolchain update checking & installation flow that is idiomatically concurrent. As a warmup, Francisco made `rustup check` concurrent, resulting in a rather easy 3x performance boost in certain cases. Along the way, he also introduced a new indicatif-based progress bar for reporting progress of concurrent operations, which replaced the original hand-rolled solution. After that, the focus of the project has moved on to the toolchain installation flow used in commands like `rustup toolchain install` and `rustup update`. In this part, Francisco developed two main improvements: 1. The possibility of downloading multiple components at once when setting up a toolchain, controlled by the `RUSTUP_CONCURRENT_DOWNLOADS` environment variable. Setting this variable to a value greater than 1 is particularly useful in certain internet environments where the speed of a single download connection could be restricted by QoS (Quality of Service) limits. 2. The ability to interleave component network downloads and disk unpacking. For the moment, unpacking will still happen sequentially, but disk and net I/O can finally be overlapped! This introduces a net gain in toolchain installation time, as only the last component being downloaded will have noticeable unpacking delays. In our tests, this typically results in a reduction of 4-6 seconds (on fast connections, that's ~33% faster!) when setting up a toolchain with the `default` profile. We have to say that these results are very impressive! While a few seconds shorter toolchain installation might not look so important at a first glance, rustup is ubiquitously used to install Rust toolchains on CI of tens of thousands of Rust projects, so this improvement (and also further improvements that it unlocks) will have an enormous effect across the Rust ecosystem. Many thanks to Francisco Gouveia's enthusiasm and active participation, without which this wouldn't have worked out! ### Mapping the Maze of Rust's UI Test Suite with Established Continuous Integration Practices * Contributor: Julien Robert * Mentor: Jieyou Xu * Final report The snapshot-based UI test suite is a crucial part of the Rust compiler's test suite. It contains _a lot_ of tests: over 19000 at the time of writing. The organization of this test suite is thus very important, for at least two reasons: 1. We want to be able to find specific tests, identify related tests, and have some sort of logical grouping of related tests. 2. We have to ensure that no directory contains so many entries such that GitHub gives up rendering the directory. Furthermore, having informative test names and having some context for each test is particularly important, as otherwise contributors would have to reverse-engineer test intent from `git blame` and friends. Over the years, we have accumulated a lot of unorganized stray test files in the top level `tests/ui` directory, and have a lot of generically named `issue-*.rs` tests in the `tests/ui/issues/` directory. The former makes it annoying to find more meaningful subdirectories, while the latter makes it completely non-obvious what each test is about. Julien's project was about introducing some order into the chaos. And that was indeed achieved! Through Julien's efforts (in conjunction with efforts from other contributors), we now have: * No more stray tests under the immediate `tests/ui/` top-level directory, and are organized into more meaningful subdirectories. We were able to then introduce a style check to prevent new stray tests from being added. * A top-level document contains TL;DRs for each of the immediate subdirectories. * Substantially fewer generically-named `issue-*.rs`under `tests/ui/issues/`. Test organization (and more generally, test suite ergonomics) is an often under- appreciated aspect of maintaining complex codebases. Julien spent a lot of effort improving test ergonomics of the Rust compiler, both in last year's GSoC (where he vastly improved our "run-make" test suite), and then again this year, where he made our UI test suite more ergonomic. We would like to appreciate your meticulous work, Julien! Thank you very much. ### Modernising the libc Crate * Contributor: Abdul Muiz * Mentor: Trevor Gross * Final report `libc` is a crucial crate in the Rust ecosystem (on average, it has ~1.5 million _daily_ downloads), providing bindings to system C API. This GSoC project had two goals: improve testing for what we currently have, and make progress toward a stable 1.0 release of `libc`. Test generation is handled by the `ctest` crate, which creates unit tests that compare properties of Rust API to properties of the C interfaces it binds. Prior to the project, `ctest` used an obsolete Rust parser that had stopped receiving major updates about eight years ago, meaning `libc` could not easily use any syntax newer than that. Abdul completely rewrote `ctest` to use `syn` as its parser and make it much easier to add new tests, then went through and switched everything over to the more modern `ctest`. After this change, we were able to remove a number of hacks that had been needed to work with the old parser. The other part of the project was to make progress toward the 1.0 release of `libc`. Abdul helped with this by going through and addressing a number of issues that need to be resolved before the release, many of which were made possible with all the `ctest` changes. While there is still a lot of work left to do before `libc` can reach 1.0, Abdul's improvements will go a long way towards making that work easier, as they give us more confidence in the test suite, which is now much easier to modify and extend. Thank you very much for all your work! ### Prepare stable_mir crate for publishing * Contributor: Makai * Mentor: Celina Val * Final report This project's goal was to prepare the Rust compiler's `stable_mir` crate (eventually renamed to `rustc_public`), which provides a way to interface with the Rust compiler for analyzing Rust code, for publication on crates.io. While the existing crate provided easier APIs for tool developers, it lacked proper versioning and was tightly coupled with compiler versions. The goal was to enable independent publication with semantic versioning. The main technical work involved restructuring `rustc_public` and `rustc_public_bridge` (previously named `rustc_smir`) by inverting their dependency relationship. Makai resolved circular dependencies by temporarily merging the crates and gradually separating them with the new architecture. They also split the existing compiler interface to separate public APIs from internal compiler details. Furthermore, Makai established infrastructure for dual maintenance: keeping an internal version in the Rust repository to track compiler changes while developing the publishable version in a dedicated repository. Makai automated a system to coordinate between versions, and developed custom tooling to validate compiler version compatibility and to run tests. Makai successfully completed the core refactoring and infrastructure setup, making it possible to publish `rustc_public` independently with proper versioning support for the Rust tooling ecosystem! As a bonus, Makai contributed several bug fixes and implemented new APIs that had been requested by the community. Great job Makai! ### Prototype an alternative architecture for cargo fix using cargo check * Contributor: Glen Thalakottur * Mentor: Ed Page * Final report The `cargo fix` command applies fixes suggested by lints, which makes it useful for cleaning up sloppy code, reducing the annoyance of toolchain upgrades when lints change and helping with edition migrations and new lint adoption. However, it has a number of issues. It can be slow, it only applies a subset of possible lints, and doesn't provide an easy way to select which lints to fix. These problems are caused by its current architecture; it is implemented as a variant of `cargo check` that replaces `rustc` with `cargo` being run in a special mode that will call `rustc` in a loop, applying fixes until there are none. While this special `rustc`-proxy mode is running, a cross-process lock is held to force only one build target to be fixed at a time to avoid race conditions. This ensures correctness at the cost of performance and difficulty in making the `rustc`-proxy interactive. Glen implemented a proof of concept of an alternative design called cargo-fixit. `cargo fixit` spawns `cargo check` in a loop, determining which build targets are safe to fix in a given pass, and then applying the suggestions. This puts the top-level program in charge of what fixes get applied, making it easier to coordinate. It also allows the locking to be removed and opens the door to an interactive mode. Glen performed various benchmarks to test how the new approach performs. And in some benchmarks, `cargo fixit` was able to finish within a few hundred milliseconds, where before the same task took `cargo fix` almost a minute! As always, there are trade-offs; the new approach comes at the cost that fixes in packages lower in the dependency tree can cause later packages to be rebuilt multiple times, slowing things down, so there were also benchmarks where the old design was a bit faster. The initial results are still very promising and impressive! Further work remains to be done on `cargo-fixit` to investigate how it could be optimized better and how should its interface look like before being stabilized. We thank Glen for all the hard work on this project, and we hope that one day the new design will become used by default in Cargo, to bring faster and more flexible fixing of lint suggestions to everyone! ### Prototype Cargo Plumbing Commands * Contributor: Vito Secona * Mentors: Cassaundra, Ed Page * Final report The goal of this project was to move forward our Project Goal for creating low-level ("plumbing") Cargo subcommands to make it easier to reuse parts of Cargo by other tools. Vito created a prototype of several plumbing commands in the cargo-plumbing crate. The idea was to better understand how the plumbing commands should look like, and what is needed from Cargo to implement them. Vito had to make compromises in some of these commands to not be blocked on making changes to the current Cargo Rust APIs, and he helpfully documented those blockers. For example, instead of solely relying on the manifests that the user passed in, the plumbing commands will re-read the manifests within each command, preventing callers from being able to edit them to get specific behavior out of Cargo, e.g. dropping all workspace members to allow resolving dependencies on a per-package basis. Vito did a lot of work, as he implemented seven different plumbing subcommands: * `locate-manifest` * `read-manifest` * `read-lockfile` * `lock-dependencies` * `write-lockfile` * `resolve-features` * `plan-build` As future work, we would like to deal with some unresolved questions around how to integrate these plumbing commands within Cargo itself, and extend the set of plumbing commands. We thank Vito for all his work on improving the flexibility of Cargo. ## Conclusion We would like to thank all contributors that have participated in Google Summer of Code 2025 with us! It was a blast, and we cannot wait to see which projects GSoC contributors will come up with in the next year. We would also like to thank Google for organizing the Google Summer of Code program and for allowing us to have so many projects this year. And last, but not least, we would like to thank all the Rust mentors who were tirelessly helping our contributors to complete their projects. Without you, Rust GSoC would not be possible. 1. You can read about what do those individual compiler stages mean e.g. here. ↩
18.11.2025 00:00 πŸ‘ 0 πŸ” 0 πŸ’¬ 0 πŸ“Œ 0
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 the `File::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 the `File::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!
10.11.2025 00:00 πŸ‘ 4 πŸ” 2 πŸ’¬ 0 πŸ“Œ 0
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 * `Path::file_prefix` * `AtomicPtr::fetch_ptr_add` * `AtomicPtr::fetch_ptr_sub` * `AtomicPtr::fetch_byte_add` * `AtomicPtr::fetch_byte_sub` * `AtomicPtr::fetch_or` * `AtomicPtr::fetch_and` * `AtomicPtr::fetch_xor` * `{integer}::strict_add` * `{integer}::strict_sub` * `{integer}::strict_mul` * `{integer}::strict_div` * `{integer}::strict_div_euclid` * `{integer}::strict_rem` * `{integer}::strict_rem_euclid` * `{integer}::strict_neg` * `{integer}::strict_shl` * `{integer}::strict_shr` * `{integer}::strict_pow` * `i{N}::strict_add_unsigned` * `i{N}::strict_sub_unsigned` * `i{N}::strict_abs` * `u{N}::strict_add_signed` * `u{N}::strict_sub_signed` * `PanicHookInfo::payload_as_str` * `core::iter::chain` * `u{N}::checked_signed_diff` * `core::array::repeat` * `PathBuf::add_extension` * `PathBuf::with_added_extension` * `Duration::from_mins` * `Duration::from_hours` * `impl PartialEq<str> for PathBuf` * `impl PartialEq<String> for PathBuf` * `impl PartialEq<str> for Path` * `impl PartialEq<String> for Path` * `impl PartialEq<PathBuf> for String` * `impl PartialEq<Path> for String` * `impl PartialEq<PathBuf> for str` * `impl PartialEq<Path> for str` * `Ipv4Addr::from_octets` * `Ipv6Addr::from_octets` * `Ipv6Addr::from_segments` * `impl<T> Default for Pin<Box<T>> where Box<T>: Default, T: ?Sized` * `impl<T> Default for Pin<Rc<T>> where Rc<T>: Default, T: ?Sized` * `impl<T> Default for Pin<Arc<T>> where Arc<T>: Default, T: ?Sized` * `Cell::as_array_of_cells` * `u{N}::carrying_add` * `u{N}::borrowing_sub` * `u{N}::carrying_mul` * `u{N}::carrying_mul_add` * `BTreeMap::extract_if` * `BTreeSet::extract_if` * `impl Debug for windows::ffi::EncodeWide<'_>` * `str::ceil_char_boundary` * `str::floor_char_boundary` * `impl Sum for Saturating<u{N}>` * `impl Sum<&Self> for Saturating<u{N}>` * `impl Product for Saturating<u{N}>` * `impl Product<&Self> for Saturating<u{N}>` These previously stable APIs are now stable in const contexts: * `<[T; N]>::each_ref` * `<[T; N]>::each_mut` * `OsString::new` * `PathBuf::new` * `TypeId::of` * `ptr::with_exposed_provenance` * `ptr::with_exposed_provenance_mut` ### Platform Support * Promote `aarch64-pc-windows-msvc` to Tier 1 * Promote `aarch64-pc-windows-gnullvm` and `x86_64-pc-windows-gnullvm` to Tier 2 with host tools. Note: llvm-tools and MSI installers are missing but will be added in future releases. 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!
30.10.2025 00:00 πŸ‘ 0 πŸ” 0 πŸ’¬ 0 πŸ“Œ 0
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: * We are improving compilation performance through (1) parallel compilation in the compiler front-end, which delivers 20-30% faster builds, and (2) making the Cranelift backend production-ready for development use, offering roughly 20% faster code generation compared to LLVM for debug builds. * We are working to stabilize a core MVP of the `-Zbuild-std` feature, which allows developers to rebuild the standard library from source with custom compiler flags. This unblocks critical use cases for embedded developers and low-level projects like Rust for Linux while also enabling improvements like using sanitizers with the standard library or building `std` with debug information. ### "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| | 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| | 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| | 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)
28.10.2025 00:00 πŸ‘ 1 πŸ” 0 πŸ’¬ 0 πŸ“Œ 0
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 using docs.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-darwin` target is now Tier 1, while `x86_64-apple-darwin` has moved to Tier 2. You can read more about this in RFC 3671 and 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 with `aarch64-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.
16.10.2025 00:00 πŸ‘ 0 πŸ” 0 πŸ’¬ 0 πŸ“Œ 0
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: * David Wood * Jack Huey * Niko Matsakis 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: * Jakob Degen * Santiago Pastorino * Scott McMurray 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.
15.10.2025 00:00 πŸ‘ 0 πŸ” 0 πŸ’¬ 0 πŸ“Œ 0
crates.io: Malicious crates faster_log and async_println **Updated September 24th, 2025 17:34:38 UTC** - Socket has also published their own accompanying blog post about the attack. ## 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 similar 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. ↩
24.09.2025 00:00 πŸ‘ 0 πŸ” 0 πŸ’¬ 0 πŸ“Œ 0
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 * `u{n}::checked_sub_signed` * `u{n}::overflowing_sub_signed` * `u{n}::saturating_sub_signed` * `u{n}::wrapping_sub_signed` * `impl Copy for IntErrorKind` * `impl Hash for IntErrorKind` * `impl PartialEq<&CStr> for CStr` * `impl PartialEq<CString> for CStr` * `impl PartialEq<Cow<CStr>> for CStr` * `impl PartialEq<&CStr> for CString` * `impl PartialEq<CStr> for CString` * `impl PartialEq<Cow<CStr>> for CString` * `impl PartialEq<&CStr> for Cow<CStr>` * `impl PartialEq<CStr> for Cow<CStr>` * `impl PartialEq<CString> for Cow<CStr>` These previously stable APIs are now stable in const contexts: * `<[T]>::reverse` * `f32::floor` * `f32::ceil` * `f32::trunc` * `f32::fract` * `f32::round` * `f32::round_ties_even` * `f64::floor` * `f64::ceil` * `f64::trunc` * `f64::fract` * `f64::round` * `f64::round_ties_even` ### 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!
18.09.2025 00:00 πŸ‘ 0 πŸ” 0 πŸ’¬ 0 πŸ“Œ 0
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.org and help@crates.io.
12.09.2025 00:00 πŸ‘ 0 πŸ” 0 πŸ’¬ 0 πŸ“Œ 0
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 * Important workflows * Incremental rebuilds * Type checking and IDE performance * Clean and CI builds * Debug information * Workarounds for improving build performance * Understanding why builds are slow ## 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. ↩
10.09.2025 00:00 πŸ‘ 0 πŸ” 0 πŸ’¬ 0 πŸ“Œ 0
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.
03.09.2025 00:00 πŸ‘ 0 πŸ” 0 πŸ’¬ 0 πŸ“Œ 0