The Rust Programming Language Blog [Unofficial]

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

Empowering everyone to build reliable and efficient software. 🌉 bridged from 🌐 https://blog.rust-lang.org/: https://fed.brid.gy/web/blog.rust-lang.org

Enabling the next iteration of the borrow checker on nightly

TL;DR We are enabling the next iteration of the borrow checker (coined Polonius Alpha) on nightly in preparation for stabilization in the next few months. ## Whaaaaaat? Yes! You heard it right! The next iteration of the Rust borrow checker is coming! Rust's first borrow checker ("AST borrowck") was very limited and was phased out in 2019 in favor of NLL, other than a "migrate mode" that was used to provide nice error messages. That migrate mode was finally removed in 2022. The Polonius borrow checker spun out of the NLL effort in 2018. The initial formulation passed the NLL test suite and accepted (sound) code that NLL did not. However, performance was a critically-limiting factor; generally borrow check was slower than NLL, but certain programs were considerably slower than NLL to the extent that using that implementation/formulation of Polonius was a non-starter. Attempts were made over the years to implement the Polonius formulation in a performant manner, without much luck in addressing the core issues. In 2023, a new formulation of a Polonius-style borrow checker was imagined that required minimal rearchitecture of the existing NLL implementation and could be extended to allow more code to compile. We had hoped, to try to stabilize this new formulation in 2024; but, various things popped up that delayed this. But! We're nearly there now! At this point, there are no known remaining issues with the subset coined Polonius Alpha that we intend to stabilize. And, performance is generally acceptable for stabilization (will discuss that a bit below). So, **we are enabling the Polonius Alpha borrow checker on nightly** for testing until we stabilize fully later in the year. We're doing this in order to help find: * Any serious performance regressions we're unaware of * Unsoundness in the formulation that we haven't thought about * Any weird diagnostic issues that we need to improve * Note: we have not _yet_ seen any diagnostic changes You can report any issues on Github or on Zulip. ## Okay, what's new? The key thing that Polonius Alpha enables that NLL does not is _flow-sensitive_ borrow checking of lifetime outlives relationships. Perhaps the smallest example demonstrating what will pass with Polonius Alpha but not the current NLL is: fn reborrow(a: &mut u8) -> &mut u8 { let b = &mut *a; if true { b } else { a } } However, the example you will see more often is: fn get_mut_or_default<'r, K: Hash + Eq + Copy, V: Default>( map: &'r mut HashMap<K, V>, key: K, ) -> &'r mut V { match map.get_mut(&key) { Some(value) => value, None => { map.insert(key, V::default()); map.get_mut(&key).unwrap() } } } The issue is that the `Some(value) => value` branch causes the borrow checker to think that the borrow returned by `map.get_mut(&key)` lives for the entire function (because of the `&'r mut V` return type), even though that borrow isn't live in the `None` branch. NLL's analysis is _flow-insensitive_. Polonius Alpha passes this because its analysis is _flow-sensitive_ , and it knows that the borrow isn't live in the `None` branch. Now, Polonius Alpha is not _perfect_ ; some programs that would compile under legacy Polonius (the slow original implementation) don't compile with Polonius Alpha. (This is of course why we call it "Polonius Alpha"). For example: struct X { next: Option<Box<X>> } fn conditional() { let mut b = Some(Box::new(X { next: None })); let mut p = &mut b; while let Some(now) = p { if true { p = &mut now.next; } } } (As a slight note: we have also found programs that compile with Polonius Alpha but not legacy Polonius, so it's not really a full subset.) ## So, what about performance? Polonius Alpha currently does strictly equal or more work compared to NLL, so we have been paying particular attention to potential performance regressions. From the top ten thousand crates by downloads on crates.io, we have seen relatively few "significant" regressions, and even crates that have a "significant" regression are typically _relatively_ minimal: _Each point represents a crate within the 10,000 most-downloaded crates. The black line is an arbitrary threshold of significance, set to a 1% regression and quadratically scaled below 30 seconds. Red points are crates that pass this arbitrary regression threshold. X-axis is compile time (for the leaf crate only without dependencies) under NLL; Y-axis is the ratio of compile time under Polonius Time compared to NLL._ If you look at the top five crates, they are: Outside the top ten thousand crates, we have focused mainly on crates with many borrows. The worst case we've seen is a 2-3x regression. We have done some initial triage of the causes of these regressions and are thinking about the best way to fix them. Though, overall we think these regressions are fairly reasonable even if we _can't_ fix them, given how rare and relatively minimal they are compared to the additional power Polonius Alpha brings over NLL. ## I really don't want this. How do I opt-out? To reiterate: this is only being enabled on nightly. But if you want to disable Polonius Alpha, and only use the stable NLL, you can pass `-Zpolonius=off` to `rustc`, use `RUSTFLAGS=-Zpolonius=off`, or with a project's .cargo/config.toml configuration file: [target.x86_64-unknown-linux-gnu] rustflags = ["-Zpolonius=off"] If you have to do this, for some reason, please do tell us why on Github or on Zulip. ## What's next? Over the next few months, we will be monitoring Github and Zulip for any reported issues about Polonius Alpha. We will also be working to address known performance regressions. Finally, we will be working on internal documentation about the implementation. All prior to stabilization. Then, we are aiming to stabilize prior to the end of the year! Although some programs that we _want_ to compile don't work with Polonius Alpha (nor NLL today), we don't currently have any concrete plans to continue active feature work on the Polonius implementation after the stabilization of Polonius Alpha. We expect to continue to optimize the implementation and address any performance regressions for a little while. We will likely come back to Polonius feature-work _at some point_ , but given that Polonius Alpha solves the most-encountered borrow-check issues, we are shifting our time to other high-priority work for the near future.

blog.rust-lang.org

The many journeys of learning Rust

_This is another post in our series covering what we learned through the Vision Doc process. We previously described the overall approach and what we learned about doing user research, we explored what people love about Rust, dug into what it takes to ship safety-crticial Rust, and described some of the major challenges that people face when using Rust._ In this post we walk through what folks have found on their journey to learn the Rust programming language with ups and downs covered. As a disclaimer, LLMs (Large Language Models) come up in this post because our interviewees brought them up. We're scoping discussion to their use as a learning tool, covering research and example generation, not broader questions about AI (Artificial Intelligence) in software development. # Many paths to needing Rust The interviews surfaced several different paths into Rust: curiosity, embedded work, job-market pressure, organizational adoption, and reassignment after a team or company chose Rust. That last path matters because many learners are not evaluating Rust from a blank slate; they are trying to become productive after Rust has already arrived in their work. > "Funny enough, I've advocated for more niche languages than Rust in the past. Rust has pretty much stopped being as much of a niche language as it was, but it's not Java." -- Fractional CTO # Rust learning resources Likely as expected, the folks that we talked to reach for a range of resources to learn Rust. Some reach for official documentation, such as The Rust Programming Language Book and find that sufficient to build on what the compiler was already showing them. > "I started with the official Rust documentation because there are a lot of great examples of how features like the borrow checker work." -- Software engineer at an Automotive supplier Others needed more passes and more formats, sometimes reaching for resources the community maintains, such as Rustlings, The Little Book of Rust Macros, and Learn Rust With Entirely Too Many Linked Lists. > "The first time I went through the chapter in [The Rust Programming Language] on borrow checking, I was like, what is this? I read it again, then I watched a YouTube video of someone explaining the chapter." -- Rust freelance consultant > "Rust book, Rustlings, Zero to Production in Rust, Jon Gjengset tutorials. A bunch of books. It's not a one-pass reading. Can't say how many times I've gone through it." -- Software engineer working on video streaming and storage These resources have brought up an entire generation of Rust programmers. But, to some, there is a perception that these resources have trouble keeping pace with the language. > "We'd like to use [The Rust Programming Language/'the book'], but we've found that it's out of date, unfortunately. We've looked at the GitHub repo and found it's got a lot of unresolved issues and unmerged PRs" -- Principal Software Engineering work on Rust adoption in a regulated industry Whether or not this is factually true, Rust's growth has nonetheless put more scrutiny on these materials. Companies evaluating adoption and engineers getting reassigned to Rust teams are looking at them with fresh eyes and finding the gaps that affect their own evaluation. # Beginner stumblings and unlearning habits It's pretty typical for Rust to be the 2nd, 3rd or Nth programming language that someone picks up. They'd end up writing their most familiar language in Rust, whether C++ patterns, Java patterns, or whatever they knew, for months or even years. Eventually they got comfortable enough to start writing idiomatic Rust. > "There's a bit of a drop in productivity compared to C if you're already familiar with it just because you're learning new rules, new syntax." -- Principal Firmware Engineer (mobile robotics) > "In the beginning it was more poking around the code and adding and removing some ampersands and asterisks to try to make sense of `mut` and not `mut` and whatever." -- Senior engineer with 20 years of Java experience in cloud and IoT We also spoke with someone who found that not having much of a programming background seemed to benefit people picking up Rust. Not having worn-in grooves from other languages may play a role here, and it's worth investigating further. > "I had someone who had never programmed much before start working on the internals of [our Rust project]. She was just fine with getting into Rust. It's more of the senior people that struggle as they need to unlearn practices which may work in other languages, but it's not the 'Rust' way." -- Researcher, Automotive OEM R&D Lab # Learning to work with the borrow checker We heard a lot about learning to work with the borrow checker instead of against it. People get there through different paths, but a few patterns came up repeatedly. ## The compiler as teacher Rust's diagnostics did the teaching on their own, especially around lifetimes. > "If you mess up the lifetimes in a piece of code that you've written by hand, I usually find that Rust's diagnostics are very helpful" -- Researcher working on static analysis of Rust programs > "Whatever's missing, the compiler usually fills in: it tells me 'you need to declare the lifetime of this reference', so I know and can figure it out. That all generally works pretty well." -- Senior Software Engineer ## Learning by doing Others felt like they only really internalized the borrow checker after writing a lot of Rust. It took projects, coding challenges, prototyping and so on until at some point it clicked. > "I actually did not understand the borrow checker until I spent a lot of time writing Rust" -- Founder of a startup built on Rust > "Besides the prototyping work, I also did coding-challenge-type stuff to get familiar with Rust for Advent of Code. [..] It eventually clicked to the point where I wasn't fighting with Rust, it was working for me. I had that experience other people describe: when I managed to get my program to fit with Rust, it worked. I didn't spend time debugging." -- Principal Software Engineer, large SaaS provider ## Letting go of "clone guilt" Some learners arrive with the assumption that good Rust means zero clones, zero copies, lifetimes threaded through everything. They set the bar at optimal before they've learned how to write idiomatic Rust, and it makes the borrow checker feel harder than it needs to be at the outset. > "On one of my first projects, I was like, 'I don't ever want to copy or clone anything,' so I carefully wove through all the lifetimes and got myself into a bit of a bind. Then I saw someone else just cloning the struct I was working with, and it was super cheap. Sometimes you can just clone and it's going to be okay." -- Researcher at a university The experienced Rust developers we spoke with consistently said the same thing: clone freely while you're learning, then optimize when you understand the problem. Rust's reputation for performance and correctness feeds this. Newcomers assume anything less than optimal is wrong before they've written a first working program, and clone guilt is how that shows up. We think it could be an interesting area of future study to check into the patterns Rust programmers employ at different levels of experience and under which circumstances. One member of the Rust Vision doc team that's very experienced with Rust noted that there's kind of an "expected shape" they understand as passing the compiler. This knowledge influences how they approach writing code which wouldn't take that shape and they naturally find themselves understanding when to use so-called workarounds, such as passing around indices into arrays or `Vec`s. # Multi-paradigm, but not the OOP some are used to The Rust programming language is multi-paradigm, and how that lands depends on what you're coming from. We heard some that came from a functional background were delighted with digging into learning how much Rust inherits from that lineage. Some others noted that they and others on their teams struggled to unlearn the object-oriented style they'd come to use heavily in other languages like C++ and Java. > "Developers coming from C++ tend to think object-oriented. I think that's a difference between C++ and Rust." -- Architect at Automotive OEM > "I had exactly that thing, where I would apply all my years of Java and JS thinking, where I could just create some object, not care about it, return it, have it sloshing around between various functions. Found myself reaching for these patterns and then being told 'no, you cannot do that'." -- Principal Engineer at a SaaS company Developers coming from functional programming had less to unlearn: strong typing, pattern matching, and an expression-oriented style were already familiar. > "My background has been more functional programming, strong typing. That originated for me as a Lisper: once a Lisper, always a Lisper." -- Principal Software Engineer working on Rust tooling for safety-regulated industries > "The languages I primarily used before Rust were things like OCaml. Way back, I came from C and C++, the classic languages, and then I spent quite a long time doing primarily pure functional stuff. These days I've ended up back in what I like to think of as a pragmatic center ground [with Rust]." -- Fractional CTO # Teaching Rust in academia We spoke with a university professor that's been teaching Rust generally. In the academic environment, they were able to use proxies for some things such as "traits are like interfaces in Java" because the students had already gone through a set of courses in their first and second years that taught them Java. They introduced concepts slowly throughout the course, choosing to deal with some more complex topics like generics later. The outcome generally was that students had no problem picking up Rust in this setting. > "I couldn't see any big difference on the embedded side. We also teach an embedded class, and we did an experiment. Half of the students' feedback was worse on the Rust class, mostly because they needed to build the project themselves. The C students just got one from [an LLM], absolutely no problem." -- University Professor, on teaching Rust The C cohort leaned on LLMs for the project in ways the Rust cohort couldn't. We don't yet have a clear answer for why. What did come through clearly was the Rust cohort's experience with the community. Some students needed to figure out which drivers to use for the embedded project and how to use them. Their professor encouraged them to open issues and ask questions directly on GitHub, and the maintainers responded. Students who had never contributed to open source before were getting answers from the people who wrote the code. # Learning using LLMs Some experienced folks shared that they saw LLMs as a tool that can help someone come up to speed quickly, either as a research tool or for generating example Rust code to understand concepts. > "I'm optimistic that there's a way to work [LLMs] in that will cut down that learning curve. One of the big things these tools bring is reducing the learning curve in general; these are very good tools to help you navigate a space that you don't know yet." -- Maintainer of large open source Rust crate > "I try [LLMs] out once a month, usually for generating an example or something like this. Just like with Stack Overflow: when you read an example, you should read it carefully and try to understand it. Not copy and paste it, but type it in your own words in code and then check it, because that's where the teeny tiny little mistakes are." -- Founder of startup built on Rust For some learners, an LLM is just another way to find answers, no different than a search engine. > "So for the most part, picking up Rust - how do I learn? I'll [use web search for] things, I'll ask [an LLM], I'll just poke around and read the code." -- Senior Software Engineer working in a regulated space One founder went further and claimed that LLMs change who can become a Rust developer. One consulting company founder described hiring high school graduates with no systems programming background and training them as Rust developers, with LLMs filling in the learning gaps that would previously have required years of experience. > "At the beginning, I was worried, but now that we have [LLMs] supporting development, the difficulty of the language doesn't matter. I'm seeing a huge opportunity behind strong runtime languages like Rust. [..] In [Developing Country] we hire 20-25 high school graduates, train them to be Rust programmers, then they enhance our workforce worldwide." -- Founder of a consulting company We heard this from one organization. This is a claim that the combination of Rust's compiler and LLM tooling can dramatically shorten the path from beginner to working developer. Whether it generalizes depends on questions we can't answer from a single interview: how long these developers stay, what kind of code they can maintain independently, and whether this training/learning model works outside this company's particular structure. If it holds up, the pool of people who can become Rust developers is much larger than the usual hiring profile suggests. # Organizational considerations for Rust learners We spoke with a number of folks on teams that are using Rust in larger organizations. Teams wanted to know that everyone would end up at roughly the same level of competence, which led a good number to invest in training courses to get there. Some leaders found that staff was able to ramp well enough by reading The Rust Programming Language, going through Rustlings, and then picking up lower risk and priority tickets to work on. Having a sense of community was also important within companies; it helps people know they are not alone when they are asked to work on Rust after, say, a reorganization happens. > "[..] the idea with the class as opposed to 'just read the Rust book on your own' was that this gives everyone kind of the same baseline going in." -- Principal Firmware Engineer (mobile robotics) > "So typically we're going to have people work through Rustlings, work through The Rust Programming Language. We have them then start to pick up lower risk tickets to work on." -- Principal Engineer at a large SaaS provider > "We've got an internal Slack channel for Rust learning where people can drop questions and others will come in and answer them. That helps build up understanding and community." -- Software Engineer at a large corporation Some organizations found that while the person they'd hire would need to learn Rust, it was still preferable to the alternative of hiring someone for a critical piece of software written in another language. > "They needed to grow and maintain this C++ codebase. They had a C++ wizard, and they tried for about two years to find someone with the same level of expertise. They ended up hiring people that didn't know Rust and ramping them up, creating FFI bindings from the C++ side so they could work in Rust. And you can feel it: the borrow checker is teaching these people the right way to handle their systems." -- Principal Engineer at an Automotive OEM The community and helping each other aspect seems to grow bonds as organizations mature. > "Our team is [all about] mentorship. I've mentored people coming up to speed on Rust, and people help each other hugely." -- Principal Software Engineer at a large SaaS company # Silent attrition We identified some cases where people have approached Rust and bounced off of it, for one reason or another. In the below case, someone with a background in a language with fewer guardrails found themselves frustrated enough with Rust to walk away. > "All of that means that that embedded ecosystem is very frustrating to somebody who comes from C and is like, why can't I just get a pointer to this peripheral and then write into the registers. What are you doing to me? [..] My friend never got over that. He looked at it and said, I'm not going to deal with this and walked away." -– A second University Professor There may be language features that for a particular domain are not seen as comfortable or usable yet, such as async Rust usage in a safety domain. We'd like to map which language features feel off-limits in which domains; async in safety-critical work probably isn't the only case. > "We're not fully sure how async [Rust] will work out in the long run in our domain. [..] People don't feel comfortable yet since C++14 doesn't provide such concepts. [..] It's the chicken-and-egg problem again: we probably need to gain some experience to see whether we can actually benefit from these new concepts in the automotive and safety domains." -- Team Lead at Automotive Supplier (ASIL D target) We heard in at least one case, that while the language was challenging and there was a near bounce, the tooling helped keep them coming back and trying. > "Well, I think my early impressions of Rust - one is I find C++ so intimidating, and I think a big part of why I was able to succeed at [..] learning Rust is the tooling. I mean, all this makes sense [..] but it's like, for me, getting started with Rust, the language was challenging, but the tooling was incredibly easy." -- Founder of another startup built on Rust While it might be considered more of a community concern, if there are interactions online and in spaces that point to learners having so-called "skill issues" this feeds into the narrative that Rust must be hard to learn. We may be unintentionally turning away Rust Project contributors and maintainers due to the vibes being put out when new learners show up in certain spaces. > "People are very helpful, but generally the attitude is: if your program is very complicated, it's mostly a skill issue. There's not that much empathy when people get stuck learning, and a lot of people are just pushed away by it. There's probably a huge number of people who silently stop wanting to write Rust, because at some point it gets complicated and the feedback they get is 'you just need to be a better programmer, obviously'." -- Software Engineer at a SaaS Provider ## Feedback on near-bounces from survey We found a few interesting perspectives collected in the Rust Vision doc survey which we administered with examples of bouncing and coming back: > "I started before 1.0, got stuck very soon when trying to translate patterns from C++ to Rust (due to borrow checking). I tried again after 1.0 and it stuck. [..]" -- Survey Respondent A Survey Respondent A went on to share in a more detailed response about a perceived weakness in Rust learning materials related to lifetimes and the borrow checker are explained. There was an observation that it's fairly easy to run into more complex situations with lifetimes and the borrow checker. They felt that the current state of this sort of material and tutorials is fairly superficial and can leave learners stuck when they run into those more complex situations. One respondent that bounced once and came back shared challenges around usage of async. In concert with Rust's memory-safety and the borrow checker, they found some of the nitty-gritty details of async were difficult to learn. While we're aware of the Rust Project's continuous efforts to improve Rust's async story, this is another data point of a user that faced challenges. Another survey respondent shared how they had multiple times bounced in trying to learn Rust. They returned after a year or so and found Rustlings to be highly motivating. We note that having multiple pathways for folks to learn Rust opens up more possibilities for those that nearly bounced, just like this person. ## Need more focused work on silent attritrion The thing that stood out most to us was the lack of real, first-hand knowledge of having bounced when learning Rust. While this is an obvious effect of soliciting answers to our survey and opportunities to interview through Rust channels and our networks, this cohort is good future candidate where interviews could start. # Conclusions Across these conversations, the experience of learning Rust depended heavily on context. Why someone was learning and what support they had mattered as much as the borrow checker. The same kinds of examples kept coming up: a training course that got a team to a shared baseline, a maintainer answering a student's first GitHub issue, and a colleague whose code showed that cloning was okay. That context is largely something the community has a hand in. With that in mind, here is what we take away from what we heard, and what we still don't know. ## What seems worth trying **Learning materials aimed at unlearning.** Syntax barely came up when people described their struggles. People struggled with unlearning habits from previous languages, whether OOP structuring from C++ and Java or the instinct to grab a raw pointer to a peripheral. Most of our learning materials teach Rust from first principles, and that works. What we didn't come across is much written for, say, the engineer with ten years of Java who lands on a Rust team after a reorg: material that names the patterns they'll reach for that won't transfer, and shows what to do instead. The professor we spoke with did a version of this in the classroom, leaning on "traits are like interfaces in Java" and saving generics for later in the course, and the students did fine. Something similar could work outside the classroom too. **Put the "clone freely while you're learning" advice somewhere official.** Every experienced developer we spoke with gave the same advice, but learners seem to mostly pick it up by accident, like the researcher who happened to see someone else cloning the struct they had been carefully threading lifetimes through. Saying it early in official materials would take some of the steepness out of the curve. The broader version belongs there too: idiomatic Rust doesn't have to mean optimal Rust, especially on a first project. **Diagnostics are already a primary learning resource: several people told us the compiler taught them lifetimes before any documentation did.** Diagnostics reach learners right at the moment they're stuck. When writing new ones, it seems worth keeping the confused newcomer in mind alongside the expert, because for a lot of people this is where the learning happens. **Is "the book" actually out of date?** Whether or not The Rust Programming Language or other materials are actually behind, a team evaluating Rust looked at its repository, saw unresolved issues and unmerged PRs, and moved on. As more companies evaluate adoption, more people will look at these materials with the same fresh eyes. Visible issue triage and some communication about what's current and what's planned would address the perception, separately from whatever content work may or may not be needed. **How stuck learners get treated is shaping who stays.** We heard about students getting answers on GitHub from the maintainers who wrote the code, and we heard about learners being told their struggles were a skill issue. The first group came away with a lasting good impression of Rust. Some of the second group walked away entirely, and because they leave quietly, it's easy to underestimate how many of them there are. The welcoming side of the community came up unprompted as a reason people stayed, so we know it makes a difference when we get this right. **Every organization we spoke with described essentially the same ramp-up for bringing a team to Rust.** Teams that brought groups of developers to Rust described roughly the same approach: get everyone to a shared baseline with a training course or with The Rust Programming Language and Rustlings, start people on lower-risk tickets, and give them somewhere internal to ask questions. Several organizations also found that hiring developers without Rust experience and ramping them up worked out better than continuing to search for rare expertise in another language. None of this is complicated, and teams weighing adoption don't need to invent a training program from scratch. ## What we still don't know The biggest gap is the people we didn't reach. Nearly everyone we spoke with stuck with Rust long enough to be reachable through Rust channels, so the stories of bouncing off came to us second-hand: a friend who walked away from embedded Rust, colleagues who quietly stopped after the responses they got. As we wrote in our first post, finding people who decided against Rust takes targeted outreach. If the proposed User Research team comes together, talking with learners who bounced would make a good early project, and learning is probably the area where that research would teach us the most. We also don't know what to make of LLMs as a learning tool yet. They came up as a search engine, as an example generator, and in one organization's case as something that makes training high school graduates into working Rust developers possible. We saw a classroom where the C cohort leaned on LLMs in ways the Rust cohort couldn't, and we don't have an explanation for it. All of this comes from a handful of conversations, so we treat it as a set of leads to follow up on. Given how quickly the tools are changing, it seems better to study this deliberately than to wait and see what folklore develops. The folks we spoke with showed that people do get there: with enough passes through the materials and enough code written, it eventually clicks. The opportunities above are mostly about making it work for the people who didn't pick Rust on purpose, and for the ones who would have stuck around if their early experience had gone a little differently.

