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.
1 detailed update available.
Comment by @frank-king posted on 2025-11-21:
Status update:
&pin const|mut T types, merged.&pin pattern and ref pin mut binding mode, merged.Drop::pin_drop, waiting for review (new updates since the last review).src/docs/book submodule, but the top repo and the sub repo must be changed together to pass the CI tests in both repos. It's because a default body is added to Drop::drop and it becomes a provided method instead of a required method in rustdoc. Is there any way to avoid that? (Possibly keep rustdoc treating Drop::drop as a required method?)&pin const|mut T and &{mut} T, waiting for review (fresh).TL;DR.
We have made lot's of progress with the novel place-based proposal made by @Nadrieril. Since the last update, he released his idea as a blog post and have had an immense amount of discussions on Zulip. There are still many open questions and problems left to solve. If you have any ideas, feel free to share them on Zulip.
At the beginning of this month, we explored moving projections and &own. We also looked into reducing the number of projection traits.
The PR https://github.com/rust-lang/rust/pull/146307 has been stale for this month, but will be picked up again in December.
3 detailed updates available.
Comment by @BennoLossin posted on 2025-11-01:
&ownMoving projections are a third kind of projection that already exists in Rust today for Box as well as any local variable holding a struct. While we won't be including it in an MVP, we still want to make sure that we can extend the language with moving projections. Here is an example with Box:
fn destructure_box(mut b: Box<Struct>) -> Box<Struct> {
let f1 = b.f1;
b.f1 = F1::new();
b
}
This projection moves the field out of the box, invalidating it in the process. To make it valid again, a new value has to be moved in for that field. Alternatively, the partially valid box can be dropped, this will drop all other fields of Struct and then deallocate the Box. Note that this last property is implemented by compiler magic today and moving projections would allow this special behavior for Box to be a library implementation instead.
To make this kind of projection available for all types, we can make it a proper operation by adding this trait:
pub unsafe trait ProjectMove: Projectable {
type OutputMove<'a, F: Field<Base = Self::Target>>;
unsafe fn project_move<'a, F: Field<Base = Self::Target>>(
this: *mut Self,
) -> Self::OutputMove<'a, F>;
unsafe fn drop_husk(husk: *mut Self);
}
Importantly, we also need a drop_husk function which is responsible for cleaning up the "husk" that remains when all fields have been move-projected. In the case of Box, it deallocates the memory. So for Box we could implement this trait like this:
impl<T> ProjectMove for Box<T> {
type OutputMove<'a, F: Field<Base = T>> = F::Type;
unsafe fn project_move<'a, F: Field<Base = T>>(
this: *mut Self,
) -> F::Type {
let ptr = unsafe { (*this).0.pointer.as_ptr() };
ptr::read(unsafe {
<*const T as Project>::project::<'a, F>(&raw const ptr)
})
}
unsafe fn drop_husk(husk: *mut Self) {
// this is exactly the code run by `Box::drop` today, as the compiler
// drops the `T` before `Box::drop` is run.
let ptr = (*husk).0;
unsafe {
let layout = Layout::for_value_raw(ptr.as_ptr());
if layout.size() != 0 {
(*husk).1.deallocate(From::from(ptr.cast()), layout);
}
}
}
}
To support moving back into a value we have two options:
ProjectMoveBack trait that declares an operation which accepts a value that is moved back into the projected one, or&own references.Until now, we have explored the second option, because there are lot's of other applications for &own.
&own ReferencesA small interlude on &own references.
An &'a own T is a special kind of exclusive reference that owns the value it points to. This means that if you drop an &own T, you also drop the pointee. You can obtain an &own T by constructing it directly to local variable &own my_local or by deriving it from an existing &own via field projections. Smart pointers generally also allow creating &own T from &own SmartPtr<T>.
One important difference to &mut T is that &own is not only temporally unique (i.e. there are no other references to that value not derived from it) but also unique for that value. In other words, one can create at most one &own T to a local variable.
let mut val = Struct { ... };
let x = &own val; //~ HELP: ownership transferred here
drop(x);
let y = &own val; //~ ERROR: cannot own `val` twice
Since the drop(x) statement drops val, the borrow checker must disallow any future access. However, we are allowed to move a value back into the memory of val:
let mut val = Struct { ... };
let x = &own val;
drop(x);
val = Struct { ... };
let y = &own val;
The lifetime 'a in &'a own T is that of the backing memory. It means that when 'a expires, the memory also is no longer valid (or rather it cannot be proven that it is valid after 'a). For this reason an &'a own T has to be dropped (or forgotten) before 'a expires (since after that it cannot be dropped any more).
&own T itself supports moving projections (another indicator that having them is a good idea). However only for types that don't implement Drop (similar to normal struct destructuring -- there are also talks about lifting this requirement, but no new issues arise from projecting &own).
&own and pinningTo make &pin own T with !(T: Unpin) sound in the face of panics, we have to add drop flags or have unforgettable types. We explored a design using drop flags below; there are separate efforts to experimenting with a Leak/Forget trait ongoing, I think it might be a better solution than drop flags at least for &own.
We need drop flags to ensure the drop guarantee of pinned values. The drop flag will be stored when the original &own is created and it will live on the stack of the function that created it. They are needed for the following scenario:
fn foo() {
let x = Struct { ... };
bar(&pin own x);
}
fn bar(x: &pin own Struct) {
if random() {
std::mem::forget(x);
}
if random() {
panic!()
}
}
Since x is pinned on the stack, it needs to be dropped before foo returns (even if it unwinds). When bar forgets the owned reference, the destructor is not run, if it now panics, the destructor needs to be run in foo. But since it gave away ownership of x to bar, it is possible that bar already dropped x (this is the case when the first random() call returns false). To keep track of this, we need a drop flag in the stack frame of foo that gets set to true when x is dropped.
There are several issues with drop flags:
&'static own T pointing to non-static values (for example coming from a Box::leak_owned function).Drop&own T and &pin own T, the former can be forgotten and the destructor will not run, the latter can also be forgotten, but the destructor runs regardless.This last point convinces me that we actually want &pin own T: !Leak when T: !Leak; but IIUC, that wouldn't prevent the following code from working:
fn main() {
let x = Struct { ... };
let x = &pin own x;
Box::leak(Box::new(x));
}
DerefMoveThe DerefMove operation & trait is something that has been discussed in the past (I haven't dug up any discussions on it though). It is the analogous operation of &own to Deref. We need to figure out the hierarchy wrt. Deref and DerefMut, but ignoring that issue for the moment, here is how DerefMove would look like:
trait DerefMove: DropHusk {
trait Target: ?Sized;
fn deref_move(&own self) -> &own Self::Target;
}
Note the super trait requirement DropHusk -- it provides a special drop operation for Self when the &own Self::Target reference has been dropped. Box<T> for example would deallocate the backing memory via DropHusk. Its definition looks like this:
pub unsafe trait DropHusk {
unsafe fn drop_husk(husk: *mut Self);
}
We would of course also use this trait for ProjectMove. Implementing DropHusk on its own does nothing; implementing DerefMove or ProjectMove will make the compiler call drop_husk instead of Drop::drop when the value goes out of scope after it has been projected or DerefMove::deref_move has been called.
We observed that DerefMove is a lot more restrictive in its usability than Deref--- and we need projections to make it actually useful in the common case. The reason for this is that &own can only be created once, but one would like to be able to create it once per field (which is exactly what moving projections allow). Consider this example:
let b = Box::new(Struct { ... });
let field1 = &own b.field1; // desugars to `DerefMove::deref_move`
let field2 = &own b.field2; //~ ERROR: cannot own `b` twice
The "cannot own `b` twice error comes from the way the deref desugaring works:
let b = Box::new(Struct { ... });
let field1 = &own DerefMove::deref_move(&own b).f1;
let field2 = &own DerefMove::deref_move(&own b).f2;
// ^^^ ERROR: cannot own `b` twice
Now it's clear that we're trying to create two &own to the same value and that can't work (the issue also arises for &mut, but that already is covered by ProjectExclusive).
We can write this instead:
let b = Box::new(Struct { ... });
let b = &own b;
let field1 = &own b.field1;
let field2 = &own b.field2;
But that's cumbersome.
We also note that ProjectMove is the correct projection for ArcRef, as it avoids any additional refcount updates. We can rely on the ergonomic refcounting proposal to provide ergonomic ways to clone the value & perform more projections.
Comment by @BennoLossin posted on 2025-11-02:
Project traitThe definition of the now 3 Project* traits are 100% verbatim the same (modulo renaming of course), so we spent some time trying to unify them into a single trait. While we cannot get rid of having to have three traits, we can merge them into a single one by adding a generic:
#[sealed]
pub trait ProjectKind {
type Ptr<T: ?Sized>;
}
pub enum Shared {}
pub enum Exclusive {}
impl ProjectKind for Shared {
type Ptr<T: ?Sized> = *const T;
}
impl ProjectKind for Exclusive {
type Ptr<T: ?Sized> = *mut T;
}
pub trait Projectable {
type Target;
}
pub unsafe trait Project<Kind: ProjectKind>: Projectable {
type Output<'a, F: Field<Base = Self::Target>>;
unsafe fn project<'a, F: Field<Base = Self::Target>>(
this: Kind::Ptr<Self>,
) -> Self::Output<'a, F>;
}
We would need some more compiler magic to ensure that nobody implements this trait generically, so impl<K> Project<K> for MyType, to keep our approach extensible (this could be an attribute if it is also useful in other cases #[rustc_deny_generic_impls]).
The benefit of merging the definitions is that we only have one single trait that we need to document and we could also add documentation on the ProjectKind types. There are also ergonomic downsides, for example all output types are now called Output and thus need to be fully qualified if multiple projection impls exist (<MyType as Project<Exclusive>>::Output<'_, F> vs MyType::OutputExclusive<'_, F>).
To make this proposal compatible with moving projections, we also either need more compiler magic to ensure that if Kind = Move we require Self: DropHusk. Or we could use associated traits and add one to ProjectKind that's then used in Project (Kind = Shared would then set this to Pointee).
This approach also makes me think a bit more about the syntax, if we discover more projections in the future, it might make sense to go for an extensible approach, like @keyword expr{->,.@,.,~}ident (so for example @move x->y or @mut x.y).
Comment by @BennoLossin posted on 2025-11-06:
@Nadrieril opened this zulip thread with the idea that "The normal rust way to reborrow a field uses places". He then proceeded to brainstorm a similar design for field projections with a crucial difference: making places the fundamental building block. We had a very long discussion in that thread (exchanging the existing ideas about field projection and the novel place-involving ones) that culminated in this awesome writeup by @Nadrieril: https://hackmd.io/[@Nadrieril][]/HJ0tuCO1-e. It is a very thorough document, so I will only be able to summarize it partially here:
Project* traits, we have the Place* traits which govern what kind of place operations are possible on *x given x: MySmartPtr, those are reading, writing and borrowing.@MySmartPtr <place-expr>&mut x.field.a and &mut x.field.bWe still have many things to flesh out in this proposal (some of these pointed out by @Nadrieril):
Projection trait?MaybeUninit<T>, UnsafeCell<T> and ManuallyDrop<T>?BorrowKind work as a model for the borrow checker?match ergonomics work nicely?This is a very interesting viewpoint and I'm inclined to make this the main proposal idea. The traits are not too different from the current field projection design and the special borrow checker behavior was also intended at least for the first level of fields. So this is a natural evolution of the field projection proposal. Thanks a lot to @Nadrieril for the stellar writeup!
1 detailed update available.
Comment by @aapoalas posted on 2025-11-11:
We've worked towards coherence checking of the CoerceShared trait, and have come to a conclusion that (at least as a first step) only one lifetime, the first one, shall participate in reborrowing. Problems abound with how to store the field mappings for CoerceShared.
1 detailed update available.
Comment by @davidtwco posted on 2025-11-22:
Our first RFC - rust-lang/rfcs#3873 - is in the FCP process, waiting on boxes being checked. rust-lang/rfcs#3874 and rust-lang/rfcs#3875 are receiving feedback which is being addressed.
No detailed updates available.
No detailed updates available.
1 detailed update available.
2 detailed updates available.
Comment by @nikomatsakis posted on 2025-11-05:
Three new blog posts:
Handle and other follow-up thoughtsThe most important conclusions from those posts are
move(cx.foo.clone()) || use(cx.foo).Alias or Share as the name for Handle trait; I am currently leaning towards Alias because it can be used as both a noun and a verb and is a bit more comparable to clone -- i.e., you can say "an alias of foo" just like you'd say "a clone of foo".clone and alias so that higher-level Rust gets the ergonomic benefits even when cloning "heavier-weight" types to which Alias does not apply.Comment by @nikomatsakis posted on 2025-11-12:
New blog post:
Exploring one way to make things more ergonomic while remaining explicit, which is to make .clone() and .alias() (1) understood by move closure desugaring and (2) optimized away when redundant.
1 detailed update available.
No detailed updates available.
1 detailed update available.
Comment by @Darksonn posted on 2025-11-14:
On Nov 12th, there was a mini-design meeting organized by Xiangfei Ding on inplace initialization. The attendees were Xiangfei Ding, Alice Ryhl, Benno Lossin, Tyler Mandry, and Taylor Cramer.
We discussed this document: https://hackmd.io/@rust-for-linux-/H11r2RXpgl
1 detailed update available.
Comment by @lcnr posted on 2025-11-13:
The new solver is now officially used by Rust Analyzer: https://rust-analyzer.github.io/thisweek/2025/10/27/changelog-299.html. A huge shoutout to Jack Huey Chayim Refael Friedman Shoyu Vanilla and Laurențiu Nicola for that work.
On the rustc end Rémy Rakic spent a lot of time triaging the most recent crater run. This uncovered a bunch of new edge cases, resulting in 6 new tracked issues.
We've also merged fixes for 4 minor issues over the last 3 weeks: https://github.com/rust-lang/rust/pull/148292 https://github.com/rust-lang/rust/pull/148173 https://github.com/rust-lang/rust/pull/147840. Thanks to Jana Dönszelmann, tiif and @adwinwhite for implementing these. @adwinwhite was also instrumental in diagnosing the underlying issue of https://github.com/rust-lang/trait-system-refactor-initiative/issues/245.
Going forward, we intend to continue the crater triage while fixing remaining issues until we're ready for stabilization :> the remaining issues are tracked in https://github.com/orgs/rust-lang/projects/61/views/1.
1 detailed update available.
Comment by @lqd posted on 2025-11-25:
Key developments:
a-mir-formality, so I've also joined these meetings, since we'll also want to model the alpha.1 detailed update available.
3 detailed updates available.
Comment by @nikomatsakis posted on 2025-11-12:
tiif, Jack Huey, and I met today and did more work on the "living-large" branch. The borrow checker judgments are taking shape. My expectation is that we will walk the CFG, tracking the sets of borrows that have occurred so far. At each statement, we will have a judgment that looks at (a) the subtyping relations generated by the type check (flow-insensitive, like NLL); (b) the loans issued so far and not killed; and (c) the live places that may be accessed later. We'll require then that if you are accessing a place P, then there are no loans accessible from a live place that have borrowed P in an incompatible way.
Comment by @nikomatsakis posted on 2025-11-19:
Continued work this week:
Elaborated some on the definition of the when an access or a statement is valid. We are working our way towards what we believe will be a "largely accurate" model of today's NLL -- obviously we'll then want to test it and compare behavior around various edge cases.
1 detailed update available.
Comment by @baumanj posted on 2025-11-26:
Key developments: What has happened since the last time. It's perfectly ok to list "nothing" if that's the truth, we know people get busy.
Nothing! This is the first update and I have yet to focus attention on the project goal. For context, I am employed by the Rust Foundation leading the C++ Interoperability initiative and so far have been executing against the strategy detailed in the problem statement. Owing to greater than anticipated success and deadlines related to WG21 meetings, I've been focusing on the Social Interoperability strategy recently. I have just reached a point where I can turn more attention to the other strategies and so expect to make progress on this goal soon.
Blockers: List any Rust teams you are waiting on and what you are waiting for.
None; I'm getting excellent support from the Project in everything I'm doing. My successes thus far would not have been possible without them, and there are too many to enumerate in this space. There will be a blog post coming soon detailing the past year of work in the initiative where I intend to go into detail. Watch this space for updates.
Help wanted: Are there places where you are looking for contribution or feedback from the broader community?
I am always interested in contribution and feedback. If you're interested, please reach out via interop@rustfoundation.org or t-lang/interop.
No detailed updates available.
2 detailed updates available.
Comment by @BoxyUwU posted on 2025-11-05:
Since the lang meeting most progress on this project goal has been unrelated to adt_const_params.
There's been a large amount of work on min_generic_const_args, specifically Noah Lev's PR (rust-lang/rust#139558) which once landed the core of the impl work for the feature will be done. I've reviewed it together with Oliver Scherer and it's pretty much ready to go other than some small reviews.
Once this PR lands I'm hoping that there should be a fair amount of "smallish" PRs that can be made which could be a good set of PRs to mentor new-ish contributors on.
Comment by @BoxyUwU posted on 2025-11-29:
Once again most progress here has been on min_generic_const_args.
Noah Lev's PR (rust-lang/rust#139558) has now landed, as well as an additional PR of his: rust-lang/rust#148716. Between the two of these the core impl should be "mostly done" now, atleast with no additional feature gates enabled :).
The next big step is to make the min_generic_const_args prototype work well with adt_const_params which I've implemented myself in rust-lang/rust#149136 and rust-lang/rust#149114. These PRs still need to be reviewed but the bulk of the impl work there is now done. These PRs allow for constructing ADTs where the field values may themselves be const parameters or non-concrete uses of type_consts (ie the values are const argument positions).
Once my PRs have landed I would consider mgca as a prototype to be truly "done" though not done as an actual feature. Huge thanks to camelid for sticking through a bunch of fairly painful PRs to get us to this point.
2 detailed updates available.
Comment by @obi1kenobi posted on 2025-11-02:
Status update as of November 1
Key developments:
Linting ?Sized and 'static bounds turned out to be quite a bit more complex than I anticipated. The key issue is that seeing T: Foo + ?Sized does not guarantee that T can be unsized, since we might have Foo: Sized which renders the ?Sized relaxation ineffective. Similarly, seeing T: Foo might also non-obviously imply T: 'static via a similar implied bound.
Failure to correctly account for implied bounds would lead to catastrophic false-positives and false-negatives. For example, changing T: Foo to T: Foo + 'static could be a major breaking change or a no-op, depending on whether we have Foo: 'static (either directly or implicitly via other trait bounds).
We cannot determine implied bounds using information present in rustdoc JSON today, so the rustdoc team and I have been iterating on the best way to compute and include that information in rustdoc JSON. Assuming something similar to the aforementioned PR becomes part of rustdoc JSON, cargo-semver-checks stands to gain several dozen new lints covering these tricky cases over trait associated types, generic type parameters, and APIT/RPIT/RPITIT.
Comment by @obi1kenobi posted on 2025-11-23:
Google Summer of Code 2025 is complete + finally some movement on cross-crate linting! 🚀
Key developments
cargo-semver-checks — find more details here!2 detailed updates available.
Comment by @PLeVasseur posted on 2025-11-05:
Meeting minutes from meeting held on 2025-10-31 (thank you to Tomas Sedovic 🥰)
Top-level:
Discussion:
1 detailed update available.
Comment by @icmccorm posted on 2025-11-11:
We've posted a pre-RFC for feedback, and we'll continue updating and expanding the draft here. This reflects most of the current state of the implementation, aside from tracking interior mutability precisely, which is still TBD but is described in the RFC.
1 detailed update available.
Comment by @joshtriplett posted on 2025-11-12:
We're putting together a prototype/demo of our reference changes at https://rust-lang.github.io/project-goal-reference-expansion/ . This includes a demonstration of tooling changes to provide stability markers (both "documenting unstable Rust" and "unstable documentation of stable Rust").
1 detailed update available.
Comment by @epage posted on 2025-11-21:
Key developments:
#[test] macro addedshould_panicignoreBlockers
Help wanted:
1 detailed update available.
Comment by @ZuseZ4 posted on 2025-11-19:
Time for the next update. By now, we've had std::autodiff for around a year in upstream rustc, but not in nightly. In order to get some more test users, I asked the infra team to re-evaluate just shipping autodiff as-is. This means that for the moment, we will increase the binary size of rustc by ~5%, even for nightly users who don't use this feature. We still have an open issue to avoid this overhead by using dlopen, please reach out if you have time to help. Thankfully, my request was accepted, so I spent most of my time lately preparing that release.
main.rs file, but also in dependencies (either lib.rs, or even rely on crates that use autodiff). With the help of Ben Kimock I figured out how to get the remaining cases covered, hopefully the PR will land soon.lto=fat: https://github.com/rust-lang/rust/pull/148855I have the following elements on my TODO list as part shipping AD on nightly
AMD Ryzen 7 PRO 7840U unfortunately turned out to be not supported by AMD drivers.All in all, I think we made great progress over the last month, and it's motivating that we finally have no blockers left for flipping the llvm.enzyme config on our nightly builds.
2 detailed updates available.
Comment by @tomassedovic posted on 2025-11-28:
Update form the 2025-11-19 meeting:
-Zharden-sls / rust#136597Andrew addressed the comment and rebased the PR. It's waiting for a review again.
#![register_tool] / rust#66079Tyler Mandry had an alternative proposal where lints would be defined in an external crate and could be brought in via use or something similar: https://rust-lang.zulipchat.com/#narrow/channel/213817-t-lang/topic/namespaced.20tool.20attrs.
A concern people had was the overhead of having to define a new crate and the potential difficulty with experimenting on new lints.
Tyler suggested adding this as a future possibility to RFC#3808 and FCPing it.
2 detailed updates available.
Comment by @tomassedovic posted on 2025-11-28:
Update from the 2025-11-19 meeting.
rustdoc checking for private and hidden items (rust##149105 & rust#149106)Miguel proposed Rust Doc checking for invalid links to items that are hidden or private even if no docs are built for them. This can help catch typos or dead links because the docs became out of date.
Guillaume was much more open to this being a toggle, lolbinarycat opened a PR here: https://github.com/rust-lang/rust/pull/141299
unsafe_op_in_unsafe_fn not respected in imported declarative macros rust#112504This lint doesn't trigger when importing a declarative macro that's calling unsafe code without having an unsafe block and without a SAFETY comment.
The lint is only triggered when the macro was actually used.
imports_granularity is not respected for #[cfg]'d items / rustfmt#6666Ding opened a PR to fix this: https://github.com/rust-lang/rustfmt/issues/6666
Ding and Manish were talking about writing up a proper fix for the vertical layout that's currently being solved by the , //, hack
TypeId layoutThis has been discussed in https://github.com/rust-lang/rust/pull/148265 and https://rust-lang.zulipchat.com/#narrow/channel/213817-t-lang/topic/TypeID.20design/near/560189854.
Apiraino proposed a compiler design meeting here: https://github.com/rust-lang/compiler-team/issues/941. That meeting has not been scheduled yet, though.
Deref / ReceiverFollowing TC's recommendation, Ding is drafting the Reference PR.
derive(CoercePointee)Ding opened a PR to fix unsoundness in the DispatchFromDyn trait: https://github.com/rust-lang/rust/pull/149068
Theemathas opened a question on whether Receiver should by dyn-compatible: https://github.com/rust-lang/rust/issues/149094
const in assemblyMerged!
Benno noted that Effects and In-place Init are not compatible with each other: https://rust-lang.zulipchat.com/#narrow/channel/528918-t-lang.2Fin-place-init/topic/Fundamental.20Issue.20of.20Effects.20and.20In-place-init/with/558268061
This is going to affect any in-place init proposal.
Benno proposes fixing this with keyword generics. This is a topic that will receive a lot of discussion doing forward.
language-advisor. Fantastic news and congratulations!No detailed updates available.
1 detailed update available.
Comment by @Amanieu posted on 2025-11-15:
An RFC draft covering the MIR changes necessary to support this optimization has been written and is currently being reviewed by T-opsem. It has already received one round of review and the feedback has been incorporated in the draft.
| Progress | |
| Point of contact | |
| Task owners |
|
No detailed updates available.
2 detailed updates available.
Comment by @weihanglo posted on 2025-11-04:
Instead of using a full-fledged database like SQLite, we switched to a basic JSONL-based logging system to collect build metrics. A simple design doc can be found here: https://hackmd.io/K5-sGEJeR5mLGsJLXqsHrw.
Here are the recent pull requests:
To enable it, set CARGO_BUILD_ANALYSIS_ENABLED=true or set the Cargo config file like this:
[build.analysis]
enabled = true
As of today (nightly-2025-11-03), it currently emits build-started and timing-info two log events to $CARGO_HOME/log/ (~/.cargo/log/ by default). The shape of timing-info JSON is basically the shape of the unstable --timing=json. I anticipate when this is stabilized we don't need --timing=json.
The build.analysis.enable is a non-blocking unstable feature. Unless bugs, should be able to set unconditionally even on stable toolchain. When not supported, it would just warn the unknown config merely.
Comment by @weihanglo posted on 2025-11-24:
Key developments: Started emitting basic fingerprint information, and kicked off the refactor of rendering HTML timing report for future report replay through cargo report timings command.
Blockers: no except my own availability
Help wanted: Mendy on Zulip brought up log compression (#t-cargo > build analysis log format @ 💬) but I personally don't have time looking at it durnig this period. Would love to see people create an issue in rust-lang/cargo and help explore the idea.
1 detailed update available.
1 detailed update available.
Comment by @ranger-ross posted on 2025-11-21:
October was largely spent working out design details of the build cache and locking design.
https://github.com/rust-lang/cargo/pull/16155 was opened with an initial implementation for fine grain locking for Cargo's build-dir however it needs to be reworked after the design clarifications mentioned above.
In November I had a change of employer so I my focus was largely on that. However, we did make some progress towards locking in https://github.com/rust-lang/cargo/pull/16230 which no longer lock the artifact-dir for cargo check. This is expected to land in 1.93.0.
I'm hoping to push fine grain locking forward later this month and in December.
1 detailed update available.
1 detailed update available.
Comment by @jakos-sec posted on 2025-11-21:
We've had a bunch of discussions and I opened a MCP (link, zulip).
I think the final sentiment was creating new targets for the few sanitizers and platforms that are critical. I'm in the process of prototyping something to get new feedback on it.
1 detailed update available.
Comment by @nikomatsakis posted on 2025-11-05:
Update:
Jack Huey has been doing great work building out a system for analyzing interviews. We are currently looking at slicing the data along a few dimensions:
and asking essentially the same set of questions for each, e.g., what about Rust worked well, what did not work as well, what got you into Rust, etc.
Our plan is to prepare a draft of an RFC with some major conclusions and next steps also a repository with more detailed analysis (e.g., a deep dive into the Security Critical space).
1 detailed update available.
Comment by @Kobzol posted on 2025-11-19:
The new system has been running in production without any major issues for a few weeks now. In a few weeks, I plan to start using the second collector, and then announce the new system to Project members to tell them how they can use its new features.
No detailed updates available.
No detailed updates available.
2 detailed updates available.
Comment by @nikomatsakis posted on 2025-11-05:
Notes from our meeting today:
only keywordWe are exploring the use of a new only keyword to identify "special" bounds that will affect the default bounds applied to the type parameter. Under this proposal, T: SizeOfVal is a regular bound, but T: only SizeOfVal indicates that the T: const Sized default is suppressed.
For the initial proposal, only can only be applied to a known set of traits; one possible extension would be to permit traits with only supertraits to also have only applied to them:
trait MyDeref: only SizeOfVal { }
fn foo<T: only MyDeref>() { }
// equivalent to
trait MyDeref: only SizeOfVal { }
fn foo<T: MyDeref + only SizeOfVal>() { }
We discussed a few other syntactic options:
^SizeOfVal sigil was appealing due to the semver analogy but rejected on the basis of it being cryptic and hard to google.only T: SizeOfVal sort of made sense, but it would not compose well if we add additional families of "opt-out" traits like Destruct and Forget, and it's not clear how it applies to supertraits.After testing, we confirmed that relaxing Target bound will result in significant breakage without some kind of transitionary measures.
We discussed the options for addressing this. One option would be to leverage "Implementable trait aliases" RFC but that would require a new trait (Deref20XX) that has a weaker bound an alias trait Deref = Deref20XX<Target: only SizeOfVal>. That seems very disruptive.
Instead, we are considering an edition-based approach where (in Rust 2024) a T: Target bound is defaulted to T: Deref<Target: only SizeOfVal> and (in Rust 20XX) T: Target is defaulted to T: Deref<Target: only Pointee>. The edition transition would therefore convert bounds to one of those two forms to be fully explicit.
One caveat here is that this edition transition, if implemented naively, would result in stronger bounds than are needed much of the time. Therefore, we will explore the option of using bottom-up analysis to determine when transitioning whether the 20XX bound can be used instead of the more conservative 2024 bound.
We explored the implications of weakening supertrait bounds a bit, looking at this example
trait FooTr<T: ?Sized> {}
struct Foo<T: ?Sized>(std::marker::PhantomData<T>);
fn bar<T: ?Sized>() {}
trait Bar: FooTr<Self> /*: no longer MetaSized */ {
// ^^^^^^^^^^^ error!
// real examples are `Pin` and `TypeOf::of`:
fn foo(&self, x: Foo<Self>) {
// ^^^^^^^^^^^^ error!
bar::<Self>();
// ^^^^^^^^^^ error!
// real examples are in core::fmt and core::iter:
trait DoThing {
fn do_thing() {}
}
impl<T: ?Sized> DoThing for T {
default fn do_thing() {}
}
impl<T: Sized> DoThing for T {
fn do_thing() {}
}
self.do_thing();
// ^^^^^^^^^^^^^ error!
// specialisation case is not an issue because that feature isn't stable, we can adjust core, but is a hazard with expanding trait hierarchies in future if stabilisation is ever stabilised
}
}
The experimental_default_bounds work originally added Self: Trait bounds to default methods but moved away from that because it could cause region errors (source 1 / source 2). We expect the same would apply to us but we are not sure.
We decided not to do much on this, the focus remains on the Deref::Target transition as it has more uncertainty.
Comment by @davidtwco posted on 2025-11-22:
No progress since [Niko Matsakis's last comment](https://github.com/rust-lang/rust-project-goals/issues/270#issuecomment-3492255970) - intending to experiment with resolving challenges with Deref::Target and land the SVE infrastructure with unfinished parts for experimentation.
2 detailed updates available.
Comment by @BoxyUwU posted on 2025-11-05:
A bit late on this update but I've sat down with lcnr a little while back and we tried to come up with a list of topics that we felt fell under type system documentation. This is an entirely unordered list and some topics may already be adequately covered in the dev guide already.
Regardless this effectively serves as a "shiny future" for everything I'd like to have documentation about somewhere (be it dev guide or in-tree module level documentation):
use<...> work'erased regions causes problems with outlives item bounds in livenessFn bounds are somewhat special in relation to thisimpl Traitimpl Trait in bindingsty::Infer in ty overview-Zhigher-ranked-assumptions existsexistsA forallB A == BSince making this list I've started working on writing documentation about coercions/adjustments. So far this has mostly resulted in spending a lot of time reading the relevant code in rustc. I've discovered a few bugs and inconsistencies in behaviour and made some nice code cleanups which should be valuable for people learning how coercions are implemented already. This can be seen in #147565
I intend to start actually writing stuff in the dev guide for coercions/adjustments now as that PR is almost done.
I also intend to use a zulip thread (#t-compiler/rustc-dev-guide > Type System Docs Rewrite) for more "lightweight" and informal updates on this project goal, as well as just miscellaneous discussion about work relating to this project goal
Comment by @BoxyUwU posted on 2025-11-29:
I've made a tracking issue on the dev guide repo for this project goal: rust-lang/rustc-dev-guide#2663. I've also written documentation for coercions: rust-lang/rustc-dev-guide#2662. There have been a few extra additions to the list in the previous update.
No detailed updates available.