---
title: Triage meeting 2025-11-12
tags: ["T-lang", "triage-meeting", "minutes"]
date: 2025-11-12
discussion: https://rust-lang.zulipchat.com/#narrow/channel/410673-t-lang.2Fmeetings/topic/Triage.20meeting.202025-11-12/
url: https://hackmd.io/wXstw3uTREiRL_7Ay-0hqQ
---
# T-lang meeting agenda
- Meeting date: 2025-11-12
## Attendance
- People: TC, Tomas, dianne, Jack, theemathas, Eric Holk, Josh, Scott, tmandry, Yosh, Amanieu, Niko
## Meeting roles
- Driver: TC
- Minutes: Tomas
## Scheduled meetings
- 2025-11-12: Extended triage and champion review
Edit the schedule here: https://github.com/orgs/rust-lang/projects/31/views/7.
## Announcements or custom items
(Meeting attendees, feel free to add items here!)
### Guest attendee items
TC: For any guests who are present, please note in this section if you're attending for the purposes of any items on (or off) the agenda in particular.
### Moving right along
TC: As we've been doing recently, due to the impressive backlog, I'm going to push the pace a bit. If it's ever too fast or you need a moment before we move on, please raise a hand and we'll pause.
### Design meeting at 12:30 EST / 09:30 PST / 17:30 CET
TC: Remember that we have a design/planning meeting that starts half an hour after this call ends.
### Next meeting with RfL
We're next meeting with RfL on 2025-11-19 to review the status of RfL project goals.
https://github.com/rust-lang/rfcs/pull/3614
## Nominated RFCs, PRs, and issues
### "Trait method impl restrictions (`final` methods)" rfcs#3678
**Link:** https://github.com/rust-lang/rfcs/pull/3678
Josh: Requested a number of times. Recently came up during libs api discussion. Went through FCP but had discussions around syntax. We cancelled the FCP because of that. I updated the RFC to use the `final` keyword (which we already have reserved) and moved the rest to alternatives. The syntax is an unresolved question. I'm proposing FCP based on that.
```rust!
trait MyTrait: Display {
final fn method(&self) {
println!("MyTrait::method: {self}");
}
}
```
Tyler: I like the proposed syntax. I'm wary of leading syntax as an open question. It's deferring the hard question for later.
Josh: I'd love to resolve this before FCP. I left it that way so we don't have to argue about alternative possibilities, because we always have the ability to change our minds before stabilization.
TC: One question. What's the prospect of us being able to stabilize enough of specialization to address this. I.e.:
```rust
trait Tr {
fn f();
}
default impl<T: Tr> Tr for T {
fn f() {}
}
```
TC: Could we carve out enough of the specialization syntax to get that through instead of final fn.
Josh: How does this relate to `final`?
Scott: Final is the opposite -- you can't override these.
This is for
```rust
trait Copy : Clone {
final fn copy(&self) -> Self { *self }
}
```
that *nobody*, specialization or not, can change what it does.
TC: You set the default impl but don't mark the final impl as default and that should prevent you from modifying it.
Niko: You get that right, but syntax-wise we can consider that specialization RFC deprecated due to syntax. But it was supposed to allow this.
Tyler: If we do have specialization we'll have to unify these. But the `final` proposal can be a simplified syntax.
Niko: The default in specialization is flipped in trait declarations. In an impl is "this can't be changed". In a trait it's the opposite. So even in specialization there's need for a `final`-like keyword. The other alternative is to go over an edition to get everyone write `default fn` for every function body in a trait. And even then we'd still want `final fn`.
```rust
// In Rust 9999 you could conceivably say that you should write
trait Foo {
fn required(&self);
default fn optional(&self) {
self.required()
}
}
// but today we have "flipped defaults" in traits and impls, so...
trait Foo {
fn required(&self);
/* default */ fn optional(&self) {
self.required()
}
}
```
Scott: I like saying "`final fn` is what we want to do. And there's always an option to change it later."
Josh: +1 to Scott. It sounds like there might be a way to do this as a side-effect of specialization. But given Niko's point that this is something we could get `final` to clarify and specialization is far away, then sounds like we should do this and then possibly use it in specialization.
TC: I wasn't asking to block this on specialization. More if we had an idea of the syntax for specialization, could we stabilize a narrow aspect to do just this. I'm very much in favor of specifying the syntax in RFC. My position on my syntax proposal has softened. I'm fine with the `final` keyword.
TC: Inherent impls on traits is more than just a diffent syntax. It's a more powerful semantics when you start thinking about generic parameters. But then you need a disambiguation syntax to say you're invoking an inherent impl in trait. So that's something else and this is a nice convenience.
Tyler: I'd like to propose to move on.
Niko's take: I am in favor of `final`. I would *like* to be able to write `default fn` as well. I don't want to block on that. I like the idea of having the ability to be explicit about which option you want. To that end, I would want to allow (but lint against, as it is the default) `final fn` in an impl.
Josh: Next steps: I'll capture more in the Future Possibility section and not treat the syntax as unresolved.
TC: Do we have an experiment?
Josh: Someone was generous enough to do a sample implementation with the `final` attribute. So yes, we have a basically functional implementation that just needs to use the syntax we settled on.
Amanieu: The main motivation in the libs API is to have a final method that's generic without affecting dyn compatibility. On the `Read` trait which is often `dyn Read` we want to return a method that is generic over `N`.
Tyler: Also useful for the visitor pattern.
### "Explicitly export core and std macros" rust#139493
**Link:** https://github.com/rust-lang/rust/pull/139493
TC: The background: trying to make macros more path-like. It exports all macros by path from std and core. This PR would stop putting macro_use when bringing in core.
Tyler: Is this a breaking change?
TC: It is a breaking change. The breakage seems to be small and addressed.
https://github.com/rust-lang/rust/pull/139493#issuecomment-3502578964
Amanieu: I can say whi libs api wants tthis. `macro_use` on a crate imports every macro present in the crate root. It's a breaking change to add any macro to the prelude. Because it will conflict to the user-defined macros. We can't deprioritise macros over user-defined macros. We can only add macros to the prelude over edition. We want to do this for `assert_matches!`
Josh: We do have shadowing for macros in general. But the prelude import that provides new macros doesn't get shadowed by a wildcard import. So if someone does a wildcard import of another prelude/module this won't get shadow.
Amanieu: This happenson tests which do `use super::*`.
Josh: What happens if someone does `no_std` and they explicitly import std (or `no_core` and manually import core). Will it change which macros they get? My guess is no as it's up to them to decide whether they're importing macros or not?
TC: Do you mean https://github.com/rust-lang/rust/pull/139493#issuecomment-3502578964
Niko: How is panic handled? Do we special-case panic?
Amanieu: The `panic` macro in std is different from the `panic` macro for core. If you're doing the glob import that would pick up both, it would cause an ambiguity error.
Niko: And so what did we do?
Amanieu: We worked around it by continuing to use `macro_use` but only for the panic macro, not anything else? We're putting `macro_use` on the extern crate. `macro_use` supports an argument to only import a specific macro.
Amanieu: Sorry, that's not what we do. We've changed that since.
Niko: It looks like we're modifying name resolution. When the word panic is ambiguous, it'll issue a lint and prefer `core::panic`. It's gated on the edition, a new edition would fix this.
TC: We table this pending the author giving us a stabilization report that includes this edition detail. The lint is called `warn` and report-in-deps is true. We typically report-in-deps on `deny` lints.
Niko: I wouldn't warn in deps, you can't do anything with it.
Tyler: Agreed, and it sounds like the impact is too high to break the existing code.
### "Tracking issue for `pub use` re-export of macros from within submodules without `macro_export`" rust#148610
**Link:** https://github.com/rust-lang/rust/issues/148610
TC: Jane has a project goal to fill in the Reference. She's writing up name resolution for us all. When you macro export a macro, it makes it resolvable by path. But it also forces it into the root crate. There's no way to make a macro in a submodule and make it path-resolvable without putting it into root.
TC: Right now, all macros are `pub(crate)`. We could just make it `pub` instead. That doesn't publish it in the crate on its own. Just makes it path-resolvable without putting it into root. I'd propose to change the default. Raising it here.
Josh: There's a lot of detail in the expansion and name resolution code to handle the difference between path-based macros and "classic" macros. That's created a lot of problems over the years. An alternative (but not a blocker to the experiment), we could allow you to put a visibility on the macro_rules. We could let you write `pub macro_rules!` instead of `pub use macro_name`. People expect that to work. Disadvantage: macros are currently `pub(crate)`. We could keep them `pub(crate)` and in a future edition we could default them to `pub(self)`.
Tyler: If I have a macro inside a public module and I don't have `macro_export` would flipping this bit let me address it from the outside of the crate?
TC: No, macros don't get path visibility by default.
Tyler: But it would if you do `macro_export`?
TC: Yes.
Josh: Why they're kinda `pub(crate)` now. Imagine you write an inline module, `mod name { ... }`. You can write a macro above that and use it inside the module, because it's *textually* visible.
TC: There's a section in the Reference. We call it "textual scoping"
Niko: I think they apply for the external files too? I think it applies in everything in the AST starting with the macro definition.
Josh: You might be right. These are really gnarly and complicated.
Niko: I've no problem with this proposal. Also no problem with Josh's proposal.
Josh: My understanding is that it would be confusing it to the existing textual scoping. If we're going this route, we'd want to transition away from textual scoping and just do path-based scoping all the time. In the current edition we'd do it for `pub(crate)` and `pub(self)`.
TC: I like the experiment as proposal as it doesn't do anything special, just flips the bit. But it fits within the broader story.
Josh: I definitely think we should try the experiment as proposed. But we could also see if we could aim for this transition.
### "`derive(PartialEq)` on enums is unsound with user-defined attribute macros." rust#148423
**Link:** https://github.com/rust-lang/rust/issues/148423
TC: theemathas discovered something new. Thank you. If you have a proc macro that discards its TokenStream, apply it to enum and you derive `PartialEq`, it sees the wrong thing, generates wrong code and it's unsound.
Niko: Is this in part because `derive(PartialEq)` is using the enum's discriminant under the hood.
Tyler: It sees the ??
Josh: That wouldn't do it on its own. It assumes it's using the correct thing and uses unsafe for performance.
Tyler: We've had several derives like that.
Scott: This used to have the more obvious expansion. But then people applied it to really big enums and the partialeq would take a long time to compile because it ran into quadratic enum matching.
Niko: 3 questions: can we fix partialeq to be not UB? (clearly yes). Are we ok with it not being UB but being odd? Third: can we tweak the system to avoid this problem? We went to some lengths to make derives safer but we didn't get to this.
Niko: For lang questions, I'd focus on the last one. I'd rather people not think about this.
Tyler: What code should you generate to do this?
Scott: You could write a code that matches all the items.
Niko: or write the match exhaustively without the underscore.
TC: I think Petrochenkov wanted to standardise things in top-to-bottom left-to-right order. But there's a lot of special cases where we reorder things.
Tyler: I also expected it to work in reverse order.
Josh: Without a compatibility issue, we could make this defensive to allow us to have a pseudo-hygienic derive here. If you later define a different definition of a new enum, they would be treated as different and it wouldn't typecheck.
Josh: We can't really fix this in general without breaking backcompatibiilyt without benig defensive. If you run the derive and then the attribute, then the attribute should see the result in the derive. And vice versa. So derive should either see the code being delete and error out. Or the attribute should see the expansion provided by the derive and discard it.
Scott: I wouldn't expert the proc macro to look through the derive to `PartialEq`
TC: Josh, if the derive was on top, it would see the unexpanded attribute and then you'd run it in the top-to-bottom order
Josh: Today, it's a mix of both. I never expect top-to-bottom, I always expect bottom-to-top. We don't do that but that's always surprising me. The point is, whichever order you apply it in, this is clearly wrong. Here you apply the derive, then generate some code and then apply the attribute to the not-generated code and the derive is discarded.
Josh: So either you run the derive, generate code and then hand it over to the attribute. Or run the attribute, delete the code and
Amanieu: The ordering that makes sense to me is always write attribute macros first and then derive macros. Attributes can ??. So the derive macro would only see what's actually generated.
Niko: I agree with Josh that if you have a macro that discards all its input, the derive would have nothing to do and that wouldn't be unsound. But you could have a macro that does something else that would be unsound. It's a different kind of unsafe than what we're accustomed to.
What does it mean for derive to generate unsafe code. That does suggest Amanieu's approach. Otherwise there's no basis to use unsafe there.
Niko: Amanieus' suggestion is that `PartialEq` always sees the struct definition. If you ever allow a macro on the output of a derive (which is somethingh we could do), it could be unsafe.
Scott: The reason I asked about ordering is to look at what attributes exist and see if the derive is there and then issue a warning. That's a non-breaking change that we could later upgrade to `deny`.
Jack: What's the best reason to want to runa macro after derive? Something like serde where you might have a derive or something that's not an actual struct? But that seems weird.
Josh: Telling people to always write their attributes before `Derive` is a good thing to recommend. But they can't sometimes reorder because they might depending on the order.
TC: What could be relying on to get the breakage?
Josh: Both proc-macros and derive are general Rust code. That means anything coudl be broken. But I've seen debugging attributes that would dump all the tokens they were given.
Niko: Let's say something modify a pair of struct definition and generated code in an interpreter that could be run in runtime. I think you could do that in other ways though. Fundamentally, we can't prevent people from running macros that take unsafe code that expected noone would touch the code and then change it.
Josh: It would be a breaking change to hand the tokens from the derive to the attribute. You could have an attribute that could handle only certain tokens. In practice you expect to process what's there and not what's not there. The config-eval example that the maathas put in the chat is ??
Josh: People have inert attributes (where the attribute is only there to be seen by the derive). You can also have an attribute that's not inert
Niko: I don't know what happens when derives get things beyond just the data structure. Does the derive always see the unexpanded data structure? Do the things the attribute adds get pased to the derive?
TC: The attribute is only going to get passed one form. It's always going to get one item.
Josh: I'd propose we look at a minimum possible change in the current edition to minimize the risk of hitting this in practice.
And then, decide the order and handling we actually want for a macro system that makes sense. And make plan to do that in another edition.
TC: Before I commit to this in an edition, I want us to come up with the ordering we want and then do a crater run and think about the transition then.
Jack: I agree. I'd be surprised if someone's relying on the order.
Josh: We just had an example of people relying on it in the order: https://rust-lang.zulipchat.com/#narrow/channel/122651-general/topic/Order.20of.20.23.5Bderive.28.29.5D.20directives.20influences.20codegen/near/554834378 (the `cfg_eval` example)
## Champion updates
People: Josh, Tomas, TC, Niko, Jack, Dianne, Tyler, elle, Yosh, Amanieu
Niko: My plan was to look at: https://github.com/rust-lang/rust-project-goals/issues?q=is%3Aissue%20state%3Aopen%20label%3AT-lang, go through goals one by one, look at updates and see what's there
### "Design a language feature to solve Field Projections" rust-project-goals#390
**Link:** https://github.com/rust-lang/rust-project-goals/issues/390
nikomatsakis: Question. With `&own`, ah, well, I guess I answer my own question -- if you `forget` the `&own`, you effectively forget the value within. OK.
Josh: This looks really well done, extremely on track. First impression: yes. How will this interact with references you can't actually materialize. But that looks like it can come in the future.
Tyler: I looked at Nadri's comment today. It's an exciting way of framing the problem. You could have virtual places along the lines of what you were saying Josh. If you have a struct-of-arrays, you can index the element and project the field. We don't have to go that route, but it seems like a natural fit.
Josh: Is what you're describing something that could fix the `Index` trait to no longer assume indexes?
Tyler: I hope so.
TC: I still have some questions about whether we need separate project mechanisms for `mut` and `const`; my model of projection is that it should be type preserving (including the `&mut`/`&`). This is the model of projection we're using for the pin ergonomics work. Conversely, if we did have `mut`/`const` projections, then it makes me suspect we may end up needing separate projection variants for other properties of places, such as whether they're pinned, non-forgettable, etc. But there's a lot to look at, and I'm curious to read Nadri's proposal, so I withhold judgment here.
Tyler: Nadri's proposal lets you have many different kinds of projections to a single place.
### "Reborrow traits" rust-project-goals#399
**Link:** https://github.com/rust-lang/rust-project-goals/issues/399
> 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.
Tyler: The `Reborrow` trait allows you to have a smart pointer type that you can borrow as a shorter mutable pointer to the same pointee and hand that out. The original proposal used multiple lifetime parameters. That led to problems so Aapo's looking into having a single lifetime parameter.
Niko: It would be interesting to see what this looks like sketched out for the next time.
Tyler: Draft RFC: https://github.com/aapoalas/rfcs/blob/autoreborrow-traits/text/0000-autoreborrow-traits.md
### "Ergonomic ref-counting: RFC decision and preview" rust-project-goals#107
**Link:** https://github.com/rust-lang/rust-project-goals/issues/107
https://github.com/rust-lang/rust-project-goals/issues/107#issuecomment-3492295013
Niko: First, I've come around for where we want to be is "low enough for the kernel, usable enough for a GUI". There are downsides of clone. I've come around to naming the trait either `Share` or `Alias`. Alias is also a noun (you can say "a clone/alias" of a thing). I talked about explicit capture clauses:
```rust
move(self.some_context_or_other.clone()) || {
foo_process(self.some_context_or_other)
// -----
bar(x.y.foo)
}
```
Niko: They're great for being explicit but I wouldn't consider them usable enough for GUI. My last blog ("just call clone") is explicit enough to see that a clone is happening and usable enough:
```rust!
let future = async move {
foo_process(self.some_context_or_other.clone())
}; // ----------------------------------
```
Niko: I could see people being a bit weirded out by this, it pushes new bounds. But also the more I think about it the more I kind of like it.
Tyler: Does the last-use-thing happen in the closure?
Niko: Yes, it would optimize away the unnecessary clones.
```rust
fn foo(x: String) -> String {
x.clone()
//------- transformed away with a warning
}
fn foo(x: String) -> String {
let clone_x: impl FnOnce() = || x.clone();
// --------- transformed away with a warning
clone_x()
}
```
Josh: I love where this currently is and where it's going. This should be easy to use and work for a low level code. The term `alias` is the only one I've seen that I really like. last-use feels like the exactly the right answer. We should do it but we should have special syntax for it. If it's magic in the compiler, then we should make it look different than function calls.
Niko: Note that `vec.push(..)` and `vec.len()` capture by reference (mutable/shared) without any syntax. But I like the suggestion and I want to explore it more. I'm interested in vibes.
Tyler: Overall I like explicit capture clauses, and if we can get away with the "place rewriting" thing it seems good. But agreed that we should have a more convenient way.
Tyler: When talking to people about the developments anecdotally I heard 1-2 say that they liked `.use` over the new proposals because of ergonomics.
Tyler: I like `Share` as a name, so happy you've come around :). (I think `Alias` is also ok.)
TC: Need to catch up and read the blog posts; I've always generally wanted explicit capture clauses, but one thing I'd always struggled with on this is how to express this syntactically in a way that's appealing once these capture clauses get long enough they'll split across multiple lines. Once it does that, there is a part of me that struggles with whether it really ends up being much of an improvement over the desugaring (wrapping it in a block and adding the `let` bindings, then making it a `move` closure).
TC: On the idea of `Alias` in general, I've seen recent discussion about cases that wouldn't neatly fall in this category. Probably I do have concern about, if special ergonomics are attached to this, that people would end up using this to achieve this ergonomic effect in the language regardless of the intended semantic for it. It's something to think more about.
Niko: I addressed that in the blog. That's why I gave the same ergonomics to clone and alias.
TC: Good good.
Josh: Also, it's less important if people "misuse" Alias in the new model. Previously alias (in the guise of `use`) might be implicit while clone wasn't, so it was important to get the semantics right and make the distinction. But if we're making both of them explicit, and giving them *both* magic "float out of "
Niko: I'm still trying to figure out what to do with the capture clauses. Happy to hear suggestions.
jackh726: fwiw, reddit definitely did *not* like the last blog post:
https://old.reddit.com/r/rust/comments/1otrast/just_call_clone_or_alias_baby_steps/
nikomatsakis: (not at all surprised to hear that)
Yosh: I like explicit capture clauses; it matches what Rust-Analyzer already does with its capture hints.
Yosh: I wonder whether the ergonomics of explicit capture clauses has any overlap with explicit contexts/capabilities? Maybe we could do something with `where`-like bounds on blocks but for variables instead of generics? E.g.
```rust
move(x) ||
with
some_context = self.some_context_or_other.clone(),
{
foo_process(some_context)
bar(x.y.foo)
}
```
### "Stabilize cargo-script" rust-project-goals#119
**Link:** https://github.com/rust-lang/rust-project-goals/issues/119
No recent update.
Josh: The last real blocker was getting thins over with rustfmt. This now got through the merge and review. It's ready for a stabilization report.
TC: Are you talking about cargo-script or the lang portion?
Josh: I'm talking about the goal overall.
TC: The lang side is the front-matter where there is a stabilization report up that's not been nominated because the Reference PR is still marked as a draft (not ready for review).
Josh: I have the impression that it's intended to be reviewed now.
TC: It's waiting on Ed at this point. It's had multiple rounds of review.
### "Const Generics" rust-project-goals#100
**Link:** https://github.com/rust-lang/rust-project-goals/issues/100
[boxy wrote:](https://github.com/rust-lang/rust-project-goals/issues/100#issuecomment-3492411671)
> 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 @camelid's PR (#139558) which once landed the core of the impl work for the feature will be done. I've reviewed it together with @oli-obk 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.
TL;DR, no major updates.
### "Finish the std::offload module" rust-project-goals#109
**Link:** https://github.com/rust-lang/rust-project-goals/issues/109
> A longer update of the changes over the fall. We had two gsoc contributors and a lot of smaller improvements for std::autodiff. The first two improvements were already mentioned as draft PRs in the previous update, but got merged since. I also upstreamed more std::offload changes.
>
> \[..\]
>
> All-in-all I spend a lot more time on infra (dlopen, cmake, download-llvm-ci, ...) then I'd like, but on the happy side there are only so many features left that I want to support here so there is an end in sight.
TC: A lot of good stuff happening. This is part of the work that includes auto differentiation side. It got held up by rustup distribution, increasing the binary side by a small amount. The infra team resolved their blockers two days ago. This should start hitting nightly soon. This unlocks a lot of potential uses for Rust: HPC, AI, machine learning. There's a huge reservoir for potential here. We should think as a Project to bring stakeholders for this.
TC: For Lang side, we can support this by bringing it into nightly, get more stakeholders relying on it will get Manuel more support.
Tyler: If so many people are using Rust for HCP I'm excited and surprised. Why haven't I noticed that in our Rust survey. Do you know?
TC: I don't think we ask this specifically. My intuition from talking to people is that Rust is used. But this is a quiet space. It's interesting for us to think about supporting use cases where it's e.g. a 10% users that would use it, but they would use it heavily.
Josh: I'd love to see us better pulling in and having conversation with folks in the HPC and AI space. It's massive usecase. We should be having that conversation. [PyTorch] just made a big announcement of a framework that had its backend written in Rust and we haven't even heard from them. We should reach out and have a conversation like we did for Bevy.
[PyTorch]: https://www.reddit.com/r/rust/comments/1oe6ekl/pytorch_monarch_distributed_ai_serving_with_a/
Josh: Every time GPU offload comes up, what it's compatibility is. Does this work with an open source stack? Or does this only support Nvidia with CUDA. I wouldn't want us to depend on a single proprietary vendor.
TC: On the LLVM side google is a big supporter. Manuel also talked with AMD to support what they're trying to do.
Jack: People are using technology that works -- and they don't interact heavily with the language development process. We need to be proactive in reaching out. They may not even have thought about it.
### "SVE and SME on AArch64" rust-project-goals#270
**Link:** https://github.com/rust-lang/rust-project-goals/issues/270
https://github.com/rust-lang/rust-project-goals/issues/270#issuecomment-3492255970
Niko: supertrait bounds are a problem as expected. David's been exploring some ways we could do a transition around an edition. Maybe there should be some way to explicitly say that this is disabling a default bound. I'm pretty convinced some kind of annotation is a good idea.
*Metanote: confusing title because it doesn't highlight the end-user impact that will happen most frequently.*
Josh: We should have the title denote both the sized hierarchy and also that this is adding SVE and SME AArch64 support. Also, on sigils, adding a sigil denoting a special behavior that's has special behavior (e.g. changing defaults) gives us a lot of mileage, and I think we'll use this more broadly than the
TC: My vibe is that long term, I'd kind of like default bounds on generic parameters to only really apply until you name one or more trait, at which point, those traits' supertraits end up dominating. But maybe we can't get there, or get there now.
### "reflection and comptime" rust-project-goals#406
**Link:** https://github.com/rust-lang/rust-project-goals/issues/406
Scott: Oli has a PR for initial comptime support.
Josh: Working with Oli to also adapt this for use as `macro fn`, in place of some of the previous thoughts about adding more procedural style to `macro_rules!`.
Yosh: *cheering*.
TC: One thing that Oli and I are talking about, relevant to this, is that one model, and the one I lean toward, is `comptime` and `runtime` being two orthogonal dimensions.
### "Getting Rust for Linux into stable Rust: language features" rust-project-goals#116
**Link:** https://github.com/rust-lang/rust-project-goals/issues/116
[Comment here](https://github.com/rust-lang/rust-project-goals/issues/116#issuecomment-3442107142):
* Layout of `core::any::TypeId` -- ok to guarantee 16 bytes or less?
* rustfmt issue around comments
* `// PANIC: ... comments / clippy#15895`
* Deref/Receiver split
Josh: Regarding rustfmt, they had maintenance issue with not having enough staffing. That is doing better now thanks to a call for help at the Council level. Style and rustfmt are having conversations on division of labor. And Style needs more people.
TC: We've been talking a lot with Caleb about rustfmt and what we could do there. And Manish put together a rustfmt-contributors team. Maybe compiler could take this on. There could be a rustfmt FCP team, and then possibly the work could be coordinated with the compiler team. I talked to the compiler team and David was interested.
(nikomatsakis: I kind of want "normalize everything to `use foo::bar::baz;` on a single line" as an option for maximally good diffs.)
(Josh: That's already an option.)
(Tyler: ^ That's [imports_granularity](https://rust-lang.github.io/rustfmt/?version=v1.8.0&search=group#imports_granularity); I think Ding said he was interested in working to stabilize this.)
(nikomatsakis: OK, that seems to be what RFL *truly* wants.)
### "Evolving trait hierarchies" rust-project-goals#393
**Link:** https://github.com/rust-lang/rust-project-goals/issues/393
*No updates since Sep 30*
Tyler: There's been proposals to split the `Receiver` and `Deref` targets. I'm still a bit skeptical.
Niko: There's been some general feature work or RFC?
Tyler: Taylor had some feedback on the RFC, a lot of the comments got resolved.
Niko: I feel motivated to see this move. I've been thinking about how to get every crate with network to 1.0. A big blocker is Tower. There was also some potential overlap with a keyword to only override the imports. E.g. "I'm only implementing `Ord` and not `PartialOrd`".
Josh: Libs API very much likes the version of this feature. Because it will make us more comfortable shipping traits in the future knowing . E.g. yesterday we blocked an item before we have the numeric trait hierarchies. We have inherent methods we want to move to traits , etc. All of that is waiting for this feature.
### "Continue Experimentation with Pin Ergonomics" rust-project-goals#389
**Link:** https://github.com/rust-lang/rust-project-goals/issues/389
TC: Two major PRs here were just merged:
- https://github.com/rust-lang/rust/pull/139751
- https://github.com/rust-lang/rust/pull/148397
TC: Talked through the experimental plan here with Niko, who had questions about this related to his earlier MinPin proposal.
TC: We're also working on carving out automatic reborrowing of pin types to RFC that and try to stabilize it. Eric Holk volunteered to draft the RFC for this.
Josh: There was an item to what degree do in-place init and field projection help us build something that would supersede some aspect of `Pin`. I want to make sure we have an option to explore that in the future before we commit.
Niko: Tyler and I talked about it recently. Helped me clarify part of the challenge. If you have a trait that can't be moved once borrowed, there's a typestate. Pin captures that. We have to talk about how that interacts with generics.
Josh: I'd love to be part of the conversation. Care about the outcome as part of design for `async` traits and similar.
Yosh: I'd be happy to set that up in whatever form. There's also an open experiment. In general I think there's possibility to completely supersede `Pin`.
- [Experiment Proposal: `Move` Trait](https://github.com/rust-lang/lang-team/issues/354)
- [Design Meeting: `Move` Trait](https://github.com/rust-lang/lang-team/issues/355)
TC: The entire concept of pin-ergonomics is to not impede any other designs that we do. This is about observing we have certain kinds of borrows and what's the minimum work we can make pin less wordy and more ergonomic. I don't see these other things being in conflict with the core goals for pin-ergonomics.
### "Unsafe Fields" rust-project-goals#273
**Link:** https://github.com/rust-lang/rust-project-goals/issues/273
*no updates*
Niko: I'd love to see this make progress.
Tyler: I missed the design meeting. Can someone give me summary?
Niko: "unsafe fields are unsafe to access".
Tyler: I'm not opposed to the simpler ideas. There's a question of what we're giving up. I'll need to read up on it.
### "C++/Rust Interop Problem Space Mapping" rust-project-goals#388
**Link:** https://github.com/rust-lang/rust-project-goals/issues/388
*no updates*
Tyler: No progress ahs been made. Jon was preparing for the WG21 meeting (C++ standards committee).
Niko: The C++ committee approves that they should have some sort of borrow-checking.
Tyler: That was Jon's proposal.
### "Develop the capabilities to keep the FLS up to date" rust-project-goals#391
**Link:** https://github.com/rust-lang/rust-project-goals/issues/391
TC: We created an FLS team. We've got a lot of energy and excitement from many people on the team. We're working together to build processes, labeling things, etc. We've already identified areas where we've opened up Reference issues. We even have work that will affect the Language.
Niko: TC raised the idea of champions either author or be involved in authoring the spec text for things they're championing. I like that idea.
TC: lcnr has a PR on documenting the type system. I think you were looking for opportunities for getting involved. I think this is a great opportunity for you.
elle: How much of this can be mechanised into some form of doc comments? So there's one central place that gets put into the Reference and Spec. Similar to contract annotations.
Niko: That would be very hard. There's a lot of style issues and terminology differences that make it hard to reuse teh same text. It's a good thing to work towards.
Josh: My understanding is there's a goal of creating cross-referencing. Have links in both directions between tests and reference/spec, have tooling that warns us that one change is incompatible with the other direction.
### "In-place initialization" rust-project-goals#395
**Link:** https://github.com/rust-lang/rust-project-goals/issues/395
*no updates*
Tyler: Taylor is a champion on this. There's been a fair amount of `&out` pointers exploration. I pinged Alice and she'll write a more coherent update.
Yosh: Do we have a communications problem? I've not been aware that a document is being written.
Tyler: When I said doc, I mean meeting notes. There's a proposal from Ding that happened a couple hours ago. I agree the communications can be better.
recent notes exploring down the out pointer path, along with some interaction with Nadri's places proposal: https://hackmd.io/zpPq14e3Qi6GqEc6fFcy1g?both
Yosh: We've been working through in-place initialization and potential interaction with the `Move` trait. There don't seem to be issues so far. `dyn` dispatch is something we've raised and need to work through. Another open question we have is: how do we drive towards a decision? We have three distinct proposal. That's a process question.
Niko: It'd be useful to have an overview. I'd love to read a mutually written summary. Is that something you or Alice thought about doing?
Tyler: There's a lot of active brainstorming happening with a lot of people .The main two options are outptr and ipml init. We're noticing connections with Nadri's placing proposal. We're still discovering it so I don't think we can write it down.
Yosh: We still disagree on the basic facts. Taylor claims that impl init and in-place functions are not compatible with dyn dispatch while out pointers are. We don't know why yet. That's why we were trying to reach Taylor, and couldn't reach here.
### "MIR move elimination" rust-project-goals#396
**Link:** https://github.com/rust-lang/rust-project-goals/issues/396
Amanieu: I haven't posted an update yet. I've got an RFC draft that's almost complete. Once that's done, I'll post an update. Had an initial round of review from opsem.
Niko: Can you summarize the biggest implication for a user of Rust?
Amanieu: If you use safe code, it will magically be faster. For unsafe Rust, there's a question of what happens to an allocation after you move a value out of it. To read it must be an undefined behaviour.
Niko: isn't undef UB?
Amanieu: no. If you try to read it, it's MaybeUninit. For optimization we need it to be UB.
Niko: I'm in favor of that user model.
Amanieu: If you move something out, the storage is dead. It leaves a hole. If you put a new allocation in that place, it will have the same address, therefore the move is no-op.
TC: The provenance changes right? Because you have a separate allocation even though you have the same address?
Amanieu: Yes.
Josh: Would that be a breaking change?
Amanieu: It's technically a breaking change. There's code miri currentrly accepts that it would reject.
Josh: We'll need to know what's the breaking change, what practical code breaks, do we want to break it. Could we do the optimization for safe code initially and do the unsafe code later.
## Nominated RFCs, PRs, and issues (part 2)
### "Derive macros that emit unsafe code can't rely on mentioning the field type twice" rust#148793
**Link:** https://github.com/rust-lang/rust/issues/148793
Niko: I feel nondetermitistic proc macros should be UB. I've been wanting to apply incremental compilation to them.
Josh: It's disappointing that it's being called twice. I think we have a tendency to expect inside out and not outside in in the invocation order.
Niko: What you expect depends on what example you're primed on
Josh: cfg is special
Niko: It would be nice to have a system where everything was an attribute macro. I think on balance the Derives should probably come very late. But cfg or e.g. a preprocessor that looks at what derive generated
Josh: I could imagine someone writing a postfix attribute that would let you write postfix macros inside a function. I don't want to suggest it's always this way. Just that this often seems like an unusual behaviour. We want both cases. Right now we have one of the cases and it's not clear to people which one we have.
Niko: Are you referring specificalyl to attribute macros?
Josh: attribute, derive and function macros. In all cases it's weird.
```rust
macro_rules! debug {
($($t:tt)*) => {
if should_print_debug {
eprintln!($($t)*);
}
};
}
debug!(foo!());
```
Niko: I guess this could work okay in both ways.
Josh: 90% of the time I want expand only after all contents have been expanded. In 10% of the time (cfg macro, stringify) I want the other direction. And I think we want to declare that's what you're doing.
Josh: If I have an assert with a macro, then I expect the stringified version has the macro pre-expansion. I want both optios
TC: In the proc-macro I'd expect to have both the original version and also ask for the expanded version.
Niko: That makes sense. But eager expansion on unsafe code is a volatile mix. If I have a macro that generates two things that go together and one is unsafe and depends on the definition of another one. If I can take those tokens and pass them to another macro, that can/will mess up the invariants of the unsafe code. It's a notable composition hazard.
Niko: We could recommend defensive strategies (enumerate all your enum fields).
Josh: There is no really trivial simple answer here. We're talking about the same problem from multiple angles. This comes up all the time, we need a coherent design rather than special-case rules each time a new special case comes up.
TC: I'd say the violation occurred when the trait's macro derive expanded there. Maybe this ties into work of maybe being able to write pure functions.
Niko: This is just a broken proc macro. I feel nondeterministic proc macros should be considered undefined behaviour. I'm sure you can get other UBs and bugs. We need to assume compilation is a function of unknown quantity of things.
TC: It seems like something we should document in the Reference. We have this implicit expectation.
Niko: I agree. It would also be nice if we could check it in the compiler in the debug mode.
Josh: I half agree, but also some people write proc macros that access an SQL database. It's something that currently works and people do. I'd like to sandbox macros to know which files you accessed so you know when to rerun the macro.
TC: I'm with Niko I feel these should be deterministic.
Josh: I'd be completely in favour of introducing deterministic macros and make them default over an edition.
Niko: We can say we're going to cache macro within a given compilation session. That would solve this problem. But I also thingk it'd be useful for people to tell when the cache would be invalidated. I think what you're saying that people have nondeterministic macros taht are deterministic macros in practice.
Josh: What TC said earlier helped me understand, it's not just about evaluated. If I write something that evaluates its arguments twice than that's my problem. In C, there's no standard way to store the value because you don't know what type it is etc. With some extensions/versions you can. Here it's the same thing: the Derive is running something twice and assuming it'll get the same value. But it's not entirely its fault because we give no way of expanding it. If you opt into wanting the unexpanded thing, that would now be your responsibility to check.
TC: That's a cache invalidation problem. When I look at things like the sqlx macro that queries the database, that's just wild. Here you need to invalidate the cache when the database schema changes. You need something that would call back into rustc that would invalidate it. The macro authors should serialize the state of the DB into a file you could hash rather than trying to do it here.
Yosh: The sqlx thing is trying to do something useful. It's working around gaps in our build system. Maybe a more powerful pluggable build system would be this sort of direction.
Niko: In duchess we had a similar problem, we were dependent on your classpath, we migrated to build.rs saving data in json that the compiler could read later. Separates out the question of what classpath sees vs. what the compiler sees.
Niko notes: we actually have a lot of knowledge thanks to hygiene....ie, we know you pasted the same tokens...
### "Partial pointers in padding can make const-eval fail" rust#148470
**Link:** https://github.com/rust-lang/rust/issues/148470
TC: This is an existing problem. It comes down to the semantics of a typed copy in the language. In some cases we copy just the fields. In other cases we copy the whole struct. That differs in whether we overwrite the padding. This is observable in the language.
TC: That's a breaking change on how copies work.
TC: We're talking about always initialised scalar pairs. See my comment here: https://github.com/rust-lang/rust/issues/148470#issuecomment-3509342459
TC: Can we just clean this up later? After you do the typed copy, can we just wipe out the uninitialized padding? The answer is complicated. I asked whether we have any benchmarks on how expensive it would be to just zero out the padding bytes. Or disabling the initialised scalar pairs.
Niko: What's the optimization?
TC: Copy the fields rather than the entire struct.
Niko: So we could always be smart about padding or never be smart about padding. But this in-between state is not good.
Josh: I wouldn't want it to be the case that looking at something via a union automatically nullifies something that might be padding. I need to be looking at a discriminant, look at different variants of the union, what might be padding in one variant might be a value next time.
TC: We just clarified the union language recently.
Josh: It would be great if we defined the behaviour. Either always clearing the padding. Or leaving it and marking it as maybeuninit to miri. I think the latter is better.
TC: My vibe is if we can get away with it, we should just do the correct thing and wipe out the padding.
Josh: I agree if it costs nothing. But it costs something.
Niko: TC said he'd like to do a memcpy and patch it afterwards.
Josh: I think in miri it's utterly reasonable to cut it up, patch it. My concern is runtime behaviour. So long as we don't erase it at runtime I'm happy.
TC: I'm talking about const-time behaviour only.
Josh: I agree.
### "Stabilize the `supertrait_item_shadowing` feature" rust#148605
**Link:** https://github.com/rust-lang/rust/pull/148605
TC: We talked previously whether we want to use gerunds as lint names. We have at least two (dropping_copy_types and dropping_references). I think this case is really motivating.
Josh: This is a name bikeshed. Is there anything blocking FCP other than the lint naming?
TC: I think it's only the lints.
Josh: I think it's reasonable to start the FCP and then raise a concern on the lint names.
TC: I want our stabilization FCPs to not confuse people on what they're checking boxes. I want it to represent the final state.
Josh: I think it's reasonable to use the phrasing of "shadowing" when it's an adjective. We shouldn't do it for cases where we describe "shadowing" as "this shadows that". We should continue using that style to describe actual code. But there's not an issue for uses where it uses an adjective. But here I think it would be more readable if we said "item_shadows_supertrait_usage" or similar.
TC: I don't think we use that present tense in a way that you're describing. We generally name the lints against the construct that we're allowing or denying. E.g. "named_arguments_used_implicitly"
Josh: Right, we have a bunch of things where we said "unused_"
Niko: what are your proposals?
TC: "shadowing_supertrait_items", my fallback is: "items_shadowing_supertrait_items"
Niko: why not "shadowed_supertrait_items"
TC: It's the item doing the shadowing.
Niko: They all seem fine personally. I think you're right it should be the shorter version.
TC: I'm leaning on precedent of `dropping_copy_types` etc.
Josh: I agree with the general phrasing you're describing TC where we "allow(...)" should read as a sentence (and similar for deny). My concern with `allow(shadowing_supertrait_items)`: are you saying "allow my code to be shadowing a supertrait item" or "allow my code that is shadowing to a supertrait item"
TC: That's always a risk when using a gerund. You could alternately interpret the present participle as being an adjective to the direct object rather than a verb. I think the same context is same as "dropping_types"
Josh: I feel there's a phrasing here that could make it unambiguous without making it much longer. "item_shadows_supertrait" or "item_usage_shadows_supertrait".
TC: The next lint name (use-site lint): we're linting on a use that resolves to a subtrait item that shadows a supertrait item. Even if you use a fully qualified thing it's a name resolution. The best I could come up with is: `resolving_shadowed_supertrait_items`.
Niko: I'd think "resolving_to_shadowing_supertrait_item".
Josh: There is an ambiguity, but I think the names you're proposing TC are fine. People will be told by the compiler and either allow/deny this, or they'll look it up and find it that way. I don't think the naming is that important.
TC: For the second one, I agree with Niko now that it points to the wrong thing.
Niko proposes: `naming_shadowing_subtrait_items`---- hmm.
Josh: If we don't want to repeat "items" here, we could lean on "definition"; "definition_shadows_supertrait_items"? and "usage_shadows_supertrait_items"
TC: I don't want to use the word "usage". It's not in any other lints.
Niko: I like "shadowing_supertrait_items". I don't have an opinion on the second one.
Josh: I think people will be turning on this lint as part of a nitpicky lint group. You'll turn it on to be notified you can eliminate a dependency.
TC: At the use-site lint, right now it only lints on the third example where you have a `.` method: https://github.com/rust-lang/rust/pull/148605#issuecomment-3514671713
```rust
trait Super {
fn f(&self) {}
}
trait Sub: Super {
fn f(&self) {}
}
fn f<T: Sub>(x: T) {
let _x = T::f; //~ TC wants this to lint but it does not today.
let _ = T::f(&x); //~ TC wants this to lint but it does not today.
let _ = x.f(); //~ Lints.
// But not:
let _x = <T as Sub>::f; //~ Does not lint.
let _ = <T as Sub>::f(&x); //~ Does not lint.
}
```
TC: I want to expand it to the other ones but I don't want to block it.
Niko: I agree with you.
### Revisit `final` from earlier in the meeting
https://github.com/rust-lang/rfcs/pull/3678
Josh: Updated as requested, seeking checkboxes.
TC: I'll read it
### "const validation: remove check for mutable refs in final value of const" rust#148746
**Link:** https://github.com/rust-lang/rust/pull/148746
TC: The rule that is important to const evaluation for references is: reference cannot be lifetime extended to live to the end of the program when they are either mutable or the referent is an interior mutable value.
TC: We also have checks about the final value of the const. And those get complicated. These rules are weird, we've been trying to nail them in the Reference and there's a lot of loopholes. This caused Ralf to look at it and realise there's no reason for the rule. We have enough faith in this check. Note, I say the "final value" not the "final type". It's not about the type. This delete a huge amount of Reference text. I proposed FCP.
Niko: sounds great.
Josh: sounds correct to me as well. I'm hoping the Reference text mentions why it is important for const evaluation to have the rule you listed on line 866.
TC: I think we have some admonitions describing it. You're trying to avoid:
```rust
const C: &mut u8 = &mut 0;
```
TC: What does this mean in the copy and paste sense? There's text in the Reference talking about this and why we don't allow it.
Josh: I see. That case seems obviously wrong and we should keep denying it. But there may be other cases where extending the reference might work. I'm looking forward to reading the rationale.
### "Warn on codegen attributes on required trait methods" rust#148756
**Link:** https://github.com/rust-lang/rust/pull/148756
...
Josh: This is about adding those attributes to the trait definition with no body, right?
TC: Yes.
Josh: I think these all make sense on method impls of a trait with a body and trait impls. The rest should be a FCW.
TC: I was about to add the T-lang label and propose FCP.
***
Meta discussion around FCP
Josh: I want to be able to say that you can propose alternatives in FCP merge and have people select which one is. With people being able to move from one proposal to the other (or abstain) and once we have full checkboxes (or abstainees) the FCP moves forward.
Josh: If you want to propose a motion because you feel that team's reached consensus. I think this is the metadata how we're reaching consensus. I'd have a bot start out one of these with no checkboxes the moment it's open.
TC: The reason for why the current thing is implemented to require that it's lang or whatever. On [this issue](https://github.com/rust-lang/rust/pull/148756) it had compiler not lang. I could have easily pinged all 15 people on the compiler. I want it to error out when you don't specify the team.
Josh: you would get an error because you're not on the compiler team.
TC: But Niko wouldn't get an error because he's on everything.
Josh: We should let people be aware of this. With that I'm fine with requiring the team.
### "Tracking Issue for `FnStatic` and `FnPtr::addr`/`from_ptr`/`as_ptr` and `Code`" rust#148768
**Link:** https://github.com/rust-lang/rust/issues/148768
Josh: I'm going to read the description for targets where code pointers are bigger than data pointers.
TC: Why does it matter in the context for this proposal which is bigger?
Josh: In general it doesn't. But here it's "what size is the usize?".
TC: What's this `pub extern type Code` thing?
Josh: They're doing `NonNull<Code>`. NonNull is a pointer, it can't be different size. It's an extern type. The original proposal for FnPtr was a pointer to `()`. This is doing a pointer to `Code`. If you're getting back a `usize` from calling `addr` it's your responsibility to make sure that's okay.
Josh: On targets where data and code pointers are different, what is the size of `size_t`? I'm going to ask that question.
TC: Why does this need to be unsized? Why can't it be a ZST?
Josh: I don't know.
Josh: `AsFn` is asking for a `fn` pointer as an associated type. Is this a proposal to make this a sealed trait?
TC: That's a great thing to say, go ahead and type it on the issue.
### "error out when `repr(align)` exceeds COFF limit" rust#142638
**Link:** https://github.com/rust-lang/rust/pull/142638
TC: This is a Windows thing. Came out at a Reference too. Nothing to do on the Lang side.
Josh: We had somethnig on the lang side and we did it. We said it's okay for this to be a property on the target.
### "Not linting irrefutable_let_patterns on let chains" rust#146832
**Link:** https://github.com/rust-lang/rust/pull/146832
*TC and Josh both checked boxes, nothing for them to do now*
Josh: This is a style thing. And there are legitimate reasons for us to lint on style things in some cases.
### "Add `cargo_cfg_target_family_multivalued` FCW" rust#147545
**Link:** https://github.com/rust-lang/rust/pull/147545
TC: Josh, you left a question. It was followed-up and renominated.
Josh: Jubilee answered Ed's question on why rustc vs clippy. The name was changed as suggested. I think a match is a comparison so I don't think that's inherently a problem.
TC: Agreed.
Josh: We could enable this globally. I suggested to warn on build.rs. The case here makes me think: still allow by default and Cargo should set it for build script or building dependencies. I think it's ultimately Cargo's responsibility to decide when it should be linting.
TC: Are you saynig it's in lang's court to decide whether we want to lint against the universe
Josh: We could decide to do that. But I think we should not be doing this in a fully general code. We're flagging semantic issues without understanding the code vs. flagging semantic issues when we know it's part of the build script.
TC: I agree with your vibe.
Josh: This would cross a line where rustc lints on a Cargo situation.
### "RFC: cfg_target_version" rfcs#3750
**Link:** https://github.com/rust-lang/rfcs/pull/3750
### "repr(ordered_fields)" rfcs#3845
**Link:** https://github.com/rust-lang/rfcs/pull/3845
### "Match guard can both move and static-promote a single constant" rust#145237
**Link:** https://github.com/rust-lang/rust/issues/145237
### "`ref` patterns can const-promote a single constant more than once" rust#145555
**Link:** https://github.com/rust-lang/rust/issues/145555
### "Uplifts and extends `clippy::needless-maybe-sized` into rustc" rust#145924
**Link:** https://github.com/rust-lang/rust/pull/145924
### "Decide about future of `rustc_legacy_const_generics`" rust#146613
**Link:** https://github.com/rust-lang/rust/issues/146613
### "Tracking Issue for enum access in offset_of" rust#120141
**Link:** https://github.com/rust-lang/rust/issues/120141
### "Stabilize the `breakpoint` function" rust#142325
**Link:** https://github.com/rust-lang/rust/pull/142325