blog.rust-lang.org

Launching the Rust Foundation Maintainers Fund

> If you want to financially support the development of Rust, please consider donating to the Rust Foundation Maintainers Fund. A few months ago, the Rust Foundation announced the Rust Foundation Maintainers Fund (RFMF). Since then, the Rust Project has been closely cooperating with the Rust Foundation to determine how exactly this fund will be used to support Rust maintainers. This resulted in the acceptance of RFC #3931, which established the Funding team and the Maintainer in Residence program. The primary goal of the Funding team is to ensure that maintainers who work on Rust and its toolchain will be properly supported. We will talk to Rust Project members to figure out their funding situation, meet Rust team leads to learn about their maintenance needs, approach companies to find opportunities for them to invest into Rust by supporting Rust maintainers, coordinate various funding efforts and ensure that the beneficial effects of funded maintenance are visibly promoted, with the help of the Content team. Maintainer in Residence is a new program dedicated to financially supporting existing Rust Project maintainers1. Each Maintainer in Residence will be funded to maintain one or more critical parts of Rust, such as the compiler, the standard library, Cargo, Clippy or one of many other projects that the Rust Project develops and maintains. The funded work will include activities such as performing large-scale refactorings, code reviews, unblocking new features, issue triaging, mentoring other contributors and more, and will be split between priorities guided by the teams they are supporting and priorities of their own choosing within the Project. Where applicable, Maintainers in Residence are also encouraged to propose, champion, and drive forward Rust Project Goals. The goal of this program is to provide stable and long-term funding so that maintainers can focus on important work that ensures the long-term health of Rust. The funding team will select Maintainers in Residence based on funding availability and maintenance needs within the Rust Project, and help ensure that they are successful. We expect that this will usually be a (near) full-time position, but that will depend on the nature of the work and the area of maintenance. This program extends our existing support for Rust maintainers, such as the program management program and the compiler-ops program. An important development is that we now have a centralized mechanism for gathering donations from both individuals and companies, and a dedicated team that will help direct those funds to specific maintainers. You can find more details about the funding team and the Maintainer in Residence program in the RFC. We expect to hire the first Maintainer in Residence in the upcoming months and announce it on this blog, so stay tuned! ## How to contribute funds If you are an individual who wants to help Rust succeed and thrive, you can donate to the RFMF through GitHub Sponsors2. Companies who would like to invest in better maintenance of Rust can also donate through GitHub Sponsors or they can contact the Rust Foundation directly. The important thing is that **all proceeds from this fund will be directly used to support Rust Project maintainers**. We currently expect that to happen primarily through the Maintainer in Residence program, but it can also be done in the form of smaller-scale grants or other mechanisms, as determined by the Funding team. We will figure this out on the go, as this is also quite new for us. We really appreciate each donation, however small, because with more money we can hire more maintainers to ensure that we can continue to develop Rust and that important improvements are not blocked on maintenance tasks. This is especially important at this time, where Rust is starting to get used more and more in the industry in various application areas, which increases the need for sustained maintenance. The importance of multiple funding sources is underscored by an unfortunate trend we currently observe, where key Rust maintainers are losing their funding for Rust work due to budget shifts. The Rust Foundation Maintainers Fund is designed to provide stable funding for Rust maintainers that is less dependent on sudden shifts in the job market and the IT industry. As with most things, there is no one-size-fits-all solution, so there are multiple ways to support Rust financially. The RustNL Maintainers Team recently hired several Rust Project maintainers. Previously, we wrote about how you can support specific individuals working on Rust. And there are also Rust Project Goals in search of funding. We welcome all efforts that can help support Rust Project maintainers, who often do work that is near invisible and thankless, while at the same time incredibly important and necessary, on a volunteer basis. Thank you for considering sponsoring the development and maintenance of Rust! You can find more information about funding Rust on our Funding page. 1. This program was inspired by the Developer in Residence concept used by the Python Software Foundation (PSF), with which we led several helpful discussions. Thank you, PSF! ↩ 2. Note that the fact that GitHub Sponsors is currently enabled on the `rustfoundation` GitHub organization, and not the `rust-lang` organization, is an implementation detail that might change in the future. All donations raised on this Sponsors page will be routed to the Rust Foundation Maintainers Fund and will be spent on directly supporting Rust Project maintainers. ↩

blog.rust-lang.org

Announcing Rust 1.96.0

The Rust team is happy to announce a new version of Rust, 1.96.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.96.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.96.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.96.0 stable ### New `Range*` types Many users expect `Range` and related `core::ops` types to be `Copy`, but this is not the case: they implement `Iterator` directly, and it is a footgun to implement both Iterator and Copy on the same type so this has been avoided. RFC3550 proposed a set of replacement range types that implement `IntoIterator` rather than `Iterator`, meaning they can also be `Copy`. The standard library portion of that RFC is now stable, introducing: * `core::range::Range` * `core::range::RangeFrom` * `core::range::RangeInclusive` * Associated iterators A Rust version in the near future will also add `core::range::RangeFull` and `core::range::RangeTo` as re-exports from `core::ops` (these do not implement `Iterator` and already implement `Copy`), and `core::range::legacy::*` as the new home for the current ranges. Range syntax like `0..1` still produces the legacy types for now, but will be updated to `core::range` types in a future edition. With these stabilizations, it is now possible to store slice accessors in `Copy` types without splitting `start` and `end`: use core::range::Range; #[derive(Clone, Copy)] pub struct Span(Range<usize>); impl Span { pub fn of(self, s: &str) -> &str { &s[self.0] } } The new `RangeInclusive` also makes its fields public, unlike the legacy version which avoided exposing the exhausted iterator state. This isn't a concern with the new type since it must be converted to begin iteration. Library authors should consider making use of `impl RangeBounds` in public API, which accepts both legacy and new range types. If a concrete type is needed, prefer using new ranges as this will eventually become the default. ### Assert matching patterns The new macros `assert_matches!` and `debug_assert_matches!` check that a value matches a given pattern, panicking with a `Debug` representation of the value otherwise. These are essentially the same as `assert!(matches!(..))` and `debug_assert!(matches!(..))`, but the printed value improves the possibility of diagnosing the failure. These new macros have not been added to the standard prelude, because they would collide with popular third-party crates that provide macros with the same name. Instead, they should be manually imported from `core` or `std` before use. use core::assert_matches; /// [Random Number](https://xkcd.com/221/) fn get_random_number() -> u32 { // chosen by a fair dice roll. // guaranteed to be random. 4 } fn main() { assert_matches!(get_random_number(), 1..=6); } ### Changes to WebAssembly targets WebAssembly targets no longer pass `--allow-undefined` to the linker which means that undefined symbols when linking are now a linker error instead of being converted to WebAssembly imports from the `"env"` module. This change prevents modules from linking unless all linking-related symbols are defined to catch bugs earlier and prevent accidental issues with symbol naming or similar. Undefined linking-related symbols are often indicative of build-time related bugs or misconfiguration. If, however, the old behavior is intended then it can be re-enabled with `RUSTFLAGS=-Clink-arg=--allow-undefined` or by editing the source code and using `#[link(wasm_import_module = "env")]` on the block defining the symbol. This change was previously announced on this blog, and now takes effect in Rust 1.96. ### Stabilized APIs * assert_matches! * debug_assert_matches! * From<T> for AssertUnwindSafe<T> * From<T> for LazyCell<T, F> * From<T> for LazyLock<T, F> * core::range::RangeToInclusive * core::range::RangeToInclusiveIter * core::range::RangeFrom * core::range::RangeFromIter * core::range::Range * core::range::RangeIter ### Two Cargo advisories Rust 1.96 contains fixes for two vulnerabilities for users of third-party registries. * CVE-2026-5223 is a **medium** severity vulnerability regarding extraction of crate tarballs with symlinks. * CVE-2026-5222 is a **low** severity vulnerability regarding authentication with normalized URLs. Users of crates.io are **not affected** by either vulnerability. ### Other changes Check out everything that changed in Rust, Cargo, and Clippy. ## Contributors to 1.96.0 Many people came together to create Rust 1.96.0. We couldn't have done it without all of you. Thanks!

blog.rust-lang.org

Security Advisory for Cargo (CVE-2026-5222)

The Rust Security Response Team was notified that Cargo incorrectly normalized the URLs of third-party registries using the sparse index protocol. If a hosting provider allowed multiple registries to be hosted with arbitrary names within the same domain, an attacker able to publish crates in a registry could obtain the credentials of others users of the same registry. This vulnerability is tracked as CVE-2026-5222. The severity of the vulnerability is **low** , due to the extremely niche requirements needed to achieve the attack. ## Overview Originally Cargo only supported storing a registry's index within git repositories. Most git hosting solutions allow accessing a git repository with or without the `.git` suffix, so Cargo mirrored this behavior when normalizing registry URLs. This allowed credentials for `https://example.com/index` to be used for `https://example.com/index.git`. This normalization was unintentionally applied to the new sparse indexes too. Sparse indexes can be hosted on any HTTPS server, which treat URLs ending with `.git` as different URLs than those without the suffix. If the following conditions apply: * `https://example.com/index` is a sparse index. * `https://example.com/index` allows crates to depend on crates from any other registry. * The attacker is able to publish crates on `https://example.com/index`. * The attacker is able to upload arbitrary files to `https://example.com/index.git`. ...the attacker could configure `https://example.com/index.git` to be a Cargo sparse registry requiring authentication for downloads, and with a download URL pointing to a server recording any credentials set to it. When the attacker then publishes a crate `foo` to `https://example.com/index` depending on a crate `bar` from `https://example.com/index.git`, and tricks the victim into downloading `foo`, Cargo will think the two registries share the same credential and send the victim's Cargo token to the malicious registry. ## Mitigations Rust 1.96, to be released on May 28th, 2026, will update Cargo to only strip the `.git` suffix from registry URLs using the git protocol. No mitigations are available for users of older versions of Cargo. ## Affected versions All versions of Cargo shipped between Rust 1.68 (the stabilization of sparse registries) and 1.96 are affected. ## Acknowledgements We'd like to thank Christos Papakonstantinou for reporting this to us according to the Rust security policy. We also want to thank the members of the Rust project who helped us address the vulnerability: Arlo Siemens for developing the fix; Weihang Lo, Eric Huss and Emily Albini for reviewing the fix; Emily Albini for writing this advisory; Emily Albini, Josh Stone and Manish Goregaokar for coordinating the disclosure.

blog.rust-lang.org

Project goals update — April 2026 (end of 2025H2)

