---
title: Triage meeting 2024-07-10
tags: ["T-lang", "triage-meeting", "minutes"]
date: 2024-07-10
discussion: https://rust-lang.zulipchat.com/#narrow/stream/410673-t-lang.2Fmeetings/topic/Triage.20meeting.202024-07-10
url: https://hackmd.io/h-O5TUPITvulH_d5YaejWA
---
# T-lang meeting agenda
- Meeting date: 2024-07-10
## Attendance
- People: TC, tmandry, Josh, nikomatsakis, scottmcm, CE, Santiago, Urgau, Mara, Xiang, Jonathan
## Meeting roles
- Minutes, driver: TC
## Scheduled meetings
- 2024-07-10: "Design meeting: Discriminant syntax (RFC 3607)" [#275](https://github.com/rust-lang/lang-team/issues/275)
- 2024-07-17: "Design meeting: Float semantics (RFC 3514)" [#273](https://github.com/rust-lang/lang-team/issues/273)
- 2024-07-24: "Design meeting: `Freeze` in bounds (RFC 3633)" [#277](https://github.com/rust-lang/lang-team/issues/277)
- 2024-07-31: "Planning meeting: 2024-07-31" [#276](https://github.com/rust-lang/lang-team/issues/276)
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 2024-07-17 to review the status of RfL project goals.
https://github.com/rust-lang/rfcs/pull/3614
### All hands at RustNL
The council has a question:
> The council is organizing (with RustNL) an all-hands (likely) May 15-17th 2025 in the Netherlands. This includes a celebration around Rust's 10 year birthday, which is happening during that time.
>
> We're trying to get some tentative gauge on interest here.
>
> 1. Are you interested in going?
> 2. Do you expect an employer to be able to cover travel costs?
> 3. Are there any specific people you'd like to get invited outside the (current) Project membership (WGs aren't treated as part of the project for this)?
> 4. Are there any logistical requirements you want from this (e.g. meeting space/time for just the team)?
> 5. Anything else?
See:
- https://rust-lang.zulipchat.com/#narrow/stream/213817-t-lang/topic/council.20updates.20and.20discussion/near/450471781
TC: Do we have any thoughts for them?
tmandry: Interested in going; could probably get my employer would cover, but probably others would want the Foundation to cover, so hopefully we'd continue that policy.
Josh: Would it be possible to have different rooms for different conversations?
Mara: We have 10 rooms available to us. Right now, there's one dedicated to lang and a smaller one for types. We have four breakout rooms available.
Mara: There's currently no budget allocated to the WGs. If there are a large number of people who aren't on teams (even if on WGs), we need to allocate the budget for that soon.
tmandry: Do the advisors group count as part of the project?
Mara: Yes, those are included.
Mara: We're also looking for sponsors. Please let us know if you have ideas here. We'll put out a document for sponsors.
### Goals RFC
https://github.com/rust-lang/rfcs/pull/3672
NM: We have the goals RFC published. We'd like everyone to look at it. We're running a manual FCP for this.
Take a look at the collated "lang team" asks:
https://rust-lang.github.io/rust-project-goals/2024h2/index.html#lang-team
## Rust 2024 review
Project board: https://github.com/orgs/rust-lang/projects/43/views/5
None.
### Meta
TC: We have tracking issues for the Rust 2024 aspects of every item queued for the edition:
https://github.com/rust-lang/rust/issues?q=label%3AA-edition-2024+label%3AC-tracking-issue
For each item, we've identified an *owner*. Our most recent update for item owners is here:
https://rust-lang.zulipchat.com/#narrow/stream/268952-edition/topic/Owners.20update.202024-04-30
Our motivating priorities are:
- Make this edition a success.
- Do so without requiring heroics from anyone.
- ...or stressing anyone or everyone out.
The current timeline to be communicated is:
| Date | Version | Edition stage |
|------------|---------------|--------------------------------|
| 2024-06-13 | Release v1.79 | Checking off items... |
| 2024-07-25 | Release v1.80 | Checking off items... |
| 2024-09-05 | Release v1.81 | Checking off items... |
| 2024-10-11 | Branch v1.83 | Go / no go on all items |
| 2024-10-17 | Release v1.82 | Rust 2024 nightly beta |
| 2024-11-22 | Branch v1.84 | Prepare to stabilize... |
| 2024-11-28 | Release v1.83 | Stabilize Rust 2024 on master |
| 2025-01-03 | Branch v1.85 | Cut Rust 2024 to beta |
| 2025-01-09 | Release v1.84 | Announce Rust 2024 is pending! |
| 2025-02-20 | Release v1.85 | Release Rust 2024 |
### Tracking Issue for Lifetime Capture Rules 2024 (RFC 3498) #117587
**Link:** https://github.com/rust-lang/rust/issues/117587
TC: With the acceptance of RFC 3617, the adoption of `+ use<..>` syntax, and the great work by CE, this is looking to be in good shape for the edition.
### Reserve gen keyword in 2024 edition for Iterator generators #3513
**Link:** https://github.com/rust-lang/rfcs/pull/3513
TC: With the acceptance of RFC 3513 and the great work by Oli, this is looking to be in good shape for the edition.
### Tracking issue for promoting `!` to a type (RFC 1216) #35121
**Link:** https://github.com/rust-lang/rust/issues/35121
**Link:** https://github.com/rust-lang/rust/pull/123508
TC: This item is now ready for Rust 2024.
## Nominated RFCs, PRs, and issues
### "Stop skewing inference in ?'s desugaring" rust#122412
**Link:** https://github.com/rust-lang/rust/pull/122412
TC: If we write this, we get an error:
```rust
fn deserialize<T>() -> Result<T, &'static str> {
Err(core::any::type_name::<T>())
}
fn bad() -> Result<(), &'static str> {
_ = deserialize().unwrap();
//~^ ERROR type annotations needed
Ok(())
}
```
...which makes sense as `T` is unconstrained. But if we write this otherwise similar code using `?`, it compiles:
```rust
fn bad() -> Result<(), &'static str> {
_ = deserialize()?; //~ OK?
Ok(())
}
```
This is due to the combined desugaring of `?` and that of never type fallback:
```rust
//@ edition: 2024
fn never_to_any<T>(x: !) -> T { x }
fn bad() -> Result<(), &'static str> {
_ = match deserialize() {
Ok(v) => v,
Err(e) => never_to_any::<_ || !>(return Err(e)),
// ^^^^^^ Fallback (pseudo-code).
};
Ok(())
}
```
This provides a plausible path to UB, and there's a report of something like this having happened:
```rust
fn deserialize<T>() -> Result<T, &'static str> {
Err(core::any::type_name::<T>())
}
fn bad(x: bool) -> Result<(), &'static str> {
_ = if x {
// If we were to write:
//
// ```rust
// deserialize.unwrap()
// //~^ ERROR type annotations needed
// ```
//
// ...we get an error. But if we use `?`, as below,
// then we don't, which is strangely inconsistent,
// and it sets us up for failure here.
//
deserialize()?
} else {
unsafe {
core::mem::transmute::<_, _ /* ?0 */>(())
//~^ WARN never type fallback affects this call
//~| to an `unsafe` function
//[2024]~^ WARN the type `!` does not permit
// ~| zero-initialization
}
};
Ok(())
}
```
We warn about that now, due to other work, but it's still surprising that `?` introduces this where `unwrap` would not.
The proposal is to change the desugaring of `?` from this:
```rust
//@ edition: 2024
fn never_to_any<T>(x: !) -> T { x }
fn foo() -> Result<(), &'static str> {
_ = match deserialize() {
Ok(v) => v,
Err(e) => never_to_any::<_ || !>(return Err(e)),
// ^^^^^^ Fallback (pseudo-code).
};
Ok(())
}
```
To this:
```rust
//@ edition: 2024
fn never_to_any<T>(x: !) -> T { x }
fn foo() -> Result<(), &'static str> {
_ = match deserialize() {
//~^ ERROR type annotations needed
Ok(v) => v,
Err(e) => never_to_any::<_>(return Err(e)),
// ^ No fallback.
};
Ok(())
}
```
This would need to happen over an edition. But like the change to the fallback type, we may later choose to apply this to all editions once the newer editions have been widely enough adopted.
One possible reason to want to do this now is that the breakage due to this change seems to significantly overlap with the breakage due to changing the fallback type.
We last discussed this on 2024-03-20. We had wanted to see a crater run (now done; it needs an edition), and we were curious about whether we could take a "bigger bite" here somehow.
I asked Waffle about the latter. Waffle didn't really think there is such a thing, or at least, there isn't such a thing that's as simple a change as this and in which Waffle has the required confidence.
This change is already implemented and could land in the edition if we want it.
TC: What do we think?
NM: I think this is a good idea. I agree with Waffle that it's non-trivial to do more here, and it's better to do something.
Josh: I'm thinking of the common pattern like:
```rust
Err(e)?;
```
TC: This breaks the cases where `Err(e).unwrap()` would fail.
Waffle: It does break that exact case. But I don't think this is an important pattern to keep. But it does exist in real code.
waffle: crater run: https://crater-reports.s3.amazonaws.com/absurd-question-mark-desugar/index.html
scottmcm: This feels difficult to explain, in terms of the desugaring, of why it is useful? I don't understand why `return` doesn't do the right thing here.
NM: Could we make the `return`s not fallback?
(Discussion...)
NM: We could maybe do something very syntactic, e.g. if there's a return on one branch of a match...
Josh: Looking at the PR, I'm seeing changes from `Err(b)?;` to `Err::<(), _>(b)?;`, which to me is a complete non-starter.
```diff
fn result() -> Result<bool, ()> {
- Err(())?;
+ Err::<(), _>(())?;
Ok(true)
}
```
NM: Two questions:
* If this was a migration from `Err(b)?;` to `yeet b;`, would that land differently for you?
* Josh: That, along with a machine-applicable fix, would seem acceptable to me; it would be an acceptable mitigation, though it might still produce some negative reaction. I'd want to see whether there are any other common patterns that would break.
* If we had a change that said -- when you instantiate a variant that doesn't use some type parameters, they could have fallback to `!`:
* `let x: Result<_, 3> = Err(3)`
* I feel like I explored this and it had some gotchas but I don't remember what
* Do we have a warning/error for fallback that decides which impl we use?
```rust
trait Deserialize {
fn deserialize(&self) -> Result<Self, ()>;
}
impl Derserialize for () { .. }
impl Deserialize for ! {
fn deserialize(&self) -> Result<Self, ()> {
panic!()
}
}
fn foo() -> Result<u32, ()> {
let x = Deserialize::deserialize()?;
u32
}
```
Josh: I'm wondering why we're thinking to do this.
Waffle: It's about rejecting the code, e.g. that Niko showed, because this is surprising.
I think the prime example is serde's `deserialize` / `run_query` from the above example. The idea is basically that you have a function that is generic over the return type (on the `Ok` path) and you don't specify the type and you ignore the value (runnable example):
```rust
fn deserialize<T>() -> Result<T, &'static str> {
Err(core::any::type_name::<T>())
}
fn do_stuff() -> Result<(), &'static str> {
// Uh, oh. What is `T` here?
// Current answer: `()` or `!` depending on the fallback.
// (+warning if `deserialize` has a bound on `T` which is not implemented for `!`)
//
// However what you probably want is a compilation error,
// `deserialize` requires a type and you do not provide it.
deserialize()?;
Ok(())
}
```
Usually what this means is that either:
- The call is just dead code.
- The call is incorrect (i.e. you wanted some other type, but it compiled, so you forgot).
- `()` was correct, but this will be broken with the fallback changes.
- Either with FCW + an error afterwards, or
- A silent behavior change.
- `!` is correct.
In all of the cases IMO it's better to specify the type explicitly (or remove the call).
NM: Playing with an example...
```rust
fn never_to_any<T>(x: !) -> T { x }
fn bad() -> Result<(), &'static str> {
_ = match <_ as Deserialize>::deserialize() {
// ^ falls back because "entangled" with `return` below
Ok(v) => v,
Err(e) => return Err::<_, _>(e.into()),
// ^ unconstrained, but ok
//
//
};
Err::<_, _>(e.into())?;
// ^ unconstrained, ok
Ok(())
}
```
One other thing about my idea is that I think it is an ergonomic improvement in other cases (e.g....)
```rust
fn main() {
let x: () = identity(Err::<_, _>(())).unwrap_err();
// ^ falls back to `!` under my proposal, error today
}
fn identity<T, E>(x: Result<T, E>) -> Result<T, E> {x}
```
### Reserve guarded string literals (RFC 3593)
https://github.com/rust-lang/rust/pull/123951
TC: Our reservation of unprefixed guarded string literals, #123735, is in some jeopardy for Rust 2024. It's blocked on this PR:
https://github.com/rust-lang/rust/pull/123951
And that PR is blocked on this discussion:
https://rust-lang.zulipchat.com/#narrow/stream/131828-t-compiler/topic/Edition-dependent.20lexing
Essentially, the folks in compiler are kind of not terribly compelled by this, and are finding it difficult to find implementation tradeoffs that seem acceptable, and **Peter Jaszkowiak (pitaj)** doesn't really have a clear idea of how to proceed.
(Discussion of this.)
Josh: The trouble is that if we don't land this reservation, then the string syntax we might want to do becomes impossible until the next edition, which means that the energy around that probably dissipates.
CE: The basic implementation trouble is that it raises the complexity class of the lexer in a way that we've been trying to avoid, and it's hard to feel compelled to do that when it's just for a reservation.
(Discussion.)
tmandry: I do have the impression that we probably do want this feature eventually. There seem to be open questions on the final design, but we'd have to look back into those. But will we need edition-dependent lexing to have this feature in any case?
NM: My take is defer it from the edition and just pursue the design we really want.
Josh: I feel like we'll end up with edition-dependent lexing for one feature or another.
### "Implement lint against unexpected unary precedence" rust#121364
(Nominated by Urgau, who is here.)
**Link:** https://github.com/rust-lang/rust/pull/121364
TC: The proposal is to lint against:
```rust
-2.pow(2); // Equals -4.
```
These would instead be written:
```rust
-(2.pow(2)); // Equals -4.
```
TC: This is a subset of:
https://github.com/rust-lang/rust/pull/117161
...which is also nominated. Whereas the #117161 proposal is to lint on both binary op and unary op cases, this proposal is to lint only on unary op cases. The proposal for this subset came out a discussion with scottmcm.
TC: What do we think?
Josh: Lint it.
TC: There's a part of me that has reservations here, especially phrasing this in terms of unary operators. We expect people to know the precedence on `*`, and this comes up all the time when handling pointers.
scottmcm: The question I'd ask is whether this is about unary operators or more about literals?
scottmcm: I'd propose that we rename this to something that uses the word "literal".
Josh/scottmcm/TC: ...`ambiguous_negative_literal`.
TC: I can get behind that.
scottmcm: I'll propose FCP.
(The meeting ended here.)
---
### "Rescope temp lifetime in let-chain into IfElse" rust#107251
**Link:** https://github.com/rust-lang/rust/pull/107251
TC: This PR is about shortening, over an edition, the scope of temporary lifetimes in if-let scrutinees so that they end before the `else` block. The current rules are a particular problem for let-chains which we hope to stabilize.
Ding assembled this report based on our request:
https://hackmd.io/@dingxf/rkJXW-0BA
TC: What do we think?
### "Async closures" rfcs#3668
**Link:** https://github.com/rust-lang/rfcs/pull/3668
TC: CE proposes for us async closures. These form part a key part of the roadmap proposed in the async project goal, as these enable library innovation in the async Rust ecosystem.
These solve two main problems. One is that we cannot currently express higher-ranked bounds on async function signatures, so this doesn't work:
```rust
async fn callee<F, Fut>(_: F)
where
F: for<'a> FnMut(&'a ()) -> Fut,
Fut: Future<Output = ()>,
{
}
async fn caller() {
async fn nop(_: &()) {}
callee(nop).await;
//~^ ERROR mismatched types
//~| NOTE one type is more general than the other
}
```
The other is that closures cannot return futures that borrow from their captures, so this fails:
```rust
use core::future::ready;
async fn callee<F, Fut>(_: F)
where
F: for<'a> FnMut(&'a ()) -> Fut,
Fut: Future<Output = ()>,
{
}
async fn caller() {
let mut xs = vec![];
callee(|x| async {
xs.push(*ready(x).await);
})
.await;
//~^ ERROR lifetime may not live long enough
//~| NOTE captured variable cannot escape `FnMut`
//~| closure body
//~| NOTE async block may outlive the current function,
//~| but it borrows `x`, which is owned by the
//~| current function
}
```
The RFC solves this with `async Fn*` trait bounds and with `async || ()` closures, e.g.:
```rust
#![feature(async_closure)]
use core::future::ready;
async fn callee<F: async FnMut(&())>(_: F) {}
async fn caller() {
let mut xs = vec![];
callee(async |x| {
xs.push(*ready(x).await);
})
.await;
}
```
There's an extensive explanation for why this is the best way to solve the problem, both in the RFC and in this blog post:
- https://hackmd.io/@compiler-errors/async-closures
The RFC leaves the underlying `AsyncFn*` traits (and all of their associated types) as unnameable to leave us future room to maneuver, e.g. so that we can later work these into a more general `LendingFn*` hierarchy.
Aside from reviewing this generally, there's one item that deserves our attention, which is whether the associated types on the underlying `AsyncFn*` traits should have `Future` or `IntoFuture` bounds. In either case, concrete `async |..| { .. }` closures would return opaque types that implement `Future`, but this would affect what `F: async FnMut()`-style bounds mean, and it would constrain the details of these traits that we may later choose to stabilize.
The question probably comes down to whether we're *betting* on `IntoFuture`. That is, whether we think that bounds should generally require `IntoFuture` (and `IntoIterator`, `IntoAsyncGen`, etc.) rather than requiring `Future` (and `Iterator`, `AsyncGen`, etc.).
There's some sense in requiring the weaker bounds. It's generally better to ask of callers the minimum that we require, and it's hard to think of cases where the `Into*` bounds aren't enough.
There's a practical angle here, in that `IntoFuture` for a type can be implemented using an `async` block and ATPIT, e.g.:
```rust
struct AlwaysAsync42;
impl IntoFuture for AlwaysAsync42 {
type Output = impl Iterator<Item = impl Fn() -> u8>;
type IntoFuture = impl Future<Output = Self::Output>;
fn into_future(self) -> Self::IntoFuture { async {
core::iter::repeat(|| 42)
}}
}
```
...whereas implementing `Future` for a type requires implementing `poll` directly. This will also be true of `AsyncGen` (that `IntoAsyncGen` can be implemented with `async gen { .. }` blocks) and of `Iterator` (that `IntoIterator` can be implemented with `gen { .. }` blocks).
Of course, this affordance is most useful if the `Into*` variants can be used in most places. Arguably, this is a kind of direction that we've signaled by allowing types that implement `IntoIterator` to be used directly in `for` loops and types that implement `IntoFuture` to be used directly with `.await`.
What these `async Fn*` bounds mean will likewise be a signal to and influence the ecosystem. If they mean the tighter bound, those tighter bounds will of course proliferate because of the convenience and increased expressiveness of this syntax.
There are two main downsides to using the `IntoFuture` bound here on the associated types. One is that many existing functions in the ecosystem take `Future` rather than `IntoFuture` in their bounds. In generic code, one would then need to write, e.g.:
```rust
async fn my_fun(f: impl async Fn()) {
takes_future(f.into_future()).await;
}
```
The deeper problem is what this would mean for the way that the async closures RFC extends RTN. This RFC allows for, e.g., this solution to the `Send` bound problem:
```rust
fn spawn<F: IntoFuture<IntoFuture: Send>>(f: F) {
todo!()
}
async fn callee<F: async FnMut(), F(..): Send>(f: F) {
// ^^^^^^^^^^^
// ^ Extension to RTN.
spawn(f);
}
```
So then, if we say that `f`, when called, returns a type that implements `IntoFuture`, we have to ask whether the `F(..): Send` syntax should constrain the `IntoFuture` type or whether it should "look through" it and constrain the `Future` returned by calling `into_future` (or maybe both).
There doesn't seem to be a conservative option that leaves us room here. We just need to make the right choice and the one that we'll hopefully regret the least.
TC: What do we think?
### "Decide on path forward for attributes on expressions" rust#127436
**Link:** https://github.com/rust-lang/rust/issues/127436
TC: Long ago, we adopted rust-lang/rfcs#16 ("attributes on statements and blocks"). However, it's long been blocked despite the known and compelling use cases for this.
Over in the tracking issue, #15701, @WaffleLapkin explains the nature of what is blocking this and [proposes](https://github.com/rust-lang/rust/issues/15701#issuecomment-2033124217) a path forward:
> From what I understand the issue blocking this is ambiguity -- even if the RFC specifies what `#[meow] 1 + 1` means, it's still not very readable. I think the path forward is to cut this feature to only allow attributes on things that are unambiguous, such as:
>
> * All kinds of braces: `#[meow] (1 + 1)`, `#[uwu] [1, 2, 3]`, `#[purr] {}` (parethesis/grouping expr, tuples, arrays, blocks)
> * Closures: `#[kwncjhn] || 2`
> * Expressions starting with a keyword: `#[meow] if x {}`, `#[attr] loop { break 'rust; }`, `#[kva] while false {}`, ...
> * etc
>
> Then we can provide a suggestion to add parenthesis around the expression, if it is not supported:
>
> ```
> error: meow meow meow ambiguous attribute
> --> src/main.rs:LL:CC
> |
> LL | let x = #[meow] 1 + 1;
> |
> help: wrap the expression in parenthesis
> |
> LL | let x = #[meow] (1 + 1);
> | + +
> help: wrap the expression in parenthesis (alternative
> |
> LL | let x = (#[meow] 1) + 1;
> | + +
> ```
This may have relevance for whether libs-api would feel the need to stabilize `core::hint::must_use`.
TC: Niko expressed +1 to Waffle's proposal. What do we think?
### "Reorder trait bound modifiers *after* `for<...>` binder in trait bounds" rust#127054
**Link:** https://github.com/rust-lang/rust/pull/127054
TC: CE proposes for us:
> This PR suggests changing the grammar of trait bounds from:
>
```
[CONSTNESS] [ASYNCNESS] [?] [BINDER] [TRAIT_PATH]
const async ? for<'a> Sized
```
>
> to
>
```
[BINDER] [CONSTNESS] [ASYNCNESS] [?] [TRAIT_PATH]
for<'a> const async ?Sized
```
>
> ### Why?
> I think it's strange that the binder applies "more tightly" than the `?` trait polarity. This becomes even weirder when considering that we (or at least, I) want to have `async` trait bounds expressed like:
>
```
where T: for<'a> async Fn(&'a ()) -> i32,
```
>
> and not:
>
```
where T: async for<'a> Fn(&'a ()) -> i32,
```
>
> ### Fallout
>
> No crates on crater use this syntax, presumably because it's literally useless. This will require modifying the reference grammar, though.
TC: What do we think?
### "Inferred types `_::Enum`" rfcs#3444
**Link:** https://github.com/rust-lang/rfcs/pull/3444
TC: This RFC allows `_` to be used more widely for type inference. Niko nominates this for discussion:
> I'd like to discuss this in a lang team meeting. The RFC is pretty broad in scope:
>
> > This RFC introduces a feature allowing the base type of enumerations and structures to be inferred in contexts where strict typing information already exists. Some examples of strict typing include match statements and function calls. The syntax is `_::EnumVariant` for enumerations and `_ { a: 1 }` for constructing structs.
>
> I'm curious to take the temperature of the lang team on this or some subset. I'm not entirely sure what I think yet, to be honest. I might be inclined towards a subset (e.g., only in match patterns). There are definitely challenging implementation questions and I'm curious how e.g. rust-analyzer would be impacted.
>
> It seems pretty clear that repeating `X::Variant` is not "fun"; Swift has its `.Variant` shorthand for this reason. OTOH, it's a bit hard for me to assess how this ranks on the list of syntactic papercuts, it seems unlikely to be a source of _confusion_ for new users and it's rarely something I've heard raised.
>
> In any case, I feel like it'd be good for the team to weigh in on our current stance towards this RFC.
### "Allow dropping `dyn Trait` principal" rust#126660
**Link:** https://github.com/rust-lang/rust/pull/126660
TC: Jules has a PR for us:
> This allows the following examples to compile:
>
> ```rust
> trait Trait: Send {}
> fn foo(x: &dyn Trait) -> &dyn Send { x }
> ```
>
> ```rust
> trait Trait {}
> fn foo(x: &dyn Trait + Send) -> &dyn Send { x }
> ```
>
> This makes the language more consistent, as we already allow:
>
> ```rust
> trait Trait {}
> fn foo(x: &dyn Trait + Send) -> &dyn Trait { x }
> ```
>
> The PR includes a test case, in `tests/ui/traits/dyn-drop-principal.rs`.
This is related to:
- https://github.com/rust-lang/rust/pull/114679
- https://github.com/rust-lang/rust/issues/126313
...and lcnr nominates with this question:
> nominating for lang, to let them decide whether they mind delegating this to t-types. We simply reuse the vtable of the parent trait when dropping the principal. This relies on all vtables to have the same header which is used for dropping and `size_of_val/align_of_val`. I don't know whether that's currently guaranteed anywhere, cc @rust-lang/opsem i guess?
TC: What do we think?
### "RFC: Implementable trait aliases" rfcs#3437
**Link:** https://github.com/rust-lang/rfcs/pull/3437
TC: We discussed this in the lang planning meeting in June, and it looks like there have been updates since we last looked at this, so it's time for us to have another look since we seemed interested in this happening.
TC: What do we think?
### "Stabilize `extended_varargs_abi_support`" rust#116161
**Link:** https://github.com/rust-lang/rust/pull/116161
TC: This stabilization was nominated for us, with pnkfelix commenting:
> Just to add on to @cjgillot 's comment above: @wesleywiser and I could not remember earlier today whether T-lang _wants_ to own FCP'ing changes like this that are restricted to extending the set of calling-conventions (i.e. the `conv` in `extern "conv" fn foo(...)`), which is largely a detail about what platforms one is interoperating with, and not about changing the expressiveness of the Rust language as a whole in the abstract.
>
> (My own gut reaction is that T-compiler is a more natural owner for this than T-lang, but I wasn't certain and so it seems best to let the nomination stand and let the two teams duke it out.)
TC: What do we think about 1) this stabilization, and 2) whether we want to own this?
### "Don't make statement nonterminals match pattern nonterminals" rust#120221
**Link:** https://github.com/rust-lang/rust/pull/120221
TC: CE handed this one to us, since it changes the contract of macro matchers.
Here's the code that does not work today that we would make work:
```rust
macro_rules! m {
($pat:pat) => {};
($stmt:stmt) => {};
}
macro_rules! m2 {
($stmt:stmt) => {
m! { $stmt }
//~^ ERROR expected pattern
};
}
m2! { let x = 1 }
```
This code does not work because we consider `:stmt` to be a possible `:pat` even though we then always reject it later in the process. By saying that `:stmt` cannot be a `:pat`, we make this code work.
We discussed this in the meeting on 2024-03-27:
> CE: Right now the tokens that a macro matcher may begin with is a stable guarantee. We are relaxing the assumption that pattern matchers may begin with statement metavariables ($var whose type is stmt), because when we actually try to *parse* such a pattern, we are always guaranteed to fail. This only allows more code to compile, and would only break future code if we specifically wanted to begin patterns with *statement metavariable*.
>
> scottmcm: I agree that it's weird to allow a `:stmt` in a pattern, so am happy to say we won't. Let's see what others think, since this conversation was in a sparsely-attended triage meeting:
>
> scottmcm: The other thing we explored was what it would take to make this actually work, since you can actually put an `:expr` into a pattern. But CE argued that we don't actually like that that works, it's just something we're stuck with because people used it before `:literal` was available, which seems fair.
TC: What do we think?
### "Initial support for auto traits with default bounds" rust#120706
**Link:** https://github.com/rust-lang/rust/pull/120706
TC: This is related to this MCP about a path toward async drop and scoped tasks:
https://github.com/rust-lang/compiler-team/issues/727
TC: petrochenkov gives some background:
> So, what are the goals here:
>
> * We want to have a possibility to add new auto traits that are added to _all_ bound lists by default on the current edition. The examples of such traits could be `Leak`, `Move`, `SyncDrop` or something else, it doesn't matter much right now. The desired behavior is similar to the current `Sized` trait. Such behavior is required for introducing `!Leak` or `!SyncDrop` types in a backward compatible way. (Both `Leak` and `SyncDrop` are likely necessary for properly supporting libraries for scoped async tasks and structured concurrency.)
> * It's not clear whether it can be done backward compatibly and without significant perf regressions, but that's exactly what we want to find out. Right now we encounter some cycle errors and exponential blow ups in the trait solver, but there's a chance that they are fixable with the new solver.
> * Then we want to land the change into rustc under an option, so it becomes available in bootstrap compiler. Then we'll be able to do standard library experiments with the aforementioned traits without adding hundreds of `#[cfg(not(bootstrap))]`s.
> * Based on the experiments, we can come up with some scheme for the next edition, in which such bounds are added more conservatively.
> * Relevant blog posts - https://without.boats/blog/changing-the-rules-of-rust/, https://without.boats/blog/follow-up-to-changing-the-rules-of-rust/ and https://without.boats/blog/generic-trait-methods-and-new-auto-traits/, https://without.boats/blog/the-scoped-task-trilemma/
> * Larger compiler team MCP including this feature - [MCP: Low level components for async drop compiler-team#727](https://github.com/rust-lang/compiler-team/issues/727), it gives some more context
We discussed this in the async WG on 2024-03-25 and commented:
> This is interesting work, but there's a lot to review here. We'd be particularly interested in seeing something in the way of a design document here, specifically e.g. with respect to when these bounds are added and when they are not, and how they interact with the `?` bounds. Seeing the algorithm spelled out in words and in theory would definitely help us understand this. The best place to put this may be in the [rustc-dev-guide](https://github.com/rust-lang/rustc-dev-guide).
The question here is whether we want to charter this as an experiment.
### "Support ?Trait bounds in supertraits and dyn Trait under a feature gate" rust#121676
**Link:** https://github.com/rust-lang/rust/pull/121676
TC: This is related to this MCP about a path toward async drop and scoped tasks:
https://github.com/rust-lang/compiler-team/issues/727
TC: petrochenkov gives some background:
> Summary:
>
> * [Initial support for auto traits with default bounds #120706](https://github.com/rust-lang/rust/pull/120706) introduces a way to add new auto traits that are appended to all bound lists by default, similarly to existing `Sized`. Such traits may include `Leak`, `SyncDrop` or similar, see [Initial support for auto traits with default bounds #120706 (comment)](https://github.com/rust-lang/rust/pull/120706#issuecomment-1934006762) for more detailed motivation.
> * To opt out from bounds added by default the `?Trait` syntax is used, but such "maybe" bounds are not supported in some contexts like supertrait lists and `dyn Trait + ...` lists, because `Sized` is not added by default in those context.
> * This PR adds a feature for supporting `trait Trait1: ?Trait2`, `dyn Trait1 + ?Trait2` and also multiple maybe bounds in the same list `?Trait1 + ?Trait2`, because the new traits need to be added by default in those contexts too, and `?Sized + ?Leak` may also make sense.
> * We need this to be available in bootstrap compiler, to make experiments on standard library without adding too many `#[cfg(not(bootstrap))]`s
> * Larger compiler team MCP including this feature - [MCP: Low level components for async drop compiler-team#727](https://github.com/rust-lang/compiler-team/issues/727), it gives some more context
TC: The question here is whether we want to charter this as an experiment.
### "Emit a warning if a `match` is too complex" rust#122685
**Link:** https://github.com/rust-lang/rust/pull/122685
TC: Nadri nominates this for us and describes the situation:
> Dear T-lang, this PR adds a warning that cannot be silenced, triggered when a match takes a really long time to analyze (in the order of seconds). This is to help users figure out what's taking so long and fix it.
>
> We _could_ make the limit configurable or the warning `allow`able. I argue that's not necessary because [crater](https://github.com/rust-lang/rust/pull/121979#issuecomment-2003089646) showed zero regressions with the current limit, and it's be pretty easy in general to split up a `match` into smaller `match`es to avoid blowup.
>
> We're still figuring out the exact limit, but does the team approve in principle?
(As an aside, awhile back someone [showed](https://niedzejkob.p4.team/rust-np/) how to [lower](https://github.com/NieDzejkob/rustc-sat) SAT to exhaustiveness checking with `match`. Probably that would hit this limit.)
TC: What do we think?
### "Stabilize `count`, `ignore`, `index`, and `length` (`macro_metavar_expr`)" rust#122808
**Link:** https://github.com/rust-lang/rust/pull/122808
TC: c410-f3r proposes the following for stabilization:
> # Stabilization proposal
>
> This PR proposes the stabilization of a subset of `#![feature(macro_metavar_expr)]` or more specifically, the stabilization of `count`, `ignore`, `index` and `length`.
>
> ## What is stabilized
>
> ### Count
> The number of times a meta variable repeats in total.
>
```rust
macro_rules! count_idents {
( $( $i:ident ),* ) => {
${count($i)}
};
}
fn main() {
assert_eq!(count_idents!(a, b, c), 3);
}
```
>
> ### Ignore
> Binds a meta variable for repetition, but expands to nothing.
>
```rust
macro_rules! count {
( $( $i:stmt ),* ) => {{
0 $( + 1 ${ignore($i)} )*
}};
}
fn main() {
assert_eq!(count!(if true {} else {}, let _: () = (), || false), 3);
}
```
>
> ### Index
> The current index of the inner-most repetition.
>
```rust
trait Foo {
fn bar(&self) -> usize;
}
macro_rules! impl_tuple {
( $( $name:ident ),* ) => {
impl<$( $name, )*> Foo for ($( $name, )*)
where
$( $name: AsRef<[u8]>, )*
{
fn bar(&self) -> usize {
let mut sum: usize = 0;
$({
const $name: () = ();
sum = sum.wrapping_add(self.${index()}.as_ref().len());
})*
sum
}
}
};
}
impl_tuple!(A, B, C, D);
fn main() {
}
```
>
> ### Length
>
> The current index starting from the inner-most repetition.
>
```rust
macro_rules! array_3d {
( $( $( $number:literal ),* );* ) => {
[
$(
[
$( $number + ${length()}, )*
],
)*
]
};
}
fn main() {
assert_eq!(array_3d!(0, 1; 2, 3; 4, 5), [[2, 3], [4, 5], [6, 7]]);
}
```
>
> ## Motivation
>
> Meta variable expressions not only facilitate the use of macros but also allow things that can't be done today like in the `$index` example.
>
> An initial effort to stabilize this feature was made in #111908 but ultimately reverted because of possible obstacles related to syntax and expansion.
>
> Nevertheless, [#83527 (comment)](https://github.com/rust-lang/rust/issues/83527#issuecomment-1744822345) tried to address some questions and fortunately the lang team accept #117050 the unblocking suggestions.
>
> Here we are today after ~4 months so everything should be mature enough for wider use.
>
> ## What isn't stabilized
> `$$` is not being stabilized due to unresolved concerns.
TC: I asked WG-macros for feedback on this here:
https://rust-lang.zulipchat.com/#narrow/stream/404510-wg-macros/topic/Partial.20macro_metavar_expr.20stabilization
TC: Josh proposed FCP merge on this stabilization.
### "Raw Keywords" rfcs#3098
**Link:** https://github.com/rust-lang/rfcs/pull/3098
TC: We've at various times discussed that we had earlier decided that if we wanted to use a new keyword within an edition, we would write it as `k#keyword`, and for that reason, we prefer to not speculatively reserve keywords ahead of an edition (except, perhaps, when it's clear we plan to use it in the near future).
TC: Somewhat amusingly, however, we never in fact accepted that RFC. Back in 2021, we accepted scottmcm's proposal to **cancel**:
> We discussed this RFC again in the lang team triage meeting today.
>
> For the short-term goal of the reservation for the edition, we'll be moving forward on #3101 instead. As such, we wanted to leave more time for conversations about this one, and maybe use crater results from 3101 to make design changes,
>
> @rfcbot cancel
Instead we accepted RFC 3101 that reserved `ident#foo`, `ident"foo"`, `ident'f'`, and `ident#123` starting in the 2023 edition.
Reading through the history, here's what I see:
- What do we want to do about Rust 2015 and Rust 2018? It's a breaking change to add this there. Is this OK? Do we want to do a crater run on this?
- Would we have the stomach to actually do this? It's one thing to *say* that if we wanted to use a new keyword within an edition, we'd write `k#keyword`, but it's another to actually do it in the face of certain criticism about that being e.g. unergonomic. Would we follow through?
TC: What do we think?
### "Supertrait item shadowing v2" rfcs#3624
**Link:** https://github.com/rust-lang/rfcs/pull/3624
TC: On 2024-04-24, we had discussed (on a gut check basis) a proposal from Amanieu to change method resolution such that when both a subtrait and one of its supertraits are in scope, shadowed methods from the subtrait would be chosen rather than resulting in ambiguity errors.
Most notably, this would allow the standard library to uplift methods from `itertools`, which they've been deferring for years due to no way to do so without causing breakage. But there are many other possible uses and reasons to believe this might be a good rule.
After our last discussion, we had asked for an RFC. This is that RFC. What do we think?
### "Tracking issue for the `start` feature" rust#29633
**Link:** https://github.com/rust-lang/rust/issues/29633
TC: Nils proposes to us that we delete the unstable `#[start]` attribute:
> I think this issue should be closed and `#[start]` should be deleted. It's nothing but an accidentally leaked implementation detail that's a not very useful mix between "portable" entrypoint logic and bad abstraction.
>
> I think the way the stable user-facing entrypoint should work (and works today on stable) is pretty simple:
>
> * `std`-using cross-platform programs should use `fn main()`. the compiler, together with `std`, will then ensure that code ends up at `main` (by having a platform-specific entrypoint that gets directed through `lang_start` in `std` to `main` - but that's just an implementation detail)
> * `no_std` platform-specific programs should use `#![no_main]` and define their own platform-specific entrypoint symbol with `#[no_mangle]`, like `main`, `_start`, `WinMain` or `my_embedded_platform_wants_to_start_here`. most of them only support a single platform anyways, and need cfg for the different platform's ways of passing arguments or other things _anyways_
>
> `#[start]` is in a super weird position of being neither of those two. It tries to pretend that it's cross-platform, but its signature is a total lie. Those arguments are just stubbed out to zero on Windows, for example. It also only handles the platform-specific entrypoints for a few platforms that are supported by `std`, like Windows or Unix-likes. `my_embedded_platform_wants_to_start_here` can't use it, and neither could a libc-less Linux program. So we have an attribute that only works in some cases anyways, that has a signature that's a total lie (and a signature that, as I might want to add, has changed recently, and that I definitely would not be comfortable giving _any_ stability guarantees on), and where there's a pretty easy way to get things working without it in the first place.
>
> Note that this feature has **not** been RFCed in the first place.
TC: What do we think?
### "Stabilize `anonymous_lifetime_in_impl_trait`" rust#107378
**Link:** https://github.com/rust-lang/rust/pull/107378
TC: We unnominated this back in October 2023 as more analysis seemed to be needed. Since then, nikomatsakis and tmandry have posted substantive analysis that it seems we should discuss.
### "#[cold] on match arms" rust#120193
**Link:** https://github.com/rust-lang/rust/pull/120193
TC: Apparently our unstable `likely` and `unlikely` intrinsics don't work. There's a proposal to do some work on fixing that and stabilizing a solution here. The nominated question is whether we want to charter this as an experiment.
### "Disallow deriving (other than Copy/Clone) on types with unnamed fields" rust#121270
**Link:** https://github.com/rust-lang/rust/pull/121270
TC: pnkfelix nominates this for us:
> This PR that addresses some ICEs arising for the unstable `feature(unnamed_fields)`, by conservatively mapping the ICE'ing cases to static errors instead.
>
> The T-compiler team wants to know the opinion of T-lang of whether `feature(unnamed_fields)` is sufficiently likely, in the near future, to be removed (or significantly reworked) to such a degree that it would make more sense to close this PR rather than have contributors spend further time on it.
>
> (See also the context established by https://hackmd.io/7r0i-EWyR8yO6po2LnS2rA#Tracking-issue-for-RFC-2102-Unnamed-fields-of-struct-and-union-type-rust49804 (where I think there was supposed to be an eventual writeup of the concerns people had with `feature(unnamed_fields)`) and [#49804 (comment)](https://github.com/rust-lang/rust/issues/49804#issuecomment-2106381721) )
On 2024-05-12, Josh said:
> It sounds like, from the minutes, that some folks would like to see this feature designed differently than it was when it was previously accepted. It wouldn't be the first or last feature to need some design adjustments when lang design met compiler reality. Happy to help with that, so that we can find a design that meets the requirements in the original RFC and any new issues that have arisen since then.
This is about RFC 2102:
https://github.com/rust-lang/rfcs/pull/2102
We discussed this in the meeting on 2024-06-12 without consensus.
Some felt that this was still needed, others first wanted to look for a more minimal approach.
We left this for further discussion.
TC: What do we think?
### "Skip pub structs with repr(c) and repr(transparent) in dead code analysis" rust#127104
**Link:** https://github.com/rust-lang/rust/pull/127104
TC: The background here is in:
- https://github.com/rust-lang/rust/issues/126169
TC: What do we think?
### "add float semantics RFC" rfcs#3514
**Link:** https://github.com/rust-lang/rfcs/pull/3514
TC: In addition to documenting the current behavior carefully, this RFC (per RalfJ)...
> says we should allow float operations in `const fn`, which is currently not stable. This is a somewhat profound decision since it is the first non-deterministic operation we stably allow in `const fn`. (We already allow those operations in `const`/`static` initializers.)
TC: What do we think? tmandry proposed this for FCP merge back in October 2023.
### "Tracking Issue for unicode and escape codes in literals" rust#116907
**Link:** https://github.com/rust-lang/rust/issues/116907
TC: nnethercote has implemented most of RFC 3349 ("Mixed UTF-8 literals") and, based on implementation experience, argues that the remainder of the RFC should not be implemented:
> I have a partial implementation of this RFC working locally (EDIT: now at #120286). The RFC proposes five changes to literal syntax. I think three of them are good, and two of them aren't necessary.
TC: What do we think?
### "Proposal: Remove `i128`/`u128` from the `improper_ctypes` lint" lang-team#255
**Link:** https://github.com/rust-lang/lang-team/issues/255
TC: Trevor Gross describes the situation:
> For a while, Rust's 128-bit integer types have been incompatible with those from C. The original issue is here [rust-lang/rust#54341](https://github.com/rust-lang/rust/issues/54341), with some more concise background information at the MCP here [rust-lang/compiler-team#683](https://github.com/rust-lang/compiler-team/issues/683)
>
> The current Beta of 1.77 will have [rust-lang/rust#116672](https://github.com/rust-lang/rust/pull/116672), which manually sets the alignment of `i128` to make it ABI-compliant with any version of LLVM (`clang` does something similar now). 1.78 will have LLVM18 as the vendored version which fixes the source of this error.
>
> Proposal: now that we are ABI-compliant, do not raise `improper_ctypes` on our 128-bit integers. I did some testing with abi-cafe and a more isolated https://github.com/tgross35/quick-abi-check during the time https://reviews.llvm.org/D86310 was being worked on, and verified everything lines up. (It would be great to have some fork of abi-cafe in tree, but that is a separate discussion.)
>
> @joshtriplett mentioned that changing this lint needs a lang FCP https://rust-lang.zulipchat.com/#narrow/stream/187780-t-compiler.2Fwg-llvm/topic/LLVM.20alignment.20of.20i128/near/398422037. cc @maurer
>
> Reference change from when I was testing [rust-lang/rust@c742908](https://github.com/rust-lang/rust/commit/c742908c4b9abde264b8c5e9663e31c649a47f2f)
TC: Josh nominates this for our discussion. What do we think?
### "`is` operator for pattern-matching and binding" rfcs#3573
**Link:** https://github.com/rust-lang/rfcs/pull/3573
TC: Josh proposes for us that we should accept:
```rust
if an_option is Some(x) && x > 3 {
println!("{x}");
}
```
And:
```rust
func(x is Some(y) && y > 3);
```
TC: The main topic discussed in the issue thread so far has been the degree to which Rust should have "two ways to do things". Probably the more interesting issue is how the binding and drop scopes for this should work.
TC: In the 2024-02-21 meeting (with limited attendance), we discussed how we should prioritize stabilizing let chains, and tmandry suggested we may want to allow those to settle first.
TC: What do we think, as a gut check?
### "Unsafe fields" rfcs#3458
**Link:** https://github.com/rust-lang/rfcs/pull/3458
TC: Nearly ten years ago, on 2014-10-09, pnkfelix proposed unsafe fields in RFC 381:
https://github.com/rust-lang/rfcs/issues/381
On 2017-05-04, Niko commented:
> I am pretty strongly in favor of unsafe fields at this point. The only thing that holds me back is some desire to think a bit more about the "unsafe" model more generally.
Then, in 2023, Jacob Pratt refreshed this proposal with RFC 3458. It proposes that:
> Fields may be declared `unsafe`. Unsafe fields may only be mutated (excluding interior mutability) or initialized in an unsafe context. Reading the value of an unsafe field may occur in either safe or unsafe contexts. An unsafe field may be relied upon as a safety invariant in other unsafe code.
E.g.:
```rust
struct Foo {
safe_field: u32,
/// Safety: Value must be an odd number.
unsafe unsafe_field: u32,
}
// Unsafe field initialization requires an `unsafe` block.
// Safety: `unsafe_field` is odd.
let mut foo = unsafe {
Foo {
safe_field: 0,
unsafe_field: 1,
}
};
```
On 2024-05-21, Niko nominated this for us:
> I'd like to nominate this RFC for discussion. I've not read the details of the thread but I think the concept of unsafe fields is something that comes up continuously and some version of it is worth doing.
TC: What do we think?
### "RFC: Allow symbol re-export in cdylib crate from linked staticlib" rfcs#3556
**Link:** https://github.com/rust-lang/rfcs/pull/3556
TC: This seems to be about making the following work:
```rust
// kind is optional if it's been specified elsewhere, e.g. via the `-l` flag to rustc
#[link(name="ext", kind="static")]
extern {
#[no_mangle]
pub fn foo();
#[no_mangle]
pub static bar: std::ffi::c_int;
}
```
There are apparently use cases for this.
What's interesting is that apparently it already does, but we issue a warning that is wrong:
```rust
warning: `#[no_mangle]` has no effect on a foreign function
--> src/lib.rs:21:5
|
21 | #[no_mangle]
| ^^^^^^^^^^^^ help: remove this attribute
22 | pub fn foo_rfc3556_pub_with_no_mangle();
| ---------------------------------------- foreign function
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: symbol names in extern blocks are not mangled
```
TC: One of the author's asks of us is that we don't make this into a hard error (e.g. with the new edition).
TC: What do we think?
### "Better errors with bad/missing identifiers in MBEs" rust#118939
**Link:** https://github.com/rust-lang/rust/pull/118939
TC: The idea here seems to be to improve some diagnostics around `macro_rules`, but this seems to be done by way of reserving the `macro_rules` token more widely, which is a breaking change. Petrochenkov has objected to it on that basis, given that reserving `macro_rules` minimally has been the intention since we hope it will one day disappear in favor of `macro`. What do we think?
### "Uplift `clippy::invalid_null_ptr_usage` lint" rust#119220
**Link:** https://github.com/rust-lang/rust/pull/119220
TC: Urgau proposes this for us:
> This PR aims at uplifting the `clippy::invalid_null_ptr_usage` lint into rustc, this is similar to the [`clippy::invalid_utf8_in_unchecked` uplift](https://github.com/rust-lang/rust/pull/111543) a few months ago, in the sense that those two lints lint on invalid parameter(s), here a null pointer where it is unexpected and UB to pass one.
>
> ## `invalid_null_ptr_usages`
>
> (deny-by-default)
>
> The `invalid_null_ptr_usages` lint checks for invalid usage of null pointers.
>
> ### Example
>
```rust
// Undefined behavior
unsafe { std::slice::from_raw_parts(ptr::null(), 0); }
// Not Undefined behavior
unsafe { std::slice::from_raw_parts(NonNull::dangling().as_ptr(), 0); }
```
>
> Produces:
>
```
error: calling this function with a null pointer is undefined behavior, even if the result of the function is unused, consider using a dangling pointer instead
--> $DIR/invalid_null_ptr_usages.rs:14:23
|
LL | let _: &[usize] = std::slice::from_raw_parts(ptr::null(), 0);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^-----------^^^^
| |
| help: use a dangling pointer instead: `core::ptr::NonNull::dangling().as_ptr()`
```
>
> ### Explanation
>
> Calling methods who's safety invariants requires non-null pointer with a null pointer is undefined behavior.
>
> The lint use a list of functions to know which functions and arguments to checks, this could be improved in the future with a rustc attribute, or maybe even with a `#[diagnostic]` attribute.
TC: What do we think?
### "panic in a no-unwind function leads to not dropping local variables" rust#123231
**Link:** https://github.com/rust-lang/rust/issues/123231
TC: RalfJ nominates this for us. Consider this code:
```rust
#![feature(c_unwind)]
struct Noise;
impl Drop for Noise {
fn drop(&mut self) {
eprintln!("Noisy Drop");
}
}
extern "C" fn test() {
let _val = Noise;
panic!("heyho");
}
fn main() {
test();
}
```
It doesn't print anything. Should it?
### "Uplift `clippy::double_neg` lint as `double_negation`" rust#126604
**Link:** https://github.com/rust-lang/rust/pull/126604
TC: This proposes to lint against cases like this:
```
fn main() {
let x = 1;
let _b = --x; //~ WARN use of a double negation
}
```
TC: What do we think?
### "Lang discussion: Item-level `const {}` blocks, and `const { assert!(...) }`" lang-team#251
**Link:** https://github.com/rust-lang/lang-team/issues/251
TC: This issue was raised due to discussion in a T-libs-api call. Josh gives the context:
> In discussion of [rust-lang/libs-team#325](https://github.com/rust-lang/libs-team/issues/325) (a proposal for a compile-time assert macro), the idea came up to allow `const {}` blocks at item level, and then have people use `const { assert!(...) }`.
>
> @rust-lang/libs-api would like some guidance from @rust-lang/lang about whether lang is open to toplevel `const { ... }` blocks like this, which would influence whether we want to add a compile-time assert macro, as well as what we want to call it (e.g. `static_assert!` vs `const_assert!` vs some other name).
>
> Filing this issue to discuss in a lang meeting. This issue is _not_ seeking any hard commitment to add such a construct, just doing a temperature check.
CAD97 noted:
> To ensure that it's noted: if both item and expression `const` blocks are valid in the same position (i.e. in statement position), a rule to disambiguate would be needed (like for statement versus expression `if`-`else`). IMO it would be quite unfortunate for item-level `const` blocks to be evaluated pre-mono if that same `const` block but statement-level would be evaluated post-mono.
>
> Additionally: since `const { assert!(...) }` is post-mono (due to using the generic context), it's potentially desirable to push people towards using `const _: () = assert!(...);` (which is pre-mono) whenever possible (not capturing generics).
TC: What do we think?
### "Add lint against function pointer comparisons" rust#118833
**Link:** https://github.com/rust-lang/rust/pull/118833
TC: In the 2024-01-03 call, we developed a tentative consensus to lint against direct function pointer comparison and to push people toward using `ptr::fn_addr_eq`. We decided to ask T-libs-api to add this. There's now an open proposal for that here:
https://github.com/rust-lang/libs-team/issues/323
One question that has come up is whether we would expect this to work like `ptr::addr_eq` and have separate generic parameters, e.g.:
```rust
/// Compares the *addresses* of the two pointers for equality,
/// ignoring any metadata in fat pointers.
///
/// If the arguments are thin pointers of the same type,
/// then this is the same as [`eq`].
pub fn addr_eq<T: ?Sized, U: ?Sized>(p: *const T, q: *const U) -> bool { .. }
```
Or whether we would prefer that `fn_addr_eq` enforced type equality of the function pointers. Since we're the ones asking for this, we probably want to develop a consensus here. We discussed this in the call on 2024-01-10, then we opened a Zulip thread:
https://rust-lang.zulipchat.com/#narrow/stream/213817-t-lang/topic/Signature.20of.20.60ptr.3A.3Afn_addr_eq.60
TC: On this subject, scottmcm raised this point, with which pnkfelix seemed to concur:
> I do feel like if I saw code that had `fn1.addr() == fn2.addr()` (if `FnPtr` were stabilized), I'd write a comment saying "isn't that what `fn_addr_eq` is for?"
>
> If the answer ends up being "no, actually, because I have different types", that feels unfortunate even if it's rare.
>
> (Like how `addr_eq(a, b)` is nice even if with strict provenance I could write `a.addr() == b.addr()` anyway.)
TC: scottmcm also asserted confidence that allowing mixed-type pointer comparisons is correct for `ptr::addr_eq` since comparing the addresses of `*const T`, `*const [T; N]`, and `*const [T]` are all reasonable. I pointed out that, if that's reasonable, then `ptr::fn_addr_eq` is the higher-ranked version of that, since for the same use cases, it could be reasonable to compare function pointers that return those three different things or accept them as arguments.
TC: Adding to that, scottmcm noted that comparing addresses despite lifetime differences is also compelling, e.g. comparing `fn(Box<T>) -> &'static mut T` with `for<'a> fn(Box<T>) -> &'a mut T`.
TC: Other alternatives we considered were not stabilizing `ptr::fn_addr_eq` at all and instead stabilizing `FnPtr` so people could write `ptr::addr_eq(fn1.addr(), fn2.addr())`, or expecting that people would write instead `fn1 as *const () == fn2 as *const ()`.
TC: Recently CAD97 raised an interesting alternative:
> From the precedent of `ptr::eq` and `ptr::addr_eq`, I'd expect a "`ptr::fn_eq`" to have one generic type and a "`ptr::fn_addr_eq`" to have two. Even if `ptr::fn_eq`'s implementation is just an address comparison, it still serves as a documentation point to call out the potential pitfalls with comparing function pointers.
TC: What do we think?
---
TC: Separately, on the 2024-01-10 call, we discussed some interest use cases for function pointer comparison, especially when it's indirected through `PartialEq`. We had earlier said we didn't want to lint when such comparisons were indirected through generics, but we did address the non-generic case of simply composing such comparisons.
One example of how this is used is in the standard library, in `Waker::will_wake`:
https://doc.rust-lang.org/core/task/struct.Waker.html#method.will_wake
It's comparing multiple function pointers via a `#[derive(PartialEq)]` on the `RawWakerVTable`.
We decided on 2024-01-01 that this case was interesting and we wanted to think about it further. We opened a discussion thread about this:
https://rust-lang.zulipchat.com/#narrow/stream/213817-t-lang/topic/Function.20pointer.20comparison.20and.20.60PartialEq.60
Since then, another interesting use case in the standard library was raised, in the formatting machinery:
https://doc.rust-lang.org/src/core/fmt/rt.rs.html
What do we think about these, and would we lint on derived `PartialEq` cases like these or no?
### "Uplift `clippy::precedence` lint" rust#117161
**Link:** https://github.com/rust-lang/rust/pull/117161
TC: The proposal is to lint against:
```rust
-2.pow(2); // Equals -4.
1 << 2 + 3; // Equals 32.
```
These would instead be written:
```rust
-(2.pow(2)); // Equals -4.
1 << (2 + 3); // Equals 32.
```
Prompts for discussion:
- Is this an appropriate lint for `rustc`?
- How do other languages handle precedence here?
- Is minus special enough to treat differently than other unary operators (e.g. `!`, `*`, `&`)?
### "Should Rust still ignore SIGPIPE by default?" rust#62569
**Link:** https://github.com/rust-lang/rust/issues/62569
TC: Prior to `main()` being executed, the Rust startup code makes a syscall to change the handling of `SIGPIPE`. Many believe that this is wrong thing for a low-level language like Rust to do, because 1) it makes it impossible to recover what the original value was, and 2) means things like `seccomp` filters must be adjusted for this.
It's also just, in a practical sense, wrong for most CLI applications.
This seems to have been added back when Rust had green threads and then forgotten about. But it's been an ongoing footgun.
Making a celebrity appearance, Rich Felker, the author of MUSL libc, notes:
> As long as Rust is changing signal dispositions inside init code in a way that the application cannot suppress or undo, it is _fundamentally unusable to implement standard unix utilities that run child processes_ or anything that needs to preserve the signal dispositions it was invoked with and pass them on to children. Changing inheritable process state behind the application's back is just unbelievably bad behavior and does not belong in a language runtime for a serious language...
>
> As an example, if you implement `find` in Rust, the `-exec` option will invoke its commands with `SIGPIPE` set to `SIG_IGN`, so that they will not properly terminate on broken pipe. But if you just made it set `SIGPIPE` to `SIG_DFL` before invoking the commands, now it would be broken in the case where the invoking user intentionally set `SIGPIPE` to `SIG_IGN` so that the commands would not die on broken pipe.
There was discussion in 2019 about fixing this over an edition, but nothing came of it.
Are we interested in fixing it over this one?
Strawman (horrible) proposal: We could stop making this pre-main syscall in Rust 2024 and have `cargo fix` insert this syscall at the start of every `main` function.
(In partial defense of the strawman, it gets us directly to the arguably best end result while having an automatic semantics-preserving edition migration and it avoids the concerns about lang/libs coupling that Mara raised. The edition migration could add a comment above this inserted code telling people under what circumstances they should either keep or delete the added line.)
### "types team / lang team interaction" rust#116557
**Link:** https://github.com/rust-lang/rust/issues/116557
TC: nikomatsakis nominated this:
> We had some discussion about types/lang team interaction. We concluded a few things:
>
> * Pinging the team like @rust-lang/lang is not an effective way to get attention. Nomination is the only official way to get attention.
> * It's ok to nominate things in an "advisory" capacity but not block (e.g., landing a PR), particularly as most any action can ultimately be reversed. But right now, triagebot doesn't track closed issues, so that's a bit risky.
>
> Action items:
>
> * We should fix triagebot to track closed issues.
TC: What do we think?
### "Match ergonomics 2024" rfcs#3627
**Link:** https://github.com/rust-lang/rfcs/pull/3627
TC: In the design meeting on 2024-05-15, we discussed Match Ergonomics 2024. We liked what we heard, and people wanted to see this move forward modulo adopting *Option 1* (make `mut x` in inherited patterns an error). This change was made, and in the meeting on 2024-05-24, we resolved the concerns about this.and it moved into FCP.
Since then, tmandry has raised a concern to ask what tradeoffs we're making with the no `ref mut` behind `&` rule. The purpose of this rule is to allow patterns like this:
```rust
let &(i, j, [s]) = &(63, 42, &mut [String::from("")]); //~ OK
//~^ i: i32, j: i32, s: &String
```
One motivation is that there are already cases in patterns where immutability takes precedence over mutability (so it *usually* works). E.g.:
```rust
let [a] = &mut &[42]; // x: &i32
let [a] = &&mut [42]; // x: &i32
```
As the RFC says,
> This change, in addition to being generally useful, makes the match ergonomics rules more consistent by ensuring that immutability *always* takes precedence over mutability.
The main drawback seems to be that, with this rule, one cannot:
> ...consistently write a `&mut` pattern that matches an inherited reference regardless of whether the binding mode has been converted to `ref` by an outer `&` so long as there is a `&mut` type involved.
That is, this is allowed:
```rust
//@ edition: 2024
let [[&mut x]] = [&mut [42]]; //~ OK, x: i32
```
(Because the `ref mut` is not behind an `&`.)
But these are not:
```rust
//@ edition: 2024
let &[[&mut x]] = &[&mut [42]]; //~ ERROR
let [[&mut x]] = &[&mut [42]]; //~ ERROR
```
(Because the `ref mut` is behind an `&`.)
However, one can write, and is intended to write, these instead:
```rust
//@ edition: 2024
let [[&x]] = [&mut [42]]; //~ OK
let &[[&x]] = &[&mut [42]]; //~ OK
let [[&x]] = &[&mut [42]]; //~ OK
```
These take advantage of the fact that `&` matches `&mut`. The reason that `&` matching `&mut` was included in this RFC (rather than e.g. being deferred to future work) was for explicitly this reason.
---
TC: Separately, tmandry writes:
>> Everything in this RFC, including the migration lint, is either already in nightly under an experimental feature gate, or waiting on PR review.
>
> Fantastic, thanks for your efforts here. Ideally I would like to see this go in as part of the unstable 2024 edition once this RFC lands, i.e. not blocking on a stabilization FCP before that happens.
TC: Does this sound right to us?
### "[RFC] `core::marker::Freeze` in bounds" rfcs#3633
**Link:** https://github.com/rust-lang/rfcs/pull/3633
TC: There's now a proposal on the table for the stabilization of the `Freeze` trait in bounds.
TC: We'll probably need to schedule a design meeting to work through this.
### "RFC: Return Type Notation" rfcs#3654
**Link:** https://github.com/rust-lang/rfcs/pull/3654
TC: Niko has now posted the long-awaited RFC for RTN in bounds and where clauses.
> Return type notation (RTN) gives a way to reference or bound the type returned by a trait method. The new bounds look like `T: Trait<method(..): Send>` or `T::method(..): Send`. The primary use case is to add bounds such as `Send` to the futures returned by `async fn`s in traits and `-> impl Future` functions, but they work for any trait function defined with return-position impl trait (e.g., `where T: Factory<widgets(..): DoubleEndedIterator>` would also be valid).
>
> This RFC proposes a new kind of type written `<T as Trait>::method(..)` (or `T::method(..)` for short). RTN refers to "the type returned by invoking `method` on `T`".
>
> To keep this RFC focused, it only covers usage of RTN as the `Self` type of a bound or where-clause. The expectation is that, after accepting this RFC, we will gradually expand RTN usage to other places as covered under [Future Possibilities](#future-possibilities). As a notable example, supporting RTN in struct field types would allow constructing types that store the results of a call to a trait `-> impl Trait` method, making them [more suitable for use in public APIs](https://rust-lang.github.io/api-guidelines/future-proofing.html).
TC: We'll probably need to schedule a design meeting to work through this.
### "Implement `PartialOrd` and `Ord` for `Discriminant`" rust#106418
**Link:** https://github.com/rust-lang/rust/pull/106418
TC: We discussed this last in the meeting on 2024-03-13. scottmcm has now raised on concern on the issue and is planning to make a counter-proposal:
> I remain concerned about exposing this with no opt-out on an unrestricted generic type @rfcbot concern overly-broad
>
> I'm committing to making an alternative proposal because I shouldn't block without one. Please hold my feet to the fire if that's no up in a week.
>
> Basically, I have an idea for how we might be able to do this, from [#106418 (comment)](https://github.com/rust-lang/rust/pull/106418#issuecomment-1698887324)
>
> > 2. Expose the variant ordering privately, only accessible by the type owner/module.
> >
> > Solution 2. is obviously more desirable, but AFAIK Rust can't do that and there is no proposal to add a feature like that.
https://github.com/rust-lang/rust/pull/106418#issuecomment-1994833151
### "Fallout from expansion of redundant import checking" rust#121708
**Link:** https://github.com/rust-lang/rust/issues/121708
TC: We discussed this in the meeting on 2024-03-13. The feelings expressed included:
- We don't want to create a perverse incentive for people to expand existing lints rather than to create new ones where appropriate just because there's less process for expanding the meaning of an existing lint.
- It would be good if potentially-disruptive expansions of an existing lint either:
- Had a machine-applicable fix.
- Or had a new name.
- We don't want to require a new lint name for each expansion.
- We don't want to require a crater run for each change to a lint.
- There are two ways to prevent disruption worth exploring:
- Prevent potentially-disruptive changes from hitting master.
- Respond quickly to early indications of disruption once the changes hit master.
- Compiler maintainers have a sense of what might be disruptive and are cautious to avoid it. It may be OK to have a policy that is not perfectly measurable.
TC: tmandry volunteered to draft a policy proposal.
### "What are the guarantees around which constants (and callees) in a function get monomorphized?" rust#122301
**Link:** https://github.com/rust-lang/rust/issues/122301
TC: The8472 asks whether this code, which compiles today, can be relied upon:
```rust
const fn panic<T>() {
struct W<T>(T);
impl<T> W<T> {
const C: () = panic!();
}
W::<T>::C
}
struct Invoke<T, const N: usize>(T);
impl<T, const N: usize> Invoke<T, N> {
const C: () = match N {
0 => (),
// Not called for `N == 0`, so not monomorphized.
_ => panic::<T>(),
};
}
fn main() {
let _x = Invoke::<(), 0>::C;
}
```
The8472 notes that this is a useful property and that there are use cases for this in the compiler and the standard library, at least unless or until we adopt something like `const if`:
https://github.com/rust-lang/rfcs/issues/3582
RalfJ has pointed out to The8472 that the current behavior might not be intentional and notes:
> It's not opt-dependent, but it's also unclear how we want to resolve the opt-dependent issue. Some [proposals](https://github.com/rust-lang/rust/issues/122814#issuecomment-2015090501) involve also walking all items "mentioned" in a const. That would be in direct conflict with your goal here I think. To be clear I think that's a weakness of those proposals. But if that turns out to be the only viable strategy then we'll have to decide what we want more: using `const` tricks to control what gets monomorphized, or not having optimization-dependent errors.
>
> One crucial part of this construction is that everything involved is generic. If somewhere in the two "branches" you end up calling a monomorphic function, then that may have its constants evaluated even if it is in the "dead" branch -- or it may not, it depends on which functions are deemed cross-crate-inlinable. That's basically what #122814 is about.
TC: The question to us is whether we want to guarantee this behavior. What do we think?
### "Policy for lint expansions" rust#122759
**Link:** https://github.com/rust-lang/rust/issues/122759
TC: In the call on 2024-03-13, we discussed this issue raised by tmandry:
"Fallout from expansion of redundant import checking"
https://github.com/rust-lang/rust/issues/121708
During the call, the thoughts expressed included:
- We don't want to create a perverse incentive for people to expand existing lints rather than to create new ones where appropriate just because there's less process for expanding the meaning of an existing lint.
- It would be good if potentially-disruptive expansions of an existing lint either:
- Had a machine-applicable fix.
- Or had a new name.
- We don't want to require a new lint name for each expansion.
- We don't want to require a crater run for each change to a lint.
- There are two ways to prevent disruption worth exploring:
- Prevent potentially-disruptive changes from hitting master.
- Respond quickly to early indications of disruption once the changes hit master.
- Compiler maintainers have a sense of what might be disruptive and are cautious to avoid it. It may be OK to have a policy that is not perfectly measurable.
TC: tmandry volunteered to draft a policy proposal. He's now written up this proposal in this issue.
> ## Background
>
> When a lint is expanded to include many new cases, it adds significant complexity to the rollout of a toolchain to large codebases. Maintainers of these codebases are stuck with the choice of
>
> 1. Disabling the existing lint while the toolchain is updated and new cases are fixed
> 2. Fixing cases manually and updating the toolchain immediately
>
> Both of these come with the problem of _racing_ with other developers in a codebase who may land new code which triggers the expanded lint in a new compiler, but does _not_ trigger the lint in an old compiler.
>
> While it would be nice to solve this "raciness" once and for all, there are other considerations at play. Instead, we propose to support these users by either providing them with a new lint name to temporarily opt out of _OR_ a machine-applicable fix which eases the pain of any races which might occur.
>
> Note that this requirement only applies to _significant_ lint expansions as measured by crater.
>
> ## Policy
>
> When an existing lint is expanded to include many new cases, we must provide either:
>
> 1. A new lint name under the existing group, so that users may opt out of the expansion at least temporarily, or
> 2. A MachineApplicable fix for the lint.
>
> Exceptions to this policy may be made via Language Team FCP.
>
> Here, we define "many new cases" as impacting more than 5% of the top-1000 crates on crates.io. This can be measured by counting the number of regressions from a crater run like the one below.
>
> A crater run is not required before landing for every lint expansion. Reviewers should use their best judgment to decide if one is required. However, if a lint expansion lands that violates this requirement, or is strongly suspected to violate this requirement based on other impact, it should be reverted.
>
> #### Crater command
>
> To measure the impact of a lint as defined by this policy, you can use the following crater command:
>
> `@craterbot run name=<name> start=master#<hash1>+rustflags=-D<lint_name> end=master#<hash2>+rustflags=-D<lint_name> crates=top-1000 mode=check-only p=1`
>
> See the [crater docs](https://github.com/rust-lang/crater/blob/master/docs/bot-usage.md#tutorial-creating-an-experiment-for-a-pr) for more information.
TC: What do we think?
### "Tracking Issue for externally implementable items" rust#125418
**Link:** https://github.com/rust-lang/rust/issues/125418
TC: We reviewed in triage an RFC for externally implementable functions on 2024-05-22 along with a companion/alternative RFC for externally implementable statics. That discussion produced two more proposals, one from Amanieu and one from tmandry.
TC: We're likely going to need a design meeting to work through these.
## Action item review
- [Action items list](https://hackmd.io/gstfhtXYTHa3Jv-P_2RK7A)
## Pending lang team project proposals
None.
## PRs on the lang-team repo
### "Add soqb`s design doc to variadics notes" lang-team#236
**Link:** https://github.com/rust-lang/lang-team/pull/236
### "Update auto traits design notes with recent discussion" lang-team#237
**Link:** https://github.com/rust-lang/lang-team/pull/237
### "Update hackmd link to a public link" lang-team#258
**Link:** https://github.com/rust-lang/lang-team/pull/258
### "Adding a link to "how to add a feature gate" in the experimenting how-to" lang-team#267
**Link:** https://github.com/rust-lang/lang-team/pull/267
## RFCs waiting to be merged
### "RFC: Return Type Notation" rfcs#3654
**Link:** https://github.com/rust-lang/rfcs/pull/3654
### "RFC: #[derive(SmartPointer)]" rfcs#3621
**Link:** https://github.com/rust-lang/rfcs/pull/3621
## `S-waiting-on-team`
### "Reorder trait bound modifiers *after* `for<...>` binder in trait bounds" rust#127054
**Link:** https://github.com/rust-lang/rust/pull/127054
### "warn less about non-exhaustive in ffi" rust#116863
**Link:** https://github.com/rust-lang/rust/pull/116863
### "offset_from: always allow pointers to point to the same address" rust#124921
**Link:** https://github.com/rust-lang/rust/pull/124921
### "Don't make statement nonterminals match pattern nonterminals" rust#120221
**Link:** https://github.com/rust-lang/rust/pull/120221
### "Initial support for auto traits with default bounds" rust#120706
**Link:** https://github.com/rust-lang/rust/pull/120706
### "Stabilize `count`, `ignore`, `index`, and `length` (`macro_metavar_expr`)" rust#122808
**Link:** https://github.com/rust-lang/rust/pull/122808
### "Skip pub structs with repr(c) and repr(transparent) in dead code analysis" rust#127104
**Link:** https://github.com/rust-lang/rust/pull/127104
### "Better errors with bad/missing identifiers in MBEs" rust#118939
**Link:** https://github.com/rust-lang/rust/pull/118939
### "Rename `AsyncIterator` back to `Stream`, introduce an AFIT-based `AsyncIterator` trait" rust#119550
**Link:** https://github.com/rust-lang/rust/pull/119550
### "Allow `#[deny]` inside `#[forbid]` as a no-op" rust#121560
**Link:** https://github.com/rust-lang/rust/pull/121560
### "Fixup Windows verbatim paths when used with the `include!` macro" rust#125205
**Link:** https://github.com/rust-lang/rust/pull/125205
## Proposed FCPs
**Check your boxes!**
### "Async closures" rfcs#3668
**Link:** https://github.com/rust-lang/rfcs/pull/3668
### "Reorder trait bound modifiers *after* `for<...>` binder in trait bounds" rust#127054
**Link:** https://github.com/rust-lang/rust/pull/127054
### "Guard Patterns" rfcs#3637
**Link:** https://github.com/rust-lang/rfcs/pull/3637
### "Stabilize `count`, `ignore`, `index`, and `length` (`macro_metavar_expr`)" rust#122808
**Link:** https://github.com/rust-lang/rust/pull/122808
### "Supertrait item shadowing v2" rfcs#3624
**Link:** https://github.com/rust-lang/rfcs/pull/3624
### "Stabilize `anonymous_lifetime_in_impl_trait`" rust#107378
**Link:** https://github.com/rust-lang/rust/pull/107378
### "add float semantics RFC" rfcs#3514
**Link:** https://github.com/rust-lang/rfcs/pull/3514
### "[RFC] externally implementable functions" rfcs#3632
**Link:** https://github.com/rust-lang/rfcs/pull/3632
### "Implement `PartialOrd` and `Ord` for `Discriminant`" rust#106418
**Link:** https://github.com/rust-lang/rust/pull/106418
### "Policy for lint expansions" rust#122759
**Link:** https://github.com/rust-lang/rust/issues/122759
### "RFC: inherent trait implementation" rfcs#2375
**Link:** https://github.com/rust-lang/rfcs/pull/2375
### "Don't allow unwinding from Drop impls" rfcs#3288
**Link:** https://github.com/rust-lang/rfcs/pull/3288
### "Add text for the CFG OS Version RFC" rfcs#3379
**Link:** https://github.com/rust-lang/rfcs/pull/3379
### "Add support for `use Trait::func`" rfcs#3591
**Link:** https://github.com/rust-lang/rfcs/pull/3591
### "[RFC] Add `#[export_ordinal(n)]` attribute" rfcs#3641
**Link:** https://github.com/rust-lang/rfcs/pull/3641
### "Tracking Issue for nested field access in offset_of" rust#120140
**Link:** https://github.com/rust-lang/rust/issues/120140
### "Tracking Issue for enum access in offset_of" rust#120141
**Link:** https://github.com/rust-lang/rust/issues/120141
### "Stabilize associated type position impl Trait (ATPIT)" rust#120700
**Link:** https://github.com/rust-lang/rust/pull/120700
### "regression: let-else syntax restriction (right curly brace not allowed)" rust#121608
**Link:** https://github.com/rust-lang/rust/issues/121608
## Active FCPs
### "elaborate on slice wide pointer metadata" reference#1499
**Link:** https://github.com/rust-lang/reference/pull/1499
### "`repr(discriminant = ...)` for type aliases" rfcs#3659
**Link:** https://github.com/rust-lang/rfcs/pull/3659
### "Fix ambiguous cases of multiple & in elided self lifetimes" rust#117967
**Link:** https://github.com/rust-lang/rust/pull/117967
### "offset_from: always allow pointers to point to the same address" rust#124921
**Link:** https://github.com/rust-lang/rust/pull/124921
### "Match ergonomics 2024" rfcs#3627
**Link:** https://github.com/rust-lang/rfcs/pull/3627
## P-critical issues
None.