The 2025H2 Project Goal period has now concluded. Over these months, the Rust Project pursued 41 Project Goals, 13 of which were designated as Flagship Goals. This post contains curated updates on our progress since the last post and the final status for each of the goals (many of which continue as part of the 2026 period). Full details for any particular goal are available in its tracking issue. Thanks to everyone who contributed! <3 ## Table of contents * Flagship: Beyond the & * Continue Experimentation with Pin Ergonomics * Design a language feature to solve Field Projections * Reborrow traits * Flagship: Flexible, fast(er) compilation * build-std * Production-ready cranelift backend * Promoting Parallel Front End * Relink don't Rebuild * Flagship: Higher-level Rust * Ergonomic ref-counting: RFC decision and preview * Stabilize cargo-script * Flagship: Unblocking dormant traits * Evolving trait hierarchies * In-place initialization * Next-generation trait solver * Stabilizable Polonius support on nightly * Other goal updates * Add a team charter for rustdoc team * Borrow checking in a-mir-formality * C++/Rust Interop Problem Space Mapping * Comprehensive niche checks for Rust * Const Generics * Continue resolving cargo-semver-checks blockers for merging into cargo * Develop the capabilities to keep the FLS up to date * Emit Retags in Codegen * Expand the Rust Reference to specify more aspects of the Rust language * Finish the libtest json output experiment * Finish the std::offload module * Getting Rust for Linux into stable Rust: compiler features * Getting Rust for Linux into stable Rust: language features * Implement Open API Namespace Support * MIR move elimination * Prototype a new set of Cargo "plumbing" commands * Prototype Cargo build analysis * reflection and comptime * Rework Cargo Build Dir Layout * Run more tests for GCC backend in the Rust's CI * Rust Stabilization of MemorySanitizer and ThreadSanitizer Support * Rust Vision Document * rustc-perf improvements * Stabilize public/private dependencies * Stabilize rustdoc doc_cfg feature * SVE and SME on AArch64 * Type System Documentation * Unsafe Fields * * * ## Flagship: Beyond the `&` ### Continue Experimentation with Pin Ergonomics * **People involved:** **Frank King** * **Champions:** compiler (Oliver Scherer), lang (TC) * **Status:** Continued 3 detailed updates available. * **Frank King** — comment from 2026-02-26 > (Just come back from the Spring Festival) > > * (locally, no PR yet): design and implement the borrow checking algorithms of `&pin` > * Reviewed Add Drop::pin_drop for pinned drops, to update the submodule `book` > * Reviewed Implement coercions between &pin (mut|const) T and &(mut) T when T: Unpin, to do some refactors according to the reviewed messages. * **Frank King** — comment from 2026-03-16 > * Merged Implement coercions between &pin (mut|const) T and &(mut) T when T: Unpin. > * Opened draft PR Implement borrowck for &pin mut|const $place. The implementation needs to be refined and self-reviewed before the community reviews. * **Frank King** — comment from 2026-04-16 > Self-reviewed Implement borrowck for &pin mut|const $place. Found that the current approach of handling pinned borrows may be incorrect, as it failed to distinguish a pinned borrow from a coercion of a normal-to-pinned reference. The latter doesn't prevent a `T: Unpin` type from being moved, but the former does, which breaks the pin coercion test. ### Design a language feature to solve Field Projections * **People involved:** **Benno Lossin** * **Champions:** lang (Tyler Mandry) * **Status:** Continued 5 detailed updates available. * **Benno Lossin** — comment from 2026-01-01 > * At the beginning of December, we set out to answer five important questions regarding the virtual places approach. We discussed four questions and arrived at answers for three. > * The first question we looked at was question 3 Canonical Projections. > * Next we looked at question 4 Non-Indirected Containers. > * As the final question we answered, we looked at question 1 Field-by-Field Projections vs One-Shot Projections. > * At the moment, we are investigating question 2 and I wrote a blog post with a potential solution that still needs feedback. > * We started a Wiki Project to consolidate our knowledge in one place. > * We implemented an algorithm to determine the type of a place expression. > * Our plan is to continue this project goal in the next goal period. * **Benno Lossin** — comment from 2026-01-25 > Earlier this month, Nadrieril Ding Xiang Fei and I held a meeting on autoref and method resolution in a world with field projections. This meeting resulted in a new page for the wiki on autoref. * **Benno Lossin** — comment from 2026-02-28 > The first pull request of the lang experiment has just been merged: rust-lang/rust#152730 > > This PR enables the use of the `field_of!` macro to obtain a unique type for each field of a struct, enum variant, tuple, or union. We call these types field representing types (FRTs). When the base type is a struct that is not `repr(packed)`, only contains `Sized` fields, this type automatically implements the `Field` trait that exposes some information about the field to the type system. The offset in bytes from the start of the struct, the type of the field and the type of the base type. > > The feature is still incomplete and highly experimental. We also want to tackle the limitations in future PRs. For the moment this is enough to give us the ability to experiment with library versions of field projections and write functions that are generic over the fields of structs. For example one can write code like this: > > #![feature(field_projections)] use std::field::{Field, field_of}; use std::ptr; fn project_ref<'a, T, F: Field<Base = T>>(r: &'a T) -> &'a F::Type { // SAFETY: the `Field` trait guarantees that this is sound. unsafe { &*ptr::from_ref(r).byte_add(F::OFFSET).cast() } } struct Struct { field: i32, other: u32, } fn main() { let s = Struct { field: 42, other: 24 }; let r = &s; let field = project_ref::<_, field_of!(Struct, field)>(r); let other = project_ref::<_, field_of!(Struct, other)>(r); println!("field: {field}"); // prints 42 println!("other: {other}"); // prints 24 } > > A very important feature of the types returned by `field_of!` is that you can implement traits for them if you own the base type. This allows anointing fields with information by extending the `Field` trait. For example, this allows encoding the property of being a structurally pinned field: > > use std::pin::Pin; unsafe trait PinnableField: Field { type StructuralRefMut<'a> where Self::Type: 'a, Self::Base: 'a; fn project_mut<'a>(base: Pin<&'a mut Self::Base>) -> Self::StructuralRefMut<'a> where Self::Type: 'a, Self::Base: 'a; } fn project_pinned<'a, T, F>(r: Pin<&'a mut T>) -> <F as PinnableField>::StructuralRefMut<'a> where F: PinnableField<Base = T>, { F::project_mut(r) } > > We can then implement this extra trait for all of the fields of our struct (and automate that with a proc-macro): > > unsafe impl PinnableField for field_of!(Struct, field) { type StructuralRefMut<'a> = &'a mut i32; fn project_mut<'a>(base: Pin<&'a mut Self::Base>) -> Self::StructuralRefMut<'a> where Self::Type: 'a, Self::Base: 'a, { let base = unsafe { Pin::into_inner_unchecked(base) }; &mut base.field } } unsafe impl PinnableField for field_of!(Struct, other) { type StructuralRefMut<'a> = Pin<&'a mut u32>; // u32 is `Unpin`, so this isn't doing anything special, but it highlights the pattern. fn project_mut<'a>(base: Pin<&'a mut Self::Base>) -> Self::StructuralRefMut<'a> where Self::Type: 'a, Self::Base: 'a, { let base = unsafe { Pin::into_inner_unchecked(base) }; unsafe { Pin::new_unchecked(&mut base.other) } } } > > Now you can safely obtain a pinned mutable reference to `other` and a normal mutable reference to `field` by calling the `project_pinned` function and supplying the correct FRT. > > (playground link) * **Benno Lossin** — comment from 2026-03-20 > ### Plan for 2026 > > We have an updated plan for this goal in 2026 consisting of three major steps: > > * `a-mir-formality`, > * Implementation, > * Experimentation. > > Some of their subtasks depend on other subtasks for other steps. You can find the details in the updated tracking issue. Here is a short rundown of each: > > **`a-mir-formality`:** we want to create a formal model of the borrow checker changes we're proposing to ensure correctness. We also want to create a document explaining our model in a more human-friendly language. To really get started with this, we're blocked on the new expression based syntax in development by Niko. > > **Implementation:** at the same time, we can start implementing more parts in the compiler. We will continue to improve FRTs, while keeping in mind that we might remove them if they end up being unnecessary. They still pose for a useful feature, but they might be orthogonal to field projections. We plan to make small and incremental changes, starting with library additions. We also want to begin exploring potential desugarings, for which we will add some manual and low level macros. When we have that figured out, we can fast-track syntax changes. When we have a sufficiently mature formal model of the borrow checker integration, we will port it to the compiler. After further evaluation, we can think about removing the `incomplete_feature` flag. > > **Experimentation:** after each compiler or standard library change, we look to several projects to stress-test our ideas in real code. I will take care of experimentation in the Linux kernel, while Tyler Mandry will be taking a look at testing field projections with `crubit`. Josh Triplett also has expressed eagerness of introducing them in the standard library; I will coordinate with him and the rest of t-libs-api to experiment there. * **Benno Lossin** — comment from 2026-04-02 > Yesterday, we held a t-lang design meeting on our current approach. Nadrieril and I authored a design document with the feedback of Tyler Mandry, Ding Xiang Fei, Alice Ryhl, and Gary Guo. In this document, we provided the motivation for this feature, what the look and feel of a solution fitting into the existing features of Rust is, and a comprehensive + compact introduction to our current approach based on virtual places. > > The general reception was extremely positive. To give some concrete quotes from the meeting: > > * Josh: > >> I adore this! I love how orthogonal it is, and how impactful and universal it is. I anticipate this becoming a beloved, _pervasive_ feature of Rust. >> >> Places and projection seem important enough to me that they're worth giving one of our precious remaining ASCII sigils to, and `@` is nicely evocative of a place (something is _at_ a place). So to the extent the final syntax benefits from a sigil, :+1: for giving this `@`. (See some feedback below on the details, though.) > > * TC: > >> Love it. High concept. As I said in the last meeting: >> >>> I particularly like language features that reduce the need for library surface area, and this is one of those. >> >> There are, of course, many details to resolve and understand further, e.g., with respect to migration issues, interaction with `const`, `async`, and other effect-like things, etc. I'm looking forward to seeing the formalization work. > > * tmandry: > >> What I love about this direction is how effectively it builds on what Rust already has. I love to see designs that reinforce our existing concepts while pushing them in directions that make them more expressive. > > * Jack: > >> Whoo boy. This is great. There's so much here that I'm not exactly sure where to begin and what to comment on. I think this is the type of thing that we will only _really_ be able to figure out the nitty gritty details and ergonomics only after some amount of experimentation. > > There are a few takeaways from this meeting: > > * Mark raised the concern that t-libs should be more involved in reviewing the experimental traits that we intend to add. Ensuring that we don't accidentally stabilize or expose some behavior, have sufficient documentation on our experimental traits, and that t-libs is in the loop of this feature in general. > * Mark offered to review PRs and I will be tagging him in those. > * Jack raised the concern that increasing the cognitive load for the 95% use-case should be avoided. Making the right choice between `@` and `&` might be challenging for users. > * We discussed this point more in the meeting and concluded with that we need to do some experimentation, possibly utilizing the user research team. We will of course keep this in mind and revisit it later when we have a partially working implementation. > * TC requested that we publish our fine-grained design axioms, essentially the list of things we go through when considering a modification of our proposal. > * I will write an update on this issue explaining exactly those. > > Aside from the concerns and directly actionable items, the meeting also covered design questions/comments that we want to take a look at in the coming weeks/months: > > * Can we support reads/writes of different types? > * Can we support re-assembly of wrapper types, so going from Cell<[T]> to [Cell<T>]? > * The PlaceDiscriminant trait needs to be carefully designed > * How do we handle naming conflicts & ensure SemVer evolution of library types implementing our traits? > * Can we support projecting through Option, so e.g. &Option<Struct> to Option<&Field>? > * Can we support a pointer that carries alignment information & which is updated on projections? > * What compatibility with effects do we need or want to support? > * What doors on future ergonomic improvements of pointers are we closing by having field projections? > > Thanks to everyone who participated in the meeting! ### Reborrow traits * **People involved:** **Aapo Alasuutari** * **Champions:** compiler (Oliver Scherer), lang (Tyler Mandry) * **Status:** Continued 1 detailed update available. * **Aapo Alasuutari** — comment from 2026-02-28 > PR open to get the first working version of the `Reborrow` and `CoerceShared` traits merged. > > ### Blockers > > Currently "blocked" on PR review, and of course my (and Ding's) work to fix all review issues. > > The review has brought up an opportunity to replace `Rvalue::Ref` / `ExprKind::Ref` with a more generalised variant that could encompass both references and user-defined references. This would be powerful, but it would be a very big and scary change. If this turns out to be a blocking issue for reviewers, then this will block the goal for the foreseeable future as the PR then starts on a massive refactoring. > > ### Help wanted > > The PR currently does not include derive traits, but we'd really want them. Instead of these: > > impl<'a> Reborrow for CustomMarker<'a> {} impl<'a> CoerceShared<CustomMarkerRef<'a>> for CustomMarker<a'> {} impl<'a, T> Reborrow for CustomMut<'a, T> {} impl<'a, T> CoerceShared<CustomRef<'a, T>> for CustomMut<'a, T> {} > > we'd prefer to have something like this: > > #[derive(Reborrow, CoerceShared(CustomMarkerRef))] struct CustomMarker<'a> { ... } #[derive(Reborrow, CoerceShared(CustomRef))] struct CustomMut<'a, T> { ... } > > If anyone feels like picking up this thread, that'd be awesome: the derive macros do not need to really perform any validity checking, as the trait itself will do that. > > If the PR merges soon, then public testing and exploration of the traits will be the next big thing. Likely concurrently with that the massive refactoring to generalise `Rvalue::Ref` / `ExprKind::Ref`. ## Flagship: Flexible, fast(er) compilation ### build-std * **People involved:** **David Wood** , Adam Gemmell * **Champions:** cargo (Eric Huss), compiler (David Wood), libs (Amanieu d'Antras) * **Status:** Continued 4 detailed updates available. * **David Wood** — comment from 2026-01-15 > rust-lang/rfcs#3873 has been merged and an FCP has been started on rust-lang/rfcs#3874 and rust-lang/rfcs#3875 - those both have some feedback for me to respond to that I'll get to as soon as I can. * **David Wood** — comment from 2026-02-17 > No major updates this cycle - we're still working through feedback on rust-lang/rfcs#3874 and rust-lang/rfcs#3875 and prototyping the implementation to be prepared. * **David Wood** — comment from 2026-03-17 > Update this cycle is the same as last time - rust-lang/rfcs#3874 and rust-lang/rfcs#3875 are progressing, with feedback being addressed and checkboxes checked, and we're still working out what the implementation would look like. * **David Wood** — comment from 2026-04-14 > rust-lang/rfcs#3874 has finished FCP and is due to be merged any day now. I'm working on resolving the remaining open comments on rust-lang/rfcs#3875 and then intend to nudge the reviewers to have a look and check their boxes or leave concerns. > > Adam Gemmell has opened rust-lang/cargo#16675 with an early sketch of some of the core changes that build-std would require and is working with the Cargo team to address feedback and work out how to proceed with the implementation. ### Production-ready cranelift backend * **People involved:** **Folkert de Vries** , bjorn3, Trifecta Tech Foundation * **Champions:** compiler (bjorn3) * **Status:** Not completed (lack of funding) ### Promoting Parallel Front End * **People involved:** **Sparrow Li** * **Status:** Continued ### Relink don't Rebuild * **People involved:** **Jane Lusby** , @dropbear32, @osiewicz * **Champions:** cargo (Weihang Lo), compiler (Oliver Scherer) * **Status:** Not completed (note) ## Flagship: Higher-level Rust ### Ergonomic ref-counting: RFC decision and preview * **People involved:** **Niko Matsakis** , Santiago Pastorino * **Champions:** compiler (Santiago Pastorino), lang (Niko Matsakis) * **Status:** Continued ### Stabilize cargo-script * **People involved:** **Ed Page** * **Champions:** cargo (Ed Page), lang (Josh Triplett), lang-docs (Josh Triplett) * **Status:** Continued 3 detailed updates available. * **Ed Page** — comment from 2026-01-14 > #146377 has been decided and merged. > > ### Blockers > > * T-lang discussing CR / text direction feedback: comment > * T-rustdoc deciding on and implementing how they want frontmatter handled in doctests * **Ed Page** — comment from 2026-02-13 > * FCP has ended on frontmatter support, just awaiting merge > * Cargo script has entered FCP > > ### Blockers > > * Potential issues around edition, see Cargo script edition policy (lang/edition aspects). * **Ed Page** — comment from 2026-03-16 > Cargo's FCP has ended. > > ### Blockers > > * Cargo script edition policy (lang/edition aspects) ## Flagship: Unblocking dormant traits ### Evolving trait hierarchies * **People involved:** **Taylor Cramer** and others * **Champions:** lang (Taylor Cramer), types (Oliver Scherer) * **Status:** Superseded by the Implement Supertrait auto impl and Arbitrary Self Types 2026 goals ### In-place initialization * **People involved:** **Alice Ryhl** , Benno Lossin, Michael Goulet, Taylor Cramer, Josh Triplett, Gary Guo, Yoshua Wuyts * **Champions:** lang (Taylor Cramer) * **Status:** Continued 1 detailed update available. * **Alice Ryhl** — comment from 2026-01-31 > A proposal to continue this goal in the next goal period was merged. ### Next-generation trait solver * **People involved:** **lcnr** , Boxy, Michael Goulet * **Champions:** types (lcnr) * **Status:** Continued 1 detailed update available. * **lcnr** — comment from 2026-01-19 > There hasn't been too much progress over the last few weeks and I've been mostly taking a Christmas break. Nicholas Nethercote has been looking into the performance of the new trait solver, cleaning up canonicalization and slightly improving its performance: PR 1 and PR 2. > > Shoyu Vanilla looked into ICE from mir validation on unsizing in opendal and uncovered the underlying bug there. While this issue also affects the old solver and the proper fix for it requires where-bounds on binders, we can work around this bug in the trait solver for now and intend to do so. > > We've started another crater run with all our recent changes and adwin has started to triage it, uncovering one new issue up until now. Intend to continue going through that over the next few weeks. > > There's also a lot in-progress work going on. I am collaborating with Niko Matsakis to specify and later RFC the cycle semantics of Rust. León Orell Valerian Liehr is working on a replacement for the rustdoc's auto trait impl synthesis. tiif is working on a fix a MIR borrowck unsoundness. Shoyu Vanilla and I are improving the way we propagate inference constraints from the expected return type to function arguments, fixing this issue. ### Stabilizable Polonius support on nightly * **People involved:** **Rémy Rakic** , Amanda Stjerna, Niko Matsakis * **Champions:** types (Jack Huey) * **Status:** Continued 2 detailed updates available. * **Rémy Rakic** — comment from 2026-01-30 > This month's update: > > * tiif is making progress on normalizing opaques while computing implied bounds > * we discussed how to investigate and fix the remaining correctness issues in Tage's work, to be able to evaluate it more accurately: in particular around variance and bidirectional edges, and without the reliance on NLL (having computed region values / errors) > * we've tried to see if it'd be possible to remove the cfg region elements > * Amanda is still working on her two papers, one about the current borrow checker and one about the work on Polonius. Her major PR for the restructuring of placeholder handling during region inference is stalled due to a conflict with further trait solver developments and may have to be abandoned. Work with the larger types team is ongoing and smaller patches/refactorings/improvements are being landed in the meantime. > * #149639 has now landed, and #150551 is still in review > * I've also fixed more small inefficiencies (computing boring/relevant locals on-demand in diagnostics, removed conversions between locations and points, etc) building on top of the previous PRs (so they need to be reviewed first) > * I've looked at crates.io again with the alpha, to find functions that are slower than with NLLs. AFAICT the worst case there is 60% for a 5KLOC function with 42K loans, 255K statements, and 125K outlives constraints. I'll see what we can do with this. Small composable functions is still good advice. > * there seem to be optimization opportunities to 1. limit propagation to the smaller number of blocks that could be affected by bidirectional edges, 2. for unifying invariant lifetimes of live locals that are assigned at most once (à la use-def chains), 3. for invalidations that are just the activation of a reservation > * we discussed possible plans to gather actual statistics, using the infrastructure that was created for the Metrics project > * we're also preparing the new project goal for this year, where we'll want to stabilize the alpha 🤞 * **Rémy Rakic** — comment from 2026-02-28 > We had a bit less time this month, the update will be shorter, but still meaningful I hope: > > * #150551 has landed, and it feels stabilizable. To me, this part of the goal is achieved. > * still, "stabilizable" is not _stable_ , and there is more work to do. We plan to stabilize this year, and the project goal proposal for 2026 tracks how. > * tiif is still deep in #152051, and `a-mir-formality` work with Niko and I. > * Amanda has opened a few cleanup PRs (#152438, and #152579), and #151863 has landed already. She also has started looking into Tage's old PR to see if we can fix it, benchmark it more accurately, and see the cool parts there that we could be using. > * Jack is possibly going to have some time to work with us this year! His help will be very welcome, especially as I will have less time available myself. > * we'll be tracking the opaque type region liveness soundness issue in #153215, and I've added a couple tests, in case tiif's PR or anything that impacts them lands. > * some of the tiny cleanups I mentioned last time have also landed in #152587. ## Other goal updates ### Add a team charter for rustdoc team * **People involved:** **Guillaume Gomez** * **Champions:** rustdoc (Guillaume Gomez) * **Status:** Completed ### Borrow checking in a-mir-formality * **People involved:** **Niko Matsakis** , tiif * **Champions:** types (Niko Matsakis) * **Status:** Continued ### C++/Rust Interop Problem Space Mapping * **People involved:** **Joel Marcey** * **Champions:** compiler (Oliver Scherer), lang (Tyler Mandry), libs (David Tolnay) * **Status:** Continued 5 detailed updates available. * **Joel Marcey** — comment from 2026-01-20 > The Rust Foundation is opening up a short-term, approximately 3-month, contracting role to assist in our Rust/C++ Interop initiative. The primary work and deliverables for the role will be to make substantial progress on the Problem Space Mapping Rust Project Goal by collecting discrete problem statements and offering up recommendations on the work that should follow based upon the problems that you found. > > If you are interested in how programming languages interoperate, are curious in understanding the problems therein, and are have a passion to think about how those problems may be resolved for the betterment of interop, then this work may be for you. > > An ideal candidate will have experience with Rust programming. Having experience in C++ is strongly preferred as well. If you have direct experience with actual engineering that required interoperating between Rust and C++ codebases, that's even better. > > If you are interested, please email me (email address found in my GitHub profile) or contact me directly on Zulip by Tuesday, January 27 and we can take it from there to see if there may be a potential fit for further discussion. > > Thank you. * **Joel Marcey** — comment from 2026-01-31 > The effort to fill the contracting role to support this project goal is in the process winding down. The interview and discussion process is nearly complete. We expect to make a final decision for the role in early February. * **teor** — comment from 2026-02-27 > Hi, I'm the new contractor on the interop problem space mapping project goal. > > In the last week and a half, I've: > > * added some draft high-level problem statement summaries > * started mapping out interop use cases > * added relationships between problems/use cases and existing project goals & unstable compiler features > > Next step is prioritising a few of the use cases, then working on related problem statements in more detail. > > ### Blockers > > Nothing at the moment, still working through the high level mapping of the problem space. > > ### Help wanted > > Suggestions for more interop use cases would be very welcome, just open a discussion in t-lang/interop and I'll turn it into a ticket. Or go ahead and open a use case ticket directly. > > I'll post an update here every few weeks, you can follow more detailed weekly updates on Zulip. * **teor** — comment from 2026-03-30 > In the last month, I've: > > * met with the lang team, Crubit team, and `cxx` author, and Joel and Mara have met with the C++ standards working group > * expanded some draft high-level problem statement summaries, and added code examples > * added 6 new interop use cases > * added more relationships between problems/use cases and existing project goals & unstable compiler features > * prepared for the Rust All Hands, and started mentoring for Outreachy > > Specifically, the last month we've identified and prioritised two high-priority use cases for more detailed work: > > * calling an overloaded C++ function from Rust, with a Rust lang experiment - implementation discussion > * adding Rust to an existing C++ build system, this currently works for basic cases, but the tooling could be improved on the Rust side > > And I analysed the problems / use cases we've collected so far, with priorities, responsible language, and a split into semantics or tooling changes. > > Next step is continuing to work on overloading and build systems in more detail. If you have specific Rust/C/C++ build system blockers, please open a chat or ticket. > > ### Blockers > > Nothing at the moment, everyone has been extremely helpful, and I'm getting good feedback on use cases, problems, priorities, and Rust language experiments. * **teor** — comment from 2026-05-01 > In the last month, I've: > > * prepared for RustWeek and the All Hands, where I will be giving a Rust Project track talk and running an All Hands interop session (schedule TBC) > * added new interop use cases and problem statements, and continued categorising them using GitHub tags > * continued to expand the draft high-level problem statement summaries > * added interop code examples, including many examples from Outreachy applicants > * continued mentoring Outreachy applicants > * continued working on the Overloading Rust language experiment > > Specifically, the last month we've made detailed progress on two high-priority use cases: > > * calling an overloaded C++ function from Rust, with a Rust lang experiment - implementation discussion > * we've merged a refactor to prepare for this experiment, which gave some nice perf wins > * the initial overloading experiment PR has been through two rounds of review, and is waiting for my revisions and rebasing > * adding Rust to an existing C++ build system > * Outreachy applicants wrote interop example code PRs > * these interop user experiences are waiting for analysis, so they can be summarised in the build system and overloading problem statements > * this will likely happen after RustWeek and the All Hands > > Next step is continuing to work on the overloading experiment, along with RustWeek/All Hands preparation, and collecting feedback during the conference. > > ### Blockers > > Nothing at the moment. There is a steady stream of new use cases, problems, code examples and Rust language experiment feedback. ### Comprehensive niche checks for Rust * **People involved:** **Bastian Kersting** , Jakob Koschel * **Champions:** compiler (Ben Kimock), opsem (Ben Kimock) * **Status:** Not completed ### Const Generics * **People involved:** **Boxy** , Noah Lev * **Champions:** lang (Niko Matsakis) * **Status:** Continued 6 detailed updates available. * **Niko Matsakis** — comment from 2026-01-27 > Boxy and I have established a regular time to check-in on formalizing this within a-mir-formality. Today we mostly worked on the "model" of const values, starting with this > > #[term] pub enum ConstData { // Sort of equivalent to `ValTreeKind::Branch` #[cast] RigidValue(RigidConstData), // Sort of equivalent to `ValTreeKind::Leaf` #[cast] Scalar(ScalarValue), #[variable(ParameterKind::Const)] Variable(Variable), } #[term] pub enum ScalarValue { #[grammar(u8($v0))] U8(u8), #[grammar(u16($v0))] U16(u16), #[grammar(u32($v0))] U32(u32), #[grammar(u64($v0))] U64(u64), #[grammar(i8($v0))] I8(i8), #[grammar(i16($v0))] I16(i16), #[grammar(i32($v0))] I32(i32), #[grammar(i64($v0))] I64(i64), #[grammar($v0)] Bool(bool), #[grammar(usize($v0))] Usize(usize), #[grammar(isize($v0))] Isize(isize), } #[term($name $<parameters> { $,values })] pub struct RigidConstData { pub name: RigidName, pub parameters: Parameters, pub values: Vec<Const>, } > > i.e., a const value can be a scalar value (as today) or a struct literal like `Foo { ... }` (which would also cover tuples and things). We got the various tests passing. Huzzah! * **Boxy** — comment from 2026-01-30 > In addition to what niko posted previously there's been a lot of other stuff happening. A lot of people have opened PRs to improve mGCA this month: León Orell Valerian Liehr Noah Lev @enthropy7 Kivooeo mu001999 @Human9000-bit Redddy @Keith-Cancel @AprilNEA > > A rough list of things that have been improved for mGCA: > > * Lots of new expressions now supported by mGCA: const constructors, tuple constructor calls, array expressions, tuple expression, literals > * `associated_const_equality` has been merged into `min_generic_const_args`. the former was effectively dependent on the latter already so this just makes it nicer to use the former :) > * traits can now be dyn compatible if all associated constants are type consts and are specified in the trait object (e.g. `dyn Trait<ASSOC = 10>`) > * type consts are enforced to be non-generic > * a bunch of ICEs have been fixed > * camelid has been working on "non-min" version of mGCA which will allow arbitrary expressions to be used in the type system (a blog post with more detail will be published once this actually lands) > > In non-mGCA updates, as niko says, we've been meeting regularly to make progress on modelling const generics in a-mir-formality. I've also been spending time thinking about the interactions between `adt_const_params` and ADTs with privacy/safety invariants and I think I know how to structure the RFC in this area so can make progress on that again > > There's some more detail about the various bits of work people have done and who did what here: #project-const-generics > perfectly adequately sized wins @ 💬 * **Niko Matsakis** — comment from 2026-02-13 > Boxy and I have met (and continue to meet) and work on modeling const generics in a-mir-formality. We're still working on laying the groundwork. > > There is a proposed project goal for next year. * **Boxy** — comment from 2026-02-28 > There's been a lot of miscellaneous fixes for mGCA this month. I've also started drafting some blog posts to explain what's going on with mGCA/oGCA as well as soliciting use cases/experience reports for them and `adt_const_params`. I also talked with some folks at Rust Nation this month about const generics and what features would be useful for them and why. * **Boxy** — comment from 2026-04-02 > Late on the update :') niko and i continue to meet to discuss const generics. we've made some progress on figuring out problems around privacy/safety in const generics. we've also been discussing the big picture stuff for const generics and where we're "heading". * **Boxy** — comment from 2026-05-01 > started running weekly meetings about const generics to make it easier to keep up to date with all the people who are working on const generics stuff. i think `min_adt_const_params` is now at the point of what the RFC is going to specify. > > GCA is making good progress thanks to ashley's work. i also met with lcnr where we talked about whether there was some version of mGCA that is stabilizeable in the near future or not (maybe!) ### Continue resolving cargo-semver-checks blockers for merging into cargo * **People involved:** **Predrag Gruevski** * **Champions:** cargo (Ed Page), rustdoc (Alona Enraght-Moony) * **Status:** Continued 1 detailed update available. * **Predrag Gruevski** — comment from 2026-01-17 > I posted a "year in review" for cargo-semver-checks. > > It has a section on how I think we should move forward in 2026 and beyond. ### Develop the capabilities to keep the FLS up to date * **People involved:** **Pete LeVasseur** , `t-spec`, and contributors from Ferrous Systems * **Champions:** bootstrap (Jakub Beránek), lang (Niko Matsakis), spec (Pete LeVasseur) * **Status:** Superseded by the Stabilize FLS Release Cadence 2026 goal 2 detailed updates available. * **Pete LeVasseur** — comment from 2026-03-04 > We have a Project Goal in 2026 that we'll take on: Stabilize FLS Release Cadence. Progress towards 1.93.1 looks good, most issues are closed. > > ### 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. * **Pete LeVasseur** — comment from 2026-04-02 > Trying to prepare FLS releases earlier: > > * since we completed the 1.94.0 release of the FLS a bit early this time, we checked into the stretch part of our goal this year to look at 1.95.0 early > * we learned a bit more of the release notes process thanks to tips from Eric Huss and TC > * Tshepang Mbambo and I attended the t-release meeting last week where we chatted about working a little "upstream" with them on generating the release notes a bit earlier > * tomorrow in our t-fls meeting we'll discuss our interest with engaging over there; at a minimum I'll get engaged with t-release > > Glossary and main-body text harmonization: > > * the first PR landed from Tshepang Mbambo removing IDs from the glossary > * further steps planned, we have a tracking issue for it > > Developer guide: > > * akin to how the Reference now has a developer's guide now for contributing we'll do the same in the FLS > * Hristian Kirtchev has been working on this ### Emit Retags in Codegen * **People involved:** **Ian McCormack** * **Champions:** compiler (Ralf Jung), opsem (Ralf Jung) * **Status:** Superseded by the BorrowSanitizer 2026 goal 4 detailed updates available. * **Ian McCormack** — comment from 2026-01-09 > Here's our January status update! > > * Yesterday, we posted an MCP for our retag intrinsics. While that's in progress, we'll start adapting our current prototype to remove our dependence on MIR-level retags. Once that's finished, we'll be ready to submit a PR. > * We published our first monthly blog post about BorrowSanitizer. > * Our overall goal for 2026 is to transition from a research prototype to a functional tool. Three key features have yet to be implemented: garbage collection, error reporting, and support for atomic memory accesses. Once these are complete, we'll be able to start testing real-world libraries and auditing our results against Miri. * **Ian McCormack** — comment from 2026-02-24 > We just posted our February status update for BorrowSanitizer. TL;DR: > > * We provide detailed error messages for aliasing violations, which look _almost_ like Miri's do! > * We have two forms of retag intrinsic: `__rust_retag_mem` and `__rust_retag_reg`. We no longer require a compiler plugin to determine the permission associated with a retag, which will make it possible to use BorrowSanitizer by providing a single `-Zsanitizer=borrow` flag to rustc. You can check out our MCP for more detailed design updates. > * We are starting to have a better understanding of how BorrowSanitizer performs in practice, but we do not have enough data yet to be certain. From one test case, it seems like we are somewhat faster but still in the same category of performance as Miri when we compare against other sanitizers. Expect more detailed results to come as we scale up our benchmarking pipeline. > * We have a tentative plan for upstreaming BorrowSanitizer in 2026, starting with its LLVM components. We intend to start the RFC process on the LLVM side this spring, once our API is stable. * **Ian McCormack** — comment from 2026-03-30 > We just posted our March status update for BorrowSanitizer. TL;DR: > > * We added hundreds more relevant tests from Miri's test suite. At the moment, 80% pass. > * We improved our cargo plugin (`cargo-bsan`) to better support multilanguage libraries. This will let us start to recreate the bugs from our earlier evaluation. > > Our goal for April is to continue expanding our test suite, finish an initial version of the LLVM components of BorrowSanitizer, and hopefully start the RFC process on the LLVM side. * **Ian McCormack** — comment from 2026-04-29 > We have some exciting news: our talk on BorrowSanitizer was accepted at RustConf this year! We’re grateful for the opportunity and looking forward to sharing our results with the broader community this September. > > We just posted our April status update. It’s a bit of a technical one. Here’s the TL;DR: > > * BorrowSanitizer now uses a shadow stack to track metadata at runtime - this is a significantly different strategy than other LLVM sanitizers, and it will help us support garbage collection. > * We are now ready to start sending in PRs for our retag intrinsics. It will take a little time to split our changes up into meaningful, reviewable chunks—you can expect to see these throughout the next week. > > The RFC for our LLVM components is taking a little longer than expected, but it was worth taking the extra time to test out compiler changes and make sure that we had the core parts of the instrumentation pass settled. We’ll be drafting the RFC throughout the next few weeks. ### Expand the Rust Reference to specify more aspects of the Rust language * **People involved:** **Josh Triplett** , Amanieu d'Antras, Guillaume Gomez, Jack Huey, lcnr, Mara Bos, Vadim Petrochenkov, Jane Lusby * **Champions:** lang-docs (Josh Triplett), spec (Josh Triplett) * **Status:** Superseded by the Experimental language specification 2026 goal 1 detailed update available. * **Josh Triplett** — comment from 2026-04-14 > This work is now continuing into a new goal by Jack Huey. ### Finish the libtest json output experiment * **People involved:** **Ed Page** * **Champions:** cargo (Ed Page) * **Status:** Continued ### Finish the std::offload module * **People involved:** **Manuel Drehwald** , LLVM offload/GPU contributors * **Champions:** compiler (Manuel Drehwald), lang (TC) * **Status:** Superseded by the High-Level ML optimizations 2026 goal 2 detailed updates available. * **Manuel Drehwald** — comment from 2026-01-16 > `std::autodiff` is moving closer to nightly, and `std::offload` is gaining various performance, feature, and hardware support improvements. > > #### autodiff > > Jakub Beránek, sgasho, and I continued working on enabling autodiff in nightly. We have a PR up that builds autodiff in CI, and verified that the artifacts can be installed and work on Linux. For apple however, we noticed that any autodiff usage hangs. After some investigation, it turns out that we ended up embedding two LLVM copies, one in rustc, and one in Enzyme. It should be comparably easy to get rid of the second one. Once we verified that this fixes the build, we'll merge the PR to enable autodiff on both targets in nightly. > > #### offload > > A lot of interesting updates on the performance, feature, and hardware support side. > > 1. Marcelo Domínguez, @kevinsala, @jdoerfert, and I started implementing the first benchmarks, since that's generally the best way to find missing features or performance issues. We were positively surprised by how good the out-of-the-box performance was. We will implement a few more benchmarks and post the results once we have verified them. We also implemented multiple PRs which implement bugfixes, cleanups, and needed features like support for scalars. We also started working on LLVM optimizations which make sure that we can achieve even better performance. > 2. I noticed that our offload intrinsic allowed running Rust code on the GPU, but it wasn't of much help when calling gpu vendor libraries like cuBLAS. I implemented a new helper intrinsic which allows calling those functions conveniently, without having to manually move data to or from the device. It will benefit from the same LLVM optimizations as our full offload intrinsic. It also a bit simpler to set up on the compiler and linker side, so it already works with `std` and mangled kernel names, something that we still have to improve for our main offload intrinsic. > 3. A lot of work happened on the LLVM offload side for SPIRV and Intel GPU support. At the moment, our Rust frontend is tested on NVIDIA and AMD server and consumer GPUs, as well as AMD HPC and Lapotop APUs. Karol Zwolak reached out since he wants to help with with also running Rust on Intel GPUs. Offload relies on LLVM which started gaining Intel support, so hopefully we won't need much work beyond a new intel-gpu target and a new stdarch module. There is also work on a new spirv target for rustc, which we could also support if it goes through LLVM. Due to some open questions around typed pointers it does not seem clear yet whether it will, so we will have to wait. > 4. Nikita started working on updating our submodule to LLVM 22. This hopefully does not only brings some compile and runtime performance improvements, but also greatly simplifies how we can build and use offload. Once it landed I'll refactor our bootstrapping logic, and as part of that start building offload in CI. * **Manuel Drehwald** — comment from 2026-04-01 > `std::autodiff` is now partly in CI, and `std::offload` got tested on a lot more benchmarks. > > #### autodiff > > Work continued on enabling autodiff in nightly. Since the last update, we have enabled autodiff in some Mingw and Linux runners. Users can now download libEnzyme artifacts, place them locally in the right spot for their toolchain, and then use autodiff on their nightly compiler. Once macOS is added, we will enable a new rustup component that will handle the download for users. Before enabling autodiff on macOS, however, we want to change how we distribute LLVM on this target (from static to dynamic linking). There are a lot of workflows and users of this target, not all of which can be modelled in the Rust CI. Our last two attempts sadly broke such downstream users and local contributors, so both attempts had to be reverted. Since testing here is tricky, progress here might be on the slower side; we will see. > > #### offload > > Most of the work on the offload side lately has been invisible, since we were working on implementing more benchmarks and LLVM optimizations, as well as missing features, discovered by those benchmarks. We achieved excellent performance on those benchmarks; more details will soon be presented by Marcelo Domínguez at the EuroLLVM conference in two weeks! > > Beyond benchmarks, there was a lot of tinkering on smaller PRs, reviewing, and housekeeping. LLVM-22 landed, so we updated our bootrstrap code to make use of new APIs, and tried to move a few smaller PRs forward, mainly around a better user experience and for making more Rust features available. Since the focus is still on benchmarks, not many of those PRs landed. They are in a mostly ready state, so it's a good time to pick them up if you're considering contributing. Please ping me on Zulip or in any PR with the offload label if you are interested! ### Getting Rust for Linux into stable Rust: compiler features * **People involved:** **Tomas Sedovic** , compiler contributors * **Champions:** compiler (Wesley Wiser) * **Status:** Continued 4 detailed updates available. * **Tomas Sedovic** — comment from 2026-01-16 > Update from the 2026-01-14 meeting: > > #### `#![register_tool]` rust#66079 > > Tyler Mandry proposed FCP of the RFC#3808 and nominated it for a Lang discussion. > > #### `-Zdebuginfo-compression` rust#120953 > > Wesley Wiser proposed stabilization: rust#150625. > > Josh Triplett suggested trying to bring zlib-rs in the kernel as a case study. > > #### `-Zdirect-access-external-data` rust#127488 > > rust#150494 was merged two days ago, what reminds is updating the documentation and stabilizing the feature. > > There's an ongoing discussion about the feature on the Rust Zulip as well. * **Tomas Sedovic** — comment from 2026-02-17 > Updates from the 2026-01-28 and 2026-02-11 meetings: > > #### -Zdirect-access-external-data rust#127488 > > Gary Guo's fix PR was merged. > > #### `--emit=noreturn` > > Miguel Ojeda reiterated that this is high on the list of compiler features the project needs. Right now, they're doing these checks manually. > > Improving objtool's handling of noreturn is on Gary Guo's radar but there wasn't time yet. * **Tomas Sedovic** — comment from 2026-03-16 > Update from the 2026-03-11 meeting: > > #### `--emit=noreturn` > > It seems that figuring out which functions are `noreturn` is at a level too low for rustc. Function signatures are not sufficient and there are cases where rustc doesn't know whether to emit `noreturn`. It is something we should ask the LLVM to give us that information. > > #### -Zsanitizer=kernel-hwaddress > > Alice Ryhl opened a new issue to introduce the `-Zsanitizer=kernel-hwaddress` sanitizer for aarch64 targets: https://github.com/rust-lang/compiler-team/issues/975 > > #### -Zharden-sls > > Wesley Wiser is working on allowing forbidden target features to be hard errors, which the `-Zharden-sls` patch should be rebased on top of. > > #### #![register_tool] > > The corresponding RFC has been discussed by the Lang team on 2026-03-11. The overall vibe was positive and TC is going to read through it and hopefully check a box on the proposed FCP. > > #### -Zdebuginfo-compression > > The proposed stabilization received some feedback that needs to be addressed. > > #### -Zdirect-access-external-data > > The discussion here has stalled. * **Tomas Sedovic** — comment from 2026-04-10 > Update from the 2026-04-08 meeting: > > #### -Zsanitize=kernel-hwaddress > > rust#153049 is merged. What remains of the tracking issue rust#154171 is a few docs checklists. > > Alice Ryhl added the unstable book doc changes in the PR itself and Wesley Wiser confirmed that's all the documentation needed for sanitizers. ### Getting Rust for Linux into stable Rust: language features * **People involved:** **Tomas Sedovic** , Ding Xiang Fei * **Champions:** lang (Josh Triplett), lang-docs (TC) * **Status:** Superseded by the Rust for Linux 2026 roadmap 6 detailed updates available. * **Tomas Sedovic** — comment from 2026-01-19 > Update from the 2026-01-14 meeting. > > #### `Deref` / `Receiver` > > Ding's arbitrary_self_types: Split the Autoderef chain rust#146095 is waiting on reviews. It updates the method resolution to essentially: `deref_chain(T).flat_map(|U| receiver_chain(U))`. > > The perf run was a wash and a carter has completed yesterday. Analysis pending. > > #### RFC #3851: Supertrait Auto-impl > > Ding has submitted a Rust Project goal for Supertrait Auto Impl. > > #### Arbitrary Self Types rust#44874 > > We've discovered the `#[feature(arbitrary_self_types_pointer)]` feature gate. As the Lang consensus is to not support the `Receiver` trait on raw pointer types we're probably going to remove it (but this needs further discussion). This was a remnant from the original proposal, but the Lang has changed direction since. > > #### `derive(CoercePointee)` rust#123430 > > Ding is working on a fix to prevent accidental specialization of the trait implementation. rust#149968 is adding an interim fix. > > Alice opened a Reference PR for rust#136776. There are questions around the behaviour of the `as` cast vs. coercions. > > #### Pass pointers to const in assembly rfc#3848 > > Gary opened implementation for the RFC: rust#138618. > > #### Field Projections goal#390 > > Benno updated the Field Representing Types PR to the latest design. This makes the PR much simpler. > > Tyler opened a Beyond References wiki to keep all the proposals, resources in one place. > > #### In-place initialization goal#395 > > Ding is writing a post to describe all the open proposals including Alice's new one that she brouhght up during the LPC 2025. He'll merge it in the Beyond References wiki. > > #### Macros, attributes, derives, etc. > > Josh brought up his work on adding more capable declarative macros for writing attributes and derives. He's asked the Rust for Linux team for what they need to stop using proc macros. > > Miguel noted they've just added dependency on syn, but they would like to remove it some day if their could. > > Benno provided a few cases of large macros that he thought were unlikely to be replaceable by declarative-style ones. Josh suggested there may be a way and suggested an asynchronous discussion. * **Tomas Sedovic** — comment from 2026-02-16 > Updates from the 2026-01-28 and 2026-02-11 meetings: > > #### Removing the `likely`/`unlikely` hints in favour of `cold_path` > > The stabilization of core::hint::cold_path lint is imminent and after it, the `likely` and `unlikely` hints are likely (pardon the pun) to be removed. > > The team discussed the impact of this. These hints are used in C but not yet in Rust. `cold_path` would be sufficient, but `likely`/`unlikely` would still be more convenient in cases where there isn't an `else` branch. Tyler Mandry mentioned that these can be implemented in terms of `cold_path`. > > #### Niche optimizations > > We discussed the feasibility of embedding data in lower bits of a pointer -- something the kernel is doing in C. This could also enable setting the top bit in the integers (which is otherwise never set) and make it represent an error in that case (and a regular pointer otherwise). > > Ideally, this would be done in safe Rust, as the idea is to improve the safety of the C code in question. > > Extending the niches is something Rust wants to see, but it's waiting on pattern types. There are short/medium-term options by using `unsafe` and wrapping it in a safe macro, but the long-term hope is to have this supported in the language. > > #### Vendoring zerocopy > > The project has interest in vendoring zerocopy. We had its maintainers Jack Wrenn and Joshua Liebow-Feeser join us to discuss this and answer our questions. The main question was about whether to vendor at all, how often should we (or will have to) upgrade, and how much of it is expected to end up in the standard library. > > The project follows semver with the extended promise to not break minor versions even before 1.0.0. We could vendor the current 0.8 and we should be upgrade on our own terms (e.g. when we bring in new features) rather than being forced to. > > Right now, the project is able to experiment with various approaches and capabilities. Any stdlib integration a long way away, but there is interest in integrating these to the language and libraries where appropriate. > > #### New trait solver > > There's been a long-term effort to finish the new trait solver, which will unblock a lot of things. Niko Matsakis asked about things it's blocking for Rust for Linux. > > This is the list: unmovable types, guaranteed destructors, Type Alias Impl Trait (TAIT), Return Type Notation (RTN), const traits, const generics (over integer types), extern type. > > #### 2026 Project goals > > This year brings in the concept of roadmaps. We now have a Rust for Linux and a few more granular Goals. We'll be adding more goals over time, but the one merged cover what we've been focusing on for now. * **Tomas Sedovic** — comment from 2026-03-11 > Update from the 2026-02-25 meeting: > > #### 2026 Project goals > > We spent most of the meeting going over the open Project goals, the Rust for Linux roadmap and other things we'd like to see that aren't the right shape for a goal. > > Miguel Ojeda brought up the upcoming Debian 14 release (coming out probably somewhere around Q2 of 2027) and we went over each item and decided whether it's something we need to make sure is in that release or not. > > Debian stable is an important milestone and the Rust version in it serves as a baseline for Rust for Linux development. > > I'll add all this data into the roadmap. * **Tomas Sedovic** — comment from 2026-03-16 > Update from the 2026-03-11 meeting: > > #### Field projections > > We now have a macro and machinery that uses the projection mechanism. > > The `dma_read!` / `dma_write!` macros switched over to it. This also fixes a soundness issue 1. > > Note: this is done entirely via macros and doesn't use any Field projections language features. The Field projection syntax and traits should make this more ergonomic and integrate the borrow checker so we can accept more code. > > We're planning to have a design meeting with the Lang team in the last week of March. > > #### rustfmt imports formatting and trailing slashes > > We talked about the rustfmt formatting of the `use` statements again. While the trailing empty comment `//` workaround (see this update) is acceptable as a temporary measure, we need to find a long-term solution where you can configure rustfmt to accept this style. > > We don't have a issue for this specific formatting yet, though it was discussed in #3361. > > The next step are to create such an issue. We were hesitant to add burden to a team that's already at limit, but having the issue would let us track it from the Rust for Linux side. * **Tomas Sedovic** — comment from 2026-03-26 > Update from the 2026-03-26 meeting: > > #### Const generics > > Boxy asked the team for features that are most important under the const generics umbrella. This might help with prioritisation and just understanding of practical uses. > > 1. **Ability to do arithmetic on const generic types** : e.g. the kernel has a type Bounded which has a value and a maximum size (in bits). Both the bit width and value are const values. They want to be able to do arithmetics on these types (starting with bit shifts) that will guarantee the the result will fit within the specified size at compile time. > 2. **Argument-position const generics** : right now, the const generic types must be specified in the type bound section (within the angle brackets). So for example you have to write: `Bounded::<u8, 4>::new::<7>()` instead of the more natural `Bounded::<u8, 4>::new(7)`. This gets more complicated when there's const-time calculation happening rather than just a numerical constant -- in which case this also needs to be wrapped in curly brackets: `{ ... }`. > 3. Being generic over types other than numbers: pointers would be useful for asm_const_ptr. String literals too -- even if they're just passed through without being processed / operated on. And if going from a passthrough string makes it possible to pass through any type, that would help the team replace some typestate patterns they're using with an `enum`. > > #### `statx` > > Alice Ryhl proposed being able to create `std::fs::Metadata` from Linux `statx` syscall. > > This was discussed in the Libs-API meeting and they had questions about possible evolutions of the `statx` ABI -- if/how it can grow in the future and how they could handle that if they wanted some of the new data available. So we discussed it in the Rust for Linux meeting. > > In the end, it seems prudent to be reasonably defensive rather than relying on the syscall pre-filling default values. > > Alice Ryhl proposed an opaque `statx` struct that would give the stdlib a way to decide on the struct's size, pre-filled contents and mask. > > Miguel Ojeda suggested contacting Christian Brauner and Alexander Viro (i.e. the VFS maintainers); Josh Triplett agreed that it would be good if we can get a thread with the right people in linux-fsdevel. * **Tomas Sedovic** — comment from 2026-04-10 > Update from the 2026-04-08 meeting: > > #### zerocopy features in Rust's std > > zerocopy uses two traits that are both polyfills for unstable traits : `KnownLayout` (for `ptr_metadata`) and `Immutable` (for `Freeze`). It would help maintenance of zerocopy (which Rust for Linux plans to start using) if these were stabilised. > > `ptr_metadata` is something the team wants in the kernel independently. It's possibly blocked on (or at least might have interactions with) the Sized Hierarchy work. > > `Freeze` (now `NoCell`) has an RFC. > > #### `Deref`/`Receiver` > > Jack Huey started reviewing Ding Xiang Fei's PR to split the autoderef chain and feels it's not ready to go in front of the full Lang team. > > We also discussed the dependence/independence of the `Deref` and `Receiver` implementations, in particular whether it ever makes sense to implement `Deref` but _not_ `Receiver`. Josh Triplett suggested gathering examples for cases like that (where you can't use the type as a `Self` type in the function declaration, but allow calling methods on it). > > The current plan for the experiment is to have these traits separate, but have the compiler enforce that if they implement the same type, their targets are identical. This will let us open the door for any future possibilities (a supertrait / subtrait relation, or having diverging targets in the future). > > We want to experiment to see where and how these traits and their possible evolution might be helpful. > > #### null-ptr-deref > > The team would like to have a (an optional) compiler guarantee, that the compiler never removes null checks on raw pointers. What can currently happen in C is that if you deref a null pointer, the compiler can do optimisations including removing any subsequent checks whether that pointer is null, because dereferencing a null pointer is undefined behaviour. > > But the null check can still help prevent further bugs and in C, the kernel now disables the optimisation that would remove it. > > Miguel Ojeda is going to open an MCP for this. > > #### In-Place Initialization > > Benno Lossin opened a proposal for an in-person room at the 2026 All Hands for In-place initialization. > > Here's a meta issue tracking all the proposals and discussions about the feature. > > The design space is complex and the team hopes that discussing it in person will help move it forward. ### Implement Open API Namespace Support * **People involved:** **Ed Page** , b-naber * **Champions:** cargo (Ed Page), compiler (b-naber), crates-io (Carol Nichols) * **Status:** Continued ### MIR move elimination * **People involved:** **Amanieu d'Antras** * **Champions:** lang (Amanieu d'Antras) * **Status:** Continued 1 detailed update available. * **Amanieu d'Antras** — comment from 2026-04-03 > The RFC has just been published. It has been significantly reworked since the last draft. > > Notable changes: > > * Removed the concept of activation/de-activation. Now the semantics don't need to deal with partially allocated locals. This is less powerful optimization-wise but should still cover most cases. > * Added byref/byval to call arguments to clarify how they are passed. > * Added a separate section for the surface language changes to separate it from the MIR changes. > * Added more details on the MIR optimization which eliminates moves. > * Changed the MIR operand evaluation order to be left-to-right, except for destination places which are always evaluated last. > * Added StorageLive back: we need it to mark the location where `llvm.lifetime.start` should be inserted, which is not the same as the location where a local is initialized. In the opsem, `StorageLive` doesn't actually allocate the local, that's still done when it is initialized by a write. ### Prototype a new set of Cargo "plumbing" commands * **People involved:** **Ed Page** * **Champions:** cargo (Ed Page) * **Status:** Continued ### Prototype Cargo build analysis * **People involved:** **Weihang Lo** * **Champions:** cargo (Weihang Lo) * **Status:** Completed 1 detailed update available. * **Weihang Lo** — comment from 2026-01-08 > The prototype of this project goal is basically complete. > > ### Current state > > This project goal introduces **build analysis support in Cargo** , with the aim of making build behavior understandable across multiple invocations, not just a single run. > > At a high level, the prototype: > > * Records build metadata over time, including: > * rebuild reasons > * timing information > * relevant invocation context > * Stores this data locally in a structured log format suitable for later analysis > * Exposes the data via unstable `cargo report` subcommands, such as: > * `cargo report sessions` - list session IDs > * `cargo report timings` - HTML timing report > * `cargo report rebuilds` - Why things rebuilt > > See the Reference for a more thorough usage documentation > > * * * > > ### Path towards stabilization > > Before this feature can be stabilized, the following unresolved questions must be answered. They might not block stabilization, but need to be evaluated if it is fine to leave for future. > > #### `cargo report` commands > > This is a stabilization blocker. > > * Currently all three report commands (`sessions`, `rebuilds`, `timings`) implicitly inspect global log files when if not in a workspace. > * Should this be explicit with a flag? > * Should this be an error if not in a workspace? > * Bikeshed on command names > * Currently we have all nouns > * For `sessions` > * `runs` simple but ambiguous > * Just `log` like `git log` > * `history` user-friendly (`docker history`, shell `history`, though not alike) > * For `timings`: > * Not controversial, as we have `--timings` flag already > * For `rebuilds`: > * `rebuild-reasons` more explicit > * Or move to action-oriented verbs: > * `cargo report list-sessions` > * `cargo report analyze-timings` (bazel analyze-profile) > * `cargo report explain-rebuilds` > * Or question-oriented verbs: > * `cargo report what-ran` more general (buck2 log what-ran) > * `cargo report why-rebuilt/why-reran` > > ##### `cargo report sessions` > > * Currently it prints a human-readable output without a format for programmable use cases. > * Should we provide a programmable output (for example behind `--message-format=json`)? > > ##### `cargo report rebuilds` > > * Extend the report from fingerprint to new hash (`-Cmetadata`/`-Cextra-filename`) > * We currently can't distinguish whether a fresh build is a real new build or just rustflags changed > * https://github.com/rust-lang/cargo/pull/16456#discussion_r2662364819 > * Make each rebuilt reason more actionable and friendly for end-users. > * Should we log the fingerprint values being compared, or just the diff result? > * #t-cargo > logging unit fingerprint @ 💬 > > #### Log message schema > > This is a stabilization blocker. > > * Providing types for reading log messages > * We should export `LogMessage` enum and related types in `cargo-util-schemas` > * Users may want to parse logs programmatically > * https://github.com/rust-lang/cargo/pull/16150#discussion_r2462065538 > * JSON schema evolution and versioning > * Should we version the schema explicitly in each message? > * Compatibility might be the same as https://doc.rust-lang.org/nightly/cargo/commands/cargo-metadata.html?highlight=compa#compatibility > * Message structure consistency > * Current log messages deviate from cargo's normal JSON message structure > * Should we align with existing cargo JSON output format, for example the `target` field? > * https://github.com/rust-lang/cargo/pull/16414#discussion_r2632724893 > * https://github.com/rust-lang/cargo/pull/16303#discussion_r2565526807 > * https://github.com/rust-lang/cargo/pull/16303#discussion_r2561862478 > * Should we expose the entire `DirtyReason` enum as-is? > * Currently exposes internal implementation details > * May want to create a separate public-facing enum > * Need to decide which variants are user-facing vs internal > * Check usefulness of each variant > * Some variants may be obsolete (e.g., `RustflagsChanged` may be rare after `-Cmetadata` changes) > * Need audit of which variants actually occur in practice > * Remove or consolidate rarely-used variants > * Make dirty reasons end-user friendly > * Current reasons are technical (e.g., "local fingerprint type changed") > * Users need actionable messages (e.g., "file modified: src/lib.rs") > * Expose `target` and `mode` > * Are they universal for all kind of units? We might want to rename mode to action, as an action kind of a unit. > * https://rust-lang.zulipchat.com/#narrow/channel/246057-t-cargo/topic/build.20analysis.20log.20format/near/564781487 > > #### Log infrastructure > > These are mostly future possibilities, not a stabilization blocker, as it is highly possible to do incremental improvements. > > * log compression https://github.com/rust-lang/cargo/issues/16475 > * log rotation https://github.com/rust-lang/cargo/issues/16471 > * Is losing data on crashes ok? https://github.com/rust-lang/cargo/pull//16150#discussion_r2462056940 > > See also https://github.com/rust-lang/cargo/issues/16471#issuecomment-3724915770 > > #### Nested Cargo calls > > See https://github.com/rust-lang/cargo/issues/16477. > > Basically, we need to have a way to associate log files of nested Cargo calls. That helps other tools as well as `cargo fix` itself. > > This is a stabilization blocker. > > #### How contributors can help > > Future contributors can help by: > > * picking up any linked issues below or in https://github.com/rust-lang/cargo/issues/15844 > * building external tools utilizing the log messages, and providing feedback > * providing real-world feedback from large or unusual builds > > A series of follow-up tasks has been cut to track remaining work: > > * https://github.com/rust-lang/cargo/issues/16470 > * https://github.com/rust-lang/cargo/issues/16471 > * https://github.com/rust-lang/cargo/issues/16472 > * https://github.com/rust-lang/cargo/issues/16473 > * https://github.com/rust-lang/cargo/issues/16474 > * https://github.com/rust-lang/cargo/issues/16475 > * https://github.com/rust-lang/cargo/issues/16477 > * https://github.com/rust-lang/cargo/issues/16488 ### reflection and comptime * **People involved:** **Oliver Scherer** * **Champions:** compiler (Oliver Scherer), lang (Scott McMurray), libs (Josh Triplett) * **Status:** Continued 5 detailed updates available. * **Oliver Scherer** — comment from 2026-01-14 > * The MVP has landed, and we even got the first contribs adding array support to reflection. > * there are lots more types and type information that we could support, and it's rather easy to add more. Happy to review any work here. > * try_as_dyn and try_as_dyn_mut have landed, and I'm working on removing the 'static requirement. * **Oliver Scherer** — comment from 2026-02-09 > * @BD103 added Type::of for unsized types and support for slices, arrays, and raw pointer > * Asuna added all of our primitives > * Jamie Hill-Daniel gave us references > * @izagawd made it possible to extract some info from dyn Trait > > There is ongoing work for Adts and function pointers, both of which will land as MVPs and will need some work to make them respect semver or generally become useful in practice > > Removing the 'static bound from try_as_dyn turned out to have many warts, so I'm limiting it to a much smaller subset and will have borrowck emit the `'static` requirement if the other rules do not apply (instead of having an unconditional `'static` requirement) * **Oliver Scherer** — comment from 2026-03-19 > * I added support for getting reflection information of any type, not just 'static ones > * 9SonSteroids added a function pointer MVP and trait object support > * Asuna added basic struct/enum/union support * **Oliver Scherer** — comment from 2026-04-22 > No changes since last time. > > I'm writing a document for the lang team meeting on reflection next week * **Oliver Scherer** — comment from 2026-04-22 > ### Help wanted > > * add more information to adts (e.g. doc comments, attributes, ...), whatever else is usually used by crates like bevy-reflect > * need to make struct field reflection respect privacy ### Rework Cargo Build Dir Layout * **People involved:** **Ross Sullivan** * **Champions:** cargo (Weihang Lo) * **Status:** Completed; the Cargo cross workspace cache 2026 goal will build on this work 2 detailed updates available. * **Ross Sullivan** — comment from 2026-01-15 > Fine grain locking for build-dir was merged and now available on nightly via `-Zfine-grain-locking` unstable flag. 🎉 > > There are some known issues we'd like to address before doing a formal call for testing. Notably, improving blocking messages, fixing potential thread starvation in Cargo's job queue when locks block, and investigate increasing rlimits to reduce risk of hitting max file descriptors for large projects. > > I am hopeful that these issues will be resolved over the coming month and we can do a call for testing to start gathering feedback from the community on whether the new locking strategy improves workflows. * **Ross Sullivan** — comment from 2026-03-09 > After the initial PR from the last update was merged, we shifted our focus to resolving some of the known issues. Notably, locking blocks the Cargo job queue slowly causing thread starvation if many build units are held by another Cargo instance. > > We investigated adding the ability for Cargo to "suspend" a job internally while waiting for a lock, but we felt this change was a bit invasive and did not fit well with how the job queue was designed. Instead we plan to change our design to acquire all build unit locks prior to running the job queue (see #16657). > > At the same time, we have continued to refine the new `build-dir` to prepare it for a call for testing and eventual stabilization. (#16542, #16502, #16515, #16514) > > Finally we decided to split `.cargo-lock` into 2 locks to allow `cargo check` and `cargo build` to run in parallel when `artifact-dir == build-dir` (and `-Zfine-grain-locking` is enabled) > > I suspect this may be the last update on this goal, as the 2026 slate of goals is coming up. While I did not renew this goal for 2026, I do plan to continue work on this and eventually stabilize this within this year. ### Run more tests for GCC backend in the Rust's CI * **People involved:** **Guillaume Gomez** * **Champions:** compiler (Wesley Wiser), infra (Marco Ieni) * **Status:** Completed ### Rust Stabilization of MemorySanitizer and ThreadSanitizer Support * **People involved:** **Jakob Koschel** , Bastian Kersting * **Status:** Continued 3 detailed updates available. * **Jakob Koschel** — comment from 2026-01-14 > The MCP has been seconded and is still waiting 3 days to be approved. Once that is done, we can proceed with merging the Tier 2 target. * **Jakob Koschel** — comment from 2026-02-16 > Both the MCP and the PR for the AddressSanitizer target have been merged. Next up I should prepare the MCP for the Memory- and ThreadSanitizer targets, hopefully sending out soon. * **Jakob Koschel** — comment from 2026-03-31 > The targets for MSan and TSan are merged now. > > Next, I'll be working on stabilizing those two, now that we have a way to use it without other unstable features (`build-std`). ### Rust Vision Document * **People involved:** **Niko Matsakis** , vision team * **Status:** Partially completed; work continues outside of Project Goals ### rustc-perf improvements * **People involved:** **James Barford** , Jakub Beránek, David Wood * **Champions:** compiler (David Wood), infra (Jakub Beránek) * **Status:** Technical work completed; remaining policy and infrastructure work postponed ### Stabilize public/private dependencies * **People involved:** **Ed Page** * **Champions:** cargo (Ed Page) * **Status:** Continued ### Stabilize rustdoc doc_cfg feature * **People involved:** **Guillaume Gomez** * **Champions:** rustdoc (Guillaume Gomez) * **Status:** Not completed (blocked) ### SVE and SME on AArch64 * **People involved:** **David Wood** * **Champions:** compiler (David Wood), lang (Niko Matsakis), libs (Amanieu d'Antras) * **Status:** Continued 5 detailed updates available. * **David Wood** — comment from 2026-01-15 > rust-lang/rust#143924 has been merged, enabling scalable vector types to be defined on nightly, and I'm working on a patch to introduce unstable intrinsics/scalable vector types to `std::arch` * **David Wood** — comment from 2026-02-17 > Progress has been slow since the last update because I've been busy, but I've been working on a rebase of rust-lang/stdarch#1509, which has bitrot quite a bit. Rémy Rakic is joining me to work on the Sized Hierarchy parts of the goal. * **David Wood** — comment from 2026-03-17 > On the scalable vector half of the goal, I've got a branch with rust-lang/stdarch#1509 rebased, though without the `intrinsic-test` tool having been updated - that ended up being tricky and we've agreed to do it as a follow-up. We've opened rust-lang/rust#153286 with the compiler fixes that the stdarch patch requires, which should land soon (rust-lang/rust#153653 was opened and landed in the interim). > > On the sized hierarchy half of the goal, Rémy Rakic has been updating our RFC such that we can discuss it in design meetings with the language team on the 18th and 25th - we'll update rust-lang/rfcs#3729 later today. We've split out the `const Sized` parts as a future possibility (though one we are committed to pursuing) as that has more open design questions, and we've discussed the proposed syntax and approach to migration - which are what we intend to focus on in the design meetings. He's also been working out how we can start implementing our migration strategy and help resolve blockers in other areas. * **David Wood** — comment from 2026-03-17 > Per last comment, rust-lang/rfcs#3729 has been updated * **David Wood** — comment from 2026-04-14 > For the scalable vector half of the goal, we've landed a bunch of compiler fixes - rust-lang/rust#153286, rust-lang/rust#153608, rust-lang/rust#154850, rust-lang/rust#154950, rust-lang/rust#155106 and rust-lang/rust#155243 - and opened our stdarch patch with intrinsics - rust-lang/stdarch#2071. That patch should be passing CI tomorrow once nightly updates to fix an unrelated spurious CI failure. We've got a handful of follow-ups to do afterwards, listed on rust-lang/rust#145052. > > For the sized hierarchy half of the goal, Rémy Rakic and I had two design meetings with the language team (2026/03/18 and 2026/03/25) discussing the syntax/naming and migration strategy respectively. > > On syntax, the language team preferred introducing an "only bounds" syntax to control opting-out of default bounds and opting-in to alternative bounds in a family of traits (described in an alternative in the RFC), but there was an open question of whether that syntax should apply to an individual bound or all of the bounds - Niko Matsakis is investigating that. > > On naming, the language team also preferred the name `SizeOfVal` over `MetaSized`, and didn't like `Pointee` but had no better alternatives. Rémy Rakic prepared rust-lang/rust#154374 to do that renaming and started a discussion with the library team to confirm they were happy with the name, because changing it involves an amount of churn. The library team wanted to know what other traits in the hierarchy might later be introduced, as that would help inform the naming of the currently proposed traits, so Rémy Rakic wrote up a document with that information. We're holding off on doing any name changes until we find some consensus between libs and lang - who is responsible for these traits' names is a bit unclear. > > On migration, the language team were largely happy with our proposed approach, and we realised that the approach proposed by lcnr for associated types might also work for our other migrations. Rémy Rakic has had meetings with lcnr to better understand that approach and to work out the next steps for implementing it. ### Type System Documentation * **People involved:** **Boxy** , lcnr * **Champions:** types (Boxy) * **Status:** Continued ### Unsafe Fields * **People involved:** **Jack Wrenn** , Jacob Pratt, Luca Versari * **Champions:** compiler (Jack Wrenn), lang (Scott McMurray) * **Status:** Continued 2 detailed updates available. * **Jack Wrenn** — comment from 2026-02-18 > RFC has been accepted. I'm preparing a 2026 continuing goal for stabilization. * **Jack Wrenn** — comment from 2026-04-14 > Opened PR (#16767(https://github.com/rust-lang/rust-clippy/pull/16767)) extending Clippy support to unsafe fields. > > ### Blockers > > Waiting for t-clippy to review #16767(https://github.com/rust-lang/rust-clippy/pull/16767).

blog.rust-lang.org

Rust is participating in Outreachy

The Rust Project has been building up a good history of participating in various open-source mentorship programs, including Google Summer of Code for three years (including this year) and previously OSPP. We're happy to announce that this year we are also participating in Outreachy starting in the May 2026 cohort. Each of these mentorship programs has different criteria for eligibility depending on who they target and the motivations of the program. Outreachy provides internships in open source, to people from any background who face underrepresentation, systemic bias, or discrimination in the technical industry where they are living. You can learn more about the Outreachy program on their website. ## What is Outreachy and how is it different than Google Summer of Code Outreachy is similar to Google Summer of Code (GSoC) in some aspects, but different in others. First off, unlike GSoC, Outreachy interns first apply to the overall program and only _then_ can apply to specific communities. Second, while oftentimes GSoC applicants submit various contributions prior to their application, Outreachy has a dedicated period where contributions are not just optional, but required. Finally, Outreachy applicants submit an application similar to GSoC applications and communities pick interns based on those applications and the interns' contributions. Outreachy has two internship periods per year, one running from May to August (in which we are currently participating) and one from December to March. The other major difference between Google Summer of Code and Outreachy is the source of intern stipends. For GSoC, Google graciously covers contributor stipends and overhead. For Outreachy, communities instead cover the interns' stipends and overhead. ## We are mentoring 4 interns for the May 2026 cohort Because of limited funding availability and mentoring capacity, the Rust Project decided to select four interns for mentorship. We'll briefly share these projects below. ### Calling overloaded C++ functions from Rust Ajay Singh has been selected, mentored by teor, Taylor Cramer, and Ethan Smith. This project aims to implement an experimental feature for calling overloaded C++ functions from Rust, and to begin testing that feature in a few representative use cases. ### Code coverage of the Rust compiler at scale Akintewe Oluwasola has been selected, mentored by Jack Huey. This project aims to develop the workflows to run and analyze code coverage of the compiler at the scale of the entire compiler test suite and on ecosystem crates detected by crater. The hope is to be able to detect when the compiler is inadequately tested, both within the compiler and in the ecosystem, and to build tools to do continuous analysis on this. ### Fuzzing the a-mir-formality type system implementation Tunde-Ajayi Olamiposi has been selected, mentored by Niko Matsakis, Rémy Rakic, and tiif. This project aims to implement fuzzing for a-mir-formality, an in-progress model for Rust's type and trait system. The goal is to generate programs in order to identify rules with underspecified semantics in a-mir-formality. ### Improve the security of GitHub Actions of the Rust Project oghenerukevwe Sandra Idjighere has been selected, mentored by Marco Ieni and Ubiratan Soares. This project aims to improve the security of GitHub Actions workflows of the repositories owned by the Rust Project. It will develop tools and workflows, integrating with existing software, to analyze Github repositories and detect if they follow the best security practices, fix existing issues, and ensure that good security practices are followed in the future. ## What's next Over the next 3 months, the interns will work closely with their mentors to make progress on their projects. When the internship period is over, we'll write another blog post to share the results! See you then! We also want to thank all the people that submitted applications and made contributions. It was quite tough to decide which applicants to select. Hopefully we will participate in Outreachy again in the future and there are other opportunities to participate. We also very much welcome you to stick around and continue being involved - there is a ton of places in the Rust Project with opportunities to be involved.

blog.rust-lang.org

Raising the baseline for the `nvptx64-nvidia-cuda` target

The `nvptx64-nvidia-cuda` target is a compilation target for NVIDIA GPUs. When using this target, the final output is PTX. Two version choices shape that output: * a GPU architecture (for example, `sm_70`, `sm_80`, …), which determines which GPUs can run the PTX, and * a PTX ISA version, which determines which CUDA driver versions can load (and JIT-compile) the PTX. In Rust 1.97 (scheduled for release on July 9, 2026), the baseline PTX ISA version and GPU architecture for `nvptx64-nvidia-cuda` will be increased. These changes affect both the Rust compiler (`rustc`) and related host tooling, and they make it impossible to generate PTX artifacts compatible with older GPUs and older CUDA drivers. The new minimum supported versions will be: * **PTX ISA 7.0** (requires a CUDA 11 driver or newer) * **SM 7.0** (GPUs with compute capability below 7.0 are no longer supported) ## Why are the requirements being changed? Until now, Rust has supported emitting PTX for a wide range of GPU architectures and PTX ISA versions. In practice, several defects existed that could cause valid Rust code to trigger compiler crashes or miscompilations. Raising the baseline addresses these issues and enables more complete support for the remaining supported hardware. Removing support affects users of the architectures being removed. In this case, the most recent affected GPU architectures date back to 2017 and are no longer actively supported by NVIDIA. We therefore expect the overall impact of this change to be limited. Maintaining support for these architectures would require substantial effort. These removals let us focus development efforts on improving correctness and performance for currently supported hardware. ## What happens when I update to Rust 1.97? If you need to target a CUDA driver that does not support PTX ISA 7.0 (CUDA 10-era drivers and older), Rust 1.97 will no longer be able to generate PTX compatible with that environment. Similarly, if you need to run on GPUs with compute capability below 7.0 (for example, Maxwell or Pascal), Rust 1.97 will no longer be able to generate compatible PTX for those GPUs. Assuming you are targeting a CUDA driver compatible with CUDA 11 or newer and using GPUs with compute capability 7.0 or newer: * If you do **not** specify `-C target-cpu`, the new default will be `sm_70`, and your build should continue to work (but will no longer be compatible with pre-Volta GPUs). * If you currently specify an older `-C target-cpu` (for example, `sm_60`), you will need to either: * remove that flag and let it default to `sm_70`, or * update it to `sm_70` or a newer architecture. * If you already specify `-C target-cpu=sm_70` (or newer), there should be no behavioral changes from this update. For more details on building and configuring `nvptx64-nvidia-cuda`, see the platform support documentation.

blog.rust-lang.org

Announcing Google Summer of Code 2026 selected projects

As previously announced, the Rust Project is participating in Google Summer of Code (GSoC) 2026. GSoC is a global program organized by Google that is designed to bring new contributors to the world of open source. A few months ago, we published a list of GSoC project ideas, and started discussing these projects with potential GSoC applicants on our Zulip. We had many interesting discussions with the potential contributors, and even saw some of them making non-trivial contributions to various Rust Project repositories before GSoC officially started! The applicants prepared and submitted their project proposals by the end of March. This year, we received 96 proposals, which is a 50% increase from last year. We are glad that there was again a lot of interest in our projects! Like many other GSoC organizations this year, we somewhat struggled with some AI-generated proposals and low-quality contributions generated using AI agents, but it stayed manageable. GSoC requires us to produce an ordered list of the best proposals, which is always challenging, as Rust is a big project with many priorities. Our mentors examined the submitted proposals and evaluated them based on their prior interactions with the given applicant, their contributions so far, the quality of the proposal itself, but also the importance of the proposed project for the Rust Project and its wider community. We also had to take mentor bandwidth and availability into account. Unfortunately, we had to cancel some projects due to several mentors losing their funding for Rust work in the past few weeks. As is usual in GSoC, even though some project topics received multiple proposals1, we had to pick only one proposal per project topic. We also had to choose between proposals targeting different work to avoid overloading a single mentor with multiple projects. In the end, we narrowed the list down to the best proposals that we could still realistically support with our available mentor pool. We submitted this list and eagerly awaited how many of them would be accepted into GSoC. ## Selected projects On the 30th of April, Google has announced the accepted projects. We are happy to share that **13** Rust Project proposals were accepted by Google for Google Summer of Code 2026. That is a lot of projects! We are really happy and excited about GSoC 2026! Below you can find the list of accepted proposals (in alphabetical order), along with the names of their authors and the assigned mentor(s): * **A Frontend for Safe GPU Offloading in Rust** by Marcelo Domínguez, mentored by Manuel Drehwald * **Adding WebAssembly Linking Support to Wild** by Kei Akiyama, mentored by David Lattimore * **Bringing autodiff and offload into Rust CI** by Shota Sugano, mentored by Manuel Drehwald * **Debugger for Miri** by Mohamed Ali Mohamed, mentored by Oli Scherer * **Implementing impl and mut restrictions** by Ryosuke Yamano, mentored by Jacob Pratt and Urgau * **Improving Ergonomics and Safety of serialport-rs** by Tanmay, mentored by Christian Meusel * **libc: transition differing bit-width time and offset variants and deprecate bug-prone constants** by Adam Martinez, mentored by Trevor Gross * **Link Linux kernel and its Modules with Wild** by Vishruth Thimmaiah, mentored by David Lattimore * **Migrating rust-analyzer assists to SyntaxEditor** by Shourya Sharma, mentored by Chayim Refael Friedman and Lukas Wirth * **Port std::arch test suite to rust-lang/rust** by Sumit Kumas, mentored by Jakub Beránek and Folkert de Vries * **Reorganizing tests/ui/issues** by Matthew, mentored by Teapot and Kivooeo * **Utilize debugger APIs to improve debug info test accuracy and error reporting** by Anthony Bolden, mentored by Jakub Beránek and Jieyou Xu * **XDG path support for rustup** by Guicheng Liu, mentored by rami3l **Congratulations to all applicants whose project was selected!** Our mentors are looking forward to working with you on these exciting projects to improve the Rust ecosystem. You can expect to hear from us soon, so that we can start coordinating the work on your GSoC projects. We are excited to mentor three contributors who already experienced GSoC with us in the previous year. Welcome back, Kei, Marcelo and Shourya! We would like to thank all the applicants whose proposal was sadly not accepted, for their interactions with the Rust community and contributions to various Rust projects. There were some great proposals that did not make the cut, in large part because of limited mentorship capacity. However, even if your proposal was not accepted, we would be happy if you would consider contributing to the projects that got you interested, even outside GSoC! Our project idea list is still current and could serve as a general entry point for contributors that would like to work on projects that would help the Rust Project and the Rust ecosystem. Some of the Rust Project Goals are also looking for help. There is a good chance we'll participate in GSoC next year as well (though we can't promise anything at this moment), so we hope to receive your proposals again in the future! The accepted GSoC projects will run for several months. After GSoC 2026 finishes (in autumn of 2026), we will publish a blog post in which we will summarize the outcome of the accepted projects. 1. The most popular project topic received fourteen different proposals! ↩

blog.rust-lang.org

Announcing Rust 1.95.0

The Rust team is happy to announce a new version of Rust, 1.95.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.95.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.95.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.95.0 stable ### `cfg_select!` Rust 1.95 introduces a cfg_select! macro that acts roughly similar to a compile-time `match` on `cfg`s. This fulfills the same purpose as the popular cfg-if crate, although with a different syntax. `cfg_select!` expands to the right-hand side of the first arm whose configuration predicate evaluates to `true`. Some examples: cfg_select! { unix => { fn foo() { /* unix specific functionality */ } } target_pointer_width = "32" => { fn foo() { /* non-unix, 32-bit functionality */ } } _ => { fn foo() { /* fallback implementation */ } } } let is_windows_str = cfg_select! { windows => "windows", _ => "not windows", }; ### if-let guards in matches Rust 1.88 stabilized let chains. Rust 1.95 brings that capability into match expressions, allowing for conditionals based on pattern matching. match value { Some(x) if let Ok(y) = compute(x) => { // Both `x` and `y` are available here println!("{}, {}", x, y); } _ => {} } Note that the compiler will not currently consider the patterns matched in `if let` guards as part of the exhaustiveness evaluation of the overall match, just like `if` guards. ### Stabilized APIs * MaybeUninit<[T; N]>: From<[MaybeUninit<T>; N]> * MaybeUninit<[T; N]>: AsRef<[MaybeUninit<T>; N]> * MaybeUninit<[T; N]>: AsRef<[MaybeUninit<T>]> * MaybeUninit<[T; N]>: AsMut<[MaybeUninit<T>; N]> * MaybeUninit<[T; N]>: AsMut<[MaybeUninit<T>]> * [MaybeUninit<T>; N]: From<MaybeUninit<[T; N]>> * Cell<[T; N]>: AsRef<[Cell<T>; N]> * Cell<[T; N]>: AsRef<[Cell<T>]> * Cell<[T]>: AsRef<[Cell<T>]> * bool: TryFrom<{integer}> * AtomicPtr::update * AtomicPtr::try_update * AtomicBool::update * AtomicBool::try_update * AtomicIn::update * AtomicIn::try_update * AtomicUn::update * AtomicUn::try_update * cfg_select! * mod core::range * core::range::RangeInclusive * core::range::RangeInclusiveIter * core::hint::cold_path * <*const T>::as_ref_unchecked * <*mut T>::as_ref_unchecked * <*mut T>::as_mut_unchecked * Vec::push_mut * Vec::insert_mut * VecDeque::push_front_mut * VecDeque::push_back_mut * VecDeque::insert_mut * LinkedList::push_front_mut * LinkedList::push_back_mut * Layout::dangling_ptr * Layout::repeat * Layout::repeat_packed * Layout::extend_packed These previously stable APIs are now stable in const contexts: * fmt::from_fn * ControlFlow::is_break * ControlFlow::is_continue ### Destabilized JSON target specs Rust 1.95 removes support on stable for passing a custom target specification to `rustc`. This should **not** affect any Rust users using a fully stable toolchain, as building the standard library (including just `core`) already required using nightly-only features. We're also gathering use cases for custom targets on the tracking issue as we consider whether some form of this feature should eventually be stabilized. ### Other changes Check out everything that changed in Rust, Cargo, and Clippy. ## Contributors to 1.95.0 Many people came together to create Rust 1.95.0. We couldn't have done it without all of you. Thanks!

blog.rust-lang.org

Changes to WebAssembly targets and handling undefined symbols

Rust's WebAssembly targets are soon going to experience a change which has a risk of breaking existing projects, and this post is intended to notify users of this upcoming change, explain what it is, and how to handle it. Specifically, all WebAssembly targets in Rust have been linked using the `--allow-undefined` flag to `wasm-ld`, and this flag is being removed. ## What is `--allow-undefined`? WebAssembly binaries in Rust today are all created by linking with `wasm-ld`. This serves a similar purpose to `ld`, `lld`, and `mold`, for example; it takes separately compiled crates/object files and creates one final binary. Since the first introduction of WebAssembly targets in Rust, the `--allow-undefined` flag has been passed to `wasm-ld`. This flag is documented as: --allow-undefined Allow undefined symbols in linked binary. This options is equivalent to --import-undefined and --unresolved-symbols=ignore-all The term "undefined" here specifically means with respect to symbol resolution in `wasm-ld` itself. Symbols used by `wasm-ld` correspond relatively closely to what native platforms use, for example all Rust functions have a symbol associated with them. Symbols can be referred to in Rust through `extern "C"` blocks, for example: unsafe extern "C" { fn mylibrary_init(); } fn init() { unsafe { mylibrary_init(); } } The symbol `mylibrary_init` is an undefined symbol. This is typically defined by a separate component of a program, such as an externally compiled C library, which will provide a definition for this symbol. By passing `--allow-undefined` to `wasm-ld`, however, it means that the above would generate a WebAssembly module like so: (module (import "env" "mylibrary_init" (func $mylibrary_init)) ;; ... ) This means that the undefined symbol was ignored and ended up as an imported symbol in the final WebAssembly module that is produced. The precise history here is somewhat lost to time, but the current understanding is that `--allow-undefined` was effectively required in the very early days of introducing `wasm-ld` to the Rust toolchain. This historical workaround stuck around till today and hasn't changed. ## What's wrong with `--allow-undefined`? By passing `--allow-undefined` on all WebAssembly targets, rustc is introducing diverging behavior between other platforms and WebAssembly. The main risk of `--allow-undefined` is that misconfiguration or mistakes in building can result in broken WebAssembly modules being produced, as opposed to compilation errors. This means that the proverbial can is kicked down the road and lengthens the distance from where the problem is discovered to where it was introduced. Some example problematic situations are: * If `mylibrary_init` was typo'd as `mylibraryinit` then the final binary would import the `mylibraryinit` symbol instead of calling the linked `mylibrary_init` C symbol. * If `mylibrary` was mistakenly not compiled and linked into a final application then the `mylibrary_init` symbol would end up imported rather than producing a linker error saying it's undefined. * If external tooling is used to process a WebAssembly module, such as `wasm-bindgen` or `wasm-tools component new`, these tools don't know what to do with `"env"` imports by default and they are likely to provide an error message of some form that isn't clearly connected back to the original source code and where the symbols was imported from. * For web users if you've ever seen an error along the lines of `Uncaught TypeError: Failed to resolve module specifier "env". Relative references must start with either "/", "./", or "../".` this can mean that `"env"` leaked into the final module unexpectedly and the true error is the undefined symbol error, not the lack of `"env"` items provided. All native platforms consider undefined symbols to be an error by default, and thus by passing `--allow-undefined` rustc is introducing surprising behavior on WebAssembly targets. The goal of the change is to remove this surprise and behave more like native platforms. ## What is going to break, and how to fix? In theory, not a whole lot is expected to break from this change. If the final WebAssembly binary imports unexpected symbols, then it's likely that the binary won't be runnable in the desired embedding, as the desired embedding probably doesn't provide the symbol as a definition. For example, if you compile an application for `wasm32-wasip1` if the final binary imports `mylibrary_init` then it'll fail to run in most runtimes because it's considered an unresolved import. This means that most of the time this change won't break users, but it'll instead provide better diagnostics. The reason for this post, however, is that it's possible users could be intentionally relying on this behavior. For example your application might have: unsafe extern "C" { fn js_log(n: u32); } // ... And then perhaps some JS code that looks like: let instance = await WebAssembly.instantiate(module, { env: { js_log: n => console.log(n), } }); Effectively it's possible for users to explicitly rely on the behavior of `--allow-undefined` generating an import in the final WebAssembly binary. If users encounter this then the code can be fixed through a `#[link]` attribute which explicitly specifies the `wasm_import_module` name: #[link(wasm_import_module = "env")] unsafe extern "C" { fn js_log(n: u32); } // ... This will have the same behavior as before and will no longer be considered an undefined symbol to `wasm-ld`, and it'll work both before and after this change. Affected users can also compile with `-Clink-arg=--allow-undefined` as well to quickly restore the old behavior. ## When is this change being made? Removing `--allow-undefined` on wasm targets is being done in rust-lang/rust#149868. That change is slated to land in nightly soon, and will then get released with Rust 1.96 on 2026-05-28. If you see any issues as a result of this fallout please don't hesitate to file an issue on rust-lang/rust.

blog.rust-lang.org

docs.rs: building fewer targets by default

# Building fewer targets by default On **2026-05-01** , docs.rs will make a **breaking** change to its build behavior. Today, if a crate does not define a `targets` list in its docs.rs metadata, docs.rs builds documentation for a default list of five targets. Starting on **2026-05-01** , docs.rs will instead build documentation for only the default target unless additional targets are requested explicitly. This is the next step in a change we first introduced in 2020, when docs.rs added support for opting into fewer build targets. Most crates do not compile different code for different targets, so building fewer targets by default is a better fit for most releases. It also reduces build times and saves resources on docs.rs. This change only affects: 1. new releases 2. rebuilds of old releases ## How is the default target chosen? If you do not set `default-target`, docs.rs uses the target of its build servers: `x86_64-unknown-linux-gnu`. You can override that by setting `default-target` in your docs.rs metadata: [package.metadata.docs.rs] default-target = "x86_64-apple-darwin" ## How do I build documentation for additional targets? If your crate needs documentation to be built for more than the default target, define the full list explicitly 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" ] When `targets` is set, docs.rs will build documentation for exactly those targets. docs.rs still supports any target available in the Rust toolchain. Only the default behavior is changing.

blog.rust-lang.org

Security advisory for Cargo

The Rust Security Response Team was notified of a vulnerability in the third-party crate tar, used by Cargo to extract packages during a build. The vulnerability, tracked as CVE-2026-33056, allows a malicious crate to change the permissions on arbitrary directories on the filesystem when Cargo extracts it during a build. For users of the public crates.io registry, we deployed a change on March 13th to prevent uploading crates exploiting this vulnerability, and we audited all crates ever published. We can confirm that no crates on crates.io are exploiting this. For users of alternate registries, please contact the vendor of your registry to verify whether you are affected by this. The Rust team will release Rust 1.94.1 on March 26th, 2026, updating to a patched version of the `tar` crate (along with other non-security fixes for the Rust toolchain), but that won't protect users of older versions of Cargo using alternate registries. We'd like to thank Sergei Zimmerman for discovering the underlying tar crate vulnerability and notifying the Rust project ahead of time, and William Woodruff for directly assisting the crates.io team with the mitigations. We'd also like to thank the Rust project members involved in this advisory: Eric Huss for patching Cargo; Tobias Bieniek, Adam Harvey and Walter Pearce for patching crates.io and analyzing existing crates; Emily Albini and Josh Stone for coordinating the response; and Emily Albini for writing this advisory.

blog.rust-lang.org

What we heard about Rust's challenges, and how we can address them

When we set out to understand Rust's challenges, we expected to hear about the borrow checker learning curve and maybe some ecosystem gaps. Of course, we did. A lot. But, of course, it's more nuanced. The conventional wisdom is that Rust has a steep learning curve, but once you "get it," smooth sailing awaits. We found that while some challenges disappear with experience, they are replaced with others. Beginners struggle with ownership concepts, experts face domain-specific challenges: async complexity for network developers, certification gaps for safety-critical teams, ecosystem maturity issues for embedded developers. This isn't all doom and gloom though: we ultimately found that despite Rust's challenges, it remains necessary and desired: > If all the things laid out [to make Rust better] were done, I'd be a happy Rust programmer. If not, I'd still be a Rust programmer. -- Engineering manager adopting Rust for performance ## The universal challenges that affect everyone Across every interview, regardless of experience level or domain, we heard about the same core set of challenges. These aren't beginner problems that go away—they're fundamental friction points that manifest differently as developers grow. ### Compilation performance: the universal productivity tax **Every single cohort** we analyzed—from novices to experts, from embedded developers to web developers—cited compilation times as a significant barrier to productivity: > "Java takes about 100 milliseconds, Rust anywhere from 5 seconds to a minute depending on what you changed" -- Distinguished engineer working on backend systems at a large company > "8 to 10s iteration cycle... when you want to tweak the padding on a box" -- GUI development team The impact varies by domain, but the pattern is consistent. CLI tool and GUI developers, who need rapid iteration cycles, are hit hardest. Safety-critical developers with 25-30 minute build times face workflow disruption. Size-constrained embedded developers are forced into optimized builds that take longer to compile and complicate debugging. What's particularly important to note, is that this isn't just about absolute build times; it's about the **development velocity tax** that compounds over time. Long compile times can have strong negative impact on code iteration time. Anything that can reduce this code iteration time - hot reloading, fast debug builds, faster linking - will have an outsized impact on development velocity. Moreover, the compilation performance tax compounds at scale. Individual developers might tolerate 5-10 second builds, but teams with CI/CD pipelines, large codebases, and frequent iterations face exponentially worse impacts. One participant noted 25-30 minute builds that create "wait for 30 minutes before the tool finds out I made a mistake" cycles. ### The borrow checker: first it's sour, then it's sweet The borrow checker is often touted as a "beginner problem", and we found that this is largely true: Novices are most strongly impacted by the borrow checker, but this often extends even into the stage where a developer is _comfortable_ writing Rust where they _still_ get tripped by the borrow checker sometimes. However, highly-experienced Rust developers basically never cite the borrow checker itself as a frustration for them. > Ownership: The first time I went through the chapter, I was really like, what is this? - Developer learning Rust as a first language > I actually did not understand the borrow checker until I spent a lot of time writing Rust - Executive at a developer tools company ### Async complexity: the "Three Horsemen" problem Multiple participants identified `async` as a pain point. Many people, not just beginners, often choose to completely avoid it, instead focusing solely on sync Rust. This is because, for many, `async` Rust feels completely different. > My biggest complaint with Rust is async. If we want to use [a tool], we're forced into that model...not just a different language, but a different programming model...I have zero [experience], I've been avoiding it. - Developer working on a security agent at a large company Of course, those who _do_ use it often share how complex it is, how it can feel incomplete in ways, or how it is difficult to learn. > "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" -- Software engineer with production Rust experience > "My general impression is actually pretty negative. It feels unbaked... there is a lot of arcane knowledge that you need" -- Research software engineer > "There's a significant learning gap between basic Rust and async programming... creating a 'chasm of sadness' that requires substantial investment to cross." -- Professional developer The async complexity isn't just about individual developer experience: it is exacerbated by **ecosystem fragmentation and architectural lock-in** : > "the fact that there is 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 or one of the other runtimes" -- Community-focused developer This fragmentation forces architectural decisions early and limits library compatibility, creating a unique challenge among programming languages. Of course, it would remiss to clarify that plenty of people _do_ express positive sentiments of async, often despite the mentioned challenges. ### Ecosystem navigation: choice paralysis and tacit knowledge The Rust ecosystem shows **uneven maturity across domains** : excellent for CLI tools and web backends, but significantly lacking in other domains such as embedded and safety-critical applications. This creates a fragmented adoption landscape where Rust's reputation varies dramatically depending on your domain. > "Biggest reason people don't use Rust is that the ecosystem they'd be entering into is not what they expect. It doesn't have the tooling that C++ has nor the libraries." -- Developer for a large tech company > "I think the amount of choice you can have often makes it difficult to make the right choice" -- Developer transitioning from high-level languages > "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" -- Web developer The problem isn't lack of libraries—it's that choosing the right ones requires expertise that newcomers don't have. The Rust Project has made this choice mostly intentionally though: it has chosen not to bless certain crates in order to not unduly stifle innovation. The expectation is that if a newer crate ends up being "better" than some well-established crate, then that newer crate should be become more popular; but, if the Project recommends using the more established crate, then that is less likely to happen. This is a tradeoff that might be worth reevaluating, or finding clever solutions to. ## How challenges amplify differently across domains While the core challenges are universal, different domains have unique challenges that ultimately must be either adoption blockers or acceptable trade-offs. ### Embedded systems: where every constraint matters Embedded developers face the most constrained environment for resources, which can amplify other challenges like learning. > "if you pull in a crate, you pull in a lot of things and you have no control" -- Embedded systems researcher > "can't use standard collections like hashmaps" -- Embedded software engineer Debug builds become too large for small controllers, forcing developers into optimized builds that complicate debugging. Cross-compilation adds another layer of complexity. The "no-std" ecosystem, while growing, still has significant gaps. ### Safety-critical systems: stability vs. innovation tension Safety-critical developers need Rust's memory safety guarantees, but face unique challenges around certification and tooling: > "we don't have the same tools we have to measure its safety criticality as we do in C++ and I think it's a worry point" -- Safety systems engineer > "not a lot of people know Rust not a lot of managers actually trust that this is a technology that's here to stay" -- Safety-critical developer on organizational barriers The tension between Rust's rapid evolution and safety-critical requirements for stability creates adoption barriers even when the technical benefits are clear. To note, we previously wrote a blog post all about safety-critical Rust. Check it out! ### GUI development: compile times inhibit iteration speed GUI developers need rapid visual feedback, making compilation times particularly painful: > We've got a UI framework that's just Rust code so when you want to tweak the padding on a box ... it's a pain that we just kind of accept a 10 seconds or more iteration cycle. -- Developer working on a GUI app ## Background-dependent learning paths One important insight gained from this work, and it seems obvious if you think about it, is that learning Rust isn't a universal experience: it depends heavily on your background: **High-level language developers** must learn systems concepts alongside Rust: > The challenge for me was I needed to grasp the idea of a lower-level computer science ideas and Rust at the same time. -- Developer with Typescript background **Low-level developers** often struggle to unlearn patterns and concepts: > I'm coming from C++ world so I had the big class that does everything. Taken a while for me to internalize that "dude you gotta go down a level". -- Developer with C++ background > Rust tried to hide away notion of pointers - Just tell me it's a pointer -- System-level developer Interestingly though, learning Rust alongside C++ can help students understand both better: > Students learn smart pointers in C++ and then 'we're just now learning smart pointers with Rust as well' — learning both at the same time makes it easier. -- Community organizer ## Recommendations ### Invest in compilation performance as a first-class concern Given that compilation performance affects every single user group, we recommend treating it as a first-class language concern, not just an implementation detail. This could include: * **Incremental compilation improvements** that better match developer workflows * **Build system innovations** that reduce the iteration cycle tax * **Tooling integration** that makes build times less disruptive We do want to quickly shout a couple of neat community projects that have this goal in mind: * The subsecond crate by the Dioxus team allows hot-reloading, which can make workflows like those found in GUI development more seamless * The Wild linker aims to be a fast linker for Linux, with plans for incremental linking ### Invest in ecosystem guidance and compatibility We previously made some suggestions in this area, and they still hold true. Finding ways to not only help users find crates that are useful to them, but also enable better compatibility between crates will surely have a net-positive benefit to the Rust community. ### Address learning diversity When someone is learning Rust, their programming language background, level of experience, and domain in which they are trying to work in, all influence the challenges they face. We recommend that the Rust Project and the community find ways to _tailor_ learning paths to individuals' needs. For example, for someone with a C or C++ background, it might be useful to be able to directly compare references to pointers. Similarly, having domain-specific learning materials can help newcomers focus on the problems they are facing more specifically than a general "Rust tutorial" might. The Embedded Rust Book does this, for example. ### Close the gap between sync and async Rust This is a tall order -- there are a lot of moving parts here, but it's clear that many people struggle. On one hand, async Rust feels often "incomplete" in some language features compared to sync Rust. On the other, documentation is often focused on sync Rust (for example, much of The Rust Programming Language Book is focused on sync code patterns). Within the Rust Project, we can work towards stabilizing long-awaited features such as async functions in dyn traits, or improving compiler errors for issues with, for example, lifetimes and async code. We can include fundamental async library traits and functions within `std`, enabling a more cohesive async ecosystem. Of course, as much as can be done _within_ the Rust Project, even getting more community involvement in producing tutorials, example code, and otherwise just sharing knowledge, can go a long way to closing the gap. ## Conclusion Rust's challenges are more nuanced than the conventional "steep learning curve" narrative suggests. They are domain-specific and evolve with experience. Understanding these patterns is crucial for Rust's continued growth. As we work to expand Rust's reach, we need to address not just the initial learning curve, but the ongoing friction that affects productivity across all experience levels. The good news is that recognizing these patterns gives us recommendations for improvement. By acknowledging the expertise gradient, prioritizing compilation performance, creating better ecosystem navigation, and addressing background-dependent challenges, we can help Rust fulfill its promise of empowering everyone to build reliable, efficient software.

blog.rust-lang.org

Call for Testing: Build Dir Layout v2

We would welcome people to try and report issues with the nightly-only `cargo -Zbuild-dir-new-layout`. While the layout of the build dir is internal-only, many projects need to rely on the unspecified details due to missing features within Cargo. While we've performed a crater run, that won't cover everything and we need help identifying tools and process that rely on the details, reporting issues to these projects so they can update to the new layout or support them both. ## How to test this? With at least nightly 2026-03-10, run your tests, release processes, and anything else that may touch build-dir/target-dir with the `-Zbuild-dir-new-layout` flag. For example: $ cargo test -Zbuild-dir-new-layout Note: if you see failures, the problem may not be isolated to just `-Zbuild-dir-new-layout`. With Cargo 1.91, users can separate where to store intermediate build artifacts (build-dir) and final artifacts (still in target-dir). You can verify this by running with only `CARGO_BUILD_BUILD_DIR=build` set. We are evaluating changing the default for build-dir in #16147. Outcomes may include: * Fixing local problems * Reporting problems in upstream tools with a note on the the tracking issue for others * Providing feedback on the the tracking issue Known failure modes: * Inferring a `[[bin]]`s path from a `[[test]]`s path: * Use `std::env::var_os("CARGO_BIN_EXE_*")` for Cargo 1.94+, maybe keeping the inference as a fallback for older Cargo versions * Use `env!("CARGO_BIN_EXE_*")` * Build scripts looking up target-dir from their binary or `OUT_DIR`: see Issue #13663 * Update current workarounds to support the new layout * Looking up user-requested artifacts from rustc, see Issue #13672 * Update current workarounds to support the new layout Library support status as of publish time: * assert_cmd: fixed * cli_test_dir: Issue #65 * compiletest_rs: Issue #309 * executable-path: fixed * snapbox: fixed * term-transcript: Issue #269 * test_bin: Issue #13 * trycmd: fixed ## What is not changing? The layout of final artifacts within target dir. Nesting of build artifacts under the profile and the target tuple, if specified. ## What is changing? We are switching from organizing by content type to scoping the content by the package name and a hash of the build unit and its inputs. Here is an example of the current layout, assuming you have a package named `lib` and a package named `bin`, and both have a build script: build-dir/ ├── CACHEDIR.TAG └── debug/ ├── .cargo-lock # file lock protecting access to this location ├── .fingerprint/ # build cache tracking │ ├── bin-[BUILD_SCRIPT_RUN_HASH]/* │ ├── bin-[BUILD_SCRIPT_BIN_HASH]/* │ ├── bin-[HASH]/* │ ├── lib-[BUILD_SCRIPT_RUN_HASH]/* │ ├── lib-[BUILD_SCRIPT_BIN_HASH]/* │ └── lib-[HASH]/* ├── build/ │ ├── bin-[BIN_HASH]/* # build script binary │ ├── bin-[RUN_HASH]/out/ # build script run OUT_DIR │ ├── bin-[RUN_HASH]/* # build script run cache │ ├── lib-[BIN_HASH]/* # build script binary │ ├── lib-[RUN_HASH]/out/ # build script run OUT_DIR │ └── lib-[RUN_HASH]/* # build script run cache ├── deps/ │ ├── bin-[HASH]* # binary and debug information │ ├── lib-[HASH]* # library and debug information │ └── liblib-[HASH]* # library and debug information ├── examples/ # unused in this case └── incremental/... # managed by rustc The proposed layout: build-dir/ ├── CACHEDIR.TAG └── debug/ ├── .cargo-lock # file lock protecting access to this location ├── build/ │ ├── bin/ # package name │ │ ├── [BUILD_SCRIPT_BIN_HASH]/ │ │ │ ├── fingerprint/* # build cache tracking │ │ │ └── out/* # build script binary │ │ ├── [BUILD_SCRIPT_RUN_HASH]/ │ │ │ ├── fingerprint/* # build cache tracking │ │ │ ├── out/* # build script run OUT_DIR │ │ │ └── run/* # build script run cache │ │ └── [HASH]/ │ │ ├── fingerprint/* # build cache tracking │ │ └── out/* # binary and debug information │ └── lib/ # package name │ ├── [BUILD_SCRIPT_BIN_HASH]/ │ │ ├── fingerprint/* # build cache tracking │ │ └── out/* # build script binary │ ├── [BUILD_SCRIPT_RUN_HASH]/ │ │ ├── fingerprint/* # build cache tracking │ │ ├── out/* # build script run OUT_DIR │ │ └── run/* # build script run cache │ └── [HASH]/ │ ├── fingerprint/* # build cache tracking │ └── out/* # library and debug information └── incremental/... # managed by rustc For more information on these Cargo internals, see the `mod layout` documentation. ## Why is this being done? ranger-ross has worked tirelessly on this as a stepping stone to cross-workspace caching which will be easier when we can track each cacheable unit in a self-contained directory. This also unblocks work on: * Automatic cleanup of stale build units to keep disks space use constant over time * More granular locking so `cargo test` and rust-analyzer don't block on each other Along the way, we found this helps with: * Build performance as the intermediate artifacts accumulate in `deps/` * Content of `deps/` polluting `PATH` during builds on Windows * Avoiding file collisions among intermediate artifacts While the Cargo team does not officially endorse sharing a `build-dir` across workspaces, that last item should reduce the chance of encountering problems for those who choose to. ## Future work We will use the experience of this layout change to help guide how and when to perform any future layout changes, including: * Efforts to reduce path lengths to reduce risks for errors for developers on Windows * Experimenting with moving artifacts out of the `--profile` and `--target` directories, allowing sharing of more artifacts where possible In addition to narrowing scope, we did not do all of the layout changes now because some are blocked on the lock change which is blocked on this layout change. We would also like to work to decouple projects from the unspecified details of build-dir.

blog.rust-lang.org

Announcing rustup 1.29.0

The rustup team is happy to announce the release of rustup version 1.29.0. Rustup is the recommended tool to install Rust, a programming language that empowers everyone to build reliable and efficient software. ## What's new in rustup 1.29.0 Following the footsteps of many package managers in the pursuit of better toolchain installation performance, the headline of this release is that rustup has been enabled to **download components concurrently** and **unpack during downloads** in operations such as `rustup update` or `rustup toolchain` and to concurrently check for updates in `rustup check`, thanks to a GSoC 2025 project. This is by no means a trivial change so a long tail of issues might occur, please report them if you have found any! Furthermore, rustup now officially supports the following host platforms: * `sparcv9-sun-solaris` * `x86_64-pc-solaris` Also, rustup will start automatically inserting the right `$PATH` entries during `rustup-init` for the following shells, in addition to those already supported: * `tcsh` * `xonsh` This release also comes with other quality-of-life improvements, to name a few: * When running rust-analyzer via a proxy, rustup will consider the `rust-analyzer` binary from `PATH` when the rustup-managed one is not found. * This should be particularly useful if you would like to bring your own `rust-analyzer` binary, e.g. if you use Neovim, Helix, etc. or are developing rust-analyzer itself. * Empty environment variables are now treated as unset. This should help with resetting configuration values to default when an override is present. * `rustup check` will use different exit codes based on whether new updates have been found: it will exit with `100` on any updates or `0` for no updates. Furthermore, @FranciscoTGouveia has joined the team. He has shown his talent, enthusiasm and commitment to the project since the first interactions with rustup and has played a significant role in bring more concurrency to it, so we are thrilled to have him on board and are actively looking forward to what we can achieve together. Further details are available in the changelog! ## How to update If you have a previous version of rustup installed, getting the new one is as easy as stopping any programs which may be using rustup (e.g. closing your IDE) and running: $ rustup self update Rustup will also automatically update itself at the end of a normal toolchain update: $ rustup update If you don't have it already, you can get rustup from the appropriate page on our website. Rustup's documentation is also available in the rustup book. ## Caveats Rustup releases can come with problems not caused by rustup itself but just due to having a new release. In particular, anti-malware scanners might block rustup or stop it from creating or copying files, especially when installing `rust-docs` which contains many small files. Issues like this should be automatically resolved in a few weeks when the anti-malware scanners are updated to be aware of the new rustup release. ## Thanks Thanks again to all the contributors who made this rustup release possible!

blog.rust-lang.org

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!

blog.rust-lang.org

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

blog.rust-lang.org

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!

blog.rust-lang.org

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.

blog.rust-lang.org

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.

blog.rust-lang.org

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!

blog.rust-lang.org

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!

blog.rust-lang.org

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. ↩

blog.rust-lang.org

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.

blog.rust-lang.org

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. ↩

blog.rust-lang.org